From b41479c91e6685511c1f8ba8586106b322073b62 Mon Sep 17 00:00:00 2001 From: Ben Sanders Date: Sun, 2 Aug 2026 09:49:25 -0400 Subject: added statscounter code --- .../ruby/3.4.0/gems/addressable-2.9.0/CHANGELOG.md | 326 + .../ruby/3.4.0/gems/addressable-2.9.0/LICENSE.txt | 202 + .../ruby/3.4.0/gems/addressable-2.9.0/README.md | 121 + .../gems/addressable-2.9.0/lib/addressable.rb | 4 + .../gems/addressable-2.9.0/lib/addressable/idna.rb | 26 + .../lib/addressable/idna/native.rb | 66 + .../addressable-2.9.0/lib/addressable/idna/pure.rb | 4710 +++++ .../addressable-2.9.0/lib/addressable/template.rb | 1040 ++ .../gems/addressable-2.9.0/lib/addressable/uri.rb | 2602 +++ .../addressable-2.9.0/lib/addressable/version.rb | 31 + .../ruby/3.4.0/gems/bigdecimal-4.1.2/LICENSE | 56 + .../3.4.0/gems/bigdecimal-4.1.2/bigdecimal.gemspec | 62 + .../gems/bigdecimal-4.1.2/ext/bigdecimal/Makefile | 274 + .../bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.c | 6207 +++++++ .../bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.h | 298 + .../gems/bigdecimal-4.1.2/ext/bigdecimal/bits.h | 144 + .../gems/bigdecimal-4.1.2/ext/bigdecimal/div.h | 192 + .../bigdecimal-4.1.2/ext/bigdecimal/extconf.rb | 63 + .../gems/bigdecimal-4.1.2/ext/bigdecimal/feature.h | 68 + .../gems/bigdecimal-4.1.2/ext/bigdecimal/missing.c | 28 + .../gems/bigdecimal-4.1.2/ext/bigdecimal/missing.h | 106 + .../bigdecimal-4.1.2/ext/bigdecimal/missing/dtoa.c | 3509 ++++ .../gems/bigdecimal-4.1.2/ext/bigdecimal/ntt.h | 191 + .../ext/bigdecimal/static_assert.h | 54 + .../gems/bigdecimal-4.1.2/lib/bigdecimal.bundle | Bin 0 -> 136640 bytes .../3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.rb | 404 + .../bigdecimal-4.1.2/lib/bigdecimal/jacobian.rb | 92 + .../gems/bigdecimal-4.1.2/lib/bigdecimal/ludcmp.rb | 91 + .../gems/bigdecimal-4.1.2/lib/bigdecimal/math.rb | 927 + .../gems/bigdecimal-4.1.2/lib/bigdecimal/newton.rb | 82 + .../gems/bigdecimal-4.1.2/lib/bigdecimal/util.rb | 186 + .../3.4.0/gems/bigdecimal-4.1.2/sample/linear.rb | 110 + .../3.4.0/gems/bigdecimal-4.1.2/sample/nlsolve.rb | 57 + .../ruby/3.4.0/gems/bigdecimal-4.1.2/sample/pi.rb | 16 + .../gems/bigdecimal-4.1.2/sig/big_decimal.rbs | 1502 ++ .../gems/bigdecimal-4.1.2/sig/big_decimal_util.rbs | 158 + .../3.4.0/gems/bigdecimal-4.1.2/sig/big_math.rbs | 423 + .../3.4.0/gems/concurrent-ruby-1.3.8/CHANGELOG.md | 621 + .../ruby/3.4.0/gems/concurrent-ruby-1.3.8/Gemfile | 36 + .../3.4.0/gems/concurrent-ruby-1.3.8/LICENSE.txt | 21 + .../3.4.0/gems/concurrent-ruby-1.3.8/README.md | 409 + .../ruby/3.4.0/gems/concurrent-ruby-1.3.8/Rakefile | 343 + .../ext/concurrent-ruby/ConcurrentRubyService.java | 17 + .../ext/AtomicReferenceLibrary.java | 140 + .../ext/JRubyMapBackendLibrary.java | 248 + .../ext/JavaAtomicBooleanLibrary.java | 93 + .../ext/JavaAtomicFixnumLibrary.java | 113 + .../concurrent_ruby/ext/JavaSemaphoreLibrary.java | 189 + .../ext/SynchronizationLibrary.java | 292 + .../ext/jsr166e/ConcurrentHashMap.java | 31 + .../ext/jsr166e/ConcurrentHashMapV8.java | 3863 ++++ .../com/concurrent_ruby/ext/jsr166e/LongAdder.java | 203 + .../com/concurrent_ruby/ext/jsr166e/Striped64.java | 342 + .../ext/jsr166e/nounsafe/ConcurrentHashMapV8.java | 3800 ++++ .../ext/jsr166e/nounsafe/LongAdder.java | 204 + .../ext/jsr166e/nounsafe/Striped64.java | 291 + .../ext/jsr166y/ThreadLocalRandom.java | 199 + .../lib/concurrent-ruby/concurrent-ruby.rb | 5 + .../lib/concurrent-ruby/concurrent.rb | 134 + .../lib/concurrent-ruby/concurrent/agent.rb | 588 + .../lib/concurrent-ruby/concurrent/array.rb | 56 + .../lib/concurrent-ruby/concurrent/async.rb | 449 + .../lib/concurrent-ruby/concurrent/atom.rb | 222 + .../concurrent/atomic/atomic_boolean.rb | 127 + .../concurrent/atomic/atomic_fixnum.rb | 144 + .../concurrent/atomic/atomic_markable_reference.rb | 167 + .../concurrent/atomic/atomic_reference.rb | 142 + .../concurrent/atomic/count_down_latch.rb | 100 + .../concurrent/atomic/cyclic_barrier.rb | 128 + .../lib/concurrent-ruby/concurrent/atomic/event.rb | 109 + .../concurrent/atomic/fiber_local_var.rb | 109 + .../concurrent/atomic/java_count_down_latch.rb | 43 + .../concurrent-ruby/concurrent/atomic/locals.rb | 189 + .../concurrent/atomic/lock_local_var.rb | 29 + .../concurrent/atomic/mutex_atomic_boolean.rb | 68 + .../concurrent/atomic/mutex_atomic_fixnum.rb | 81 + .../concurrent/atomic/mutex_count_down_latch.rb | 44 + .../concurrent/atomic/mutex_semaphore.rb | 131 + .../concurrent/atomic/read_write_lock.rb | 268 + .../concurrent/atomic/reentrant_read_write_lock.rb | 386 + .../concurrent-ruby/concurrent/atomic/semaphore.rb | 163 + .../concurrent/atomic/thread_local_var.rb | 111 + .../atomic_reference/atomic_direct_update.rb | 37 + .../concurrent/atomic_reference/mutex_atomic.rb | 66 + .../atomic_reference/numeric_cas_wrapper.rb | 36 + .../lib/concurrent-ruby/concurrent/atomics.rb | 10 + .../collection/copy_on_notify_observer_set.rb | 107 + .../collection/copy_on_write_observer_set.rb | 111 + .../java_non_concurrent_priority_queue.rb | 84 + .../concurrent/collection/lock_free_stack.rb | 160 + .../concurrent/collection/map/mri_map_backend.rb | 66 + .../collection/map/non_concurrent_map_backend.rb | 148 + .../collection/map/synchronized_map_backend.rb | 85 + .../collection/map/truffleruby_map_backend.rb | 14 + .../collection/non_concurrent_priority_queue.rb | 143 + .../ruby_non_concurrent_priority_queue.rb | 160 + .../concurrent/collection/ruby_timeout_queue.rb | 55 + .../concurrent/collection/timeout_queue.rb | 18 + .../concurrent/concern/deprecation.rb | 34 + .../concurrent/concern/dereferenceable.rb | 73 + .../concurrent-ruby/concurrent/concern/logging.rb | 121 + .../concurrent/concern/obligation.rb | 220 + .../concurrent/concern/observable.rb | 110 + .../concurrent-ruby/concurrent/concurrent_ruby.jar | Bin 0 -> 136802 bytes .../concurrent-ruby/concurrent/configuration.rb | 105 + .../lib/concurrent-ruby/concurrent/constants.rb | 8 + .../lib/concurrent-ruby/concurrent/dataflow.rb | 81 + .../lib/concurrent-ruby/concurrent/delay.rb | 199 + .../lib/concurrent-ruby/concurrent/errors.rb | 74 + .../lib/concurrent-ruby/concurrent/exchanger.rb | 353 + .../executor/abstract_executor_service.rb | 131 + .../concurrent/executor/cached_thread_pool.rb | 62 + .../concurrent/executor/executor_service.rb | 185 + .../concurrent/executor/fixed_thread_pool.rb | 222 + .../concurrent/executor/immediate_executor.rb | 66 + .../executor/indirect_immediate_executor.rb | 44 + .../concurrent/executor/java_executor_service.rb | 101 + .../executor/java_single_thread_executor.rb | 30 + .../executor/java_thread_pool_executor.rb | 147 + .../concurrent/executor/ruby_executor_service.rb | 82 + .../executor/ruby_single_thread_executor.rb | 23 + .../executor/ruby_thread_pool_executor.rb | 396 + .../concurrent/executor/safe_task_executor.rb | 35 + .../concurrent/executor/serial_executor_service.rb | 34 + .../concurrent/executor/serialized_execution.rb | 107 + .../executor/serialized_execution_delegator.rb | 28 + .../concurrent/executor/simple_executor_service.rb | 103 + .../concurrent/executor/single_thread_executor.rb | 57 + .../concurrent/executor/thread_pool_executor.rb | 88 + .../concurrent/executor/timer_set.rb | 179 + .../lib/concurrent-ruby/concurrent/executors.rb | 19 + .../lib/concurrent-ruby/concurrent/future.rb | 141 + .../lib/concurrent-ruby/concurrent/hash.rb | 52 + .../concurrent-ruby/concurrent/immutable_struct.rb | 101 + .../lib/concurrent-ruby/concurrent/ivar.rb | 208 + .../lib/concurrent-ruby/concurrent/map.rb | 350 + .../lib/concurrent-ruby/concurrent/maybe.rb | 229 + .../concurrent-ruby/concurrent/mutable_struct.rb | 239 + .../lib/concurrent-ruby/concurrent/mvar.rb | 242 + .../lib/concurrent-ruby/concurrent/options.rb | 42 + .../lib/concurrent-ruby/concurrent/promise.rb | 580 + .../lib/concurrent-ruby/concurrent/promises.rb | 2184 +++ .../lib/concurrent-ruby/concurrent/re_include.rb | 60 + .../concurrent-ruby/concurrent/scheduled_task.rb | 331 + .../lib/concurrent-ruby/concurrent/set.rb | 64 + .../concurrent-ruby/concurrent/settable_struct.rb | 139 + .../concurrent-ruby/concurrent/synchronization.rb | 13 + .../synchronization/abstract_lockable_object.rb | 102 + .../concurrent/synchronization/abstract_object.rb | 22 + .../concurrent/synchronization/abstract_struct.rb | 171 + .../concurrent/synchronization/condition.rb | 62 + .../synchronization/full_memory_barrier.rb | 29 + .../synchronization/jruby_lockable_object.rb | 15 + .../concurrent/synchronization/lock.rb | 38 + .../concurrent/synchronization/lockable_object.rb | 75 + .../synchronization/mutex_lockable_object.rb | 89 + .../concurrent/synchronization/object.rb | 151 + .../synchronization/safe_initialization.rb | 36 + .../concurrent/synchronization/volatile.rb | 101 + .../thread_safe/synchronized_delegator.rb | 47 + .../concurrent-ruby/concurrent/thread_safe/util.rb | 16 + .../concurrent/thread_safe/util/adder.rb | 74 + .../concurrent/thread_safe/util/data_structures.rb | 52 + .../thread_safe/util/power_of_two_tuple.rb | 38 + .../concurrent/thread_safe/util/striped64.rb | 246 + .../concurrent/thread_safe/util/volatile.rb | 75 + .../thread_safe/util/xor_shift_random.rb | 50 + .../lib/concurrent-ruby/concurrent/timer_task.rb | 366 + .../lib/concurrent-ruby/concurrent/tuple.rb | 82 + .../lib/concurrent-ruby/concurrent/tvar.rb | 222 + .../concurrent-ruby/concurrent/utility/engine.rb | 45 + .../concurrent/utility/monotonic_time.rb | 19 + .../concurrent/utility/native_extension_loader.rb | 77 + .../concurrent/utility/native_integer.rb | 54 + .../concurrent/utility/processor_counter.rb | 220 + .../lib/concurrent-ruby/concurrent/version.rb | 3 + .../gems/ffi-1.17.4-arm64-darwin/CHANGELOG.md | 507 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/COPYING | 49 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/Gemfile | 26 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE | 24 + .../gems/ffi-1.17.4-arm64-darwin/LICENSE.SPECS | 22 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/README.md | 138 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/Rakefile | 209 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/Steepfile | 8 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/ffi.gemspec | 43 + .../ffi-1.17.4-arm64-darwin/lib/3.0/ffi_c.bundle | Bin 0 -> 332473 bytes .../ffi-1.17.4-arm64-darwin/lib/3.1/ffi_c.bundle | Bin 0 -> 266153 bytes .../ffi-1.17.4-arm64-darwin/lib/3.2/ffi_c.bundle | Bin 0 -> 266153 bytes .../ffi-1.17.4-arm64-darwin/lib/3.3/ffi_c.bundle | Bin 0 -> 265625 bytes .../ffi-1.17.4-arm64-darwin/lib/3.4/ffi_c.bundle | Bin 0 -> 265657 bytes .../ffi-1.17.4-arm64-darwin/lib/4.0/ffi_c.bundle | Bin 0 -> 282361 bytes .../3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi.rb | 27 + .../lib/ffi/abstract_memory.rb | 44 + .../ffi-1.17.4-arm64-darwin/lib/ffi/autopointer.rb | 186 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/buffer.rb | 4 + .../ffi-1.17.4-arm64-darwin/lib/ffi/callback.rb | 4 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/compat.rb | 54 + .../lib/ffi/data_converter.rb | 67 + .../lib/ffi/dynamic_library.rb | 118 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/enum.rb | 302 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/errno.rb | 43 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/ffi.rb | 109 + .../ffi-1.17.4-arm64-darwin/lib/ffi/function.rb | 94 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/io.rb | 62 + .../ffi-1.17.4-arm64-darwin/lib/ffi/library.rb | 592 + .../lib/ffi/library_path.rb | 109 + .../lib/ffi/managedstruct.rb | 84 + .../lib/ffi/memorypointer.rb | 1 + .../ffi-1.17.4-arm64-darwin/lib/ffi/platform.rb | 187 + .../lib/ffi/platform/aarch64-darwin/types.conf | 130 + .../lib/ffi/platform/aarch64-freebsd/types.conf | 128 + .../lib/ffi/platform/aarch64-freebsd12/types.conf | 181 + .../lib/ffi/platform/aarch64-linux/types.conf | 175 + .../lib/ffi/platform/aarch64-openbsd/types.conf | 134 + .../lib/ffi/platform/aarch64-windows/types.conf | 52 + .../lib/ffi/platform/arm-freebsd/types.conf | 152 + .../lib/ffi/platform/arm-freebsd12/types.conf | 152 + .../lib/ffi/platform/arm-linux/types.conf | 132 + .../lib/ffi/platform/hppa1.1-linux/types.conf | 178 + .../lib/ffi/platform/hppa2.0-linux/types.conf | 178 + .../lib/ffi/platform/i386-cygwin/types.conf | 3 + .../lib/ffi/platform/i386-darwin/types.conf | 100 + .../lib/ffi/platform/i386-freebsd/types.conf | 152 + .../lib/ffi/platform/i386-freebsd12/types.conf | 152 + .../lib/ffi/platform/i386-gnu/types.conf | 107 + .../lib/ffi/platform/i386-linux/types.conf | 103 + .../lib/ffi/platform/i386-netbsd/types.conf | 126 + .../lib/ffi/platform/i386-openbsd/types.conf | 128 + .../lib/ffi/platform/i386-solaris/types.conf | 122 + .../lib/ffi/platform/i386-windows/types.conf | 52 + .../lib/ffi/platform/ia64-linux/types.conf | 104 + .../lib/ffi/platform/loongarch64-linux/types.conf | 141 + .../lib/ffi/platform/mips-linux/types.conf | 102 + .../lib/ffi/platform/mips64-linux/types.conf | 104 + .../lib/ffi/platform/mips64el-linux/types.conf | 104 + .../lib/ffi/platform/mipsel-linux/types.conf | 102 + .../lib/ffi/platform/mipsisa32r6-linux/types.conf | 102 + .../ffi/platform/mipsisa32r6el-linux/types.conf | 102 + .../lib/ffi/platform/mipsisa64r6-linux/types.conf | 104 + .../ffi/platform/mipsisa64r6el-linux/types.conf | 104 + .../lib/ffi/platform/powerpc-aix/types.conf | 180 + .../lib/ffi/platform/powerpc-darwin/types.conf | 100 + .../lib/ffi/platform/powerpc-linux/types.conf | 130 + .../lib/ffi/platform/powerpc-openbsd/types.conf | 156 + .../lib/ffi/platform/powerpc64-linux/types.conf | 104 + .../lib/ffi/platform/powerpc64le-linux/types.conf | 100 + .../lib/ffi/platform/riscv64-linux/types.conf | 104 + .../lib/ffi/platform/s390-linux/types.conf | 102 + .../lib/ffi/platform/s390x-linux/types.conf | 102 + .../lib/ffi/platform/sparc-linux/types.conf | 102 + .../lib/ffi/platform/sparc-solaris/types.conf | 128 + .../lib/ffi/platform/sparcv9-linux/types.conf | 102 + .../lib/ffi/platform/sparcv9-openbsd/types.conf | 156 + .../lib/ffi/platform/sparcv9-solaris/types.conf | 128 + .../lib/ffi/platform/sw_64-linux/types.conf | 141 + .../lib/ffi/platform/x86_64-cygwin/types.conf | 3 + .../lib/ffi/platform/x86_64-darwin/types.conf | 130 + .../ffi/platform/x86_64-dragonflybsd/types.conf | 130 + .../lib/ffi/platform/x86_64-freebsd/types.conf | 128 + .../lib/ffi/platform/x86_64-freebsd12/types.conf | 158 + .../lib/ffi/platform/x86_64-haiku/types.conf | 117 + .../lib/ffi/platform/x86_64-linux/types.conf | 132 + .../lib/ffi/platform/x86_64-msys/types.conf | 119 + .../lib/ffi/platform/x86_64-netbsd/types.conf | 128 + .../lib/ffi/platform/x86_64-openbsd/types.conf | 134 + .../lib/ffi/platform/x86_64-solaris/types.conf | 122 + .../lib/ffi/platform/x86_64-windows/types.conf | 52 + .../ffi-1.17.4-arm64-darwin/lib/ffi/pointer.rb | 167 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct.rb | 317 + .../lib/ffi/struct_by_reference.rb | 72 + .../lib/ffi/struct_layout.rb | 96 + .../lib/ffi/struct_layout_builder.rb | 227 + .../lib/ffi/tools/const_generator.rb | 232 + .../lib/ffi/tools/generator.rb | 105 + .../lib/ffi/tools/generator_task.rb | 32 + .../lib/ffi/tools/struct_generator.rb | 195 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/types.rb | 222 + .../gems/ffi-1.17.4-arm64-darwin/lib/ffi/union.rb | 43 + .../ffi-1.17.4-arm64-darwin/lib/ffi/variadic.rb | 80 + .../ffi-1.17.4-arm64-darwin/lib/ffi/version.rb | 3 + .../ffi-1.17.4-arm64-darwin/samples/getlogin.rb | 8 + .../gems/ffi-1.17.4-arm64-darwin/samples/getpid.rb | 8 + .../samples/gettimeofday.rb | 18 + .../gems/ffi-1.17.4-arm64-darwin/samples/hello.rb | 8 + .../samples/hello_ractor.rb | 19 + .../ffi-1.17.4-arm64-darwin/samples/inotify.rb | 60 + .../gems/ffi-1.17.4-arm64-darwin/samples/pty.rb | 75 + .../gems/ffi-1.17.4-arm64-darwin/samples/qsort.rb | 20 + .../samples/qsort_ractor.rb | 36 + .../3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi.rbs | 29 + .../sig/ffi/abstract_memory.rbs | 165 + .../sig/ffi/auto_pointer.rbs | 26 + .../ffi-1.17.4-arm64-darwin/sig/ffi/buffer.rbs | 18 + .../sig/ffi/data_converter.rbs | 10 + .../sig/ffi/dynamic_library.rbs | 9 + .../gems/ffi-1.17.4-arm64-darwin/sig/ffi/enum.rbs | 38 + .../gems/ffi-1.17.4-arm64-darwin/sig/ffi/errno.rbs | 8 + .../ffi-1.17.4-arm64-darwin/sig/ffi/function.rbs | 39 + .../ffi-1.17.4-arm64-darwin/sig/ffi/library.rbs | 42 + .../sig/ffi/native_type.rbs | 86 + .../ffi-1.17.4-arm64-darwin/sig/ffi/platform.rbs | 49 + .../ffi-1.17.4-arm64-darwin/sig/ffi/pointer.rbs | 42 + .../ffi-1.17.4-arm64-darwin/sig/ffi/struct.rbs | 76 + .../sig/ffi/struct_by_reference.rbs | 11 + .../sig/ffi/struct_by_value.rbs | 7 + .../sig/ffi/struct_layout.rbs | 9 + .../sig/ffi/struct_layout_builder.rbs | 5 + .../gems/ffi-1.17.4-arm64-darwin/sig/ffi/type.rbs | 39 + .../ext/google/protobuf_c/Rakefile | 3 + .../ext/google/protobuf_c/convert.c | 335 + .../ext/google/protobuf_c/convert.h | 50 + .../ext/google/protobuf_c/defs.c | 2084 +++ .../ext/google/protobuf_c/defs.h | 82 + .../ext/google/protobuf_c/extconf.rb | 38 + .../ext/google/protobuf_c/glue.c | 135 + .../ext/google/protobuf_c/map.c | 768 + .../ext/google/protobuf_c/map.h | 48 + .../ext/google/protobuf_c/message.c | 1462 ++ .../ext/google/protobuf_c/message.h | 82 + .../ext/google/protobuf_c/protobuf.c | 357 + .../ext/google/protobuf_c/protobuf.h | 100 + .../ext/google/protobuf_c/repeated_field.c | 728 + .../ext/google/protobuf_c/repeated_field.h | 45 + .../ext/google/protobuf_c/ruby-upb.c | 18154 +++++++++++++++++++ .../ext/google/protobuf_c/ruby-upb.h | 18003 ++++++++++++++++++ .../ext/google/protobuf_c/shared_convert.c | 69 + .../ext/google/protobuf_c/shared_convert.h | 26 + .../ext/google/protobuf_c/shared_message.c | 37 + .../ext/google/protobuf_c/shared_message.h | 21 + .../protobuf_c/third_party/utf8_range/LICENSE | 22 + .../protobuf_c/third_party/utf8_range/utf8_range.c | 207 + .../protobuf_c/third_party/utf8_range/utf8_range.h | 23 + .../third_party/utf8_range/utf8_range_neon.inc | 117 + .../third_party/utf8_range/utf8_range_sse.inc | 272 + .../lib/google/3.1/protobuf_c.bundle | Bin 0 -> 414574 bytes .../lib/google/3.2/protobuf_c.bundle | Bin 0 -> 414686 bytes .../lib/google/3.3/protobuf_c.bundle | Bin 0 -> 414382 bytes .../lib/google/3.4/protobuf_c.bundle | Bin 0 -> 414366 bytes .../lib/google/4.0/protobuf_c.bundle | Bin 0 -> 430926 bytes .../lib/google/protobuf.rb | 61 + .../lib/google/protobuf/any_pb.rb | 17 + .../lib/google/protobuf/api_pb.rb | 22 + .../lib/google/protobuf/descriptor_pb.rb | 70 + .../lib/google/protobuf/duration_pb.rb | 17 + .../lib/google/protobuf/empty_pb.rb | 17 + .../lib/google/protobuf/ffi/descriptor.rb | 175 + .../lib/google/protobuf/ffi/descriptor_pool.rb | 83 + .../lib/google/protobuf/ffi/enum_descriptor.rb | 183 + .../lib/google/protobuf/ffi/ffi.rb | 213 + .../lib/google/protobuf/ffi/field_descriptor.rb | 346 + .../lib/google/protobuf/ffi/file_descriptor.rb | 85 + .../lib/google/protobuf/ffi/internal/arena.rb | 60 + .../lib/google/protobuf/ffi/internal/convert.rb | 292 + .../google/protobuf/ffi/internal/pointer_helper.rb | 36 + .../google/protobuf/ffi/internal/type_safety.rb | 25 + .../lib/google/protobuf/ffi/map.rb | 433 + .../lib/google/protobuf/ffi/message.rb | 783 + .../lib/google/protobuf/ffi/method_descriptor.rb | 124 + .../lib/google/protobuf/ffi/object_cache.rb | 30 + .../lib/google/protobuf/ffi/oneof_descriptor.rb | 107 + .../lib/google/protobuf/ffi/repeated_field.rb | 411 + .../lib/google/protobuf/ffi/service_descriptor.rb | 117 + .../lib/google/protobuf/field_mask_pb.rb | 17 + .../lib/google/protobuf/internal/object_cache.rb | 99 + .../lib/google/protobuf/message_exts.rb | 39 + .../lib/google/protobuf/plugin_pb.rb | 25 + .../lib/google/protobuf/repeated_field.rb | 177 + .../lib/google/protobuf/source_context_pb.rb | 17 + .../lib/google/protobuf/struct_pb.rb | 20 + .../lib/google/protobuf/timestamp_pb.rb | 17 + .../lib/google/protobuf/type_pb.rb | 27 + .../lib/google/protobuf/well_known_types.rb | 211 + .../lib/google/protobuf/wrappers_pb.rb | 25 + .../lib/google/protobuf_ffi.rb | 52 + .../lib/google/protobuf_native.rb | 19 + .../lib/google/tasks/ffi.rake | 100 + .../.github/workflows/linux.yml | 23 + .../.github/workflows/windows.yml | 23 + .../3.4.0/gems/http_parser.rb-0.8.1/.gitignore | 12 + .../3.4.0/gems/http_parser.rb-0.8.1/.gitmodules | 6 + .../ruby/3.4.0/gems/http_parser.rb-0.8.1/Gemfile | 2 + .../3.4.0/gems/http_parser.rb-0.8.1/LICENSE-MIT | 20 + .../ruby/3.4.0/gems/http_parser.rb-0.8.1/README.md | 90 + .../ruby/3.4.0/gems/http_parser.rb-0.8.1/Rakefile | 8 + .../gems/http_parser.rb-0.8.1/bench/standalone.rb | 23 + .../3.4.0/gems/http_parser.rb-0.8.1/bench/thin.rb | 58 + .../ext/ruby_http_parser/.gitignore | 1 + .../ruby_http_parser/RubyHttpParserService.java | 18 + .../ext/ruby_http_parser/ext_help.h | 23 + .../ext/ruby_http_parser/extconf.rb | 24 + .../org/ruby_http_parser/RubyHttpParser.java | 502 + .../ext/ruby_http_parser/ruby_http_parser.c | 569 + .../ext/ruby_http_parser/vendor/.gitkeep | 0 .../vendor/http-parser-java/AUTHORS | 32 + .../vendor/http-parser-java/LICENSE-MIT | 48 + .../vendor/http-parser-java/README.md | 183 + .../ruby_http_parser/vendor/http-parser-java/TODO | 28 + .../vendor/http-parser-java/build.xml | 74 + .../vendor/http-parser-java/http_parser.c | 2175 +++ .../vendor/http-parser-java/http_parser.gyp | 79 + .../vendor/http-parser-java/http_parser.h | 304 + .../http-parser-java/src/Http-parser.java.iml | 22 + .../src/impl/http_parser/FieldData.java | 41 + .../src/impl/http_parser/HTTPCallback.java | 8 + .../src/impl/http_parser/HTTPDataCallback.java | 34 + .../src/impl/http_parser/HTTPErrorCallback.java | 12 + .../src/impl/http_parser/HTTPException.java | 9 + .../src/impl/http_parser/HTTPMethod.java | 107 + .../src/impl/http_parser/HTTPParser.java | 36 + .../src/impl/http_parser/HTTPParserUrl.java | 76 + .../src/impl/http_parser/ParserSettings.java | 256 + .../src/impl/http_parser/ParserType.java | 13 + .../src/impl/http_parser/Util.java | 111 + .../src/impl/http_parser/lolevel/HTTPCallback.java | 5 + .../impl/http_parser/lolevel/HTTPDataCallback.java | 25 + .../http_parser/lolevel/HTTPErrorCallback.java | 7 + .../src/impl/http_parser/lolevel/HTTPParser.java | 2161 +++ .../impl/http_parser/lolevel/ParserSettings.java | 83 + .../src/test/http_parser/lolevel/Message.java | 374 + .../src/test/http_parser/lolevel/ParseUrl.java | 51 + .../src/test/http_parser/lolevel/Requests.java | 69 + .../src/test/http_parser/lolevel/Responses.java | 52 + .../src/test/http_parser/lolevel/Test.java | 16 + .../lolevel/TestHeaderOverflowError.java | 48 + .../src/test/http_parser/lolevel/TestLoaderNG.java | 212 + .../lolevel/TestNoOverflowLongBody.java | 62 + .../src/test/http_parser/lolevel/UnitTest.java | 117 + .../src/test/http_parser/lolevel/Upgrade.java | 27 + .../src/test/http_parser/lolevel/Url.java | 127 + .../src/test/http_parser/lolevel/Util.java | 236 + .../http_parser/lolevel/WrongContentLength.java | 59 + .../vendor/http-parser-java/test.c | 3425 ++++ .../vendor/http-parser-java/tests.dumped | 845 + .../vendor/http-parser-java/tests.utf8 | 17 + .../http-parser-java/tools/byte_constants.rb | 6 + .../vendor/http-parser-java/tools/const_char.rb | 13 + .../vendor/http-parser-java/tools/lowcase.rb | 15 + .../vendor/http-parser-java/tools/parse_tests.rb | 33 + .../ruby_http_parser/vendor/http-parser/AUTHORS | 68 + .../vendor/http-parser/LICENSE-MIT | 19 + .../ruby_http_parser/vendor/http-parser/README.md | 246 + .../ruby_http_parser/vendor/http-parser/bench.c | 128 + .../vendor/http-parser/contrib/parsertrace.c | 157 + .../vendor/http-parser/contrib/url_parser.c | 47 + .../vendor/http-parser/http_parser.c | 2440 +++ .../vendor/http-parser/http_parser.gyp | 111 + .../vendor/http-parser/http_parser.h | 433 + .../ext/ruby_http_parser/vendor/http-parser/test.c | 4456 +++++ .../http_parser.rb-0.8.1/http_parser.rb.gemspec | 32 + .../gems/http_parser.rb-0.8.1/lib/http/parser.rb | 1 + .../gems/http_parser.rb-0.8.1/lib/http_parser.rb | 21 + .../gems/http_parser.rb-0.8.1/tasks/compile.rake | 42 + .../gems/http_parser.rb-0.8.1/tasks/fixtures.rake | 71 + .../gems/http_parser.rb-0.8.1/tasks/spec.rake | 5 + .../http_parser.rb-0.8.1/tasks/submodules.rake | 7 + .../bundle/ruby/3.4.0/gems/i18n-1.15.2/MIT-LICENSE | 20 + .../bundle/ruby/3.4.0/gems/i18n-1.15.2/README.md | 139 + .../bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n.rb | 507 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/backend.rb | 22 + .../gems/i18n-1.15.2/lib/i18n/backend/base.rb | 314 + .../gems/i18n-1.15.2/lib/i18n/backend/cache.rb | 113 + .../i18n-1.15.2/lib/i18n/backend/cache_file.rb | 36 + .../gems/i18n-1.15.2/lib/i18n/backend/cascade.rb | 56 + .../gems/i18n-1.15.2/lib/i18n/backend/chain.rb | 130 + .../gems/i18n-1.15.2/lib/i18n/backend/fallbacks.rb | 127 + .../gems/i18n-1.15.2/lib/i18n/backend/flatten.rb | 118 + .../gems/i18n-1.15.2/lib/i18n/backend/gettext.rb | 83 + .../lib/i18n/backend/interpolation_compiler.rb | 122 + .../gems/i18n-1.15.2/lib/i18n/backend/key_value.rb | 204 + .../i18n-1.15.2/lib/i18n/backend/lazy_loadable.rb | 184 + .../gems/i18n-1.15.2/lib/i18n/backend/memoize.rb | 54 + .../gems/i18n-1.15.2/lib/i18n/backend/metadata.rb | 71 + .../i18n-1.15.2/lib/i18n/backend/pluralization.rb | 96 + .../gems/i18n-1.15.2/lib/i18n/backend/simple.rb | 113 + .../i18n-1.15.2/lib/i18n/backend/transliterator.rb | 109 + .../ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/config.rb | 199 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/exceptions.rb | 155 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/gettext.rb | 28 + .../gems/i18n-1.15.2/lib/i18n/gettext/helpers.rb | 75 + .../gems/i18n-1.15.2/lib/i18n/gettext/po_parser.rb | 329 + .../gems/i18n-1.15.2/lib/i18n/interpolate/ruby.rb | 53 + .../ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale.rb | 8 + .../gems/i18n-1.15.2/lib/i18n/locale/fallbacks.rb | 107 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag.rb | 28 + .../i18n-1.15.2/lib/i18n/locale/tag/parents.rb | 24 + .../i18n-1.15.2/lib/i18n/locale/tag/rfc4646.rb | 74 + .../gems/i18n-1.15.2/lib/i18n/locale/tag/simple.rb | 39 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/middleware.rb | 21 + .../ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests.rb | 14 + .../gems/i18n-1.15.2/lib/i18n/tests/basics.rb | 58 + .../gems/i18n-1.15.2/lib/i18n/tests/defaults.rb | 59 + .../i18n-1.15.2/lib/i18n/tests/interpolation.rb | 185 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/tests/link.rb | 66 + .../i18n-1.15.2/lib/i18n/tests/localization.rb | 19 + .../lib/i18n/tests/localization/date.rb | 122 + .../lib/i18n/tests/localization/date_time.rb | 103 + .../lib/i18n/tests/localization/procs.rb | 118 + .../lib/i18n/tests/localization/time.rb | 103 + .../gems/i18n-1.15.2/lib/i18n/tests/lookup.rb | 87 + .../i18n-1.15.2/lib/i18n/tests/pluralization.rb | 35 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/tests/procs.rb | 71 + .../ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/utils.rb | 55 + .../3.4.0/gems/i18n-1.15.2/lib/i18n/version.rb | 5 + .../jekyll-seo-tag-2.9.0/.github/workflows/ci.yml | 103 + .../.github/workflows/release.yml | 33 + .../.github/workflows/scripts/memprof | 4 + .../.github/workflows/scripts/memprof.rb | 14 + .../.github/workflows/third-party.yml | 63 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/.gitignore | 9 + .../ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rspec | 2 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop.yml | 42 + .../gems/jekyll-seo-tag-2.9.0/.rubocop_todo.yml | 46 + .../ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/Gemfile | 8 + .../gems/jekyll-seo-tag-2.9.0/History.markdown | 242 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/LICENSE.txt | 21 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/docs/README.md | 33 + .../gems/jekyll-seo-tag-2.9.0/docs/_config.yml | 10 + .../docs/_layouts/default.html | 18 + .../jekyll-seo-tag-2.9.0/docs/advanced-usage.md | 224 + .../gems/jekyll-seo-tag-2.9.0/docs/installation.md | 24 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/docs/usage.md | 81 + .../jekyll-seo-tag-2.9.0/jekyll-seo-tag.gemspec | 34 + .../jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag.rb | 94 + .../lib/jekyll-seo-tag/author_drop.rb | 93 + .../lib/jekyll-seo-tag/drop.rb | 274 + .../lib/jekyll-seo-tag/filters.rb | 14 + .../lib/jekyll-seo-tag/image_drop.rb | 83 + .../lib/jekyll-seo-tag/json_ld.rb | 31 + .../lib/jekyll-seo-tag/json_ld_drop.rb | 104 + .../lib/jekyll-seo-tag/url_helper.rb | 23 + .../lib/jekyll-seo-tag/version.rb | 10 + .../gems/jekyll-seo-tag-2.9.0/lib/template.html | 131 + .../gems/jekyll-seo-tag-2.9.0/script/bootstrap | 5 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/script/cibuild | 7 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/script/release | 38 + .../3.4.0/gems/jekyll-seo-tag-2.9.0/script/site | 3 + vendor/bundle/ruby/3.4.0/gems/json-2.21.1/BSDL | 22 + .../bundle/ruby/3.4.0/gems/json-2.21.1/CHANGES.md | 810 + vendor/bundle/ruby/3.4.0/gems/json-2.21.1/COPYING | 56 + vendor/bundle/ruby/3.4.0/gems/json-2.21.1/LEGAL | 20 + .../bundle/ruby/3.4.0/gems/json-2.21.1/README.md | 308 + .../json-2.21.1/ext/json/ext/fbuffer/fbuffer.h | 259 + .../json-2.21.1/ext/json/ext/generator/Makefile | 273 + .../json-2.21.1/ext/json/ext/generator/extconf.rb | 19 + .../json-2.21.1/ext/json/ext/generator/generator.c | 2066 +++ .../3.4.0/gems/json-2.21.1/ext/json/ext/json.h | 183 + .../gems/json-2.21.1/ext/json/ext/parser/Makefile | 273 + .../json-2.21.1/ext/json/ext/parser/extconf.rb | 37 + .../gems/json-2.21.1/ext/json/ext/parser/parser.c | 2917 +++ .../gems/json-2.21.1/ext/json/ext/simd/conf.rb | 24 + .../gems/json-2.21.1/ext/json/ext/simd/simd.h | 208 + .../ext/json/ext/vendor/fast_float_parser.h | 814 + .../gems/json-2.21.1/ext/json/ext/vendor/fpconv.c | 480 + .../json-2.21.1/ext/json/ext/vendor/jeaiii-ltoa.h | 267 + .../ruby/3.4.0/gems/json-2.21.1/json.gemspec | 62 + .../bundle/ruby/3.4.0/gems/json-2.21.1/lib/json.rb | 693 + .../gems/json-2.21.1/lib/json/add/bigdecimal.rb | 58 + .../3.4.0/gems/json-2.21.1/lib/json/add/complex.rb | 51 + .../3.4.0/gems/json-2.21.1/lib/json/add/core.rb | 13 + .../3.4.0/gems/json-2.21.1/lib/json/add/date.rb | 54 + .../gems/json-2.21.1/lib/json/add/date_time.rb | 67 + .../gems/json-2.21.1/lib/json/add/exception.rb | 49 + .../3.4.0/gems/json-2.21.1/lib/json/add/ostruct.rb | 54 + .../3.4.0/gems/json-2.21.1/lib/json/add/range.rb | 54 + .../gems/json-2.21.1/lib/json/add/rational.rb | 49 + .../3.4.0/gems/json-2.21.1/lib/json/add/regexp.rb | 48 + .../3.4.0/gems/json-2.21.1/lib/json/add/set.rb | 48 + .../3.4.0/gems/json-2.21.1/lib/json/add/string.rb | 35 + .../3.4.0/gems/json-2.21.1/lib/json/add/struct.rb | 52 + .../3.4.0/gems/json-2.21.1/lib/json/add/symbol.rb | 52 + .../3.4.0/gems/json-2.21.1/lib/json/add/time.rb | 52 + .../ruby/3.4.0/gems/json-2.21.1/lib/json/common.rb | 1182 ++ .../ruby/3.4.0/gems/json-2.21.1/lib/json/ext.rb | 71 + .../gems/json-2.21.1/lib/json/ext/generator.bundle | Bin 0 -> 98464 bytes .../json-2.21.1/lib/json/ext/generator/state.rb | 104 + .../gems/json-2.21.1/lib/json/ext/parser.bundle | Bin 0 -> 100048 bytes .../gems/json-2.21.1/lib/json/generic_object.rb | 67 + .../json-2.21.1/lib/json/truffle_ruby/generator.rb | 790 + .../3.4.0/gems/json-2.21.1/lib/json/version.rb | 5 + .../bundle/ruby/3.4.0/gems/kramdown-2.5.2/AUTHORS | 1 + .../ruby/3.4.0/gems/kramdown-2.5.2/CONTRIBUTERS | 93 + .../bundle/ruby/3.4.0/gems/kramdown-2.5.2/COPYING | 30 + .../ruby/3.4.0/gems/kramdown-2.5.2/README.md | 77 + .../bundle/ruby/3.4.0/gems/kramdown-2.5.2/VERSION | 1 + .../ruby/3.4.0/gems/kramdown-2.5.2/bin/kramdown | 135 + .../kramdown-2.5.2/data/kramdown/document.html | 22 + .../kramdown-2.5.2/data/kramdown/document.latex | 50 + .../ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown.rb | 10 + .../gems/kramdown-2.5.2/lib/kramdown/converter.rb | 68 + .../kramdown-2.5.2/lib/kramdown/converter/base.rb | 257 + .../lib/kramdown/converter/hash_ast.rb | 38 + .../kramdown-2.5.2/lib/kramdown/converter/html.rb | 545 + .../lib/kramdown/converter/kramdown.rb | 458 + .../kramdown-2.5.2/lib/kramdown/converter/latex.rb | 626 + .../kramdown-2.5.2/lib/kramdown/converter/man.rb | 300 + .../lib/kramdown/converter/math_engine/mathjax.rb | 32 + .../lib/kramdown/converter/remove_html_tags.rb | 58 + .../lib/kramdown/converter/syntax_highlighter.rb | 56 + .../converter/syntax_highlighter/minted.rb | 35 + .../kramdown/converter/syntax_highlighter/rouge.rb | 85 + .../kramdown-2.5.2/lib/kramdown/converter/toc.rb | 69 + .../gems/kramdown-2.5.2/lib/kramdown/document.rb | 139 + .../gems/kramdown-2.5.2/lib/kramdown/element.rb | 551 + .../gems/kramdown-2.5.2/lib/kramdown/error.rb | 17 + .../gems/kramdown-2.5.2/lib/kramdown/options.rb | 645 + .../gems/kramdown-2.5.2/lib/kramdown/parser.rb | 26 + .../kramdown-2.5.2/lib/kramdown/parser/base.rb | 137 + .../kramdown-2.5.2/lib/kramdown/parser/html.rb | 621 + .../kramdown-2.5.2/lib/kramdown/parser/kramdown.rb | 377 + .../lib/kramdown/parser/kramdown/abbreviation.rb | 80 + .../lib/kramdown/parser/kramdown/autolink.rb | 31 + .../lib/kramdown/parser/kramdown/blank_line.rb | 30 + .../lib/kramdown/parser/kramdown/block_boundary.rb | 34 + .../lib/kramdown/parser/kramdown/blockquote.rb | 38 + .../lib/kramdown/parser/kramdown/codeblock.rb | 57 + .../lib/kramdown/parser/kramdown/codespan.rb | 58 + .../lib/kramdown/parser/kramdown/emphasis.rb | 66 + .../lib/kramdown/parser/kramdown/eob.rb | 26 + .../lib/kramdown/parser/kramdown/escaped_chars.rb | 25 + .../lib/kramdown/parser/kramdown/extensions.rb | 214 + .../lib/kramdown/parser/kramdown/footnote.rb | 64 + .../lib/kramdown/parser/kramdown/header.rb | 70 + .../kramdown/parser/kramdown/horizontal_rule.rb | 27 + .../lib/kramdown/parser/kramdown/html.rb | 165 + .../lib/kramdown/parser/kramdown/html_entity.rb | 34 + .../lib/kramdown/parser/kramdown/line_break.rb | 25 + .../lib/kramdown/parser/kramdown/link.rb | 149 + .../lib/kramdown/parser/kramdown/list.rb | 286 + .../lib/kramdown/parser/kramdown/math.rb | 53 + .../lib/kramdown/parser/kramdown/paragraph.rb | 62 + .../lib/kramdown/parser/kramdown/smart_quotes.rb | 174 + .../lib/kramdown/parser/kramdown/table.rb | 171 + .../kramdown/parser/kramdown/typographic_symbol.rb | 44 + .../kramdown-2.5.2/lib/kramdown/parser/markdown.rb | 57 + .../gems/kramdown-2.5.2/lib/kramdown/utils.rb | 45 + .../lib/kramdown/utils/configurable.rb | 45 + .../kramdown-2.5.2/lib/kramdown/utils/entities.rb | 1000 + .../gems/kramdown-2.5.2/lib/kramdown/utils/html.rb | 84 + .../kramdown-2.5.2/lib/kramdown/utils/lru_cache.rb | 41 + .../lib/kramdown/utils/string_scanner.rb | 81 + .../lib/kramdown/utils/unidecoder.rb | 46 + .../gems/kramdown-2.5.2/lib/kramdown/version.rb | 15 + .../3.4.0/gems/kramdown-2.5.2/man/man1/kramdown.1 | 373 + .../3.4.0/gems/kramdown-2.5.2/test/run_tests.rb | 46 + .../3.4.0/gems/kramdown-2.5.2/test/test_files.rb | 313 + .../gems/kramdown-2.5.2/test/test_location.rb | 216 + .../test/test_string_scanner_kramdown.rb | 27 + .../test/testcases/block/01_blank_line/spaces.html | 1 + .../test/testcases/block/01_blank_line/spaces.text | 3 + .../test/testcases/block/01_blank_line/tabs.html | 1 + .../test/testcases/block/01_blank_line/tabs.text | 6 + .../test/testcases/block/02_eob/beginning.html | 1 + .../test/testcases/block/02_eob/beginning.text | 3 + .../test/testcases/block/02_eob/end.html | 1 + .../test/testcases/block/02_eob/end.text | 3 + .../test/testcases/block/02_eob/middle.html | 1 + .../test/testcases/block/02_eob/middle.text | 5 + .../testcases/block/03_paragraph/indented.html | 18 + .../testcases/block/03_paragraph/indented.html.gfm | 18 + .../testcases/block/03_paragraph/indented.text | 19 + .../block/03_paragraph/line_break_last_line.html | 9 + .../block/03_paragraph/line_break_last_line.text | 9 + .../block/03_paragraph/no_newline_at_end.html | 5 + .../block/03_paragraph/no_newline_at_end.text | 5 + .../testcases/block/03_paragraph/one_para.html | 1 + .../testcases/block/03_paragraph/one_para.text | 1 + .../block/03_paragraph/standalone_image.html | 13 + .../block/03_paragraph/standalone_image.text | 9 + .../block/03_paragraph/to_kramdown.kramdown | 7 + .../testcases/block/03_paragraph/to_kramdown.text | 5 + .../testcases/block/03_paragraph/two_para.html | 4 + .../testcases/block/03_paragraph/two_para.text | 4 + .../block/03_paragraph/with_html_to_native.html | 1 + .../block/03_paragraph/with_html_to_native.options | 1 + .../block/03_paragraph/with_html_to_native.text | 1 + .../test/testcases/block/04_header/atx_header.html | 57 + .../test/testcases/block/04_header/atx_header.text | 54 + .../04_header/atx_header_no_newline_at_end.html | 1 + .../04_header/atx_header_no_newline_at_end.text | 1 + .../block/04_header/header_type_offset.html | 11 + .../block/04_header/header_type_offset.kramdown | 12 + .../block/04_header/header_type_offset.latex | 12 + .../block/04_header/header_type_offset.options | 2 + .../block/04_header/header_type_offset.text | 13 + .../testcases/block/04_header/setext_header.html | 32 + .../testcases/block/04_header/setext_header.text | 39 + .../04_header/setext_header_no_newline_at_end.html | 1 + .../04_header/setext_header_no_newline_at_end.text | 2 + .../block/04_header/with_auto_id_prefix.html | 3 + .../block/04_header/with_auto_id_prefix.options | 2 + .../block/04_header/with_auto_id_prefix.text | 3 + .../block/04_header/with_auto_id_stripping.html | 1 + .../block/04_header/with_auto_id_stripping.options | 1 + .../block/04_header/with_auto_id_stripping.text | 1 + .../testcases/block/04_header/with_auto_ids.html | 21 + .../block/04_header/with_auto_ids.options | 2 + .../testcases/block/04_header/with_auto_ids.text | 24 + .../block/04_header/with_header_links.html | 7 + .../block/04_header/with_header_links.options | 2 + .../block/04_header/with_header_links.text | 8 + .../testcases/block/04_header/with_line_break.html | 1 + .../testcases/block/04_header/with_line_break.text | 1 + .../testcases/block/05_blockquote/indented.html | 25 + .../testcases/block/05_blockquote/indented.text | 14 + .../test/testcases/block/05_blockquote/lazy.html | 34 + .../test/testcases/block/05_blockquote/lazy.text | 20 + .../test/testcases/block/05_blockquote/nested.html | 10 + .../test/testcases/block/05_blockquote/nested.text | 6 + .../block/05_blockquote/no_newline_at_end.html | 4 + .../block/05_blockquote/no_newline_at_end.text | 2 + .../block/05_blockquote/very_long_line.html | 3 + .../block/05_blockquote/very_long_line.text | 1 + .../block/05_blockquote/with_code_blocks.html | 15 + .../block/05_blockquote/with_code_blocks.text | 11 + .../block/06_codeblock/disable-highlighting.html | 4 + .../06_codeblock/disable-highlighting.options | 1 + .../block/06_codeblock/disable-highlighting.text | 4 + .../test/testcases/block/06_codeblock/error.html | 4 + .../test/testcases/block/06_codeblock/error.text | 4 + .../block/06_codeblock/guess_lang_css_class.html | 15 + .../06_codeblock/guess_lang_css_class.options | 2 + .../block/06_codeblock/guess_lang_css_class.text | 13 + .../highlighting-minted-with-opts.latex | 9 + .../highlighting-minted-with-opts.options | 4 + .../highlighting-minted-with-opts.text | 5 + .../block/06_codeblock/highlighting-minted.latex | 8 + .../block/06_codeblock/highlighting-minted.options | 3 + .../block/06_codeblock/highlighting-minted.text | 4 + .../block/06_codeblock/highlighting-opts.html | 6 + .../block/06_codeblock/highlighting-opts.options | 7 + .../block/06_codeblock/highlighting-opts.text | 4 + .../testcases/block/06_codeblock/highlighting.html | 5 + .../block/06_codeblock/highlighting.options | 5 + .../testcases/block/06_codeblock/highlighting.text | 4 + .../testcases/block/06_codeblock/issue_gh45.html | 164 + .../testcases/block/06_codeblock/issue_gh45.test | 188 + .../test/testcases/block/06_codeblock/lazy.html | 4 + .../test/testcases/block/06_codeblock/lazy.text | 5 + .../block/06_codeblock/no_newline_at_end.html | 2 + .../block/06_codeblock/no_newline_at_end.text | 1 + .../block/06_codeblock/no_newline_at_end_1.html | 2 + .../block/06_codeblock/no_newline_at_end_1.text | 2 + .../test/testcases/block/06_codeblock/normal.html | 13 + .../test/testcases/block/06_codeblock/normal.text | 10 + .../block/06_codeblock/rouge/disabled.html | 2 + .../block/06_codeblock/rouge/disabled.options | 4 + .../block/06_codeblock/rouge/disabled.text | 1 + .../block/06_codeblock/rouge/multiple.html | 11 + .../block/06_codeblock/rouge/multiple.options | 4 + .../block/06_codeblock/rouge/multiple.text | 11 + .../testcases/block/06_codeblock/rouge/simple.html | 10 + .../block/06_codeblock/rouge/simple.options | 3 + .../testcases/block/06_codeblock/rouge/simple.text | 9 + .../testcases/block/06_codeblock/tilde_syntax.html | 7 + .../testcases/block/06_codeblock/tilde_syntax.text | 9 + .../testcases/block/06_codeblock/whitespace.html | 3 + .../testcases/block/06_codeblock/whitespace.text | 3 + .../block/06_codeblock/with_blank_line.html | 13 + .../block/06_codeblock/with_blank_line.text | 12 + .../block/06_codeblock/with_eob_marker.html | 6 + .../block/06_codeblock/with_eob_marker.text | 5 + .../testcases/block/06_codeblock/with_ial.html | 6 + .../testcases/block/06_codeblock/with_ial.text | 5 + .../06_codeblock/with_lang_in_fenced_block.html | 24 + .../06_codeblock/with_lang_in_fenced_block.options | 2 + .../06_codeblock/with_lang_in_fenced_block.text | 33 + .../with_lang_in_fenced_block_any_char.html | 8 + .../with_lang_in_fenced_block_any_char.options | 2 + .../with_lang_in_fenced_block_any_char.text | 11 + .../with_lang_in_fenced_block_name_with_dash.html | 3 + ...ith_lang_in_fenced_block_name_with_dash.options | 2 + .../with_lang_in_fenced_block_name_with_dash.text | 4 + .../testcases/block/07_horizontal_rule/error.html | 7 + .../testcases/block/07_horizontal_rule/error.text | 7 + .../testcases/block/07_horizontal_rule/normal.html | 19 + .../testcases/block/07_horizontal_rule/normal.text | 20 + .../block/07_horizontal_rule/sepspaces.html | 3 + .../block/07_horizontal_rule/sepspaces.text | 3 + .../block/07_horizontal_rule/septabs.html | 3 + .../block/07_horizontal_rule/septabs.text | 3 + .../testcases/block/08_list/brackets_in_item.latex | 3 + .../testcases/block/08_list/brackets_in_item.text | 1 + .../test/testcases/block/08_list/escaping.html | 21 + .../test/testcases/block/08_list/escaping.text | 21 + .../test/testcases/block/08_list/item_ial.html | 10 + .../test/testcases/block/08_list/item_ial.text | 8 + .../test/testcases/block/08_list/lazy.html | 39 + .../test/testcases/block/08_list/lazy.text | 29 + .../testcases/block/08_list/lazy_and_nested.html | 9 + .../testcases/block/08_list/lazy_and_nested.text | 4 + .../test/testcases/block/08_list/list_and_hr.html | 9 + .../test/testcases/block/08_list/list_and_hr.text | 5 + .../testcases/block/08_list/list_and_others.html | 40 + .../testcases/block/08_list/list_and_others.text | 26 + .../test/testcases/block/08_list/mixed.html | 117 + .../test/testcases/block/08_list/mixed.text | 66 + .../test/testcases/block/08_list/nested.html | 17 + .../test/testcases/block/08_list/nested.text | 7 + .../block/08_list/nested_compact.kramdown | 7 + .../testcases/block/08_list/nested_compact.text | 6 + .../block/08_list/other_first_element.html | 39 + .../block/08_list/other_first_element.text | 18 + .../test/testcases/block/08_list/simple_ol.html | 19 + .../test/testcases/block/08_list/simple_ol.text | 13 + .../test/testcases/block/08_list/simple_ul.html | 48 + .../test/testcases/block/08_list/simple_ul.text | 36 + .../test/testcases/block/08_list/single_item.html | 3 + .../test/testcases/block/08_list/single_item.text | 1 + .../testcases/block/08_list/special_cases.html | 72 + .../testcases/block/08_list/special_cases.text | 49 + .../testcases/block/09_html/cdata_section.html | 10 + .../testcases/block/09_html/cdata_section.text | 10 + .../test/testcases/block/09_html/comment.html | 18 + .../test/testcases/block/09_html/comment.text | 15 + .../block/09_html/content_model/deflists.html | 6 + .../block/09_html/content_model/deflists.options | 1 + .../block/09_html/content_model/deflists.text | 6 + .../block/09_html/content_model/tables.html | 14 + .../block/09_html/content_model/tables.options | 1 + .../block/09_html/content_model/tables.text | 14 + .../testcases/block/09_html/html5_attributes.html | 15 + .../testcases/block/09_html/html5_attributes.text | 15 + .../testcases/block/09_html/html_after_block.html | 7 + .../testcases/block/09_html/html_after_block.text | 5 + .../block/09_html/html_and_codeblocks.html | 15 + .../block/09_html/html_and_codeblocks.options | 1 + .../block/09_html/html_and_codeblocks.text | 13 + .../testcases/block/09_html/html_and_headers.html | 5 + .../testcases/block/09_html/html_and_headers.text | 6 + .../block/09_html/html_to_native/code.html | 10 + .../block/09_html/html_to_native/code.text | 9 + .../block/09_html/html_to_native/comment.html | 7 + .../block/09_html/html_to_native/comment.text | 8 + .../block/09_html/html_to_native/emphasis.html | 6 + .../block/09_html/html_to_native/emphasis.text | 6 + .../block/09_html/html_to_native/entity.html | 1 + .../block/09_html/html_to_native/entity.text | 1 + .../block/09_html/html_to_native/header.html | 6 + .../block/09_html/html_to_native/header.options | 2 + .../block/09_html/html_to_native/header.text | 6 + .../block/09_html/html_to_native/list_dl.html | 8 + .../block/09_html/html_to_native/list_dl.text | 8 + .../block/09_html/html_to_native/list_ol.html | 15 + .../block/09_html/html_to_native/list_ol.text | 17 + .../block/09_html/html_to_native/list_ul.html | 19 + .../block/09_html/html_to_native/list_ul.text | 22 + .../testcases/block/09_html/html_to_native/options | 1 + .../block/09_html/html_to_native/paragraph.html | 3 + .../block/09_html/html_to_native/paragraph.text | 4 + .../block/09_html/html_to_native/table_normal.html | 12 + .../block/09_html/html_to_native/table_normal.text | 12 + .../block/09_html/html_to_native/table_simple.html | 64 + .../block/09_html/html_to_native/table_simple.text | 74 + .../block/09_html/html_to_native/typography.html | 1 + .../block/09_html/html_to_native/typography.text | 1 + .../testcases/block/09_html/invalid_html_1.html | 5 + .../testcases/block/09_html/invalid_html_1.text | 5 + .../testcases/block/09_html/invalid_html_2.html | 5 + .../testcases/block/09_html/invalid_html_2.text | 5 + .../testcases/block/09_html/markdown_attr.html | 38 + .../testcases/block/09_html/markdown_attr.text | 38 + .../test/testcases/block/09_html/not_parsed.html | 24 + .../test/testcases/block/09_html/not_parsed.text | 24 + .../test/testcases/block/09_html/parse_as_raw.html | 35 + .../testcases/block/09_html/parse_as_raw.htmlinput | 34 + .../testcases/block/09_html/parse_as_raw.options | 1 + .../test/testcases/block/09_html/parse_as_raw.text | 33 + .../testcases/block/09_html/parse_as_span.html | 12 + .../block/09_html/parse_as_span.htmlinput | 12 + .../testcases/block/09_html/parse_as_span.options | 1 + .../testcases/block/09_html/parse_as_span.text | 9 + .../testcases/block/09_html/parse_block_html.html | 21 + .../block/09_html/parse_block_html.options | 1 + .../testcases/block/09_html/parse_block_html.text | 17 + .../block/09_html/processing_instruction.html | 12 + .../block/09_html/processing_instruction.text | 12 + .../test/testcases/block/09_html/simple.html | 60 + .../test/testcases/block/09_html/simple.options | 1 + .../test/testcases/block/09_html/simple.text | 55 + .../09_html/standalone_image_in_div.htmlinput | 7 + .../block/09_html/standalone_image_in_div.text | 8 + .../test/testcases/block/09_html/table.kramdown | 8 + .../test/testcases/block/09_html/table.text | 7 + .../test/testcases/block/09_html/textarea.html | 8 + .../test/testcases/block/09_html/textarea.text | 8 + .../test/testcases/block/09_html/xml.html | 8 + .../test/testcases/block/09_html/xml.text | 7 + .../test/testcases/block/10_ald/simple.html | 2 + .../test/testcases/block/10_ald/simple.text | 8 + .../testcases/block/11_ial/auto_id_and_ial.html | 1 + .../testcases/block/11_ial/auto_id_and_ial.options | 1 + .../testcases/block/11_ial/auto_id_and_ial.text | 2 + .../test/testcases/block/11_ial/nested.html | 11 + .../test/testcases/block/11_ial/nested.text | 15 + .../test/testcases/block/11_ial/simple.html | 29 + .../test/testcases/block/11_ial/simple.text | 41 + .../test/testcases/block/12_extension/comment.html | 8 + .../test/testcases/block/12_extension/comment.text | 12 + .../test/testcases/block/12_extension/ignored.html | 8 + .../test/testcases/block/12_extension/ignored.text | 8 + .../testcases/block/12_extension/nomarkdown.html | 10 + .../block/12_extension/nomarkdown.kramdown | 20 + .../testcases/block/12_extension/nomarkdown.latex | 13 + .../testcases/block/12_extension/nomarkdown.text | 21 + .../test/testcases/block/12_extension/options.html | 21 + .../test/testcases/block/12_extension/options.text | 23 + .../testcases/block/12_extension/options2.html | 10 + .../testcases/block/12_extension/options2.text | 5 + .../testcases/block/12_extension/options3.html | 8 + .../testcases/block/12_extension/options3.text | 7 + .../block/13_definition_list/auto_ids.html | 15 + .../block/13_definition_list/auto_ids.text | 18 + .../definition_at_beginning.html | 1 + .../definition_at_beginning.text | 1 + .../block/13_definition_list/deflist_ial.html | 4 + .../block/13_definition_list/deflist_ial.text | 4 + .../block/13_definition_list/item_ial.html | 17 + .../block/13_definition_list/item_ial.text | 16 + .../block/13_definition_list/multiple_terms.html | 13 + .../block/13_definition_list/multiple_terms.text | 10 + .../block/13_definition_list/no_def_list.html | 2 + .../block/13_definition_list/no_def_list.text | 2 + .../block/13_definition_list/para_wrapping.html | 10 + .../block/13_definition_list/para_wrapping.text | 6 + .../block/13_definition_list/separated_by_eob.html | 8 + .../block/13_definition_list/separated_by_eob.text | 5 + .../testcases/block/13_definition_list/simple.html | 10 + .../testcases/block/13_definition_list/simple.text | 10 + .../block/13_definition_list/styled_terms.html | 4 + .../block/13_definition_list/styled_terms.text | 2 + .../block/13_definition_list/too_much_space.html | 3 + .../block/13_definition_list/too_much_space.text | 4 + .../block/13_definition_list/with_blocks.html | 38 + .../block/13_definition_list/with_blocks.text | 24 + .../block/14_table/empty_tag_in_cell.html | 8 + .../block/14_table/empty_tag_in_cell.options | 1 + .../block/14_table/empty_tag_in_cell.text | 1 + .../test/testcases/block/14_table/errors.html | 12 + .../test/testcases/block/14_table/errors.text | 13 + .../test/testcases/block/14_table/escaping.html | 52 + .../test/testcases/block/14_table/escaping.text | 19 + .../test/testcases/block/14_table/footer.html | 65 + .../test/testcases/block/14_table/footer.text | 25 + .../test/testcases/block/14_table/header.html | 117 + .../test/testcases/block/14_table/header.text | 39 + .../test/testcases/block/14_table/no_table.html | 3 + .../test/testcases/block/14_table/no_table.text | 3 + .../test/testcases/block/14_table/simple.html | 192 + .../test/testcases/block/14_table/simple.text | 53 + .../block/14_table/table_with_footnote.html | 25 + .../block/14_table/table_with_footnote.latex | 11 + .../block/14_table/table_with_footnote.text | 6 + .../test/testcases/block/15_math/gh_128.html | 1 + .../test/testcases/block/15_math/gh_128.text | 1 + .../test/testcases/block/15_math/no_engine.html | 3 + .../test/testcases/block/15_math/no_engine.options | 1 + .../test/testcases/block/15_math/no_engine.text | 2 + .../test/testcases/block/15_math/normal.html | 30 + .../test/testcases/block/15_math/normal.text | 30 + .../test/testcases/block/16_toc/no_toc.html | 14 + .../test/testcases/block/16_toc/no_toc.text | 16 + .../test/testcases/block/16_toc/toc_exclude.html | 35 + .../testcases/block/16_toc/toc_exclude.options | 1 + .../test/testcases/block/16_toc/toc_exclude.text | 19 + .../test/testcases/block/16_toc/toc_levels.html | 24 + .../test/testcases/block/16_toc/toc_levels.options | 2 + .../test/testcases/block/16_toc/toc_levels.text | 16 + .../testcases/block/16_toc/toc_with_footnotes.html | 13 + .../block/16_toc/toc_with_footnotes.options | 1 + .../testcases/block/16_toc/toc_with_footnotes.text | 6 + .../testcases/block/16_toc/toc_with_links.html | 8 + .../testcases/block/16_toc/toc_with_links.options | 2 + .../testcases/block/16_toc/toc_with_links.text | 8 + .../test/testcases/cjk-line-break.html | 4 + .../test/testcases/cjk-line-break.options | 1 + .../test/testcases/cjk-line-break.text | 12 + .../kramdown-2.5.2/test/testcases/encoding.html | 46 + .../kramdown-2.5.2/test/testcases/encoding.text | 28 + .../kramdown-2.5.2/test/testcases/man/example.man | 123 + .../kramdown-2.5.2/test/testcases/man/example.text | 85 + .../man/heading-name-dash-description.man | 4 + .../man/heading-name-dash-description.text | 1 + .../testcases/man/heading-name-description.man | 4 + .../testcases/man/heading-name-description.text | 2 + .../man/heading-name-section-description.man | 4 + .../man/heading-name-section-description.text | 1 + .../test/testcases/man/heading-name-section.man | 2 + .../test/testcases/man/heading-name-section.text | 1 + .../test/testcases/man/heading-name.man | 2 + .../test/testcases/man/heading-name.text | 1 + .../kramdown-2.5.2/test/testcases/man/sections.man | 4 + .../test/testcases/man/sections.text | 11 + .../test/testcases/man/text-escaping.man | 8 + .../test/testcases/man/text-escaping.text | 7 + .../test/testcases/span/01_link/empty.html | 5 + .../test/testcases/span/01_link/empty.text | 5 + .../testcases/span/01_link/empty_title.htmlinput | 3 + .../test/testcases/span/01_link/empty_title.text | 7 + .../test/testcases/span/01_link/image_in_a.html | 5 + .../test/testcases/span/01_link/image_in_a.text | 5 + .../test/testcases/span/01_link/imagelinks.html | 15 + .../test/testcases/span/01_link/imagelinks.text | 18 + .../test/testcases/span/01_link/inline.html | 46 + .../test/testcases/span/01_link/inline.text | 48 + .../testcases/span/01_link/latex_escaping.latex | 6 + .../testcases/span/01_link/latex_escaping.text | 5 + .../test/testcases/span/01_link/link_defs.html | 9 + .../test/testcases/span/01_link/link_defs.text | 27 + .../testcases/span/01_link/link_defs_with_ial.html | 4 + .../testcases/span/01_link/link_defs_with_ial.text | 16 + .../span/01_link/links_with_angle_brackets.html | 3 + .../span/01_link/links_with_angle_brackets.text | 3 + .../test/testcases/span/01_link/reference.html | 37 + .../test/testcases/span/01_link/reference.options | 3 + .../test/testcases/span/01_link/reference.text | 53 + .../test/testcases/span/02_emphasis/empty.html | 3 + .../test/testcases/span/02_emphasis/empty.text | 3 + .../test/testcases/span/02_emphasis/errors.html | 9 + .../test/testcases/span/02_emphasis/errors.text | 9 + .../test/testcases/span/02_emphasis/nesting.html | 41 + .../test/testcases/span/02_emphasis/nesting.text | 36 + .../test/testcases/span/02_emphasis/normal.html | 70 + .../test/testcases/span/02_emphasis/normal.options | 1 + .../test/testcases/span/02_emphasis/normal.text | 68 + .../test/testcases/span/03_codespan/empty.html | 5 + .../test/testcases/span/03_codespan/empty.text | 5 + .../test/testcases/span/03_codespan/errors.html | 1 + .../test/testcases/span/03_codespan/errors.text | 1 + .../span/03_codespan/highlighting-minted.latex | 2 + .../span/03_codespan/highlighting-minted.options | 1 + .../span/03_codespan/highlighting-minted.text | 1 + .../testcases/span/03_codespan/highlighting.html | 1 + .../testcases/span/03_codespan/highlighting.text | 1 + .../span/03_codespan/normal-css-class.html | 1 + .../span/03_codespan/normal-css-class.options | 2 + .../span/03_codespan/normal-css-class.text | 1 + .../test/testcases/span/03_codespan/normal.html | 20 + .../test/testcases/span/03_codespan/normal.text | 20 + .../testcases/span/03_codespan/rouge/disabled.html | 1 + .../span/03_codespan/rouge/disabled.options | 4 + .../testcases/span/03_codespan/rouge/disabled.text | 1 + .../testcases/span/03_codespan/rouge/simple.html | 1 + .../span/03_codespan/rouge/simple.options | 1 + .../testcases/span/03_codespan/rouge/simple.text | 1 + .../span/04_footnote/backlink_inline.html | 79 + .../span/04_footnote/backlink_inline.options | 1 + .../span/04_footnote/backlink_inline.text | 38 + .../testcases/span/04_footnote/backlink_text.html | 9 + .../span/04_footnote/backlink_text.options | 1 + .../testcases/span/04_footnote/backlink_text.text | 3 + .../testcases/span/04_footnote/definitions.html | 17 + .../testcases/span/04_footnote/definitions.latex | 17 + .../testcases/span/04_footnote/definitions.text | 24 + .../span/04_footnote/footnote_link_text.html | 12 + .../span/04_footnote/footnote_link_text.options | 1 + .../span/04_footnote/footnote_link_text.text | 4 + .../testcases/span/04_footnote/footnote_nr.html | 12 + .../testcases/span/04_footnote/footnote_nr.latex | 2 + .../testcases/span/04_footnote/footnote_nr.options | 1 + .../testcases/span/04_footnote/footnote_nr.text | 4 + .../span/04_footnote/footnote_prefix.html | 12 + .../span/04_footnote/footnote_prefix.options | 1 + .../span/04_footnote/footnote_prefix.text | 4 + .../span/04_footnote/inside_footnote.html | 17 + .../span/04_footnote/inside_footnote.text | 9 + .../test/testcases/span/04_footnote/markers.html | 46 + .../test/testcases/span/04_footnote/markers.latex | 23 + .../testcases/span/04_footnote/markers.options | 2 + .../test/testcases/span/04_footnote/markers.text | 27 + .../test/testcases/span/04_footnote/placement.html | 11 + .../testcases/span/04_footnote/placement.options | 1 + .../test/testcases/span/04_footnote/placement.text | 8 + .../testcases/span/04_footnote/regexp_problem.html | 14 + .../span/04_footnote/regexp_problem.options | 2 + .../testcases/span/04_footnote/regexp_problem.text | 52 + .../span/04_footnote/without_backlink.html | 9 + .../span/04_footnote/without_backlink.options | 1 + .../span/04_footnote/without_backlink.text | 3 + .../test/testcases/span/05_html/across_lines.html | 1 + .../test/testcases/span/05_html/across_lines.text | 2 + .../test/testcases/span/05_html/button.html | 7 + .../test/testcases/span/05_html/button.text | 7 + .../test/testcases/span/05_html/invalid.html | 1 + .../test/testcases/span/05_html/invalid.text | 1 + .../testcases/span/05_html/link_with_mailto.html | 1 + .../testcases/span/05_html/link_with_mailto.text | 1 + .../test/testcases/span/05_html/mark_element.html | 3 + .../test/testcases/span/05_html/mark_element.text | 3 + .../test/testcases/span/05_html/markdown_attr.html | 6 + .../test/testcases/span/05_html/markdown_attr.text | 6 + .../test/testcases/span/05_html/normal.html | 43 + .../test/testcases/span/05_html/normal.text | 43 + .../testcases/span/05_html/raw_span_elements.html | 2 + .../testcases/span/05_html/raw_span_elements.text | 2 + .../test/testcases/span/05_html/xml.html | 5 + .../test/testcases/span/05_html/xml.text | 5 + .../test/testcases/span/abbreviations/abbrev.html | 25 + .../test/testcases/span/abbreviations/abbrev.text | 41 + .../testcases/span/abbreviations/abbrev_defs.html | 2 + .../testcases/span/abbreviations/abbrev_defs.text | 5 + .../span/abbreviations/abbrev_in_html.html | 9 + .../span/abbreviations/abbrev_in_html.text | 10 + .../testcases/span/abbreviations/in_footnote.html | 9 + .../testcases/span/abbreviations/in_footnote.text | 5 + .../test/testcases/span/autolinks/url_links.html | 15 + .../test/testcases/span/autolinks/url_links.text | 16 + .../test/testcases/span/escaped_chars/normal.html | 47 + .../test/testcases/span/escaped_chars/normal.text | 47 + .../test/testcases/span/extension/comment.html | 6 + .../test/testcases/span/extension/comment.text | 6 + .../test/testcases/span/extension/ignored.html | 1 + .../test/testcases/span/extension/ignored.text | 1 + .../test/testcases/span/extension/nomarkdown.html | 1 + .../test/testcases/span/extension/nomarkdown.text | 1 + .../test/testcases/span/extension/options.html | 1 + .../test/testcases/span/extension/options.text | 1 + .../test/testcases/span/ial/simple.html | 6 + .../test/testcases/span/ial/simple.text | 6 + .../test/testcases/span/line_breaks/normal.html | 11 + .../test/testcases/span/line_breaks/normal.latex | 12 + .../test/testcases/span/line_breaks/normal.text | 11 + .../test/testcases/span/math/no_engine.html | 1 + .../test/testcases/span/math/no_engine.options | 1 + .../test/testcases/span/math/no_engine.text | 1 + .../test/testcases/span/math/normal.html | 10 + .../test/testcases/span/math/normal.text | 10 + .../span/text_substitutions/entities.html | 6 + .../span/text_substitutions/entities.options | 1 + .../span/text_substitutions/entities.text | 6 + .../span/text_substitutions/entities_as_char.html | 1 + .../text_substitutions/entities_as_char.options | 2 + .../span/text_substitutions/entities_as_char.text | 1 + .../span/text_substitutions/entities_as_input.html | 1 + .../text_substitutions/entities_as_input.options | 1 + .../span/text_substitutions/entities_as_input.text | 1 + .../span/text_substitutions/entities_numeric.html | 1 + .../text_substitutions/entities_numeric.options | 1 + .../span/text_substitutions/entities_numeric.text | 1 + .../span/text_substitutions/entities_symbolic.html | 1 + .../text_substitutions/entities_symbolic.options | 1 + .../span/text_substitutions/entities_symbolic.text | 1 + .../span/text_substitutions/greaterthan.html | 1 + .../span/text_substitutions/greaterthan.text | 1 + .../span/text_substitutions/lowerthan.html | 1 + .../span/text_substitutions/lowerthan.text | 1 + .../span/text_substitutions/typography.html | 40 + .../span/text_substitutions/typography.options | 1 + .../span/text_substitutions/typography.text | 40 + .../span/text_substitutions/typography_subst.html | 3 + .../span/text_substitutions/typography_subst.latex | 4 + .../text_substitutions/typography_subst.options | 8 + .../span/text_substitutions/typography_subst.text | 3 + .../ruby/3.4.0/gems/listen-3.10.0/CHANGELOG.md | 1 + .../ruby/3.4.0/gems/listen-3.10.0/CONTRIBUTING.md | 45 + .../ruby/3.4.0/gems/listen-3.10.0/LICENSE.txt | 22 + .../bundle/ruby/3.4.0/gems/listen-3.10.0/README.md | 490 + .../ruby/3.4.0/gems/listen-3.10.0/bin/listen | 11 + .../ruby/3.4.0/gems/listen-3.10.0/lib/listen.rb | 47 + .../3.4.0/gems/listen-3.10.0/lib/listen/adapter.rb | 43 + .../gems/listen-3.10.0/lib/listen/adapter/base.rb | 129 + .../gems/listen-3.10.0/lib/listen/adapter/bsd.rb | 104 + .../listen-3.10.0/lib/listen/adapter/config.rb | 31 + .../listen-3.10.0/lib/listen/adapter/darwin.rb | 77 + .../gems/listen-3.10.0/lib/listen/adapter/linux.rb | 108 + .../listen-3.10.0/lib/listen/adapter/polling.rb | 40 + .../listen-3.10.0/lib/listen/adapter/windows.rb | 96 + .../3.4.0/gems/listen-3.10.0/lib/listen/backend.rb | 40 + .../3.4.0/gems/listen-3.10.0/lib/listen/change.rb | 69 + .../3.4.0/gems/listen-3.10.0/lib/listen/cli.rb | 65 + .../gems/listen-3.10.0/lib/listen/directory.rb | 93 + .../3.4.0/gems/listen-3.10.0/lib/listen/error.rb | 11 + .../gems/listen-3.10.0/lib/listen/event/config.rb | 39 + .../gems/listen-3.10.0/lib/listen/event/loop.rb | 92 + .../listen-3.10.0/lib/listen/event/processor.rb | 128 + .../gems/listen-3.10.0/lib/listen/event/queue.rb | 52 + .../3.4.0/gems/listen-3.10.0/lib/listen/file.rb | 95 + .../3.4.0/gems/listen-3.10.0/lib/listen/fsm.rb | 131 + .../gems/listen-3.10.0/lib/listen/listener.rb | 136 + .../listen-3.10.0/lib/listen/listener/config.rb | 41 + .../3.4.0/gems/listen-3.10.0/lib/listen/logger.rb | 65 + .../listen-3.10.0/lib/listen/monotonic_time.rb | 27 + .../3.4.0/gems/listen-3.10.0/lib/listen/options.rb | 24 + .../listen-3.10.0/lib/listen/queue_optimizer.rb | 129 + .../3.4.0/gems/listen-3.10.0/lib/listen/record.rb | 122 + .../gems/listen-3.10.0/lib/listen/record/entry.rb | 66 + .../lib/listen/record/symlink_detector.rb | 47 + .../gems/listen-3.10.0/lib/listen/silencer.rb | 106 + .../lib/listen/silencer/controller.rb | 50 + .../3.4.0/gems/listen-3.10.0/lib/listen/thread.rb | 54 + .../3.4.0/gems/listen-3.10.0/lib/listen/version.rb | 5 + .../bundle/ruby/3.4.0/gems/logger-1.7.0/.document | 4 + .../ruby/3.4.0/gems/logger-1.7.0/.rdoc_options | 3 + vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL | 22 + vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING | 56 + .../bundle/ruby/3.4.0/gems/logger-1.7.0/README.md | 104 + .../ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb | 789 + .../3.4.0/gems/logger-1.7.0/lib/logger/errors.rb | 9 + .../gems/logger-1.7.0/lib/logger/formatter.rb | 36 + .../gems/logger-1.7.0/lib/logger/log_device.rb | 265 + .../3.4.0/gems/logger-1.7.0/lib/logger/period.rb | 47 + .../3.4.0/gems/logger-1.7.0/lib/logger/severity.rb | 38 + .../3.4.0/gems/logger-1.7.0/lib/logger/version.rb | 5 + .../ruby/3.4.0/gems/public_suffix-7.0.5/.yardopts | 1 + .../3.4.0/gems/public_suffix-7.0.5/CHANGELOG.md | 649 + .../ruby/3.4.0/gems/public_suffix-7.0.5/Gemfile | 16 + .../3.4.0/gems/public_suffix-7.0.5/LICENSE.txt | 22 + .../ruby/3.4.0/gems/public_suffix-7.0.5/README.md | 231 + .../3.4.0/gems/public_suffix-7.0.5/SECURITY.md | 24 + .../3.4.0/gems/public_suffix-7.0.5/data/list.txt | 16298 +++++++++++++++++ .../gems/public_suffix-7.0.5/lib/public_suffix.rb | 177 + .../lib/public_suffix/domain.rb | 235 + .../lib/public_suffix/errors.rb | 41 + .../public_suffix-7.0.5/lib/public_suffix/list.rb | 247 + .../public_suffix-7.0.5/lib/public_suffix/rule.rb | 350 + .../lib/public_suffix/version.rb | 14 + .../ruby/3.4.0/gems/rake-13.4.2/History.rdoc | 2454 +++ .../bundle/ruby/3.4.0/gems/rake-13.4.2/MIT-LICENSE | 21 + .../bundle/ruby/3.4.0/gems/rake-13.4.2/README.rdoc | 155 + .../gems/rake-13.4.2/doc/command_line_usage.rdoc | 171 + .../3.4.0/gems/rake-13.4.2/doc/example/Rakefile1 | 38 + .../3.4.0/gems/rake-13.4.2/doc/example/Rakefile2 | 35 + .../ruby/3.4.0/gems/rake-13.4.2/doc/example/a.c | 6 + .../ruby/3.4.0/gems/rake-13.4.2/doc/example/b.c | 6 + .../ruby/3.4.0/gems/rake-13.4.2/doc/example/main.c | 11 + .../ruby/3.4.0/gems/rake-13.4.2/doc/glossary.rdoc | 42 + .../ruby/3.4.0/gems/rake-13.4.2/doc/jamis.rb | 592 + .../3.4.0/gems/rake-13.4.2/doc/proto_rake.rdoc | 127 + .../bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rake.1 | 156 + .../ruby/3.4.0/gems/rake-13.4.2/doc/rakefile.rdoc | 635 + .../ruby/3.4.0/gems/rake-13.4.2/doc/rational.rdoc | 151 + vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake | 27 + .../bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake.rb | 69 + .../3.4.0/gems/rake-13.4.2/lib/rake/application.rb | 847 + .../3.4.0/gems/rake-13.4.2/lib/rake/backtrace.rb | 25 + .../ruby/3.4.0/gems/rake-13.4.2/lib/rake/clean.rb | 78 + .../3.4.0/gems/rake-13.4.2/lib/rake/cloneable.rb | 17 + .../3.4.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb | 122 + .../gems/rake-13.4.2/lib/rake/default_loader.rb | 15 + .../gems/rake-13.4.2/lib/rake/dsl_definition.rb | 196 + .../3.4.0/gems/rake-13.4.2/lib/rake/early_time.rb | 22 + .../3.4.0/gems/rake-13.4.2/lib/rake/ext/core.rb | 26 + .../3.4.0/gems/rake-13.4.2/lib/rake/ext/string.rb | 176 + .../rake-13.4.2/lib/rake/file_creation_task.rb | 25 + .../3.4.0/gems/rake-13.4.2/lib/rake/file_list.rb | 435 + .../3.4.0/gems/rake-13.4.2/lib/rake/file_task.rb | 58 + .../3.4.0/gems/rake-13.4.2/lib/rake/file_utils.rb | 137 + .../gems/rake-13.4.2/lib/rake/file_utils_ext.rb | 135 + .../gems/rake-13.4.2/lib/rake/invocation_chain.rb | 57 + .../lib/rake/invocation_exception_mixin.rb | 17 + .../3.4.0/gems/rake-13.4.2/lib/rake/late_time.rb | 18 + .../3.4.0/gems/rake-13.4.2/lib/rake/linked_list.rb | 112 + .../gems/rake-13.4.2/lib/rake/loaders/makefile.rb | 54 + .../3.4.0/gems/rake-13.4.2/lib/rake/multi_task.rb | 14 + .../3.4.0/gems/rake-13.4.2/lib/rake/name_space.rb | 38 + .../3.4.0/gems/rake-13.4.2/lib/rake/options.rb | 31 + .../3.4.0/gems/rake-13.4.2/lib/rake/packagetask.rb | 222 + .../ruby/3.4.0/gems/rake-13.4.2/lib/rake/phony.rb | 16 + .../gems/rake-13.4.2/lib/rake/private_reader.rb | 21 + .../3.4.0/gems/rake-13.4.2/lib/rake/promise.rb | 100 + .../gems/rake-13.4.2/lib/rake/pseudo_status.rb | 30 + .../3.4.0/gems/rake-13.4.2/lib/rake/rake_module.rb | 67 + .../gems/rake-13.4.2/lib/rake/rake_test_loader.rb | 27 + .../lib/rake/rule_recursion_overflow_error.rb | 20 + .../ruby/3.4.0/gems/rake-13.4.2/lib/rake/scope.rb | 43 + .../ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb | 434 + .../rake-13.4.2/lib/rake/task_argument_error.rb | 8 + .../gems/rake-13.4.2/lib/rake/task_arguments.rb | 113 + .../gems/rake-13.4.2/lib/rake/task_manager.rb | 333 + .../3.4.0/gems/rake-13.4.2/lib/rake/tasklib.rb | 12 + .../3.4.0/gems/rake-13.4.2/lib/rake/testtask.rb | 192 + .../rake-13.4.2/lib/rake/thread_history_display.rb | 49 + .../3.4.0/gems/rake-13.4.2/lib/rake/thread_pool.rb | 157 + .../gems/rake-13.4.2/lib/rake/trace_output.rb | 23 + .../3.4.0/gems/rake-13.4.2/lib/rake/version.rb | 10 + .../ruby/3.4.0/gems/rake-13.4.2/lib/rake/win32.rb | 17 + .../ruby/3.4.0/gems/rake-13.4.2/rake.gemspec | 102 + .../bundle/ruby/3.4.0/gems/rexml-3.4.4/LICENSE.txt | 22 + vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/NEWS.md | 843 + .../bundle/ruby/3.4.0/gems/rexml-3.4.4/README.md | 57 + .../3.4.0/gems/rexml-3.4.4/doc/rexml/context.rdoc | 143 + .../rexml-3.4.4/doc/rexml/tasks/rdoc/child.rdoc | 87 + .../rexml-3.4.4/doc/rexml/tasks/rdoc/document.rdoc | 276 + .../rexml-3.4.4/doc/rexml/tasks/rdoc/element.rdoc | 602 + .../rexml-3.4.4/doc/rexml/tasks/rdoc/node.rdoc | 97 + .../rexml-3.4.4/doc/rexml/tasks/rdoc/parent.rdoc | 267 + .../doc/rexml/tasks/tocs/child_toc.rdoc | 12 + .../doc/rexml/tasks/tocs/document_toc.rdoc | 30 + .../doc/rexml/tasks/tocs/element_toc.rdoc | 55 + .../doc/rexml/tasks/tocs/master_toc.rdoc | 135 + .../rexml-3.4.4/doc/rexml/tasks/tocs/node_toc.rdoc | 16 + .../doc/rexml/tasks/tocs/parent_toc.rdoc | 25 + .../3.4.0/gems/rexml-3.4.4/doc/rexml/tutorial.rdoc | 1358 ++ .../ruby/3.4.0/gems/rexml-3.4.4/lib/rexml.rb | 3 + .../gems/rexml-3.4.4/lib/rexml/attlistdecl.rb | 63 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/attribute.rb | 210 + .../ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/cdata.rb | 68 + .../ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/child.rb | 96 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/comment.rb | 80 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/doctype.rb | 306 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/document.rb | 471 + .../gems/rexml-3.4.4/lib/rexml/dtd/attlistdecl.rb | 11 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/dtd.rb | 47 + .../gems/rexml-3.4.4/lib/rexml/dtd/elementdecl.rb | 18 + .../gems/rexml-3.4.4/lib/rexml/dtd/entitydecl.rb | 57 + .../gems/rexml-3.4.4/lib/rexml/dtd/notationdecl.rb | 40 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/element.rb | 2578 +++ .../3.4.0/gems/rexml-3.4.4/lib/rexml/encoding.rb | 48 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/entity.rb | 142 + .../rexml-3.4.4/lib/rexml/formatters/default.rb | 116 + .../rexml-3.4.4/lib/rexml/formatters/pretty.rb | 142 + .../rexml-3.4.4/lib/rexml/formatters/transitive.rb | 58 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/functions.rb | 446 + .../gems/rexml-3.4.4/lib/rexml/instruction.rb | 79 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/light/node.rb | 188 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/namespace.rb | 63 + .../ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/node.rb | 80 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/output.rb | 30 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/parent.rb | 166 + .../gems/rexml-3.4.4/lib/rexml/parseexception.rb | 53 + .../rexml-3.4.4/lib/rexml/parsers/baseparser.rb | 949 + .../rexml-3.4.4/lib/rexml/parsers/lightparser.rb | 59 + .../rexml-3.4.4/lib/rexml/parsers/pullparser.rb | 213 + .../rexml-3.4.4/lib/rexml/parsers/sax2parser.rb | 270 + .../rexml-3.4.4/lib/rexml/parsers/streamparser.rb | 67 + .../rexml-3.4.4/lib/rexml/parsers/treeparser.rb | 89 + .../lib/rexml/parsers/ultralightparser.rb | 57 + .../rexml-3.4.4/lib/rexml/parsers/xpathparser.rb | 739 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/quickpath.rb | 267 + .../ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/rexml.rb | 39 + .../gems/rexml-3.4.4/lib/rexml/sax2listener.rb | 98 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/security.rb | 28 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/source.rb | 388 + .../gems/rexml-3.4.4/lib/rexml/streamlistener.rb | 93 + .../ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/text.rb | 420 + .../lib/rexml/undefinednamespaceexception.rb | 9 + .../rexml-3.4.4/lib/rexml/validation/relaxng.rb | 540 + .../rexml-3.4.4/lib/rexml/validation/validation.rb | 144 + .../lib/rexml/validation/validationexception.rb | 10 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/xmldecl.rb | 130 + .../3.4.0/gems/rexml-3.4.4/lib/rexml/xmltokens.rb | 85 + .../ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath.rb | 70 + .../gems/rexml-3.4.4/lib/rexml/xpath_parser.rb | 980 + vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/Gemfile | 41 + vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/LICENSE | 187 + .../bundle/ruby/3.4.0/gems/rouge-4.7.0/bin/rougify | 18 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge.rb | 106 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/cli.rb | 530 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/abap | 6 + .../gems/rouge-4.7.0/lib/rouge/demos/actionscript | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ada | 26 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apache | 21 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apex | 9 + .../gems/rouge-4.7.0/lib/rouge/demos/apiblueprint | 33 + .../gems/rouge-4.7.0/lib/rouge/demos/applescript | 2 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/armasm | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/augeas | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/awk | 4 + .../gems/rouge-4.7.0/lib/rouge/demos/batchfile | 3 + .../gems/rouge-4.7.0/lib/rouge/demos/bbcbasic | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bibtex | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bicep | 10 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/biml | 38 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bpf | 7 + .../gems/rouge-4.7.0/lib/rouge/demos/brainfuck | 5 + .../gems/rouge-4.7.0/lib/rouge/demos/brightscript | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bsl | 7 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/c | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ceylon | 7 + .../gems/rouge-4.7.0/lib/rouge/demos/cfscript | 18 + .../gems/rouge-4.7.0/lib/rouge/demos/cisco_ios | 19 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clean | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clojure | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmake | 7 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmhg | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cobol | 103 + .../gems/rouge-4.7.0/lib/rouge/demos/codeowners | 6 + .../gems/rouge-4.7.0/lib/rouge/demos/coffeescript | 5 + .../gems/rouge-4.7.0/lib/rouge/demos/common_lisp | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/conf | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/console | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coq | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cpp | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/crystal | 45 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csharp | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/css | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csvs | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cuda | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cypher | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cython | 6 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/d | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dafny | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dart | 6 + .../gems/rouge-4.7.0/lib/rouge/demos/datastudio | 20 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/diff | 7 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/digdag | 19 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/docker | 9 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dot | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ecl | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eex | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eiffel | 30 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elixir | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elm | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/email | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/epp | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erb | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erlang | 7 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/escape | 3 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/factor | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fluent | 13 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fortran | 22 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/freefem | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fsharp | 12 + .../gems/rouge-4.7.0/lib/rouge/demos/gdscript | 18 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-cmm | 23 + .../gems/rouge-4.7.0/lib/rouge/demos/ghc-core | 26 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gherkin | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gjs | 23 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/glsl | 14 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/go | 7 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gradle | 10 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/graphql | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/groovy | 9 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gts | 36 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hack | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/haml | 5 + .../gems/rouge-4.7.0/lib/rouge/demos/handlebars | 7 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/haskell | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/haxe | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hcl | 7 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hlsl | 20 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hocon | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hql | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/html | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/http | 14 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hylang | 10 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/idlang | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/idris | 13 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/iecst | 21 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/igorpro | 9 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ini | 4 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/io | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/irb | 4 + .../gems/rouge-4.7.0/lib/rouge/demos/irb_output | 2 + .../gems/rouge-4.7.0/lib/rouge/demos/isabelle | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/isbl | 4 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/j | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/janet | 3 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/java | 5 + .../gems/rouge-4.7.0/lib/rouge/demos/javascript | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jinja | 9 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsl | 3 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/json | 1 + .../gems/rouge-4.7.0/lib/rouge/demos/json-doc | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/json5 | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsonnet | 28 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsp | 29 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsx | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/julia | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/kotlin | 3 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lasso | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lean | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/liquid | 10 + .../lib/rouge/demos/literate_coffeescript | 3 + .../rouge-4.7.0/lib/rouge/demos/literate_haskell | 7 + .../gems/rouge-4.7.0/lib/rouge/demos/livescript | 15 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/llvm | 20 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lua | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lustre | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lutin | 18 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/m68k | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/magik | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/make | 6 + .../gems/rouge-4.7.0/lib/rouge/demos/markdown | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mason | 22 + .../gems/rouge-4.7.0/lib/rouge/demos/mathematica | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/matlab | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/meson | 10 + .../gems/rouge-4.7.0/lib/rouge/demos/minizinc | 23 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mojo | 10 + .../gems/rouge-4.7.0/lib/rouge/demos/moonscript | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mosel | 10 + .../gems/rouge-4.7.0/lib/rouge/demos/msgtrans | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mxml | 22 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nasm | 26 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nesasm | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nginx | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nial | 35 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nim | 27 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nix | 19 + .../gems/rouge-4.7.0/lib/rouge/demos/objective_c | 18 + .../gems/rouge-4.7.0/lib/rouge/demos/objective_cpp | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ocaml | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ocl | 4 + .../gems/rouge-4.7.0/lib/rouge/demos/openedge | 4 + .../lib/rouge/demos/opentype_feature_file | 5 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/p4 | 99 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/pascal | 14 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/perl | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/php | 3 + .../gems/rouge-4.7.0/lib/rouge/demos/plaintext | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/plist | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/plsql | 2 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/pony | 17 + .../gems/rouge-4.7.0/lib/rouge/demos/postscript | 9 + .../gems/rouge-4.7.0/lib/rouge/demos/powershell | 13 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/praat | 26 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/prolog | 9 + .../gems/rouge-4.7.0/lib/rouge/demos/prometheus | 9 + .../gems/rouge-4.7.0/lib/rouge/demos/properties | 7 + .../gems/rouge-4.7.0/lib/rouge/demos/protobuf | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/puppet | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/python | 6 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/q | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/qml | 9 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/r | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/racket | 24 + .../gems/rouge-4.7.0/lib/rouge/demos/reasonml | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rego | 8 + .../gems/rouge-4.7.0/lib/rouge/demos/rescript | 26 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rml | 33 + .../rouge-4.7.0/lib/rouge/demos/robot_framework | 27 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ruby | 9 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rust | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sas | 13 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sass | 3 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scala | 3 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scheme | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scss | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sed | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/shell | 2 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sieve | 10 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slice | 10 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slim | 17 + .../gems/rouge-4.7.0/lib/rouge/demos/smalltalk | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smarty | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sml | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sparql | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sqf | 14 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sql | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ssh | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stan | 13 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stata | 14 + .../gems/rouge-4.7.0/lib/rouge/demos/supercollider | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/svelte | 29 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/swift | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/systemd | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzlang | 15 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzprog | 8 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tap | 5 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tcl | 1 + .../gems/rouge-4.7.0/lib/rouge/demos/terraform | 16 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tex | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/toml | 9 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tsx | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ttcn3 | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tulip | 13 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/turtle | 26 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/twig | 9 + .../gems/rouge-4.7.0/lib/rouge/demos/typescript | 1 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vala | 8 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vb | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vcl | 12 + .../gems/rouge-4.7.0/lib/rouge/demos/velocity | 9 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/verilog | 27 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vhdl | 23 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/viml | 14 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vue | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/wollok | 11 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xml | 2 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xojo | 14 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xpath | 2 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xquery | 22 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yaml | 4 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yang | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/demos/zig | 6 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/formatter.rb | 112 + .../gems/rouge-4.7.0/lib/rouge/formatters/html.rb | 57 + .../lib/rouge/formatters/html_inline.rb | 30 + .../lib/rouge/formatters/html_legacy.rb | 42 + .../lib/rouge/formatters/html_line_highlighter.rb | 24 + .../lib/rouge/formatters/html_line_table.rb | 51 + .../lib/rouge/formatters/html_linewise.rb | 22 + .../lib/rouge/formatters/html_pygments.rb | 18 + .../rouge-4.7.0/lib/rouge/formatters/html_table.rb | 51 + .../gems/rouge-4.7.0/lib/rouge/formatters/null.rb | 20 + .../lib/rouge/formatters/terminal256.rb | 198 + .../lib/rouge/formatters/terminal_truecolor.rb | 37 + .../gems/rouge-4.7.0/lib/rouge/formatters/tex.rb | 92 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/guesser.rb | 57 + .../lib/rouge/guessers/disambiguation.rb | 172 + .../rouge-4.7.0/lib/rouge/guessers/filename.rb | 27 + .../rouge-4.7.0/lib/rouge/guessers/glob_mapping.rb | 45 + .../rouge-4.7.0/lib/rouge/guessers/mimetype.rb | 16 + .../rouge-4.7.0/lib/rouge/guessers/modeline.rb | 46 + .../gems/rouge-4.7.0/lib/rouge/guessers/source.rb | 31 + .../gems/rouge-4.7.0/lib/rouge/guessers/util.rb | 34 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexer.rb | 537 + .../gems/rouge-4.7.0/lib/rouge/lexers/abap.rb | 240 + .../rouge-4.7.0/lib/rouge/lexers/actionscript.rb | 196 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ada.rb | 162 + .../gems/rouge-4.7.0/lib/rouge/lexers/apache.rb | 83 + .../lib/rouge/lexers/apache/keywords.rb | 24 + .../gems/rouge-4.7.0/lib/rouge/lexers/apex.rb | 128 + .../rouge-4.7.0/lib/rouge/lexers/apiblueprint.rb | 49 + .../rouge-4.7.0/lib/rouge/lexers/apple_script.rb | 370 + .../gems/rouge-4.7.0/lib/rouge/lexers/armasm.rb | 145 + .../gems/rouge-4.7.0/lib/rouge/lexers/augeas.rb | 93 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/awk.rb | 162 + .../gems/rouge-4.7.0/lib/rouge/lexers/batchfile.rb | 165 + .../gems/rouge-4.7.0/lib/rouge/lexers/bbcbasic.rb | 112 + .../gems/rouge-4.7.0/lib/rouge/lexers/bibtex.rb | 115 + .../gems/rouge-4.7.0/lib/rouge/lexers/bicep.rb | 111 + .../gems/rouge-4.7.0/lib/rouge/lexers/biml.rb | 43 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bpf.rb | 118 + .../gems/rouge-4.7.0/lib/rouge/lexers/brainfuck.rb | 54 + .../rouge-4.7.0/lib/rouge/lexers/brightscript.rb | 147 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bsl.rb | 82 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/c.rb | 200 + .../gems/rouge-4.7.0/lib/rouge/lexers/ceylon.rb | 96 + .../gems/rouge-4.7.0/lib/rouge/lexers/cfscript.rb | 154 + .../gems/rouge-4.7.0/lib/rouge/lexers/cisco_ios.rb | 83 + .../gems/rouge-4.7.0/lib/rouge/lexers/clean.rb | 156 + .../gems/rouge-4.7.0/lib/rouge/lexers/clojure.rb | 113 + .../gems/rouge-4.7.0/lib/rouge/lexers/cmake.rb | 218 + .../gems/rouge-4.7.0/lib/rouge/lexers/cmhg.rb | 34 + .../gems/rouge-4.7.0/lib/rouge/lexers/cobol.rb | 137 + .../rouge-4.7.0/lib/rouge/lexers/codeowners.rb | 30 + .../rouge-4.7.0/lib/rouge/lexers/coffeescript.rb | 215 + .../rouge-4.7.0/lib/rouge/lexers/common_lisp.rb | 346 + .../gems/rouge-4.7.0/lib/rouge/lexers/conf.rb | 25 + .../gems/rouge-4.7.0/lib/rouge/lexers/console.rb | 190 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/coq.rb | 255 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cpp.rb | 104 + .../gems/rouge-4.7.0/lib/rouge/lexers/crystal.rb | 435 + .../gems/rouge-4.7.0/lib/rouge/lexers/csharp.rb | 118 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/css.rb | 318 + .../gems/rouge-4.7.0/lib/rouge/lexers/csvs.rb | 44 + .../gems/rouge-4.7.0/lib/rouge/lexers/cuda.rb | 35 + .../gems/rouge-4.7.0/lib/rouge/lexers/cypher.rb | 116 + .../gems/rouge-4.7.0/lib/rouge/lexers/cython.rb | 151 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/d.rb | 177 + .../gems/rouge-4.7.0/lib/rouge/lexers/dafny.rb | 128 + .../gems/rouge-4.7.0/lib/rouge/lexers/dart.rb | 106 + .../rouge-4.7.0/lib/rouge/lexers/datastudio.rb | 138 + .../gems/rouge-4.7.0/lib/rouge/lexers/diff.rb | 47 + .../gems/rouge-4.7.0/lib/rouge/lexers/digdag.rb | 70 + .../gems/rouge-4.7.0/lib/rouge/lexers/docker.rb | 55 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/dot.rb | 70 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ecl.rb | 175 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/eex.rb | 52 + .../gems/rouge-4.7.0/lib/rouge/lexers/eiffel.rb | 65 + .../gems/rouge-4.7.0/lib/rouge/lexers/elixir.rb | 153 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/elm.rb | 90 + .../gems/rouge-4.7.0/lib/rouge/lexers/email.rb | 39 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/epp.rb | 51 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/erb.rb | 53 + .../gems/rouge-4.7.0/lib/rouge/lexers/erlang.rb | 115 + .../gems/rouge-4.7.0/lib/rouge/lexers/escape.rb | 58 + .../gems/rouge-4.7.0/lib/rouge/lexers/factor.rb | 303 + .../gems/rouge-4.7.0/lib/rouge/lexers/fluent.rb | 74 + .../gems/rouge-4.7.0/lib/rouge/lexers/fortran.rb | 178 + .../gems/rouge-4.7.0/lib/rouge/lexers/freefem.rb | 240 + .../gems/rouge-4.7.0/lib/rouge/lexers/fsharp.rb | 120 + .../gems/rouge-4.7.0/lib/rouge/lexers/gdscript.rb | 171 + .../gems/rouge-4.7.0/lib/rouge/lexers/ghc_cmm.rb | 340 + .../gems/rouge-4.7.0/lib/rouge/lexers/ghc_core.rb | 152 + .../gems/rouge-4.7.0/lib/rouge/lexers/gherkin.rb | 140 + .../lib/rouge/lexers/gherkin/keywords.rb | 19 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gjs.rb | 39 + .../gems/rouge-4.7.0/lib/rouge/lexers/glsl.rb | 132 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/go.rb | 177 + .../gems/rouge-4.7.0/lib/rouge/lexers/gradle.rb | 38 + .../gems/rouge-4.7.0/lib/rouge/lexers/graphql.rb | 261 + .../gems/rouge-4.7.0/lib/rouge/lexers/groovy.rb | 113 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gts.rb | 39 + .../gems/rouge-4.7.0/lib/rouge/lexers/hack.rb | 49 + .../gems/rouge-4.7.0/lib/rouge/lexers/haml.rb | 226 + .../rouge-4.7.0/lib/rouge/lexers/handlebars.rb | 91 + .../gems/rouge-4.7.0/lib/rouge/lexers/haskell.rb | 207 + .../gems/rouge-4.7.0/lib/rouge/lexers/haxe.rb | 265 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hcl.rb | 166 + .../gems/rouge-4.7.0/lib/rouge/lexers/hlsl.rb | 166 + .../gems/rouge-4.7.0/lib/rouge/lexers/hocon.rb | 86 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hql.rb | 139 + .../gems/rouge-4.7.0/lib/rouge/lexers/html.rb | 141 + .../gems/rouge-4.7.0/lib/rouge/lexers/http.rb | 87 + .../gems/rouge-4.7.0/lib/rouge/lexers/hylang.rb | 93 + .../gems/rouge-4.7.0/lib/rouge/lexers/idlang.rb | 312 + .../gems/rouge-4.7.0/lib/rouge/lexers/idris.rb | 210 + .../gems/rouge-4.7.0/lib/rouge/lexers/iecst.rb | 92 + .../gems/rouge-4.7.0/lib/rouge/lexers/igorpro.rb | 664 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ini.rb | 56 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/io.rb | 69 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/irb.rb | 73 + .../gems/rouge-4.7.0/lib/rouge/lexers/isabelle.rb | 251 + .../gems/rouge-4.7.0/lib/rouge/lexers/isbl.rb | 97 + .../rouge-4.7.0/lib/rouge/lexers/isbl/builtins.rb | 17 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/j.rb | 244 + .../gems/rouge-4.7.0/lib/rouge/lexers/janet.rb | 218 + .../gems/rouge-4.7.0/lib/rouge/lexers/java.rb | 92 + .../rouge-4.7.0/lib/rouge/lexers/javascript.rb | 315 + .../gems/rouge-4.7.0/lib/rouge/lexers/jinja.rb | 169 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jsl.rb | 66 + .../gems/rouge-4.7.0/lib/rouge/lexers/json.rb | 72 + .../gems/rouge-4.7.0/lib/rouge/lexers/json5.rb | 74 + .../gems/rouge-4.7.0/lib/rouge/lexers/json_doc.rb | 26 + .../gems/rouge-4.7.0/lib/rouge/lexers/jsonnet.rb | 153 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jsp.rb | 119 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jsx.rb | 91 + .../gems/rouge-4.7.0/lib/rouge/lexers/julia.rb | 293 + .../gems/rouge-4.7.0/lib/rouge/lexers/kotlin.rb | 145 + .../gems/rouge-4.7.0/lib/rouge/lexers/lasso.rb | 214 + .../rouge-4.7.0/lib/rouge/lexers/lasso/keywords.rb | 20 + .../gems/rouge-4.7.0/lib/rouge/lexers/lean.rb | 164 + .../gems/rouge-4.7.0/lib/rouge/lexers/liquid.rb | 285 + .../lib/rouge/lexers/literate_coffeescript.rb | 34 + .../lib/rouge/lexers/literate_haskell.rb | 37 + .../rouge-4.7.0/lib/rouge/lexers/livescript.rb | 310 + .../gems/rouge-4.7.0/lib/rouge/lexers/llvm.rb | 70 + .../rouge-4.7.0/lib/rouge/lexers/llvm/keywords.rb | 25 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lua.rb | 185 + .../rouge-4.7.0/lib/rouge/lexers/lua/keywords.rb | 28 + .../gems/rouge-4.7.0/lib/rouge/lexers/lustre.rb | 79 + .../gems/rouge-4.7.0/lib/rouge/lexers/lutin.rb | 33 + .../gems/rouge-4.7.0/lib/rouge/lexers/m68k.rb | 143 + .../gems/rouge-4.7.0/lib/rouge/lexers/magik.rb | 127 + .../gems/rouge-4.7.0/lib/rouge/lexers/make.rb | 148 + .../gems/rouge-4.7.0/lib/rouge/lexers/markdown.rb | 183 + .../gems/rouge-4.7.0/lib/rouge/lexers/mason.rb | 110 + .../rouge-4.7.0/lib/rouge/lexers/mathematica.rb | 96 + .../lib/rouge/lexers/mathematica/keywords.rb | 17 + .../gems/rouge-4.7.0/lib/rouge/lexers/matlab.rb | 81 + .../lib/rouge/lexers/matlab/builtins.rb | 11 + .../lib/rouge/lexers/matlab/keywords.rb | 15 + .../gems/rouge-4.7.0/lib/rouge/lexers/meson.rb | 158 + .../gems/rouge-4.7.0/lib/rouge/lexers/minizinc.rb | 87 + .../gems/rouge-4.7.0/lib/rouge/lexers/mojo.rb | 35 + .../rouge-4.7.0/lib/rouge/lexers/moonscript.rb | 115 + .../gems/rouge-4.7.0/lib/rouge/lexers/mosel.rb | 228 + .../gems/rouge-4.7.0/lib/rouge/lexers/msgtrans.rb | 26 + .../gems/rouge-4.7.0/lib/rouge/lexers/mxml.rb | 69 + .../gems/rouge-4.7.0/lib/rouge/lexers/nasm.rb | 73 + .../gems/rouge-4.7.0/lib/rouge/lexers/nesasm.rb | 78 + .../gems/rouge-4.7.0/lib/rouge/lexers/nginx.rb | 73 + .../gems/rouge-4.7.0/lib/rouge/lexers/nial.rb | 166 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nim.rb | 154 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nix.rb | 211 + .../rouge-4.7.0/lib/rouge/lexers/objective_c.rb | 21 + .../lib/rouge/lexers/objective_c/common.rb | 182 + .../rouge-4.7.0/lib/rouge/lexers/objective_cpp.rb | 31 + .../gems/rouge-4.7.0/lib/rouge/lexers/ocaml.rb | 65 + .../rouge-4.7.0/lib/rouge/lexers/ocaml/common.rb | 53 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocl.rb | 84 + .../gems/rouge-4.7.0/lib/rouge/lexers/openedge.rb | 632 + .../lib/rouge/lexers/opentype_feature_file.rb | 97 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/p4.rb | 81 + .../gems/rouge-4.7.0/lib/rouge/lexers/pascal.rb | 68 + .../gems/rouge-4.7.0/lib/rouge/lexers/perl.rb | 251 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php.rb | 421 + .../rouge-4.7.0/lib/rouge/lexers/php/keywords.rb | 152 + .../rouge-4.7.0/lib/rouge/lexers/plain_text.rb | 27 + .../gems/rouge-4.7.0/lib/rouge/lexers/plist.rb | 47 + .../gems/rouge-4.7.0/lib/rouge/lexers/plsql.rb | 578 + .../gems/rouge-4.7.0/lib/rouge/lexers/pony.rb | 94 + .../rouge-4.7.0/lib/rouge/lexers/postscript.rb | 93 + .../rouge-4.7.0/lib/rouge/lexers/powershell.rb | 248 + .../gems/rouge-4.7.0/lib/rouge/lexers/praat.rb | 438 + .../gems/rouge-4.7.0/lib/rouge/lexers/prolog.rb | 67 + .../rouge-4.7.0/lib/rouge/lexers/prometheus.rb | 122 + .../rouge-4.7.0/lib/rouge/lexers/properties.rb | 52 + .../gems/rouge-4.7.0/lib/rouge/lexers/protobuf.rb | 71 + .../gems/rouge-4.7.0/lib/rouge/lexers/puppet.rb | 129 + .../gems/rouge-4.7.0/lib/rouge/lexers/python.rb | 295 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/q.rb | 125 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/qml.rb | 74 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/r.rb | 89 + .../gems/rouge-4.7.0/lib/rouge/lexers/racket.rb | 568 + .../gems/rouge-4.7.0/lib/rouge/lexers/reasonml.rb | 66 + .../gems/rouge-4.7.0/lib/rouge/lexers/rego.rb | 60 + .../gems/rouge-4.7.0/lib/rouge/lexers/rescript.rb | 119 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rml.rb | 142 + .../lib/rouge/lexers/robot_framework.rb | 249 + .../gems/rouge-4.7.0/lib/rouge/lexers/ruby.rb | 455 + .../gems/rouge-4.7.0/lib/rouge/lexers/rust.rb | 260 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sas.rb | 563 + .../gems/rouge-4.7.0/lib/rouge/lexers/sass.rb | 75 + .../rouge-4.7.0/lib/rouge/lexers/sass/common.rb | 182 + .../gems/rouge-4.7.0/lib/rouge/lexers/scala.rb | 172 + .../gems/rouge-4.7.0/lib/rouge/lexers/scheme.rb | 113 + .../gems/rouge-4.7.0/lib/rouge/lexers/scss.rb | 35 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sed.rb | 173 + .../gems/rouge-4.7.0/lib/rouge/lexers/shell.rb | 205 + .../gems/rouge-4.7.0/lib/rouge/lexers/sieve.rb | 97 + .../gems/rouge-4.7.0/lib/rouge/lexers/slice.rb | 32 + .../gems/rouge-4.7.0/lib/rouge/lexers/slim.rb | 229 + .../gems/rouge-4.7.0/lib/rouge/lexers/smalltalk.rb | 117 + .../gems/rouge-4.7.0/lib/rouge/lexers/smarty.rb | 81 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sml.rb | 345 + .../gems/rouge-4.7.0/lib/rouge/lexers/sparql.rb | 131 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf.rb | 109 + .../rouge-4.7.0/lib/rouge/lexers/sqf/keywords.rb | 12 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sql.rb | 161 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ssh.rb | 33 + .../gems/rouge-4.7.0/lib/rouge/lexers/stan.rb | 451 + .../gems/rouge-4.7.0/lib/rouge/lexers/stata.rb | 165 + .../rouge-4.7.0/lib/rouge/lexers/supercollider.rb | 115 + .../gems/rouge-4.7.0/lib/rouge/lexers/svelte.rb | 91 + .../gems/rouge-4.7.0/lib/rouge/lexers/swift.rb | 202 + .../gems/rouge-4.7.0/lib/rouge/lexers/systemd.rb | 34 + .../gems/rouge-4.7.0/lib/rouge/lexers/syzlang.rb | 316 + .../gems/rouge-4.7.0/lib/rouge/lexers/syzprog.rb | 122 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tap.rb | 88 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tcl.rb | 198 + .../gems/rouge-4.7.0/lib/rouge/lexers/terraform.rb | 121 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tex.rb | 70 + .../gems/rouge-4.7.0/lib/rouge/lexers/toml.rb | 124 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tsx.rb | 33 + .../gems/rouge-4.7.0/lib/rouge/lexers/ttcn3.rb | 117 + .../gems/rouge-4.7.0/lib/rouge/lexers/tulip.rb | 107 + .../gems/rouge-4.7.0/lib/rouge/lexers/turtle.rb | 61 + .../gems/rouge-4.7.0/lib/rouge/lexers/twig.rb | 40 + .../rouge-4.7.0/lib/rouge/lexers/typescript.rb | 23 + .../lib/rouge/lexers/typescript/common.rb | 60 + .../gems/rouge-4.7.0/lib/rouge/lexers/vala.rb | 78 + .../gems/rouge-4.7.0/lib/rouge/lexers/varnish.rb | 168 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vb.rb | 165 + .../gems/rouge-4.7.0/lib/rouge/lexers/velocity.rb | 71 + .../gems/rouge-4.7.0/lib/rouge/lexers/verilog.rb | 163 + .../gems/rouge-4.7.0/lib/rouge/lexers/vhdl.rb | 98 + .../gems/rouge-4.7.0/lib/rouge/lexers/viml.rb | 70 + .../rouge-4.7.0/lib/rouge/lexers/viml/keywords.rb | 21 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vue.rb | 127 + .../gems/rouge-4.7.0/lib/rouge/lexers/wollok.rb | 107 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xml.rb | 56 + .../gems/rouge-4.7.0/lib/rouge/lexers/xojo.rb | 61 + .../gems/rouge-4.7.0/lib/rouge/lexers/xpath.rb | 332 + .../gems/rouge-4.7.0/lib/rouge/lexers/xquery.rb | 145 + .../gems/rouge-4.7.0/lib/rouge/lexers/yaml.rb | 376 + .../gems/rouge-4.7.0/lib/rouge/lexers/yang.rb | 147 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/zig.rb | 139 + .../rouge-4.7.0/lib/rouge/plugins/redcarpet.rb | 37 + .../gems/rouge-4.7.0/lib/rouge/regex_lexer.rb | 511 + .../gems/rouge-4.7.0/lib/rouge/template_lexer.rb | 21 + .../rouge-4.7.0/lib/rouge/tex_theme_renderer.rb | 132 + .../gems/rouge-4.7.0/lib/rouge/text_analyzer.rb | 50 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/theme.rb | 218 + .../gems/rouge-4.7.0/lib/rouge/themes/base16.rb | 137 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/themes/bw.rb | 43 + .../gems/rouge-4.7.0/lib/rouge/themes/colorful.rb | 70 + .../gems/rouge-4.7.0/lib/rouge/themes/github.rb | 149 + .../gems/rouge-4.7.0/lib/rouge/themes/gruvbox.rb | 173 + .../gems/rouge-4.7.0/lib/rouge/themes/igor_pro.rb | 25 + .../gems/rouge-4.7.0/lib/rouge/themes/magritte.rb | 80 + .../gems/rouge-4.7.0/lib/rouge/themes/molokai.rb | 84 + .../gems/rouge-4.7.0/lib/rouge/themes/monokai.rb | 95 + .../lib/rouge/themes/monokai_sublime.rb | 94 + .../gems/rouge-4.7.0/lib/rouge/themes/pastie.rb | 72 + .../rouge-4.7.0/lib/rouge/themes/thankful_eyes.rb | 77 + .../gems/rouge-4.7.0/lib/rouge/themes/tulip.rb | 72 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/token.rb | 192 + .../ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/util.rb | 102 + .../3.4.0/gems/rouge-4.7.0/lib/rouge/version.rb | 8 + .../ruby/3.4.0/gems/rouge-4.7.0/rouge.gemspec | 26 + .../sass-embedded-1.101.0-arm64-darwin/LICENSE | 21 + .../sass-embedded-1.101.0-arm64-darwin/README.md | 48 + .../sass-embedded-1.101.0-arm64-darwin/exe/sass | 13 + .../lib/sass-embedded.rb | 4 + .../lib/sass/calculation_value.rb | 22 + .../calculation_value/calculation_operation.rb | 49 + .../lib/sass/canonicalize_context.rb | 25 + .../lib/sass/cli.rb | 12 + .../lib/sass/compile_result.rb | 24 + .../lib/sass/compiler.rb | 214 + .../lib/sass/compiler/channel.rb | 70 + .../lib/sass/compiler/connection.rb | 90 + .../lib/sass/compiler/dispatcher.rb | 142 + .../lib/sass/compiler/session.rb | 233 + .../lib/sass/compiler/session/function_registry.rb | 92 + .../lib/sass/compiler/session/importer_registry.rb | 162 + .../lib/sass/compiler/session/logger_registry.rb | 77 + .../lib/sass/compiler/session/path.rb | 34 + .../lib/sass/compiler/session/protofier.rb | 376 + .../lib/sass/compiler/session/stack_trace.rb | 46 + .../lib/sass/compiler/session/struct.rb | 36 + .../lib/sass/compiler/varint.rb | 39 + .../lib/sass/dart-sass/sass | 20 + .../lib/sass/dart-sass/src/LICENSE | 1720 ++ .../lib/sass/dart-sass/src/dart | Bin 0 -> 4759584 bytes .../lib/sass/dart-sass/src/sass.snapshot | Bin 0 -> 5630688 bytes .../lib/sass/elf.rb | 386 + .../lib/sass/embedded.rb | 68 + .../lib/sass/embedded/version.rb | 7 + .../lib/sass/embedded_protocol.rb | 10 + .../lib/sass/embedded_sass_pb.rb | 61 + .../lib/sass/exception.rb | 126 + .../lib/sass/fork_tracker.rb | 59 + .../lib/sass/gem_package_importer.rb | 28 + .../lib/sass/logger/silent.rb | 28 + .../lib/sass/logger/source_location.rb | 22 + .../lib/sass/logger/source_span.rb | 28 + .../lib/sass/node_package_importer.rb | 17 + .../lib/sass/serializer.rb | 30 + .../lib/sass/uri.rb | 56 + .../lib/sass/value.rb | 136 + .../lib/sass/value/argument_list.rb | 29 + .../lib/sass/value/boolean.rb | 52 + .../lib/sass/value/calculation.rb | 90 + .../lib/sass/value/color.rb | 630 + .../lib/sass/value/color/channel.rb | 79 + .../lib/sass/value/color/conversions.rb | 473 + .../lib/sass/value/color/gamut_map_method.rb | 45 + .../lib/sass/value/color/gamut_map_method/clip.rb | 45 + .../value/color/gamut_map_method/local_minde.rb | 94 + .../lib/sass/value/color/interpolation_method.rb | 51 + .../lib/sass/value/color/space.rb | 201 + .../lib/sass/value/color/space/a98_rgb.rb | 57 + .../lib/sass/value/color/space/display_p3.rb | 72 + .../sass/value/color/space/display_p3_linear.rb | 72 + .../lib/sass/value/color/space/hsl.rb | 65 + .../lib/sass/value/color/space/hwb.rb | 70 + .../lib/sass/value/color/space/lab.rb | 77 + .../lib/sass/value/color/space/lch.rb | 53 + .../lib/sass/value/color/space/lms.rb | 129 + .../lib/sass/value/color/space/oklab.rb | 66 + .../lib/sass/value/color/space/oklch.rb | 54 + .../lib/sass/value/color/space/prophoto_rgb.rb | 59 + .../lib/sass/value/color/space/rec2020.rb | 69 + .../lib/sass/value/color/space/rgb.rb | 52 + .../lib/sass/value/color/space/srgb.rb | 140 + .../lib/sass/value/color/space/srgb_linear.rb | 72 + .../lib/sass/value/color/space/utils.rb | 86 + .../lib/sass/value/color/space/xyz_d50.rb | 100 + .../lib/sass/value/color/space/xyz_d65.rb | 57 + .../lib/sass/value/function.rb | 52 + .../lib/sass/value/fuzzy_math.rb | 84 + .../lib/sass/value/list.rb | 79 + .../lib/sass/value/map.rb | 71 + .../lib/sass/value/mixin.rb | 37 + .../lib/sass/value/null.rb | 48 + .../lib/sass/value/number.rb | 364 + .../lib/sass/value/number/unit.rb | 187 + .../lib/sass/value/string.rb | 61 + .../bundle/ruby/3.4.0/gems/webrick-1.9.2/Gemfile | 10 + .../ruby/3.4.0/gems/webrick-1.9.2/LICENSE.txt | 22 + .../bundle/ruby/3.4.0/gems/webrick-1.9.2/README.md | 63 + .../bundle/ruby/3.4.0/gems/webrick-1.9.2/Rakefile | 10 + .../ruby/3.4.0/gems/webrick-1.9.2/lib/webrick.rb | 232 + .../gems/webrick-1.9.2/lib/webrick/accesslog.rb | 157 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/cgi.rb | 313 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/compat.rb | 36 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/config.rb | 158 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/cookie.rb | 172 + .../gems/webrick-1.9.2/lib/webrick/htmlutils.rb | 30 + .../gems/webrick-1.9.2/lib/webrick/httpauth.rb | 96 + .../lib/webrick/httpauth/authenticator.rb | 117 + .../lib/webrick/httpauth/basicauth.rb | 116 + .../lib/webrick/httpauth/digestauth.rb | 395 + .../webrick-1.9.2/lib/webrick/httpauth/htdigest.rb | 132 + .../webrick-1.9.2/lib/webrick/httpauth/htgroup.rb | 97 + .../webrick-1.9.2/lib/webrick/httpauth/htpasswd.rb | 158 + .../webrick-1.9.2/lib/webrick/httpauth/userdb.rb | 53 + .../gems/webrick-1.9.2/lib/webrick/httpproxy.rb | 354 + .../gems/webrick-1.9.2/lib/webrick/httprequest.rb | 668 + .../gems/webrick-1.9.2/lib/webrick/httpresponse.rb | 588 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/https.rb | 152 + .../gems/webrick-1.9.2/lib/webrick/httpserver.rb | 294 + .../gems/webrick-1.9.2/lib/webrick/httpservlet.rb | 23 + .../lib/webrick/httpservlet/abstract.rb | 152 + .../lib/webrick/httpservlet/cgi_runner.rb | 47 + .../lib/webrick/httpservlet/cgihandler.rb | 126 + .../lib/webrick/httpservlet/erbhandler.rb | 88 + .../lib/webrick/httpservlet/filehandler.rb | 552 + .../lib/webrick/httpservlet/prochandler.rb | 48 + .../gems/webrick-1.9.2/lib/webrick/httpstatus.rb | 194 + .../gems/webrick-1.9.2/lib/webrick/httputils.rb | 543 + .../gems/webrick-1.9.2/lib/webrick/httpversion.rb | 76 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/log.rb | 156 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/server.rb | 380 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/ssl.rb | 219 + .../3.4.0/gems/webrick-1.9.2/lib/webrick/utils.rb | 265 + .../gems/webrick-1.9.2/lib/webrick/version.rb | 18 + .../3.4.0/gems/webrick-1.9.2/sig/accesslog.rbs | 24 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/cgi.rbs | 92 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/compat.rbs | 18 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/config.rbs | 17 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/cookie.rbs | 37 + .../3.4.0/gems/webrick-1.9.2/sig/htmlutils.rbs | 5 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth.rbs | 13 + .../webrick-1.9.2/sig/httpauth/authenticator.rbs | 55 + .../gems/webrick-1.9.2/sig/httpauth/basicauth.rbs | 29 + .../gems/webrick-1.9.2/sig/httpauth/digestauth.rbs | 85 + .../gems/webrick-1.9.2/sig/httpauth/htdigest.rbs | 31 + .../gems/webrick-1.9.2/sig/httpauth/htgroup.rbs | 21 + .../gems/webrick-1.9.2/sig/httpauth/htpasswd.rbs | 31 + .../gems/webrick-1.9.2/sig/httpauth/userdb.rbs | 13 + .../3.4.0/gems/webrick-1.9.2/sig/httpproxy.rbs | 61 + .../3.4.0/gems/webrick-1.9.2/sig/httprequest.rbs | 167 + .../3.4.0/gems/webrick-1.9.2/sig/httpresponse.rbs | 117 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/https.rbs | 49 + .../3.4.0/gems/webrick-1.9.2/sig/httpserver.rbs | 71 + .../3.4.0/gems/webrick-1.9.2/sig/httpservlet.rbs | 4 + .../webrick-1.9.2/sig/httpservlet/abstract.rbs | 36 + .../webrick-1.9.2/sig/httpservlet/cgi_runner.rbs | 3 + .../webrick-1.9.2/sig/httpservlet/cgihandler.rbs | 23 + .../webrick-1.9.2/sig/httpservlet/erbhandler.rbs | 17 + .../webrick-1.9.2/sig/httpservlet/filehandler.rbs | 76 + .../webrick-1.9.2/sig/httpservlet/prochandler.rbs | 21 + .../3.4.0/gems/webrick-1.9.2/sig/httpstatus.rbs | 255 + .../3.4.0/gems/webrick-1.9.2/sig/httputils.rbs | 116 + .../3.4.0/gems/webrick-1.9.2/sig/httpversion.rbs | 17 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/log.rbs | 93 + .../3.4.0/gems/webrick-1.9.2/sig/manifest.yaml | 8 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/server.rbs | 57 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/ssl.rbs | 19 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/utils.rbs | 122 + .../ruby/3.4.0/gems/webrick-1.9.2/sig/version.rbs | 3 + .../ruby/3.4.0/gems/webrick-1.9.2/webrick.gemspec | 105 + 2017 files changed, 277610 insertions(+) create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/CHANGELOG.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/LICENSE.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/native.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/pure.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/template.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/uri.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/LICENSE create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/bigdecimal.gemspec create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/Makefile create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bits.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/div.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/extconf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/feature.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing/dtoa.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/ntt.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/static_assert.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.bundle create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/jacobian.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/ludcmp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/math.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/newton.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/util.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/linear.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/nlsolve.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/pi.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal_util.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_math.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/CHANGELOG.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Gemfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/LICENSE.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Rakefile create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/ConcurrentRubyService.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent-ruby.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/agent.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/array.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/async.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atom.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/event.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/locals.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/semaphore.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomics.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_timeout_queue.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/timeout_queue.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/deprecation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/logging.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/obligation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/observable.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concurrent_ruby.jar create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/configuration.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/constants.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/dataflow.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/delay.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/errors.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/exchanger.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/executor_service.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/timer_set.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executors.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/future.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/hash.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/immutable_struct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/ivar.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/map.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/maybe.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mutable_struct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mvar.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/options.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promise.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promises.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/re_include.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/scheduled_task.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/set.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/settable_struct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/condition.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lock.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/object.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/volatile.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/timer_task.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tuple.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tvar.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/engine.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_integer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/processor_counter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/CHANGELOG.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/COPYING create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Gemfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE.SPECS create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Rakefile create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Steepfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/ffi.gemspec create mode 100755 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.0/ffi_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.1/ffi_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.2/ffi_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.3/ffi_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.4/ffi_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/4.0/ffi_c.bundle create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/abstract_memory.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/autopointer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/buffer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/callback.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/compat.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/data_converter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/dynamic_library.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/enum.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/errno.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/ffi.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/function.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/io.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library_path.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/managedstruct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/memorypointer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-darwin/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd12/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-openbsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-windows/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd12/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa1.1-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa2.0-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-cygwin/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-darwin/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd12/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-gnu/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-netbsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-openbsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-solaris/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-windows/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/ia64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/loongarch64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64el-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsel-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6el-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6el-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-aix/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-darwin/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-openbsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64le-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/riscv64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390x-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-solaris/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-openbsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-solaris/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sw_64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-cygwin/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-darwin/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-dragonflybsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd12/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-haiku/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-linux/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-msys/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-netbsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-openbsd/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-solaris/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-windows/types.conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/pointer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_by_reference.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout_builder.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/types.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/union.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/variadic.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getlogin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getpid.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/gettimeofday.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello_ractor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/inotify.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/pty.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort_ractor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/abstract_memory.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/auto_pointer.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/buffer.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/data_converter.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/dynamic_library.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/enum.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/errno.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/function.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/library.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/native_type.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/platform.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/pointer.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_reference.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_value.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout_builder.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/type.rbs create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/Rakefile create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/extconf.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/glue.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/LICENSE create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.1/protobuf_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.2/protobuf_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.3/protobuf_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.4/protobuf_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/4.0/protobuf_c.bundle create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/any_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/api_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/descriptor_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/duration_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/empty_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor_pool.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/enum_descriptor.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/ffi.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/field_descriptor.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/file_descriptor.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/arena.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/convert.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/pointer_helper.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/type_safety.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/map.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/message.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/method_descriptor.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/object_cache.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/oneof_descriptor.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/repeated_field.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/service_descriptor.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/field_mask_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/internal/object_cache.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/message_exts.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/plugin_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/repeated_field.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/source_context_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/struct_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/timestamp_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/type_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/well_known_types.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/wrappers_pb.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_ffi.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_native.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/tasks/ffi.rake create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/linux.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/windows.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitignore create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitmodules create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Gemfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/LICENSE-MIT create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Rakefile create mode 100755 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/standalone.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/thin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/.gitignore create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/RubyHttpParserService.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ext_help.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/extconf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ruby_http_parser.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/.gitkeep create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/AUTHORS create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/TODO create mode 100755 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/build.xml create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.gyp create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/Http-parser.java.iml create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/FieldData.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParserUrl.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/Util.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/ParseUrl.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Url.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/test.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/AUTHORS create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/bench.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/parsertrace.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/url_parser.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.gyp create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/test.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/http_parser.rb.gemspec create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http/parser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http_parser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/compile.rake create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/fixtures.rake create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/spec.rake create mode 100644 vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/submodules.rake create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/MIT-LICENSE create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/base.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache_file.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cascade.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/chain.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/fallbacks.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/flatten.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/gettext.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/interpolation_compiler.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/key_value.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/lazy_loadable.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/memoize.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/metadata.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/pluralization.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/simple.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/transliterator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/config.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/exceptions.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/helpers.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/po_parser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/interpolate/ruby.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/fallbacks.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/parents.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/rfc4646.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/simple.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/middleware.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/basics.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/defaults.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/interpolation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/link.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date_time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/procs.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/lookup.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/pluralization.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/procs.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/utils.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/ci.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/release.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/third-party.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.gitignore create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rspec create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop_todo.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/Gemfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/History.markdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/LICENSE.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_config.yml create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_layouts/default.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/advanced-usage.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/installation.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/usage.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/jekyll-seo-tag.gemspec create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/author_drop.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/drop.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/filters.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/image_drop.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld_drop.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/url_helper.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/version.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/template.html create mode 100755 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/bootstrap create mode 100755 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/cibuild create mode 100755 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/release create mode 100755 vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/site create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/BSDL create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/CHANGES.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/COPYING create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/LEGAL create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/fbuffer/fbuffer.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/Makefile create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/extconf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/generator.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/json.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/Makefile create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/extconf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/parser.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/conf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/simd.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fast_float_parser.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fpconv.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/jeaiii-ltoa.h create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/json.gemspec create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/bigdecimal.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/complex.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/core.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date_time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/exception.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/ostruct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/range.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/rational.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/regexp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/set.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/string.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/struct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/symbol.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/common.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator.bundle create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator/state.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/parser.bundle create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/generic_object.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/truffle_ruby/generator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/AUTHORS create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/CONTRIBUTERS create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/COPYING create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/VERSION create mode 100755 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/bin/kramdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/base.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/hash_ast.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/html.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/kramdown.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/latex.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/man.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/math_engine/mathjax.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/remove_html_tags.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/minted.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/rouge.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/toc.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/document.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/element.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/error.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/options.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/base.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/html.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/abbreviation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/autolink.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blank_line.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/block_boundary.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blockquote.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codeblock.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codespan.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/emphasis.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/eob.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/escaped_chars.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/extensions.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/footnote.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/header.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/horizontal_rule.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html_entity.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/line_break.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/link.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/list.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/math.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/paragraph.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/smart_quotes.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/table.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/typographic_symbol.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/markdown.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/configurable.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/entities.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/html.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/lru_cache.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/string_scanner.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/unidecoder.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/man/man1/kramdown.1 create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/run_tests.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_files.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_location.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_string_scanner_kramdown.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html.gfm create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.kramdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.kramdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.test create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.kramdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.htmlinput create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.htmlinput create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.htmlinput create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.kramdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.kramdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.man create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.htmlinput create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.html create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.latex create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.options create mode 100644 vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.text create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CHANGELOG.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CONTRIBUTING.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/LICENSE.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/README.md create mode 100755 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/bin/listen create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/base.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/bsd.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/config.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/darwin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/linux.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/polling.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/windows.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/backend.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/change.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/cli.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/directory.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/error.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/config.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/loop.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/processor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/queue.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/file.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/fsm.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener/config.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/logger.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/monotonic_time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/options.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/queue_optimizer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/entry.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/symlink_detector.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer/controller.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/thread.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.document create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.rdoc_options create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/.yardopts create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/CHANGELOG.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/Gemfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/LICENSE.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/SECURITY.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/data/list.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/domain.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/errors.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/list.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/rule.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/History.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/MIT-LICENSE create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/README.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/command_line_usage.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile1 create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile2 create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/a.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/b.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/main.c create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/glossary.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/jamis.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/proto_rake.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rake.1 create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rakefile.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rational.rdoc create mode 100755 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/backtrace.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/clean.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cloneable.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/default_loader.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/early_time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/core.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/string.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_list.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_task.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/late_time.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/linked_list.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/multi_task.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/name_space.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/options.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/packagetask.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/phony.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/private_reader.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/promise.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_module.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/scope.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_arguments.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_manager.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/tasklib.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/testtask.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_pool.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/trace_output.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/win32.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/rake.gemspec create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/LICENSE.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/NEWS.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/context.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/child.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/document.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/element.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/node.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/parent.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/child_toc.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/document_toc.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/element_toc.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/master_toc.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/node_toc.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/parent_toc.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tutorial.rdoc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attlistdecl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attribute.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/cdata.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/child.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/comment.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/doctype.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/document.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/attlistdecl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/dtd.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/elementdecl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/entitydecl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/notationdecl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/element.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/encoding.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/entity.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/default.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/pretty.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/transitive.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/functions.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/instruction.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/light/node.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/namespace.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/node.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/output.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parent.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parseexception.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/lightparser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/pullparser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/sax2parser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/streamparser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/ultralightparser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/xpathparser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/quickpath.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/rexml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/sax2listener.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/security.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/source.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/streamlistener.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/text.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/undefinednamespaceexception.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/relaxng.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validationexception.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmldecl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmltokens.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath_parser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/Gemfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/LICENSE create mode 100755 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/bin/rougify create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/cli.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/abap create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/actionscript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ada create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apache create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apex create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apiblueprint create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/applescript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/armasm create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/augeas create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/awk create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/batchfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bbcbasic create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bibtex create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bicep create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/biml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bpf create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brainfuck create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brightscript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bsl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/c create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ceylon create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cfscript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cisco_ios create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clean create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clojure create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmake create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmhg create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cobol create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/codeowners create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coffeescript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/common_lisp create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/conf create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/console create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coq create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cpp create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/crystal create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csharp create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/css create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csvs create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cuda create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cypher create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cython create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/d create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dafny create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dart create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/datastudio create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/diff create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/digdag create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/docker create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dot create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ecl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eex create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eiffel create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elixir create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elm create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/email create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/epp create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erlang create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/escape create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/factor create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fluent create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fortran create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/freefem create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fsharp create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gdscript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-cmm create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-core create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gherkin create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gjs create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/glsl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/go create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gradle create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/graphql create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/groovy create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gts create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hack create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/haml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/handlebars create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/haskell create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/haxe create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hcl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hlsl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hocon create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hql create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/html create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/http create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/hylang create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/idlang create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/idris create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/iecst create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/igorpro create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ini create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/io create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/irb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/irb_output create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/isabelle create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/isbl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/j create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/janet create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/java create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/javascript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jinja create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/json create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/json-doc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/json5 create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsonnet create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsp create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/jsx create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/julia create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/kotlin create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lasso create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lean create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/liquid create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/literate_coffeescript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/literate_haskell create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/livescript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/llvm create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lua create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lustre create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/lutin create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/m68k create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/magik create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/make create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/markdown create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mason create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mathematica create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/matlab create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/meson create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/minizinc create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mojo create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/moonscript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mosel create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/msgtrans create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/mxml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nasm create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nesasm create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nginx create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nial create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nim create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/nix create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/objective_c create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/objective_cpp create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ocaml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ocl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/openedge create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/opentype_feature_file create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/p4 create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/pascal create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/perl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/php create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/plaintext create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/plist create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/plsql create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/pony create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/postscript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/powershell create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/praat create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/prolog create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/prometheus create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/properties create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/protobuf create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/puppet create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/python create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/q create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/qml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/r create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/racket create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/reasonml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rego create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rescript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/robot_framework create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ruby create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rust create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sas create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sass create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scala create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scheme create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scss create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sed create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/shell create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sieve create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slice create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slim create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smalltalk create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smarty create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sparql create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sqf create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sql create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ssh create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stan create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stata create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/supercollider create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/svelte create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/swift create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/systemd create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzlang create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzprog create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tap create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tcl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/terraform create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tex create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/toml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tsx create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ttcn3 create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tulip create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/turtle create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/twig create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/typescript create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vala create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vcl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/velocity create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/verilog create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vhdl create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/viml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vue create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/wollok create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xojo create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xpath create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xquery create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yaml create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yang create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/zig create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_inline.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_legacy.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_highlighter.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_table.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_linewise.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_pygments.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_table.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/null.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal256.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal_truecolor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/tex.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guesser.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/disambiguation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/filename.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/glob_mapping.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/mimetype.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/modeline.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/source.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/util.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/abap.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/actionscript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ada.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apex.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apiblueprint.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apple_script.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/armasm.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/augeas.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/awk.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/batchfile.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bbcbasic.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bibtex.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bicep.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/biml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bpf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brainfuck.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brightscript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bsl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/c.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ceylon.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cfscript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cisco_ios.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clean.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clojure.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmake.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmhg.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cobol.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/codeowners.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/coffeescript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/common_lisp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/conf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/console.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/coq.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cpp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/crystal.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/csharp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/css.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/csvs.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cuda.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cypher.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cython.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/d.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/dafny.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/dart.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/datastudio.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/diff.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/digdag.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/docker.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/dot.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ecl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/eex.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/eiffel.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/elixir.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/elm.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/email.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/epp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/erb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/erlang.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/escape.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/factor.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/fluent.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/fortran.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/freefem.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/fsharp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gdscript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ghc_cmm.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ghc_core.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gherkin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gherkin/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gjs.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/glsl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/go.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gradle.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/graphql.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/groovy.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/gts.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hack.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/haml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/handlebars.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/haskell.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/haxe.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hcl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hlsl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hocon.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hql.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/html.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/http.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hylang.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idlang.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idris.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/iecst.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/igorpro.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ini.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/io.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/irb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isabelle.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl/builtins.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/j.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/janet.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/java.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/javascript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jinja.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jsl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/json.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/json5.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/json_doc.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jsonnet.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jsp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/jsx.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/julia.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/kotlin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lasso.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lasso/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lean.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/liquid.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_coffeescript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_haskell.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/livescript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lua.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lua/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lustre.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lutin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/m68k.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/magik.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/make.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/markdown.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mason.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/builtins.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/meson.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/minizinc.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mojo.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/moonscript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mosel.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/msgtrans.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mxml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nasm.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nesasm.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nginx.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nial.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nim.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nix.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c/common.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_cpp.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml/common.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/openedge.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/opentype_feature_file.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/p4.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pascal.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/perl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plain_text.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plist.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plsql.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pony.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/postscript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/powershell.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/praat.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/prolog.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/prometheus.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/properties.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/protobuf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/puppet.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/python.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/q.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/qml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/r.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/racket.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/reasonml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rego.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rescript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/robot_framework.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ruby.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rust.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sas.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass/common.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scala.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scheme.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scss.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sed.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/shell.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sieve.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/slice.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/slim.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/smalltalk.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/smarty.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sparql.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sql.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ssh.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stan.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stata.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/supercollider.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/svelte.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/swift.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/systemd.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzlang.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzprog.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tap.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tcl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/terraform.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tex.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/toml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tsx.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ttcn3.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tulip.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/turtle.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/twig.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript/common.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vala.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/varnish.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/velocity.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/verilog.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vhdl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml/keywords.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vue.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/wollok.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xojo.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xpath.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xquery.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yaml.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yang.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/zig.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/plugins/redcarpet.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/regex_lexer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/template_lexer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/tex_theme_renderer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/text_analyzer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/theme.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/base16.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/bw.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/colorful.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/github.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/gruvbox.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/igor_pro.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/magritte.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/molokai.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai_sublime.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/pastie.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/thankful_eyes.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/tulip.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/token.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/util.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/rouge.gemspec create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/LICENSE create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/README.md create mode 100755 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/exe/sass create mode 100755 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass-embedded.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value/calculation_operation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/canonicalize_context.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/cli.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compile_result.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/channel.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/connection.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/dispatcher.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/function_registry.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/importer_registry.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/logger_registry.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/path.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/protofier.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/stack_trace.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/struct.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/varint.rb create mode 100755 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/sass create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/LICENSE create mode 100755 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/dart create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/sass.snapshot create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/elf.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/embedded.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/embedded/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/embedded_protocol.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/embedded_sass_pb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/exception.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/fork_tracker.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/gem_package_importer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/silent.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_location.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_span.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/node_package_importer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/serializer.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/uri.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/argument_list.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/boolean.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/calculation.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/channel.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/conversions.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/clip.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/local_minde.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/interpolation_method.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/a98_rgb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3_linear.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hsl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hwb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lab.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lch.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lms.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklab.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklch.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/prophoto_rgb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rec2020.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rgb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb_linear.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/utils.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d50.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d65.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/function.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/fuzzy_math.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/list.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/map.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/mixin.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/null.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number/unit.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/string.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Gemfile create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/LICENSE.txt create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/README.md create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Rakefile create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/accesslog.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cgi.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/compat.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/config.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cookie.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/htmlutils.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/authenticator.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/basicauth.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/digestauth.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htdigest.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htgroup.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htpasswd.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/userdb.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpproxy.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httprequest.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpresponse.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/https.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpserver.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/abstract.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgi_runner.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgihandler.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/erbhandler.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/filehandler.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/prochandler.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpstatus.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httputils.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpversion.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/log.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/server.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/ssl.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/utils.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/version.rb create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/accesslog.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cgi.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/compat.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/config.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cookie.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/htmlutils.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/authenticator.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/basicauth.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/digestauth.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htdigest.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htgroup.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htpasswd.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/userdb.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpproxy.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httprequest.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpresponse.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/https.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpserver.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/abstract.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgi_runner.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgihandler.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/erbhandler.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/filehandler.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/prochandler.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpstatus.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httputils.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpversion.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/log.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/manifest.yaml create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/server.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/ssl.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/utils.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/version.rbs create mode 100644 vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/webrick.gemspec (limited to 'vendor/bundle/ruby/3.4.0/gems') diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/CHANGELOG.md new file mode 100644 index 0000000..76708d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/CHANGELOG.md @@ -0,0 +1,326 @@ +# Changelog + +## Addressable 2.9.0 +- fixes ReDoS vulnerability in Addressable::Template#match (fixes incomplete + remediation in 2.8.10) + +## Addressable 2.8.10 +- fixes ReDoS vulnerability in Addressable::Template#match + +## Addressable 2.8.9 +- Reduce gem size by excluding test files ([#569]) +- No need for bundler as development dependency ([#571], [5fc1d93](https://github.com/sporkmonger/addressable/commit/5fc1d93)) +- idna/pure: stop building the useless `COMPOSITION_TABLE` (removes the `Addressable::IDNA::COMPOSITION_TABLE` constant) ([#564]) + +[#569]: https://github.com/sporkmonger/addressable/pull/569 +[#571]: https://github.com/sporkmonger/addressable/pull/571 +[#564]: https://github.com/sporkmonger/addressable/pull/564 + +## Addressable 2.8.8 +- Replace the `unicode.data` blob by a ruby constant ([#561]) +- Allow `public_suffix` 7 ([#558]) + +[#561]: https://github.com/sporkmonger/addressable/pull/561 +[#558]: https://github.com/sporkmonger/addressable/pull/558 + +## Addressable 2.8.7 +- Allow `public_suffix` 6 ([#535]) + +[#535]: https://github.com/sporkmonger/addressable/pull/535 + +## Addressable 2.8.6 +- Memoize regexps for common character classes ([#524]) + +[#524]: https://github.com/sporkmonger/addressable/pull/524 + +## Addressable 2.8.5 +- Fix thread safety issue with encoding tables ([#515]) +- Define URI::NONE as a module to avoid serialization issues ([#509]) +- Fix YAML serialization ([#508]) + +[#508]: https://github.com/sporkmonger/addressable/pull/508 +[#509]: https://github.com/sporkmonger/addressable/pull/509 +[#515]: https://github.com/sporkmonger/addressable/pull/515 + +## Addressable 2.8.4 +- Restore `Addressable::IDNA.unicode_normalize_kc` as a deprecated method ([#504]) + +[#504]: https://github.com/sporkmonger/addressable/pull/504 + +## Addressable 2.8.3 +- Fix template expand level 2 hash support for non-string objects ([#499], [#498]) + +[#499]: https://github.com/sporkmonger/addressable/pull/499 +[#498]: https://github.com/sporkmonger/addressable/pull/498 + +## Addressable 2.8.2 +- Improve cache hits and JIT friendliness ([#486](https://github.com/sporkmonger/addressable/pull/486)) +- Improve code style and test coverage ([#482](https://github.com/sporkmonger/addressable/pull/482)) +- Ensure reset of deferred validation ([#481](https://github.com/sporkmonger/addressable/pull/481)) +- Resolve normalization differences between `IDNA::Native` and `IDNA::Pure` ([#408](https://github.com/sporkmonger/addressable/issues/408), [#492]) +- Remove redundant colon in `Addressable::URI::CharacterClasses::AUTHORITY` regex ([#438](https://github.com/sporkmonger/addressable/pull/438)) (accidentally reverted by [#449] merge but [added back](https://github.com/sporkmonger/addressable/pull/492#discussion_r1105125280) in [#492]) + +[#492]: https://github.com/sporkmonger/addressable/pull/492 + +## Addressable 2.8.1 +- refactor `Addressable::URI.normalize_path` to address linter offenses ([#430](https://github.com/sporkmonger/addressable/pull/430)) +- update gemspec to reflect supported Ruby versions ([#466], [#464], [#463]) +- compatibility w/ public_suffix 5.x ([#466], [#465], [#460]) +- fixes "invalid byte sequence in UTF-8" exception when unencoding URLs containing non UTF-8 characters ([#459](https://github.com/sporkmonger/addressable/pull/459)) +- `Ractor` compatibility ([#449]) +- use the whole string instead of a single line for template match ([#431](https://github.com/sporkmonger/addressable/pull/431)) +- force UTF-8 encoding only if needed ([#341](https://github.com/sporkmonger/addressable/pull/341)) + +[#449]: https://github.com/sporkmonger/addressable/pull/449 +[#460]: https://github.com/sporkmonger/addressable/pull/460 +[#463]: https://github.com/sporkmonger/addressable/pull/463 +[#464]: https://github.com/sporkmonger/addressable/pull/464 +[#465]: https://github.com/sporkmonger/addressable/pull/465 +[#466]: https://github.com/sporkmonger/addressable/pull/466 + +## Addressable 2.8.0 +- fixes ReDoS vulnerability in Addressable::Template#match +- no longer replaces `+` with spaces in queries for non-http(s) schemes +- fixed encoding ipv6 literals +- the `:compacted` flag for `normalized_query` now dedupes parameters +- fix broken `escape_component` alias +- dropping support for Ruby 2.0 and 2.1 +- adding Ruby 3.0 compatibility for development tasks +- drop support for `rack-mount` and remove Addressable::Template#generate +- performance improvements +- switch CI/CD to GitHub Actions + +## Addressable 2.7.0 +- added `:compacted` flag to `normalized_query` +- `heuristic_parse` handles `mailto:` more intuitively +- dropped explicit support for JRuby 9.0.5.0 +- compatibility w/ public_suffix 4.x +- performance improvements + +## Addressable 2.6.0 +- added `tld=` method to allow assignment to the public suffix +- most `heuristic_parse` patterns are now case-insensitive +- `heuristic_parse` handles more `file://` URI variations +- fixes bug in `heuristic_parse` when uri starts with digit +- fixes bug in `request_uri=` with query strings +- fixes template issues with `nil` and `?` operator +- `frozen_string_literal` pragmas added +- minor performance improvements in regexps +- fixes to eliminate warnings + +## Addressable 2.5.2 +- better support for frozen string literals +- fixed bug w/ uppercase characters in scheme +- IDNA errors w/ emoji URLs +- compatibility w/ public_suffix 3.x + +## Addressable 2.5.1 +- allow unicode normalization to be disabled for URI Template expansion +- removed duplicate test + +## Addressable 2.5.0 +- dropping support for Ruby 1.9 +- adding support for Ruby 2.4 preview +- add support for public suffixes and tld; first runtime dependency +- hostname escaping should match RFC; underscores in hostnames no longer escaped +- paths beginning with // and missing an authority are now considered invalid +- validation now also takes place after setting a path +- handle backslashes in authority more like a browser for `heuristic_parse` +- unescaped backslashes in host now raise an `InvalidURIError` +- `merge!`, `join!`, `omit!` and `normalize!` don't disable deferred validation +- `heuristic_parse` now trims whitespace before parsing +- host parts longer than 63 bytes will be ignored and not passed to libidn +- normalized values always encoded as UTF-8 + +## Addressable 2.4.0 +- support for 1.8.x dropped +- double quotes in a host now raises an error +- newlines in host will no longer get unescaped during normalization +- stricter handling of bogus scheme values +- stricter handling of encoded port values +- calling `require 'addressable'` will now load both the URI and Template files +- assigning to the `hostname` component with an `IPAddr` object is now supported +- assigning to the `origin` component is now supported +- fixed minor bug where an exception would be thrown for a missing ACE suffix +- better partial expansion of URI templates + +## Addressable 2.3.8 +- fix warnings +- update dependency gems +- support for 1.8.x officially deprecated + +## Addressable 2.3.7 +- fix scenario in which invalid URIs don't get an exception until inspected +- handle hostnames with two adjacent periods correctly +- upgrade of RSpec + +## Addressable 2.3.6 +- normalization drops empty query string +- better handling in template extract for missing values +- template modifier for `'?'` now treated as optional +- fixed issue where character class parameters were modified +- templates can now be tested for equality +- added `:sorted` option to normalization of query strings +- fixed issue with normalization of hosts given in `'example.com.'` form + +## Addressable 2.3.5 +- added Addressable::URI#empty? method +- Addressable::URI#hostname methods now strip square brackets from IPv6 hosts +- compatibility with Net::HTTP in Ruby 2.0.0 +- Addressable::URI#route_from should always give relative URIs + +## Addressable 2.3.4 +- fixed issue with encoding altering its inputs +- query string normalization now leaves ';' characters alone +- FakeFS is detected before attempting to load unicode tables +- additional testing to ensure frozen objects don't cause problems + +## Addressable 2.3.3 +- fixed issue with converting common primitives during template expansion +- fixed port encoding issue +- removed a few warnings +- normalize should now ignore %2B in query strings +- the IDNA logic should now be handled by libidn in Ruby 1.9 +- no template match should now result in nil instead of an empty MatchData +- added license information to gemspec + +## Addressable 2.3.2 +- added Addressable::URI#default_port method +- fixed issue with Marshalling Unicode data on Windows +- improved heuristic parsing to better handle IPv4 addresses + +## Addressable 2.3.1 +- fixed missing unicode data file + +## Addressable 2.3.0 +- updated Addressable::Template to use RFC 6570, level 4 +- fixed compatibility problems with some versions of Ruby +- moved unicode tables into a data file for performance reasons +- removing support for multiple query value notations + +## Addressable 2.2.8 +- fixed issues with dot segment removal code +- form encoding can now handle multiple values per key +- updated development environment + +## Addressable 2.2.7 +- fixed issues related to Addressable::URI#query_values= +- the Addressable::URI.parse method is now polymorphic + +## Addressable 2.2.6 +- changed the way ambiguous paths are handled +- fixed bug with frozen URIs +- https supported in heuristic parsing + +## Addressable 2.2.5 +- 'parsing' a pre-parsed URI object is now a dup operation +- introduced conditional support for libidn +- fixed normalization issue on ampersands in query strings +- added additional tests around handling of query strings + +## Addressable 2.2.4 +- added origin support from draft-ietf-websec-origin-00 +- resolved issue with attempting to navigate below root +- fixed bug with string splitting in query strings + +## Addressable 2.2.3 +- added :flat_array notation for query strings + +## Addressable 2.2.2 +- fixed issue with percent escaping of '+' character in query strings + +## Addressable 2.2.1 +- added support for application/x-www-form-urlencoded. + +## Addressable 2.2.0 +- added site methods +- improved documentation + +## Addressable 2.1.2 +- added HTTP request URI methods +- better handling of Windows file paths +- validation_deferred boolean replaced with defer_validation block +- normalization of percent-encoded paths should now be correct +- fixed issue with constructing URIs with relative paths +- fixed warnings + +## Addressable 2.1.1 +- more type checking changes +- fixed issue with unicode normalization +- added method to find template defaults +- symbolic keys are now allowed in template mappings +- numeric values and symbolic values are now allowed in template mappings + +## Addressable 2.1.0 +- refactored URI template support out into its own class +- removed extract method due to being useless and unreliable +- removed Addressable::URI.expand_template +- removed Addressable::URI#extract_mapping +- added partial template expansion +- fixed minor bugs in the parse and heuristic_parse methods +- fixed incompatibility with Ruby 1.9.1 +- fixed bottleneck in Addressable::URI#hash and Addressable::URI#to_s +- fixed unicode normalization exception +- updated query_values methods to better handle subscript notation +- worked around issue with freezing URIs +- improved specs + +## Addressable 2.0.2 +- fixed issue with URI template expansion +- fixed issue with percent escaping characters 0-15 + +## Addressable 2.0.1 +- fixed issue with query string assignment +- fixed issue with improperly encoded components + +## Addressable 2.0.0 +- the initialize method now takes an options hash as its only parameter +- added query_values method to URI class +- completely replaced IDNA implementation with pure Ruby +- renamed Addressable::ADDRESSABLE_VERSION to Addressable::VERSION +- completely reworked the Rakefile +- changed the behavior of the port method significantly +- Addressable::URI.encode_segment, Addressable::URI.unencode_segment renamed +- documentation is now in YARD format +- more rigorous type checking +- to_str method implemented, implicit conversion to Strings now allowed +- Addressable::URI#omit method added, Addressable::URI#merge method replaced +- updated URI Template code to match v 03 of the draft spec +- added a bunch of new specifications + +## Addressable 1.0.4 +- switched to using RSpec's pending system for specs that rely on IDN +- fixed issue with creating URIs with paths that are not prefixed with '/' + +## Addressable 1.0.3 +- implemented a hash method + +## Addressable 1.0.2 +- fixed minor bug with the extract_mapping method + +## Addressable 1.0.1 +- fixed minor bug with the extract_mapping method + +## Addressable 1.0.0 +- heuristic parse method added +- parsing is slightly more strict +- replaced to_h with to_hash +- fixed routing methods +- improved specifications +- improved heckle rake task +- no surviving heckle mutations + +## Addressable 0.1.2 +- improved normalization +- fixed bug in joining algorithm +- updated specifications + +## Addressable 0.1.1 +- updated documentation +- added URI Template variable extraction + +## Addressable 0.1.0 +- initial release +- implementation based on RFC 3986, 3987 +- support for IRIs via libidn +- support for the URI Template draft spec diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/LICENSE.txt new file mode 100644 index 0000000..ef51da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/README.md b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/README.md new file mode 100644 index 0000000..d9fa04f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/README.md @@ -0,0 +1,121 @@ +# Addressable + +
+
Homepage
github.com/sporkmonger/addressable
+
Author
Bob Aman
+
Copyright
Copyright © Bob Aman
+
License
Apache 2.0
+
+ +[![Gem Version](https://img.shields.io/gem/dt/addressable.svg)][gem] +[![Build Status](https://github.com/sporkmonger/addressable/workflows/CI/badge.svg)][actions] +[![Test Coverage Status](https://img.shields.io/coveralls/sporkmonger/addressable.svg)][coveralls] +[![Documentation Coverage Status](https://inch-ci.org/github/sporkmonger/addressable.svg?branch=master)][inch] + +[gem]: https://rubygems.org/gems/addressable +[actions]: https://github.com/sporkmonger/addressable/actions +[coveralls]: https://coveralls.io/r/sporkmonger/addressable +[inch]: https://inch-ci.org/github/sporkmonger/addressable + +## Description + +Addressable is an alternative implementation to the URI implementation +that is part of Ruby's standard library. It is flexible, offers heuristic +parsing, and additionally provides extensive support for IRIs and URI templates. + +Addressable closely conforms to RFC 3986, RFC 3987, and RFC 6570 (level 4). + +## Reference + +- {Addressable::URI} +- {Addressable::Template} + +## Example usage + +```ruby +require "addressable/uri" + +uri = Addressable::URI.parse("http://example.com/path/to/resource/") +uri.scheme +#=> "http" +uri.host +#=> "example.com" +uri.path +#=> "/path/to/resource/" + +uri = Addressable::URI.parse("http://www.詹姆斯.com/") +uri.normalize +#=> # +``` + + +## URI Templates + +For more details, see [RFC 6570](https://www.rfc-editor.org/rfc/rfc6570.txt). + + +```ruby + +require "addressable/template" + +template = Addressable::Template.new("http://example.com/{?query*}") +template.expand({ + "query" => { + 'foo' => 'bar', + 'color' => 'red' + } +}) +#=> # + +template = Addressable::Template.new("http://example.com/{?one,two,three}") +template.partial_expand({"one" => "1", "three" => 3}).pattern +#=> "http://example.com/?one=1{&two}&three=3" + +template = Addressable::Template.new( + "http://{host}{/segments*}/{?one,two,bogus}{#fragment}" +) +uri = Addressable::URI.parse( + "http://example.com/a/b/c/?one=1&two=2#foo" +) +template.extract(uri) +#=> +# { +# "host" => "example.com", +# "segments" => ["a", "b", "c"], +# "one" => "1", +# "two" => "2", +# "fragment" => "foo" +# } +``` + +## Install + +```console +$ gem install addressable +``` + +You may optionally turn on native IDN support by installing libidn and the +idn gem: + +```console +$ sudo apt-get install libidn11-dev # Debian/Ubuntu +$ brew install libidn # OS X +$ gem install idn-ruby +``` + +## Semantic Versioning + +This project uses [Semantic Versioning](https://semver.org/). You can (and should) specify your +dependency using a pessimistic version constraint covering the major and minor +values: + +```ruby +spec.add_dependency 'addressable', '~> 2.7' +``` + +If you need a specific bug fix, you can also specify minimum tiny versions +without preventing updates to the latest minor release: + +```ruby +spec.add_dependency 'addressable', '~> 2.3', '>= 2.3.7' +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable.rb new file mode 100644 index 0000000..b4e98b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +require 'addressable/uri' +require 'addressable/template' diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna.rb new file mode 100644 index 0000000..2dbd393 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +begin + require "addressable/idna/native" +rescue LoadError + # libidn or the idn gem was not available, fall back on a pure-Ruby + # implementation... + require "addressable/idna/pure" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/native.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/native.rb new file mode 100644 index 0000000..a718364 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/native.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +require "idn" + +module Addressable + module IDNA + def self.punycode_encode(value) + IDN::Punycode.encode(value.to_s) + end + + def self.punycode_decode(value) + IDN::Punycode.decode(value.to_s) + end + + class << self + # @deprecated Use {String#unicode_normalize(:nfkc)} instead + def unicode_normalize_kc(value) + value.to_s.unicode_normalize(:nfkc) + end + + extend Gem::Deprecate + deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4 + end + + def self.to_ascii(value) + value.to_s.split('.', -1).map do |segment| + if segment.size > 0 && segment.size < 64 + IDN::Idna.toASCII(segment, IDN::Idna::ALLOW_UNASSIGNED) + elsif segment.size >= 64 + segment + else + '' + end + end.join('.') + end + + def self.to_unicode(value) + value.to_s.split('.', -1).map do |segment| + if segment.size > 0 && segment.size < 64 + IDN::Idna.toUnicode(segment, IDN::Idna::ALLOW_UNASSIGNED) + elsif segment.size >= 64 + segment + else + '' + end + end.join('.') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/pure.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/pure.rb new file mode 100644 index 0000000..6572e64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/idna/pure.rb @@ -0,0 +1,4710 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +module Addressable + module IDNA + # This module is loosely based on idn_actionmailer by Mick Staugaard, + # the unicode library by Yoshida Masato, and the punycode implementation + # by Kazuhiro Nishiyama. Most of the code was copied verbatim, but + # some reformatting was done, and some translation from C was done. + # + # Without their code to work from as a base, we'd all still be relying + # on the presence of libidn. Which nobody ever seems to have installed. + # + # Original sources: + # http://github.com/staugaard/idn_actionmailer + # http://www.yoshidam.net/Ruby.html#unicode + # http://rubyforge.org/frs/?group_id=2550 + + ACE_PREFIX = "xn--" + + UTF8_REGEX = /\A(?: + [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*\z/mnx + + UTF8_REGEX_MULTIBYTE = /(?: + [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )/mnx + + # :startdoc: + + # Converts from a Unicode internationalized domain name to an ASCII + # domain name as described in RFC 3490. + def self.to_ascii(input) + input = input.to_s unless input.is_a?(String) + input = input.dup.force_encoding(Encoding::UTF_8).unicode_normalize(:nfkc) + if input.respond_to?(:force_encoding) + input.force_encoding(Encoding::ASCII_8BIT) + end + if input =~ UTF8_REGEX && input =~ UTF8_REGEX_MULTIBYTE + parts = unicode_downcase(input).split('.') + parts.map! do |part| + if part.respond_to?(:force_encoding) + part.force_encoding(Encoding::ASCII_8BIT) + end + if part =~ UTF8_REGEX && part =~ UTF8_REGEX_MULTIBYTE + ACE_PREFIX + punycode_encode(part) + else + part + end + end + parts.join('.') + else + input + end + end + + # Converts from an ASCII domain name to a Unicode internationalized + # domain name as described in RFC 3490. + def self.to_unicode(input) + input = input.to_s unless input.is_a?(String) + parts = input.split('.') + parts.map! do |part| + if part =~ /^#{ACE_PREFIX}(.+)/ + begin + punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1]) + rescue Addressable::IDNA::PunycodeBadInput + # toUnicode is explicitly defined as never-fails by the spec + part + end + else + part + end + end + output = parts.join('.') + if output.respond_to?(:force_encoding) + output.force_encoding(Encoding::UTF_8) + end + output + end + + class << self + # @deprecated Use {String#unicode_normalize(:nfkc)} instead + def unicode_normalize_kc(value) + value.to_s.unicode_normalize(:nfkc) + end + + extend Gem::Deprecate + deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4 + end + + ## + # Unicode aware downcase method. + # + # @api private + # @param [String] input + # The input string. + # @return [String] The downcased result. + def self.unicode_downcase(input) + input = input.to_s unless input.is_a?(String) + unpacked = input.unpack("U*") + unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) } + return unpacked.pack("U*") + end + private_class_method :unicode_downcase + + def self.lookup_unicode_lowercase(codepoint) + codepoint_data = UNICODE_DATA[codepoint] + (codepoint_data ? + (codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) : + codepoint) + end + private_class_method :lookup_unicode_lowercase + + UNICODE_DATA_COMBINING_CLASS = 0 + UNICODE_DATA_EXCLUSION = 1 + UNICODE_DATA_CANONICAL = 2 + UNICODE_DATA_COMPATIBILITY = 3 + UNICODE_DATA_UPPERCASE = 4 + UNICODE_DATA_LOWERCASE = 5 + UNICODE_DATA_TITLECASE = 6 + + UNICODE_DATA = { + 65 => [0, 0, nil, nil, nil, 97, nil], + 66 => [0, 0, nil, nil, nil, 98, nil], + 67 => [0, 0, nil, nil, nil, 99, nil], + 68 => [0, 0, nil, nil, nil, 100, nil], + 69 => [0, 0, nil, nil, nil, 101, nil], + 70 => [0, 0, nil, nil, nil, 102, nil], + 71 => [0, 0, nil, nil, nil, 103, nil], + 72 => [0, 0, nil, nil, nil, 104, nil], + 73 => [0, 0, nil, nil, nil, 105, nil], + 74 => [0, 0, nil, nil, nil, 106, nil], + 75 => [0, 0, nil, nil, nil, 107, nil], + 76 => [0, 0, nil, nil, nil, 108, nil], + 77 => [0, 0, nil, nil, nil, 109, nil], + 78 => [0, 0, nil, nil, nil, 110, nil], + 79 => [0, 0, nil, nil, nil, 111, nil], + 80 => [0, 0, nil, nil, nil, 112, nil], + 81 => [0, 0, nil, nil, nil, 113, nil], + 82 => [0, 0, nil, nil, nil, 114, nil], + 83 => [0, 0, nil, nil, nil, 115, nil], + 84 => [0, 0, nil, nil, nil, 116, nil], + 85 => [0, 0, nil, nil, nil, 117, nil], + 86 => [0, 0, nil, nil, nil, 118, nil], + 87 => [0, 0, nil, nil, nil, 119, nil], + 88 => [0, 0, nil, nil, nil, 120, nil], + 89 => [0, 0, nil, nil, nil, 121, nil], + 90 => [0, 0, nil, nil, nil, 122, nil], + 97 => [0, 0, nil, nil, 65, nil, 65], + 98 => [0, 0, nil, nil, 66, nil, 66], + 99 => [0, 0, nil, nil, 67, nil, 67], + 100 => [0, 0, nil, nil, 68, nil, 68], + 101 => [0, 0, nil, nil, 69, nil, 69], + 102 => [0, 0, nil, nil, 70, nil, 70], + 103 => [0, 0, nil, nil, 71, nil, 71], + 104 => [0, 0, nil, nil, 72, nil, 72], + 105 => [0, 0, nil, nil, 73, nil, 73], + 106 => [0, 0, nil, nil, 74, nil, 74], + 107 => [0, 0, nil, nil, 75, nil, 75], + 108 => [0, 0, nil, nil, 76, nil, 76], + 109 => [0, 0, nil, nil, 77, nil, 77], + 110 => [0, 0, nil, nil, 78, nil, 78], + 111 => [0, 0, nil, nil, 79, nil, 79], + 112 => [0, 0, nil, nil, 80, nil, 80], + 113 => [0, 0, nil, nil, 81, nil, 81], + 114 => [0, 0, nil, nil, 82, nil, 82], + 115 => [0, 0, nil, nil, 83, nil, 83], + 116 => [0, 0, nil, nil, 84, nil, 84], + 117 => [0, 0, nil, nil, 85, nil, 85], + 118 => [0, 0, nil, nil, 86, nil, 86], + 119 => [0, 0, nil, nil, 87, nil, 87], + 120 => [0, 0, nil, nil, 88, nil, 88], + 121 => [0, 0, nil, nil, 89, nil, 89], + 122 => [0, 0, nil, nil, 90, nil, 90], + 160 => [0, 0, nil, " ", nil, nil, nil], + 168 => [0, 0, nil, " ̈", nil, nil, nil], + 170 => [0, 0, nil, "a", nil, nil, nil], + 175 => [0, 0, nil, " ̄", nil, nil, nil], + 178 => [0, 0, nil, "2", nil, nil, nil], + 179 => [0, 0, nil, "3", nil, nil, nil], + 180 => [0, 0, nil, " ́", nil, nil, nil], + 181 => [0, 0, nil, "μ", 924, nil, 924], + 184 => [0, 0, nil, " ̧", nil, nil, nil], + 185 => [0, 0, nil, "1", nil, nil, nil], + 186 => [0, 0, nil, "o", nil, nil, nil], + 188 => [0, 0, nil, "1⁄4", nil, nil, nil], + 189 => [0, 0, nil, "1⁄2", nil, nil, nil], + 190 => [0, 0, nil, "3⁄4", nil, nil, nil], + 192 => [0, 0, "À", "À", nil, 224, nil], + 193 => [0, 0, "Á", "Á", nil, 225, nil], + 194 => [0, 0, "Â", "Â", nil, 226, nil], + 195 => [0, 0, "Ã", "Ã", nil, 227, nil], + 196 => [0, 0, "Ä", "Ä", nil, 228, nil], + 197 => [0, 0, "Å", "Å", nil, 229, nil], + 198 => [0, 0, nil, nil, nil, 230, nil], + 199 => [0, 0, "Ç", "Ç", nil, 231, nil], + 200 => [0, 0, "È", "È", nil, 232, nil], + 201 => [0, 0, "É", "É", nil, 233, nil], + 202 => [0, 0, "Ê", "Ê", nil, 234, nil], + 203 => [0, 0, "Ë", "Ë", nil, 235, nil], + 204 => [0, 0, "Ì", "Ì", nil, 236, nil], + 205 => [0, 0, "Í", "Í", nil, 237, nil], + 206 => [0, 0, "Î", "Î", nil, 238, nil], + 207 => [0, 0, "Ï", "Ï", nil, 239, nil], + 208 => [0, 0, nil, nil, nil, 240, nil], + 209 => [0, 0, "Ñ", "Ñ", nil, 241, nil], + 210 => [0, 0, "Ò", "Ò", nil, 242, nil], + 211 => [0, 0, "Ó", "Ó", nil, 243, nil], + 212 => [0, 0, "Ô", "Ô", nil, 244, nil], + 213 => [0, 0, "Õ", "Õ", nil, 245, nil], + 214 => [0, 0, "Ö", "Ö", nil, 246, nil], + 216 => [0, 0, nil, nil, nil, 248, nil], + 217 => [0, 0, "Ù", "Ù", nil, 249, nil], + 218 => [0, 0, "Ú", "Ú", nil, 250, nil], + 219 => [0, 0, "Û", "Û", nil, 251, nil], + 220 => [0, 0, "Ü", "Ü", nil, 252, nil], + 221 => [0, 0, "Ý", "Ý", nil, 253, nil], + 222 => [0, 0, nil, nil, nil, 254, nil], + 224 => [0, 0, "à", "à", 192, nil, 192], + 225 => [0, 0, "á", "á", 193, nil, 193], + 226 => [0, 0, "â", "â", 194, nil, 194], + 227 => [0, 0, "ã", "ã", 195, nil, 195], + 228 => [0, 0, "ä", "ä", 196, nil, 196], + 229 => [0, 0, "å", "å", 197, nil, 197], + 230 => [0, 0, nil, nil, 198, nil, 198], + 231 => [0, 0, "ç", "ç", 199, nil, 199], + 232 => [0, 0, "è", "è", 200, nil, 200], + 233 => [0, 0, "é", "é", 201, nil, 201], + 234 => [0, 0, "ê", "ê", 202, nil, 202], + 235 => [0, 0, "ë", "ë", 203, nil, 203], + 236 => [0, 0, "ì", "ì", 204, nil, 204], + 237 => [0, 0, "í", "í", 205, nil, 205], + 238 => [0, 0, "î", "î", 206, nil, 206], + 239 => [0, 0, "ï", "ï", 207, nil, 207], + 240 => [0, 0, nil, nil, 208, nil, 208], + 241 => [0, 0, "ñ", "ñ", 209, nil, 209], + 242 => [0, 0, "ò", "ò", 210, nil, 210], + 243 => [0, 0, "ó", "ó", 211, nil, 211], + 244 => [0, 0, "ô", "ô", 212, nil, 212], + 245 => [0, 0, "õ", "õ", 213, nil, 213], + 246 => [0, 0, "ö", "ö", 214, nil, 214], + 248 => [0, 0, nil, nil, 216, nil, 216], + 249 => [0, 0, "ù", "ù", 217, nil, 217], + 250 => [0, 0, "ú", "ú", 218, nil, 218], + 251 => [0, 0, "û", "û", 219, nil, 219], + 252 => [0, 0, "ü", "ü", 220, nil, 220], + 253 => [0, 0, "ý", "ý", 221, nil, 221], + 254 => [0, 0, nil, nil, 222, nil, 222], + 255 => [0, 0, "ÿ", "ÿ", 376, nil, 376], + 256 => [0, 0, "Ā", "Ā", nil, 257, nil], + 257 => [0, 0, "ā", "ā", 256, nil, 256], + 258 => [0, 0, "Ă", "Ă", nil, 259, nil], + 259 => [0, 0, "ă", "ă", 258, nil, 258], + 260 => [0, 0, "Ą", "Ą", nil, 261, nil], + 261 => [0, 0, "ą", "ą", 260, nil, 260], + 262 => [0, 0, "Ć", "Ć", nil, 263, nil], + 263 => [0, 0, "ć", "ć", 262, nil, 262], + 264 => [0, 0, "Ĉ", "Ĉ", nil, 265, nil], + 265 => [0, 0, "ĉ", "ĉ", 264, nil, 264], + 266 => [0, 0, "Ċ", "Ċ", nil, 267, nil], + 267 => [0, 0, "ċ", "ċ", 266, nil, 266], + 268 => [0, 0, "Č", "Č", nil, 269, nil], + 269 => [0, 0, "č", "č", 268, nil, 268], + 270 => [0, 0, "Ď", "Ď", nil, 271, nil], + 271 => [0, 0, "ď", "ď", 270, nil, 270], + 272 => [0, 0, nil, nil, nil, 273, nil], + 273 => [0, 0, nil, nil, 272, nil, 272], + 274 => [0, 0, "Ē", "Ē", nil, 275, nil], + 275 => [0, 0, "ē", "ē", 274, nil, 274], + 276 => [0, 0, "Ĕ", "Ĕ", nil, 277, nil], + 277 => [0, 0, "ĕ", "ĕ", 276, nil, 276], + 278 => [0, 0, "Ė", "Ė", nil, 279, nil], + 279 => [0, 0, "ė", "ė", 278, nil, 278], + 280 => [0, 0, "Ę", "Ę", nil, 281, nil], + 281 => [0, 0, "ę", "ę", 280, nil, 280], + 282 => [0, 0, "Ě", "Ě", nil, 283, nil], + 283 => [0, 0, "ě", "ě", 282, nil, 282], + 284 => [0, 0, "Ĝ", "Ĝ", nil, 285, nil], + 285 => [0, 0, "ĝ", "ĝ", 284, nil, 284], + 286 => [0, 0, "Ğ", "Ğ", nil, 287, nil], + 287 => [0, 0, "ğ", "ğ", 286, nil, 286], + 288 => [0, 0, "Ġ", "Ġ", nil, 289, nil], + 289 => [0, 0, "ġ", "ġ", 288, nil, 288], + 290 => [0, 0, "Ģ", "Ģ", nil, 291, nil], + 291 => [0, 0, "ģ", "ģ", 290, nil, 290], + 292 => [0, 0, "Ĥ", "Ĥ", nil, 293, nil], + 293 => [0, 0, "ĥ", "ĥ", 292, nil, 292], + 294 => [0, 0, nil, nil, nil, 295, nil], + 295 => [0, 0, nil, nil, 294, nil, 294], + 296 => [0, 0, "Ĩ", "Ĩ", nil, 297, nil], + 297 => [0, 0, "ĩ", "ĩ", 296, nil, 296], + 298 => [0, 0, "Ī", "Ī", nil, 299, nil], + 299 => [0, 0, "ī", "ī", 298, nil, 298], + 300 => [0, 0, "Ĭ", "Ĭ", nil, 301, nil], + 301 => [0, 0, "ĭ", "ĭ", 300, nil, 300], + 302 => [0, 0, "Į", "Į", nil, 303, nil], + 303 => [0, 0, "į", "į", 302, nil, 302], + 304 => [0, 0, "İ", "İ", nil, 105, nil], + 305 => [0, 0, nil, nil, 73, nil, 73], + 306 => [0, 0, nil, "IJ", nil, 307, nil], + 307 => [0, 0, nil, "ij", 306, nil, 306], + 308 => [0, 0, "Ĵ", "Ĵ", nil, 309, nil], + 309 => [0, 0, "ĵ", "ĵ", 308, nil, 308], + 310 => [0, 0, "Ķ", "Ķ", nil, 311, nil], + 311 => [0, 0, "ķ", "ķ", 310, nil, 310], + 313 => [0, 0, "Ĺ", "Ĺ", nil, 314, nil], + 314 => [0, 0, "ĺ", "ĺ", 313, nil, 313], + 315 => [0, 0, "Ļ", "Ļ", nil, 316, nil], + 316 => [0, 0, "ļ", "ļ", 315, nil, 315], + 317 => [0, 0, "Ľ", "Ľ", nil, 318, nil], + 318 => [0, 0, "ľ", "ľ", 317, nil, 317], + 319 => [0, 0, nil, "L·", nil, 320, nil], + 320 => [0, 0, nil, "l·", 319, nil, 319], + 321 => [0, 0, nil, nil, nil, 322, nil], + 322 => [0, 0, nil, nil, 321, nil, 321], + 323 => [0, 0, "Ń", "Ń", nil, 324, nil], + 324 => [0, 0, "ń", "ń", 323, nil, 323], + 325 => [0, 0, "Ņ", "Ņ", nil, 326, nil], + 326 => [0, 0, "ņ", "ņ", 325, nil, 325], + 327 => [0, 0, "Ň", "Ň", nil, 328, nil], + 328 => [0, 0, "ň", "ň", 327, nil, 327], + 329 => [0, 0, nil, "ʼn", nil, nil, nil], + 330 => [0, 0, nil, nil, nil, 331, nil], + 331 => [0, 0, nil, nil, 330, nil, 330], + 332 => [0, 0, "Ō", "Ō", nil, 333, nil], + 333 => [0, 0, "ō", "ō", 332, nil, 332], + 334 => [0, 0, "Ŏ", "Ŏ", nil, 335, nil], + 335 => [0, 0, "ŏ", "ŏ", 334, nil, 334], + 336 => [0, 0, "Ő", "Ő", nil, 337, nil], + 337 => [0, 0, "ő", "ő", 336, nil, 336], + 338 => [0, 0, nil, nil, nil, 339, nil], + 339 => [0, 0, nil, nil, 338, nil, 338], + 340 => [0, 0, "Ŕ", "Ŕ", nil, 341, nil], + 341 => [0, 0, "ŕ", "ŕ", 340, nil, 340], + 342 => [0, 0, "Ŗ", "Ŗ", nil, 343, nil], + 343 => [0, 0, "ŗ", "ŗ", 342, nil, 342], + 344 => [0, 0, "Ř", "Ř", nil, 345, nil], + 345 => [0, 0, "ř", "ř", 344, nil, 344], + 346 => [0, 0, "Ś", "Ś", nil, 347, nil], + 347 => [0, 0, "ś", "ś", 346, nil, 346], + 348 => [0, 0, "Ŝ", "Ŝ", nil, 349, nil], + 349 => [0, 0, "ŝ", "ŝ", 348, nil, 348], + 350 => [0, 0, "Ş", "Ş", nil, 351, nil], + 351 => [0, 0, "ş", "ş", 350, nil, 350], + 352 => [0, 0, "Š", "Š", nil, 353, nil], + 353 => [0, 0, "š", "š", 352, nil, 352], + 354 => [0, 0, "Ţ", "Ţ", nil, 355, nil], + 355 => [0, 0, "ţ", "ţ", 354, nil, 354], + 356 => [0, 0, "Ť", "Ť", nil, 357, nil], + 357 => [0, 0, "ť", "ť", 356, nil, 356], + 358 => [0, 0, nil, nil, nil, 359, nil], + 359 => [0, 0, nil, nil, 358, nil, 358], + 360 => [0, 0, "Ũ", "Ũ", nil, 361, nil], + 361 => [0, 0, "ũ", "ũ", 360, nil, 360], + 362 => [0, 0, "Ū", "Ū", nil, 363, nil], + 363 => [0, 0, "ū", "ū", 362, nil, 362], + 364 => [0, 0, "Ŭ", "Ŭ", nil, 365, nil], + 365 => [0, 0, "ŭ", "ŭ", 364, nil, 364], + 366 => [0, 0, "Ů", "Ů", nil, 367, nil], + 367 => [0, 0, "ů", "ů", 366, nil, 366], + 368 => [0, 0, "Ű", "Ű", nil, 369, nil], + 369 => [0, 0, "ű", "ű", 368, nil, 368], + 370 => [0, 0, "Ų", "Ų", nil, 371, nil], + 371 => [0, 0, "ų", "ų", 370, nil, 370], + 372 => [0, 0, "Ŵ", "Ŵ", nil, 373, nil], + 373 => [0, 0, "ŵ", "ŵ", 372, nil, 372], + 374 => [0, 0, "Ŷ", "Ŷ", nil, 375, nil], + 375 => [0, 0, "ŷ", "ŷ", 374, nil, 374], + 376 => [0, 0, "Ÿ", "Ÿ", nil, 255, nil], + 377 => [0, 0, "Ź", "Ź", nil, 378, nil], + 378 => [0, 0, "ź", "ź", 377, nil, 377], + 379 => [0, 0, "Ż", "Ż", nil, 380, nil], + 380 => [0, 0, "ż", "ż", 379, nil, 379], + 381 => [0, 0, "Ž", "Ž", nil, 382, nil], + 382 => [0, 0, "ž", "ž", 381, nil, 381], + 383 => [0, 0, nil, "s", 83, nil, 83], + 385 => [0, 0, nil, nil, nil, 595, nil], + 386 => [0, 0, nil, nil, nil, 387, nil], + 387 => [0, 0, nil, nil, 386, nil, 386], + 388 => [0, 0, nil, nil, nil, 389, nil], + 389 => [0, 0, nil, nil, 388, nil, 388], + 390 => [0, 0, nil, nil, nil, 596, nil], + 391 => [0, 0, nil, nil, nil, 392, nil], + 392 => [0, 0, nil, nil, 391, nil, 391], + 393 => [0, 0, nil, nil, nil, 598, nil], + 394 => [0, 0, nil, nil, nil, 599, nil], + 395 => [0, 0, nil, nil, nil, 396, nil], + 396 => [0, 0, nil, nil, 395, nil, 395], + 398 => [0, 0, nil, nil, nil, 477, nil], + 399 => [0, 0, nil, nil, nil, 601, nil], + 400 => [0, 0, nil, nil, nil, 603, nil], + 401 => [0, 0, nil, nil, nil, 402, nil], + 402 => [0, 0, nil, nil, 401, nil, 401], + 403 => [0, 0, nil, nil, nil, 608, nil], + 404 => [0, 0, nil, nil, nil, 611, nil], + 405 => [0, 0, nil, nil, 502, nil, 502], + 406 => [0, 0, nil, nil, nil, 617, nil], + 407 => [0, 0, nil, nil, nil, 616, nil], + 408 => [0, 0, nil, nil, nil, 409, nil], + 409 => [0, 0, nil, nil, 408, nil, 408], + 412 => [0, 0, nil, nil, nil, 623, nil], + 413 => [0, 0, nil, nil, nil, 626, nil], + 415 => [0, 0, nil, nil, nil, 629, nil], + 416 => [0, 0, "Ơ", "Ơ", nil, 417, nil], + 417 => [0, 0, "ơ", "ơ", 416, nil, 416], + 418 => [0, 0, nil, nil, nil, 419, nil], + 419 => [0, 0, nil, nil, 418, nil, 418], + 420 => [0, 0, nil, nil, nil, 421, nil], + 421 => [0, 0, nil, nil, 420, nil, 420], + 422 => [0, 0, nil, nil, nil, 640, nil], + 423 => [0, 0, nil, nil, nil, 424, nil], + 424 => [0, 0, nil, nil, 423, nil, 423], + 425 => [0, 0, nil, nil, nil, 643, nil], + 428 => [0, 0, nil, nil, nil, 429, nil], + 429 => [0, 0, nil, nil, 428, nil, 428], + 430 => [0, 0, nil, nil, nil, 648, nil], + 431 => [0, 0, "Ư", "Ư", nil, 432, nil], + 432 => [0, 0, "ư", "ư", 431, nil, 431], + 433 => [0, 0, nil, nil, nil, 650, nil], + 434 => [0, 0, nil, nil, nil, 651, nil], + 435 => [0, 0, nil, nil, nil, 436, nil], + 436 => [0, 0, nil, nil, 435, nil, 435], + 437 => [0, 0, nil, nil, nil, 438, nil], + 438 => [0, 0, nil, nil, 437, nil, 437], + 439 => [0, 0, nil, nil, nil, 658, nil], + 440 => [0, 0, nil, nil, nil, 441, nil], + 441 => [0, 0, nil, nil, 440, nil, 440], + 444 => [0, 0, nil, nil, nil, 445, nil], + 445 => [0, 0, nil, nil, 444, nil, 444], + 447 => [0, 0, nil, nil, 503, nil, 503], + 452 => [0, 0, nil, "DŽ", nil, 454, 453], + 453 => [0, 0, nil, "Dž", 452, 454, nil], + 454 => [0, 0, nil, "dž", 452, nil, 453], + 455 => [0, 0, nil, "LJ", nil, 457, 456], + 456 => [0, 0, nil, "Lj", 455, 457, nil], + 457 => [0, 0, nil, "lj", 455, nil, 456], + 458 => [0, 0, nil, "NJ", nil, 460, 459], + 459 => [0, 0, nil, "Nj", 458, 460, nil], + 460 => [0, 0, nil, "nj", 458, nil, 459], + 461 => [0, 0, "Ǎ", "Ǎ", nil, 462, nil], + 462 => [0, 0, "ǎ", "ǎ", 461, nil, 461], + 463 => [0, 0, "Ǐ", "Ǐ", nil, 464, nil], + 464 => [0, 0, "ǐ", "ǐ", 463, nil, 463], + 465 => [0, 0, "Ǒ", "Ǒ", nil, 466, nil], + 466 => [0, 0, "ǒ", "ǒ", 465, nil, 465], + 467 => [0, 0, "Ǔ", "Ǔ", nil, 468, nil], + 468 => [0, 0, "ǔ", "ǔ", 467, nil, 467], + 469 => [0, 0, "Ǖ", "Ǖ", nil, 470, nil], + 470 => [0, 0, "ǖ", "ǖ", 469, nil, 469], + 471 => [0, 0, "Ǘ", "Ǘ", nil, 472, nil], + 472 => [0, 0, "ǘ", "ǘ", 471, nil, 471], + 473 => [0, 0, "Ǚ", "Ǚ", nil, 474, nil], + 474 => [0, 0, "ǚ", "ǚ", 473, nil, 473], + 475 => [0, 0, "Ǜ", "Ǜ", nil, 476, nil], + 476 => [0, 0, "ǜ", "ǜ", 475, nil, 475], + 477 => [0, 0, nil, nil, 398, nil, 398], + 478 => [0, 0, "Ǟ", "Ǟ", nil, 479, nil], + 479 => [0, 0, "ǟ", "ǟ", 478, nil, 478], + 480 => [0, 0, "Ǡ", "Ǡ", nil, 481, nil], + 481 => [0, 0, "ǡ", "ǡ", 480, nil, 480], + 482 => [0, 0, "Ǣ", "Ǣ", nil, 483, nil], + 483 => [0, 0, "ǣ", "ǣ", 482, nil, 482], + 484 => [0, 0, nil, nil, nil, 485, nil], + 485 => [0, 0, nil, nil, 484, nil, 484], + 486 => [0, 0, "Ǧ", "Ǧ", nil, 487, nil], + 487 => [0, 0, "ǧ", "ǧ", 486, nil, 486], + 488 => [0, 0, "Ǩ", "Ǩ", nil, 489, nil], + 489 => [0, 0, "ǩ", "ǩ", 488, nil, 488], + 490 => [0, 0, "Ǫ", "Ǫ", nil, 491, nil], + 491 => [0, 0, "ǫ", "ǫ", 490, nil, 490], + 492 => [0, 0, "Ǭ", "Ǭ", nil, 493, nil], + 493 => [0, 0, "ǭ", "ǭ", 492, nil, 492], + 494 => [0, 0, "Ǯ", "Ǯ", nil, 495, nil], + 495 => [0, 0, "ǯ", "ǯ", 494, nil, 494], + 496 => [0, 0, "ǰ", "ǰ", nil, nil, nil], + 497 => [0, 0, nil, "DZ", nil, 499, 498], + 498 => [0, 0, nil, "Dz", 497, 499, nil], + 499 => [0, 0, nil, "dz", 497, nil, 498], + 500 => [0, 0, "Ǵ", "Ǵ", nil, 501, nil], + 501 => [0, 0, "ǵ", "ǵ", 500, nil, 500], + 502 => [0, 0, nil, nil, nil, 405, nil], + 503 => [0, 0, nil, nil, nil, 447, nil], + 504 => [0, 0, "Ǹ", "Ǹ", nil, 505, nil], + 505 => [0, 0, "ǹ", "ǹ", 504, nil, 504], + 506 => [0, 0, "Ǻ", "Ǻ", nil, 507, nil], + 507 => [0, 0, "ǻ", "ǻ", 506, nil, 506], + 508 => [0, 0, "Ǽ", "Ǽ", nil, 509, nil], + 509 => [0, 0, "ǽ", "ǽ", 508, nil, 508], + 510 => [0, 0, "Ǿ", "Ǿ", nil, 511, nil], + 511 => [0, 0, "ǿ", "ǿ", 510, nil, 510], + 512 => [0, 0, "Ȁ", "Ȁ", nil, 513, nil], + 513 => [0, 0, "ȁ", "ȁ", 512, nil, 512], + 514 => [0, 0, "Ȃ", "Ȃ", nil, 515, nil], + 515 => [0, 0, "ȃ", "ȃ", 514, nil, 514], + 516 => [0, 0, "Ȅ", "Ȅ", nil, 517, nil], + 517 => [0, 0, "ȅ", "ȅ", 516, nil, 516], + 518 => [0, 0, "Ȇ", "Ȇ", nil, 519, nil], + 519 => [0, 0, "ȇ", "ȇ", 518, nil, 518], + 520 => [0, 0, "Ȉ", "Ȉ", nil, 521, nil], + 521 => [0, 0, "ȉ", "ȉ", 520, nil, 520], + 522 => [0, 0, "Ȋ", "Ȋ", nil, 523, nil], + 523 => [0, 0, "ȋ", "ȋ", 522, nil, 522], + 524 => [0, 0, "Ȍ", "Ȍ", nil, 525, nil], + 525 => [0, 0, "ȍ", "ȍ", 524, nil, 524], + 526 => [0, 0, "Ȏ", "Ȏ", nil, 527, nil], + 527 => [0, 0, "ȏ", "ȏ", 526, nil, 526], + 528 => [0, 0, "Ȑ", "Ȑ", nil, 529, nil], + 529 => [0, 0, "ȑ", "ȑ", 528, nil, 528], + 530 => [0, 0, "Ȓ", "Ȓ", nil, 531, nil], + 531 => [0, 0, "ȓ", "ȓ", 530, nil, 530], + 532 => [0, 0, "Ȕ", "Ȕ", nil, 533, nil], + 533 => [0, 0, "ȕ", "ȕ", 532, nil, 532], + 534 => [0, 0, "Ȗ", "Ȗ", nil, 535, nil], + 535 => [0, 0, "ȗ", "ȗ", 534, nil, 534], + 536 => [0, 0, "Ș", "Ș", nil, 537, nil], + 537 => [0, 0, "ș", "ș", 536, nil, 536], + 538 => [0, 0, "Ț", "Ț", nil, 539, nil], + 539 => [0, 0, "ț", "ț", 538, nil, 538], + 540 => [0, 0, nil, nil, nil, 541, nil], + 541 => [0, 0, nil, nil, 540, nil, 540], + 542 => [0, 0, "Ȟ", "Ȟ", nil, 543, nil], + 543 => [0, 0, "ȟ", "ȟ", 542, nil, 542], + 546 => [0, 0, nil, nil, nil, 547, nil], + 547 => [0, 0, nil, nil, 546, nil, 546], + 548 => [0, 0, nil, nil, nil, 549, nil], + 549 => [0, 0, nil, nil, 548, nil, 548], + 550 => [0, 0, "Ȧ", "Ȧ", nil, 551, nil], + 551 => [0, 0, "ȧ", "ȧ", 550, nil, 550], + 552 => [0, 0, "Ȩ", "Ȩ", nil, 553, nil], + 553 => [0, 0, "ȩ", "ȩ", 552, nil, 552], + 554 => [0, 0, "Ȫ", "Ȫ", nil, 555, nil], + 555 => [0, 0, "ȫ", "ȫ", 554, nil, 554], + 556 => [0, 0, "Ȭ", "Ȭ", nil, 557, nil], + 557 => [0, 0, "ȭ", "ȭ", 556, nil, 556], + 558 => [0, 0, "Ȯ", "Ȯ", nil, 559, nil], + 559 => [0, 0, "ȯ", "ȯ", 558, nil, 558], + 560 => [0, 0, "Ȱ", "Ȱ", nil, 561, nil], + 561 => [0, 0, "ȱ", "ȱ", 560, nil, 560], + 562 => [0, 0, "Ȳ", "Ȳ", nil, 563, nil], + 563 => [0, 0, "ȳ", "ȳ", 562, nil, 562], + 595 => [0, 0, nil, nil, 385, nil, 385], + 596 => [0, 0, nil, nil, 390, nil, 390], + 598 => [0, 0, nil, nil, 393, nil, 393], + 599 => [0, 0, nil, nil, 394, nil, 394], + 601 => [0, 0, nil, nil, 399, nil, 399], + 603 => [0, 0, nil, nil, 400, nil, 400], + 608 => [0, 0, nil, nil, 403, nil, 403], + 611 => [0, 0, nil, nil, 404, nil, 404], + 616 => [0, 0, nil, nil, 407, nil, 407], + 617 => [0, 0, nil, nil, 406, nil, 406], + 623 => [0, 0, nil, nil, 412, nil, 412], + 626 => [0, 0, nil, nil, 413, nil, 413], + 629 => [0, 0, nil, nil, 415, nil, 415], + 640 => [0, 0, nil, nil, 422, nil, 422], + 643 => [0, 0, nil, nil, 425, nil, 425], + 648 => [0, 0, nil, nil, 430, nil, 430], + 650 => [0, 0, nil, nil, 433, nil, 433], + 651 => [0, 0, nil, nil, 434, nil, 434], + 658 => [0, 0, nil, nil, 439, nil, 439], + 688 => [0, 0, nil, "h", nil, nil, nil], + 689 => [0, 0, nil, "ɦ", nil, nil, nil], + 690 => [0, 0, nil, "j", nil, nil, nil], + 691 => [0, 0, nil, "r", nil, nil, nil], + 692 => [0, 0, nil, "ɹ", nil, nil, nil], + 693 => [0, 0, nil, "ɻ", nil, nil, nil], + 694 => [0, 0, nil, "ʁ", nil, nil, nil], + 695 => [0, 0, nil, "w", nil, nil, nil], + 696 => [0, 0, nil, "y", nil, nil, nil], + 728 => [0, 0, nil, " ̆", nil, nil, nil], + 729 => [0, 0, nil, " ̇", nil, nil, nil], + 730 => [0, 0, nil, " ̊", nil, nil, nil], + 731 => [0, 0, nil, " ̨", nil, nil, nil], + 732 => [0, 0, nil, " ̃", nil, nil, nil], + 733 => [0, 0, nil, " ̋", nil, nil, nil], + 736 => [0, 0, nil, "ɣ", nil, nil, nil], + 737 => [0, 0, nil, "l", nil, nil, nil], + 738 => [0, 0, nil, "s", nil, nil, nil], + 739 => [0, 0, nil, "x", nil, nil, nil], + 740 => [0, 0, nil, "ʕ", nil, nil, nil], + 768 => [230, 0, nil, nil, nil, nil, nil], + 769 => [230, 0, nil, nil, nil, nil, nil], + 770 => [230, 0, nil, nil, nil, nil, nil], + 771 => [230, 0, nil, nil, nil, nil, nil], + 772 => [230, 0, nil, nil, nil, nil, nil], + 773 => [230, 0, nil, nil, nil, nil, nil], + 774 => [230, 0, nil, nil, nil, nil, nil], + 775 => [230, 0, nil, nil, nil, nil, nil], + 776 => [230, 0, nil, nil, nil, nil, nil], + 777 => [230, 0, nil, nil, nil, nil, nil], + 778 => [230, 0, nil, nil, nil, nil, nil], + 779 => [230, 0, nil, nil, nil, nil, nil], + 780 => [230, 0, nil, nil, nil, nil, nil], + 781 => [230, 0, nil, nil, nil, nil, nil], + 782 => [230, 0, nil, nil, nil, nil, nil], + 783 => [230, 0, nil, nil, nil, nil, nil], + 784 => [230, 0, nil, nil, nil, nil, nil], + 785 => [230, 0, nil, nil, nil, nil, nil], + 786 => [230, 0, nil, nil, nil, nil, nil], + 787 => [230, 0, nil, nil, nil, nil, nil], + 788 => [230, 0, nil, nil, nil, nil, nil], + 789 => [232, 0, nil, nil, nil, nil, nil], + 790 => [220, 0, nil, nil, nil, nil, nil], + 791 => [220, 0, nil, nil, nil, nil, nil], + 792 => [220, 0, nil, nil, nil, nil, nil], + 793 => [220, 0, nil, nil, nil, nil, nil], + 794 => [232, 0, nil, nil, nil, nil, nil], + 795 => [216, 0, nil, nil, nil, nil, nil], + 796 => [220, 0, nil, nil, nil, nil, nil], + 797 => [220, 0, nil, nil, nil, nil, nil], + 798 => [220, 0, nil, nil, nil, nil, nil], + 799 => [220, 0, nil, nil, nil, nil, nil], + 800 => [220, 0, nil, nil, nil, nil, nil], + 801 => [202, 0, nil, nil, nil, nil, nil], + 802 => [202, 0, nil, nil, nil, nil, nil], + 803 => [220, 0, nil, nil, nil, nil, nil], + 804 => [220, 0, nil, nil, nil, nil, nil], + 805 => [220, 0, nil, nil, nil, nil, nil], + 806 => [220, 0, nil, nil, nil, nil, nil], + 807 => [202, 0, nil, nil, nil, nil, nil], + 808 => [202, 0, nil, nil, nil, nil, nil], + 809 => [220, 0, nil, nil, nil, nil, nil], + 810 => [220, 0, nil, nil, nil, nil, nil], + 811 => [220, 0, nil, nil, nil, nil, nil], + 812 => [220, 0, nil, nil, nil, nil, nil], + 813 => [220, 0, nil, nil, nil, nil, nil], + 814 => [220, 0, nil, nil, nil, nil, nil], + 815 => [220, 0, nil, nil, nil, nil, nil], + 816 => [220, 0, nil, nil, nil, nil, nil], + 817 => [220, 0, nil, nil, nil, nil, nil], + 818 => [220, 0, nil, nil, nil, nil, nil], + 819 => [220, 0, nil, nil, nil, nil, nil], + 820 => [1, 0, nil, nil, nil, nil, nil], + 821 => [1, 0, nil, nil, nil, nil, nil], + 822 => [1, 0, nil, nil, nil, nil, nil], + 823 => [1, 0, nil, nil, nil, nil, nil], + 824 => [1, 0, nil, nil, nil, nil, nil], + 825 => [220, 0, nil, nil, nil, nil, nil], + 826 => [220, 0, nil, nil, nil, nil, nil], + 827 => [220, 0, nil, nil, nil, nil, nil], + 828 => [220, 0, nil, nil, nil, nil, nil], + 829 => [230, 0, nil, nil, nil, nil, nil], + 830 => [230, 0, nil, nil, nil, nil, nil], + 831 => [230, 0, nil, nil, nil, nil, nil], + 832 => [230, 2, "̀", "̀", nil, nil, nil], + 833 => [230, 2, "́", "́", nil, nil, nil], + 834 => [230, 0, nil, nil, nil, nil, nil], + 835 => [230, 2, "̓", "̓", nil, nil, nil], + 836 => [230, 3, "̈́", "̈́", nil, nil, nil], + 837 => [240, 0, nil, nil, 921, nil, 921], + 838 => [230, 0, nil, nil, nil, nil, nil], + 839 => [220, 0, nil, nil, nil, nil, nil], + 840 => [220, 0, nil, nil, nil, nil, nil], + 841 => [220, 0, nil, nil, nil, nil, nil], + 842 => [230, 0, nil, nil, nil, nil, nil], + 843 => [230, 0, nil, nil, nil, nil, nil], + 844 => [230, 0, nil, nil, nil, nil, nil], + 845 => [220, 0, nil, nil, nil, nil, nil], + 846 => [220, 0, nil, nil, nil, nil, nil], + 864 => [234, 0, nil, nil, nil, nil, nil], + 865 => [234, 0, nil, nil, nil, nil, nil], + 866 => [233, 0, nil, nil, nil, nil, nil], + 884 => [0, 2, "ʹ", "ʹ", nil, nil, nil], + 890 => [0, 0, nil, " ͅ", nil, nil, nil], + 894 => [0, 2, ";", ";", nil, nil, nil], + 900 => [0, 0, nil, " ́", nil, nil, nil], + 901 => [0, 0, "΅", "΅", nil, nil, nil], + 902 => [0, 0, "Ά", "Ά", nil, 940, nil], + 903 => [0, 2, "·", "·", nil, nil, nil], + 904 => [0, 0, "Έ", "Έ", nil, 941, nil], + 905 => [0, 0, "Ή", "Ή", nil, 942, nil], + 906 => [0, 0, "Ί", "Ί", nil, 943, nil], + 908 => [0, 0, "Ό", "Ό", nil, 972, nil], + 910 => [0, 0, "Ύ", "Ύ", nil, 973, nil], + 911 => [0, 0, "Ώ", "Ώ", nil, 974, nil], + 912 => [0, 0, "ΐ", "ΐ", nil, nil, nil], + 913 => [0, 0, nil, nil, nil, 945, nil], + 914 => [0, 0, nil, nil, nil, 946, nil], + 915 => [0, 0, nil, nil, nil, 947, nil], + 916 => [0, 0, nil, nil, nil, 948, nil], + 917 => [0, 0, nil, nil, nil, 949, nil], + 918 => [0, 0, nil, nil, nil, 950, nil], + 919 => [0, 0, nil, nil, nil, 951, nil], + 920 => [0, 0, nil, nil, nil, 952, nil], + 921 => [0, 0, nil, nil, nil, 953, nil], + 922 => [0, 0, nil, nil, nil, 954, nil], + 923 => [0, 0, nil, nil, nil, 955, nil], + 924 => [0, 0, nil, nil, nil, 956, nil], + 925 => [0, 0, nil, nil, nil, 957, nil], + 926 => [0, 0, nil, nil, nil, 958, nil], + 927 => [0, 0, nil, nil, nil, 959, nil], + 928 => [0, 0, nil, nil, nil, 960, nil], + 929 => [0, 0, nil, nil, nil, 961, nil], + 931 => [0, 0, nil, nil, nil, 963, nil], + 932 => [0, 0, nil, nil, nil, 964, nil], + 933 => [0, 0, nil, nil, nil, 965, nil], + 934 => [0, 0, nil, nil, nil, 966, nil], + 935 => [0, 0, nil, nil, nil, 967, nil], + 936 => [0, 0, nil, nil, nil, 968, nil], + 937 => [0, 0, nil, nil, nil, 969, nil], + 938 => [0, 0, "Ϊ", "Ϊ", nil, 970, nil], + 939 => [0, 0, "Ϋ", "Ϋ", nil, 971, nil], + 940 => [0, 0, "ά", "ά", 902, nil, 902], + 941 => [0, 0, "έ", "έ", 904, nil, 904], + 942 => [0, 0, "ή", "ή", 905, nil, 905], + 943 => [0, 0, "ί", "ί", 906, nil, 906], + 944 => [0, 0, "ΰ", "ΰ", nil, nil, nil], + 945 => [0, 0, nil, nil, 913, nil, 913], + 946 => [0, 0, nil, nil, 914, nil, 914], + 947 => [0, 0, nil, nil, 915, nil, 915], + 948 => [0, 0, nil, nil, 916, nil, 916], + 949 => [0, 0, nil, nil, 917, nil, 917], + 950 => [0, 0, nil, nil, 918, nil, 918], + 951 => [0, 0, nil, nil, 919, nil, 919], + 952 => [0, 0, nil, nil, 920, nil, 920], + 953 => [0, 0, nil, nil, 921, nil, 921], + 954 => [0, 0, nil, nil, 922, nil, 922], + 955 => [0, 0, nil, nil, 923, nil, 923], + 956 => [0, 0, nil, nil, 924, nil, 924], + 957 => [0, 0, nil, nil, 925, nil, 925], + 958 => [0, 0, nil, nil, 926, nil, 926], + 959 => [0, 0, nil, nil, 927, nil, 927], + 960 => [0, 0, nil, nil, 928, nil, 928], + 961 => [0, 0, nil, nil, 929, nil, 929], + 962 => [0, 0, nil, nil, 931, nil, 931], + 963 => [0, 0, nil, nil, 931, nil, 931], + 964 => [0, 0, nil, nil, 932, nil, 932], + 965 => [0, 0, nil, nil, 933, nil, 933], + 966 => [0, 0, nil, nil, 934, nil, 934], + 967 => [0, 0, nil, nil, 935, nil, 935], + 968 => [0, 0, nil, nil, 936, nil, 936], + 969 => [0, 0, nil, nil, 937, nil, 937], + 970 => [0, 0, "ϊ", "ϊ", 938, nil, 938], + 971 => [0, 0, "ϋ", "ϋ", 939, nil, 939], + 972 => [0, 0, "ό", "ό", 908, nil, 908], + 973 => [0, 0, "ύ", "ύ", 910, nil, 910], + 974 => [0, 0, "ώ", "ώ", 911, nil, 911], + 976 => [0, 0, nil, "β", 914, nil, 914], + 977 => [0, 0, nil, "θ", 920, nil, 920], + 978 => [0, 0, nil, "Υ", nil, nil, nil], + 979 => [0, 0, "ϓ", "ϓ", nil, nil, nil], + 980 => [0, 0, "ϔ", "ϔ", nil, nil, nil], + 981 => [0, 0, nil, "φ", 934, nil, 934], + 982 => [0, 0, nil, "π", 928, nil, 928], + 986 => [0, 0, nil, nil, nil, 987, nil], + 987 => [0, 0, nil, nil, 986, nil, 986], + 988 => [0, 0, nil, nil, nil, 989, nil], + 989 => [0, 0, nil, nil, 988, nil, 988], + 990 => [0, 0, nil, nil, nil, 991, nil], + 991 => [0, 0, nil, nil, 990, nil, 990], + 992 => [0, 0, nil, nil, nil, 993, nil], + 993 => [0, 0, nil, nil, 992, nil, 992], + 994 => [0, 0, nil, nil, nil, 995, nil], + 995 => [0, 0, nil, nil, 994, nil, 994], + 996 => [0, 0, nil, nil, nil, 997, nil], + 997 => [0, 0, nil, nil, 996, nil, 996], + 998 => [0, 0, nil, nil, nil, 999, nil], + 999 => [0, 0, nil, nil, 998, nil, 998], + 1000 => [0, 0, nil, nil, nil, 1001, nil], + 1001 => [0, 0, nil, nil, 1000, nil, 1000], + 1002 => [0, 0, nil, nil, nil, 1003, nil], + 1003 => [0, 0, nil, nil, 1002, nil, 1002], + 1004 => [0, 0, nil, nil, nil, 1005, nil], + 1005 => [0, 0, nil, nil, 1004, nil, 1004], + 1006 => [0, 0, nil, nil, nil, 1007, nil], + 1007 => [0, 0, nil, nil, 1006, nil, 1006], + 1008 => [0, 0, nil, "κ", 922, nil, 922], + 1009 => [0, 0, nil, "ρ", 929, nil, 929], + 1010 => [0, 0, nil, "ς", 931, nil, 931], + 1024 => [0, 0, "Ѐ", "Ѐ", nil, 1104, nil], + 1025 => [0, 0, "Ё", "Ё", nil, 1105, nil], + 1026 => [0, 0, nil, nil, nil, 1106, nil], + 1027 => [0, 0, "Ѓ", "Ѓ", nil, 1107, nil], + 1028 => [0, 0, nil, nil, nil, 1108, nil], + 1029 => [0, 0, nil, nil, nil, 1109, nil], + 1030 => [0, 0, nil, nil, nil, 1110, nil], + 1031 => [0, 0, "Ї", "Ї", nil, 1111, nil], + 1032 => [0, 0, nil, nil, nil, 1112, nil], + 1033 => [0, 0, nil, nil, nil, 1113, nil], + 1034 => [0, 0, nil, nil, nil, 1114, nil], + 1035 => [0, 0, nil, nil, nil, 1115, nil], + 1036 => [0, 0, "Ќ", "Ќ", nil, 1116, nil], + 1037 => [0, 0, "Ѝ", "Ѝ", nil, 1117, nil], + 1038 => [0, 0, "Ў", "Ў", nil, 1118, nil], + 1039 => [0, 0, nil, nil, nil, 1119, nil], + 1040 => [0, 0, nil, nil, nil, 1072, nil], + 1041 => [0, 0, nil, nil, nil, 1073, nil], + 1042 => [0, 0, nil, nil, nil, 1074, nil], + 1043 => [0, 0, nil, nil, nil, 1075, nil], + 1044 => [0, 0, nil, nil, nil, 1076, nil], + 1045 => [0, 0, nil, nil, nil, 1077, nil], + 1046 => [0, 0, nil, nil, nil, 1078, nil], + 1047 => [0, 0, nil, nil, nil, 1079, nil], + 1048 => [0, 0, nil, nil, nil, 1080, nil], + 1049 => [0, 0, "Й", "Й", nil, 1081, nil], + 1050 => [0, 0, nil, nil, nil, 1082, nil], + 1051 => [0, 0, nil, nil, nil, 1083, nil], + 1052 => [0, 0, nil, nil, nil, 1084, nil], + 1053 => [0, 0, nil, nil, nil, 1085, nil], + 1054 => [0, 0, nil, nil, nil, 1086, nil], + 1055 => [0, 0, nil, nil, nil, 1087, nil], + 1056 => [0, 0, nil, nil, nil, 1088, nil], + 1057 => [0, 0, nil, nil, nil, 1089, nil], + 1058 => [0, 0, nil, nil, nil, 1090, nil], + 1059 => [0, 0, nil, nil, nil, 1091, nil], + 1060 => [0, 0, nil, nil, nil, 1092, nil], + 1061 => [0, 0, nil, nil, nil, 1093, nil], + 1062 => [0, 0, nil, nil, nil, 1094, nil], + 1063 => [0, 0, nil, nil, nil, 1095, nil], + 1064 => [0, 0, nil, nil, nil, 1096, nil], + 1065 => [0, 0, nil, nil, nil, 1097, nil], + 1066 => [0, 0, nil, nil, nil, 1098, nil], + 1067 => [0, 0, nil, nil, nil, 1099, nil], + 1068 => [0, 0, nil, nil, nil, 1100, nil], + 1069 => [0, 0, nil, nil, nil, 1101, nil], + 1070 => [0, 0, nil, nil, nil, 1102, nil], + 1071 => [0, 0, nil, nil, nil, 1103, nil], + 1072 => [0, 0, nil, nil, 1040, nil, 1040], + 1073 => [0, 0, nil, nil, 1041, nil, 1041], + 1074 => [0, 0, nil, nil, 1042, nil, 1042], + 1075 => [0, 0, nil, nil, 1043, nil, 1043], + 1076 => [0, 0, nil, nil, 1044, nil, 1044], + 1077 => [0, 0, nil, nil, 1045, nil, 1045], + 1078 => [0, 0, nil, nil, 1046, nil, 1046], + 1079 => [0, 0, nil, nil, 1047, nil, 1047], + 1080 => [0, 0, nil, nil, 1048, nil, 1048], + 1081 => [0, 0, "й", "й", 1049, nil, 1049], + 1082 => [0, 0, nil, nil, 1050, nil, 1050], + 1083 => [0, 0, nil, nil, 1051, nil, 1051], + 1084 => [0, 0, nil, nil, 1052, nil, 1052], + 1085 => [0, 0, nil, nil, 1053, nil, 1053], + 1086 => [0, 0, nil, nil, 1054, nil, 1054], + 1087 => [0, 0, nil, nil, 1055, nil, 1055], + 1088 => [0, 0, nil, nil, 1056, nil, 1056], + 1089 => [0, 0, nil, nil, 1057, nil, 1057], + 1090 => [0, 0, nil, nil, 1058, nil, 1058], + 1091 => [0, 0, nil, nil, 1059, nil, 1059], + 1092 => [0, 0, nil, nil, 1060, nil, 1060], + 1093 => [0, 0, nil, nil, 1061, nil, 1061], + 1094 => [0, 0, nil, nil, 1062, nil, 1062], + 1095 => [0, 0, nil, nil, 1063, nil, 1063], + 1096 => [0, 0, nil, nil, 1064, nil, 1064], + 1097 => [0, 0, nil, nil, 1065, nil, 1065], + 1098 => [0, 0, nil, nil, 1066, nil, 1066], + 1099 => [0, 0, nil, nil, 1067, nil, 1067], + 1100 => [0, 0, nil, nil, 1068, nil, 1068], + 1101 => [0, 0, nil, nil, 1069, nil, 1069], + 1102 => [0, 0, nil, nil, 1070, nil, 1070], + 1103 => [0, 0, nil, nil, 1071, nil, 1071], + 1104 => [0, 0, "ѐ", "ѐ", 1024, nil, 1024], + 1105 => [0, 0, "ё", "ё", 1025, nil, 1025], + 1106 => [0, 0, nil, nil, 1026, nil, 1026], + 1107 => [0, 0, "ѓ", "ѓ", 1027, nil, 1027], + 1108 => [0, 0, nil, nil, 1028, nil, 1028], + 1109 => [0, 0, nil, nil, 1029, nil, 1029], + 1110 => [0, 0, nil, nil, 1030, nil, 1030], + 1111 => [0, 0, "ї", "ї", 1031, nil, 1031], + 1112 => [0, 0, nil, nil, 1032, nil, 1032], + 1113 => [0, 0, nil, nil, 1033, nil, 1033], + 1114 => [0, 0, nil, nil, 1034, nil, 1034], + 1115 => [0, 0, nil, nil, 1035, nil, 1035], + 1116 => [0, 0, "ќ", "ќ", 1036, nil, 1036], + 1117 => [0, 0, "ѝ", "ѝ", 1037, nil, 1037], + 1118 => [0, 0, "ў", "ў", 1038, nil, 1038], + 1119 => [0, 0, nil, nil, 1039, nil, 1039], + 1120 => [0, 0, nil, nil, nil, 1121, nil], + 1121 => [0, 0, nil, nil, 1120, nil, 1120], + 1122 => [0, 0, nil, nil, nil, 1123, nil], + 1123 => [0, 0, nil, nil, 1122, nil, 1122], + 1124 => [0, 0, nil, nil, nil, 1125, nil], + 1125 => [0, 0, nil, nil, 1124, nil, 1124], + 1126 => [0, 0, nil, nil, nil, 1127, nil], + 1127 => [0, 0, nil, nil, 1126, nil, 1126], + 1128 => [0, 0, nil, nil, nil, 1129, nil], + 1129 => [0, 0, nil, nil, 1128, nil, 1128], + 1130 => [0, 0, nil, nil, nil, 1131, nil], + 1131 => [0, 0, nil, nil, 1130, nil, 1130], + 1132 => [0, 0, nil, nil, nil, 1133, nil], + 1133 => [0, 0, nil, nil, 1132, nil, 1132], + 1134 => [0, 0, nil, nil, nil, 1135, nil], + 1135 => [0, 0, nil, nil, 1134, nil, 1134], + 1136 => [0, 0, nil, nil, nil, 1137, nil], + 1137 => [0, 0, nil, nil, 1136, nil, 1136], + 1138 => [0, 0, nil, nil, nil, 1139, nil], + 1139 => [0, 0, nil, nil, 1138, nil, 1138], + 1140 => [0, 0, nil, nil, nil, 1141, nil], + 1141 => [0, 0, nil, nil, 1140, nil, 1140], + 1142 => [0, 0, "Ѷ", "Ѷ", nil, 1143, nil], + 1143 => [0, 0, "ѷ", "ѷ", 1142, nil, 1142], + 1144 => [0, 0, nil, nil, nil, 1145, nil], + 1145 => [0, 0, nil, nil, 1144, nil, 1144], + 1146 => [0, 0, nil, nil, nil, 1147, nil], + 1147 => [0, 0, nil, nil, 1146, nil, 1146], + 1148 => [0, 0, nil, nil, nil, 1149, nil], + 1149 => [0, 0, nil, nil, 1148, nil, 1148], + 1150 => [0, 0, nil, nil, nil, 1151, nil], + 1151 => [0, 0, nil, nil, 1150, nil, 1150], + 1152 => [0, 0, nil, nil, nil, 1153, nil], + 1153 => [0, 0, nil, nil, 1152, nil, 1152], + 1155 => [230, 0, nil, nil, nil, nil, nil], + 1156 => [230, 0, nil, nil, nil, nil, nil], + 1157 => [230, 0, nil, nil, nil, nil, nil], + 1158 => [230, 0, nil, nil, nil, nil, nil], + 1164 => [0, 0, nil, nil, nil, 1165, nil], + 1165 => [0, 0, nil, nil, 1164, nil, 1164], + 1166 => [0, 0, nil, nil, nil, 1167, nil], + 1167 => [0, 0, nil, nil, 1166, nil, 1166], + 1168 => [0, 0, nil, nil, nil, 1169, nil], + 1169 => [0, 0, nil, nil, 1168, nil, 1168], + 1170 => [0, 0, nil, nil, nil, 1171, nil], + 1171 => [0, 0, nil, nil, 1170, nil, 1170], + 1172 => [0, 0, nil, nil, nil, 1173, nil], + 1173 => [0, 0, nil, nil, 1172, nil, 1172], + 1174 => [0, 0, nil, nil, nil, 1175, nil], + 1175 => [0, 0, nil, nil, 1174, nil, 1174], + 1176 => [0, 0, nil, nil, nil, 1177, nil], + 1177 => [0, 0, nil, nil, 1176, nil, 1176], + 1178 => [0, 0, nil, nil, nil, 1179, nil], + 1179 => [0, 0, nil, nil, 1178, nil, 1178], + 1180 => [0, 0, nil, nil, nil, 1181, nil], + 1181 => [0, 0, nil, nil, 1180, nil, 1180], + 1182 => [0, 0, nil, nil, nil, 1183, nil], + 1183 => [0, 0, nil, nil, 1182, nil, 1182], + 1184 => [0, 0, nil, nil, nil, 1185, nil], + 1185 => [0, 0, nil, nil, 1184, nil, 1184], + 1186 => [0, 0, nil, nil, nil, 1187, nil], + 1187 => [0, 0, nil, nil, 1186, nil, 1186], + 1188 => [0, 0, nil, nil, nil, 1189, nil], + 1189 => [0, 0, nil, nil, 1188, nil, 1188], + 1190 => [0, 0, nil, nil, nil, 1191, nil], + 1191 => [0, 0, nil, nil, 1190, nil, 1190], + 1192 => [0, 0, nil, nil, nil, 1193, nil], + 1193 => [0, 0, nil, nil, 1192, nil, 1192], + 1194 => [0, 0, nil, nil, nil, 1195, nil], + 1195 => [0, 0, nil, nil, 1194, nil, 1194], + 1196 => [0, 0, nil, nil, nil, 1197, nil], + 1197 => [0, 0, nil, nil, 1196, nil, 1196], + 1198 => [0, 0, nil, nil, nil, 1199, nil], + 1199 => [0, 0, nil, nil, 1198, nil, 1198], + 1200 => [0, 0, nil, nil, nil, 1201, nil], + 1201 => [0, 0, nil, nil, 1200, nil, 1200], + 1202 => [0, 0, nil, nil, nil, 1203, nil], + 1203 => [0, 0, nil, nil, 1202, nil, 1202], + 1204 => [0, 0, nil, nil, nil, 1205, nil], + 1205 => [0, 0, nil, nil, 1204, nil, 1204], + 1206 => [0, 0, nil, nil, nil, 1207, nil], + 1207 => [0, 0, nil, nil, 1206, nil, 1206], + 1208 => [0, 0, nil, nil, nil, 1209, nil], + 1209 => [0, 0, nil, nil, 1208, nil, 1208], + 1210 => [0, 0, nil, nil, nil, 1211, nil], + 1211 => [0, 0, nil, nil, 1210, nil, 1210], + 1212 => [0, 0, nil, nil, nil, 1213, nil], + 1213 => [0, 0, nil, nil, 1212, nil, 1212], + 1214 => [0, 0, nil, nil, nil, 1215, nil], + 1215 => [0, 0, nil, nil, 1214, nil, 1214], + 1217 => [0, 0, "Ӂ", "Ӂ", nil, 1218, nil], + 1218 => [0, 0, "ӂ", "ӂ", 1217, nil, 1217], + 1219 => [0, 0, nil, nil, nil, 1220, nil], + 1220 => [0, 0, nil, nil, 1219, nil, 1219], + 1223 => [0, 0, nil, nil, nil, 1224, nil], + 1224 => [0, 0, nil, nil, 1223, nil, 1223], + 1227 => [0, 0, nil, nil, nil, 1228, nil], + 1228 => [0, 0, nil, nil, 1227, nil, 1227], + 1232 => [0, 0, "Ӑ", "Ӑ", nil, 1233, nil], + 1233 => [0, 0, "ӑ", "ӑ", 1232, nil, 1232], + 1234 => [0, 0, "Ӓ", "Ӓ", nil, 1235, nil], + 1235 => [0, 0, "ӓ", "ӓ", 1234, nil, 1234], + 1236 => [0, 0, nil, nil, nil, 1237, nil], + 1237 => [0, 0, nil, nil, 1236, nil, 1236], + 1238 => [0, 0, "Ӗ", "Ӗ", nil, 1239, nil], + 1239 => [0, 0, "ӗ", "ӗ", 1238, nil, 1238], + 1240 => [0, 0, nil, nil, nil, 1241, nil], + 1241 => [0, 0, nil, nil, 1240, nil, 1240], + 1242 => [0, 0, "Ӛ", "Ӛ", nil, 1243, nil], + 1243 => [0, 0, "ӛ", "ӛ", 1242, nil, 1242], + 1244 => [0, 0, "Ӝ", "Ӝ", nil, 1245, nil], + 1245 => [0, 0, "ӝ", "ӝ", 1244, nil, 1244], + 1246 => [0, 0, "Ӟ", "Ӟ", nil, 1247, nil], + 1247 => [0, 0, "ӟ", "ӟ", 1246, nil, 1246], + 1248 => [0, 0, nil, nil, nil, 1249, nil], + 1249 => [0, 0, nil, nil, 1248, nil, 1248], + 1250 => [0, 0, "Ӣ", "Ӣ", nil, 1251, nil], + 1251 => [0, 0, "ӣ", "ӣ", 1250, nil, 1250], + 1252 => [0, 0, "Ӥ", "Ӥ", nil, 1253, nil], + 1253 => [0, 0, "ӥ", "ӥ", 1252, nil, 1252], + 1254 => [0, 0, "Ӧ", "Ӧ", nil, 1255, nil], + 1255 => [0, 0, "ӧ", "ӧ", 1254, nil, 1254], + 1256 => [0, 0, nil, nil, nil, 1257, nil], + 1257 => [0, 0, nil, nil, 1256, nil, 1256], + 1258 => [0, 0, "Ӫ", "Ӫ", nil, 1259, nil], + 1259 => [0, 0, "ӫ", "ӫ", 1258, nil, 1258], + 1260 => [0, 0, "Ӭ", "Ӭ", nil, 1261, nil], + 1261 => [0, 0, "ӭ", "ӭ", 1260, nil, 1260], + 1262 => [0, 0, "Ӯ", "Ӯ", nil, 1263, nil], + 1263 => [0, 0, "ӯ", "ӯ", 1262, nil, 1262], + 1264 => [0, 0, "Ӱ", "Ӱ", nil, 1265, nil], + 1265 => [0, 0, "ӱ", "ӱ", 1264, nil, 1264], + 1266 => [0, 0, "Ӳ", "Ӳ", nil, 1267, nil], + 1267 => [0, 0, "ӳ", "ӳ", 1266, nil, 1266], + 1268 => [0, 0, "Ӵ", "Ӵ", nil, 1269, nil], + 1269 => [0, 0, "ӵ", "ӵ", 1268, nil, 1268], + 1272 => [0, 0, "Ӹ", "Ӹ", nil, 1273, nil], + 1273 => [0, 0, "ӹ", "ӹ", 1272, nil, 1272], + 1329 => [0, 0, nil, nil, nil, 1377, nil], + 1330 => [0, 0, nil, nil, nil, 1378, nil], + 1331 => [0, 0, nil, nil, nil, 1379, nil], + 1332 => [0, 0, nil, nil, nil, 1380, nil], + 1333 => [0, 0, nil, nil, nil, 1381, nil], + 1334 => [0, 0, nil, nil, nil, 1382, nil], + 1335 => [0, 0, nil, nil, nil, 1383, nil], + 1336 => [0, 0, nil, nil, nil, 1384, nil], + 1337 => [0, 0, nil, nil, nil, 1385, nil], + 1338 => [0, 0, nil, nil, nil, 1386, nil], + 1339 => [0, 0, nil, nil, nil, 1387, nil], + 1340 => [0, 0, nil, nil, nil, 1388, nil], + 1341 => [0, 0, nil, nil, nil, 1389, nil], + 1342 => [0, 0, nil, nil, nil, 1390, nil], + 1343 => [0, 0, nil, nil, nil, 1391, nil], + 1344 => [0, 0, nil, nil, nil, 1392, nil], + 1345 => [0, 0, nil, nil, nil, 1393, nil], + 1346 => [0, 0, nil, nil, nil, 1394, nil], + 1347 => [0, 0, nil, nil, nil, 1395, nil], + 1348 => [0, 0, nil, nil, nil, 1396, nil], + 1349 => [0, 0, nil, nil, nil, 1397, nil], + 1350 => [0, 0, nil, nil, nil, 1398, nil], + 1351 => [0, 0, nil, nil, nil, 1399, nil], + 1352 => [0, 0, nil, nil, nil, 1400, nil], + 1353 => [0, 0, nil, nil, nil, 1401, nil], + 1354 => [0, 0, nil, nil, nil, 1402, nil], + 1355 => [0, 0, nil, nil, nil, 1403, nil], + 1356 => [0, 0, nil, nil, nil, 1404, nil], + 1357 => [0, 0, nil, nil, nil, 1405, nil], + 1358 => [0, 0, nil, nil, nil, 1406, nil], + 1359 => [0, 0, nil, nil, nil, 1407, nil], + 1360 => [0, 0, nil, nil, nil, 1408, nil], + 1361 => [0, 0, nil, nil, nil, 1409, nil], + 1362 => [0, 0, nil, nil, nil, 1410, nil], + 1363 => [0, 0, nil, nil, nil, 1411, nil], + 1364 => [0, 0, nil, nil, nil, 1412, nil], + 1365 => [0, 0, nil, nil, nil, 1413, nil], + 1366 => [0, 0, nil, nil, nil, 1414, nil], + 1377 => [0, 0, nil, nil, 1329, nil, 1329], + 1378 => [0, 0, nil, nil, 1330, nil, 1330], + 1379 => [0, 0, nil, nil, 1331, nil, 1331], + 1380 => [0, 0, nil, nil, 1332, nil, 1332], + 1381 => [0, 0, nil, nil, 1333, nil, 1333], + 1382 => [0, 0, nil, nil, 1334, nil, 1334], + 1383 => [0, 0, nil, nil, 1335, nil, 1335], + 1384 => [0, 0, nil, nil, 1336, nil, 1336], + 1385 => [0, 0, nil, nil, 1337, nil, 1337], + 1386 => [0, 0, nil, nil, 1338, nil, 1338], + 1387 => [0, 0, nil, nil, 1339, nil, 1339], + 1388 => [0, 0, nil, nil, 1340, nil, 1340], + 1389 => [0, 0, nil, nil, 1341, nil, 1341], + 1390 => [0, 0, nil, nil, 1342, nil, 1342], + 1391 => [0, 0, nil, nil, 1343, nil, 1343], + 1392 => [0, 0, nil, nil, 1344, nil, 1344], + 1393 => [0, 0, nil, nil, 1345, nil, 1345], + 1394 => [0, 0, nil, nil, 1346, nil, 1346], + 1395 => [0, 0, nil, nil, 1347, nil, 1347], + 1396 => [0, 0, nil, nil, 1348, nil, 1348], + 1397 => [0, 0, nil, nil, 1349, nil, 1349], + 1398 => [0, 0, nil, nil, 1350, nil, 1350], + 1399 => [0, 0, nil, nil, 1351, nil, 1351], + 1400 => [0, 0, nil, nil, 1352, nil, 1352], + 1401 => [0, 0, nil, nil, 1353, nil, 1353], + 1402 => [0, 0, nil, nil, 1354, nil, 1354], + 1403 => [0, 0, nil, nil, 1355, nil, 1355], + 1404 => [0, 0, nil, nil, 1356, nil, 1356], + 1405 => [0, 0, nil, nil, 1357, nil, 1357], + 1406 => [0, 0, nil, nil, 1358, nil, 1358], + 1407 => [0, 0, nil, nil, 1359, nil, 1359], + 1408 => [0, 0, nil, nil, 1360, nil, 1360], + 1409 => [0, 0, nil, nil, 1361, nil, 1361], + 1410 => [0, 0, nil, nil, 1362, nil, 1362], + 1411 => [0, 0, nil, nil, 1363, nil, 1363], + 1412 => [0, 0, nil, nil, 1364, nil, 1364], + 1413 => [0, 0, nil, nil, 1365, nil, 1365], + 1414 => [0, 0, nil, nil, 1366, nil, 1366], + 1415 => [0, 0, nil, "եւ", nil, nil, nil], + 1425 => [220, 0, nil, nil, nil, nil, nil], + 1426 => [230, 0, nil, nil, nil, nil, nil], + 1427 => [230, 0, nil, nil, nil, nil, nil], + 1428 => [230, 0, nil, nil, nil, nil, nil], + 1429 => [230, 0, nil, nil, nil, nil, nil], + 1430 => [220, 0, nil, nil, nil, nil, nil], + 1431 => [230, 0, nil, nil, nil, nil, nil], + 1432 => [230, 0, nil, nil, nil, nil, nil], + 1433 => [230, 0, nil, nil, nil, nil, nil], + 1434 => [222, 0, nil, nil, nil, nil, nil], + 1435 => [220, 0, nil, nil, nil, nil, nil], + 1436 => [230, 0, nil, nil, nil, nil, nil], + 1437 => [230, 0, nil, nil, nil, nil, nil], + 1438 => [230, 0, nil, nil, nil, nil, nil], + 1439 => [230, 0, nil, nil, nil, nil, nil], + 1440 => [230, 0, nil, nil, nil, nil, nil], + 1441 => [230, 0, nil, nil, nil, nil, nil], + 1443 => [220, 0, nil, nil, nil, nil, nil], + 1444 => [220, 0, nil, nil, nil, nil, nil], + 1445 => [220, 0, nil, nil, nil, nil, nil], + 1446 => [220, 0, nil, nil, nil, nil, nil], + 1447 => [220, 0, nil, nil, nil, nil, nil], + 1448 => [230, 0, nil, nil, nil, nil, nil], + 1449 => [230, 0, nil, nil, nil, nil, nil], + 1450 => [220, 0, nil, nil, nil, nil, nil], + 1451 => [230, 0, nil, nil, nil, nil, nil], + 1452 => [230, 0, nil, nil, nil, nil, nil], + 1453 => [222, 0, nil, nil, nil, nil, nil], + 1454 => [228, 0, nil, nil, nil, nil, nil], + 1455 => [230, 0, nil, nil, nil, nil, nil], + 1456 => [10, 0, nil, nil, nil, nil, nil], + 1457 => [11, 0, nil, nil, nil, nil, nil], + 1458 => [12, 0, nil, nil, nil, nil, nil], + 1459 => [13, 0, nil, nil, nil, nil, nil], + 1460 => [14, 0, nil, nil, nil, nil, nil], + 1461 => [15, 0, nil, nil, nil, nil, nil], + 1462 => [16, 0, nil, nil, nil, nil, nil], + 1463 => [17, 0, nil, nil, nil, nil, nil], + 1464 => [18, 0, nil, nil, nil, nil, nil], + 1465 => [19, 0, nil, nil, nil, nil, nil], + 1467 => [20, 0, nil, nil, nil, nil, nil], + 1468 => [21, 0, nil, nil, nil, nil, nil], + 1469 => [22, 0, nil, nil, nil, nil, nil], + 1471 => [23, 0, nil, nil, nil, nil, nil], + 1473 => [24, 0, nil, nil, nil, nil, nil], + 1474 => [25, 0, nil, nil, nil, nil, nil], + 1476 => [230, 0, nil, nil, nil, nil, nil], + 1570 => [0, 0, "آ", "آ", nil, nil, nil], + 1571 => [0, 0, "أ", "أ", nil, nil, nil], + 1572 => [0, 0, "ؤ", "ؤ", nil, nil, nil], + 1573 => [0, 0, "إ", "إ", nil, nil, nil], + 1574 => [0, 0, "ئ", "ئ", nil, nil, nil], + 1611 => [27, 0, nil, nil, nil, nil, nil], + 1612 => [28, 0, nil, nil, nil, nil, nil], + 1613 => [29, 0, nil, nil, nil, nil, nil], + 1614 => [30, 0, nil, nil, nil, nil, nil], + 1615 => [31, 0, nil, nil, nil, nil, nil], + 1616 => [32, 0, nil, nil, nil, nil, nil], + 1617 => [33, 0, nil, nil, nil, nil, nil], + 1618 => [34, 0, nil, nil, nil, nil, nil], + 1619 => [230, 0, nil, nil, nil, nil, nil], + 1620 => [230, 0, nil, nil, nil, nil, nil], + 1621 => [220, 0, nil, nil, nil, nil, nil], + 1648 => [35, 0, nil, nil, nil, nil, nil], + 1653 => [0, 0, nil, "اٴ", nil, nil, nil], + 1654 => [0, 0, nil, "وٴ", nil, nil, nil], + 1655 => [0, 0, nil, "ۇٴ", nil, nil, nil], + 1656 => [0, 0, nil, "يٴ", nil, nil, nil], + 1728 => [0, 0, "ۀ", "ۀ", nil, nil, nil], + 1730 => [0, 0, "ۂ", "ۂ", nil, nil, nil], + 1747 => [0, 0, "ۓ", "ۓ", nil, nil, nil], + 1750 => [230, 0, nil, nil, nil, nil, nil], + 1751 => [230, 0, nil, nil, nil, nil, nil], + 1752 => [230, 0, nil, nil, nil, nil, nil], + 1753 => [230, 0, nil, nil, nil, nil, nil], + 1754 => [230, 0, nil, nil, nil, nil, nil], + 1755 => [230, 0, nil, nil, nil, nil, nil], + 1756 => [230, 0, nil, nil, nil, nil, nil], + 1759 => [230, 0, nil, nil, nil, nil, nil], + 1760 => [230, 0, nil, nil, nil, nil, nil], + 1761 => [230, 0, nil, nil, nil, nil, nil], + 1762 => [230, 0, nil, nil, nil, nil, nil], + 1763 => [220, 0, nil, nil, nil, nil, nil], + 1764 => [230, 0, nil, nil, nil, nil, nil], + 1767 => [230, 0, nil, nil, nil, nil, nil], + 1768 => [230, 0, nil, nil, nil, nil, nil], + 1770 => [220, 0, nil, nil, nil, nil, nil], + 1771 => [230, 0, nil, nil, nil, nil, nil], + 1772 => [230, 0, nil, nil, nil, nil, nil], + 1773 => [220, 0, nil, nil, nil, nil, nil], + 1809 => [36, 0, nil, nil, nil, nil, nil], + 1840 => [230, 0, nil, nil, nil, nil, nil], + 1841 => [220, 0, nil, nil, nil, nil, nil], + 1842 => [230, 0, nil, nil, nil, nil, nil], + 1843 => [230, 0, nil, nil, nil, nil, nil], + 1844 => [220, 0, nil, nil, nil, nil, nil], + 1845 => [230, 0, nil, nil, nil, nil, nil], + 1846 => [230, 0, nil, nil, nil, nil, nil], + 1847 => [220, 0, nil, nil, nil, nil, nil], + 1848 => [220, 0, nil, nil, nil, nil, nil], + 1849 => [220, 0, nil, nil, nil, nil, nil], + 1850 => [230, 0, nil, nil, nil, nil, nil], + 1851 => [220, 0, nil, nil, nil, nil, nil], + 1852 => [220, 0, nil, nil, nil, nil, nil], + 1853 => [230, 0, nil, nil, nil, nil, nil], + 1854 => [220, 0, nil, nil, nil, nil, nil], + 1855 => [230, 0, nil, nil, nil, nil, nil], + 1856 => [230, 0, nil, nil, nil, nil, nil], + 1857 => [230, 0, nil, nil, nil, nil, nil], + 1858 => [220, 0, nil, nil, nil, nil, nil], + 1859 => [230, 0, nil, nil, nil, nil, nil], + 1860 => [220, 0, nil, nil, nil, nil, nil], + 1861 => [230, 0, nil, nil, nil, nil, nil], + 1862 => [220, 0, nil, nil, nil, nil, nil], + 1863 => [230, 0, nil, nil, nil, nil, nil], + 1864 => [220, 0, nil, nil, nil, nil, nil], + 1865 => [230, 0, nil, nil, nil, nil, nil], + 1866 => [230, 0, nil, nil, nil, nil, nil], + 2345 => [0, 0, "ऩ", "ऩ", nil, nil, nil], + 2353 => [0, 0, "ऱ", "ऱ", nil, nil, nil], + 2356 => [0, 0, "ऴ", "ऴ", nil, nil, nil], + 2364 => [7, 0, nil, nil, nil, nil, nil], + 2381 => [9, 0, nil, nil, nil, nil, nil], + 2385 => [230, 0, nil, nil, nil, nil, nil], + 2386 => [220, 0, nil, nil, nil, nil, nil], + 2387 => [230, 0, nil, nil, nil, nil, nil], + 2388 => [230, 0, nil, nil, nil, nil, nil], + 2392 => [0, 1, "क़", "क़", nil, nil, nil], + 2393 => [0, 1, "ख़", "ख़", nil, nil, nil], + 2394 => [0, 1, "ग़", "ग़", nil, nil, nil], + 2395 => [0, 1, "ज़", "ज़", nil, nil, nil], + 2396 => [0, 1, "ड़", "ड़", nil, nil, nil], + 2397 => [0, 1, "ढ़", "ढ़", nil, nil, nil], + 2398 => [0, 1, "फ़", "फ़", nil, nil, nil], + 2399 => [0, 1, "य़", "य़", nil, nil, nil], + 2492 => [7, 0, nil, nil, nil, nil, nil], + 2507 => [0, 0, "ো", "ো", nil, nil, nil], + 2508 => [0, 0, "ৌ", "ৌ", nil, nil, nil], + 2509 => [9, 0, nil, nil, nil, nil, nil], + 2524 => [0, 1, "ড়", "ড়", nil, nil, nil], + 2525 => [0, 1, "ঢ়", "ঢ়", nil, nil, nil], + 2527 => [0, 1, "য়", "য়", nil, nil, nil], + 2611 => [0, 1, "ਲ਼", "ਲ਼", nil, nil, nil], + 2614 => [0, 1, "ਸ਼", "ਸ਼", nil, nil, nil], + 2620 => [7, 0, nil, nil, nil, nil, nil], + 2637 => [9, 0, nil, nil, nil, nil, nil], + 2649 => [0, 1, "ਖ਼", "ਖ਼", nil, nil, nil], + 2650 => [0, 1, "ਗ਼", "ਗ਼", nil, nil, nil], + 2651 => [0, 1, "ਜ਼", "ਜ਼", nil, nil, nil], + 2654 => [0, 1, "ਫ਼", "ਫ਼", nil, nil, nil], + 2748 => [7, 0, nil, nil, nil, nil, nil], + 2765 => [9, 0, nil, nil, nil, nil, nil], + 2876 => [7, 0, nil, nil, nil, nil, nil], + 2888 => [0, 0, "ୈ", "ୈ", nil, nil, nil], + 2891 => [0, 0, "ୋ", "ୋ", nil, nil, nil], + 2892 => [0, 0, "ୌ", "ୌ", nil, nil, nil], + 2893 => [9, 0, nil, nil, nil, nil, nil], + 2908 => [0, 1, "ଡ଼", "ଡ଼", nil, nil, nil], + 2909 => [0, 1, "ଢ଼", "ଢ଼", nil, nil, nil], + 2964 => [0, 0, "ஔ", "ஔ", nil, nil, nil], + 3018 => [0, 0, "ொ", "ொ", nil, nil, nil], + 3019 => [0, 0, "ோ", "ோ", nil, nil, nil], + 3020 => [0, 0, "ௌ", "ௌ", nil, nil, nil], + 3021 => [9, 0, nil, nil, nil, nil, nil], + 3144 => [0, 0, "ై", "ై", nil, nil, nil], + 3149 => [9, 0, nil, nil, nil, nil, nil], + 3157 => [84, 0, nil, nil, nil, nil, nil], + 3158 => [91, 0, nil, nil, nil, nil, nil], + 3264 => [0, 0, "ೀ", "ೀ", nil, nil, nil], + 3271 => [0, 0, "ೇ", "ೇ", nil, nil, nil], + 3272 => [0, 0, "ೈ", "ೈ", nil, nil, nil], + 3274 => [0, 0, "ೊ", "ೊ", nil, nil, nil], + 3275 => [0, 0, "ೋ", "ೋ", nil, nil, nil], + 3277 => [9, 0, nil, nil, nil, nil, nil], + 3402 => [0, 0, "ൊ", "ൊ", nil, nil, nil], + 3403 => [0, 0, "ോ", "ോ", nil, nil, nil], + 3404 => [0, 0, "ൌ", "ൌ", nil, nil, nil], + 3405 => [9, 0, nil, nil, nil, nil, nil], + 3530 => [9, 0, nil, nil, nil, nil, nil], + 3546 => [0, 0, "ේ", "ේ", nil, nil, nil], + 3548 => [0, 0, "ො", "ො", nil, nil, nil], + 3549 => [0, 0, "ෝ", "ෝ", nil, nil, nil], + 3550 => [0, 0, "ෞ", "ෞ", nil, nil, nil], + 3635 => [0, 0, nil, "ํา", nil, nil, nil], + 3640 => [103, 0, nil, nil, nil, nil, nil], + 3641 => [103, 0, nil, nil, nil, nil, nil], + 3642 => [9, 0, nil, nil, nil, nil, nil], + 3656 => [107, 0, nil, nil, nil, nil, nil], + 3657 => [107, 0, nil, nil, nil, nil, nil], + 3658 => [107, 0, nil, nil, nil, nil, nil], + 3659 => [107, 0, nil, nil, nil, nil, nil], + 3763 => [0, 0, nil, "ໍາ", nil, nil, nil], + 3768 => [118, 0, nil, nil, nil, nil, nil], + 3769 => [118, 0, nil, nil, nil, nil, nil], + 3784 => [122, 0, nil, nil, nil, nil, nil], + 3785 => [122, 0, nil, nil, nil, nil, nil], + 3786 => [122, 0, nil, nil, nil, nil, nil], + 3787 => [122, 0, nil, nil, nil, nil, nil], + 3804 => [0, 0, nil, "ຫນ", nil, nil, nil], + 3805 => [0, 0, nil, "ຫມ", nil, nil, nil], + 3852 => [0, 0, nil, "་", nil, nil, nil], + 3864 => [220, 0, nil, nil, nil, nil, nil], + 3865 => [220, 0, nil, nil, nil, nil, nil], + 3893 => [220, 0, nil, nil, nil, nil, nil], + 3895 => [220, 0, nil, nil, nil, nil, nil], + 3897 => [216, 0, nil, nil, nil, nil, nil], + 3907 => [0, 1, "གྷ", "གྷ", nil, nil, nil], + 3917 => [0, 1, "ཌྷ", "ཌྷ", nil, nil, nil], + 3922 => [0, 1, "དྷ", "དྷ", nil, nil, nil], + 3927 => [0, 1, "བྷ", "བྷ", nil, nil, nil], + 3932 => [0, 1, "ཛྷ", "ཛྷ", nil, nil, nil], + 3945 => [0, 1, "ཀྵ", "ཀྵ", nil, nil, nil], + 3953 => [129, 0, nil, nil, nil, nil, nil], + 3954 => [130, 0, nil, nil, nil, nil, nil], + 3955 => [0, 3, "ཱི", "ཱི", nil, nil, nil], + 3956 => [132, 0, nil, nil, nil, nil, nil], + 3957 => [0, 3, "ཱུ", "ཱུ", nil, nil, nil], + 3958 => [0, 1, "ྲྀ", "ྲྀ", nil, nil, nil], + 3959 => [0, 0, nil, "ྲཱྀ", nil, nil, nil], + 3960 => [0, 1, "ླྀ", "ླྀ", nil, nil, nil], + 3961 => [0, 0, nil, "ླཱྀ", nil, nil, nil], + 3962 => [130, 0, nil, nil, nil, nil, nil], + 3963 => [130, 0, nil, nil, nil, nil, nil], + 3964 => [130, 0, nil, nil, nil, nil, nil], + 3965 => [130, 0, nil, nil, nil, nil, nil], + 3968 => [130, 0, nil, nil, nil, nil, nil], + 3969 => [0, 3, "ཱྀ", "ཱྀ", nil, nil, nil], + 3970 => [230, 0, nil, nil, nil, nil, nil], + 3971 => [230, 0, nil, nil, nil, nil, nil], + 3972 => [9, 0, nil, nil, nil, nil, nil], + 3974 => [230, 0, nil, nil, nil, nil, nil], + 3975 => [230, 0, nil, nil, nil, nil, nil], + 3987 => [0, 1, "ྒྷ", "ྒྷ", nil, nil, nil], + 3997 => [0, 1, "ྜྷ", "ྜྷ", nil, nil, nil], + 4002 => [0, 1, "ྡྷ", "ྡྷ", nil, nil, nil], + 4007 => [0, 1, "ྦྷ", "ྦྷ", nil, nil, nil], + 4012 => [0, 1, "ྫྷ", "ྫྷ", nil, nil, nil], + 4025 => [0, 1, "ྐྵ", "ྐྵ", nil, nil, nil], + 4038 => [220, 0, nil, nil, nil, nil, nil], + 4134 => [0, 0, "ဦ", "ဦ", nil, nil, nil], + 4151 => [7, 0, nil, nil, nil, nil, nil], + 4153 => [9, 0, nil, nil, nil, nil, nil], + 6098 => [9, 0, nil, nil, nil, nil, nil], + 6313 => [228, 0, nil, nil, nil, nil, nil], + 7680 => [0, 0, "Ḁ", "Ḁ", nil, 7681, nil], + 7681 => [0, 0, "ḁ", "ḁ", 7680, nil, 7680], + 7682 => [0, 0, "Ḃ", "Ḃ", nil, 7683, nil], + 7683 => [0, 0, "ḃ", "ḃ", 7682, nil, 7682], + 7684 => [0, 0, "Ḅ", "Ḅ", nil, 7685, nil], + 7685 => [0, 0, "ḅ", "ḅ", 7684, nil, 7684], + 7686 => [0, 0, "Ḇ", "Ḇ", nil, 7687, nil], + 7687 => [0, 0, "ḇ", "ḇ", 7686, nil, 7686], + 7688 => [0, 0, "Ḉ", "Ḉ", nil, 7689, nil], + 7689 => [0, 0, "ḉ", "ḉ", 7688, nil, 7688], + 7690 => [0, 0, "Ḋ", "Ḋ", nil, 7691, nil], + 7691 => [0, 0, "ḋ", "ḋ", 7690, nil, 7690], + 7692 => [0, 0, "Ḍ", "Ḍ", nil, 7693, nil], + 7693 => [0, 0, "ḍ", "ḍ", 7692, nil, 7692], + 7694 => [0, 0, "Ḏ", "Ḏ", nil, 7695, nil], + 7695 => [0, 0, "ḏ", "ḏ", 7694, nil, 7694], + 7696 => [0, 0, "Ḑ", "Ḑ", nil, 7697, nil], + 7697 => [0, 0, "ḑ", "ḑ", 7696, nil, 7696], + 7698 => [0, 0, "Ḓ", "Ḓ", nil, 7699, nil], + 7699 => [0, 0, "ḓ", "ḓ", 7698, nil, 7698], + 7700 => [0, 0, "Ḕ", "Ḕ", nil, 7701, nil], + 7701 => [0, 0, "ḕ", "ḕ", 7700, nil, 7700], + 7702 => [0, 0, "Ḗ", "Ḗ", nil, 7703, nil], + 7703 => [0, 0, "ḗ", "ḗ", 7702, nil, 7702], + 7704 => [0, 0, "Ḙ", "Ḙ", nil, 7705, nil], + 7705 => [0, 0, "ḙ", "ḙ", 7704, nil, 7704], + 7706 => [0, 0, "Ḛ", "Ḛ", nil, 7707, nil], + 7707 => [0, 0, "ḛ", "ḛ", 7706, nil, 7706], + 7708 => [0, 0, "Ḝ", "Ḝ", nil, 7709, nil], + 7709 => [0, 0, "ḝ", "ḝ", 7708, nil, 7708], + 7710 => [0, 0, "Ḟ", "Ḟ", nil, 7711, nil], + 7711 => [0, 0, "ḟ", "ḟ", 7710, nil, 7710], + 7712 => [0, 0, "Ḡ", "Ḡ", nil, 7713, nil], + 7713 => [0, 0, "ḡ", "ḡ", 7712, nil, 7712], + 7714 => [0, 0, "Ḣ", "Ḣ", nil, 7715, nil], + 7715 => [0, 0, "ḣ", "ḣ", 7714, nil, 7714], + 7716 => [0, 0, "Ḥ", "Ḥ", nil, 7717, nil], + 7717 => [0, 0, "ḥ", "ḥ", 7716, nil, 7716], + 7718 => [0, 0, "Ḧ", "Ḧ", nil, 7719, nil], + 7719 => [0, 0, "ḧ", "ḧ", 7718, nil, 7718], + 7720 => [0, 0, "Ḩ", "Ḩ", nil, 7721, nil], + 7721 => [0, 0, "ḩ", "ḩ", 7720, nil, 7720], + 7722 => [0, 0, "Ḫ", "Ḫ", nil, 7723, nil], + 7723 => [0, 0, "ḫ", "ḫ", 7722, nil, 7722], + 7724 => [0, 0, "Ḭ", "Ḭ", nil, 7725, nil], + 7725 => [0, 0, "ḭ", "ḭ", 7724, nil, 7724], + 7726 => [0, 0, "Ḯ", "Ḯ", nil, 7727, nil], + 7727 => [0, 0, "ḯ", "ḯ", 7726, nil, 7726], + 7728 => [0, 0, "Ḱ", "Ḱ", nil, 7729, nil], + 7729 => [0, 0, "ḱ", "ḱ", 7728, nil, 7728], + 7730 => [0, 0, "Ḳ", "Ḳ", nil, 7731, nil], + 7731 => [0, 0, "ḳ", "ḳ", 7730, nil, 7730], + 7732 => [0, 0, "Ḵ", "Ḵ", nil, 7733, nil], + 7733 => [0, 0, "ḵ", "ḵ", 7732, nil, 7732], + 7734 => [0, 0, "Ḷ", "Ḷ", nil, 7735, nil], + 7735 => [0, 0, "ḷ", "ḷ", 7734, nil, 7734], + 7736 => [0, 0, "Ḹ", "Ḹ", nil, 7737, nil], + 7737 => [0, 0, "ḹ", "ḹ", 7736, nil, 7736], + 7738 => [0, 0, "Ḻ", "Ḻ", nil, 7739, nil], + 7739 => [0, 0, "ḻ", "ḻ", 7738, nil, 7738], + 7740 => [0, 0, "Ḽ", "Ḽ", nil, 7741, nil], + 7741 => [0, 0, "ḽ", "ḽ", 7740, nil, 7740], + 7742 => [0, 0, "Ḿ", "Ḿ", nil, 7743, nil], + 7743 => [0, 0, "ḿ", "ḿ", 7742, nil, 7742], + 7744 => [0, 0, "Ṁ", "Ṁ", nil, 7745, nil], + 7745 => [0, 0, "ṁ", "ṁ", 7744, nil, 7744], + 7746 => [0, 0, "Ṃ", "Ṃ", nil, 7747, nil], + 7747 => [0, 0, "ṃ", "ṃ", 7746, nil, 7746], + 7748 => [0, 0, "Ṅ", "Ṅ", nil, 7749, nil], + 7749 => [0, 0, "ṅ", "ṅ", 7748, nil, 7748], + 7750 => [0, 0, "Ṇ", "Ṇ", nil, 7751, nil], + 7751 => [0, 0, "ṇ", "ṇ", 7750, nil, 7750], + 7752 => [0, 0, "Ṉ", "Ṉ", nil, 7753, nil], + 7753 => [0, 0, "ṉ", "ṉ", 7752, nil, 7752], + 7754 => [0, 0, "Ṋ", "Ṋ", nil, 7755, nil], + 7755 => [0, 0, "ṋ", "ṋ", 7754, nil, 7754], + 7756 => [0, 0, "Ṍ", "Ṍ", nil, 7757, nil], + 7757 => [0, 0, "ṍ", "ṍ", 7756, nil, 7756], + 7758 => [0, 0, "Ṏ", "Ṏ", nil, 7759, nil], + 7759 => [0, 0, "ṏ", "ṏ", 7758, nil, 7758], + 7760 => [0, 0, "Ṑ", "Ṑ", nil, 7761, nil], + 7761 => [0, 0, "ṑ", "ṑ", 7760, nil, 7760], + 7762 => [0, 0, "Ṓ", "Ṓ", nil, 7763, nil], + 7763 => [0, 0, "ṓ", "ṓ", 7762, nil, 7762], + 7764 => [0, 0, "Ṕ", "Ṕ", nil, 7765, nil], + 7765 => [0, 0, "ṕ", "ṕ", 7764, nil, 7764], + 7766 => [0, 0, "Ṗ", "Ṗ", nil, 7767, nil], + 7767 => [0, 0, "ṗ", "ṗ", 7766, nil, 7766], + 7768 => [0, 0, "Ṙ", "Ṙ", nil, 7769, nil], + 7769 => [0, 0, "ṙ", "ṙ", 7768, nil, 7768], + 7770 => [0, 0, "Ṛ", "Ṛ", nil, 7771, nil], + 7771 => [0, 0, "ṛ", "ṛ", 7770, nil, 7770], + 7772 => [0, 0, "Ṝ", "Ṝ", nil, 7773, nil], + 7773 => [0, 0, "ṝ", "ṝ", 7772, nil, 7772], + 7774 => [0, 0, "Ṟ", "Ṟ", nil, 7775, nil], + 7775 => [0, 0, "ṟ", "ṟ", 7774, nil, 7774], + 7776 => [0, 0, "Ṡ", "Ṡ", nil, 7777, nil], + 7777 => [0, 0, "ṡ", "ṡ", 7776, nil, 7776], + 7778 => [0, 0, "Ṣ", "Ṣ", nil, 7779, nil], + 7779 => [0, 0, "ṣ", "ṣ", 7778, nil, 7778], + 7780 => [0, 0, "Ṥ", "Ṥ", nil, 7781, nil], + 7781 => [0, 0, "ṥ", "ṥ", 7780, nil, 7780], + 7782 => [0, 0, "Ṧ", "Ṧ", nil, 7783, nil], + 7783 => [0, 0, "ṧ", "ṧ", 7782, nil, 7782], + 7784 => [0, 0, "Ṩ", "Ṩ", nil, 7785, nil], + 7785 => [0, 0, "ṩ", "ṩ", 7784, nil, 7784], + 7786 => [0, 0, "Ṫ", "Ṫ", nil, 7787, nil], + 7787 => [0, 0, "ṫ", "ṫ", 7786, nil, 7786], + 7788 => [0, 0, "Ṭ", "Ṭ", nil, 7789, nil], + 7789 => [0, 0, "ṭ", "ṭ", 7788, nil, 7788], + 7790 => [0, 0, "Ṯ", "Ṯ", nil, 7791, nil], + 7791 => [0, 0, "ṯ", "ṯ", 7790, nil, 7790], + 7792 => [0, 0, "Ṱ", "Ṱ", nil, 7793, nil], + 7793 => [0, 0, "ṱ", "ṱ", 7792, nil, 7792], + 7794 => [0, 0, "Ṳ", "Ṳ", nil, 7795, nil], + 7795 => [0, 0, "ṳ", "ṳ", 7794, nil, 7794], + 7796 => [0, 0, "Ṵ", "Ṵ", nil, 7797, nil], + 7797 => [0, 0, "ṵ", "ṵ", 7796, nil, 7796], + 7798 => [0, 0, "Ṷ", "Ṷ", nil, 7799, nil], + 7799 => [0, 0, "ṷ", "ṷ", 7798, nil, 7798], + 7800 => [0, 0, "Ṹ", "Ṹ", nil, 7801, nil], + 7801 => [0, 0, "ṹ", "ṹ", 7800, nil, 7800], + 7802 => [0, 0, "Ṻ", "Ṻ", nil, 7803, nil], + 7803 => [0, 0, "ṻ", "ṻ", 7802, nil, 7802], + 7804 => [0, 0, "Ṽ", "Ṽ", nil, 7805, nil], + 7805 => [0, 0, "ṽ", "ṽ", 7804, nil, 7804], + 7806 => [0, 0, "Ṿ", "Ṿ", nil, 7807, nil], + 7807 => [0, 0, "ṿ", "ṿ", 7806, nil, 7806], + 7808 => [0, 0, "Ẁ", "Ẁ", nil, 7809, nil], + 7809 => [0, 0, "ẁ", "ẁ", 7808, nil, 7808], + 7810 => [0, 0, "Ẃ", "Ẃ", nil, 7811, nil], + 7811 => [0, 0, "ẃ", "ẃ", 7810, nil, 7810], + 7812 => [0, 0, "Ẅ", "Ẅ", nil, 7813, nil], + 7813 => [0, 0, "ẅ", "ẅ", 7812, nil, 7812], + 7814 => [0, 0, "Ẇ", "Ẇ", nil, 7815, nil], + 7815 => [0, 0, "ẇ", "ẇ", 7814, nil, 7814], + 7816 => [0, 0, "Ẉ", "Ẉ", nil, 7817, nil], + 7817 => [0, 0, "ẉ", "ẉ", 7816, nil, 7816], + 7818 => [0, 0, "Ẋ", "Ẋ", nil, 7819, nil], + 7819 => [0, 0, "ẋ", "ẋ", 7818, nil, 7818], + 7820 => [0, 0, "Ẍ", "Ẍ", nil, 7821, nil], + 7821 => [0, 0, "ẍ", "ẍ", 7820, nil, 7820], + 7822 => [0, 0, "Ẏ", "Ẏ", nil, 7823, nil], + 7823 => [0, 0, "ẏ", "ẏ", 7822, nil, 7822], + 7824 => [0, 0, "Ẑ", "Ẑ", nil, 7825, nil], + 7825 => [0, 0, "ẑ", "ẑ", 7824, nil, 7824], + 7826 => [0, 0, "Ẓ", "Ẓ", nil, 7827, nil], + 7827 => [0, 0, "ẓ", "ẓ", 7826, nil, 7826], + 7828 => [0, 0, "Ẕ", "Ẕ", nil, 7829, nil], + 7829 => [0, 0, "ẕ", "ẕ", 7828, nil, 7828], + 7830 => [0, 0, "ẖ", "ẖ", nil, nil, nil], + 7831 => [0, 0, "ẗ", "ẗ", nil, nil, nil], + 7832 => [0, 0, "ẘ", "ẘ", nil, nil, nil], + 7833 => [0, 0, "ẙ", "ẙ", nil, nil, nil], + 7834 => [0, 0, nil, "aʾ", nil, nil, nil], + 7835 => [0, 0, "ẛ", "ẛ", 7776, nil, 7776], + 7840 => [0, 0, "Ạ", "Ạ", nil, 7841, nil], + 7841 => [0, 0, "ạ", "ạ", 7840, nil, 7840], + 7842 => [0, 0, "Ả", "Ả", nil, 7843, nil], + 7843 => [0, 0, "ả", "ả", 7842, nil, 7842], + 7844 => [0, 0, "Ấ", "Ấ", nil, 7845, nil], + 7845 => [0, 0, "ấ", "ấ", 7844, nil, 7844], + 7846 => [0, 0, "Ầ", "Ầ", nil, 7847, nil], + 7847 => [0, 0, "ầ", "ầ", 7846, nil, 7846], + 7848 => [0, 0, "Ẩ", "Ẩ", nil, 7849, nil], + 7849 => [0, 0, "ẩ", "ẩ", 7848, nil, 7848], + 7850 => [0, 0, "Ẫ", "Ẫ", nil, 7851, nil], + 7851 => [0, 0, "ẫ", "ẫ", 7850, nil, 7850], + 7852 => [0, 0, "Ậ", "Ậ", nil, 7853, nil], + 7853 => [0, 0, "ậ", "ậ", 7852, nil, 7852], + 7854 => [0, 0, "Ắ", "Ắ", nil, 7855, nil], + 7855 => [0, 0, "ắ", "ắ", 7854, nil, 7854], + 7856 => [0, 0, "Ằ", "Ằ", nil, 7857, nil], + 7857 => [0, 0, "ằ", "ằ", 7856, nil, 7856], + 7858 => [0, 0, "Ẳ", "Ẳ", nil, 7859, nil], + 7859 => [0, 0, "ẳ", "ẳ", 7858, nil, 7858], + 7860 => [0, 0, "Ẵ", "Ẵ", nil, 7861, nil], + 7861 => [0, 0, "ẵ", "ẵ", 7860, nil, 7860], + 7862 => [0, 0, "Ặ", "Ặ", nil, 7863, nil], + 7863 => [0, 0, "ặ", "ặ", 7862, nil, 7862], + 7864 => [0, 0, "Ẹ", "Ẹ", nil, 7865, nil], + 7865 => [0, 0, "ẹ", "ẹ", 7864, nil, 7864], + 7866 => [0, 0, "Ẻ", "Ẻ", nil, 7867, nil], + 7867 => [0, 0, "ẻ", "ẻ", 7866, nil, 7866], + 7868 => [0, 0, "Ẽ", "Ẽ", nil, 7869, nil], + 7869 => [0, 0, "ẽ", "ẽ", 7868, nil, 7868], + 7870 => [0, 0, "Ế", "Ế", nil, 7871, nil], + 7871 => [0, 0, "ế", "ế", 7870, nil, 7870], + 7872 => [0, 0, "Ề", "Ề", nil, 7873, nil], + 7873 => [0, 0, "ề", "ề", 7872, nil, 7872], + 7874 => [0, 0, "Ể", "Ể", nil, 7875, nil], + 7875 => [0, 0, "ể", "ể", 7874, nil, 7874], + 7876 => [0, 0, "Ễ", "Ễ", nil, 7877, nil], + 7877 => [0, 0, "ễ", "ễ", 7876, nil, 7876], + 7878 => [0, 0, "Ệ", "Ệ", nil, 7879, nil], + 7879 => [0, 0, "ệ", "ệ", 7878, nil, 7878], + 7880 => [0, 0, "Ỉ", "Ỉ", nil, 7881, nil], + 7881 => [0, 0, "ỉ", "ỉ", 7880, nil, 7880], + 7882 => [0, 0, "Ị", "Ị", nil, 7883, nil], + 7883 => [0, 0, "ị", "ị", 7882, nil, 7882], + 7884 => [0, 0, "Ọ", "Ọ", nil, 7885, nil], + 7885 => [0, 0, "ọ", "ọ", 7884, nil, 7884], + 7886 => [0, 0, "Ỏ", "Ỏ", nil, 7887, nil], + 7887 => [0, 0, "ỏ", "ỏ", 7886, nil, 7886], + 7888 => [0, 0, "Ố", "Ố", nil, 7889, nil], + 7889 => [0, 0, "ố", "ố", 7888, nil, 7888], + 7890 => [0, 0, "Ồ", "Ồ", nil, 7891, nil], + 7891 => [0, 0, "ồ", "ồ", 7890, nil, 7890], + 7892 => [0, 0, "Ổ", "Ổ", nil, 7893, nil], + 7893 => [0, 0, "ổ", "ổ", 7892, nil, 7892], + 7894 => [0, 0, "Ỗ", "Ỗ", nil, 7895, nil], + 7895 => [0, 0, "ỗ", "ỗ", 7894, nil, 7894], + 7896 => [0, 0, "Ộ", "Ộ", nil, 7897, nil], + 7897 => [0, 0, "ộ", "ộ", 7896, nil, 7896], + 7898 => [0, 0, "Ớ", "Ớ", nil, 7899, nil], + 7899 => [0, 0, "ớ", "ớ", 7898, nil, 7898], + 7900 => [0, 0, "Ờ", "Ờ", nil, 7901, nil], + 7901 => [0, 0, "ờ", "ờ", 7900, nil, 7900], + 7902 => [0, 0, "Ở", "Ở", nil, 7903, nil], + 7903 => [0, 0, "ở", "ở", 7902, nil, 7902], + 7904 => [0, 0, "Ỡ", "Ỡ", nil, 7905, nil], + 7905 => [0, 0, "ỡ", "ỡ", 7904, nil, 7904], + 7906 => [0, 0, "Ợ", "Ợ", nil, 7907, nil], + 7907 => [0, 0, "ợ", "ợ", 7906, nil, 7906], + 7908 => [0, 0, "Ụ", "Ụ", nil, 7909, nil], + 7909 => [0, 0, "ụ", "ụ", 7908, nil, 7908], + 7910 => [0, 0, "Ủ", "Ủ", nil, 7911, nil], + 7911 => [0, 0, "ủ", "ủ", 7910, nil, 7910], + 7912 => [0, 0, "Ứ", "Ứ", nil, 7913, nil], + 7913 => [0, 0, "ứ", "ứ", 7912, nil, 7912], + 7914 => [0, 0, "Ừ", "Ừ", nil, 7915, nil], + 7915 => [0, 0, "ừ", "ừ", 7914, nil, 7914], + 7916 => [0, 0, "Ử", "Ử", nil, 7917, nil], + 7917 => [0, 0, "ử", "ử", 7916, nil, 7916], + 7918 => [0, 0, "Ữ", "Ữ", nil, 7919, nil], + 7919 => [0, 0, "ữ", "ữ", 7918, nil, 7918], + 7920 => [0, 0, "Ự", "Ự", nil, 7921, nil], + 7921 => [0, 0, "ự", "ự", 7920, nil, 7920], + 7922 => [0, 0, "Ỳ", "Ỳ", nil, 7923, nil], + 7923 => [0, 0, "ỳ", "ỳ", 7922, nil, 7922], + 7924 => [0, 0, "Ỵ", "Ỵ", nil, 7925, nil], + 7925 => [0, 0, "ỵ", "ỵ", 7924, nil, 7924], + 7926 => [0, 0, "Ỷ", "Ỷ", nil, 7927, nil], + 7927 => [0, 0, "ỷ", "ỷ", 7926, nil, 7926], + 7928 => [0, 0, "Ỹ", "Ỹ", nil, 7929, nil], + 7929 => [0, 0, "ỹ", "ỹ", 7928, nil, 7928], + 7936 => [0, 0, "ἀ", "ἀ", 7944, nil, 7944], + 7937 => [0, 0, "ἁ", "ἁ", 7945, nil, 7945], + 7938 => [0, 0, "ἂ", "ἂ", 7946, nil, 7946], + 7939 => [0, 0, "ἃ", "ἃ", 7947, nil, 7947], + 7940 => [0, 0, "ἄ", "ἄ", 7948, nil, 7948], + 7941 => [0, 0, "ἅ", "ἅ", 7949, nil, 7949], + 7942 => [0, 0, "ἆ", "ἆ", 7950, nil, 7950], + 7943 => [0, 0, "ἇ", "ἇ", 7951, nil, 7951], + 7944 => [0, 0, "Ἀ", "Ἀ", nil, 7936, nil], + 7945 => [0, 0, "Ἁ", "Ἁ", nil, 7937, nil], + 7946 => [0, 0, "Ἂ", "Ἂ", nil, 7938, nil], + 7947 => [0, 0, "Ἃ", "Ἃ", nil, 7939, nil], + 7948 => [0, 0, "Ἄ", "Ἄ", nil, 7940, nil], + 7949 => [0, 0, "Ἅ", "Ἅ", nil, 7941, nil], + 7950 => [0, 0, "Ἆ", "Ἆ", nil, 7942, nil], + 7951 => [0, 0, "Ἇ", "Ἇ", nil, 7943, nil], + 7952 => [0, 0, "ἐ", "ἐ", 7960, nil, 7960], + 7953 => [0, 0, "ἑ", "ἑ", 7961, nil, 7961], + 7954 => [0, 0, "ἒ", "ἒ", 7962, nil, 7962], + 7955 => [0, 0, "ἓ", "ἓ", 7963, nil, 7963], + 7956 => [0, 0, "ἔ", "ἔ", 7964, nil, 7964], + 7957 => [0, 0, "ἕ", "ἕ", 7965, nil, 7965], + 7960 => [0, 0, "Ἐ", "Ἐ", nil, 7952, nil], + 7961 => [0, 0, "Ἑ", "Ἑ", nil, 7953, nil], + 7962 => [0, 0, "Ἒ", "Ἒ", nil, 7954, nil], + 7963 => [0, 0, "Ἓ", "Ἓ", nil, 7955, nil], + 7964 => [0, 0, "Ἔ", "Ἔ", nil, 7956, nil], + 7965 => [0, 0, "Ἕ", "Ἕ", nil, 7957, nil], + 7968 => [0, 0, "ἠ", "ἠ", 7976, nil, 7976], + 7969 => [0, 0, "ἡ", "ἡ", 7977, nil, 7977], + 7970 => [0, 0, "ἢ", "ἢ", 7978, nil, 7978], + 7971 => [0, 0, "ἣ", "ἣ", 7979, nil, 7979], + 7972 => [0, 0, "ἤ", "ἤ", 7980, nil, 7980], + 7973 => [0, 0, "ἥ", "ἥ", 7981, nil, 7981], + 7974 => [0, 0, "ἦ", "ἦ", 7982, nil, 7982], + 7975 => [0, 0, "ἧ", "ἧ", 7983, nil, 7983], + 7976 => [0, 0, "Ἠ", "Ἠ", nil, 7968, nil], + 7977 => [0, 0, "Ἡ", "Ἡ", nil, 7969, nil], + 7978 => [0, 0, "Ἢ", "Ἢ", nil, 7970, nil], + 7979 => [0, 0, "Ἣ", "Ἣ", nil, 7971, nil], + 7980 => [0, 0, "Ἤ", "Ἤ", nil, 7972, nil], + 7981 => [0, 0, "Ἥ", "Ἥ", nil, 7973, nil], + 7982 => [0, 0, "Ἦ", "Ἦ", nil, 7974, nil], + 7983 => [0, 0, "Ἧ", "Ἧ", nil, 7975, nil], + 7984 => [0, 0, "ἰ", "ἰ", 7992, nil, 7992], + 7985 => [0, 0, "ἱ", "ἱ", 7993, nil, 7993], + 7986 => [0, 0, "ἲ", "ἲ", 7994, nil, 7994], + 7987 => [0, 0, "ἳ", "ἳ", 7995, nil, 7995], + 7988 => [0, 0, "ἴ", "ἴ", 7996, nil, 7996], + 7989 => [0, 0, "ἵ", "ἵ", 7997, nil, 7997], + 7990 => [0, 0, "ἶ", "ἶ", 7998, nil, 7998], + 7991 => [0, 0, "ἷ", "ἷ", 7999, nil, 7999], + 7992 => [0, 0, "Ἰ", "Ἰ", nil, 7984, nil], + 7993 => [0, 0, "Ἱ", "Ἱ", nil, 7985, nil], + 7994 => [0, 0, "Ἲ", "Ἲ", nil, 7986, nil], + 7995 => [0, 0, "Ἳ", "Ἳ", nil, 7987, nil], + 7996 => [0, 0, "Ἴ", "Ἴ", nil, 7988, nil], + 7997 => [0, 0, "Ἵ", "Ἵ", nil, 7989, nil], + 7998 => [0, 0, "Ἶ", "Ἶ", nil, 7990, nil], + 7999 => [0, 0, "Ἷ", "Ἷ", nil, 7991, nil], + 8000 => [0, 0, "ὀ", "ὀ", 8008, nil, 8008], + 8001 => [0, 0, "ὁ", "ὁ", 8009, nil, 8009], + 8002 => [0, 0, "ὂ", "ὂ", 8010, nil, 8010], + 8003 => [0, 0, "ὃ", "ὃ", 8011, nil, 8011], + 8004 => [0, 0, "ὄ", "ὄ", 8012, nil, 8012], + 8005 => [0, 0, "ὅ", "ὅ", 8013, nil, 8013], + 8008 => [0, 0, "Ὀ", "Ὀ", nil, 8000, nil], + 8009 => [0, 0, "Ὁ", "Ὁ", nil, 8001, nil], + 8010 => [0, 0, "Ὂ", "Ὂ", nil, 8002, nil], + 8011 => [0, 0, "Ὃ", "Ὃ", nil, 8003, nil], + 8012 => [0, 0, "Ὄ", "Ὄ", nil, 8004, nil], + 8013 => [0, 0, "Ὅ", "Ὅ", nil, 8005, nil], + 8016 => [0, 0, "ὐ", "ὐ", nil, nil, nil], + 8017 => [0, 0, "ὑ", "ὑ", 8025, nil, 8025], + 8018 => [0, 0, "ὒ", "ὒ", nil, nil, nil], + 8019 => [0, 0, "ὓ", "ὓ", 8027, nil, 8027], + 8020 => [0, 0, "ὔ", "ὔ", nil, nil, nil], + 8021 => [0, 0, "ὕ", "ὕ", 8029, nil, 8029], + 8022 => [0, 0, "ὖ", "ὖ", nil, nil, nil], + 8023 => [0, 0, "ὗ", "ὗ", 8031, nil, 8031], + 8025 => [0, 0, "Ὑ", "Ὑ", nil, 8017, nil], + 8027 => [0, 0, "Ὓ", "Ὓ", nil, 8019, nil], + 8029 => [0, 0, "Ὕ", "Ὕ", nil, 8021, nil], + 8031 => [0, 0, "Ὗ", "Ὗ", nil, 8023, nil], + 8032 => [0, 0, "ὠ", "ὠ", 8040, nil, 8040], + 8033 => [0, 0, "ὡ", "ὡ", 8041, nil, 8041], + 8034 => [0, 0, "ὢ", "ὢ", 8042, nil, 8042], + 8035 => [0, 0, "ὣ", "ὣ", 8043, nil, 8043], + 8036 => [0, 0, "ὤ", "ὤ", 8044, nil, 8044], + 8037 => [0, 0, "ὥ", "ὥ", 8045, nil, 8045], + 8038 => [0, 0, "ὦ", "ὦ", 8046, nil, 8046], + 8039 => [0, 0, "ὧ", "ὧ", 8047, nil, 8047], + 8040 => [0, 0, "Ὠ", "Ὠ", nil, 8032, nil], + 8041 => [0, 0, "Ὡ", "Ὡ", nil, 8033, nil], + 8042 => [0, 0, "Ὢ", "Ὢ", nil, 8034, nil], + 8043 => [0, 0, "Ὣ", "Ὣ", nil, 8035, nil], + 8044 => [0, 0, "Ὤ", "Ὤ", nil, 8036, nil], + 8045 => [0, 0, "Ὥ", "Ὥ", nil, 8037, nil], + 8046 => [0, 0, "Ὦ", "Ὦ", nil, 8038, nil], + 8047 => [0, 0, "Ὧ", "Ὧ", nil, 8039, nil], + 8048 => [0, 0, "ὰ", "ὰ", 8122, nil, 8122], + 8049 => [0, 2, "ά", "ά", 8123, nil, 8123], + 8050 => [0, 0, "ὲ", "ὲ", 8136, nil, 8136], + 8051 => [0, 2, "έ", "έ", 8137, nil, 8137], + 8052 => [0, 0, "ὴ", "ὴ", 8138, nil, 8138], + 8053 => [0, 2, "ή", "ή", 8139, nil, 8139], + 8054 => [0, 0, "ὶ", "ὶ", 8154, nil, 8154], + 8055 => [0, 2, "ί", "ί", 8155, nil, 8155], + 8056 => [0, 0, "ὸ", "ὸ", 8184, nil, 8184], + 8057 => [0, 2, "ό", "ό", 8185, nil, 8185], + 8058 => [0, 0, "ὺ", "ὺ", 8170, nil, 8170], + 8059 => [0, 2, "ύ", "ύ", 8171, nil, 8171], + 8060 => [0, 0, "ὼ", "ὼ", 8186, nil, 8186], + 8061 => [0, 2, "ώ", "ώ", 8187, nil, 8187], + 8064 => [0, 0, "ᾀ", "ᾀ", 8072, nil, 8072], + 8065 => [0, 0, "ᾁ", "ᾁ", 8073, nil, 8073], + 8066 => [0, 0, "ᾂ", "ᾂ", 8074, nil, 8074], + 8067 => [0, 0, "ᾃ", "ᾃ", 8075, nil, 8075], + 8068 => [0, 0, "ᾄ", "ᾄ", 8076, nil, 8076], + 8069 => [0, 0, "ᾅ", "ᾅ", 8077, nil, 8077], + 8070 => [0, 0, "ᾆ", "ᾆ", 8078, nil, 8078], + 8071 => [0, 0, "ᾇ", "ᾇ", 8079, nil, 8079], + 8072 => [0, 0, "ᾈ", "ᾈ", nil, 8064, nil], + 8073 => [0, 0, "ᾉ", "ᾉ", nil, 8065, nil], + 8074 => [0, 0, "ᾊ", "ᾊ", nil, 8066, nil], + 8075 => [0, 0, "ᾋ", "ᾋ", nil, 8067, nil], + 8076 => [0, 0, "ᾌ", "ᾌ", nil, 8068, nil], + 8077 => [0, 0, "ᾍ", "ᾍ", nil, 8069, nil], + 8078 => [0, 0, "ᾎ", "ᾎ", nil, 8070, nil], + 8079 => [0, 0, "ᾏ", "ᾏ", nil, 8071, nil], + 8080 => [0, 0, "ᾐ", "ᾐ", 8088, nil, 8088], + 8081 => [0, 0, "ᾑ", "ᾑ", 8089, nil, 8089], + 8082 => [0, 0, "ᾒ", "ᾒ", 8090, nil, 8090], + 8083 => [0, 0, "ᾓ", "ᾓ", 8091, nil, 8091], + 8084 => [0, 0, "ᾔ", "ᾔ", 8092, nil, 8092], + 8085 => [0, 0, "ᾕ", "ᾕ", 8093, nil, 8093], + 8086 => [0, 0, "ᾖ", "ᾖ", 8094, nil, 8094], + 8087 => [0, 0, "ᾗ", "ᾗ", 8095, nil, 8095], + 8088 => [0, 0, "ᾘ", "ᾘ", nil, 8080, nil], + 8089 => [0, 0, "ᾙ", "ᾙ", nil, 8081, nil], + 8090 => [0, 0, "ᾚ", "ᾚ", nil, 8082, nil], + 8091 => [0, 0, "ᾛ", "ᾛ", nil, 8083, nil], + 8092 => [0, 0, "ᾜ", "ᾜ", nil, 8084, nil], + 8093 => [0, 0, "ᾝ", "ᾝ", nil, 8085, nil], + 8094 => [0, 0, "ᾞ", "ᾞ", nil, 8086, nil], + 8095 => [0, 0, "ᾟ", "ᾟ", nil, 8087, nil], + 8096 => [0, 0, "ᾠ", "ᾠ", 8104, nil, 8104], + 8097 => [0, 0, "ᾡ", "ᾡ", 8105, nil, 8105], + 8098 => [0, 0, "ᾢ", "ᾢ", 8106, nil, 8106], + 8099 => [0, 0, "ᾣ", "ᾣ", 8107, nil, 8107], + 8100 => [0, 0, "ᾤ", "ᾤ", 8108, nil, 8108], + 8101 => [0, 0, "ᾥ", "ᾥ", 8109, nil, 8109], + 8102 => [0, 0, "ᾦ", "ᾦ", 8110, nil, 8110], + 8103 => [0, 0, "ᾧ", "ᾧ", 8111, nil, 8111], + 8104 => [0, 0, "ᾨ", "ᾨ", nil, 8096, nil], + 8105 => [0, 0, "ᾩ", "ᾩ", nil, 8097, nil], + 8106 => [0, 0, "ᾪ", "ᾪ", nil, 8098, nil], + 8107 => [0, 0, "ᾫ", "ᾫ", nil, 8099, nil], + 8108 => [0, 0, "ᾬ", "ᾬ", nil, 8100, nil], + 8109 => [0, 0, "ᾭ", "ᾭ", nil, 8101, nil], + 8110 => [0, 0, "ᾮ", "ᾮ", nil, 8102, nil], + 8111 => [0, 0, "ᾯ", "ᾯ", nil, 8103, nil], + 8112 => [0, 0, "ᾰ", "ᾰ", 8120, nil, 8120], + 8113 => [0, 0, "ᾱ", "ᾱ", 8121, nil, 8121], + 8114 => [0, 0, "ᾲ", "ᾲ", nil, nil, nil], + 8115 => [0, 0, "ᾳ", "ᾳ", 8124, nil, 8124], + 8116 => [0, 0, "ᾴ", "ᾴ", nil, nil, nil], + 8118 => [0, 0, "ᾶ", "ᾶ", nil, nil, nil], + 8119 => [0, 0, "ᾷ", "ᾷ", nil, nil, nil], + 8120 => [0, 0, "Ᾰ", "Ᾰ", nil, 8112, nil], + 8121 => [0, 0, "Ᾱ", "Ᾱ", nil, 8113, nil], + 8122 => [0, 0, "Ὰ", "Ὰ", nil, 8048, nil], + 8123 => [0, 2, "Ά", "Ά", nil, 8049, nil], + 8124 => [0, 0, "ᾼ", "ᾼ", nil, 8115, nil], + 8125 => [0, 0, nil, " ̓", nil, nil, nil], + 8126 => [0, 2, "ι", "ι", 921, nil, 921], + 8127 => [0, 0, nil, " ̓", nil, nil, nil], + 8128 => [0, 0, nil, " ͂", nil, nil, nil], + 8129 => [0, 0, "῁", "῁", nil, nil, nil], + 8130 => [0, 0, "ῂ", "ῂ", nil, nil, nil], + 8131 => [0, 0, "ῃ", "ῃ", 8140, nil, 8140], + 8132 => [0, 0, "ῄ", "ῄ", nil, nil, nil], + 8134 => [0, 0, "ῆ", "ῆ", nil, nil, nil], + 8135 => [0, 0, "ῇ", "ῇ", nil, nil, nil], + 8136 => [0, 0, "Ὲ", "Ὲ", nil, 8050, nil], + 8137 => [0, 2, "Έ", "Έ", nil, 8051, nil], + 8138 => [0, 0, "Ὴ", "Ὴ", nil, 8052, nil], + 8139 => [0, 2, "Ή", "Ή", nil, 8053, nil], + 8140 => [0, 0, "ῌ", "ῌ", nil, 8131, nil], + 8141 => [0, 0, "῍", "῍", nil, nil, nil], + 8142 => [0, 0, "῎", "῎", nil, nil, nil], + 8143 => [0, 0, "῏", "῏", nil, nil, nil], + 8144 => [0, 0, "ῐ", "ῐ", 8152, nil, 8152], + 8145 => [0, 0, "ῑ", "ῑ", 8153, nil, 8153], + 8146 => [0, 0, "ῒ", "ῒ", nil, nil, nil], + 8147 => [0, 2, "ΐ", "ΐ", nil, nil, nil], + 8150 => [0, 0, "ῖ", "ῖ", nil, nil, nil], + 8151 => [0, 0, "ῗ", "ῗ", nil, nil, nil], + 8152 => [0, 0, "Ῐ", "Ῐ", nil, 8144, nil], + 8153 => [0, 0, "Ῑ", "Ῑ", nil, 8145, nil], + 8154 => [0, 0, "Ὶ", "Ὶ", nil, 8054, nil], + 8155 => [0, 2, "Ί", "Ί", nil, 8055, nil], + 8157 => [0, 0, "῝", "῝", nil, nil, nil], + 8158 => [0, 0, "῞", "῞", nil, nil, nil], + 8159 => [0, 0, "῟", "῟", nil, nil, nil], + 8160 => [0, 0, "ῠ", "ῠ", 8168, nil, 8168], + 8161 => [0, 0, "ῡ", "ῡ", 8169, nil, 8169], + 8162 => [0, 0, "ῢ", "ῢ", nil, nil, nil], + 8163 => [0, 2, "ΰ", "ΰ", nil, nil, nil], + 8164 => [0, 0, "ῤ", "ῤ", nil, nil, nil], + 8165 => [0, 0, "ῥ", "ῥ", 8172, nil, 8172], + 8166 => [0, 0, "ῦ", "ῦ", nil, nil, nil], + 8167 => [0, 0, "ῧ", "ῧ", nil, nil, nil], + 8168 => [0, 0, "Ῠ", "Ῠ", nil, 8160, nil], + 8169 => [0, 0, "Ῡ", "Ῡ", nil, 8161, nil], + 8170 => [0, 0, "Ὺ", "Ὺ", nil, 8058, nil], + 8171 => [0, 2, "Ύ", "Ύ", nil, 8059, nil], + 8172 => [0, 0, "Ῥ", "Ῥ", nil, 8165, nil], + 8173 => [0, 0, "῭", "῭", nil, nil, nil], + 8174 => [0, 2, "΅", "΅", nil, nil, nil], + 8175 => [0, 2, "`", "`", nil, nil, nil], + 8178 => [0, 0, "ῲ", "ῲ", nil, nil, nil], + 8179 => [0, 0, "ῳ", "ῳ", 8188, nil, 8188], + 8180 => [0, 0, "ῴ", "ῴ", nil, nil, nil], + 8182 => [0, 0, "ῶ", "ῶ", nil, nil, nil], + 8183 => [0, 0, "ῷ", "ῷ", nil, nil, nil], + 8184 => [0, 0, "Ὸ", "Ὸ", nil, 8056, nil], + 8185 => [0, 2, "Ό", "Ό", nil, 8057, nil], + 8186 => [0, 0, "Ὼ", "Ὼ", nil, 8060, nil], + 8187 => [0, 2, "Ώ", "Ώ", nil, 8061, nil], + 8188 => [0, 0, "ῼ", "ῼ", nil, 8179, nil], + 8189 => [0, 2, "´", "´", nil, nil, nil], + 8190 => [0, 0, nil, " ̔", nil, nil, nil], + 8192 => [0, 2, " ", " ", nil, nil, nil], + 8193 => [0, 2, " ", " ", nil, nil, nil], + 8194 => [0, 0, nil, " ", nil, nil, nil], + 8195 => [0, 0, nil, " ", nil, nil, nil], + 8196 => [0, 0, nil, " ", nil, nil, nil], + 8197 => [0, 0, nil, " ", nil, nil, nil], + 8198 => [0, 0, nil, " ", nil, nil, nil], + 8199 => [0, 0, nil, " ", nil, nil, nil], + 8200 => [0, 0, nil, " ", nil, nil, nil], + 8201 => [0, 0, nil, " ", nil, nil, nil], + 8202 => [0, 0, nil, " ", nil, nil, nil], + 8209 => [0, 0, nil, "‐", nil, nil, nil], + 8215 => [0, 0, nil, " ̳", nil, nil, nil], + 8228 => [0, 0, nil, ".", nil, nil, nil], + 8229 => [0, 0, nil, "..", nil, nil, nil], + 8230 => [0, 0, nil, "...", nil, nil, nil], + 8239 => [0, 0, nil, " ", nil, nil, nil], + 8243 => [0, 0, nil, "′′", nil, nil, nil], + 8244 => [0, 0, nil, "′′′", nil, nil, nil], + 8246 => [0, 0, nil, "‵‵", nil, nil, nil], + 8247 => [0, 0, nil, "‵‵‵", nil, nil, nil], + 8252 => [0, 0, nil, "!!", nil, nil, nil], + 8254 => [0, 0, nil, " ̅", nil, nil, nil], + 8264 => [0, 0, nil, "?!", nil, nil, nil], + 8265 => [0, 0, nil, "!?", nil, nil, nil], + 8304 => [0, 0, nil, "0", nil, nil, nil], + 8308 => [0, 0, nil, "4", nil, nil, nil], + 8309 => [0, 0, nil, "5", nil, nil, nil], + 8310 => [0, 0, nil, "6", nil, nil, nil], + 8311 => [0, 0, nil, "7", nil, nil, nil], + 8312 => [0, 0, nil, "8", nil, nil, nil], + 8313 => [0, 0, nil, "9", nil, nil, nil], + 8314 => [0, 0, nil, "+", nil, nil, nil], + 8315 => [0, 0, nil, "−", nil, nil, nil], + 8316 => [0, 0, nil, "=", nil, nil, nil], + 8317 => [0, 0, nil, "(", nil, nil, nil], + 8318 => [0, 0, nil, ")", nil, nil, nil], + 8319 => [0, 0, nil, "n", nil, nil, nil], + 8320 => [0, 0, nil, "0", nil, nil, nil], + 8321 => [0, 0, nil, "1", nil, nil, nil], + 8322 => [0, 0, nil, "2", nil, nil, nil], + 8323 => [0, 0, nil, "3", nil, nil, nil], + 8324 => [0, 0, nil, "4", nil, nil, nil], + 8325 => [0, 0, nil, "5", nil, nil, nil], + 8326 => [0, 0, nil, "6", nil, nil, nil], + 8327 => [0, 0, nil, "7", nil, nil, nil], + 8328 => [0, 0, nil, "8", nil, nil, nil], + 8329 => [0, 0, nil, "9", nil, nil, nil], + 8330 => [0, 0, nil, "+", nil, nil, nil], + 8331 => [0, 0, nil, "−", nil, nil, nil], + 8332 => [0, 0, nil, "=", nil, nil, nil], + 8333 => [0, 0, nil, "(", nil, nil, nil], + 8334 => [0, 0, nil, ")", nil, nil, nil], + 8360 => [0, 0, nil, "Rs", nil, nil, nil], + 8400 => [230, 0, nil, nil, nil, nil, nil], + 8401 => [230, 0, nil, nil, nil, nil, nil], + 8402 => [1, 0, nil, nil, nil, nil, nil], + 8403 => [1, 0, nil, nil, nil, nil, nil], + 8404 => [230, 0, nil, nil, nil, nil, nil], + 8405 => [230, 0, nil, nil, nil, nil, nil], + 8406 => [230, 0, nil, nil, nil, nil, nil], + 8407 => [230, 0, nil, nil, nil, nil, nil], + 8408 => [1, 0, nil, nil, nil, nil, nil], + 8409 => [1, 0, nil, nil, nil, nil, nil], + 8410 => [1, 0, nil, nil, nil, nil, nil], + 8411 => [230, 0, nil, nil, nil, nil, nil], + 8412 => [230, 0, nil, nil, nil, nil, nil], + 8417 => [230, 0, nil, nil, nil, nil, nil], + 8448 => [0, 0, nil, "a/c", nil, nil, nil], + 8449 => [0, 0, nil, "a/s", nil, nil, nil], + 8450 => [0, 0, nil, "C", nil, nil, nil], + 8451 => [0, 0, nil, "°C", nil, nil, nil], + 8453 => [0, 0, nil, "c/o", nil, nil, nil], + 8454 => [0, 0, nil, "c/u", nil, nil, nil], + 8455 => [0, 0, nil, "Ɛ", nil, nil, nil], + 8457 => [0, 0, nil, "°F", nil, nil, nil], + 8458 => [0, 0, nil, "g", nil, nil, nil], + 8459 => [0, 0, nil, "H", nil, nil, nil], + 8460 => [0, 0, nil, "H", nil, nil, nil], + 8461 => [0, 0, nil, "H", nil, nil, nil], + 8462 => [0, 0, nil, "h", nil, nil, nil], + 8463 => [0, 0, nil, "ħ", nil, nil, nil], + 8464 => [0, 0, nil, "I", nil, nil, nil], + 8465 => [0, 0, nil, "I", nil, nil, nil], + 8466 => [0, 0, nil, "L", nil, nil, nil], + 8467 => [0, 0, nil, "l", nil, nil, nil], + 8469 => [0, 0, nil, "N", nil, nil, nil], + 8470 => [0, 0, nil, "No", nil, nil, nil], + 8473 => [0, 0, nil, "P", nil, nil, nil], + 8474 => [0, 0, nil, "Q", nil, nil, nil], + 8475 => [0, 0, nil, "R", nil, nil, nil], + 8476 => [0, 0, nil, "R", nil, nil, nil], + 8477 => [0, 0, nil, "R", nil, nil, nil], + 8480 => [0, 0, nil, "SM", nil, nil, nil], + 8481 => [0, 0, nil, "TEL", nil, nil, nil], + 8482 => [0, 0, nil, "TM", nil, nil, nil], + 8484 => [0, 0, nil, "Z", nil, nil, nil], + 8486 => [0, 2, "Ω", "Ω", nil, 969, nil], + 8488 => [0, 0, nil, "Z", nil, nil, nil], + 8490 => [0, 2, "K", "K", nil, 107, nil], + 8491 => [0, 2, "Å", "Å", nil, 229, nil], + 8492 => [0, 0, nil, "B", nil, nil, nil], + 8493 => [0, 0, nil, "C", nil, nil, nil], + 8495 => [0, 0, nil, "e", nil, nil, nil], + 8496 => [0, 0, nil, "E", nil, nil, nil], + 8497 => [0, 0, nil, "F", nil, nil, nil], + 8499 => [0, 0, nil, "M", nil, nil, nil], + 8500 => [0, 0, nil, "o", nil, nil, nil], + 8501 => [0, 0, nil, "א", nil, nil, nil], + 8502 => [0, 0, nil, "ב", nil, nil, nil], + 8503 => [0, 0, nil, "ג", nil, nil, nil], + 8504 => [0, 0, nil, "ד", nil, nil, nil], + 8505 => [0, 0, nil, "i", nil, nil, nil], + 8531 => [0, 0, nil, "1⁄3", nil, nil, nil], + 8532 => [0, 0, nil, "2⁄3", nil, nil, nil], + 8533 => [0, 0, nil, "1⁄5", nil, nil, nil], + 8534 => [0, 0, nil, "2⁄5", nil, nil, nil], + 8535 => [0, 0, nil, "3⁄5", nil, nil, nil], + 8536 => [0, 0, nil, "4⁄5", nil, nil, nil], + 8537 => [0, 0, nil, "1⁄6", nil, nil, nil], + 8538 => [0, 0, nil, "5⁄6", nil, nil, nil], + 8539 => [0, 0, nil, "1⁄8", nil, nil, nil], + 8540 => [0, 0, nil, "3⁄8", nil, nil, nil], + 8541 => [0, 0, nil, "5⁄8", nil, nil, nil], + 8542 => [0, 0, nil, "7⁄8", nil, nil, nil], + 8543 => [0, 0, nil, "1⁄", nil, nil, nil], + 8544 => [0, 0, nil, "I", nil, 8560, nil], + 8545 => [0, 0, nil, "II", nil, 8561, nil], + 8546 => [0, 0, nil, "III", nil, 8562, nil], + 8547 => [0, 0, nil, "IV", nil, 8563, nil], + 8548 => [0, 0, nil, "V", nil, 8564, nil], + 8549 => [0, 0, nil, "VI", nil, 8565, nil], + 8550 => [0, 0, nil, "VII", nil, 8566, nil], + 8551 => [0, 0, nil, "VIII", nil, 8567, nil], + 8552 => [0, 0, nil, "IX", nil, 8568, nil], + 8553 => [0, 0, nil, "X", nil, 8569, nil], + 8554 => [0, 0, nil, "XI", nil, 8570, nil], + 8555 => [0, 0, nil, "XII", nil, 8571, nil], + 8556 => [0, 0, nil, "L", nil, 8572, nil], + 8557 => [0, 0, nil, "C", nil, 8573, nil], + 8558 => [0, 0, nil, "D", nil, 8574, nil], + 8559 => [0, 0, nil, "M", nil, 8575, nil], + 8560 => [0, 0, nil, "i", 8544, nil, 8544], + 8561 => [0, 0, nil, "ii", 8545, nil, 8545], + 8562 => [0, 0, nil, "iii", 8546, nil, 8546], + 8563 => [0, 0, nil, "iv", 8547, nil, 8547], + 8564 => [0, 0, nil, "v", 8548, nil, 8548], + 8565 => [0, 0, nil, "vi", 8549, nil, 8549], + 8566 => [0, 0, nil, "vii", 8550, nil, 8550], + 8567 => [0, 0, nil, "viii", 8551, nil, 8551], + 8568 => [0, 0, nil, "ix", 8552, nil, 8552], + 8569 => [0, 0, nil, "x", 8553, nil, 8553], + 8570 => [0, 0, nil, "xi", 8554, nil, 8554], + 8571 => [0, 0, nil, "xii", 8555, nil, 8555], + 8572 => [0, 0, nil, "l", 8556, nil, 8556], + 8573 => [0, 0, nil, "c", 8557, nil, 8557], + 8574 => [0, 0, nil, "d", 8558, nil, 8558], + 8575 => [0, 0, nil, "m", 8559, nil, 8559], + 8602 => [0, 0, "↚", "↚", nil, nil, nil], + 8603 => [0, 0, "↛", "↛", nil, nil, nil], + 8622 => [0, 0, "↮", "↮", nil, nil, nil], + 8653 => [0, 0, "⇍", "⇍", nil, nil, nil], + 8654 => [0, 0, "⇎", "⇎", nil, nil, nil], + 8655 => [0, 0, "⇏", "⇏", nil, nil, nil], + 8708 => [0, 0, "∄", "∄", nil, nil, nil], + 8713 => [0, 0, "∉", "∉", nil, nil, nil], + 8716 => [0, 0, "∌", "∌", nil, nil, nil], + 8740 => [0, 0, "∤", "∤", nil, nil, nil], + 8742 => [0, 0, "∦", "∦", nil, nil, nil], + 8748 => [0, 0, nil, "∫∫", nil, nil, nil], + 8749 => [0, 0, nil, "∫∫∫", nil, nil, nil], + 8751 => [0, 0, nil, "∮∮", nil, nil, nil], + 8752 => [0, 0, nil, "∮∮∮", nil, nil, nil], + 8769 => [0, 0, "≁", "≁", nil, nil, nil], + 8772 => [0, 0, "≄", "≄", nil, nil, nil], + 8775 => [0, 0, "≇", "≇", nil, nil, nil], + 8777 => [0, 0, "≉", "≉", nil, nil, nil], + 8800 => [0, 0, "≠", "≠", nil, nil, nil], + 8802 => [0, 0, "≢", "≢", nil, nil, nil], + 8813 => [0, 0, "≭", "≭", nil, nil, nil], + 8814 => [0, 0, "≮", "≮", nil, nil, nil], + 8815 => [0, 0, "≯", "≯", nil, nil, nil], + 8816 => [0, 0, "≰", "≰", nil, nil, nil], + 8817 => [0, 0, "≱", "≱", nil, nil, nil], + 8820 => [0, 0, "≴", "≴", nil, nil, nil], + 8821 => [0, 0, "≵", "≵", nil, nil, nil], + 8824 => [0, 0, "≸", "≸", nil, nil, nil], + 8825 => [0, 0, "≹", "≹", nil, nil, nil], + 8832 => [0, 0, "⊀", "⊀", nil, nil, nil], + 8833 => [0, 0, "⊁", "⊁", nil, nil, nil], + 8836 => [0, 0, "⊄", "⊄", nil, nil, nil], + 8837 => [0, 0, "⊅", "⊅", nil, nil, nil], + 8840 => [0, 0, "⊈", "⊈", nil, nil, nil], + 8841 => [0, 0, "⊉", "⊉", nil, nil, nil], + 8876 => [0, 0, "⊬", "⊬", nil, nil, nil], + 8877 => [0, 0, "⊭", "⊭", nil, nil, nil], + 8878 => [0, 0, "⊮", "⊮", nil, nil, nil], + 8879 => [0, 0, "⊯", "⊯", nil, nil, nil], + 8928 => [0, 0, "⋠", "⋠", nil, nil, nil], + 8929 => [0, 0, "⋡", "⋡", nil, nil, nil], + 8930 => [0, 0, "⋢", "⋢", nil, nil, nil], + 8931 => [0, 0, "⋣", "⋣", nil, nil, nil], + 8938 => [0, 0, "⋪", "⋪", nil, nil, nil], + 8939 => [0, 0, "⋫", "⋫", nil, nil, nil], + 8940 => [0, 0, "⋬", "⋬", nil, nil, nil], + 8941 => [0, 0, "⋭", "⋭", nil, nil, nil], + 9001 => [0, 2, "〈", "〈", nil, nil, nil], + 9002 => [0, 2, "〉", "〉", nil, nil, nil], + 9312 => [0, 0, nil, "1", nil, nil, nil], + 9313 => [0, 0, nil, "2", nil, nil, nil], + 9314 => [0, 0, nil, "3", nil, nil, nil], + 9315 => [0, 0, nil, "4", nil, nil, nil], + 9316 => [0, 0, nil, "5", nil, nil, nil], + 9317 => [0, 0, nil, "6", nil, nil, nil], + 9318 => [0, 0, nil, "7", nil, nil, nil], + 9319 => [0, 0, nil, "8", nil, nil, nil], + 9320 => [0, 0, nil, "9", nil, nil, nil], + 9321 => [0, 0, nil, "10", nil, nil, nil], + 9322 => [0, 0, nil, "11", nil, nil, nil], + 9323 => [0, 0, nil, "12", nil, nil, nil], + 9324 => [0, 0, nil, "13", nil, nil, nil], + 9325 => [0, 0, nil, "14", nil, nil, nil], + 9326 => [0, 0, nil, "15", nil, nil, nil], + 9327 => [0, 0, nil, "16", nil, nil, nil], + 9328 => [0, 0, nil, "17", nil, nil, nil], + 9329 => [0, 0, nil, "18", nil, nil, nil], + 9330 => [0, 0, nil, "19", nil, nil, nil], + 9331 => [0, 0, nil, "20", nil, nil, nil], + 9332 => [0, 0, nil, "(1)", nil, nil, nil], + 9333 => [0, 0, nil, "(2)", nil, nil, nil], + 9334 => [0, 0, nil, "(3)", nil, nil, nil], + 9335 => [0, 0, nil, "(4)", nil, nil, nil], + 9336 => [0, 0, nil, "(5)", nil, nil, nil], + 9337 => [0, 0, nil, "(6)", nil, nil, nil], + 9338 => [0, 0, nil, "(7)", nil, nil, nil], + 9339 => [0, 0, nil, "(8)", nil, nil, nil], + 9340 => [0, 0, nil, "(9)", nil, nil, nil], + 9341 => [0, 0, nil, "(10)", nil, nil, nil], + 9342 => [0, 0, nil, "(11)", nil, nil, nil], + 9343 => [0, 0, nil, "(12)", nil, nil, nil], + 9344 => [0, 0, nil, "(13)", nil, nil, nil], + 9345 => [0, 0, nil, "(14)", nil, nil, nil], + 9346 => [0, 0, nil, "(15)", nil, nil, nil], + 9347 => [0, 0, nil, "(16)", nil, nil, nil], + 9348 => [0, 0, nil, "(17)", nil, nil, nil], + 9349 => [0, 0, nil, "(18)", nil, nil, nil], + 9350 => [0, 0, nil, "(19)", nil, nil, nil], + 9351 => [0, 0, nil, "(20)", nil, nil, nil], + 9352 => [0, 0, nil, "1.", nil, nil, nil], + 9353 => [0, 0, nil, "2.", nil, nil, nil], + 9354 => [0, 0, nil, "3.", nil, nil, nil], + 9355 => [0, 0, nil, "4.", nil, nil, nil], + 9356 => [0, 0, nil, "5.", nil, nil, nil], + 9357 => [0, 0, nil, "6.", nil, nil, nil], + 9358 => [0, 0, nil, "7.", nil, nil, nil], + 9359 => [0, 0, nil, "8.", nil, nil, nil], + 9360 => [0, 0, nil, "9.", nil, nil, nil], + 9361 => [0, 0, nil, "10.", nil, nil, nil], + 9362 => [0, 0, nil, "11.", nil, nil, nil], + 9363 => [0, 0, nil, "12.", nil, nil, nil], + 9364 => [0, 0, nil, "13.", nil, nil, nil], + 9365 => [0, 0, nil, "14.", nil, nil, nil], + 9366 => [0, 0, nil, "15.", nil, nil, nil], + 9367 => [0, 0, nil, "16.", nil, nil, nil], + 9368 => [0, 0, nil, "17.", nil, nil, nil], + 9369 => [0, 0, nil, "18.", nil, nil, nil], + 9370 => [0, 0, nil, "19.", nil, nil, nil], + 9371 => [0, 0, nil, "20.", nil, nil, nil], + 9372 => [0, 0, nil, "(a)", nil, nil, nil], + 9373 => [0, 0, nil, "(b)", nil, nil, nil], + 9374 => [0, 0, nil, "(c)", nil, nil, nil], + 9375 => [0, 0, nil, "(d)", nil, nil, nil], + 9376 => [0, 0, nil, "(e)", nil, nil, nil], + 9377 => [0, 0, nil, "(f)", nil, nil, nil], + 9378 => [0, 0, nil, "(g)", nil, nil, nil], + 9379 => [0, 0, nil, "(h)", nil, nil, nil], + 9380 => [0, 0, nil, "(i)", nil, nil, nil], + 9381 => [0, 0, nil, "(j)", nil, nil, nil], + 9382 => [0, 0, nil, "(k)", nil, nil, nil], + 9383 => [0, 0, nil, "(l)", nil, nil, nil], + 9384 => [0, 0, nil, "(m)", nil, nil, nil], + 9385 => [0, 0, nil, "(n)", nil, nil, nil], + 9386 => [0, 0, nil, "(o)", nil, nil, nil], + 9387 => [0, 0, nil, "(p)", nil, nil, nil], + 9388 => [0, 0, nil, "(q)", nil, nil, nil], + 9389 => [0, 0, nil, "(r)", nil, nil, nil], + 9390 => [0, 0, nil, "(s)", nil, nil, nil], + 9391 => [0, 0, nil, "(t)", nil, nil, nil], + 9392 => [0, 0, nil, "(u)", nil, nil, nil], + 9393 => [0, 0, nil, "(v)", nil, nil, nil], + 9394 => [0, 0, nil, "(w)", nil, nil, nil], + 9395 => [0, 0, nil, "(x)", nil, nil, nil], + 9396 => [0, 0, nil, "(y)", nil, nil, nil], + 9397 => [0, 0, nil, "(z)", nil, nil, nil], + 9398 => [0, 0, nil, "A", nil, 9424, nil], + 9399 => [0, 0, nil, "B", nil, 9425, nil], + 9400 => [0, 0, nil, "C", nil, 9426, nil], + 9401 => [0, 0, nil, "D", nil, 9427, nil], + 9402 => [0, 0, nil, "E", nil, 9428, nil], + 9403 => [0, 0, nil, "F", nil, 9429, nil], + 9404 => [0, 0, nil, "G", nil, 9430, nil], + 9405 => [0, 0, nil, "H", nil, 9431, nil], + 9406 => [0, 0, nil, "I", nil, 9432, nil], + 9407 => [0, 0, nil, "J", nil, 9433, nil], + 9408 => [0, 0, nil, "K", nil, 9434, nil], + 9409 => [0, 0, nil, "L", nil, 9435, nil], + 9410 => [0, 0, nil, "M", nil, 9436, nil], + 9411 => [0, 0, nil, "N", nil, 9437, nil], + 9412 => [0, 0, nil, "O", nil, 9438, nil], + 9413 => [0, 0, nil, "P", nil, 9439, nil], + 9414 => [0, 0, nil, "Q", nil, 9440, nil], + 9415 => [0, 0, nil, "R", nil, 9441, nil], + 9416 => [0, 0, nil, "S", nil, 9442, nil], + 9417 => [0, 0, nil, "T", nil, 9443, nil], + 9418 => [0, 0, nil, "U", nil, 9444, nil], + 9419 => [0, 0, nil, "V", nil, 9445, nil], + 9420 => [0, 0, nil, "W", nil, 9446, nil], + 9421 => [0, 0, nil, "X", nil, 9447, nil], + 9422 => [0, 0, nil, "Y", nil, 9448, nil], + 9423 => [0, 0, nil, "Z", nil, 9449, nil], + 9424 => [0, 0, nil, "a", 9398, nil, 9398], + 9425 => [0, 0, nil, "b", 9399, nil, 9399], + 9426 => [0, 0, nil, "c", 9400, nil, 9400], + 9427 => [0, 0, nil, "d", 9401, nil, 9401], + 9428 => [0, 0, nil, "e", 9402, nil, 9402], + 9429 => [0, 0, nil, "f", 9403, nil, 9403], + 9430 => [0, 0, nil, "g", 9404, nil, 9404], + 9431 => [0, 0, nil, "h", 9405, nil, 9405], + 9432 => [0, 0, nil, "i", 9406, nil, 9406], + 9433 => [0, 0, nil, "j", 9407, nil, 9407], + 9434 => [0, 0, nil, "k", 9408, nil, 9408], + 9435 => [0, 0, nil, "l", 9409, nil, 9409], + 9436 => [0, 0, nil, "m", 9410, nil, 9410], + 9437 => [0, 0, nil, "n", 9411, nil, 9411], + 9438 => [0, 0, nil, "o", 9412, nil, 9412], + 9439 => [0, 0, nil, "p", 9413, nil, 9413], + 9440 => [0, 0, nil, "q", 9414, nil, 9414], + 9441 => [0, 0, nil, "r", 9415, nil, 9415], + 9442 => [0, 0, nil, "s", 9416, nil, 9416], + 9443 => [0, 0, nil, "t", 9417, nil, 9417], + 9444 => [0, 0, nil, "u", 9418, nil, 9418], + 9445 => [0, 0, nil, "v", 9419, nil, 9419], + 9446 => [0, 0, nil, "w", 9420, nil, 9420], + 9447 => [0, 0, nil, "x", 9421, nil, 9421], + 9448 => [0, 0, nil, "y", 9422, nil, 9422], + 9449 => [0, 0, nil, "z", 9423, nil, 9423], + 9450 => [0, 0, nil, "0", nil, nil, nil], + 11935 => [0, 0, nil, "母", nil, nil, nil], + 12019 => [0, 0, nil, "龟", nil, nil, nil], + 12032 => [0, 0, nil, "一", nil, nil, nil], + 12033 => [0, 0, nil, "丨", nil, nil, nil], + 12034 => [0, 0, nil, "丶", nil, nil, nil], + 12035 => [0, 0, nil, "丿", nil, nil, nil], + 12036 => [0, 0, nil, "乙", nil, nil, nil], + 12037 => [0, 0, nil, "亅", nil, nil, nil], + 12038 => [0, 0, nil, "二", nil, nil, nil], + 12039 => [0, 0, nil, "亠", nil, nil, nil], + 12040 => [0, 0, nil, "人", nil, nil, nil], + 12041 => [0, 0, nil, "儿", nil, nil, nil], + 12042 => [0, 0, nil, "入", nil, nil, nil], + 12043 => [0, 0, nil, "八", nil, nil, nil], + 12044 => [0, 0, nil, "冂", nil, nil, nil], + 12045 => [0, 0, nil, "冖", nil, nil, nil], + 12046 => [0, 0, nil, "冫", nil, nil, nil], + 12047 => [0, 0, nil, "几", nil, nil, nil], + 12048 => [0, 0, nil, "凵", nil, nil, nil], + 12049 => [0, 0, nil, "刀", nil, nil, nil], + 12050 => [0, 0, nil, "力", nil, nil, nil], + 12051 => [0, 0, nil, "勹", nil, nil, nil], + 12052 => [0, 0, nil, "匕", nil, nil, nil], + 12053 => [0, 0, nil, "匚", nil, nil, nil], + 12054 => [0, 0, nil, "匸", nil, nil, nil], + 12055 => [0, 0, nil, "十", nil, nil, nil], + 12056 => [0, 0, nil, "卜", nil, nil, nil], + 12057 => [0, 0, nil, "卩", nil, nil, nil], + 12058 => [0, 0, nil, "厂", nil, nil, nil], + 12059 => [0, 0, nil, "厶", nil, nil, nil], + 12060 => [0, 0, nil, "又", nil, nil, nil], + 12061 => [0, 0, nil, "口", nil, nil, nil], + 12062 => [0, 0, nil, "囗", nil, nil, nil], + 12063 => [0, 0, nil, "土", nil, nil, nil], + 12064 => [0, 0, nil, "士", nil, nil, nil], + 12065 => [0, 0, nil, "夂", nil, nil, nil], + 12066 => [0, 0, nil, "夊", nil, nil, nil], + 12067 => [0, 0, nil, "夕", nil, nil, nil], + 12068 => [0, 0, nil, "大", nil, nil, nil], + 12069 => [0, 0, nil, "女", nil, nil, nil], + 12070 => [0, 0, nil, "子", nil, nil, nil], + 12071 => [0, 0, nil, "宀", nil, nil, nil], + 12072 => [0, 0, nil, "寸", nil, nil, nil], + 12073 => [0, 0, nil, "小", nil, nil, nil], + 12074 => [0, 0, nil, "尢", nil, nil, nil], + 12075 => [0, 0, nil, "尸", nil, nil, nil], + 12076 => [0, 0, nil, "屮", nil, nil, nil], + 12077 => [0, 0, nil, "山", nil, nil, nil], + 12078 => [0, 0, nil, "巛", nil, nil, nil], + 12079 => [0, 0, nil, "工", nil, nil, nil], + 12080 => [0, 0, nil, "己", nil, nil, nil], + 12081 => [0, 0, nil, "巾", nil, nil, nil], + 12082 => [0, 0, nil, "干", nil, nil, nil], + 12083 => [0, 0, nil, "幺", nil, nil, nil], + 12084 => [0, 0, nil, "广", nil, nil, nil], + 12085 => [0, 0, nil, "廴", nil, nil, nil], + 12086 => [0, 0, nil, "廾", nil, nil, nil], + 12087 => [0, 0, nil, "弋", nil, nil, nil], + 12088 => [0, 0, nil, "弓", nil, nil, nil], + 12089 => [0, 0, nil, "彐", nil, nil, nil], + 12090 => [0, 0, nil, "彡", nil, nil, nil], + 12091 => [0, 0, nil, "彳", nil, nil, nil], + 12092 => [0, 0, nil, "心", nil, nil, nil], + 12093 => [0, 0, nil, "戈", nil, nil, nil], + 12094 => [0, 0, nil, "戶", nil, nil, nil], + 12095 => [0, 0, nil, "手", nil, nil, nil], + 12096 => [0, 0, nil, "支", nil, nil, nil], + 12097 => [0, 0, nil, "攴", nil, nil, nil], + 12098 => [0, 0, nil, "文", nil, nil, nil], + 12099 => [0, 0, nil, "斗", nil, nil, nil], + 12100 => [0, 0, nil, "斤", nil, nil, nil], + 12101 => [0, 0, nil, "方", nil, nil, nil], + 12102 => [0, 0, nil, "无", nil, nil, nil], + 12103 => [0, 0, nil, "日", nil, nil, nil], + 12104 => [0, 0, nil, "曰", nil, nil, nil], + 12105 => [0, 0, nil, "月", nil, nil, nil], + 12106 => [0, 0, nil, "木", nil, nil, nil], + 12107 => [0, 0, nil, "欠", nil, nil, nil], + 12108 => [0, 0, nil, "止", nil, nil, nil], + 12109 => [0, 0, nil, "歹", nil, nil, nil], + 12110 => [0, 0, nil, "殳", nil, nil, nil], + 12111 => [0, 0, nil, "毋", nil, nil, nil], + 12112 => [0, 0, nil, "比", nil, nil, nil], + 12113 => [0, 0, nil, "毛", nil, nil, nil], + 12114 => [0, 0, nil, "氏", nil, nil, nil], + 12115 => [0, 0, nil, "气", nil, nil, nil], + 12116 => [0, 0, nil, "水", nil, nil, nil], + 12117 => [0, 0, nil, "火", nil, nil, nil], + 12118 => [0, 0, nil, "爪", nil, nil, nil], + 12119 => [0, 0, nil, "父", nil, nil, nil], + 12120 => [0, 0, nil, "爻", nil, nil, nil], + 12121 => [0, 0, nil, "爿", nil, nil, nil], + 12122 => [0, 0, nil, "片", nil, nil, nil], + 12123 => [0, 0, nil, "牙", nil, nil, nil], + 12124 => [0, 0, nil, "牛", nil, nil, nil], + 12125 => [0, 0, nil, "犬", nil, nil, nil], + 12126 => [0, 0, nil, "玄", nil, nil, nil], + 12127 => [0, 0, nil, "玉", nil, nil, nil], + 12128 => [0, 0, nil, "瓜", nil, nil, nil], + 12129 => [0, 0, nil, "瓦", nil, nil, nil], + 12130 => [0, 0, nil, "甘", nil, nil, nil], + 12131 => [0, 0, nil, "生", nil, nil, nil], + 12132 => [0, 0, nil, "用", nil, nil, nil], + 12133 => [0, 0, nil, "田", nil, nil, nil], + 12134 => [0, 0, nil, "疋", nil, nil, nil], + 12135 => [0, 0, nil, "疒", nil, nil, nil], + 12136 => [0, 0, nil, "癶", nil, nil, nil], + 12137 => [0, 0, nil, "白", nil, nil, nil], + 12138 => [0, 0, nil, "皮", nil, nil, nil], + 12139 => [0, 0, nil, "皿", nil, nil, nil], + 12140 => [0, 0, nil, "目", nil, nil, nil], + 12141 => [0, 0, nil, "矛", nil, nil, nil], + 12142 => [0, 0, nil, "矢", nil, nil, nil], + 12143 => [0, 0, nil, "石", nil, nil, nil], + 12144 => [0, 0, nil, "示", nil, nil, nil], + 12145 => [0, 0, nil, "禸", nil, nil, nil], + 12146 => [0, 0, nil, "禾", nil, nil, nil], + 12147 => [0, 0, nil, "穴", nil, nil, nil], + 12148 => [0, 0, nil, "立", nil, nil, nil], + 12149 => [0, 0, nil, "竹", nil, nil, nil], + 12150 => [0, 0, nil, "米", nil, nil, nil], + 12151 => [0, 0, nil, "糸", nil, nil, nil], + 12152 => [0, 0, nil, "缶", nil, nil, nil], + 12153 => [0, 0, nil, "网", nil, nil, nil], + 12154 => [0, 0, nil, "羊", nil, nil, nil], + 12155 => [0, 0, nil, "羽", nil, nil, nil], + 12156 => [0, 0, nil, "老", nil, nil, nil], + 12157 => [0, 0, nil, "而", nil, nil, nil], + 12158 => [0, 0, nil, "耒", nil, nil, nil], + 12159 => [0, 0, nil, "耳", nil, nil, nil], + 12160 => [0, 0, nil, "聿", nil, nil, nil], + 12161 => [0, 0, nil, "肉", nil, nil, nil], + 12162 => [0, 0, nil, "臣", nil, nil, nil], + 12163 => [0, 0, nil, "自", nil, nil, nil], + 12164 => [0, 0, nil, "至", nil, nil, nil], + 12165 => [0, 0, nil, "臼", nil, nil, nil], + 12166 => [0, 0, nil, "舌", nil, nil, nil], + 12167 => [0, 0, nil, "舛", nil, nil, nil], + 12168 => [0, 0, nil, "舟", nil, nil, nil], + 12169 => [0, 0, nil, "艮", nil, nil, nil], + 12170 => [0, 0, nil, "色", nil, nil, nil], + 12171 => [0, 0, nil, "艸", nil, nil, nil], + 12172 => [0, 0, nil, "虍", nil, nil, nil], + 12173 => [0, 0, nil, "虫", nil, nil, nil], + 12174 => [0, 0, nil, "血", nil, nil, nil], + 12175 => [0, 0, nil, "行", nil, nil, nil], + 12176 => [0, 0, nil, "衣", nil, nil, nil], + 12177 => [0, 0, nil, "襾", nil, nil, nil], + 12178 => [0, 0, nil, "見", nil, nil, nil], + 12179 => [0, 0, nil, "角", nil, nil, nil], + 12180 => [0, 0, nil, "言", nil, nil, nil], + 12181 => [0, 0, nil, "谷", nil, nil, nil], + 12182 => [0, 0, nil, "豆", nil, nil, nil], + 12183 => [0, 0, nil, "豕", nil, nil, nil], + 12184 => [0, 0, nil, "豸", nil, nil, nil], + 12185 => [0, 0, nil, "貝", nil, nil, nil], + 12186 => [0, 0, nil, "赤", nil, nil, nil], + 12187 => [0, 0, nil, "走", nil, nil, nil], + 12188 => [0, 0, nil, "足", nil, nil, nil], + 12189 => [0, 0, nil, "身", nil, nil, nil], + 12190 => [0, 0, nil, "車", nil, nil, nil], + 12191 => [0, 0, nil, "辛", nil, nil, nil], + 12192 => [0, 0, nil, "辰", nil, nil, nil], + 12193 => [0, 0, nil, "辵", nil, nil, nil], + 12194 => [0, 0, nil, "邑", nil, nil, nil], + 12195 => [0, 0, nil, "酉", nil, nil, nil], + 12196 => [0, 0, nil, "釆", nil, nil, nil], + 12197 => [0, 0, nil, "里", nil, nil, nil], + 12198 => [0, 0, nil, "金", nil, nil, nil], + 12199 => [0, 0, nil, "長", nil, nil, nil], + 12200 => [0, 0, nil, "門", nil, nil, nil], + 12201 => [0, 0, nil, "阜", nil, nil, nil], + 12202 => [0, 0, nil, "隶", nil, nil, nil], + 12203 => [0, 0, nil, "隹", nil, nil, nil], + 12204 => [0, 0, nil, "雨", nil, nil, nil], + 12205 => [0, 0, nil, "靑", nil, nil, nil], + 12206 => [0, 0, nil, "非", nil, nil, nil], + 12207 => [0, 0, nil, "面", nil, nil, nil], + 12208 => [0, 0, nil, "革", nil, nil, nil], + 12209 => [0, 0, nil, "韋", nil, nil, nil], + 12210 => [0, 0, nil, "韭", nil, nil, nil], + 12211 => [0, 0, nil, "音", nil, nil, nil], + 12212 => [0, 0, nil, "頁", nil, nil, nil], + 12213 => [0, 0, nil, "風", nil, nil, nil], + 12214 => [0, 0, nil, "飛", nil, nil, nil], + 12215 => [0, 0, nil, "食", nil, nil, nil], + 12216 => [0, 0, nil, "首", nil, nil, nil], + 12217 => [0, 0, nil, "香", nil, nil, nil], + 12218 => [0, 0, nil, "馬", nil, nil, nil], + 12219 => [0, 0, nil, "骨", nil, nil, nil], + 12220 => [0, 0, nil, "高", nil, nil, nil], + 12221 => [0, 0, nil, "髟", nil, nil, nil], + 12222 => [0, 0, nil, "鬥", nil, nil, nil], + 12223 => [0, 0, nil, "鬯", nil, nil, nil], + 12224 => [0, 0, nil, "鬲", nil, nil, nil], + 12225 => [0, 0, nil, "鬼", nil, nil, nil], + 12226 => [0, 0, nil, "魚", nil, nil, nil], + 12227 => [0, 0, nil, "鳥", nil, nil, nil], + 12228 => [0, 0, nil, "鹵", nil, nil, nil], + 12229 => [0, 0, nil, "鹿", nil, nil, nil], + 12230 => [0, 0, nil, "麥", nil, nil, nil], + 12231 => [0, 0, nil, "麻", nil, nil, nil], + 12232 => [0, 0, nil, "黃", nil, nil, nil], + 12233 => [0, 0, nil, "黍", nil, nil, nil], + 12234 => [0, 0, nil, "黑", nil, nil, nil], + 12235 => [0, 0, nil, "黹", nil, nil, nil], + 12236 => [0, 0, nil, "黽", nil, nil, nil], + 12237 => [0, 0, nil, "鼎", nil, nil, nil], + 12238 => [0, 0, nil, "鼓", nil, nil, nil], + 12239 => [0, 0, nil, "鼠", nil, nil, nil], + 12240 => [0, 0, nil, "鼻", nil, nil, nil], + 12241 => [0, 0, nil, "齊", nil, nil, nil], + 12242 => [0, 0, nil, "齒", nil, nil, nil], + 12243 => [0, 0, nil, "龍", nil, nil, nil], + 12244 => [0, 0, nil, "龜", nil, nil, nil], + 12245 => [0, 0, nil, "龠", nil, nil, nil], + 12288 => [0, 0, nil, " ", nil, nil, nil], + 12330 => [218, 0, nil, nil, nil, nil, nil], + 12331 => [228, 0, nil, nil, nil, nil, nil], + 12332 => [232, 0, nil, nil, nil, nil, nil], + 12333 => [222, 0, nil, nil, nil, nil, nil], + 12334 => [224, 0, nil, nil, nil, nil, nil], + 12335 => [224, 0, nil, nil, nil, nil, nil], + 12342 => [0, 0, nil, "〒", nil, nil, nil], + 12344 => [0, 0, nil, "十", nil, nil, nil], + 12345 => [0, 0, nil, "卄", nil, nil, nil], + 12346 => [0, 0, nil, "卅", nil, nil, nil], + 12364 => [0, 0, "が", "が", nil, nil, nil], + 12366 => [0, 0, "ぎ", "ぎ", nil, nil, nil], + 12368 => [0, 0, "ぐ", "ぐ", nil, nil, nil], + 12370 => [0, 0, "げ", "げ", nil, nil, nil], + 12372 => [0, 0, "ご", "ご", nil, nil, nil], + 12374 => [0, 0, "ざ", "ざ", nil, nil, nil], + 12376 => [0, 0, "じ", "じ", nil, nil, nil], + 12378 => [0, 0, "ず", "ず", nil, nil, nil], + 12380 => [0, 0, "ぜ", "ぜ", nil, nil, nil], + 12382 => [0, 0, "ぞ", "ぞ", nil, nil, nil], + 12384 => [0, 0, "だ", "だ", nil, nil, nil], + 12386 => [0, 0, "ぢ", "ぢ", nil, nil, nil], + 12389 => [0, 0, "づ", "づ", nil, nil, nil], + 12391 => [0, 0, "で", "で", nil, nil, nil], + 12393 => [0, 0, "ど", "ど", nil, nil, nil], + 12400 => [0, 0, "ば", "ば", nil, nil, nil], + 12401 => [0, 0, "ぱ", "ぱ", nil, nil, nil], + 12403 => [0, 0, "び", "び", nil, nil, nil], + 12404 => [0, 0, "ぴ", "ぴ", nil, nil, nil], + 12406 => [0, 0, "ぶ", "ぶ", nil, nil, nil], + 12407 => [0, 0, "ぷ", "ぷ", nil, nil, nil], + 12409 => [0, 0, "べ", "べ", nil, nil, nil], + 12410 => [0, 0, "ぺ", "ぺ", nil, nil, nil], + 12412 => [0, 0, "ぼ", "ぼ", nil, nil, nil], + 12413 => [0, 0, "ぽ", "ぽ", nil, nil, nil], + 12436 => [0, 0, "ゔ", "ゔ", nil, nil, nil], + 12441 => [8, 0, nil, nil, nil, nil, nil], + 12442 => [8, 0, nil, nil, nil, nil, nil], + 12443 => [0, 0, nil, " ゙", nil, nil, nil], + 12444 => [0, 0, nil, " ゚", nil, nil, nil], + 12446 => [0, 0, "ゞ", "ゞ", nil, nil, nil], + 12460 => [0, 0, "ガ", "ガ", nil, nil, nil], + 12462 => [0, 0, "ギ", "ギ", nil, nil, nil], + 12464 => [0, 0, "グ", "グ", nil, nil, nil], + 12466 => [0, 0, "ゲ", "ゲ", nil, nil, nil], + 12468 => [0, 0, "ゴ", "ゴ", nil, nil, nil], + 12470 => [0, 0, "ザ", "ザ", nil, nil, nil], + 12472 => [0, 0, "ジ", "ジ", nil, nil, nil], + 12474 => [0, 0, "ズ", "ズ", nil, nil, nil], + 12476 => [0, 0, "ゼ", "ゼ", nil, nil, nil], + 12478 => [0, 0, "ゾ", "ゾ", nil, nil, nil], + 12480 => [0, 0, "ダ", "ダ", nil, nil, nil], + 12482 => [0, 0, "ヂ", "ヂ", nil, nil, nil], + 12485 => [0, 0, "ヅ", "ヅ", nil, nil, nil], + 12487 => [0, 0, "デ", "デ", nil, nil, nil], + 12489 => [0, 0, "ド", "ド", nil, nil, nil], + 12496 => [0, 0, "バ", "バ", nil, nil, nil], + 12497 => [0, 0, "パ", "パ", nil, nil, nil], + 12499 => [0, 0, "ビ", "ビ", nil, nil, nil], + 12500 => [0, 0, "ピ", "ピ", nil, nil, nil], + 12502 => [0, 0, "ブ", "ブ", nil, nil, nil], + 12503 => [0, 0, "プ", "プ", nil, nil, nil], + 12505 => [0, 0, "ベ", "ベ", nil, nil, nil], + 12506 => [0, 0, "ペ", "ペ", nil, nil, nil], + 12508 => [0, 0, "ボ", "ボ", nil, nil, nil], + 12509 => [0, 0, "ポ", "ポ", nil, nil, nil], + 12532 => [0, 0, "ヴ", "ヴ", nil, nil, nil], + 12535 => [0, 0, "ヷ", "ヷ", nil, nil, nil], + 12536 => [0, 0, "ヸ", "ヸ", nil, nil, nil], + 12537 => [0, 0, "ヹ", "ヹ", nil, nil, nil], + 12538 => [0, 0, "ヺ", "ヺ", nil, nil, nil], + 12542 => [0, 0, "ヾ", "ヾ", nil, nil, nil], + 12593 => [0, 0, nil, "ᄀ", nil, nil, nil], + 12594 => [0, 0, nil, "ᄁ", nil, nil, nil], + 12595 => [0, 0, nil, "ᆪ", nil, nil, nil], + 12596 => [0, 0, nil, "ᄂ", nil, nil, nil], + 12597 => [0, 0, nil, "ᆬ", nil, nil, nil], + 12598 => [0, 0, nil, "ᆭ", nil, nil, nil], + 12599 => [0, 0, nil, "ᄃ", nil, nil, nil], + 12600 => [0, 0, nil, "ᄄ", nil, nil, nil], + 12601 => [0, 0, nil, "ᄅ", nil, nil, nil], + 12602 => [0, 0, nil, "ᆰ", nil, nil, nil], + 12603 => [0, 0, nil, "ᆱ", nil, nil, nil], + 12604 => [0, 0, nil, "ᆲ", nil, nil, nil], + 12605 => [0, 0, nil, "ᆳ", nil, nil, nil], + 12606 => [0, 0, nil, "ᆴ", nil, nil, nil], + 12607 => [0, 0, nil, "ᆵ", nil, nil, nil], + 12608 => [0, 0, nil, "ᄚ", nil, nil, nil], + 12609 => [0, 0, nil, "ᄆ", nil, nil, nil], + 12610 => [0, 0, nil, "ᄇ", nil, nil, nil], + 12611 => [0, 0, nil, "ᄈ", nil, nil, nil], + 12612 => [0, 0, nil, "ᄡ", nil, nil, nil], + 12613 => [0, 0, nil, "ᄉ", nil, nil, nil], + 12614 => [0, 0, nil, "ᄊ", nil, nil, nil], + 12615 => [0, 0, nil, "ᄋ", nil, nil, nil], + 12616 => [0, 0, nil, "ᄌ", nil, nil, nil], + 12617 => [0, 0, nil, "ᄍ", nil, nil, nil], + 12618 => [0, 0, nil, "ᄎ", nil, nil, nil], + 12619 => [0, 0, nil, "ᄏ", nil, nil, nil], + 12620 => [0, 0, nil, "ᄐ", nil, nil, nil], + 12621 => [0, 0, nil, "ᄑ", nil, nil, nil], + 12622 => [0, 0, nil, "ᄒ", nil, nil, nil], + 12623 => [0, 0, nil, "ᅡ", nil, nil, nil], + 12624 => [0, 0, nil, "ᅢ", nil, nil, nil], + 12625 => [0, 0, nil, "ᅣ", nil, nil, nil], + 12626 => [0, 0, nil, "ᅤ", nil, nil, nil], + 12627 => [0, 0, nil, "ᅥ", nil, nil, nil], + 12628 => [0, 0, nil, "ᅦ", nil, nil, nil], + 12629 => [0, 0, nil, "ᅧ", nil, nil, nil], + 12630 => [0, 0, nil, "ᅨ", nil, nil, nil], + 12631 => [0, 0, nil, "ᅩ", nil, nil, nil], + 12632 => [0, 0, nil, "ᅪ", nil, nil, nil], + 12633 => [0, 0, nil, "ᅫ", nil, nil, nil], + 12634 => [0, 0, nil, "ᅬ", nil, nil, nil], + 12635 => [0, 0, nil, "ᅭ", nil, nil, nil], + 12636 => [0, 0, nil, "ᅮ", nil, nil, nil], + 12637 => [0, 0, nil, "ᅯ", nil, nil, nil], + 12638 => [0, 0, nil, "ᅰ", nil, nil, nil], + 12639 => [0, 0, nil, "ᅱ", nil, nil, nil], + 12640 => [0, 0, nil, "ᅲ", nil, nil, nil], + 12641 => [0, 0, nil, "ᅳ", nil, nil, nil], + 12642 => [0, 0, nil, "ᅴ", nil, nil, nil], + 12643 => [0, 0, nil, "ᅵ", nil, nil, nil], + 12644 => [0, 0, nil, "ᅠ", nil, nil, nil], + 12645 => [0, 0, nil, "ᄔ", nil, nil, nil], + 12646 => [0, 0, nil, "ᄕ", nil, nil, nil], + 12647 => [0, 0, nil, "ᇇ", nil, nil, nil], + 12648 => [0, 0, nil, "ᇈ", nil, nil, nil], + 12649 => [0, 0, nil, "ᇌ", nil, nil, nil], + 12650 => [0, 0, nil, "ᇎ", nil, nil, nil], + 12651 => [0, 0, nil, "ᇓ", nil, nil, nil], + 12652 => [0, 0, nil, "ᇗ", nil, nil, nil], + 12653 => [0, 0, nil, "ᇙ", nil, nil, nil], + 12654 => [0, 0, nil, "ᄜ", nil, nil, nil], + 12655 => [0, 0, nil, "ᇝ", nil, nil, nil], + 12656 => [0, 0, nil, "ᇟ", nil, nil, nil], + 12657 => [0, 0, nil, "ᄝ", nil, nil, nil], + 12658 => [0, 0, nil, "ᄞ", nil, nil, nil], + 12659 => [0, 0, nil, "ᄠ", nil, nil, nil], + 12660 => [0, 0, nil, "ᄢ", nil, nil, nil], + 12661 => [0, 0, nil, "ᄣ", nil, nil, nil], + 12662 => [0, 0, nil, "ᄧ", nil, nil, nil], + 12663 => [0, 0, nil, "ᄩ", nil, nil, nil], + 12664 => [0, 0, nil, "ᄫ", nil, nil, nil], + 12665 => [0, 0, nil, "ᄬ", nil, nil, nil], + 12666 => [0, 0, nil, "ᄭ", nil, nil, nil], + 12667 => [0, 0, nil, "ᄮ", nil, nil, nil], + 12668 => [0, 0, nil, "ᄯ", nil, nil, nil], + 12669 => [0, 0, nil, "ᄲ", nil, nil, nil], + 12670 => [0, 0, nil, "ᄶ", nil, nil, nil], + 12671 => [0, 0, nil, "ᅀ", nil, nil, nil], + 12672 => [0, 0, nil, "ᅇ", nil, nil, nil], + 12673 => [0, 0, nil, "ᅌ", nil, nil, nil], + 12674 => [0, 0, nil, "ᇱ", nil, nil, nil], + 12675 => [0, 0, nil, "ᇲ", nil, nil, nil], + 12676 => [0, 0, nil, "ᅗ", nil, nil, nil], + 12677 => [0, 0, nil, "ᅘ", nil, nil, nil], + 12678 => [0, 0, nil, "ᅙ", nil, nil, nil], + 12679 => [0, 0, nil, "ᆄ", nil, nil, nil], + 12680 => [0, 0, nil, "ᆅ", nil, nil, nil], + 12681 => [0, 0, nil, "ᆈ", nil, nil, nil], + 12682 => [0, 0, nil, "ᆑ", nil, nil, nil], + 12683 => [0, 0, nil, "ᆒ", nil, nil, nil], + 12684 => [0, 0, nil, "ᆔ", nil, nil, nil], + 12685 => [0, 0, nil, "ᆞ", nil, nil, nil], + 12686 => [0, 0, nil, "ᆡ", nil, nil, nil], + 12690 => [0, 0, nil, "一", nil, nil, nil], + 12691 => [0, 0, nil, "二", nil, nil, nil], + 12692 => [0, 0, nil, "三", nil, nil, nil], + 12693 => [0, 0, nil, "四", nil, nil, nil], + 12694 => [0, 0, nil, "上", nil, nil, nil], + 12695 => [0, 0, nil, "中", nil, nil, nil], + 12696 => [0, 0, nil, "下", nil, nil, nil], + 12697 => [0, 0, nil, "甲", nil, nil, nil], + 12698 => [0, 0, nil, "乙", nil, nil, nil], + 12699 => [0, 0, nil, "丙", nil, nil, nil], + 12700 => [0, 0, nil, "丁", nil, nil, nil], + 12701 => [0, 0, nil, "天", nil, nil, nil], + 12702 => [0, 0, nil, "地", nil, nil, nil], + 12703 => [0, 0, nil, "人", nil, nil, nil], + 12800 => [0, 0, nil, "(ᄀ)", nil, nil, nil], + 12801 => [0, 0, nil, "(ᄂ)", nil, nil, nil], + 12802 => [0, 0, nil, "(ᄃ)", nil, nil, nil], + 12803 => [0, 0, nil, "(ᄅ)", nil, nil, nil], + 12804 => [0, 0, nil, "(ᄆ)", nil, nil, nil], + 12805 => [0, 0, nil, "(ᄇ)", nil, nil, nil], + 12806 => [0, 0, nil, "(ᄉ)", nil, nil, nil], + 12807 => [0, 0, nil, "(ᄋ)", nil, nil, nil], + 12808 => [0, 0, nil, "(ᄌ)", nil, nil, nil], + 12809 => [0, 0, nil, "(ᄎ)", nil, nil, nil], + 12810 => [0, 0, nil, "(ᄏ)", nil, nil, nil], + 12811 => [0, 0, nil, "(ᄐ)", nil, nil, nil], + 12812 => [0, 0, nil, "(ᄑ)", nil, nil, nil], + 12813 => [0, 0, nil, "(ᄒ)", nil, nil, nil], + 12814 => [0, 0, nil, "(가)", nil, nil, nil], + 12815 => [0, 0, nil, "(나)", nil, nil, nil], + 12816 => [0, 0, nil, "(다)", nil, nil, nil], + 12817 => [0, 0, nil, "(라)", nil, nil, nil], + 12818 => [0, 0, nil, "(마)", nil, nil, nil], + 12819 => [0, 0, nil, "(바)", nil, nil, nil], + 12820 => [0, 0, nil, "(사)", nil, nil, nil], + 12821 => [0, 0, nil, "(아)", nil, nil, nil], + 12822 => [0, 0, nil, "(자)", nil, nil, nil], + 12823 => [0, 0, nil, "(차)", nil, nil, nil], + 12824 => [0, 0, nil, "(카)", nil, nil, nil], + 12825 => [0, 0, nil, "(타)", nil, nil, nil], + 12826 => [0, 0, nil, "(파)", nil, nil, nil], + 12827 => [0, 0, nil, "(하)", nil, nil, nil], + 12828 => [0, 0, nil, "(주)", nil, nil, nil], + 12832 => [0, 0, nil, "(一)", nil, nil, nil], + 12833 => [0, 0, nil, "(二)", nil, nil, nil], + 12834 => [0, 0, nil, "(三)", nil, nil, nil], + 12835 => [0, 0, nil, "(四)", nil, nil, nil], + 12836 => [0, 0, nil, "(五)", nil, nil, nil], + 12837 => [0, 0, nil, "(六)", nil, nil, nil], + 12838 => [0, 0, nil, "(七)", nil, nil, nil], + 12839 => [0, 0, nil, "(八)", nil, nil, nil], + 12840 => [0, 0, nil, "(九)", nil, nil, nil], + 12841 => [0, 0, nil, "(十)", nil, nil, nil], + 12842 => [0, 0, nil, "(月)", nil, nil, nil], + 12843 => [0, 0, nil, "(火)", nil, nil, nil], + 12844 => [0, 0, nil, "(水)", nil, nil, nil], + 12845 => [0, 0, nil, "(木)", nil, nil, nil], + 12846 => [0, 0, nil, "(金)", nil, nil, nil], + 12847 => [0, 0, nil, "(土)", nil, nil, nil], + 12848 => [0, 0, nil, "(日)", nil, nil, nil], + 12849 => [0, 0, nil, "(株)", nil, nil, nil], + 12850 => [0, 0, nil, "(有)", nil, nil, nil], + 12851 => [0, 0, nil, "(社)", nil, nil, nil], + 12852 => [0, 0, nil, "(名)", nil, nil, nil], + 12853 => [0, 0, nil, "(特)", nil, nil, nil], + 12854 => [0, 0, nil, "(財)", nil, nil, nil], + 12855 => [0, 0, nil, "(祝)", nil, nil, nil], + 12856 => [0, 0, nil, "(労)", nil, nil, nil], + 12857 => [0, 0, nil, "(代)", nil, nil, nil], + 12858 => [0, 0, nil, "(呼)", nil, nil, nil], + 12859 => [0, 0, nil, "(学)", nil, nil, nil], + 12860 => [0, 0, nil, "(監)", nil, nil, nil], + 12861 => [0, 0, nil, "(企)", nil, nil, nil], + 12862 => [0, 0, nil, "(資)", nil, nil, nil], + 12863 => [0, 0, nil, "(協)", nil, nil, nil], + 12864 => [0, 0, nil, "(祭)", nil, nil, nil], + 12865 => [0, 0, nil, "(休)", nil, nil, nil], + 12866 => [0, 0, nil, "(自)", nil, nil, nil], + 12867 => [0, 0, nil, "(至)", nil, nil, nil], + 12896 => [0, 0, nil, "ᄀ", nil, nil, nil], + 12897 => [0, 0, nil, "ᄂ", nil, nil, nil], + 12898 => [0, 0, nil, "ᄃ", nil, nil, nil], + 12899 => [0, 0, nil, "ᄅ", nil, nil, nil], + 12900 => [0, 0, nil, "ᄆ", nil, nil, nil], + 12901 => [0, 0, nil, "ᄇ", nil, nil, nil], + 12902 => [0, 0, nil, "ᄉ", nil, nil, nil], + 12903 => [0, 0, nil, "ᄋ", nil, nil, nil], + 12904 => [0, 0, nil, "ᄌ", nil, nil, nil], + 12905 => [0, 0, nil, "ᄎ", nil, nil, nil], + 12906 => [0, 0, nil, "ᄏ", nil, nil, nil], + 12907 => [0, 0, nil, "ᄐ", nil, nil, nil], + 12908 => [0, 0, nil, "ᄑ", nil, nil, nil], + 12909 => [0, 0, nil, "ᄒ", nil, nil, nil], + 12910 => [0, 0, nil, "가", nil, nil, nil], + 12911 => [0, 0, nil, "나", nil, nil, nil], + 12912 => [0, 0, nil, "다", nil, nil, nil], + 12913 => [0, 0, nil, "라", nil, nil, nil], + 12914 => [0, 0, nil, "마", nil, nil, nil], + 12915 => [0, 0, nil, "바", nil, nil, nil], + 12916 => [0, 0, nil, "사", nil, nil, nil], + 12917 => [0, 0, nil, "아", nil, nil, nil], + 12918 => [0, 0, nil, "자", nil, nil, nil], + 12919 => [0, 0, nil, "차", nil, nil, nil], + 12920 => [0, 0, nil, "카", nil, nil, nil], + 12921 => [0, 0, nil, "타", nil, nil, nil], + 12922 => [0, 0, nil, "파", nil, nil, nil], + 12923 => [0, 0, nil, "하", nil, nil, nil], + 12928 => [0, 0, nil, "一", nil, nil, nil], + 12929 => [0, 0, nil, "二", nil, nil, nil], + 12930 => [0, 0, nil, "三", nil, nil, nil], + 12931 => [0, 0, nil, "四", nil, nil, nil], + 12932 => [0, 0, nil, "五", nil, nil, nil], + 12933 => [0, 0, nil, "六", nil, nil, nil], + 12934 => [0, 0, nil, "七", nil, nil, nil], + 12935 => [0, 0, nil, "八", nil, nil, nil], + 12936 => [0, 0, nil, "九", nil, nil, nil], + 12937 => [0, 0, nil, "十", nil, nil, nil], + 12938 => [0, 0, nil, "月", nil, nil, nil], + 12939 => [0, 0, nil, "火", nil, nil, nil], + 12940 => [0, 0, nil, "水", nil, nil, nil], + 12941 => [0, 0, nil, "木", nil, nil, nil], + 12942 => [0, 0, nil, "金", nil, nil, nil], + 12943 => [0, 0, nil, "土", nil, nil, nil], + 12944 => [0, 0, nil, "日", nil, nil, nil], + 12945 => [0, 0, nil, "株", nil, nil, nil], + 12946 => [0, 0, nil, "有", nil, nil, nil], + 12947 => [0, 0, nil, "社", nil, nil, nil], + 12948 => [0, 0, nil, "名", nil, nil, nil], + 12949 => [0, 0, nil, "特", nil, nil, nil], + 12950 => [0, 0, nil, "財", nil, nil, nil], + 12951 => [0, 0, nil, "祝", nil, nil, nil], + 12952 => [0, 0, nil, "労", nil, nil, nil], + 12953 => [0, 0, nil, "秘", nil, nil, nil], + 12954 => [0, 0, nil, "男", nil, nil, nil], + 12955 => [0, 0, nil, "女", nil, nil, nil], + 12956 => [0, 0, nil, "適", nil, nil, nil], + 12957 => [0, 0, nil, "優", nil, nil, nil], + 12958 => [0, 0, nil, "印", nil, nil, nil], + 12959 => [0, 0, nil, "注", nil, nil, nil], + 12960 => [0, 0, nil, "項", nil, nil, nil], + 12961 => [0, 0, nil, "休", nil, nil, nil], + 12962 => [0, 0, nil, "写", nil, nil, nil], + 12963 => [0, 0, nil, "正", nil, nil, nil], + 12964 => [0, 0, nil, "上", nil, nil, nil], + 12965 => [0, 0, nil, "中", nil, nil, nil], + 12966 => [0, 0, nil, "下", nil, nil, nil], + 12967 => [0, 0, nil, "左", nil, nil, nil], + 12968 => [0, 0, nil, "右", nil, nil, nil], + 12969 => [0, 0, nil, "医", nil, nil, nil], + 12970 => [0, 0, nil, "宗", nil, nil, nil], + 12971 => [0, 0, nil, "学", nil, nil, nil], + 12972 => [0, 0, nil, "監", nil, nil, nil], + 12973 => [0, 0, nil, "企", nil, nil, nil], + 12974 => [0, 0, nil, "資", nil, nil, nil], + 12975 => [0, 0, nil, "協", nil, nil, nil], + 12976 => [0, 0, nil, "夜", nil, nil, nil], + 12992 => [0, 0, nil, "1月", nil, nil, nil], + 12993 => [0, 0, nil, "2月", nil, nil, nil], + 12994 => [0, 0, nil, "3月", nil, nil, nil], + 12995 => [0, 0, nil, "4月", nil, nil, nil], + 12996 => [0, 0, nil, "5月", nil, nil, nil], + 12997 => [0, 0, nil, "6月", nil, nil, nil], + 12998 => [0, 0, nil, "7月", nil, nil, nil], + 12999 => [0, 0, nil, "8月", nil, nil, nil], + 13000 => [0, 0, nil, "9月", nil, nil, nil], + 13001 => [0, 0, nil, "10月", nil, nil, nil], + 13002 => [0, 0, nil, "11月", nil, nil, nil], + 13003 => [0, 0, nil, "12月", nil, nil, nil], + 13008 => [0, 0, nil, "ア", nil, nil, nil], + 13009 => [0, 0, nil, "イ", nil, nil, nil], + 13010 => [0, 0, nil, "ウ", nil, nil, nil], + 13011 => [0, 0, nil, "エ", nil, nil, nil], + 13012 => [0, 0, nil, "オ", nil, nil, nil], + 13013 => [0, 0, nil, "カ", nil, nil, nil], + 13014 => [0, 0, nil, "キ", nil, nil, nil], + 13015 => [0, 0, nil, "ク", nil, nil, nil], + 13016 => [0, 0, nil, "ケ", nil, nil, nil], + 13017 => [0, 0, nil, "コ", nil, nil, nil], + 13018 => [0, 0, nil, "サ", nil, nil, nil], + 13019 => [0, 0, nil, "シ", nil, nil, nil], + 13020 => [0, 0, nil, "ス", nil, nil, nil], + 13021 => [0, 0, nil, "セ", nil, nil, nil], + 13022 => [0, 0, nil, "ソ", nil, nil, nil], + 13023 => [0, 0, nil, "タ", nil, nil, nil], + 13024 => [0, 0, nil, "チ", nil, nil, nil], + 13025 => [0, 0, nil, "ツ", nil, nil, nil], + 13026 => [0, 0, nil, "テ", nil, nil, nil], + 13027 => [0, 0, nil, "ト", nil, nil, nil], + 13028 => [0, 0, nil, "ナ", nil, nil, nil], + 13029 => [0, 0, nil, "ニ", nil, nil, nil], + 13030 => [0, 0, nil, "ヌ", nil, nil, nil], + 13031 => [0, 0, nil, "ネ", nil, nil, nil], + 13032 => [0, 0, nil, "ノ", nil, nil, nil], + 13033 => [0, 0, nil, "ハ", nil, nil, nil], + 13034 => [0, 0, nil, "ヒ", nil, nil, nil], + 13035 => [0, 0, nil, "フ", nil, nil, nil], + 13036 => [0, 0, nil, "ヘ", nil, nil, nil], + 13037 => [0, 0, nil, "ホ", nil, nil, nil], + 13038 => [0, 0, nil, "マ", nil, nil, nil], + 13039 => [0, 0, nil, "ミ", nil, nil, nil], + 13040 => [0, 0, nil, "ム", nil, nil, nil], + 13041 => [0, 0, nil, "メ", nil, nil, nil], + 13042 => [0, 0, nil, "モ", nil, nil, nil], + 13043 => [0, 0, nil, "ヤ", nil, nil, nil], + 13044 => [0, 0, nil, "ユ", nil, nil, nil], + 13045 => [0, 0, nil, "ヨ", nil, nil, nil], + 13046 => [0, 0, nil, "ラ", nil, nil, nil], + 13047 => [0, 0, nil, "リ", nil, nil, nil], + 13048 => [0, 0, nil, "ル", nil, nil, nil], + 13049 => [0, 0, nil, "レ", nil, nil, nil], + 13050 => [0, 0, nil, "ロ", nil, nil, nil], + 13051 => [0, 0, nil, "ワ", nil, nil, nil], + 13052 => [0, 0, nil, "ヰ", nil, nil, nil], + 13053 => [0, 0, nil, "ヱ", nil, nil, nil], + 13054 => [0, 0, nil, "ヲ", nil, nil, nil], + 13056 => [0, 0, nil, "アパート", nil, nil, nil], + 13057 => [0, 0, nil, "アルファ", nil, nil, nil], + 13058 => [0, 0, nil, "アンペア", nil, nil, nil], + 13059 => [0, 0, nil, "アール", nil, nil, nil], + 13060 => [0, 0, nil, "イニング", nil, nil, nil], + 13061 => [0, 0, nil, "インチ", nil, nil, nil], + 13062 => [0, 0, nil, "ウォン", nil, nil, nil], + 13063 => [0, 0, nil, "エスクード", nil, nil, nil], + 13064 => [0, 0, nil, "エーカー", nil, nil, nil], + 13065 => [0, 0, nil, "オンス", nil, nil, nil], + 13066 => [0, 0, nil, "オーム", nil, nil, nil], + 13067 => [0, 0, nil, "カイリ", nil, nil, nil], + 13068 => [0, 0, nil, "カラット", nil, nil, nil], + 13069 => [0, 0, nil, "カロリー", nil, nil, nil], + 13070 => [0, 0, nil, "ガロン", nil, nil, nil], + 13071 => [0, 0, nil, "ガンマ", nil, nil, nil], + 13072 => [0, 0, nil, "ギガ", nil, nil, nil], + 13073 => [0, 0, nil, "ギニー", nil, nil, nil], + 13074 => [0, 0, nil, "キュリー", nil, nil, nil], + 13075 => [0, 0, nil, "ギルダー", nil, nil, nil], + 13076 => [0, 0, nil, "キロ", nil, nil, nil], + 13077 => [0, 0, nil, "キログラム", nil, nil, nil], + 13078 => [0, 0, nil, "キロメートル", nil, nil, nil], + 13079 => [0, 0, nil, "キロワット", nil, nil, nil], + 13080 => [0, 0, nil, "グラム", nil, nil, nil], + 13081 => [0, 0, nil, "グラムトン", nil, nil, nil], + 13082 => [0, 0, nil, "クルゼイロ", nil, nil, nil], + 13083 => [0, 0, nil, "クローネ", nil, nil, nil], + 13084 => [0, 0, nil, "ケース", nil, nil, nil], + 13085 => [0, 0, nil, "コルナ", nil, nil, nil], + 13086 => [0, 0, nil, "コーポ", nil, nil, nil], + 13087 => [0, 0, nil, "サイクル", nil, nil, nil], + 13088 => [0, 0, nil, "サンチーム", nil, nil, nil], + 13089 => [0, 0, nil, "シリング", nil, nil, nil], + 13090 => [0, 0, nil, "センチ", nil, nil, nil], + 13091 => [0, 0, nil, "セント", nil, nil, nil], + 13092 => [0, 0, nil, "ダース", nil, nil, nil], + 13093 => [0, 0, nil, "デシ", nil, nil, nil], + 13094 => [0, 0, nil, "ドル", nil, nil, nil], + 13095 => [0, 0, nil, "トン", nil, nil, nil], + 13096 => [0, 0, nil, "ナノ", nil, nil, nil], + 13097 => [0, 0, nil, "ノット", nil, nil, nil], + 13098 => [0, 0, nil, "ハイツ", nil, nil, nil], + 13099 => [0, 0, nil, "パーセント", nil, nil, nil], + 13100 => [0, 0, nil, "パーツ", nil, nil, nil], + 13101 => [0, 0, nil, "バーレル", nil, nil, nil], + 13102 => [0, 0, nil, "ピアストル", nil, nil, nil], + 13103 => [0, 0, nil, "ピクル", nil, nil, nil], + 13104 => [0, 0, nil, "ピコ", nil, nil, nil], + 13105 => [0, 0, nil, "ビル", nil, nil, nil], + 13106 => [0, 0, nil, "ファラッド", nil, nil, nil], + 13107 => [0, 0, nil, "フィート", nil, nil, nil], + 13108 => [0, 0, nil, "ブッシェル", nil, nil, nil], + 13109 => [0, 0, nil, "フラン", nil, nil, nil], + 13110 => [0, 0, nil, "ヘクタール", nil, nil, nil], + 13111 => [0, 0, nil, "ペソ", nil, nil, nil], + 13112 => [0, 0, nil, "ペニヒ", nil, nil, nil], + 13113 => [0, 0, nil, "ヘルツ", nil, nil, nil], + 13114 => [0, 0, nil, "ペンス", nil, nil, nil], + 13115 => [0, 0, nil, "ページ", nil, nil, nil], + 13116 => [0, 0, nil, "ベータ", nil, nil, nil], + 13117 => [0, 0, nil, "ポイント", nil, nil, nil], + 13118 => [0, 0, nil, "ボルト", nil, nil, nil], + 13119 => [0, 0, nil, "ホン", nil, nil, nil], + 13120 => [0, 0, nil, "ポンド", nil, nil, nil], + 13121 => [0, 0, nil, "ホール", nil, nil, nil], + 13122 => [0, 0, nil, "ホーン", nil, nil, nil], + 13123 => [0, 0, nil, "マイクロ", nil, nil, nil], + 13124 => [0, 0, nil, "マイル", nil, nil, nil], + 13125 => [0, 0, nil, "マッハ", nil, nil, nil], + 13126 => [0, 0, nil, "マルク", nil, nil, nil], + 13127 => [0, 0, nil, "マンション", nil, nil, nil], + 13128 => [0, 0, nil, "ミクロン", nil, nil, nil], + 13129 => [0, 0, nil, "ミリ", nil, nil, nil], + 13130 => [0, 0, nil, "ミリバール", nil, nil, nil], + 13131 => [0, 0, nil, "メガ", nil, nil, nil], + 13132 => [0, 0, nil, "メガトン", nil, nil, nil], + 13133 => [0, 0, nil, "メートル", nil, nil, nil], + 13134 => [0, 0, nil, "ヤード", nil, nil, nil], + 13135 => [0, 0, nil, "ヤール", nil, nil, nil], + 13136 => [0, 0, nil, "ユアン", nil, nil, nil], + 13137 => [0, 0, nil, "リットル", nil, nil, nil], + 13138 => [0, 0, nil, "リラ", nil, nil, nil], + 13139 => [0, 0, nil, "ルピー", nil, nil, nil], + 13140 => [0, 0, nil, "ルーブル", nil, nil, nil], + 13141 => [0, 0, nil, "レム", nil, nil, nil], + 13142 => [0, 0, nil, "レントゲン", nil, nil, nil], + 13143 => [0, 0, nil, "ワット", nil, nil, nil], + 13144 => [0, 0, nil, "0点", nil, nil, nil], + 13145 => [0, 0, nil, "1点", nil, nil, nil], + 13146 => [0, 0, nil, "2点", nil, nil, nil], + 13147 => [0, 0, nil, "3点", nil, nil, nil], + 13148 => [0, 0, nil, "4点", nil, nil, nil], + 13149 => [0, 0, nil, "5点", nil, nil, nil], + 13150 => [0, 0, nil, "6点", nil, nil, nil], + 13151 => [0, 0, nil, "7点", nil, nil, nil], + 13152 => [0, 0, nil, "8点", nil, nil, nil], + 13153 => [0, 0, nil, "9点", nil, nil, nil], + 13154 => [0, 0, nil, "10点", nil, nil, nil], + 13155 => [0, 0, nil, "11点", nil, nil, nil], + 13156 => [0, 0, nil, "12点", nil, nil, nil], + 13157 => [0, 0, nil, "13点", nil, nil, nil], + 13158 => [0, 0, nil, "14点", nil, nil, nil], + 13159 => [0, 0, nil, "15点", nil, nil, nil], + 13160 => [0, 0, nil, "16点", nil, nil, nil], + 13161 => [0, 0, nil, "17点", nil, nil, nil], + 13162 => [0, 0, nil, "18点", nil, nil, nil], + 13163 => [0, 0, nil, "19点", nil, nil, nil], + 13164 => [0, 0, nil, "20点", nil, nil, nil], + 13165 => [0, 0, nil, "21点", nil, nil, nil], + 13166 => [0, 0, nil, "22点", nil, nil, nil], + 13167 => [0, 0, nil, "23点", nil, nil, nil], + 13168 => [0, 0, nil, "24点", nil, nil, nil], + 13169 => [0, 0, nil, "hPa", nil, nil, nil], + 13170 => [0, 0, nil, "da", nil, nil, nil], + 13171 => [0, 0, nil, "AU", nil, nil, nil], + 13172 => [0, 0, nil, "bar", nil, nil, nil], + 13173 => [0, 0, nil, "oV", nil, nil, nil], + 13174 => [0, 0, nil, "pc", nil, nil, nil], + 13179 => [0, 0, nil, "平成", nil, nil, nil], + 13180 => [0, 0, nil, "昭和", nil, nil, nil], + 13181 => [0, 0, nil, "大正", nil, nil, nil], + 13182 => [0, 0, nil, "明治", nil, nil, nil], + 13183 => [0, 0, nil, "株式会社", nil, nil, nil], + 13184 => [0, 0, nil, "pA", nil, nil, nil], + 13185 => [0, 0, nil, "nA", nil, nil, nil], + 13186 => [0, 0, nil, "μA", nil, nil, nil], + 13187 => [0, 0, nil, "mA", nil, nil, nil], + 13188 => [0, 0, nil, "kA", nil, nil, nil], + 13189 => [0, 0, nil, "KB", nil, nil, nil], + 13190 => [0, 0, nil, "MB", nil, nil, nil], + 13191 => [0, 0, nil, "GB", nil, nil, nil], + 13192 => [0, 0, nil, "cal", nil, nil, nil], + 13193 => [0, 0, nil, "kcal", nil, nil, nil], + 13194 => [0, 0, nil, "pF", nil, nil, nil], + 13195 => [0, 0, nil, "nF", nil, nil, nil], + 13196 => [0, 0, nil, "μF", nil, nil, nil], + 13197 => [0, 0, nil, "μg", nil, nil, nil], + 13198 => [0, 0, nil, "mg", nil, nil, nil], + 13199 => [0, 0, nil, "kg", nil, nil, nil], + 13200 => [0, 0, nil, "Hz", nil, nil, nil], + 13201 => [0, 0, nil, "kHz", nil, nil, nil], + 13202 => [0, 0, nil, "MHz", nil, nil, nil], + 13203 => [0, 0, nil, "GHz", nil, nil, nil], + 13204 => [0, 0, nil, "THz", nil, nil, nil], + 13205 => [0, 0, nil, "μℓ", nil, nil, nil], + 13206 => [0, 0, nil, "mℓ", nil, nil, nil], + 13207 => [0, 0, nil, "dℓ", nil, nil, nil], + 13208 => [0, 0, nil, "kℓ", nil, nil, nil], + 13209 => [0, 0, nil, "fm", nil, nil, nil], + 13210 => [0, 0, nil, "nm", nil, nil, nil], + 13211 => [0, 0, nil, "μm", nil, nil, nil], + 13212 => [0, 0, nil, "mm", nil, nil, nil], + 13213 => [0, 0, nil, "cm", nil, nil, nil], + 13214 => [0, 0, nil, "km", nil, nil, nil], + 13215 => [0, 0, nil, "mm²", nil, nil, nil], + 13216 => [0, 0, nil, "cm²", nil, nil, nil], + 13217 => [0, 0, nil, "m²", nil, nil, nil], + 13218 => [0, 0, nil, "km²", nil, nil, nil], + 13219 => [0, 0, nil, "mm³", nil, nil, nil], + 13220 => [0, 0, nil, "cm³", nil, nil, nil], + 13221 => [0, 0, nil, "m³", nil, nil, nil], + 13222 => [0, 0, nil, "km³", nil, nil, nil], + 13223 => [0, 0, nil, "m∕s", nil, nil, nil], + 13224 => [0, 0, nil, "m∕s²", nil, nil, nil], + 13225 => [0, 0, nil, "Pa", nil, nil, nil], + 13226 => [0, 0, nil, "kPa", nil, nil, nil], + 13227 => [0, 0, nil, "MPa", nil, nil, nil], + 13228 => [0, 0, nil, "GPa", nil, nil, nil], + 13229 => [0, 0, nil, "rad", nil, nil, nil], + 13230 => [0, 0, nil, "rad∕s", nil, nil, nil], + 13231 => [0, 0, nil, "rad∕s²", nil, nil, nil], + 13232 => [0, 0, nil, "ps", nil, nil, nil], + 13233 => [0, 0, nil, "ns", nil, nil, nil], + 13234 => [0, 0, nil, "μs", nil, nil, nil], + 13235 => [0, 0, nil, "ms", nil, nil, nil], + 13236 => [0, 0, nil, "pV", nil, nil, nil], + 13237 => [0, 0, nil, "nV", nil, nil, nil], + 13238 => [0, 0, nil, "μV", nil, nil, nil], + 13239 => [0, 0, nil, "mV", nil, nil, nil], + 13240 => [0, 0, nil, "kV", nil, nil, nil], + 13241 => [0, 0, nil, "MV", nil, nil, nil], + 13242 => [0, 0, nil, "pW", nil, nil, nil], + 13243 => [0, 0, nil, "nW", nil, nil, nil], + 13244 => [0, 0, nil, "μW", nil, nil, nil], + 13245 => [0, 0, nil, "mW", nil, nil, nil], + 13246 => [0, 0, nil, "kW", nil, nil, nil], + 13247 => [0, 0, nil, "MW", nil, nil, nil], + 13248 => [0, 0, nil, "kΩ", nil, nil, nil], + 13249 => [0, 0, nil, "MΩ", nil, nil, nil], + 13250 => [0, 0, nil, "a.m.", nil, nil, nil], + 13251 => [0, 0, nil, "Bq", nil, nil, nil], + 13252 => [0, 0, nil, "cc", nil, nil, nil], + 13253 => [0, 0, nil, "cd", nil, nil, nil], + 13254 => [0, 0, nil, "C∕kg", nil, nil, nil], + 13255 => [0, 0, nil, "Co.", nil, nil, nil], + 13256 => [0, 0, nil, "dB", nil, nil, nil], + 13257 => [0, 0, nil, "Gy", nil, nil, nil], + 13258 => [0, 0, nil, "ha", nil, nil, nil], + 13259 => [0, 0, nil, "HP", nil, nil, nil], + 13260 => [0, 0, nil, "in", nil, nil, nil], + 13261 => [0, 0, nil, "KK", nil, nil, nil], + 13262 => [0, 0, nil, "KM", nil, nil, nil], + 13263 => [0, 0, nil, "kt", nil, nil, nil], + 13264 => [0, 0, nil, "lm", nil, nil, nil], + 13265 => [0, 0, nil, "ln", nil, nil, nil], + 13266 => [0, 0, nil, "log", nil, nil, nil], + 13267 => [0, 0, nil, "lx", nil, nil, nil], + 13268 => [0, 0, nil, "mb", nil, nil, nil], + 13269 => [0, 0, nil, "mil", nil, nil, nil], + 13270 => [0, 0, nil, "mol", nil, nil, nil], + 13271 => [0, 0, nil, "PH", nil, nil, nil], + 13272 => [0, 0, nil, "p.m.", nil, nil, nil], + 13273 => [0, 0, nil, "PPM", nil, nil, nil], + 13274 => [0, 0, nil, "PR", nil, nil, nil], + 13275 => [0, 0, nil, "sr", nil, nil, nil], + 13276 => [0, 0, nil, "Sv", nil, nil, nil], + 13277 => [0, 0, nil, "Wb", nil, nil, nil], + 13280 => [0, 0, nil, "1日", nil, nil, nil], + 13281 => [0, 0, nil, "2日", nil, nil, nil], + 13282 => [0, 0, nil, "3日", nil, nil, nil], + 13283 => [0, 0, nil, "4日", nil, nil, nil], + 13284 => [0, 0, nil, "5日", nil, nil, nil], + 13285 => [0, 0, nil, "6日", nil, nil, nil], + 13286 => [0, 0, nil, "7日", nil, nil, nil], + 13287 => [0, 0, nil, "8日", nil, nil, nil], + 13288 => [0, 0, nil, "9日", nil, nil, nil], + 13289 => [0, 0, nil, "10日", nil, nil, nil], + 13290 => [0, 0, nil, "11日", nil, nil, nil], + 13291 => [0, 0, nil, "12日", nil, nil, nil], + 13292 => [0, 0, nil, "13日", nil, nil, nil], + 13293 => [0, 0, nil, "14日", nil, nil, nil], + 13294 => [0, 0, nil, "15日", nil, nil, nil], + 13295 => [0, 0, nil, "16日", nil, nil, nil], + 13296 => [0, 0, nil, "17日", nil, nil, nil], + 13297 => [0, 0, nil, "18日", nil, nil, nil], + 13298 => [0, 0, nil, "19日", nil, nil, nil], + 13299 => [0, 0, nil, "20日", nil, nil, nil], + 13300 => [0, 0, nil, "21日", nil, nil, nil], + 13301 => [0, 0, nil, "22日", nil, nil, nil], + 13302 => [0, 0, nil, "23日", nil, nil, nil], + 13303 => [0, 0, nil, "24日", nil, nil, nil], + 13304 => [0, 0, nil, "25日", nil, nil, nil], + 13305 => [0, 0, nil, "26日", nil, nil, nil], + 13306 => [0, 0, nil, "27日", nil, nil, nil], + 13307 => [0, 0, nil, "28日", nil, nil, nil], + 13308 => [0, 0, nil, "29日", nil, nil, nil], + 13309 => [0, 0, nil, "30日", nil, nil, nil], + 13310 => [0, 0, nil, "31日", nil, nil, nil], + 63744 => [0, 2, "豈", "豈", nil, nil, nil], + 63745 => [0, 2, "更", "更", nil, nil, nil], + 63746 => [0, 2, "車", "車", nil, nil, nil], + 63747 => [0, 2, "賈", "賈", nil, nil, nil], + 63748 => [0, 2, "滑", "滑", nil, nil, nil], + 63749 => [0, 2, "串", "串", nil, nil, nil], + 63750 => [0, 2, "句", "句", nil, nil, nil], + 63751 => [0, 2, "龜", "龜", nil, nil, nil], + 63752 => [0, 2, "龜", "龜", nil, nil, nil], + 63753 => [0, 2, "契", "契", nil, nil, nil], + 63754 => [0, 2, "金", "金", nil, nil, nil], + 63755 => [0, 2, "喇", "喇", nil, nil, nil], + 63756 => [0, 2, "奈", "奈", nil, nil, nil], + 63757 => [0, 2, "懶", "懶", nil, nil, nil], + 63758 => [0, 2, "癩", "癩", nil, nil, nil], + 63759 => [0, 2, "羅", "羅", nil, nil, nil], + 63760 => [0, 2, "蘿", "蘿", nil, nil, nil], + 63761 => [0, 2, "螺", "螺", nil, nil, nil], + 63762 => [0, 2, "裸", "裸", nil, nil, nil], + 63763 => [0, 2, "邏", "邏", nil, nil, nil], + 63764 => [0, 2, "樂", "樂", nil, nil, nil], + 63765 => [0, 2, "洛", "洛", nil, nil, nil], + 63766 => [0, 2, "烙", "烙", nil, nil, nil], + 63767 => [0, 2, "珞", "珞", nil, nil, nil], + 63768 => [0, 2, "落", "落", nil, nil, nil], + 63769 => [0, 2, "酪", "酪", nil, nil, nil], + 63770 => [0, 2, "駱", "駱", nil, nil, nil], + 63771 => [0, 2, "亂", "亂", nil, nil, nil], + 63772 => [0, 2, "卵", "卵", nil, nil, nil], + 63773 => [0, 2, "欄", "欄", nil, nil, nil], + 63774 => [0, 2, "爛", "爛", nil, nil, nil], + 63775 => [0, 2, "蘭", "蘭", nil, nil, nil], + 63776 => [0, 2, "鸞", "鸞", nil, nil, nil], + 63777 => [0, 2, "嵐", "嵐", nil, nil, nil], + 63778 => [0, 2, "濫", "濫", nil, nil, nil], + 63779 => [0, 2, "藍", "藍", nil, nil, nil], + 63780 => [0, 2, "襤", "襤", nil, nil, nil], + 63781 => [0, 2, "拉", "拉", nil, nil, nil], + 63782 => [0, 2, "臘", "臘", nil, nil, nil], + 63783 => [0, 2, "蠟", "蠟", nil, nil, nil], + 63784 => [0, 2, "廊", "廊", nil, nil, nil], + 63785 => [0, 2, "朗", "朗", nil, nil, nil], + 63786 => [0, 2, "浪", "浪", nil, nil, nil], + 63787 => [0, 2, "狼", "狼", nil, nil, nil], + 63788 => [0, 2, "郎", "郎", nil, nil, nil], + 63789 => [0, 2, "來", "來", nil, nil, nil], + 63790 => [0, 2, "冷", "冷", nil, nil, nil], + 63791 => [0, 2, "勞", "勞", nil, nil, nil], + 63792 => [0, 2, "擄", "擄", nil, nil, nil], + 63793 => [0, 2, "櫓", "櫓", nil, nil, nil], + 63794 => [0, 2, "爐", "爐", nil, nil, nil], + 63795 => [0, 2, "盧", "盧", nil, nil, nil], + 63796 => [0, 2, "老", "老", nil, nil, nil], + 63797 => [0, 2, "蘆", "蘆", nil, nil, nil], + 63798 => [0, 2, "虜", "虜", nil, nil, nil], + 63799 => [0, 2, "路", "路", nil, nil, nil], + 63800 => [0, 2, "露", "露", nil, nil, nil], + 63801 => [0, 2, "魯", "魯", nil, nil, nil], + 63802 => [0, 2, "鷺", "鷺", nil, nil, nil], + 63803 => [0, 2, "碌", "碌", nil, nil, nil], + 63804 => [0, 2, "祿", "祿", nil, nil, nil], + 63805 => [0, 2, "綠", "綠", nil, nil, nil], + 63806 => [0, 2, "菉", "菉", nil, nil, nil], + 63807 => [0, 2, "錄", "錄", nil, nil, nil], + 63808 => [0, 2, "鹿", "鹿", nil, nil, nil], + 63809 => [0, 2, "論", "論", nil, nil, nil], + 63810 => [0, 2, "壟", "壟", nil, nil, nil], + 63811 => [0, 2, "弄", "弄", nil, nil, nil], + 63812 => [0, 2, "籠", "籠", nil, nil, nil], + 63813 => [0, 2, "聾", "聾", nil, nil, nil], + 63814 => [0, 2, "牢", "牢", nil, nil, nil], + 63815 => [0, 2, "磊", "磊", nil, nil, nil], + 63816 => [0, 2, "賂", "賂", nil, nil, nil], + 63817 => [0, 2, "雷", "雷", nil, nil, nil], + 63818 => [0, 2, "壘", "壘", nil, nil, nil], + 63819 => [0, 2, "屢", "屢", nil, nil, nil], + 63820 => [0, 2, "樓", "樓", nil, nil, nil], + 63821 => [0, 2, "淚", "淚", nil, nil, nil], + 63822 => [0, 2, "漏", "漏", nil, nil, nil], + 63823 => [0, 2, "累", "累", nil, nil, nil], + 63824 => [0, 2, "縷", "縷", nil, nil, nil], + 63825 => [0, 2, "電", "電", nil, nil, nil], + 63826 => [0, 2, "勒", "勒", nil, nil, nil], + 63827 => [0, 2, "肋", "肋", nil, nil, nil], + 63828 => [0, 2, "凜", "凜", nil, nil, nil], + 63829 => [0, 2, "凌", "凌", nil, nil, nil], + 63830 => [0, 2, "稜", "稜", nil, nil, nil], + 63831 => [0, 2, "綾", "綾", nil, nil, nil], + 63832 => [0, 2, "菱", "菱", nil, nil, nil], + 63833 => [0, 2, "陵", "陵", nil, nil, nil], + 63834 => [0, 2, "讀", "讀", nil, nil, nil], + 63835 => [0, 2, "拏", "拏", nil, nil, nil], + 63836 => [0, 2, "樂", "樂", nil, nil, nil], + 63837 => [0, 2, "諾", "諾", nil, nil, nil], + 63838 => [0, 2, "丹", "丹", nil, nil, nil], + 63839 => [0, 2, "寧", "寧", nil, nil, nil], + 63840 => [0, 2, "怒", "怒", nil, nil, nil], + 63841 => [0, 2, "率", "率", nil, nil, nil], + 63842 => [0, 2, "異", "異", nil, nil, nil], + 63843 => [0, 2, "北", "北", nil, nil, nil], + 63844 => [0, 2, "磻", "磻", nil, nil, nil], + 63845 => [0, 2, "便", "便", nil, nil, nil], + 63846 => [0, 2, "復", "復", nil, nil, nil], + 63847 => [0, 2, "不", "不", nil, nil, nil], + 63848 => [0, 2, "泌", "泌", nil, nil, nil], + 63849 => [0, 2, "數", "數", nil, nil, nil], + 63850 => [0, 2, "索", "索", nil, nil, nil], + 63851 => [0, 2, "參", "參", nil, nil, nil], + 63852 => [0, 2, "塞", "塞", nil, nil, nil], + 63853 => [0, 2, "省", "省", nil, nil, nil], + 63854 => [0, 2, "葉", "葉", nil, nil, nil], + 63855 => [0, 2, "說", "說", nil, nil, nil], + 63856 => [0, 2, "殺", "殺", nil, nil, nil], + 63857 => [0, 2, "辰", "辰", nil, nil, nil], + 63858 => [0, 2, "沈", "沈", nil, nil, nil], + 63859 => [0, 2, "拾", "拾", nil, nil, nil], + 63860 => [0, 2, "若", "若", nil, nil, nil], + 63861 => [0, 2, "掠", "掠", nil, nil, nil], + 63862 => [0, 2, "略", "略", nil, nil, nil], + 63863 => [0, 2, "亮", "亮", nil, nil, nil], + 63864 => [0, 2, "兩", "兩", nil, nil, nil], + 63865 => [0, 2, "凉", "凉", nil, nil, nil], + 63866 => [0, 2, "梁", "梁", nil, nil, nil], + 63867 => [0, 2, "糧", "糧", nil, nil, nil], + 63868 => [0, 2, "良", "良", nil, nil, nil], + 63869 => [0, 2, "諒", "諒", nil, nil, nil], + 63870 => [0, 2, "量", "量", nil, nil, nil], + 63871 => [0, 2, "勵", "勵", nil, nil, nil], + 63872 => [0, 2, "呂", "呂", nil, nil, nil], + 63873 => [0, 2, "女", "女", nil, nil, nil], + 63874 => [0, 2, "廬", "廬", nil, nil, nil], + 63875 => [0, 2, "旅", "旅", nil, nil, nil], + 63876 => [0, 2, "濾", "濾", nil, nil, nil], + 63877 => [0, 2, "礪", "礪", nil, nil, nil], + 63878 => [0, 2, "閭", "閭", nil, nil, nil], + 63879 => [0, 2, "驪", "驪", nil, nil, nil], + 63880 => [0, 2, "麗", "麗", nil, nil, nil], + 63881 => [0, 2, "黎", "黎", nil, nil, nil], + 63882 => [0, 2, "力", "力", nil, nil, nil], + 63883 => [0, 2, "曆", "曆", nil, nil, nil], + 63884 => [0, 2, "歷", "歷", nil, nil, nil], + 63885 => [0, 2, "轢", "轢", nil, nil, nil], + 63886 => [0, 2, "年", "年", nil, nil, nil], + 63887 => [0, 2, "憐", "憐", nil, nil, nil], + 63888 => [0, 2, "戀", "戀", nil, nil, nil], + 63889 => [0, 2, "撚", "撚", nil, nil, nil], + 63890 => [0, 2, "漣", "漣", nil, nil, nil], + 63891 => [0, 2, "煉", "煉", nil, nil, nil], + 63892 => [0, 2, "璉", "璉", nil, nil, nil], + 63893 => [0, 2, "秊", "秊", nil, nil, nil], + 63894 => [0, 2, "練", "練", nil, nil, nil], + 63895 => [0, 2, "聯", "聯", nil, nil, nil], + 63896 => [0, 2, "輦", "輦", nil, nil, nil], + 63897 => [0, 2, "蓮", "蓮", nil, nil, nil], + 63898 => [0, 2, "連", "連", nil, nil, nil], + 63899 => [0, 2, "鍊", "鍊", nil, nil, nil], + 63900 => [0, 2, "列", "列", nil, nil, nil], + 63901 => [0, 2, "劣", "劣", nil, nil, nil], + 63902 => [0, 2, "咽", "咽", nil, nil, nil], + 63903 => [0, 2, "烈", "烈", nil, nil, nil], + 63904 => [0, 2, "裂", "裂", nil, nil, nil], + 63905 => [0, 2, "說", "說", nil, nil, nil], + 63906 => [0, 2, "廉", "廉", nil, nil, nil], + 63907 => [0, 2, "念", "念", nil, nil, nil], + 63908 => [0, 2, "捻", "捻", nil, nil, nil], + 63909 => [0, 2, "殮", "殮", nil, nil, nil], + 63910 => [0, 2, "簾", "簾", nil, nil, nil], + 63911 => [0, 2, "獵", "獵", nil, nil, nil], + 63912 => [0, 2, "令", "令", nil, nil, nil], + 63913 => [0, 2, "囹", "囹", nil, nil, nil], + 63914 => [0, 2, "寧", "寧", nil, nil, nil], + 63915 => [0, 2, "嶺", "嶺", nil, nil, nil], + 63916 => [0, 2, "怜", "怜", nil, nil, nil], + 63917 => [0, 2, "玲", "玲", nil, nil, nil], + 63918 => [0, 2, "瑩", "瑩", nil, nil, nil], + 63919 => [0, 2, "羚", "羚", nil, nil, nil], + 63920 => [0, 2, "聆", "聆", nil, nil, nil], + 63921 => [0, 2, "鈴", "鈴", nil, nil, nil], + 63922 => [0, 2, "零", "零", nil, nil, nil], + 63923 => [0, 2, "靈", "靈", nil, nil, nil], + 63924 => [0, 2, "領", "領", nil, nil, nil], + 63925 => [0, 2, "例", "例", nil, nil, nil], + 63926 => [0, 2, "禮", "禮", nil, nil, nil], + 63927 => [0, 2, "醴", "醴", nil, nil, nil], + 63928 => [0, 2, "隸", "隸", nil, nil, nil], + 63929 => [0, 2, "惡", "惡", nil, nil, nil], + 63930 => [0, 2, "了", "了", nil, nil, nil], + 63931 => [0, 2, "僚", "僚", nil, nil, nil], + 63932 => [0, 2, "寮", "寮", nil, nil, nil], + 63933 => [0, 2, "尿", "尿", nil, nil, nil], + 63934 => [0, 2, "料", "料", nil, nil, nil], + 63935 => [0, 2, "樂", "樂", nil, nil, nil], + 63936 => [0, 2, "燎", "燎", nil, nil, nil], + 63937 => [0, 2, "療", "療", nil, nil, nil], + 63938 => [0, 2, "蓼", "蓼", nil, nil, nil], + 63939 => [0, 2, "遼", "遼", nil, nil, nil], + 63940 => [0, 2, "龍", "龍", nil, nil, nil], + 63941 => [0, 2, "暈", "暈", nil, nil, nil], + 63942 => [0, 2, "阮", "阮", nil, nil, nil], + 63943 => [0, 2, "劉", "劉", nil, nil, nil], + 63944 => [0, 2, "杻", "杻", nil, nil, nil], + 63945 => [0, 2, "柳", "柳", nil, nil, nil], + 63946 => [0, 2, "流", "流", nil, nil, nil], + 63947 => [0, 2, "溜", "溜", nil, nil, nil], + 63948 => [0, 2, "琉", "琉", nil, nil, nil], + 63949 => [0, 2, "留", "留", nil, nil, nil], + 63950 => [0, 2, "硫", "硫", nil, nil, nil], + 63951 => [0, 2, "紐", "紐", nil, nil, nil], + 63952 => [0, 2, "類", "類", nil, nil, nil], + 63953 => [0, 2, "六", "六", nil, nil, nil], + 63954 => [0, 2, "戮", "戮", nil, nil, nil], + 63955 => [0, 2, "陸", "陸", nil, nil, nil], + 63956 => [0, 2, "倫", "倫", nil, nil, nil], + 63957 => [0, 2, "崙", "崙", nil, nil, nil], + 63958 => [0, 2, "淪", "淪", nil, nil, nil], + 63959 => [0, 2, "輪", "輪", nil, nil, nil], + 63960 => [0, 2, "律", "律", nil, nil, nil], + 63961 => [0, 2, "慄", "慄", nil, nil, nil], + 63962 => [0, 2, "栗", "栗", nil, nil, nil], + 63963 => [0, 2, "率", "率", nil, nil, nil], + 63964 => [0, 2, "隆", "隆", nil, nil, nil], + 63965 => [0, 2, "利", "利", nil, nil, nil], + 63966 => [0, 2, "吏", "吏", nil, nil, nil], + 63967 => [0, 2, "履", "履", nil, nil, nil], + 63968 => [0, 2, "易", "易", nil, nil, nil], + 63969 => [0, 2, "李", "李", nil, nil, nil], + 63970 => [0, 2, "梨", "梨", nil, nil, nil], + 63971 => [0, 2, "泥", "泥", nil, nil, nil], + 63972 => [0, 2, "理", "理", nil, nil, nil], + 63973 => [0, 2, "痢", "痢", nil, nil, nil], + 63974 => [0, 2, "罹", "罹", nil, nil, nil], + 63975 => [0, 2, "裏", "裏", nil, nil, nil], + 63976 => [0, 2, "裡", "裡", nil, nil, nil], + 63977 => [0, 2, "里", "里", nil, nil, nil], + 63978 => [0, 2, "離", "離", nil, nil, nil], + 63979 => [0, 2, "匿", "匿", nil, nil, nil], + 63980 => [0, 2, "溺", "溺", nil, nil, nil], + 63981 => [0, 2, "吝", "吝", nil, nil, nil], + 63982 => [0, 2, "燐", "燐", nil, nil, nil], + 63983 => [0, 2, "璘", "璘", nil, nil, nil], + 63984 => [0, 2, "藺", "藺", nil, nil, nil], + 63985 => [0, 2, "隣", "隣", nil, nil, nil], + 63986 => [0, 2, "鱗", "鱗", nil, nil, nil], + 63987 => [0, 2, "麟", "麟", nil, nil, nil], + 63988 => [0, 2, "林", "林", nil, nil, nil], + 63989 => [0, 2, "淋", "淋", nil, nil, nil], + 63990 => [0, 2, "臨", "臨", nil, nil, nil], + 63991 => [0, 2, "立", "立", nil, nil, nil], + 63992 => [0, 2, "笠", "笠", nil, nil, nil], + 63993 => [0, 2, "粒", "粒", nil, nil, nil], + 63994 => [0, 2, "狀", "狀", nil, nil, nil], + 63995 => [0, 2, "炙", "炙", nil, nil, nil], + 63996 => [0, 2, "識", "識", nil, nil, nil], + 63997 => [0, 2, "什", "什", nil, nil, nil], + 63998 => [0, 2, "茶", "茶", nil, nil, nil], + 63999 => [0, 2, "刺", "刺", nil, nil, nil], + 64000 => [0, 2, "切", "切", nil, nil, nil], + 64001 => [0, 2, "度", "度", nil, nil, nil], + 64002 => [0, 2, "拓", "拓", nil, nil, nil], + 64003 => [0, 2, "糖", "糖", nil, nil, nil], + 64004 => [0, 2, "宅", "宅", nil, nil, nil], + 64005 => [0, 2, "洞", "洞", nil, nil, nil], + 64006 => [0, 2, "暴", "暴", nil, nil, nil], + 64007 => [0, 2, "輻", "輻", nil, nil, nil], + 64008 => [0, 2, "行", "行", nil, nil, nil], + 64009 => [0, 2, "降", "降", nil, nil, nil], + 64010 => [0, 2, "見", "見", nil, nil, nil], + 64011 => [0, 2, "廓", "廓", nil, nil, nil], + 64012 => [0, 2, "兀", "兀", nil, nil, nil], + 64013 => [0, 2, "嗀", "嗀", nil, nil, nil], + 64016 => [0, 2, "塚", "塚", nil, nil, nil], + 64018 => [0, 2, "晴", "晴", nil, nil, nil], + 64021 => [0, 2, "凞", "凞", nil, nil, nil], + 64022 => [0, 2, "猪", "猪", nil, nil, nil], + 64023 => [0, 2, "益", "益", nil, nil, nil], + 64024 => [0, 2, "礼", "礼", nil, nil, nil], + 64025 => [0, 2, "神", "神", nil, nil, nil], + 64026 => [0, 2, "祥", "祥", nil, nil, nil], + 64027 => [0, 2, "福", "福", nil, nil, nil], + 64028 => [0, 2, "靖", "靖", nil, nil, nil], + 64029 => [0, 2, "精", "精", nil, nil, nil], + 64030 => [0, 2, "羽", "羽", nil, nil, nil], + 64032 => [0, 2, "蘒", "蘒", nil, nil, nil], + 64034 => [0, 2, "諸", "諸", nil, nil, nil], + 64037 => [0, 2, "逸", "逸", nil, nil, nil], + 64038 => [0, 2, "都", "都", nil, nil, nil], + 64042 => [0, 2, "飯", "飯", nil, nil, nil], + 64043 => [0, 2, "飼", "飼", nil, nil, nil], + 64044 => [0, 2, "館", "館", nil, nil, nil], + 64045 => [0, 2, "鶴", "鶴", nil, nil, nil], + 64256 => [0, 0, nil, "ff", nil, nil, nil], + 64257 => [0, 0, nil, "fi", nil, nil, nil], + 64258 => [0, 0, nil, "fl", nil, nil, nil], + 64259 => [0, 0, nil, "ffi", nil, nil, nil], + 64260 => [0, 0, nil, "ffl", nil, nil, nil], + 64261 => [0, 0, nil, "ſt", nil, nil, nil], + 64262 => [0, 0, nil, "st", nil, nil, nil], + 64275 => [0, 0, nil, "մն", nil, nil, nil], + 64276 => [0, 0, nil, "մե", nil, nil, nil], + 64277 => [0, 0, nil, "մի", nil, nil, nil], + 64278 => [0, 0, nil, "վն", nil, nil, nil], + 64279 => [0, 0, nil, "մխ", nil, nil, nil], + 64285 => [0, 0, "יִ", "יִ", nil, nil, nil], + 64286 => [26, 0, nil, nil, nil, nil, nil], + 64287 => [0, 1, "ײַ", "ײַ", nil, nil, nil], + 64288 => [0, 0, nil, "ע", nil, nil, nil], + 64289 => [0, 0, nil, "א", nil, nil, nil], + 64290 => [0, 0, nil, "ד", nil, nil, nil], + 64291 => [0, 0, nil, "ה", nil, nil, nil], + 64292 => [0, 0, nil, "כ", nil, nil, nil], + 64293 => [0, 0, nil, "ל", nil, nil, nil], + 64294 => [0, 0, nil, "ם", nil, nil, nil], + 64295 => [0, 0, nil, "ר", nil, nil, nil], + 64296 => [0, 0, nil, "ת", nil, nil, nil], + 64297 => [0, 0, nil, "+", nil, nil, nil], + 64298 => [0, 1, "שׁ", "שׁ", nil, nil, nil], + 64299 => [0, 1, "שׂ", "שׂ", nil, nil, nil], + 64300 => [0, 1, "שּׁ", "שּׁ", nil, nil, nil], + 64301 => [0, 1, "שּׂ", "שּׂ", nil, nil, nil], + 64302 => [0, 1, "אַ", "אַ", nil, nil, nil], + 64303 => [0, 1, "אָ", "אָ", nil, nil, nil], + 64304 => [0, 1, "אּ", "אּ", nil, nil, nil], + 64305 => [0, 1, "בּ", "בּ", nil, nil, nil], + 64306 => [0, 1, "גּ", "גּ", nil, nil, nil], + 64307 => [0, 1, "דּ", "דּ", nil, nil, nil], + 64308 => [0, 1, "הּ", "הּ", nil, nil, nil], + 64309 => [0, 1, "וּ", "וּ", nil, nil, nil], + 64310 => [0, 1, "זּ", "זּ", nil, nil, nil], + 64312 => [0, 1, "טּ", "טּ", nil, nil, nil], + 64313 => [0, 1, "יּ", "יּ", nil, nil, nil], + 64314 => [0, 1, "ךּ", "ךּ", nil, nil, nil], + 64315 => [0, 1, "כּ", "כּ", nil, nil, nil], + 64316 => [0, 1, "לּ", "לּ", nil, nil, nil], + 64318 => [0, 1, "מּ", "מּ", nil, nil, nil], + 64320 => [0, 1, "נּ", "נּ", nil, nil, nil], + 64321 => [0, 1, "סּ", "סּ", nil, nil, nil], + 64323 => [0, 1, "ףּ", "ףּ", nil, nil, nil], + 64324 => [0, 1, "פּ", "פּ", nil, nil, nil], + 64326 => [0, 1, "צּ", "צּ", nil, nil, nil], + 64327 => [0, 1, "קּ", "קּ", nil, nil, nil], + 64328 => [0, 1, "רּ", "רּ", nil, nil, nil], + 64329 => [0, 1, "שּ", "שּ", nil, nil, nil], + 64330 => [0, 1, "תּ", "תּ", nil, nil, nil], + 64331 => [0, 1, "וֹ", "וֹ", nil, nil, nil], + 64332 => [0, 1, "בֿ", "בֿ", nil, nil, nil], + 64333 => [0, 1, "כֿ", "כֿ", nil, nil, nil], + 64334 => [0, 1, "פֿ", "פֿ", nil, nil, nil], + 64335 => [0, 0, nil, "אל", nil, nil, nil], + 64336 => [0, 0, nil, "ٱ", nil, nil, nil], + 64337 => [0, 0, nil, "ٱ", nil, nil, nil], + 64338 => [0, 0, nil, "ٻ", nil, nil, nil], + 64339 => [0, 0, nil, "ٻ", nil, nil, nil], + 64340 => [0, 0, nil, "ٻ", nil, nil, nil], + 64341 => [0, 0, nil, "ٻ", nil, nil, nil], + 64342 => [0, 0, nil, "پ", nil, nil, nil], + 64343 => [0, 0, nil, "پ", nil, nil, nil], + 64344 => [0, 0, nil, "پ", nil, nil, nil], + 64345 => [0, 0, nil, "پ", nil, nil, nil], + 64346 => [0, 0, nil, "ڀ", nil, nil, nil], + 64347 => [0, 0, nil, "ڀ", nil, nil, nil], + 64348 => [0, 0, nil, "ڀ", nil, nil, nil], + 64349 => [0, 0, nil, "ڀ", nil, nil, nil], + 64350 => [0, 0, nil, "ٺ", nil, nil, nil], + 64351 => [0, 0, nil, "ٺ", nil, nil, nil], + 64352 => [0, 0, nil, "ٺ", nil, nil, nil], + 64353 => [0, 0, nil, "ٺ", nil, nil, nil], + 64354 => [0, 0, nil, "ٿ", nil, nil, nil], + 64355 => [0, 0, nil, "ٿ", nil, nil, nil], + 64356 => [0, 0, nil, "ٿ", nil, nil, nil], + 64357 => [0, 0, nil, "ٿ", nil, nil, nil], + 64358 => [0, 0, nil, "ٹ", nil, nil, nil], + 64359 => [0, 0, nil, "ٹ", nil, nil, nil], + 64360 => [0, 0, nil, "ٹ", nil, nil, nil], + 64361 => [0, 0, nil, "ٹ", nil, nil, nil], + 64362 => [0, 0, nil, "ڤ", nil, nil, nil], + 64363 => [0, 0, nil, "ڤ", nil, nil, nil], + 64364 => [0, 0, nil, "ڤ", nil, nil, nil], + 64365 => [0, 0, nil, "ڤ", nil, nil, nil], + 64366 => [0, 0, nil, "ڦ", nil, nil, nil], + 64367 => [0, 0, nil, "ڦ", nil, nil, nil], + 64368 => [0, 0, nil, "ڦ", nil, nil, nil], + 64369 => [0, 0, nil, "ڦ", nil, nil, nil], + 64370 => [0, 0, nil, "ڄ", nil, nil, nil], + 64371 => [0, 0, nil, "ڄ", nil, nil, nil], + 64372 => [0, 0, nil, "ڄ", nil, nil, nil], + 64373 => [0, 0, nil, "ڄ", nil, nil, nil], + 64374 => [0, 0, nil, "ڃ", nil, nil, nil], + 64375 => [0, 0, nil, "ڃ", nil, nil, nil], + 64376 => [0, 0, nil, "ڃ", nil, nil, nil], + 64377 => [0, 0, nil, "ڃ", nil, nil, nil], + 64378 => [0, 0, nil, "چ", nil, nil, nil], + 64379 => [0, 0, nil, "چ", nil, nil, nil], + 64380 => [0, 0, nil, "چ", nil, nil, nil], + 64381 => [0, 0, nil, "چ", nil, nil, nil], + 64382 => [0, 0, nil, "ڇ", nil, nil, nil], + 64383 => [0, 0, nil, "ڇ", nil, nil, nil], + 64384 => [0, 0, nil, "ڇ", nil, nil, nil], + 64385 => [0, 0, nil, "ڇ", nil, nil, nil], + 64386 => [0, 0, nil, "ڍ", nil, nil, nil], + 64387 => [0, 0, nil, "ڍ", nil, nil, nil], + 64388 => [0, 0, nil, "ڌ", nil, nil, nil], + 64389 => [0, 0, nil, "ڌ", nil, nil, nil], + 64390 => [0, 0, nil, "ڎ", nil, nil, nil], + 64391 => [0, 0, nil, "ڎ", nil, nil, nil], + 64392 => [0, 0, nil, "ڈ", nil, nil, nil], + 64393 => [0, 0, nil, "ڈ", nil, nil, nil], + 64394 => [0, 0, nil, "ژ", nil, nil, nil], + 64395 => [0, 0, nil, "ژ", nil, nil, nil], + 64396 => [0, 0, nil, "ڑ", nil, nil, nil], + 64397 => [0, 0, nil, "ڑ", nil, nil, nil], + 64398 => [0, 0, nil, "ک", nil, nil, nil], + 64399 => [0, 0, nil, "ک", nil, nil, nil], + 64400 => [0, 0, nil, "ک", nil, nil, nil], + 64401 => [0, 0, nil, "ک", nil, nil, nil], + 64402 => [0, 0, nil, "گ", nil, nil, nil], + 64403 => [0, 0, nil, "گ", nil, nil, nil], + 64404 => [0, 0, nil, "گ", nil, nil, nil], + 64405 => [0, 0, nil, "گ", nil, nil, nil], + 64406 => [0, 0, nil, "ڳ", nil, nil, nil], + 64407 => [0, 0, nil, "ڳ", nil, nil, nil], + 64408 => [0, 0, nil, "ڳ", nil, nil, nil], + 64409 => [0, 0, nil, "ڳ", nil, nil, nil], + 64410 => [0, 0, nil, "ڱ", nil, nil, nil], + 64411 => [0, 0, nil, "ڱ", nil, nil, nil], + 64412 => [0, 0, nil, "ڱ", nil, nil, nil], + 64413 => [0, 0, nil, "ڱ", nil, nil, nil], + 64414 => [0, 0, nil, "ں", nil, nil, nil], + 64415 => [0, 0, nil, "ں", nil, nil, nil], + 64416 => [0, 0, nil, "ڻ", nil, nil, nil], + 64417 => [0, 0, nil, "ڻ", nil, nil, nil], + 64418 => [0, 0, nil, "ڻ", nil, nil, nil], + 64419 => [0, 0, nil, "ڻ", nil, nil, nil], + 64420 => [0, 0, nil, "ۀ", nil, nil, nil], + 64421 => [0, 0, nil, "ۀ", nil, nil, nil], + 64422 => [0, 0, nil, "ہ", nil, nil, nil], + 64423 => [0, 0, nil, "ہ", nil, nil, nil], + 64424 => [0, 0, nil, "ہ", nil, nil, nil], + 64425 => [0, 0, nil, "ہ", nil, nil, nil], + 64426 => [0, 0, nil, "ھ", nil, nil, nil], + 64427 => [0, 0, nil, "ھ", nil, nil, nil], + 64428 => [0, 0, nil, "ھ", nil, nil, nil], + 64429 => [0, 0, nil, "ھ", nil, nil, nil], + 64430 => [0, 0, nil, "ے", nil, nil, nil], + 64431 => [0, 0, nil, "ے", nil, nil, nil], + 64432 => [0, 0, nil, "ۓ", nil, nil, nil], + 64433 => [0, 0, nil, "ۓ", nil, nil, nil], + 64467 => [0, 0, nil, "ڭ", nil, nil, nil], + 64468 => [0, 0, nil, "ڭ", nil, nil, nil], + 64469 => [0, 0, nil, "ڭ", nil, nil, nil], + 64470 => [0, 0, nil, "ڭ", nil, nil, nil], + 64471 => [0, 0, nil, "ۇ", nil, nil, nil], + 64472 => [0, 0, nil, "ۇ", nil, nil, nil], + 64473 => [0, 0, nil, "ۆ", nil, nil, nil], + 64474 => [0, 0, nil, "ۆ", nil, nil, nil], + 64475 => [0, 0, nil, "ۈ", nil, nil, nil], + 64476 => [0, 0, nil, "ۈ", nil, nil, nil], + 64477 => [0, 0, nil, "ٷ", nil, nil, nil], + 64478 => [0, 0, nil, "ۋ", nil, nil, nil], + 64479 => [0, 0, nil, "ۋ", nil, nil, nil], + 64480 => [0, 0, nil, "ۅ", nil, nil, nil], + 64481 => [0, 0, nil, "ۅ", nil, nil, nil], + 64482 => [0, 0, nil, "ۉ", nil, nil, nil], + 64483 => [0, 0, nil, "ۉ", nil, nil, nil], + 64484 => [0, 0, nil, "ې", nil, nil, nil], + 64485 => [0, 0, nil, "ې", nil, nil, nil], + 64486 => [0, 0, nil, "ې", nil, nil, nil], + 64487 => [0, 0, nil, "ې", nil, nil, nil], + 64488 => [0, 0, nil, "ى", nil, nil, nil], + 64489 => [0, 0, nil, "ى", nil, nil, nil], + 64490 => [0, 0, nil, "ئا", nil, nil, nil], + 64491 => [0, 0, nil, "ئا", nil, nil, nil], + 64492 => [0, 0, nil, "ئە", nil, nil, nil], + 64493 => [0, 0, nil, "ئە", nil, nil, nil], + 64494 => [0, 0, nil, "ئو", nil, nil, nil], + 64495 => [0, 0, nil, "ئو", nil, nil, nil], + 64496 => [0, 0, nil, "ئۇ", nil, nil, nil], + 64497 => [0, 0, nil, "ئۇ", nil, nil, nil], + 64498 => [0, 0, nil, "ئۆ", nil, nil, nil], + 64499 => [0, 0, nil, "ئۆ", nil, nil, nil], + 64500 => [0, 0, nil, "ئۈ", nil, nil, nil], + 64501 => [0, 0, nil, "ئۈ", nil, nil, nil], + 64502 => [0, 0, nil, "ئې", nil, nil, nil], + 64503 => [0, 0, nil, "ئې", nil, nil, nil], + 64504 => [0, 0, nil, "ئې", nil, nil, nil], + 64505 => [0, 0, nil, "ئى", nil, nil, nil], + 64506 => [0, 0, nil, "ئى", nil, nil, nil], + 64507 => [0, 0, nil, "ئى", nil, nil, nil], + 64508 => [0, 0, nil, "ی", nil, nil, nil], + 64509 => [0, 0, nil, "ی", nil, nil, nil], + 64510 => [0, 0, nil, "ی", nil, nil, nil], + 64511 => [0, 0, nil, "ی", nil, nil, nil], + 64512 => [0, 0, nil, "ئج", nil, nil, nil], + 64513 => [0, 0, nil, "ئح", nil, nil, nil], + 64514 => [0, 0, nil, "ئم", nil, nil, nil], + 64515 => [0, 0, nil, "ئى", nil, nil, nil], + 64516 => [0, 0, nil, "ئي", nil, nil, nil], + 64517 => [0, 0, nil, "بج", nil, nil, nil], + 64518 => [0, 0, nil, "بح", nil, nil, nil], + 64519 => [0, 0, nil, "بخ", nil, nil, nil], + 64520 => [0, 0, nil, "بم", nil, nil, nil], + 64521 => [0, 0, nil, "بى", nil, nil, nil], + 64522 => [0, 0, nil, "بي", nil, nil, nil], + 64523 => [0, 0, nil, "تج", nil, nil, nil], + 64524 => [0, 0, nil, "تح", nil, nil, nil], + 64525 => [0, 0, nil, "تخ", nil, nil, nil], + 64526 => [0, 0, nil, "تم", nil, nil, nil], + 64527 => [0, 0, nil, "تى", nil, nil, nil], + 64528 => [0, 0, nil, "تي", nil, nil, nil], + 64529 => [0, 0, nil, "ثج", nil, nil, nil], + 64530 => [0, 0, nil, "ثم", nil, nil, nil], + 64531 => [0, 0, nil, "ثى", nil, nil, nil], + 64532 => [0, 0, nil, "ثي", nil, nil, nil], + 64533 => [0, 0, nil, "جح", nil, nil, nil], + 64534 => [0, 0, nil, "جم", nil, nil, nil], + 64535 => [0, 0, nil, "حج", nil, nil, nil], + 64536 => [0, 0, nil, "حم", nil, nil, nil], + 64537 => [0, 0, nil, "خج", nil, nil, nil], + 64538 => [0, 0, nil, "خح", nil, nil, nil], + 64539 => [0, 0, nil, "خم", nil, nil, nil], + 64540 => [0, 0, nil, "سج", nil, nil, nil], + 64541 => [0, 0, nil, "سح", nil, nil, nil], + 64542 => [0, 0, nil, "سخ", nil, nil, nil], + 64543 => [0, 0, nil, "سم", nil, nil, nil], + 64544 => [0, 0, nil, "صح", nil, nil, nil], + 64545 => [0, 0, nil, "صم", nil, nil, nil], + 64546 => [0, 0, nil, "ضج", nil, nil, nil], + 64547 => [0, 0, nil, "ضح", nil, nil, nil], + 64548 => [0, 0, nil, "ضخ", nil, nil, nil], + 64549 => [0, 0, nil, "ضم", nil, nil, nil], + 64550 => [0, 0, nil, "طح", nil, nil, nil], + 64551 => [0, 0, nil, "طم", nil, nil, nil], + 64552 => [0, 0, nil, "ظم", nil, nil, nil], + 64553 => [0, 0, nil, "عج", nil, nil, nil], + 64554 => [0, 0, nil, "عم", nil, nil, nil], + 64555 => [0, 0, nil, "غج", nil, nil, nil], + 64556 => [0, 0, nil, "غم", nil, nil, nil], + 64557 => [0, 0, nil, "فج", nil, nil, nil], + 64558 => [0, 0, nil, "فح", nil, nil, nil], + 64559 => [0, 0, nil, "فخ", nil, nil, nil], + 64560 => [0, 0, nil, "فم", nil, nil, nil], + 64561 => [0, 0, nil, "فى", nil, nil, nil], + 64562 => [0, 0, nil, "في", nil, nil, nil], + 64563 => [0, 0, nil, "قح", nil, nil, nil], + 64564 => [0, 0, nil, "قم", nil, nil, nil], + 64565 => [0, 0, nil, "قى", nil, nil, nil], + 64566 => [0, 0, nil, "قي", nil, nil, nil], + 64567 => [0, 0, nil, "كا", nil, nil, nil], + 64568 => [0, 0, nil, "كج", nil, nil, nil], + 64569 => [0, 0, nil, "كح", nil, nil, nil], + 64570 => [0, 0, nil, "كخ", nil, nil, nil], + 64571 => [0, 0, nil, "كل", nil, nil, nil], + 64572 => [0, 0, nil, "كم", nil, nil, nil], + 64573 => [0, 0, nil, "كى", nil, nil, nil], + 64574 => [0, 0, nil, "كي", nil, nil, nil], + 64575 => [0, 0, nil, "لج", nil, nil, nil], + 64576 => [0, 0, nil, "لح", nil, nil, nil], + 64577 => [0, 0, nil, "لخ", nil, nil, nil], + 64578 => [0, 0, nil, "لم", nil, nil, nil], + 64579 => [0, 0, nil, "لى", nil, nil, nil], + 64580 => [0, 0, nil, "لي", nil, nil, nil], + 64581 => [0, 0, nil, "مج", nil, nil, nil], + 64582 => [0, 0, nil, "مح", nil, nil, nil], + 64583 => [0, 0, nil, "مخ", nil, nil, nil], + 64584 => [0, 0, nil, "مم", nil, nil, nil], + 64585 => [0, 0, nil, "مى", nil, nil, nil], + 64586 => [0, 0, nil, "مي", nil, nil, nil], + 64587 => [0, 0, nil, "نج", nil, nil, nil], + 64588 => [0, 0, nil, "نح", nil, nil, nil], + 64589 => [0, 0, nil, "نخ", nil, nil, nil], + 64590 => [0, 0, nil, "نم", nil, nil, nil], + 64591 => [0, 0, nil, "نى", nil, nil, nil], + 64592 => [0, 0, nil, "ني", nil, nil, nil], + 64593 => [0, 0, nil, "هج", nil, nil, nil], + 64594 => [0, 0, nil, "هم", nil, nil, nil], + 64595 => [0, 0, nil, "هى", nil, nil, nil], + 64596 => [0, 0, nil, "هي", nil, nil, nil], + 64597 => [0, 0, nil, "يج", nil, nil, nil], + 64598 => [0, 0, nil, "يح", nil, nil, nil], + 64599 => [0, 0, nil, "يخ", nil, nil, nil], + 64600 => [0, 0, nil, "يم", nil, nil, nil], + 64601 => [0, 0, nil, "يى", nil, nil, nil], + 64602 => [0, 0, nil, "يي", nil, nil, nil], + 64603 => [0, 0, nil, "ذٰ", nil, nil, nil], + 64604 => [0, 0, nil, "رٰ", nil, nil, nil], + 64605 => [0, 0, nil, "ىٰ", nil, nil, nil], + 64606 => [0, 0, nil, " ٌّ", nil, nil, nil], + 64607 => [0, 0, nil, " ٍّ", nil, nil, nil], + 64608 => [0, 0, nil, " َّ", nil, nil, nil], + 64609 => [0, 0, nil, " ُّ", nil, nil, nil], + 64610 => [0, 0, nil, " ِّ", nil, nil, nil], + 64611 => [0, 0, nil, " ّٰ", nil, nil, nil], + 64612 => [0, 0, nil, "ئر", nil, nil, nil], + 64613 => [0, 0, nil, "ئز", nil, nil, nil], + 64614 => [0, 0, nil, "ئم", nil, nil, nil], + 64615 => [0, 0, nil, "ئن", nil, nil, nil], + 64616 => [0, 0, nil, "ئى", nil, nil, nil], + 64617 => [0, 0, nil, "ئي", nil, nil, nil], + 64618 => [0, 0, nil, "بر", nil, nil, nil], + 64619 => [0, 0, nil, "بز", nil, nil, nil], + 64620 => [0, 0, nil, "بم", nil, nil, nil], + 64621 => [0, 0, nil, "بن", nil, nil, nil], + 64622 => [0, 0, nil, "بى", nil, nil, nil], + 64623 => [0, 0, nil, "بي", nil, nil, nil], + 64624 => [0, 0, nil, "تر", nil, nil, nil], + 64625 => [0, 0, nil, "تز", nil, nil, nil], + 64626 => [0, 0, nil, "تم", nil, nil, nil], + 64627 => [0, 0, nil, "تن", nil, nil, nil], + 64628 => [0, 0, nil, "تى", nil, nil, nil], + 64629 => [0, 0, nil, "تي", nil, nil, nil], + 64630 => [0, 0, nil, "ثر", nil, nil, nil], + 64631 => [0, 0, nil, "ثز", nil, nil, nil], + 64632 => [0, 0, nil, "ثم", nil, nil, nil], + 64633 => [0, 0, nil, "ثن", nil, nil, nil], + 64634 => [0, 0, nil, "ثى", nil, nil, nil], + 64635 => [0, 0, nil, "ثي", nil, nil, nil], + 64636 => [0, 0, nil, "فى", nil, nil, nil], + 64637 => [0, 0, nil, "في", nil, nil, nil], + 64638 => [0, 0, nil, "قى", nil, nil, nil], + 64639 => [0, 0, nil, "قي", nil, nil, nil], + 64640 => [0, 0, nil, "كا", nil, nil, nil], + 64641 => [0, 0, nil, "كل", nil, nil, nil], + 64642 => [0, 0, nil, "كم", nil, nil, nil], + 64643 => [0, 0, nil, "كى", nil, nil, nil], + 64644 => [0, 0, nil, "كي", nil, nil, nil], + 64645 => [0, 0, nil, "لم", nil, nil, nil], + 64646 => [0, 0, nil, "لى", nil, nil, nil], + 64647 => [0, 0, nil, "لي", nil, nil, nil], + 64648 => [0, 0, nil, "ما", nil, nil, nil], + 64649 => [0, 0, nil, "مم", nil, nil, nil], + 64650 => [0, 0, nil, "نر", nil, nil, nil], + 64651 => [0, 0, nil, "نز", nil, nil, nil], + 64652 => [0, 0, nil, "نم", nil, nil, nil], + 64653 => [0, 0, nil, "نن", nil, nil, nil], + 64654 => [0, 0, nil, "نى", nil, nil, nil], + 64655 => [0, 0, nil, "ني", nil, nil, nil], + 64656 => [0, 0, nil, "ىٰ", nil, nil, nil], + 64657 => [0, 0, nil, "ير", nil, nil, nil], + 64658 => [0, 0, nil, "يز", nil, nil, nil], + 64659 => [0, 0, nil, "يم", nil, nil, nil], + 64660 => [0, 0, nil, "ين", nil, nil, nil], + 64661 => [0, 0, nil, "يى", nil, nil, nil], + 64662 => [0, 0, nil, "يي", nil, nil, nil], + 64663 => [0, 0, nil, "ئج", nil, nil, nil], + 64664 => [0, 0, nil, "ئح", nil, nil, nil], + 64665 => [0, 0, nil, "ئخ", nil, nil, nil], + 64666 => [0, 0, nil, "ئم", nil, nil, nil], + 64667 => [0, 0, nil, "ئه", nil, nil, nil], + 64668 => [0, 0, nil, "بج", nil, nil, nil], + 64669 => [0, 0, nil, "بح", nil, nil, nil], + 64670 => [0, 0, nil, "بخ", nil, nil, nil], + 64671 => [0, 0, nil, "بم", nil, nil, nil], + 64672 => [0, 0, nil, "به", nil, nil, nil], + 64673 => [0, 0, nil, "تج", nil, nil, nil], + 64674 => [0, 0, nil, "تح", nil, nil, nil], + 64675 => [0, 0, nil, "تخ", nil, nil, nil], + 64676 => [0, 0, nil, "تم", nil, nil, nil], + 64677 => [0, 0, nil, "ته", nil, nil, nil], + 64678 => [0, 0, nil, "ثم", nil, nil, nil], + 64679 => [0, 0, nil, "جح", nil, nil, nil], + 64680 => [0, 0, nil, "جم", nil, nil, nil], + 64681 => [0, 0, nil, "حج", nil, nil, nil], + 64682 => [0, 0, nil, "حم", nil, nil, nil], + 64683 => [0, 0, nil, "خج", nil, nil, nil], + 64684 => [0, 0, nil, "خم", nil, nil, nil], + 64685 => [0, 0, nil, "سج", nil, nil, nil], + 64686 => [0, 0, nil, "سح", nil, nil, nil], + 64687 => [0, 0, nil, "سخ", nil, nil, nil], + 64688 => [0, 0, nil, "سم", nil, nil, nil], + 64689 => [0, 0, nil, "صح", nil, nil, nil], + 64690 => [0, 0, nil, "صخ", nil, nil, nil], + 64691 => [0, 0, nil, "صم", nil, nil, nil], + 64692 => [0, 0, nil, "ضج", nil, nil, nil], + 64693 => [0, 0, nil, "ضح", nil, nil, nil], + 64694 => [0, 0, nil, "ضخ", nil, nil, nil], + 64695 => [0, 0, nil, "ضم", nil, nil, nil], + 64696 => [0, 0, nil, "طح", nil, nil, nil], + 64697 => [0, 0, nil, "ظم", nil, nil, nil], + 64698 => [0, 0, nil, "عج", nil, nil, nil], + 64699 => [0, 0, nil, "عم", nil, nil, nil], + 64700 => [0, 0, nil, "غج", nil, nil, nil], + 64701 => [0, 0, nil, "غم", nil, nil, nil], + 64702 => [0, 0, nil, "فج", nil, nil, nil], + 64703 => [0, 0, nil, "فح", nil, nil, nil], + 64704 => [0, 0, nil, "فخ", nil, nil, nil], + 64705 => [0, 0, nil, "فم", nil, nil, nil], + 64706 => [0, 0, nil, "قح", nil, nil, nil], + 64707 => [0, 0, nil, "قم", nil, nil, nil], + 64708 => [0, 0, nil, "كج", nil, nil, nil], + 64709 => [0, 0, nil, "كح", nil, nil, nil], + 64710 => [0, 0, nil, "كخ", nil, nil, nil], + 64711 => [0, 0, nil, "كل", nil, nil, nil], + 64712 => [0, 0, nil, "كم", nil, nil, nil], + 64713 => [0, 0, nil, "لج", nil, nil, nil], + 64714 => [0, 0, nil, "لح", nil, nil, nil], + 64715 => [0, 0, nil, "لخ", nil, nil, nil], + 64716 => [0, 0, nil, "لم", nil, nil, nil], + 64717 => [0, 0, nil, "له", nil, nil, nil], + 64718 => [0, 0, nil, "مج", nil, nil, nil], + 64719 => [0, 0, nil, "مح", nil, nil, nil], + 64720 => [0, 0, nil, "مخ", nil, nil, nil], + 64721 => [0, 0, nil, "مم", nil, nil, nil], + 64722 => [0, 0, nil, "نج", nil, nil, nil], + 64723 => [0, 0, nil, "نح", nil, nil, nil], + 64724 => [0, 0, nil, "نخ", nil, nil, nil], + 64725 => [0, 0, nil, "نم", nil, nil, nil], + 64726 => [0, 0, nil, "نه", nil, nil, nil], + 64727 => [0, 0, nil, "هج", nil, nil, nil], + 64728 => [0, 0, nil, "هم", nil, nil, nil], + 64729 => [0, 0, nil, "هٰ", nil, nil, nil], + 64730 => [0, 0, nil, "يج", nil, nil, nil], + 64731 => [0, 0, nil, "يح", nil, nil, nil], + 64732 => [0, 0, nil, "يخ", nil, nil, nil], + 64733 => [0, 0, nil, "يم", nil, nil, nil], + 64734 => [0, 0, nil, "يه", nil, nil, nil], + 64735 => [0, 0, nil, "ئم", nil, nil, nil], + 64736 => [0, 0, nil, "ئه", nil, nil, nil], + 64737 => [0, 0, nil, "بم", nil, nil, nil], + 64738 => [0, 0, nil, "به", nil, nil, nil], + 64739 => [0, 0, nil, "تم", nil, nil, nil], + 64740 => [0, 0, nil, "ته", nil, nil, nil], + 64741 => [0, 0, nil, "ثم", nil, nil, nil], + 64742 => [0, 0, nil, "ثه", nil, nil, nil], + 64743 => [0, 0, nil, "سم", nil, nil, nil], + 64744 => [0, 0, nil, "سه", nil, nil, nil], + 64745 => [0, 0, nil, "شم", nil, nil, nil], + 64746 => [0, 0, nil, "شه", nil, nil, nil], + 64747 => [0, 0, nil, "كل", nil, nil, nil], + 64748 => [0, 0, nil, "كم", nil, nil, nil], + 64749 => [0, 0, nil, "لم", nil, nil, nil], + 64750 => [0, 0, nil, "نم", nil, nil, nil], + 64751 => [0, 0, nil, "نه", nil, nil, nil], + 64752 => [0, 0, nil, "يم", nil, nil, nil], + 64753 => [0, 0, nil, "يه", nil, nil, nil], + 64754 => [0, 0, nil, "ـَّ", nil, nil, nil], + 64755 => [0, 0, nil, "ـُّ", nil, nil, nil], + 64756 => [0, 0, nil, "ـِّ", nil, nil, nil], + 64757 => [0, 0, nil, "طى", nil, nil, nil], + 64758 => [0, 0, nil, "طي", nil, nil, nil], + 64759 => [0, 0, nil, "عى", nil, nil, nil], + 64760 => [0, 0, nil, "عي", nil, nil, nil], + 64761 => [0, 0, nil, "غى", nil, nil, nil], + 64762 => [0, 0, nil, "غي", nil, nil, nil], + 64763 => [0, 0, nil, "سى", nil, nil, nil], + 64764 => [0, 0, nil, "سي", nil, nil, nil], + 64765 => [0, 0, nil, "شى", nil, nil, nil], + 64766 => [0, 0, nil, "شي", nil, nil, nil], + 64767 => [0, 0, nil, "حى", nil, nil, nil], + 64768 => [0, 0, nil, "حي", nil, nil, nil], + 64769 => [0, 0, nil, "جى", nil, nil, nil], + 64770 => [0, 0, nil, "جي", nil, nil, nil], + 64771 => [0, 0, nil, "خى", nil, nil, nil], + 64772 => [0, 0, nil, "خي", nil, nil, nil], + 64773 => [0, 0, nil, "صى", nil, nil, nil], + 64774 => [0, 0, nil, "صي", nil, nil, nil], + 64775 => [0, 0, nil, "ضى", nil, nil, nil], + 64776 => [0, 0, nil, "ضي", nil, nil, nil], + 64777 => [0, 0, nil, "شج", nil, nil, nil], + 64778 => [0, 0, nil, "شح", nil, nil, nil], + 64779 => [0, 0, nil, "شخ", nil, nil, nil], + 64780 => [0, 0, nil, "شم", nil, nil, nil], + 64781 => [0, 0, nil, "شر", nil, nil, nil], + 64782 => [0, 0, nil, "سر", nil, nil, nil], + 64783 => [0, 0, nil, "صر", nil, nil, nil], + 64784 => [0, 0, nil, "ضر", nil, nil, nil], + 64785 => [0, 0, nil, "طى", nil, nil, nil], + 64786 => [0, 0, nil, "طي", nil, nil, nil], + 64787 => [0, 0, nil, "عى", nil, nil, nil], + 64788 => [0, 0, nil, "عي", nil, nil, nil], + 64789 => [0, 0, nil, "غى", nil, nil, nil], + 64790 => [0, 0, nil, "غي", nil, nil, nil], + 64791 => [0, 0, nil, "سى", nil, nil, nil], + 64792 => [0, 0, nil, "سي", nil, nil, nil], + 64793 => [0, 0, nil, "شى", nil, nil, nil], + 64794 => [0, 0, nil, "شي", nil, nil, nil], + 64795 => [0, 0, nil, "حى", nil, nil, nil], + 64796 => [0, 0, nil, "حي", nil, nil, nil], + 64797 => [0, 0, nil, "جى", nil, nil, nil], + 64798 => [0, 0, nil, "جي", nil, nil, nil], + 64799 => [0, 0, nil, "خى", nil, nil, nil], + 64800 => [0, 0, nil, "خي", nil, nil, nil], + 64801 => [0, 0, nil, "صى", nil, nil, nil], + 64802 => [0, 0, nil, "صي", nil, nil, nil], + 64803 => [0, 0, nil, "ضى", nil, nil, nil], + 64804 => [0, 0, nil, "ضي", nil, nil, nil], + 64805 => [0, 0, nil, "شج", nil, nil, nil], + 64806 => [0, 0, nil, "شح", nil, nil, nil], + 64807 => [0, 0, nil, "شخ", nil, nil, nil], + 64808 => [0, 0, nil, "شم", nil, nil, nil], + 64809 => [0, 0, nil, "شر", nil, nil, nil], + 64810 => [0, 0, nil, "سر", nil, nil, nil], + 64811 => [0, 0, nil, "صر", nil, nil, nil], + 64812 => [0, 0, nil, "ضر", nil, nil, nil], + 64813 => [0, 0, nil, "شج", nil, nil, nil], + 64814 => [0, 0, nil, "شح", nil, nil, nil], + 64815 => [0, 0, nil, "شخ", nil, nil, nil], + 64816 => [0, 0, nil, "شم", nil, nil, nil], + 64817 => [0, 0, nil, "سه", nil, nil, nil], + 64818 => [0, 0, nil, "شه", nil, nil, nil], + 64819 => [0, 0, nil, "طم", nil, nil, nil], + 64820 => [0, 0, nil, "سج", nil, nil, nil], + 64821 => [0, 0, nil, "سح", nil, nil, nil], + 64822 => [0, 0, nil, "سخ", nil, nil, nil], + 64823 => [0, 0, nil, "شج", nil, nil, nil], + 64824 => [0, 0, nil, "شح", nil, nil, nil], + 64825 => [0, 0, nil, "شخ", nil, nil, nil], + 64826 => [0, 0, nil, "طم", nil, nil, nil], + 64827 => [0, 0, nil, "ظم", nil, nil, nil], + 64828 => [0, 0, nil, "اً", nil, nil, nil], + 64829 => [0, 0, nil, "اً", nil, nil, nil], + 64848 => [0, 0, nil, "تجم", nil, nil, nil], + 64849 => [0, 0, nil, "تحج", nil, nil, nil], + 64850 => [0, 0, nil, "تحج", nil, nil, nil], + 64851 => [0, 0, nil, "تحم", nil, nil, nil], + 64852 => [0, 0, nil, "تخم", nil, nil, nil], + 64853 => [0, 0, nil, "تمج", nil, nil, nil], + 64854 => [0, 0, nil, "تمح", nil, nil, nil], + 64855 => [0, 0, nil, "تمخ", nil, nil, nil], + 64856 => [0, 0, nil, "جمح", nil, nil, nil], + 64857 => [0, 0, nil, "جمح", nil, nil, nil], + 64858 => [0, 0, nil, "حمي", nil, nil, nil], + 64859 => [0, 0, nil, "حمى", nil, nil, nil], + 64860 => [0, 0, nil, "سحج", nil, nil, nil], + 64861 => [0, 0, nil, "سجح", nil, nil, nil], + 64862 => [0, 0, nil, "سجى", nil, nil, nil], + 64863 => [0, 0, nil, "سمح", nil, nil, nil], + 64864 => [0, 0, nil, "سمح", nil, nil, nil], + 64865 => [0, 0, nil, "سمج", nil, nil, nil], + 64866 => [0, 0, nil, "سمم", nil, nil, nil], + 64867 => [0, 0, nil, "سمم", nil, nil, nil], + 64868 => [0, 0, nil, "صحح", nil, nil, nil], + 64869 => [0, 0, nil, "صحح", nil, nil, nil], + 64870 => [0, 0, nil, "صمم", nil, nil, nil], + 64871 => [0, 0, nil, "شحم", nil, nil, nil], + 64872 => [0, 0, nil, "شحم", nil, nil, nil], + 64873 => [0, 0, nil, "شجي", nil, nil, nil], + 64874 => [0, 0, nil, "شمخ", nil, nil, nil], + 64875 => [0, 0, nil, "شمخ", nil, nil, nil], + 64876 => [0, 0, nil, "شمم", nil, nil, nil], + 64877 => [0, 0, nil, "شمم", nil, nil, nil], + 64878 => [0, 0, nil, "ضحى", nil, nil, nil], + 64879 => [0, 0, nil, "ضخم", nil, nil, nil], + 64880 => [0, 0, nil, "ضخم", nil, nil, nil], + 64881 => [0, 0, nil, "طمح", nil, nil, nil], + 64882 => [0, 0, nil, "طمح", nil, nil, nil], + 64883 => [0, 0, nil, "طمم", nil, nil, nil], + 64884 => [0, 0, nil, "طمي", nil, nil, nil], + 64885 => [0, 0, nil, "عجم", nil, nil, nil], + 64886 => [0, 0, nil, "عمم", nil, nil, nil], + 64887 => [0, 0, nil, "عمم", nil, nil, nil], + 64888 => [0, 0, nil, "عمى", nil, nil, nil], + 64889 => [0, 0, nil, "غمم", nil, nil, nil], + 64890 => [0, 0, nil, "غمي", nil, nil, nil], + 64891 => [0, 0, nil, "غمى", nil, nil, nil], + 64892 => [0, 0, nil, "فخم", nil, nil, nil], + 64893 => [0, 0, nil, "فخم", nil, nil, nil], + 64894 => [0, 0, nil, "قمح", nil, nil, nil], + 64895 => [0, 0, nil, "قمم", nil, nil, nil], + 64896 => [0, 0, nil, "لحم", nil, nil, nil], + 64897 => [0, 0, nil, "لحي", nil, nil, nil], + 64898 => [0, 0, nil, "لحى", nil, nil, nil], + 64899 => [0, 0, nil, "لجج", nil, nil, nil], + 64900 => [0, 0, nil, "لجج", nil, nil, nil], + 64901 => [0, 0, nil, "لخم", nil, nil, nil], + 64902 => [0, 0, nil, "لخم", nil, nil, nil], + 64903 => [0, 0, nil, "لمح", nil, nil, nil], + 64904 => [0, 0, nil, "لمح", nil, nil, nil], + 64905 => [0, 0, nil, "محج", nil, nil, nil], + 64906 => [0, 0, nil, "محم", nil, nil, nil], + 64907 => [0, 0, nil, "محي", nil, nil, nil], + 64908 => [0, 0, nil, "مجح", nil, nil, nil], + 64909 => [0, 0, nil, "مجم", nil, nil, nil], + 64910 => [0, 0, nil, "مخج", nil, nil, nil], + 64911 => [0, 0, nil, "مخم", nil, nil, nil], + 64914 => [0, 0, nil, "مجخ", nil, nil, nil], + 64915 => [0, 0, nil, "همج", nil, nil, nil], + 64916 => [0, 0, nil, "همم", nil, nil, nil], + 64917 => [0, 0, nil, "نحم", nil, nil, nil], + 64918 => [0, 0, nil, "نحى", nil, nil, nil], + 64919 => [0, 0, nil, "نجم", nil, nil, nil], + 64920 => [0, 0, nil, "نجم", nil, nil, nil], + 64921 => [0, 0, nil, "نجى", nil, nil, nil], + 64922 => [0, 0, nil, "نمي", nil, nil, nil], + 64923 => [0, 0, nil, "نمى", nil, nil, nil], + 64924 => [0, 0, nil, "يمم", nil, nil, nil], + 64925 => [0, 0, nil, "يمم", nil, nil, nil], + 64926 => [0, 0, nil, "بخي", nil, nil, nil], + 64927 => [0, 0, nil, "تجي", nil, nil, nil], + 64928 => [0, 0, nil, "تجى", nil, nil, nil], + 64929 => [0, 0, nil, "تخي", nil, nil, nil], + 64930 => [0, 0, nil, "تخى", nil, nil, nil], + 64931 => [0, 0, nil, "تمي", nil, nil, nil], + 64932 => [0, 0, nil, "تمى", nil, nil, nil], + 64933 => [0, 0, nil, "جمي", nil, nil, nil], + 64934 => [0, 0, nil, "جحى", nil, nil, nil], + 64935 => [0, 0, nil, "جمى", nil, nil, nil], + 64936 => [0, 0, nil, "سخى", nil, nil, nil], + 64937 => [0, 0, nil, "صحي", nil, nil, nil], + 64938 => [0, 0, nil, "شحي", nil, nil, nil], + 64939 => [0, 0, nil, "ضحي", nil, nil, nil], + 64940 => [0, 0, nil, "لجي", nil, nil, nil], + 64941 => [0, 0, nil, "لمي", nil, nil, nil], + 64942 => [0, 0, nil, "يحي", nil, nil, nil], + 64943 => [0, 0, nil, "يجي", nil, nil, nil], + 64944 => [0, 0, nil, "يمي", nil, nil, nil], + 64945 => [0, 0, nil, "ممي", nil, nil, nil], + 64946 => [0, 0, nil, "قمي", nil, nil, nil], + 64947 => [0, 0, nil, "نحي", nil, nil, nil], + 64948 => [0, 0, nil, "قمح", nil, nil, nil], + 64949 => [0, 0, nil, "لحم", nil, nil, nil], + 64950 => [0, 0, nil, "عمي", nil, nil, nil], + 64951 => [0, 0, nil, "كمي", nil, nil, nil], + 64952 => [0, 0, nil, "نجح", nil, nil, nil], + 64953 => [0, 0, nil, "مخي", nil, nil, nil], + 64954 => [0, 0, nil, "لجم", nil, nil, nil], + 64955 => [0, 0, nil, "كمم", nil, nil, nil], + 64956 => [0, 0, nil, "لجم", nil, nil, nil], + 64957 => [0, 0, nil, "نجح", nil, nil, nil], + 64958 => [0, 0, nil, "جحي", nil, nil, nil], + 64959 => [0, 0, nil, "حجي", nil, nil, nil], + 64960 => [0, 0, nil, "مجي", nil, nil, nil], + 64961 => [0, 0, nil, "فمي", nil, nil, nil], + 64962 => [0, 0, nil, "بحي", nil, nil, nil], + 64963 => [0, 0, nil, "كمم", nil, nil, nil], + 64964 => [0, 0, nil, "عجم", nil, nil, nil], + 64965 => [0, 0, nil, "صمم", nil, nil, nil], + 64966 => [0, 0, nil, "سخي", nil, nil, nil], + 64967 => [0, 0, nil, "نجي", nil, nil, nil], + 65008 => [0, 0, nil, "صلے", nil, nil, nil], + 65009 => [0, 0, nil, "قلے", nil, nil, nil], + 65010 => [0, 0, nil, "الله", nil, nil, nil], + 65011 => [0, 0, nil, "اكبر", nil, nil, nil], + 65012 => [0, 0, nil, "محمد", nil, nil, nil], + 65013 => [0, 0, nil, "صلعم", nil, nil, nil], + 65014 => [0, 0, nil, "رسول", nil, nil, nil], + 65015 => [0, 0, nil, "عليه", nil, nil, nil], + 65016 => [0, 0, nil, "وسلم", nil, nil, nil], + 65017 => [0, 0, nil, "صلى", nil, nil, nil], + 65018 => [0, 0, nil, "صلى الله عليه وسلم", nil, nil, nil], + 65019 => [0, 0, nil, "جل جلاله", nil, nil, nil], + 65056 => [230, 0, nil, nil, nil, nil, nil], + 65057 => [230, 0, nil, nil, nil, nil, nil], + 65058 => [230, 0, nil, nil, nil, nil, nil], + 65059 => [230, 0, nil, nil, nil, nil, nil], + 65072 => [0, 0, nil, "‥", nil, nil, nil], + 65073 => [0, 0, nil, "—", nil, nil, nil], + 65074 => [0, 0, nil, "–", nil, nil, nil], + 65075 => [0, 0, nil, "_", nil, nil, nil], + 65076 => [0, 0, nil, "_", nil, nil, nil], + 65077 => [0, 0, nil, "(", nil, nil, nil], + 65078 => [0, 0, nil, ")", nil, nil, nil], + 65079 => [0, 0, nil, "{", nil, nil, nil], + 65080 => [0, 0, nil, "}", nil, nil, nil], + 65081 => [0, 0, nil, "〔", nil, nil, nil], + 65082 => [0, 0, nil, "〕", nil, nil, nil], + 65083 => [0, 0, nil, "【", nil, nil, nil], + 65084 => [0, 0, nil, "】", nil, nil, nil], + 65085 => [0, 0, nil, "《", nil, nil, nil], + 65086 => [0, 0, nil, "》", nil, nil, nil], + 65087 => [0, 0, nil, "〈", nil, nil, nil], + 65088 => [0, 0, nil, "〉", nil, nil, nil], + 65089 => [0, 0, nil, "「", nil, nil, nil], + 65090 => [0, 0, nil, "」", nil, nil, nil], + 65091 => [0, 0, nil, "『", nil, nil, nil], + 65092 => [0, 0, nil, "』", nil, nil, nil], + 65097 => [0, 0, nil, "‾", nil, nil, nil], + 65098 => [0, 0, nil, "‾", nil, nil, nil], + 65099 => [0, 0, nil, "‾", nil, nil, nil], + 65100 => [0, 0, nil, "‾", nil, nil, nil], + 65101 => [0, 0, nil, "_", nil, nil, nil], + 65102 => [0, 0, nil, "_", nil, nil, nil], + 65103 => [0, 0, nil, "_", nil, nil, nil], + 65104 => [0, 0, nil, ",", nil, nil, nil], + 65105 => [0, 0, nil, "、", nil, nil, nil], + 65106 => [0, 0, nil, ".", nil, nil, nil], + 65108 => [0, 0, nil, ";", nil, nil, nil], + 65109 => [0, 0, nil, ":", nil, nil, nil], + 65110 => [0, 0, nil, "?", nil, nil, nil], + 65111 => [0, 0, nil, "!", nil, nil, nil], + 65112 => [0, 0, nil, "—", nil, nil, nil], + 65113 => [0, 0, nil, "(", nil, nil, nil], + 65114 => [0, 0, nil, ")", nil, nil, nil], + 65115 => [0, 0, nil, "{", nil, nil, nil], + 65116 => [0, 0, nil, "}", nil, nil, nil], + 65117 => [0, 0, nil, "〔", nil, nil, nil], + 65118 => [0, 0, nil, "〕", nil, nil, nil], + 65119 => [0, 0, nil, "#", nil, nil, nil], + 65120 => [0, 0, nil, "&", nil, nil, nil], + 65121 => [0, 0, nil, "*", nil, nil, nil], + 65122 => [0, 0, nil, "+", nil, nil, nil], + 65123 => [0, 0, nil, "-", nil, nil, nil], + 65124 => [0, 0, nil, "<", nil, nil, nil], + 65125 => [0, 0, nil, ">", nil, nil, nil], + 65126 => [0, 0, nil, "=", nil, nil, nil], + 65128 => [0, 0, nil, "\\", nil, nil, nil], + 65129 => [0, 0, nil, "$", nil, nil, nil], + 65130 => [0, 0, nil, "%", nil, nil, nil], + 65131 => [0, 0, nil, "@", nil, nil, nil], + 65136 => [0, 0, nil, " ً", nil, nil, nil], + 65137 => [0, 0, nil, "ـً", nil, nil, nil], + 65138 => [0, 0, nil, " ٌ", nil, nil, nil], + 65140 => [0, 0, nil, " ٍ", nil, nil, nil], + 65142 => [0, 0, nil, " َ", nil, nil, nil], + 65143 => [0, 0, nil, "ـَ", nil, nil, nil], + 65144 => [0, 0, nil, " ُ", nil, nil, nil], + 65145 => [0, 0, nil, "ـُ", nil, nil, nil], + 65146 => [0, 0, nil, " ِ", nil, nil, nil], + 65147 => [0, 0, nil, "ـِ", nil, nil, nil], + 65148 => [0, 0, nil, " ّ", nil, nil, nil], + 65149 => [0, 0, nil, "ـّ", nil, nil, nil], + 65150 => [0, 0, nil, " ْ", nil, nil, nil], + 65151 => [0, 0, nil, "ـْ", nil, nil, nil], + 65152 => [0, 0, nil, "ء", nil, nil, nil], + 65153 => [0, 0, nil, "آ", nil, nil, nil], + 65154 => [0, 0, nil, "آ", nil, nil, nil], + 65155 => [0, 0, nil, "أ", nil, nil, nil], + 65156 => [0, 0, nil, "أ", nil, nil, nil], + 65157 => [0, 0, nil, "ؤ", nil, nil, nil], + 65158 => [0, 0, nil, "ؤ", nil, nil, nil], + 65159 => [0, 0, nil, "إ", nil, nil, nil], + 65160 => [0, 0, nil, "إ", nil, nil, nil], + 65161 => [0, 0, nil, "ئ", nil, nil, nil], + 65162 => [0, 0, nil, "ئ", nil, nil, nil], + 65163 => [0, 0, nil, "ئ", nil, nil, nil], + 65164 => [0, 0, nil, "ئ", nil, nil, nil], + 65165 => [0, 0, nil, "ا", nil, nil, nil], + 65166 => [0, 0, nil, "ا", nil, nil, nil], + 65167 => [0, 0, nil, "ب", nil, nil, nil], + 65168 => [0, 0, nil, "ب", nil, nil, nil], + 65169 => [0, 0, nil, "ب", nil, nil, nil], + 65170 => [0, 0, nil, "ب", nil, nil, nil], + 65171 => [0, 0, nil, "ة", nil, nil, nil], + 65172 => [0, 0, nil, "ة", nil, nil, nil], + 65173 => [0, 0, nil, "ت", nil, nil, nil], + 65174 => [0, 0, nil, "ت", nil, nil, nil], + 65175 => [0, 0, nil, "ت", nil, nil, nil], + 65176 => [0, 0, nil, "ت", nil, nil, nil], + 65177 => [0, 0, nil, "ث", nil, nil, nil], + 65178 => [0, 0, nil, "ث", nil, nil, nil], + 65179 => [0, 0, nil, "ث", nil, nil, nil], + 65180 => [0, 0, nil, "ث", nil, nil, nil], + 65181 => [0, 0, nil, "ج", nil, nil, nil], + 65182 => [0, 0, nil, "ج", nil, nil, nil], + 65183 => [0, 0, nil, "ج", nil, nil, nil], + 65184 => [0, 0, nil, "ج", nil, nil, nil], + 65185 => [0, 0, nil, "ح", nil, nil, nil], + 65186 => [0, 0, nil, "ح", nil, nil, nil], + 65187 => [0, 0, nil, "ح", nil, nil, nil], + 65188 => [0, 0, nil, "ح", nil, nil, nil], + 65189 => [0, 0, nil, "خ", nil, nil, nil], + 65190 => [0, 0, nil, "خ", nil, nil, nil], + 65191 => [0, 0, nil, "خ", nil, nil, nil], + 65192 => [0, 0, nil, "خ", nil, nil, nil], + 65193 => [0, 0, nil, "د", nil, nil, nil], + 65194 => [0, 0, nil, "د", nil, nil, nil], + 65195 => [0, 0, nil, "ذ", nil, nil, nil], + 65196 => [0, 0, nil, "ذ", nil, nil, nil], + 65197 => [0, 0, nil, "ر", nil, nil, nil], + 65198 => [0, 0, nil, "ر", nil, nil, nil], + 65199 => [0, 0, nil, "ز", nil, nil, nil], + 65200 => [0, 0, nil, "ز", nil, nil, nil], + 65201 => [0, 0, nil, "س", nil, nil, nil], + 65202 => [0, 0, nil, "س", nil, nil, nil], + 65203 => [0, 0, nil, "س", nil, nil, nil], + 65204 => [0, 0, nil, "س", nil, nil, nil], + 65205 => [0, 0, nil, "ش", nil, nil, nil], + 65206 => [0, 0, nil, "ش", nil, nil, nil], + 65207 => [0, 0, nil, "ش", nil, nil, nil], + 65208 => [0, 0, nil, "ش", nil, nil, nil], + 65209 => [0, 0, nil, "ص", nil, nil, nil], + 65210 => [0, 0, nil, "ص", nil, nil, nil], + 65211 => [0, 0, nil, "ص", nil, nil, nil], + 65212 => [0, 0, nil, "ص", nil, nil, nil], + 65213 => [0, 0, nil, "ض", nil, nil, nil], + 65214 => [0, 0, nil, "ض", nil, nil, nil], + 65215 => [0, 0, nil, "ض", nil, nil, nil], + 65216 => [0, 0, nil, "ض", nil, nil, nil], + 65217 => [0, 0, nil, "ط", nil, nil, nil], + 65218 => [0, 0, nil, "ط", nil, nil, nil], + 65219 => [0, 0, nil, "ط", nil, nil, nil], + 65220 => [0, 0, nil, "ط", nil, nil, nil], + 65221 => [0, 0, nil, "ظ", nil, nil, nil], + 65222 => [0, 0, nil, "ظ", nil, nil, nil], + 65223 => [0, 0, nil, "ظ", nil, nil, nil], + 65224 => [0, 0, nil, "ظ", nil, nil, nil], + 65225 => [0, 0, nil, "ع", nil, nil, nil], + 65226 => [0, 0, nil, "ع", nil, nil, nil], + 65227 => [0, 0, nil, "ع", nil, nil, nil], + 65228 => [0, 0, nil, "ع", nil, nil, nil], + 65229 => [0, 0, nil, "غ", nil, nil, nil], + 65230 => [0, 0, nil, "غ", nil, nil, nil], + 65231 => [0, 0, nil, "غ", nil, nil, nil], + 65232 => [0, 0, nil, "غ", nil, nil, nil], + 65233 => [0, 0, nil, "ف", nil, nil, nil], + 65234 => [0, 0, nil, "ف", nil, nil, nil], + 65235 => [0, 0, nil, "ف", nil, nil, nil], + 65236 => [0, 0, nil, "ف", nil, nil, nil], + 65237 => [0, 0, nil, "ق", nil, nil, nil], + 65238 => [0, 0, nil, "ق", nil, nil, nil], + 65239 => [0, 0, nil, "ق", nil, nil, nil], + 65240 => [0, 0, nil, "ق", nil, nil, nil], + 65241 => [0, 0, nil, "ك", nil, nil, nil], + 65242 => [0, 0, nil, "ك", nil, nil, nil], + 65243 => [0, 0, nil, "ك", nil, nil, nil], + 65244 => [0, 0, nil, "ك", nil, nil, nil], + 65245 => [0, 0, nil, "ل", nil, nil, nil], + 65246 => [0, 0, nil, "ل", nil, nil, nil], + 65247 => [0, 0, nil, "ل", nil, nil, nil], + 65248 => [0, 0, nil, "ل", nil, nil, nil], + 65249 => [0, 0, nil, "م", nil, nil, nil], + 65250 => [0, 0, nil, "م", nil, nil, nil], + 65251 => [0, 0, nil, "م", nil, nil, nil], + 65252 => [0, 0, nil, "م", nil, nil, nil], + 65253 => [0, 0, nil, "ن", nil, nil, nil], + 65254 => [0, 0, nil, "ن", nil, nil, nil], + 65255 => [0, 0, nil, "ن", nil, nil, nil], + 65256 => [0, 0, nil, "ن", nil, nil, nil], + 65257 => [0, 0, nil, "ه", nil, nil, nil], + 65258 => [0, 0, nil, "ه", nil, nil, nil], + 65259 => [0, 0, nil, "ه", nil, nil, nil], + 65260 => [0, 0, nil, "ه", nil, nil, nil], + 65261 => [0, 0, nil, "و", nil, nil, nil], + 65262 => [0, 0, nil, "و", nil, nil, nil], + 65263 => [0, 0, nil, "ى", nil, nil, nil], + 65264 => [0, 0, nil, "ى", nil, nil, nil], + 65265 => [0, 0, nil, "ي", nil, nil, nil], + 65266 => [0, 0, nil, "ي", nil, nil, nil], + 65267 => [0, 0, nil, "ي", nil, nil, nil], + 65268 => [0, 0, nil, "ي", nil, nil, nil], + 65269 => [0, 0, nil, "لآ", nil, nil, nil], + 65270 => [0, 0, nil, "لآ", nil, nil, nil], + 65271 => [0, 0, nil, "لأ", nil, nil, nil], + 65272 => [0, 0, nil, "لأ", nil, nil, nil], + 65273 => [0, 0, nil, "لإ", nil, nil, nil], + 65274 => [0, 0, nil, "لإ", nil, nil, nil], + 65275 => [0, 0, nil, "لا", nil, nil, nil], + 65276 => [0, 0, nil, "لا", nil, nil, nil], + 65281 => [0, 0, nil, "!", nil, nil, nil], + 65282 => [0, 0, nil, "\"", nil, nil, nil], + 65283 => [0, 0, nil, "#", nil, nil, nil], + 65284 => [0, 0, nil, "$", nil, nil, nil], + 65285 => [0, 0, nil, "%", nil, nil, nil], + 65286 => [0, 0, nil, "&", nil, nil, nil], + 65287 => [0, 0, nil, "'", nil, nil, nil], + 65288 => [0, 0, nil, "(", nil, nil, nil], + 65289 => [0, 0, nil, ")", nil, nil, nil], + 65290 => [0, 0, nil, "*", nil, nil, nil], + 65291 => [0, 0, nil, "+", nil, nil, nil], + 65292 => [0, 0, nil, ",", nil, nil, nil], + 65293 => [0, 0, nil, "-", nil, nil, nil], + 65294 => [0, 0, nil, ".", nil, nil, nil], + 65295 => [0, 0, nil, "/", nil, nil, nil], + 65296 => [0, 0, nil, "0", nil, nil, nil], + 65297 => [0, 0, nil, "1", nil, nil, nil], + 65298 => [0, 0, nil, "2", nil, nil, nil], + 65299 => [0, 0, nil, "3", nil, nil, nil], + 65300 => [0, 0, nil, "4", nil, nil, nil], + 65301 => [0, 0, nil, "5", nil, nil, nil], + 65302 => [0, 0, nil, "6", nil, nil, nil], + 65303 => [0, 0, nil, "7", nil, nil, nil], + 65304 => [0, 0, nil, "8", nil, nil, nil], + 65305 => [0, 0, nil, "9", nil, nil, nil], + 65306 => [0, 0, nil, ":", nil, nil, nil], + 65307 => [0, 0, nil, ";", nil, nil, nil], + 65308 => [0, 0, nil, "<", nil, nil, nil], + 65309 => [0, 0, nil, "=", nil, nil, nil], + 65310 => [0, 0, nil, ">", nil, nil, nil], + 65311 => [0, 0, nil, "?", nil, nil, nil], + 65312 => [0, 0, nil, "@", nil, nil, nil], + 65313 => [0, 0, nil, "A", nil, 65345, nil], + 65314 => [0, 0, nil, "B", nil, 65346, nil], + 65315 => [0, 0, nil, "C", nil, 65347, nil], + 65316 => [0, 0, nil, "D", nil, 65348, nil], + 65317 => [0, 0, nil, "E", nil, 65349, nil], + 65318 => [0, 0, nil, "F", nil, 65350, nil], + 65319 => [0, 0, nil, "G", nil, 65351, nil], + 65320 => [0, 0, nil, "H", nil, 65352, nil], + 65321 => [0, 0, nil, "I", nil, 65353, nil], + 65322 => [0, 0, nil, "J", nil, 65354, nil], + 65323 => [0, 0, nil, "K", nil, 65355, nil], + 65324 => [0, 0, nil, "L", nil, 65356, nil], + 65325 => [0, 0, nil, "M", nil, 65357, nil], + 65326 => [0, 0, nil, "N", nil, 65358, nil], + 65327 => [0, 0, nil, "O", nil, 65359, nil], + 65328 => [0, 0, nil, "P", nil, 65360, nil], + 65329 => [0, 0, nil, "Q", nil, 65361, nil], + 65330 => [0, 0, nil, "R", nil, 65362, nil], + 65331 => [0, 0, nil, "S", nil, 65363, nil], + 65332 => [0, 0, nil, "T", nil, 65364, nil], + 65333 => [0, 0, nil, "U", nil, 65365, nil], + 65334 => [0, 0, nil, "V", nil, 65366, nil], + 65335 => [0, 0, nil, "W", nil, 65367, nil], + 65336 => [0, 0, nil, "X", nil, 65368, nil], + 65337 => [0, 0, nil, "Y", nil, 65369, nil], + 65338 => [0, 0, nil, "Z", nil, 65370, nil], + 65339 => [0, 0, nil, "[", nil, nil, nil], + 65340 => [0, 0, nil, "\\", nil, nil, nil], + 65341 => [0, 0, nil, "]", nil, nil, nil], + 65342 => [0, 0, nil, "^", nil, nil, nil], + 65343 => [0, 0, nil, "_", nil, nil, nil], + 65344 => [0, 0, nil, "`", nil, nil, nil], + 65345 => [0, 0, nil, "a", 65313, nil, 65313], + 65346 => [0, 0, nil, "b", 65314, nil, 65314], + 65347 => [0, 0, nil, "c", 65315, nil, 65315], + 65348 => [0, 0, nil, "d", 65316, nil, 65316], + 65349 => [0, 0, nil, "e", 65317, nil, 65317], + 65350 => [0, 0, nil, "f", 65318, nil, 65318], + 65351 => [0, 0, nil, "g", 65319, nil, 65319], + 65352 => [0, 0, nil, "h", 65320, nil, 65320], + 65353 => [0, 0, nil, "i", 65321, nil, 65321], + 65354 => [0, 0, nil, "j", 65322, nil, 65322], + 65355 => [0, 0, nil, "k", 65323, nil, 65323], + 65356 => [0, 0, nil, "l", 65324, nil, 65324], + 65357 => [0, 0, nil, "m", 65325, nil, 65325], + 65358 => [0, 0, nil, "n", 65326, nil, 65326], + 65359 => [0, 0, nil, "o", 65327, nil, 65327], + 65360 => [0, 0, nil, "p", 65328, nil, 65328], + 65361 => [0, 0, nil, "q", 65329, nil, 65329], + 65362 => [0, 0, nil, "r", 65330, nil, 65330], + 65363 => [0, 0, nil, "s", 65331, nil, 65331], + 65364 => [0, 0, nil, "t", 65332, nil, 65332], + 65365 => [0, 0, nil, "u", 65333, nil, 65333], + 65366 => [0, 0, nil, "v", 65334, nil, 65334], + 65367 => [0, 0, nil, "w", 65335, nil, 65335], + 65368 => [0, 0, nil, "x", 65336, nil, 65336], + 65369 => [0, 0, nil, "y", 65337, nil, 65337], + 65370 => [0, 0, nil, "z", 65338, nil, 65338], + 65371 => [0, 0, nil, "{", nil, nil, nil], + 65372 => [0, 0, nil, "|", nil, nil, nil], + 65373 => [0, 0, nil, "}", nil, nil, nil], + 65374 => [0, 0, nil, "~", nil, nil, nil], + 65377 => [0, 0, nil, "。", nil, nil, nil], + 65378 => [0, 0, nil, "「", nil, nil, nil], + 65379 => [0, 0, nil, "」", nil, nil, nil], + 65380 => [0, 0, nil, "、", nil, nil, nil], + 65381 => [0, 0, nil, "・", nil, nil, nil], + 65382 => [0, 0, nil, "ヲ", nil, nil, nil], + 65383 => [0, 0, nil, "ァ", nil, nil, nil], + 65384 => [0, 0, nil, "ィ", nil, nil, nil], + 65385 => [0, 0, nil, "ゥ", nil, nil, nil], + 65386 => [0, 0, nil, "ェ", nil, nil, nil], + 65387 => [0, 0, nil, "ォ", nil, nil, nil], + 65388 => [0, 0, nil, "ャ", nil, nil, nil], + 65389 => [0, 0, nil, "ュ", nil, nil, nil], + 65390 => [0, 0, nil, "ョ", nil, nil, nil], + 65391 => [0, 0, nil, "ッ", nil, nil, nil], + 65392 => [0, 0, nil, "ー", nil, nil, nil], + 65393 => [0, 0, nil, "ア", nil, nil, nil], + 65394 => [0, 0, nil, "イ", nil, nil, nil], + 65395 => [0, 0, nil, "ウ", nil, nil, nil], + 65396 => [0, 0, nil, "エ", nil, nil, nil], + 65397 => [0, 0, nil, "オ", nil, nil, nil], + 65398 => [0, 0, nil, "カ", nil, nil, nil], + 65399 => [0, 0, nil, "キ", nil, nil, nil], + 65400 => [0, 0, nil, "ク", nil, nil, nil], + 65401 => [0, 0, nil, "ケ", nil, nil, nil], + 65402 => [0, 0, nil, "コ", nil, nil, nil], + 65403 => [0, 0, nil, "サ", nil, nil, nil], + 65404 => [0, 0, nil, "シ", nil, nil, nil], + 65405 => [0, 0, nil, "ス", nil, nil, nil], + 65406 => [0, 0, nil, "セ", nil, nil, nil], + 65407 => [0, 0, nil, "ソ", nil, nil, nil], + 65408 => [0, 0, nil, "タ", nil, nil, nil], + 65409 => [0, 0, nil, "チ", nil, nil, nil], + 65410 => [0, 0, nil, "ツ", nil, nil, nil], + 65411 => [0, 0, nil, "テ", nil, nil, nil], + 65412 => [0, 0, nil, "ト", nil, nil, nil], + 65413 => [0, 0, nil, "ナ", nil, nil, nil], + 65414 => [0, 0, nil, "ニ", nil, nil, nil], + 65415 => [0, 0, nil, "ヌ", nil, nil, nil], + 65416 => [0, 0, nil, "ネ", nil, nil, nil], + 65417 => [0, 0, nil, "ノ", nil, nil, nil], + 65418 => [0, 0, nil, "ハ", nil, nil, nil], + 65419 => [0, 0, nil, "ヒ", nil, nil, nil], + 65420 => [0, 0, nil, "フ", nil, nil, nil], + 65421 => [0, 0, nil, "ヘ", nil, nil, nil], + 65422 => [0, 0, nil, "ホ", nil, nil, nil], + 65423 => [0, 0, nil, "マ", nil, nil, nil], + 65424 => [0, 0, nil, "ミ", nil, nil, nil], + 65425 => [0, 0, nil, "ム", nil, nil, nil], + 65426 => [0, 0, nil, "メ", nil, nil, nil], + 65427 => [0, 0, nil, "モ", nil, nil, nil], + 65428 => [0, 0, nil, "ヤ", nil, nil, nil], + 65429 => [0, 0, nil, "ユ", nil, nil, nil], + 65430 => [0, 0, nil, "ヨ", nil, nil, nil], + 65431 => [0, 0, nil, "ラ", nil, nil, nil], + 65432 => [0, 0, nil, "リ", nil, nil, nil], + 65433 => [0, 0, nil, "ル", nil, nil, nil], + 65434 => [0, 0, nil, "レ", nil, nil, nil], + 65435 => [0, 0, nil, "ロ", nil, nil, nil], + 65436 => [0, 0, nil, "ワ", nil, nil, nil], + 65437 => [0, 0, nil, "ン", nil, nil, nil], + 65438 => [0, 0, nil, "゙", nil, nil, nil], + 65439 => [0, 0, nil, "゚", nil, nil, nil], + 65440 => [0, 0, nil, "ㅤ", nil, nil, nil], + 65441 => [0, 0, nil, "ㄱ", nil, nil, nil], + 65442 => [0, 0, nil, "ㄲ", nil, nil, nil], + 65443 => [0, 0, nil, "ㄳ", nil, nil, nil], + 65444 => [0, 0, nil, "ㄴ", nil, nil, nil], + 65445 => [0, 0, nil, "ㄵ", nil, nil, nil], + 65446 => [0, 0, nil, "ㄶ", nil, nil, nil], + 65447 => [0, 0, nil, "ㄷ", nil, nil, nil], + 65448 => [0, 0, nil, "ㄸ", nil, nil, nil], + 65449 => [0, 0, nil, "ㄹ", nil, nil, nil], + 65450 => [0, 0, nil, "ㄺ", nil, nil, nil], + 65451 => [0, 0, nil, "ㄻ", nil, nil, nil], + 65452 => [0, 0, nil, "ㄼ", nil, nil, nil], + 65453 => [0, 0, nil, "ㄽ", nil, nil, nil], + 65454 => [0, 0, nil, "ㄾ", nil, nil, nil], + 65455 => [0, 0, nil, "ㄿ", nil, nil, nil], + 65456 => [0, 0, nil, "ㅀ", nil, nil, nil], + 65457 => [0, 0, nil, "ㅁ", nil, nil, nil], + 65458 => [0, 0, nil, "ㅂ", nil, nil, nil], + 65459 => [0, 0, nil, "ㅃ", nil, nil, nil], + 65460 => [0, 0, nil, "ㅄ", nil, nil, nil], + 65461 => [0, 0, nil, "ㅅ", nil, nil, nil], + 65462 => [0, 0, nil, "ㅆ", nil, nil, nil], + 65463 => [0, 0, nil, "ㅇ", nil, nil, nil], + 65464 => [0, 0, nil, "ㅈ", nil, nil, nil], + 65465 => [0, 0, nil, "ㅉ", nil, nil, nil], + 65466 => [0, 0, nil, "ㅊ", nil, nil, nil], + 65467 => [0, 0, nil, "ㅋ", nil, nil, nil], + 65468 => [0, 0, nil, "ㅌ", nil, nil, nil], + 65469 => [0, 0, nil, "ㅍ", nil, nil, nil], + 65470 => [0, 0, nil, "ㅎ", nil, nil, nil], + 65474 => [0, 0, nil, "ㅏ", nil, nil, nil], + 65475 => [0, 0, nil, "ㅐ", nil, nil, nil], + 65476 => [0, 0, nil, "ㅑ", nil, nil, nil], + 65477 => [0, 0, nil, "ㅒ", nil, nil, nil], + 65478 => [0, 0, nil, "ㅓ", nil, nil, nil], + 65479 => [0, 0, nil, "ㅔ", nil, nil, nil], + 65482 => [0, 0, nil, "ㅕ", nil, nil, nil], + 65483 => [0, 0, nil, "ㅖ", nil, nil, nil], + 65484 => [0, 0, nil, "ㅗ", nil, nil, nil], + 65485 => [0, 0, nil, "ㅘ", nil, nil, nil], + 65486 => [0, 0, nil, "ㅙ", nil, nil, nil], + 65487 => [0, 0, nil, "ㅚ", nil, nil, nil], + 65490 => [0, 0, nil, "ㅛ", nil, nil, nil], + 65491 => [0, 0, nil, "ㅜ", nil, nil, nil], + 65492 => [0, 0, nil, "ㅝ", nil, nil, nil], + 65493 => [0, 0, nil, "ㅞ", nil, nil, nil], + 65494 => [0, 0, nil, "ㅟ", nil, nil, nil], + 65495 => [0, 0, nil, "ㅠ", nil, nil, nil], + 65498 => [0, 0, nil, "ㅡ", nil, nil, nil], + 65499 => [0, 0, nil, "ㅢ", nil, nil, nil], + 65500 => [0, 0, nil, "ㅣ", nil, nil, nil], + 65504 => [0, 0, nil, "¢", nil, nil, nil], + 65505 => [0, 0, nil, "£", nil, nil, nil], + 65506 => [0, 0, nil, "¬", nil, nil, nil], + 65507 => [0, 0, nil, "¯", nil, nil, nil], + 65508 => [0, 0, nil, "¦", nil, nil, nil], + 65509 => [0, 0, nil, "¥", nil, nil, nil], + 65510 => [0, 0, nil, "₩", nil, nil, nil], + 65512 => [0, 0, nil, "│", nil, nil, nil], + 65513 => [0, 0, nil, "←", nil, nil, nil], + 65514 => [0, 0, nil, "↑", nil, nil, nil], + 65515 => [0, 0, nil, "→", nil, nil, nil], + 65516 => [0, 0, nil, "↓", nil, nil, nil], + 65517 => [0, 0, nil, "■", nil, nil, nil], + 65518 => [0, 0, nil, "○", nil, nil, nil], + } + + UNICODE_MAX_LENGTH = 256 + ACE_MAX_LENGTH = 256 + + PUNYCODE_BASE = 36 + PUNYCODE_TMIN = 1 + PUNYCODE_TMAX = 26 + PUNYCODE_SKEW = 38 + PUNYCODE_DAMP = 700 + PUNYCODE_INITIAL_BIAS = 72 + PUNYCODE_INITIAL_N = 0x80 + PUNYCODE_DELIMITER = 0x2D + + PUNYCODE_MAXINT = 1 << 64 + + PUNYCODE_PRINT_ASCII = + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + + " !\"\#$%&'()*+,-./" + + "0123456789:;<=>?" + + "@ABCDEFGHIJKLMNO" + + "PQRSTUVWXYZ[\\]^_" + + "`abcdefghijklmno" + + "pqrstuvwxyz{|}~\n" + + # Input is invalid. + class PunycodeBadInput < StandardError; end + # Output would exceed the space provided. + class PunycodeBigOutput < StandardError; end + # Input needs wider integers to process. + class PunycodeOverflow < StandardError; end + + def self.punycode_encode(unicode) + unicode = unicode.to_s unless unicode.is_a?(String) + input = unicode.unpack("U*") + output = [0] * (ACE_MAX_LENGTH + 1) + input_length = input.size + output_length = [ACE_MAX_LENGTH] + + # Initialize the state + n = PUNYCODE_INITIAL_N + delta = out = 0 + max_out = output_length[0] + bias = PUNYCODE_INITIAL_BIAS + + # Handle the basic code points: + input_length.times do |j| + if punycode_basic?(input[j]) + if max_out - out < 2 + raise PunycodeBigOutput, + "Output would exceed the space provided." + end + output[out] = input[j] + out += 1 + end + end + + h = b = out + + # h is the number of code points that have been handled, b is the + # number of basic code points, and out is the number of characters + # that have been output. + + if b > 0 + output[out] = PUNYCODE_DELIMITER + out += 1 + end + + # Main encoding loop: + + while h < input_length + # All non-basic code points < n have been + # handled already. Find the next larger one: + + m = PUNYCODE_MAXINT + input_length.times do |j| + m = input[j] if (n...m) === input[j] + end + + # Increase delta enough to advance the decoder's + # state to , but guard against overflow: + + if m - n > (PUNYCODE_MAXINT - delta) / (h + 1) + raise PunycodeOverflow, "Input needs wider integers to process." + end + delta += (m - n) * (h + 1) + n = m + + input_length.times do |j| + # Punycode does not need to check whether input[j] is basic: + if input[j] < n + delta += 1 + if delta == 0 + raise PunycodeOverflow, + "Input needs wider integers to process." + end + end + + if input[j] == n + # Represent delta as a generalized variable-length integer: + + q = delta; k = PUNYCODE_BASE + while true + if out >= max_out + raise PunycodeBigOutput, + "Output would exceed the space provided." + end + t = ( + if k <= bias + PUNYCODE_TMIN + elsif k >= bias + PUNYCODE_TMAX + PUNYCODE_TMAX + else + k - bias + end + ) + break if q < t + output[out] = + punycode_encode_digit(t + (q - t) % (PUNYCODE_BASE - t)) + out += 1 + q = (q - t) / (PUNYCODE_BASE - t) + k += PUNYCODE_BASE + end + + output[out] = punycode_encode_digit(q) + out += 1 + bias = punycode_adapt(delta, h + 1, h == b) + delta = 0 + h += 1 + end + end + + delta += 1 + n += 1 + end + + output_length[0] = out + + outlen = out + outlen.times do |j| + c = output[j] + unless c >= 0 && c <= 127 + raise StandardError, "Invalid output char." + end + unless PUNYCODE_PRINT_ASCII[c] + raise PunycodeBadInput, "Input is invalid." + end + end + + output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "") + end + private_class_method :punycode_encode + + def self.punycode_decode(punycode) + input = [] + output = [] + + if ACE_MAX_LENGTH * 2 < punycode.size + raise PunycodeBigOutput, "Output would exceed the space provided." + end + punycode.each_byte do |c| + unless c >= 0 && c <= 127 + raise PunycodeBadInput, "Input is invalid." + end + input.push(c) + end + + input_length = input.length + output_length = [UNICODE_MAX_LENGTH] + + # Initialize the state + n = PUNYCODE_INITIAL_N + + out = i = 0 + max_out = output_length[0] + bias = PUNYCODE_INITIAL_BIAS + + # Handle the basic code points: Let b be the number of input code + # points before the last delimiter, or 0 if there is none, then + # copy the first b code points to the output. + + b = 0 + input_length.times do |j| + b = j if punycode_delimiter?(input[j]) + end + if b > max_out + raise PunycodeBigOutput, "Output would exceed the space provided." + end + + b.times do |j| + unless punycode_basic?(input[j]) + raise PunycodeBadInput, "Input is invalid." + end + output[out] = input[j] + out+=1 + end + + # Main decoding loop: Start just after the last delimiter if any + # basic code points were copied; start at the beginning otherwise. + + in_ = b > 0 ? b + 1 : 0 + while in_ < input_length + + # in_ is the index of the next character to be consumed, and + # out is the number of code points in the output array. + + # Decode a generalized variable-length integer into delta, + # which gets added to i. The overflow checking is easier + # if we increase i as we go, then subtract off its starting + # value at the end to obtain delta. + + oldi = i; w = 1; k = PUNYCODE_BASE + while true + if in_ >= input_length + raise PunycodeBadInput, "Input is invalid." + end + digit = punycode_decode_digit(input[in_]) + in_+=1 + if digit >= PUNYCODE_BASE + raise PunycodeBadInput, "Input is invalid." + end + if digit > (PUNYCODE_MAXINT - i) / w + raise PunycodeOverflow, "Input needs wider integers to process." + end + i += digit * w + t = ( + if k <= bias + PUNYCODE_TMIN + elsif k >= bias + PUNYCODE_TMAX + PUNYCODE_TMAX + else + k - bias + end + ) + break if digit < t + if w > PUNYCODE_MAXINT / (PUNYCODE_BASE - t) + raise PunycodeOverflow, "Input needs wider integers to process." + end + w *= PUNYCODE_BASE - t + k += PUNYCODE_BASE + end + + bias = punycode_adapt(i - oldi, out + 1, oldi == 0) + + # I was supposed to wrap around from out + 1 to 0, + # incrementing n each time, so we'll fix that now: + + if i / (out + 1) > PUNYCODE_MAXINT - n + raise PunycodeOverflow, "Input needs wider integers to process." + end + n += i / (out + 1) + i %= out + 1 + + # Insert n at position i of the output: + + # not needed for Punycode: + # raise PUNYCODE_INVALID_INPUT if decode_digit(n) <= base + if out >= max_out + raise PunycodeBigOutput, "Output would exceed the space provided." + end + + #memmove(output + i + 1, output + i, (out - i) * sizeof *output) + output[i + 1, out - i] = output[i, out - i] + output[i] = n + i += 1 + + out += 1 + end + + output_length[0] = out + + output.pack("U*") + end + private_class_method :punycode_decode + + def self.punycode_basic?(codepoint) + codepoint < 0x80 + end + private_class_method :punycode_basic? + + def self.punycode_delimiter?(codepoint) + codepoint == PUNYCODE_DELIMITER + end + private_class_method :punycode_delimiter? + + def self.punycode_encode_digit(d) + d + 22 + 75 * ((d < 26) ? 1 : 0) + end + private_class_method :punycode_encode_digit + + # Returns the numeric value of a basic codepoint + # (for use in representing integers) in the range 0 to + # base - 1, or PUNYCODE_BASE if codepoint does not represent a value. + def self.punycode_decode_digit(codepoint) + if codepoint - 48 < 10 + codepoint - 22 + elsif codepoint - 65 < 26 + codepoint - 65 + elsif codepoint - 97 < 26 + codepoint - 97 + else + PUNYCODE_BASE + end + end + private_class_method :punycode_decode_digit + + # Bias adaptation method + def self.punycode_adapt(delta, numpoints, firsttime) + delta = firsttime ? delta / PUNYCODE_DAMP : delta >> 1 + # delta >> 1 is a faster way of doing delta / 2 + delta += delta / numpoints + difference = PUNYCODE_BASE - PUNYCODE_TMIN + + k = 0 + while delta > (difference * PUNYCODE_TMAX) / 2 + delta /= difference + k += PUNYCODE_BASE + end + + k + (difference + 1) * delta / (delta + PUNYCODE_SKEW) + end + private_class_method :punycode_adapt + end + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/template.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/template.rb new file mode 100644 index 0000000..cb39028 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/template.rb @@ -0,0 +1,1040 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +require "addressable/version" +require "addressable/uri" + +module Addressable + ## + # This is an implementation of a URI template based on + # RFC 6570 (http://tools.ietf.org/html/rfc6570). + class Template + # Constants used throughout the template code. + anything = + Addressable::URI::CharacterClasses::RESERVED + + Addressable::URI::CharacterClasses::UNRESERVED + + + variable_char_class = + Addressable::URI::CharacterClasses::ALPHA + + Addressable::URI::CharacterClasses::DIGIT + '_' + + var_char = + "(?>(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)" + RESERVED = + "(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])" + RESERVED_NO_COMMA = + "(?:[#{anything.delete(',')}]|%[a-fA-F0-9][a-fA-F0-9])" + UNRESERVED = + "(?:[#{ + Addressable::URI::CharacterClasses::UNRESERVED + }]|%[a-fA-F0-9][a-fA-F0-9])" + variable = + "(?:#{var_char}(?:\\.?#{var_char})*)" + varspec = + "(?:(#{variable})(\\*|:\\d+)?)" + VARNAME = + /^#{variable}$/ + VARSPEC = + /^#{varspec}$/ + VARIABLE_LIST = + /^#{varspec}(?:,#{varspec})*$/ + operator = + "+#./;?&=,!@|" + EXPRESSION = + /\{([#{operator}])?(#{varspec}(?:,#{varspec})*)\}/ + + + LEADERS = { + '?' => '?', + '/' => '/', + '#' => '#', + '.' => '.', + ';' => ';', + '&' => '&' + } + JOINERS = { + '?' => '&', + '.' => '.', + ';' => ';', + '&' => '&', + '/' => '/' + } + + ## + # Raised if an invalid template value is supplied. + class InvalidTemplateValueError < StandardError + end + + ## + # Raised if an invalid template operator is used in a pattern. + class InvalidTemplateOperatorError < StandardError + end + + ## + # Raised if an invalid template operator is used in a pattern. + class TemplateOperatorAbortedError < StandardError + end + + ## + # This class represents the data that is extracted when a Template + # is matched against a URI. + class MatchData + ## + # Creates a new MatchData object. + # MatchData objects should never be instantiated directly. + # + # @param [Addressable::URI] uri + # The URI that the template was matched against. + def initialize(uri, template, mapping) + @uri = uri.dup.freeze + @template = template + @mapping = mapping.dup.freeze + end + + ## + # @return [Addressable::URI] + # The URI that the Template was matched against. + attr_reader :uri + + ## + # @return [Addressable::Template] + # The Template used for the match. + attr_reader :template + + ## + # @return [Hash] + # The mapping that resulted from the match. + # Note that this mapping does not include keys or values for + # variables that appear in the Template, but are not present + # in the URI. + attr_reader :mapping + + ## + # @return [Array] + # The list of variables that were present in the Template. + # Note that this list will include variables which do not appear + # in the mapping because they were not present in URI. + def variables + self.template.variables + end + alias_method :keys, :variables + alias_method :names, :variables + + ## + # @return [Array] + # The list of values that were captured by the Template. + # Note that this list will include nils for any variables which + # were in the Template, but did not appear in the URI. + def values + @values ||= self.variables.inject([]) do |accu, key| + accu << self.mapping[key] + accu + end + end + alias_method :captures, :values + + ## + # Accesses captured values by name or by index. + # + # @param [String, Symbol, Fixnum] key + # Capture index or name. Note that when accessing by with index + # of 0, the full URI will be returned. The intention is to mimic + # the ::MatchData#[] behavior. + # + # @param [#to_int, nil] len + # If provided, an array of values will be returned with the given + # parameter used as length. + # + # @return [Array, String, nil] + # The captured value corresponding to the index or name. If the + # value was not provided or the key is unknown, nil will be + # returned. + # + # If the second parameter is provided, an array of that length will + # be returned instead. + def [](key, len = nil) + if len + to_a[key, len] + elsif String === key or Symbol === key + mapping[key.to_s] + else + to_a[key] + end + end + + ## + # @return [Array] + # Array with the matched URI as first element followed by the captured + # values. + def to_a + [to_s, *values] + end + + ## + # @return [String] + # The matched URI as String. + def to_s + uri.to_s + end + alias_method :string, :to_s + + # Returns multiple captured values at once. + # + # @param [String, Symbol, Fixnum] *indexes + # Indices of the captures to be returned + # + # @return [Array] + # Values corresponding to given indices. + # + # @see Addressable::Template::MatchData#[] + def values_at(*indexes) + indexes.map { |i| self[i] } + end + + ## + # Returns a String representation of the MatchData's state. + # + # @return [String] The MatchData's state, as a String. + def inspect + sprintf("#<%s:%#0x RESULT:%s>", + self.class.to_s, self.object_id, self.mapping.inspect) + end + + ## + # Dummy method for code expecting a ::MatchData instance + # + # @return [String] An empty string. + def pre_match + "" + end + alias_method :post_match, :pre_match + end + + ## + # Creates a new Addressable::Template object. + # + # @param [#to_str] pattern The URI Template pattern. + # + # @return [Addressable::Template] The initialized Template object. + def initialize(pattern) + if !pattern.respond_to?(:to_str) + raise TypeError, "Can't convert #{pattern.class} into String." + end + @pattern = pattern.to_str.dup.freeze + end + + ## + # Freeze URI, initializing instance variables. + # + # @return [Addressable::URI] The frozen URI object. + def freeze + self.variables + self.variable_defaults + self.named_captures + super + end + + ## + # @return [String] The Template object's pattern. + attr_reader :pattern + + ## + # Returns a String representation of the Template object's state. + # + # @return [String] The Template object's state, as a String. + def inspect + sprintf("#<%s:%#0x PATTERN:%s>", + self.class.to_s, self.object_id, self.pattern) + end + + ## + # Returns true if the Template objects are equal. This method + # does NOT normalize either Template before doing the comparison. + # + # @param [Object] template The Template to compare. + # + # @return [TrueClass, FalseClass] + # true if the Templates are equivalent, false + # otherwise. + def ==(template) + return false unless template.kind_of?(Template) + return self.pattern == template.pattern + end + + ## + # Addressable::Template makes no distinction between `==` and `eql?`. + # + # @see #== + alias_method :eql?, :== + + ## + # Extracts a mapping from the URI using a URI Template pattern. + # + # @param [Addressable::URI, #to_str] uri + # The URI to extract from. + # + # @param [#restore, #match] processor + # A template processor object may optionally be supplied. + # + # The object should respond to either the restore or + # match messages or both. The restore method should + # take two parameters: `[String] name` and `[String] value`. + # The restore method should reverse any transformations that + # have been performed on the value to ensure a valid URI. + # The match method should take a single + # parameter: `[String] name`. The match method should return + # a String containing a regular expression capture group for + # matching on that particular variable. The default value is `".*?"`. + # The match method has no effect on multivariate operator + # expansions. + # + # @return [Hash, NilClass] + # The Hash mapping that was extracted from the URI, or + # nil if the URI didn't match the template. + # + # @example + # class ExampleProcessor + # def self.restore(name, value) + # return value.gsub(/\+/, " ") if name == "query" + # return value + # end + # + # def self.match(name) + # return ".*?" if name == "first" + # return ".*" + # end + # end + # + # uri = Addressable::URI.parse( + # "http://example.com/search/an+example+search+query/" + # ) + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).extract(uri, ExampleProcessor) + # #=> {"query" => "an example search query"} + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # Addressable::Template.new( + # "http://example.com/{first}/{second}/" + # ).extract(uri, ExampleProcessor) + # #=> {"first" => "a", "second" => "b/c"} + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # Addressable::Template.new( + # "http://example.com/{first}/{-list|/|second}/" + # ).extract(uri) + # #=> {"first" => "a", "second" => ["b", "c"]} + def extract(uri, processor=nil) + match_data = self.match(uri, processor) + return (match_data ? match_data.mapping : nil) + end + + ## + # Extracts match data from the URI using a URI Template pattern. + # + # @param [Addressable::URI, #to_str] uri + # The URI to extract from. + # + # @param [#restore, #match] processor + # A template processor object may optionally be supplied. + # + # The object should respond to either the restore or + # match messages or both. The restore method should + # take two parameters: `[String] name` and `[String] value`. + # The restore method should reverse any transformations that + # have been performed on the value to ensure a valid URI. + # The match method should take a single + # parameter: `[String] name`. The match method should return + # a String containing a regular expression capture group for + # matching on that particular variable. The default value is `".*?"`. + # The match method has no effect on multivariate operator + # expansions. + # + # @return [Hash, NilClass] + # The Hash mapping that was extracted from the URI, or + # nil if the URI didn't match the template. + # + # @example + # class ExampleProcessor + # def self.restore(name, value) + # return value.gsub(/\+/, " ") if name == "query" + # return value + # end + # + # def self.match(name) + # return ".*?" if name == "first" + # return ".*" + # end + # end + # + # uri = Addressable::URI.parse( + # "http://example.com/search/an+example+search+query/" + # ) + # match = Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).match(uri, ExampleProcessor) + # match.variables + # #=> ["query"] + # match.captures + # #=> ["an example search query"] + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # match = Addressable::Template.new( + # "http://example.com/{first}/{+second}/" + # ).match(uri, ExampleProcessor) + # match.variables + # #=> ["first", "second"] + # match.captures + # #=> ["a", "b/c"] + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # match = Addressable::Template.new( + # "http://example.com/{first}{/second*}/" + # ).match(uri) + # match.variables + # #=> ["first", "second"] + # match.captures + # #=> ["a", ["b", "c"]] + def match(uri, processor=nil) + uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI) + mapping = {} + + # First, we need to process the pattern, and extract the values. + expansions, expansion_regexp = + parse_template_pattern(pattern, processor) + + return nil unless uri.to_str.match(expansion_regexp) + unparsed_values = uri.to_str.scan(expansion_regexp).flatten + + if uri.to_str == pattern + return Addressable::Template::MatchData.new(uri, self, mapping) + elsif expansions.size > 0 + index = 0 + expansions.each do |expansion| + _, operator, varlist = *expansion.match(EXPRESSION) + varlist.split(',').each do |varspec| + _, name, modifier = *varspec.match(VARSPEC) + mapping[name] ||= nil + case operator + when nil, '+', '#', '/', '.' + unparsed_value = unparsed_values[index] + name = varspec[VARSPEC, 1] + value = unparsed_value + value = value.split(JOINERS[operator]) if value && modifier == '*' + when ';', '?', '&' + if modifier == '*' + if unparsed_values[index] + value = unparsed_values[index].split(JOINERS[operator]) + value = value.inject({}) do |acc, v| + key, val = v.split('=') + val = "" if val.nil? + acc[key] = val + acc + end + end + else + if (unparsed_values[index]) + name, value = unparsed_values[index].split('=') + value = "" if value.nil? + end + end + end + if processor != nil && processor.respond_to?(:restore) + value = processor.restore(name, value) + end + if processor == nil + if value.is_a?(Hash) + value = value.inject({}){|acc, (k, v)| + acc[Addressable::URI.unencode_component(k)] = + Addressable::URI.unencode_component(v) + acc + } + elsif value.is_a?(Array) + value = value.map{|v| Addressable::URI.unencode_component(v) } + else + value = Addressable::URI.unencode_component(value) + end + end + if !mapping.has_key?(name) || mapping[name].nil? + # Doesn't exist, set to value (even if value is nil) + mapping[name] = value + end + index = index + 1 + end + end + return Addressable::Template::MatchData.new(uri, self, mapping) + else + return nil + end + end + + ## + # Expands a URI template into another URI template. + # + # @param [Hash] mapping The mapping that corresponds to the pattern. + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError + # exception will be raised if the value is invalid. The transform + # method should return the transformed variable value as a String. + # If a transform method is used, the value will not be percent + # encoded automatically. Unicode normalization will be performed both + # before and after sending the value to the transform method. + # + # @return [Addressable::Template] The partially expanded URI template. + # + # @example + # Addressable::Template.new( + # "http://example.com/{one}/{two}/" + # ).partial_expand({"one" => "1"}).pattern + # #=> "http://example.com/1/{two}/" + # + # Addressable::Template.new( + # "http://example.com/{?one,two}/" + # ).partial_expand({"one" => "1"}).pattern + # #=> "http://example.com/?one=1{&two}/" + # + # Addressable::Template.new( + # "http://example.com/{?one,two,three}/" + # ).partial_expand({"one" => "1", "three" => 3}).pattern + # #=> "http://example.com/?one=1{&two}&three=3" + def partial_expand(mapping, processor=nil, normalize_values=true) + result = self.pattern.dup + mapping = normalize_keys(mapping) + result.gsub!( EXPRESSION ) do |capture| + transform_partial_capture(mapping, capture, processor, normalize_values) + end + return Addressable::Template.new(result) + end + + ## + # Expands a URI template into a full URI. + # + # @param [Hash] mapping The mapping that corresponds to the pattern. + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError + # exception will be raised if the value is invalid. The transform + # method should return the transformed variable value as a String. + # If a transform method is used, the value will not be percent + # encoded automatically. Unicode normalization will be performed both + # before and after sending the value to the transform method. + # + # @return [Addressable::URI] The expanded URI template. + # + # @example + # class ExampleProcessor + # def self.validate(name, value) + # return !!(value =~ /^[\w ]+$/) if name == "query" + # return true + # end + # + # def self.transform(name, value) + # return value.gsub(/ /, "+") if name == "query" + # return value + # end + # end + # + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).expand( + # {"query" => "an example search query"}, + # ExampleProcessor + # ).to_str + # #=> "http://example.com/search/an+example+search+query/" + # + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).expand( + # {"query" => "an example search query"} + # ).to_str + # #=> "http://example.com/search/an%20example%20search%20query/" + # + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).expand( + # {"query" => "bogus!"}, + # ExampleProcessor + # ).to_str + # #=> Addressable::Template::InvalidTemplateValueError + def expand(mapping, processor=nil, normalize_values=true) + result = self.pattern.dup + mapping = normalize_keys(mapping) + result.gsub!( EXPRESSION ) do |capture| + transform_capture(mapping, capture, processor, normalize_values) + end + return Addressable::URI.parse(result) + end + + ## + # Returns an Array of variables used within the template pattern. + # The variables are listed in the Array in the order they appear within + # the pattern. Multiple occurrences of a variable within a pattern are + # not represented in this Array. + # + # @return [Array] The variables present in the template's pattern. + def variables + @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq + end + alias_method :keys, :variables + alias_method :names, :variables + + ## + # Returns a mapping of variables to their default values specified + # in the template. Variables without defaults are not returned. + # + # @return [Hash] Mapping of template variables to their defaults + def variable_defaults + @variable_defaults ||= + Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten] + end + + ## + # Coerces a template into a `Regexp` object. This regular expression will + # behave very similarly to the actual template, and should match the same + # URI values, but it cannot fully handle, for example, values that would + # extract to an `Array`. + # + # @return [Regexp] A regular expression which should match the template. + def to_regexp + _, source = parse_template_pattern(pattern) + Regexp.new(source) + end + + ## + # Returns the source of the coerced `Regexp`. + # + # @return [String] The source of the `Regexp` given by {#to_regexp}. + # + # @api private + def source + self.to_regexp.source + end + + ## + # Returns the named captures of the coerced `Regexp`. + # + # @return [Hash] The named captures of the `Regexp` given by {#to_regexp}. + # + # @api private + def named_captures + self.to_regexp.named_captures + end + + private + def ordered_variable_defaults + @ordered_variable_defaults ||= begin + expansions, _ = parse_template_pattern(pattern) + expansions.flat_map do |capture| + _, _, varlist = *capture.match(EXPRESSION) + varlist.split(',').map do |varspec| + varspec[VARSPEC, 1] + end + end + end + end + + + ## + # Loops through each capture and expands any values available in mapping + # + # @param [Hash] mapping + # Set of keys to expand + # @param [String] capture + # The expression to expand + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError exception + # will be raised if the value is invalid. The transform method + # should return the transformed variable value as a String. If a + # transform method is used, the value will not be percent encoded + # automatically. Unicode normalization will be performed both before and + # after sending the value to the transform method. + # + # @return [String] The expanded expression + def transform_partial_capture(mapping, capture, processor = nil, + normalize_values = true) + _, operator, varlist = *capture.match(EXPRESSION) + + vars = varlist.split(",") + + if operator == "?" + # partial expansion of form style query variables sometimes requires a + # slight reordering of the variables to produce a valid url. + first_to_expand = vars.find { |varspec| + _, name, _ = *varspec.match(VARSPEC) + mapping.key?(name) && !mapping[name].nil? + } + + vars = [first_to_expand] + vars.reject {|varspec| varspec == first_to_expand} if first_to_expand + end + + vars. + inject("".dup) do |acc, varspec| + _, name, _ = *varspec.match(VARSPEC) + next_val = if mapping.key? name + transform_capture(mapping, "{#{operator}#{varspec}}", + processor, normalize_values) + else + "{#{operator}#{varspec}}" + end + # If we've already expanded at least one '?' operator with non-empty + # value, change to '&' + operator = "&" if (operator == "?") && (next_val != "") + acc << next_val + end + end + + ## + # Transforms a mapped value so that values can be substituted into the + # template. + # + # @param [Hash] mapping The mapping to replace captures + # @param [String] capture + # The expression to replace + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError exception + # will be raised if the value is invalid. The transform method + # should return the transformed variable value as a String. If a + # transform method is used, the value will not be percent encoded + # automatically. Unicode normalization will be performed both before and + # after sending the value to the transform method. + # + # @return [String] The expanded expression + def transform_capture(mapping, capture, processor=nil, + normalize_values=true) + _, operator, varlist = *capture.match(EXPRESSION) + return_value = varlist.split(',').inject([]) do |acc, varspec| + _, name, modifier = *varspec.match(VARSPEC) + value = mapping[name] + unless value == nil || value == {} + allow_reserved = %w(+ #).include?(operator) + # Common primitives where the .to_s output is well-defined + if Numeric === value || Symbol === value || + value == true || value == false + value = value.to_s + end + length = modifier.gsub(':', '').to_i if modifier =~ /^:\d+/ + + unless (Hash === value) || + value.respond_to?(:to_ary) || value.respond_to?(:to_str) + raise TypeError, + "Can't convert #{value.class} into String or Array." + end + + value = normalize_value(value) if normalize_values + + if processor == nil || !processor.respond_to?(:transform) + # Handle percent escaping + if allow_reserved + encode_map = + Addressable::URI::CharacterClasses::RESERVED + + Addressable::URI::CharacterClasses::UNRESERVED + else + encode_map = Addressable::URI::CharacterClasses::UNRESERVED + end + if value.kind_of?(Array) + transformed_value = value.map do |val| + if length + Addressable::URI.encode_component(val[0...length], encode_map) + else + Addressable::URI.encode_component(val, encode_map) + end + end + unless modifier == "*" + transformed_value = transformed_value.join(',') + end + elsif value.kind_of?(Hash) + transformed_value = value.map do |key, val| + if modifier == "*" + "#{ + Addressable::URI.encode_component( key, encode_map) + }=#{ + Addressable::URI.encode_component( val, encode_map) + }" + else + "#{ + Addressable::URI.encode_component( key, encode_map) + },#{ + Addressable::URI.encode_component( val, encode_map) + }" + end + end + unless modifier == "*" + transformed_value = transformed_value.join(',') + end + else + if length + transformed_value = Addressable::URI.encode_component( + value[0...length], encode_map) + else + transformed_value = Addressable::URI.encode_component( + value, encode_map) + end + end + end + + # Process, if we've got a processor + if processor != nil + if processor.respond_to?(:validate) + if !processor.validate(name, value) + display_value = value.kind_of?(Array) ? value.inspect : value + raise InvalidTemplateValueError, + "#{name}=#{display_value} is an invalid template value." + end + end + if processor.respond_to?(:transform) + transformed_value = processor.transform(name, value) + if normalize_values + transformed_value = normalize_value(transformed_value) + end + end + end + acc << [name, transformed_value] + end + acc + end + return "" if return_value.empty? + join_values(operator, return_value) + end + + ## + # Takes a set of values, and joins them together based on the + # operator. + # + # @param [String, Nil] operator One of the operators from the set + # (?,&,+,#,;,/,.), or nil if there wasn't one. + # @param [Array] return_value + # The set of return values (as [variable_name, value] tuples) that will + # be joined together. + # + # @return [String] The transformed mapped value + def join_values(operator, return_value) + leader = LEADERS.fetch(operator, '') + joiner = JOINERS.fetch(operator, ',') + case operator + when '&', '?' + leader + return_value.map{|k,v| + if v.is_a?(Array) && v.first =~ /=/ + v.join(joiner) + elsif v.is_a?(Array) + v.map{|inner_value| "#{k}=#{inner_value}"}.join(joiner) + else + "#{k}=#{v}" + end + }.join(joiner) + when ';' + return_value.map{|k,v| + if v.is_a?(Array) && v.first =~ /=/ + ';' + v.join(";") + elsif v.is_a?(Array) + ';' + v.map{|inner_value| "#{k}=#{inner_value}"}.join(";") + else + v && v != '' ? ";#{k}=#{v}" : ";#{k}" + end + }.join + else + leader + return_value.map{|k,v| v}.join(joiner) + end + end + + ## + # Takes a set of values, and joins them together based on the + # operator. + # + # @param [Hash, Array, String] value + # Normalizes unicode keys and values with String#unicode_normalize (NFC) + # + # @return [Hash, Array, String] The normalized values + def normalize_value(value) + # Handle unicode normalization + if value.respond_to?(:to_ary) + value.to_ary.map! { |val| normalize_value(val) } + elsif value.kind_of?(Hash) + value = value.inject({}) { |acc, (k, v)| + acc[normalize_value(k)] = normalize_value(v) + acc + } + else + value = value.to_s if !value.kind_of?(String) + if value.encoding != Encoding::UTF_8 + value = value.dup.force_encoding(Encoding::UTF_8) + end + value = value.unicode_normalize(:nfc) + end + value + end + + ## + # Generates a hash with string keys + # + # @param [Hash] mapping A mapping hash to normalize + # + # @return [Hash] + # A hash with stringified keys + def normalize_keys(mapping) + return mapping.inject({}) do |accu, pair| + name, value = pair + if Symbol === name + name = name.to_s + elsif name.respond_to?(:to_str) + name = name.to_str + else + raise TypeError, + "Can't convert #{name.class} into String." + end + accu[name] = value + accu + end + end + + ## + # Generates the Regexp that parses a template pattern. Memoizes the + # value if template processor not set (processors may not be deterministic) + # + # @param [String] pattern The URI template pattern. + # @param [#match] processor The template processor to use. + # + # @return [Array, Regexp] + # An array of expansion variables nad a regular expression which may be + # used to parse a template pattern + def parse_template_pattern(pattern, processor = nil) + if processor.nil? && pattern == @pattern + @cached_template_parse ||= + parse_new_template_pattern(pattern, processor) + else + parse_new_template_pattern(pattern, processor) + end + end + + ## + # Generates the Regexp that parses a template pattern. + # + # @param [String] pattern The URI template pattern. + # @param [#match] processor The template processor to use. + # + # @return [Array, Regexp] + # An array of expansion variables nad a regular expression which may be + # used to parse a template pattern + def parse_new_template_pattern(pattern, processor = nil) + # Escape the pattern. The two gsubs restore the escaped curly braces + # back to their original form. Basically, escape everything that isn't + # within an expansion. + escaped_pattern = Regexp.escape( + pattern + ).gsub(/\\\{(.*?)\\\}/) do |escaped| + escaped.gsub(/\\(.)/, "\\1") + end + + expansions = [] + + # Create a regular expression that captures the values of the + # variables in the URI. + regexp_string = escaped_pattern.gsub( EXPRESSION ) do |expansion| + + expansions << expansion + _, operator, varlist = *expansion.match(EXPRESSION) + leader = Regexp.escape(LEADERS.fetch(operator, '')) + joiner = Regexp.escape(JOINERS.fetch(operator, ',')) + varspecs = varlist.split(',') + combined = varspecs.map do |varspec| + _, name, modifier = *varspec.match(VARSPEC) + + result = processor && processor.respond_to?(:match) ? processor.match(name) : nil + if result + "(?<#{name}>#{ result })" + else + group = case operator + when '+' + "#{ RESERVED }*?" + when '#' + "#{ RESERVED }*?" + when '/' + "#{ UNRESERVED }*?" + when '.' + "#{ UNRESERVED.gsub('\.', '') }*?" + when ';' + "#{ UNRESERVED }*=?#{ UNRESERVED }*?" + when '?' + "#{ UNRESERVED }*=#{ UNRESERVED }*?" + when '&' + "#{ UNRESERVED }*=#{ UNRESERVED }*?" + else + "#{ UNRESERVED }*?" + end + if modifier == '*' + seg = case operator + when '+', '#' then "#{RESERVED_NO_COMMA}*+" + else group + end + joiner_pattern = operator.nil? ? joiner : "#{joiner}?" + "(?<#{name}>#{seg}(?:#{joiner_pattern}#{seg})*)?" + elsif varspecs.size > 1 && (operator == '+' || operator == '#') && + varspec != varspecs.last + "(?<#{name}>#{RESERVED_NO_COMMA}*+)?" + else + "(?<#{name}>#{group})?" + end + end + end.join("#{joiner}?") + "(?:|#{leader}#{combined})" + end + + # Ensure that the regular expression matches the whole URI. + regexp_string = "\\A#{regexp_string}\\z" + return expansions, Regexp.new(regexp_string) + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/uri.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/uri.rb new file mode 100644 index 0000000..07c9aeb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/uri.rb @@ -0,0 +1,2602 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +require "addressable/version" +require "addressable/idna" +require "public_suffix" + +## +# Addressable is a library for processing links and URIs. +module Addressable + ## + # This is an implementation of a URI parser based on + # RFC 3986, + # RFC 3987. + class URI + ## + # Raised if something other than a uri is supplied. + class InvalidURIError < StandardError + end + + ## + # Container for the character classes specified in + # RFC 3986. + # + # Note: Concatenated and interpolated `String`s are not affected by the + # `frozen_string_literal` directive and must be frozen explicitly. + # + # Interpolated `String`s *were* frozen this way before Ruby 3.0: + # https://bugs.ruby-lang.org/issues/17104 + module CharacterClasses + ALPHA = "a-zA-Z" + DIGIT = "0-9" + GEN_DELIMS = "\\:\\/\\?\\#\\[\\]\\@" + SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=" + RESERVED = (GEN_DELIMS + SUB_DELIMS).freeze + UNRESERVED = (ALPHA + DIGIT + "\\-\\.\\_\\~").freeze + RESERVED_AND_UNRESERVED = RESERVED + UNRESERVED + PCHAR = (UNRESERVED + SUB_DELIMS + "\\:\\@").freeze + SCHEME = (ALPHA + DIGIT + "\\-\\+\\.").freeze + HOST = (UNRESERVED + SUB_DELIMS + "\\[\\:\\]").freeze + AUTHORITY = (PCHAR + "\\[\\]").freeze + PATH = (PCHAR + "\\/").freeze + QUERY = (PCHAR + "\\/\\?").freeze + FRAGMENT = (PCHAR + "\\/\\?").freeze + end + + module NormalizeCharacterClasses + HOST = /[^#{CharacterClasses::HOST}]/ + UNRESERVED = /[^#{CharacterClasses::UNRESERVED}]/ + PCHAR = /[^#{CharacterClasses::PCHAR}]/ + SCHEME = /[^#{CharacterClasses::SCHEME}]/ + FRAGMENT = /[^#{CharacterClasses::FRAGMENT}]/ + QUERY = %r{[^a-zA-Z0-9\-\.\_\~\!\$\'\(\)\*\+\,\=\:\@\/\?%]|%(?!2B|2b)} + end + + module CharacterClassesRegexps + AUTHORITY = /[^#{CharacterClasses::AUTHORITY}]/ + FRAGMENT = /[^#{CharacterClasses::FRAGMENT}]/ + HOST = /[^#{CharacterClasses::HOST}]/ + PATH = /[^#{CharacterClasses::PATH}]/ + QUERY = /[^#{CharacterClasses::QUERY}]/ + RESERVED = /[^#{CharacterClasses::RESERVED}]/ + RESERVED_AND_UNRESERVED = /[^#{CharacterClasses::RESERVED_AND_UNRESERVED}]/ + SCHEME = /[^#{CharacterClasses::SCHEME}]/ + UNRESERVED = /[^#{CharacterClasses::UNRESERVED}]/ + end + + SLASH = '/' + EMPTY_STR = '' + + URIREGEX = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/ + + PORT_MAPPING = { + "http" => 80, + "https" => 443, + "ftp" => 21, + "tftp" => 69, + "sftp" => 22, + "ssh" => 22, + "svn+ssh" => 22, + "telnet" => 23, + "nntp" => 119, + "gopher" => 70, + "wais" => 210, + "ldap" => 389, + "prospero" => 1525 + }.freeze + + ## + # Returns a URI object based on the parsed string. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI string to parse. + # No parsing is performed if the object is already an + # Addressable::URI. + # + # @return [Addressable::URI] The parsed URI. + def self.parse(uri) + # If we were given nil, return nil. + return nil unless uri + # If a URI object is passed, just return itself. + return uri.dup if uri.kind_of?(self) + + # If a URI object of the Ruby standard library variety is passed, + # convert it to a string, then parse the string. + # We do the check this way because we don't want to accidentally + # cause a missing constant exception to be thrown. + if uri.class.name =~ /^URI\b/ + uri = uri.to_s + end + + # Otherwise, convert to a String + begin + uri = uri.to_str + rescue TypeError, NoMethodError + raise TypeError, "Can't convert #{uri.class} into String." + end unless uri.is_a?(String) + + # This Regexp supplied as an example in RFC 3986, and it works great. + scan = uri.scan(URIREGEX) + fragments = scan[0] + scheme = fragments[1] + authority = fragments[3] + path = fragments[4] + query = fragments[6] + fragment = fragments[8] + user = nil + password = nil + host = nil + port = nil + if authority != nil + # The Regexp above doesn't split apart the authority. + userinfo = authority[/^([^\[\]]*)@/, 1] + if userinfo != nil + user = userinfo.strip[/^([^:]*):?/, 1] + password = userinfo.strip[/:(.*)$/, 1] + end + + host = authority.sub( + /^([^\[\]]*)@/, EMPTY_STR + ).sub( + /:([^:@\[\]]*?)$/, EMPTY_STR + ) + + port = authority[/:([^:@\[\]]*?)$/, 1] + port = nil if port == EMPTY_STR + end + + return new( + :scheme => scheme, + :user => user, + :password => password, + :host => host, + :port => port, + :path => path, + :query => query, + :fragment => fragment + ) + end + + ## + # Converts an input to a URI. The input does not have to be a valid + # URI — the method will use heuristics to guess what URI was intended. + # This is not standards-compliant, merely user-friendly. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI string to parse. + # No parsing is performed if the object is already an + # Addressable::URI. + # @param [Hash] hints + # A Hash of hints to the heuristic parser. + # Defaults to {:scheme => "http"}. + # + # @return [Addressable::URI] The parsed URI. + def self.heuristic_parse(uri, hints={}) + # If we were given nil, return nil. + return nil unless uri + # If a URI object is passed, just return itself. + return uri.dup if uri.kind_of?(self) + + # If a URI object of the Ruby standard library variety is passed, + # convert it to a string, then parse the string. + # We do the check this way because we don't want to accidentally + # cause a missing constant exception to be thrown. + if uri.class.name =~ /^URI\b/ + uri = uri.to_s + end + + unless uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{uri.class} into String." + end + # Otherwise, convert to a String + uri = uri.to_str.dup.strip + hints = { + :scheme => "http" + }.merge(hints) + case uri + when /^http:\//i + uri.sub!(/^http:\/+/i, "http://") + when /^https:\//i + uri.sub!(/^https:\/+/i, "https://") + when /^feed:\/+http:\//i + uri.sub!(/^feed:\/+http:\/+/i, "feed:http://") + when /^feed:\//i + uri.sub!(/^feed:\/+/i, "feed://") + when %r[^file:/{4}]i + uri.sub!(%r[^file:/+]i, "file:////") + when %r[^file://localhost/]i + uri.sub!(%r[^file://localhost/+]i, "file:///") + when %r[^file:/+]i + uri.sub!(%r[^file:/+]i, "file:///") + when /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ + uri.sub!(/^/, hints[:scheme] + "://") + when /\A\d+\..*:\d+\z/ + uri = "#{hints[:scheme]}://#{uri}" + end + match = uri.match(URIREGEX) + fragments = match.captures + authority = fragments[3] + if authority && authority.length > 0 + new_authority = authority.tr("\\", "/").gsub(" ", "%20") + # NOTE: We want offset 4, not 3! + offset = match.offset(4) + uri = uri.dup + uri[offset[0]...offset[1]] = new_authority + end + parsed = self.parse(uri) + if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/ + parsed = self.parse(hints[:scheme] + "://" + uri) + end + if parsed.path.include?(".") + if parsed.path[/\b@\b/] + parsed.scheme = "mailto" unless parsed.scheme + elsif new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1] + parsed.defer_validation do + new_path = parsed.path.sub( + Regexp.new("^" + Regexp.escape(new_host)), EMPTY_STR) + parsed.host = new_host + parsed.path = new_path + parsed.scheme = hints[:scheme] unless parsed.scheme + end + end + end + return parsed + end + + ## + # Converts a path to a file scheme URI. If the path supplied is + # relative, it will be returned as a relative URI. If the path supplied + # is actually a non-file URI, it will parse the URI as if it had been + # parsed with Addressable::URI.parse. Handles all of the + # various Microsoft-specific formats for specifying paths. + # + # @param [String, Addressable::URI, #to_str] path + # Typically a String path to a file or directory, but + # will return a sensible return value if an absolute URI is supplied + # instead. + # + # @return [Addressable::URI] + # The parsed file scheme URI or the original URI if some other URI + # scheme was provided. + # + # @example + # base = Addressable::URI.convert_path("/absolute/path/") + # uri = Addressable::URI.convert_path("relative/path") + # (base + uri).to_s + # #=> "file:///absolute/path/relative/path" + # + # Addressable::URI.convert_path( + # "c:\\windows\\My Documents 100%20\\foo.txt" + # ).to_s + # #=> "file:///c:/windows/My%20Documents%20100%20/foo.txt" + # + # Addressable::URI.convert_path("http://example.com/").to_s + # #=> "http://example.com/" + def self.convert_path(path) + # If we were given nil, return nil. + return nil unless path + # If a URI object is passed, just return itself. + return path if path.kind_of?(self) + unless path.respond_to?(:to_str) + raise TypeError, "Can't convert #{path.class} into String." + end + # Otherwise, convert to a String + path = path.to_str.strip + + path.sub!(/^file:\/?\/?/, EMPTY_STR) if path =~ /^file:\/?\/?/ + path = SLASH + path if path =~ /^([a-zA-Z])[\|:]/ + uri = self.parse(path) + + if uri.scheme == nil + # Adjust windows-style uris + uri.path.sub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do + "/#{$1.downcase}:/" + end + uri.path.tr!("\\", SLASH) + if File.exist?(uri.path) && + File.stat(uri.path).directory? + uri.path.chomp!(SLASH) + uri.path = uri.path + '/' + end + + # If the path is absolute, set the scheme and host. + if uri.path.start_with?(SLASH) + uri.scheme = "file" + uri.host = EMPTY_STR + end + uri.normalize! + end + + return uri + end + + ## + # Joins several URIs together. + # + # @param [String, Addressable::URI, #to_str] *uris + # The URIs to join. + # + # @return [Addressable::URI] The joined URI. + # + # @example + # base = "http://example.com/" + # uri = Addressable::URI.parse("relative/path") + # Addressable::URI.join(base, uri) + # #=> # + def self.join(*uris) + uri_objects = uris.collect do |uri| + unless uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{uri.class} into String." + end + uri.kind_of?(self) ? uri : self.parse(uri.to_str) + end + result = uri_objects.shift.dup + uri_objects.each do |uri| + result.join!(uri) + end + return result + end + + ## + # Tables used to optimize encoding operations in `self.encode_component` + # and `self.normalize_component` + SEQUENCE_ENCODING_TABLE = (0..255).map do |byte| + format("%02x", byte).freeze + end.freeze + + SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE = (0..255).map do |byte| + format("%%%02X", byte).freeze + end.freeze + + ## + # Percent encodes a URI component. + # + # @param [String, #to_str] component The URI component to encode. + # + # @param [String, Regexp] character_class + # The characters which are not percent encoded. If a String + # is passed, the String must be formatted as a regular + # expression character class. (Do not include the surrounding square + # brackets.) For example, "b-zB-Z0-9" would cause + # everything but the letters 'b' through 'z' and the numbers '0' through + # '9' to be percent encoded. If a Regexp is passed, the + # value /[^b-zB-Z0-9]/ would have the same effect. A set of + # useful String values may be found in the + # Addressable::URI::CharacterClasses module. The default + # value is the reserved plus unreserved character classes specified in + # RFC 3986. + # + # @param [Regexp] upcase_encoded + # A string of characters that may already be percent encoded, and whose + # encodings should be upcased. This allows normalization of percent + # encodings for characters not included in the + # character_class. + # + # @return [String] The encoded component. + # + # @example + # Addressable::URI.encode_component("simple/example", "b-zB-Z0-9") + # => "simple%2Fex%61mple" + # Addressable::URI.encode_component("simple/example", /[^b-zB-Z0-9]/) + # => "simple%2Fex%61mple" + # Addressable::URI.encode_component( + # "simple/example", Addressable::URI::CharacterClasses::UNRESERVED + # ) + # => "simple%2Fexample" + def self.encode_component(component, character_class=CharacterClassesRegexps::RESERVED_AND_UNRESERVED, upcase_encoded='') + return nil if component.nil? + + begin + if component.kind_of?(Symbol) || + component.kind_of?(Numeric) || + component.kind_of?(TrueClass) || + component.kind_of?(FalseClass) + component = component.to_s + else + component = component.to_str + end + rescue TypeError, NoMethodError + raise TypeError, "Can't convert #{component.class} into String." + end if !component.is_a? String + + if ![String, Regexp].include?(character_class.class) + raise TypeError, + "Expected String or Regexp, got #{character_class.inspect}" + end + if character_class.kind_of?(String) + character_class = /[^#{character_class}]/ + end + # We can't perform regexps on invalid UTF sequences, but + # here we need to, so switch to ASCII. + component = component.dup + component.force_encoding(Encoding::ASCII_8BIT) + # Avoiding gsub! because there are edge cases with frozen strings + component = component.gsub(character_class) do |char| + SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[char.ord] + end + if upcase_encoded.length > 0 + upcase_encoded_chars = upcase_encoded.bytes.map do |byte| + SEQUENCE_ENCODING_TABLE[byte] + end + component = component.gsub(/%(#{upcase_encoded_chars.join('|')})/, + &:upcase) + end + + return component + end + + class << self + alias_method :escape_component, :encode_component + end + + ## + # Unencodes any percent encoded characters within a URI component. + # This method may be used for unencoding either components or full URIs, + # however, it is recommended to use the unencode_component + # alias when unencoding components. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI or component to unencode. + # + # @param [Class] return_type + # The type of object to return. + # This value may only be set to String or + # Addressable::URI. All other values are invalid. Defaults + # to String. + # + # @param [String] leave_encoded + # A string of characters to leave encoded. If a percent encoded character + # in this list is encountered then it will remain percent encoded. + # + # @return [String, Addressable::URI] + # The unencoded component or URI. + # The return type is determined by the return_type + # parameter. + def self.unencode(uri, return_type=String, leave_encoded='') + return nil if uri.nil? + + begin + uri = uri.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{uri.class} into String." + end if !uri.is_a? String + if ![String, ::Addressable::URI].include?(return_type) + raise TypeError, + "Expected Class (String or Addressable::URI), " + + "got #{return_type.inspect}" + end + + result = uri.gsub(/%[0-9a-f]{2}/i) do |sequence| + c = sequence[1..3].to_i(16).chr + c.force_encoding(sequence.encoding) + leave_encoded.include?(c) ? sequence : c + end + + result.force_encoding(Encoding::UTF_8) + if return_type == String + return result + elsif return_type == ::Addressable::URI + return ::Addressable::URI.parse(result) + end + end + + class << self + alias_method :unescape, :unencode + alias_method :unencode_component, :unencode + alias_method :unescape_component, :unencode + end + + + ## + # Normalizes the encoding of a URI component. + # + # @param [String, #to_str] component The URI component to encode. + # + # @param [String, Regexp] character_class + # The characters which are not percent encoded. If a String + # is passed, the String must be formatted as a regular + # expression character class. (Do not include the surrounding square + # brackets.) For example, "b-zB-Z0-9" would cause + # everything but the letters 'b' through 'z' and the numbers '0' + # through '9' to be percent encoded. If a Regexp is passed, + # the value /[^b-zB-Z0-9]/ would have the same effect. A + # set of useful String values may be found in the + # Addressable::URI::CharacterClasses module. The default + # value is the reserved plus unreserved character classes specified in + # RFC 3986. + # + # @param [String] leave_encoded + # When character_class is a String then + # leave_encoded is a string of characters that should remain + # percent encoded while normalizing the component; if they appear percent + # encoded in the original component, then they will be upcased ("%2f" + # normalized to "%2F") but otherwise left alone. + # + # @return [String] The normalized component. + # + # @example + # Addressable::URI.normalize_component("simpl%65/%65xampl%65", "b-zB-Z") + # => "simple%2Fex%61mple" + # Addressable::URI.normalize_component( + # "simpl%65/%65xampl%65", /[^b-zB-Z]/ + # ) + # => "simple%2Fex%61mple" + # Addressable::URI.normalize_component( + # "simpl%65/%65xampl%65", + # Addressable::URI::CharacterClasses::UNRESERVED + # ) + # => "simple%2Fexample" + # Addressable::URI.normalize_component( + # "one%20two%2fthree%26four", + # "0-9a-zA-Z &/", + # "/" + # ) + # => "one two%2Fthree&four" + def self.normalize_component(component, character_class= + CharacterClassesRegexps::RESERVED_AND_UNRESERVED, + leave_encoded='') + return nil if component.nil? + + begin + component = component.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{component.class} into String." + end if !component.is_a? String + + if ![String, Regexp].include?(character_class.class) + raise TypeError, + "Expected String or Regexp, got #{character_class.inspect}" + end + if character_class.kind_of?(String) + leave_re = if leave_encoded.length > 0 + character_class = "#{character_class}%" unless character_class.include?('%') + + bytes = leave_encoded.bytes + leave_encoded_pattern = bytes.map { |b| SEQUENCE_ENCODING_TABLE[b] }.join('|') + "|%(?!#{leave_encoded_pattern}|#{leave_encoded_pattern.upcase})" + end + + character_class = if leave_re + /[^#{character_class}]#{leave_re}/ + else + /[^#{character_class}]/ + end + end + # We can't perform regexps on invalid UTF sequences, but + # here we need to, so switch to ASCII. + component = component.dup + component.force_encoding(Encoding::ASCII_8BIT) + unencoded = self.unencode_component(component, String, leave_encoded) + begin + encoded = self.encode_component( + unencoded.unicode_normalize(:nfc), + character_class, + leave_encoded + ) + rescue ArgumentError + encoded = self.encode_component(unencoded) + end + encoded.force_encoding(Encoding::UTF_8) + return encoded + end + + ## + # Percent encodes any special characters in the URI. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI to encode. + # + # @param [Class] return_type + # The type of object to return. + # This value may only be set to String or + # Addressable::URI. All other values are invalid. Defaults + # to String. + # + # @return [String, Addressable::URI] + # The encoded URI. + # The return type is determined by the return_type + # parameter. + def self.encode(uri, return_type=String) + return nil if uri.nil? + + begin + uri = uri.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{uri.class} into String." + end if !uri.is_a? String + + if ![String, ::Addressable::URI].include?(return_type) + raise TypeError, + "Expected Class (String or Addressable::URI), " + + "got #{return_type.inspect}" + end + uri_object = uri.kind_of?(self) ? uri : self.parse(uri) + encoded_uri = Addressable::URI.new( + :scheme => self.encode_component(uri_object.scheme, + Addressable::URI::CharacterClassesRegexps::SCHEME), + :authority => self.encode_component(uri_object.authority, + Addressable::URI::CharacterClassesRegexps::AUTHORITY), + :path => self.encode_component(uri_object.path, + Addressable::URI::CharacterClassesRegexps::PATH), + :query => self.encode_component(uri_object.query, + Addressable::URI::CharacterClassesRegexps::QUERY), + :fragment => self.encode_component(uri_object.fragment, + Addressable::URI::CharacterClassesRegexps::FRAGMENT) + ) + if return_type == String + return encoded_uri.to_s + elsif return_type == ::Addressable::URI + return encoded_uri + end + end + + class << self + alias_method :escape, :encode + end + + ## + # Normalizes the encoding of a URI. Characters within a hostname are + # not percent encoded to allow for internationalized domain names. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI to encode. + # + # @param [Class] return_type + # The type of object to return. + # This value may only be set to String or + # Addressable::URI. All other values are invalid. Defaults + # to String. + # + # @return [String, Addressable::URI] + # The encoded URI. + # The return type is determined by the return_type + # parameter. + def self.normalized_encode(uri, return_type=String) + begin + uri = uri.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{uri.class} into String." + end if !uri.is_a? String + + if ![String, ::Addressable::URI].include?(return_type) + raise TypeError, + "Expected Class (String or Addressable::URI), " + + "got #{return_type.inspect}" + end + uri_object = uri.kind_of?(self) ? uri : self.parse(uri) + components = { + :scheme => self.unencode_component(uri_object.scheme), + :user => self.unencode_component(uri_object.user), + :password => self.unencode_component(uri_object.password), + :host => self.unencode_component(uri_object.host), + :port => (uri_object.port.nil? ? nil : uri_object.port.to_s), + :path => self.unencode_component(uri_object.path), + :query => self.unencode_component(uri_object.query), + :fragment => self.unencode_component(uri_object.fragment) + } + components.each do |key, value| + if value != nil + begin + components[key] = value.to_str.unicode_normalize(:nfc) + rescue ArgumentError + # Likely a malformed UTF-8 character, skip unicode normalization + components[key] = value.to_str + end + end + end + encoded_uri = Addressable::URI.new( + :scheme => self.encode_component(components[:scheme], + Addressable::URI::CharacterClassesRegexps::SCHEME), + :user => self.encode_component(components[:user], + Addressable::URI::CharacterClassesRegexps::UNRESERVED), + :password => self.encode_component(components[:password], + Addressable::URI::CharacterClassesRegexps::UNRESERVED), + :host => components[:host], + :port => components[:port], + :path => self.encode_component(components[:path], + Addressable::URI::CharacterClassesRegexps::PATH), + :query => self.encode_component(components[:query], + Addressable::URI::CharacterClassesRegexps::QUERY), + :fragment => self.encode_component(components[:fragment], + Addressable::URI::CharacterClassesRegexps::FRAGMENT) + ) + if return_type == String + return encoded_uri.to_s + elsif return_type == ::Addressable::URI + return encoded_uri + end + end + + ## + # Encodes a set of key/value pairs according to the rules for the + # application/x-www-form-urlencoded MIME type. + # + # @param [#to_hash, #to_ary] form_values + # The form values to encode. + # + # @param [TrueClass, FalseClass] sort + # Sort the key/value pairs prior to encoding. + # Defaults to false. + # + # @return [String] + # The encoded value. + def self.form_encode(form_values, sort=false) + if form_values.respond_to?(:to_hash) + form_values = form_values.to_hash.to_a + elsif form_values.respond_to?(:to_ary) + form_values = form_values.to_ary + else + raise TypeError, "Can't convert #{form_values.class} into Array." + end + + form_values = form_values.inject([]) do |accu, (key, value)| + if value.kind_of?(Array) + value.each do |v| + accu << [key.to_s, v.to_s] + end + else + accu << [key.to_s, value.to_s] + end + accu + end + + if sort + # Useful for OAuth and optimizing caching systems + form_values = form_values.sort + end + escaped_form_values = form_values.map do |(key, value)| + # Line breaks are CRLF pairs + [ + self.encode_component( + key.gsub(/(\r\n|\n|\r)/, "\r\n"), + CharacterClassesRegexps::UNRESERVED + ).gsub("%20", "+"), + self.encode_component( + value.gsub(/(\r\n|\n|\r)/, "\r\n"), + CharacterClassesRegexps::UNRESERVED + ).gsub("%20", "+") + ] + end + return escaped_form_values.map do |(key, value)| + "#{key}=#{value}" + end.join("&") + end + + ## + # Decodes a String according to the rules for the + # application/x-www-form-urlencoded MIME type. + # + # @param [String, #to_str] encoded_value + # The form values to decode. + # + # @return [Array] + # The decoded values. + # This is not a Hash because of the possibility for + # duplicate keys. + def self.form_unencode(encoded_value) + if !encoded_value.respond_to?(:to_str) + raise TypeError, "Can't convert #{encoded_value.class} into String." + end + encoded_value = encoded_value.to_str + split_values = encoded_value.split("&").map do |pair| + pair.split("=", 2) + end + return split_values.map do |(key, value)| + [ + key ? self.unencode_component( + key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil, + value ? (self.unencode_component( + value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil + ] + end + end + + ## + # Creates a new uri object from component parts. + # + # @option [String, #to_str] scheme The scheme component. + # @option [String, #to_str] user The user component. + # @option [String, #to_str] password The password component. + # @option [String, #to_str] userinfo + # The userinfo component. If this is supplied, the user and password + # components must be omitted. + # @option [String, #to_str] host The host component. + # @option [String, #to_str] port The port component. + # @option [String, #to_str] authority + # The authority component. If this is supplied, the user, password, + # userinfo, host, and port components must be omitted. + # @option [String, #to_str] path The path component. + # @option [String, #to_str] query The query component. + # @option [String, #to_str] fragment The fragment component. + # + # @return [Addressable::URI] The constructed URI object. + def initialize(options={}) + if options.has_key?(:authority) + if (options.keys & [:userinfo, :user, :password, :host, :port]).any? + raise ArgumentError, + "Cannot specify both an authority and any of the components " + + "within the authority." + end + end + if options.has_key?(:userinfo) + if (options.keys & [:user, :password]).any? + raise ArgumentError, + "Cannot specify both a userinfo and either the user or password." + end + end + + reset_ivs + + defer_validation do + # Bunch of crazy logic required because of the composite components + # like userinfo and authority. + self.scheme = options[:scheme] if options[:scheme] + self.user = options[:user] if options[:user] + self.password = options[:password] if options[:password] + self.userinfo = options[:userinfo] if options[:userinfo] + self.host = options[:host] if options[:host] + self.port = options[:port] if options[:port] + self.authority = options[:authority] if options[:authority] + self.path = options[:path] if options[:path] + self.query = options[:query] if options[:query] + self.query_values = options[:query_values] if options[:query_values] + self.fragment = options[:fragment] if options[:fragment] + end + + to_s # force path validation + end + + ## + # Freeze URI, initializing instance variables. + # + # @return [Addressable::URI] The frozen URI object. + def freeze + self.normalized_scheme + self.normalized_user + self.normalized_password + self.normalized_userinfo + self.normalized_host + self.normalized_port + self.normalized_authority + self.normalized_site + self.normalized_path + self.normalized_query + self.normalized_fragment + self.hash + super + end + + ## + # The scheme component for this URI. + # + # @return [String] The scheme component. + attr_reader :scheme + + ## + # The scheme component for this URI, normalized. + # + # @return [String] The scheme component, normalized. + def normalized_scheme + return nil unless self.scheme + if @normalized_scheme == NONE + @normalized_scheme = if self.scheme =~ /^\s*ssh\+svn\s*$/i + "svn+ssh".dup + else + Addressable::URI.normalize_component( + self.scheme.strip.downcase, + Addressable::URI::NormalizeCharacterClasses::SCHEME + ) + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_scheme) + @normalized_scheme + end + + ## + # Sets the scheme component for this URI. + # + # @param [String, #to_str] new_scheme The new scheme component. + def scheme=(new_scheme) + if new_scheme && !new_scheme.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_scheme.class} into String." + elsif new_scheme + new_scheme = new_scheme.to_str + end + if new_scheme && new_scheme !~ /\A[a-z][a-z0-9\.\+\-]*\z/i + raise InvalidURIError, "Invalid scheme format: '#{new_scheme}'" + end + @scheme = new_scheme + @scheme = nil if @scheme.to_s.strip.empty? + + # Reset dependent values + @normalized_scheme = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The user component for this URI. + # + # @return [String] The user component. + attr_reader :user + + ## + # The user component for this URI, normalized. + # + # @return [String] The user component, normalized. + def normalized_user + return nil unless self.user + return @normalized_user unless @normalized_user == NONE + @normalized_user = begin + if normalized_scheme =~ /https?/ && self.user.strip.empty? && + (!self.password || self.password.strip.empty?) + nil + else + Addressable::URI.normalize_component( + self.user.strip, + Addressable::URI::NormalizeCharacterClasses::UNRESERVED + ) + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_user) + @normalized_user + end + + ## + # Sets the user component for this URI. + # + # @param [String, #to_str] new_user The new user component. + def user=(new_user) + if new_user && !new_user.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_user.class} into String." + end + @user = new_user ? new_user.to_str : nil + + # You can't have a nil user with a non-nil password + if password != nil + @user = EMPTY_STR unless user + end + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @normalized_user = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The password component for this URI. + # + # @return [String] The password component. + attr_reader :password + + ## + # The password component for this URI, normalized. + # + # @return [String] The password component, normalized. + def normalized_password + return nil unless self.password + return @normalized_password unless @normalized_password == NONE + @normalized_password = begin + if self.normalized_scheme =~ /https?/ && self.password.strip.empty? && + (!self.user || self.user.strip.empty?) + nil + else + Addressable::URI.normalize_component( + self.password.strip, + Addressable::URI::NormalizeCharacterClasses::UNRESERVED + ) + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_password) + @normalized_password + end + + ## + # Sets the password component for this URI. + # + # @param [String, #to_str] new_password The new password component. + def password=(new_password) + if new_password && !new_password.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_password.class} into String." + end + @password = new_password ? new_password.to_str : nil + + # You can't have a nil user with a non-nil password + if @password != nil + self.user = EMPTY_STR if user.nil? + end + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @normalized_password = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The userinfo component for this URI. + # Combines the user and password components. + # + # @return [String] The userinfo component. + def userinfo + current_user = self.user + current_password = self.password + (current_user || current_password) && @userinfo ||= begin + if current_user && current_password + "#{current_user}:#{current_password}" + elsif current_user && !current_password + "#{current_user}" + end + end + end + + ## + # The userinfo component for this URI, normalized. + # + # @return [String] The userinfo component, normalized. + def normalized_userinfo + return nil unless self.userinfo + return @normalized_userinfo unless @normalized_userinfo == NONE + @normalized_userinfo = begin + current_user = self.normalized_user + current_password = self.normalized_password + if !current_user && !current_password + nil + elsif current_user && current_password + "#{current_user}:#{current_password}".dup + elsif current_user && !current_password + "#{current_user}".dup + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_userinfo) + @normalized_userinfo + end + + ## + # Sets the userinfo component for this URI. + # + # @param [String, #to_str] new_userinfo The new userinfo component. + def userinfo=(new_userinfo) + if new_userinfo && !new_userinfo.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_userinfo.class} into String." + end + new_user, new_password = if new_userinfo + [ + new_userinfo.to_str.strip[/^(.*):/, 1], + new_userinfo.to_str.strip[/:(.*)$/, 1] + ] + else + [nil, nil] + end + + # Password assigned first to ensure validity in case of nil + self.password = new_password + self.user = new_user + + # Reset dependent values + @authority = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The host component for this URI. + # + # @return [String] The host component. + attr_reader :host + + ## + # The host component for this URI, normalized. + # + # @return [String] The host component, normalized. + def normalized_host + return nil unless self.host + + @normalized_host ||= begin + if !self.host.strip.empty? + result = ::Addressable::IDNA.to_ascii( + URI.unencode_component(self.host.strip.downcase) + ) + if result =~ /[^\.]\.$/ + # Single trailing dots are unnecessary. + result = result[0...-1] + end + result = Addressable::URI.normalize_component( + result, + NormalizeCharacterClasses::HOST + ) + result + else + EMPTY_STR.dup + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_host) + @normalized_host + end + + ## + # Sets the host component for this URI. + # + # @param [String, #to_str] new_host The new host component. + def host=(new_host) + if new_host && !new_host.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_host.class} into String." + end + @host = new_host ? new_host.to_str : nil + + # Reset dependent values + @authority = nil + @normalized_host = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # This method is same as URI::Generic#host except + # brackets for IPv6 (and 'IPvFuture') addresses are removed. + # + # @see Addressable::URI#host + # + # @return [String] The hostname for this URI. + def hostname + v = self.host + /\A\[(.*)\]\z/ =~ v ? $1 : v + end + + ## + # This method is same as URI::Generic#host= except + # the argument can be a bare IPv6 address (or 'IPvFuture'). + # + # @see Addressable::URI#host= + # + # @param [String, #to_str] new_hostname The new hostname for this URI. + def hostname=(new_hostname) + if new_hostname && + (new_hostname.respond_to?(:ipv4?) || new_hostname.respond_to?(:ipv6?)) + new_hostname = new_hostname.to_s + elsif new_hostname && !new_hostname.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_hostname.class} into String." + end + v = new_hostname ? new_hostname.to_str : nil + v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v + self.host = v + end + + ## + # Returns the top-level domain for this host. + # + # @example + # Addressable::URI.parse("http://www.example.co.uk").tld # => "co.uk" + def tld + PublicSuffix.parse(self.host, ignore_private: true).tld + end + + ## + # Sets the top-level domain for this URI. + # + # @param [String, #to_str] new_tld The new top-level domain. + def tld=(new_tld) + replaced_tld = host.sub(/#{tld}\z/, new_tld) + self.host = PublicSuffix::Domain.new(replaced_tld).to_s + end + + ## + # Returns the public suffix domain for this host. + # + # @example + # Addressable::URI.parse("http://www.example.co.uk").domain # => "example.co.uk" + def domain + PublicSuffix.domain(self.host, ignore_private: true) + end + + ## + # The authority component for this URI. + # Combines the user, password, host, and port components. + # + # @return [String] The authority component. + def authority + self.host && @authority ||= begin + authority = String.new + if self.userinfo != nil + authority << "#{self.userinfo}@" + end + authority << self.host + if self.port != nil + authority << ":#{self.port}" + end + authority + end + end + + ## + # The authority component for this URI, normalized. + # + # @return [String] The authority component, normalized. + def normalized_authority + return nil unless self.authority + @normalized_authority ||= begin + authority = String.new + if self.normalized_userinfo != nil + authority << "#{self.normalized_userinfo}@" + end + authority << self.normalized_host + if self.normalized_port != nil + authority << ":#{self.normalized_port}" + end + authority + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_authority) + @normalized_authority + end + + ## + # Sets the authority component for this URI. + # + # @param [String, #to_str] new_authority The new authority component. + def authority=(new_authority) + if new_authority + if !new_authority.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_authority.class} into String." + end + new_authority = new_authority.to_str + new_userinfo = new_authority[/^([^\[\]]*)@/, 1] + if new_userinfo + new_user = new_userinfo.strip[/^([^:]*):?/, 1] + new_password = new_userinfo.strip[/:(.*)$/, 1] + end + new_host = new_authority.sub( + /^([^\[\]]*)@/, EMPTY_STR + ).sub( + /:([^:@\[\]]*?)$/, EMPTY_STR + ) + new_port = + new_authority[/:([^:@\[\]]*?)$/, 1] + end + + # Password assigned first to ensure validity in case of nil + self.password = new_password + self.user = new_user + self.host = new_host + self.port = new_port + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The origin for this URI, serialized to ASCII, as per + # RFC 6454, section 6.2. + # + # @return [String] The serialized origin. + def origin + if self.scheme && self.authority + if self.normalized_port + "#{self.normalized_scheme}://#{self.normalized_host}" + + ":#{self.normalized_port}" + else + "#{self.normalized_scheme}://#{self.normalized_host}" + end + else + "null" + end + end + + ## + # Sets the origin for this URI, serialized to ASCII, as per + # RFC 6454, section 6.2. This assignment will reset the `userinfo` + # component. + # + # @param [String, #to_str] new_origin The new origin component. + def origin=(new_origin) + if new_origin + if !new_origin.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_origin.class} into String." + end + new_origin = new_origin.to_str + new_scheme = new_origin[/^([^:\/?#]+):\/\//, 1] + unless new_scheme + raise InvalidURIError, 'An origin cannot omit the scheme.' + end + new_host = new_origin[/:\/\/([^\/?#:]+)/, 1] + unless new_host + raise InvalidURIError, 'An origin cannot omit the host.' + end + new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1] + end + + self.scheme = new_scheme + self.host = new_host + self.port = new_port + self.userinfo = nil + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @normalized_authority = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + # Returns an array of known ip-based schemes. These schemes typically + # use a similar URI form: + # //:@:/ + def self.ip_based_schemes + return self.port_mapping.keys + end + + # Returns a hash of common IP-based schemes and their default port + # numbers. Adding new schemes to this hash, as necessary, will allow + # for better URI normalization. + def self.port_mapping + PORT_MAPPING + end + + ## + # The port component for this URI. + # This is the port number actually given in the URI. This does not + # infer port numbers from default values. + # + # @return [Integer] The port component. + attr_reader :port + + ## + # The port component for this URI, normalized. + # + # @return [Integer] The port component, normalized. + def normalized_port + return nil unless self.port + return @normalized_port unless @normalized_port == NONE + @normalized_port = begin + if URI.port_mapping[self.normalized_scheme] == self.port + nil + else + self.port + end + end + end + + ## + # Sets the port component for this URI. + # + # @param [String, Integer, #to_s] new_port The new port component. + def port=(new_port) + if new_port != nil && new_port.respond_to?(:to_str) + new_port = Addressable::URI.unencode_component(new_port.to_str) + end + + if new_port.respond_to?(:valid_encoding?) && !new_port.valid_encoding? + raise InvalidURIError, "Invalid encoding in port" + end + + if new_port != nil && !(new_port.to_s =~ /^\d+$/) + raise InvalidURIError, + "Invalid port number: #{new_port.inspect}" + end + + @port = new_port.to_s.to_i + @port = nil if @port == 0 + + # Reset dependent values + @authority = nil + @normalized_port = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The inferred port component for this URI. + # This method will normalize to the default port for the URI's scheme if + # the port isn't explicitly specified in the URI. + # + # @return [Integer] The inferred port component. + def inferred_port + if self.port.to_i == 0 + self.default_port + else + self.port.to_i + end + end + + ## + # The default port for this URI's scheme. + # This method will always returns the default port for the URI's scheme + # regardless of the presence of an explicit port in the URI. + # + # @return [Integer] The default port. + def default_port + URI.port_mapping[self.scheme.strip.downcase] if self.scheme + end + + ## + # The combination of components that represent a site. + # Combines the scheme, user, password, host, and port components. + # Primarily useful for HTTP and HTTPS. + # + # For example, "http://example.com/path?query" would have a + # site value of "http://example.com". + # + # @return [String] The components that identify a site. + def site + (self.scheme || self.authority) && @site ||= begin + site_string = "".dup + site_string << "#{self.scheme}:" if self.scheme != nil + site_string << "//#{self.authority}" if self.authority != nil + site_string + end + end + + ## + # The normalized combination of components that represent a site. + # Combines the scheme, user, password, host, and port components. + # Primarily useful for HTTP and HTTPS. + # + # For example, "http://example.com/path?query" would have a + # site value of "http://example.com". + # + # @return [String] The normalized components that identify a site. + def normalized_site + return nil unless self.site + @normalized_site ||= begin + site_string = "".dup + if self.normalized_scheme != nil + site_string << "#{self.normalized_scheme}:" + end + if self.normalized_authority != nil + site_string << "//#{self.normalized_authority}" + end + site_string + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_site) + @normalized_site + end + + ## + # Sets the site value for this URI. + # + # @param [String, #to_str] new_site The new site value. + def site=(new_site) + if new_site + if !new_site.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_site.class} into String." + end + new_site = new_site.to_str + # These two regular expressions derived from the primary parsing + # expression + self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1] + self.authority = new_site[ + /^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1 + ] + else + self.scheme = nil + self.authority = nil + end + end + + ## + # The path component for this URI. + # + # @return [String] The path component. + attr_reader :path + + NORMPATH = /^(?!\/)[^\/:]*:.*$/ + ## + # The path component for this URI, normalized. + # + # @return [String] The path component, normalized. + def normalized_path + @normalized_path ||= begin + path = self.path.to_s + if self.scheme == nil && path =~ NORMPATH + # Relative paths with colons in the first segment are ambiguous. + path = path.sub(":", "%2F") + end + # String#split(delimiter, -1) uses the more strict splitting behavior + # found by default in Python. + result = path.strip.split(SLASH, -1).map do |segment| + Addressable::URI.normalize_component( + segment, + Addressable::URI::NormalizeCharacterClasses::PCHAR + ) + end.join(SLASH) + + result = URI.normalize_path(result) + if result.empty? && + ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme) + result = SLASH.dup + end + result + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_path) + @normalized_path + end + + ## + # Sets the path component for this URI. + # + # @param [String, #to_str] new_path The new path component. + def path=(new_path) + if new_path && !new_path.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_path.class} into String." + end + @path = (new_path || EMPTY_STR).to_str + if !@path.empty? && @path[0..0] != SLASH && host != nil + @path = "/#{@path}" + end + + # Reset dependent values + @normalized_path = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The basename, if any, of the file in the path component. + # + # @return [String] The path's basename. + def basename + # Path cannot be nil + return File.basename(self.path).sub(/;[^\/]*$/, EMPTY_STR) + end + + ## + # The extname, if any, of the file in the path component. + # Empty string if there is no extension. + # + # @return [String] The path's extname. + def extname + return nil unless self.path + return File.extname(self.basename) + end + + ## + # The query component for this URI. + # + # @return [String] The query component. + attr_reader :query + + ## + # The query component for this URI, normalized. + # + # @return [String] The query component, normalized. + def normalized_query(*flags) + return nil unless self.query + return @normalized_query unless @normalized_query == NONE + @normalized_query = begin + modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup + # Make sure possible key-value pair delimiters are escaped. + modified_query_class.sub!("\\&", "").sub!("\\;", "") + pairs = (query || "").split("&", -1) + pairs.delete_if(&:empty?).uniq! if flags.include?(:compacted) + pairs.sort! if flags.include?(:sorted) + component = pairs.map do |pair| + Addressable::URI.normalize_component( + pair, + Addressable::URI::NormalizeCharacterClasses::QUERY, + "+" + ) + end.join("&") + component == "" ? nil : component + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_query) + @normalized_query + end + + ## + # Sets the query component for this URI. + # + # @param [String, #to_str] new_query The new query component. + def query=(new_query) + if new_query && !new_query.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_query.class} into String." + end + @query = new_query ? new_query.to_str : nil + + # Reset dependent values + @normalized_query = NONE + remove_composite_values + end + + ## + # Converts the query component to a Hash value. + # + # @param [Class] return_type The return type desired. Value must be either + # `Hash` or `Array`. + # + # @return [Hash, Array, nil] The query string parsed as a Hash or Array + # or nil if the query string is blank. + # + # @example + # Addressable::URI.parse("?one=1&two=2&three=3").query_values + # #=> {"one" => "1", "two" => "2", "three" => "3"} + # Addressable::URI.parse("?one=two&one=three").query_values(Array) + # #=> [["one", "two"], ["one", "three"]] + # Addressable::URI.parse("?one=two&one=three").query_values(Hash) + # #=> {"one" => "three"} + # Addressable::URI.parse("?").query_values + # #=> {} + # Addressable::URI.parse("").query_values + # #=> nil + def query_values(return_type=Hash) + empty_accumulator = Array == return_type ? [] : {} + if return_type != Hash && return_type != Array + raise ArgumentError, "Invalid return type. Must be Hash or Array." + end + return nil if self.query == nil + split_query = self.query.split("&").map do |pair| + pair.split("=", 2) if pair && !pair.empty? + end.compact + return split_query.inject(empty_accumulator.dup) do |accu, pair| + # I'd rather use key/value identifiers instead of array lookups, + # but in this case I really want to maintain the exact pair structure, + # so it's best to make all changes in-place. + pair[0] = URI.unencode_component(pair[0]) + if pair[1].respond_to?(:to_str) + value = pair[1].to_str + # I loathe the fact that I have to do this. Stupid HTML 4.01. + # Treating '+' as a space was just an unbelievably bad idea. + # There was nothing wrong with '%20'! + # If it ain't broke, don't fix it! + value = value.tr("+", " ") if ["http", "https", nil].include?(scheme) + pair[1] = URI.unencode_component(value) + end + if return_type == Hash + accu[pair[0]] = pair[1] + else + accu << pair + end + accu + end + end + + ## + # Sets the query component for this URI from a Hash object. + # An empty Hash or Array will result in an empty query string. + # + # @param [Hash, #to_hash, Array] new_query_values The new query values. + # + # @example + # uri.query_values = {:a => "a", :b => ["c", "d", "e"]} + # uri.query + # # => "a=a&b=c&b=d&b=e" + # uri.query_values = [['a', 'a'], ['b', 'c'], ['b', 'd'], ['b', 'e']] + # uri.query + # # => "a=a&b=c&b=d&b=e" + # uri.query_values = [['a', 'a'], ['b', ['c', 'd', 'e']]] + # uri.query + # # => "a=a&b=c&b=d&b=e" + # uri.query_values = [['flag'], ['key', 'value']] + # uri.query + # # => "flag&key=value" + def query_values=(new_query_values) + if new_query_values == nil + self.query = nil + return nil + end + + if !new_query_values.is_a?(Array) + if !new_query_values.respond_to?(:to_hash) + raise TypeError, + "Can't convert #{new_query_values.class} into Hash." + end + new_query_values = new_query_values.to_hash + new_query_values = new_query_values.map do |key, value| + key = key.to_s if key.kind_of?(Symbol) + [key, value] + end + # Useful default for OAuth and caching. + # Only to be used for non-Array inputs. Arrays should preserve order. + new_query_values.sort! + end + + # new_query_values have form [['key1', 'value1'], ['key2', 'value2']] + buffer = "".dup + new_query_values.each do |key, value| + encoded_key = URI.encode_component( + key, CharacterClassesRegexps::UNRESERVED + ) + if value == nil + buffer << "#{encoded_key}&" + elsif value.kind_of?(Array) + value.each do |sub_value| + encoded_value = URI.encode_component( + sub_value, CharacterClassesRegexps::UNRESERVED + ) + buffer << "#{encoded_key}=#{encoded_value}&" + end + else + encoded_value = URI.encode_component( + value, CharacterClassesRegexps::UNRESERVED + ) + buffer << "#{encoded_key}=#{encoded_value}&" + end + end + self.query = buffer.chop + end + + ## + # The HTTP request URI for this URI. This is the path and the + # query string. + # + # @return [String] The request URI required for an HTTP request. + def request_uri + return nil if self.absolute? && self.scheme !~ /^https?$/i + return ( + (!self.path.empty? ? self.path : SLASH) + + (self.query ? "?#{self.query}" : EMPTY_STR) + ) + end + + ## + # Sets the HTTP request URI for this URI. + # + # @param [String, #to_str] new_request_uri The new HTTP request URI. + def request_uri=(new_request_uri) + if !new_request_uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_request_uri.class} into String." + end + if self.absolute? && self.scheme !~ /^https?$/i + raise InvalidURIError, + "Cannot set an HTTP request URI for a non-HTTP URI." + end + new_request_uri = new_request_uri.to_str + path_component = new_request_uri[/^([^\?]*)\??(?:.*)$/, 1] + query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1] + path_component = path_component.to_s + path_component = (!path_component.empty? ? path_component : SLASH) + self.path = path_component + self.query = query_component + + # Reset dependent values + remove_composite_values + end + + ## + # The fragment component for this URI. + # + # @return [String] The fragment component. + attr_reader :fragment + + ## + # The fragment component for this URI, normalized. + # + # @return [String] The fragment component, normalized. + def normalized_fragment + return nil unless self.fragment + return @normalized_fragment unless @normalized_fragment == NONE + @normalized_fragment = begin + component = Addressable::URI.normalize_component( + self.fragment, + Addressable::URI::NormalizeCharacterClasses::FRAGMENT + ) + component == "" ? nil : component + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_fragment) + @normalized_fragment + end + + ## + # Sets the fragment component for this URI. + # + # @param [String, #to_str] new_fragment The new fragment component. + def fragment=(new_fragment) + if new_fragment && !new_fragment.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_fragment.class} into String." + end + @fragment = new_fragment ? new_fragment.to_str : nil + + # Reset dependent values + @normalized_fragment = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # Determines if the scheme indicates an IP-based protocol. + # + # @return [TrueClass, FalseClass] + # true if the scheme indicates an IP-based protocol. + # false otherwise. + def ip_based? + if self.scheme + return URI.ip_based_schemes.include?( + self.scheme.strip.downcase) + end + return false + end + + ## + # Determines if the URI is relative. + # + # @return [TrueClass, FalseClass] + # true if the URI is relative. false + # otherwise. + def relative? + return self.scheme.nil? + end + + ## + # Determines if the URI is absolute. + # + # @return [TrueClass, FalseClass] + # true if the URI is absolute. false + # otherwise. + def absolute? + return !relative? + end + + ## + # Joins two URIs together. + # + # @param [String, Addressable::URI, #to_str] The URI to join with. + # + # @return [Addressable::URI] The joined URI. + def join(uri) + if !uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{uri.class} into String." + end + if !uri.kind_of?(URI) + # Otherwise, convert to a String, then parse. + uri = URI.parse(uri.to_str) + end + if uri.to_s.empty? + return self.dup + end + + joined_scheme = nil + joined_user = nil + joined_password = nil + joined_host = nil + joined_port = nil + joined_path = nil + joined_query = nil + joined_fragment = nil + + # Section 5.2.2 of RFC 3986 + if uri.scheme != nil + joined_scheme = uri.scheme + joined_user = uri.user + joined_password = uri.password + joined_host = uri.host + joined_port = uri.port + joined_path = URI.normalize_path(uri.path) + joined_query = uri.query + else + if uri.authority != nil + joined_user = uri.user + joined_password = uri.password + joined_host = uri.host + joined_port = uri.port + joined_path = URI.normalize_path(uri.path) + joined_query = uri.query + else + if uri.path == nil || uri.path.empty? + joined_path = self.path + if uri.query != nil + joined_query = uri.query + else + joined_query = self.query + end + else + if uri.path[0..0] == SLASH + joined_path = URI.normalize_path(uri.path) + else + base_path = self.path.dup + base_path = EMPTY_STR if base_path == nil + base_path = URI.normalize_path(base_path) + + # Section 5.2.3 of RFC 3986 + # + # Removes the right-most path segment from the base path. + if base_path.include?(SLASH) + base_path.sub!(/\/[^\/]+$/, SLASH) + else + base_path = EMPTY_STR + end + + # If the base path is empty and an authority segment has been + # defined, use a base path of SLASH + if base_path.empty? && self.authority != nil + base_path = SLASH + end + + joined_path = URI.normalize_path(base_path + uri.path) + end + joined_query = uri.query + end + joined_user = self.user + joined_password = self.password + joined_host = self.host + joined_port = self.port + end + joined_scheme = self.scheme + end + joined_fragment = uri.fragment + + return self.class.new( + :scheme => joined_scheme, + :user => joined_user, + :password => joined_password, + :host => joined_host, + :port => joined_port, + :path => joined_path, + :query => joined_query, + :fragment => joined_fragment + ) + end + alias_method :+, :join + + ## + # Destructive form of join. + # + # @param [String, Addressable::URI, #to_str] The URI to join with. + # + # @return [Addressable::URI] The joined URI. + # + # @see Addressable::URI#join + def join!(uri) + replace_self(self.join(uri)) + end + + ## + # Merges a URI with a Hash of components. + # This method has different behavior from join. Any + # components present in the hash parameter will override the + # original components. The path component is not treated specially. + # + # @param [Hash, Addressable::URI, #to_hash] The components to merge with. + # + # @return [Addressable::URI] The merged URI. + # + # @see Hash#merge + def merge(hash) + unless hash.respond_to?(:to_hash) + raise TypeError, "Can't convert #{hash.class} into Hash." + end + hash = hash.to_hash + + if hash.has_key?(:authority) + if (hash.keys & [:userinfo, :user, :password, :host, :port]).any? + raise ArgumentError, + "Cannot specify both an authority and any of the components " + + "within the authority." + end + end + if hash.has_key?(:userinfo) + if (hash.keys & [:user, :password]).any? + raise ArgumentError, + "Cannot specify both a userinfo and either the user or password." + end + end + + uri = self.class.new + uri.defer_validation do + # Bunch of crazy logic required because of the composite components + # like userinfo and authority. + uri.scheme = + hash.has_key?(:scheme) ? hash[:scheme] : self.scheme + if hash.has_key?(:authority) + uri.authority = + hash.has_key?(:authority) ? hash[:authority] : self.authority + end + if hash.has_key?(:userinfo) + uri.userinfo = + hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo + end + if !hash.has_key?(:userinfo) && !hash.has_key?(:authority) + uri.user = + hash.has_key?(:user) ? hash[:user] : self.user + uri.password = + hash.has_key?(:password) ? hash[:password] : self.password + end + if !hash.has_key?(:authority) + uri.host = + hash.has_key?(:host) ? hash[:host] : self.host + uri.port = + hash.has_key?(:port) ? hash[:port] : self.port + end + uri.path = + hash.has_key?(:path) ? hash[:path] : self.path + uri.query = + hash.has_key?(:query) ? hash[:query] : self.query + uri.fragment = + hash.has_key?(:fragment) ? hash[:fragment] : self.fragment + end + + return uri + end + + ## + # Destructive form of merge. + # + # @param [Hash, Addressable::URI, #to_hash] The components to merge with. + # + # @return [Addressable::URI] The merged URI. + # + # @see Addressable::URI#merge + def merge!(uri) + replace_self(self.merge(uri)) + end + + ## + # Returns the shortest normalized relative form of this URI that uses the + # supplied URI as a base for resolution. Returns an absolute URI if + # necessary. This is effectively the opposite of route_to. + # + # @param [String, Addressable::URI, #to_str] uri The URI to route from. + # + # @return [Addressable::URI] + # The normalized relative URI that is equivalent to the original URI. + def route_from(uri) + uri = URI.parse(uri).normalize + normalized_self = self.normalize + if normalized_self.relative? + raise ArgumentError, "Expected absolute URI, got: #{self.to_s}" + end + if uri.relative? + raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}" + end + if normalized_self == uri + return Addressable::URI.parse("##{normalized_self.fragment}") + end + components = normalized_self.to_hash + if normalized_self.scheme == uri.scheme + components[:scheme] = nil + if normalized_self.authority == uri.authority + components[:user] = nil + components[:password] = nil + components[:host] = nil + components[:port] = nil + if normalized_self.path == uri.path + components[:path] = nil + if normalized_self.query == uri.query + components[:query] = nil + end + else + if uri.path != SLASH and components[:path] + self_splitted_path = split_path(components[:path]) + uri_splitted_path = split_path(uri.path) + self_dir = self_splitted_path.shift + uri_dir = uri_splitted_path.shift + while !self_splitted_path.empty? && !uri_splitted_path.empty? and self_dir == uri_dir + self_dir = self_splitted_path.shift + uri_dir = uri_splitted_path.shift + end + components[:path] = (uri_splitted_path.fill('..') + [self_dir] + self_splitted_path).join(SLASH) + end + end + end + end + # Avoid network-path references. + if components[:host] != nil + components[:scheme] = normalized_self.scheme + end + return Addressable::URI.new( + :scheme => components[:scheme], + :user => components[:user], + :password => components[:password], + :host => components[:host], + :port => components[:port], + :path => components[:path], + :query => components[:query], + :fragment => components[:fragment] + ) + end + + ## + # Returns the shortest normalized relative form of the supplied URI that + # uses this URI as a base for resolution. Returns an absolute URI if + # necessary. This is effectively the opposite of route_from. + # + # @param [String, Addressable::URI, #to_str] uri The URI to route to. + # + # @return [Addressable::URI] + # The normalized relative URI that is equivalent to the supplied URI. + def route_to(uri) + return URI.parse(uri).route_from(self) + end + + ## + # Returns a normalized URI object. + # + # NOTE: This method does not attempt to fully conform to specifications. + # It exists largely to correct other people's failures to read the + # specifications, and also to deal with caching issues since several + # different URIs may represent the same resource and should not be + # cached multiple times. + # + # @return [Addressable::URI] The normalized URI. + def normalize + # This is a special exception for the frequently misused feed + # URI scheme. + if normalized_scheme == "feed" + if self.to_s =~ /^feed:\/*http:\/*/ + return URI.parse( + self.to_s[/^feed:\/*(http:\/*.*)/, 1] + ).normalize + end + end + + return self.class.new( + :scheme => normalized_scheme, + :authority => normalized_authority, + :path => normalized_path, + :query => normalized_query, + :fragment => normalized_fragment + ) + end + + ## + # Destructively normalizes this URI object. + # + # @return [Addressable::URI] The normalized URI. + # + # @see Addressable::URI#normalize + def normalize! + replace_self(self.normalize) + end + + ## + # Creates a URI suitable for display to users. If semantic attacks are + # likely, the application should try to detect these and warn the user. + # See RFC 3986, + # section 7.6 for more information. + # + # @return [Addressable::URI] A URI suitable for display purposes. + def display_uri + display_uri = self.normalize + display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host) + return display_uri + end + + ## + # Returns true if the URI objects are equal. This method + # normalizes both URIs before doing the comparison, and allows comparison + # against Strings. + # + # @param [Object] uri The URI to compare. + # + # @return [TrueClass, FalseClass] + # true if the URIs are equivalent, false + # otherwise. + def ===(uri) + if uri.respond_to?(:normalize) + uri_string = uri.normalize.to_s + else + begin + uri_string = ::Addressable::URI.parse(uri).normalize.to_s + rescue InvalidURIError, TypeError + return false + end + end + return self.normalize.to_s == uri_string + end + + ## + # Returns true if the URI objects are equal. This method + # normalizes both URIs before doing the comparison. + # + # @param [Object] uri The URI to compare. + # + # @return [TrueClass, FalseClass] + # true if the URIs are equivalent, false + # otherwise. + def ==(uri) + return false unless uri.kind_of?(URI) + return self.normalize.to_s == uri.normalize.to_s + end + + ## + # Returns true if the URI objects are equal. This method + # does NOT normalize either URI before doing the comparison. + # + # @param [Object] uri The URI to compare. + # + # @return [TrueClass, FalseClass] + # true if the URIs are equivalent, false + # otherwise. + def eql?(uri) + return false unless uri.kind_of?(URI) + return self.to_s == uri.to_s + end + + ## + # A hash value that will make a URI equivalent to its normalized + # form. + # + # @return [Integer] A hash of the URI. + def hash + @hash ||= self.to_s.hash * -1 + end + + ## + # Clones the URI object. + # + # @return [Addressable::URI] The cloned URI. + def dup + duplicated_uri = self.class.new( + :scheme => self.scheme ? self.scheme.dup : nil, + :user => self.user ? self.user.dup : nil, + :password => self.password ? self.password.dup : nil, + :host => self.host ? self.host.dup : nil, + :port => self.port, + :path => self.path ? self.path.dup : nil, + :query => self.query ? self.query.dup : nil, + :fragment => self.fragment ? self.fragment.dup : nil + ) + return duplicated_uri + end + + ## + # Omits components from a URI. + # + # @param [Symbol] *components The components to be omitted. + # + # @return [Addressable::URI] The URI with components omitted. + # + # @example + # uri = Addressable::URI.parse("http://example.com/path?query") + # #=> # + # uri.omit(:scheme, :authority) + # #=> # + def omit(*components) + invalid_components = components - [ + :scheme, :user, :password, :userinfo, :host, :port, :authority, + :path, :query, :fragment + ] + unless invalid_components.empty? + raise ArgumentError, + "Invalid component names: #{invalid_components.inspect}." + end + duplicated_uri = self.dup + duplicated_uri.defer_validation do + components.each do |component| + duplicated_uri.send((component.to_s + "=").to_sym, nil) + end + duplicated_uri.user = duplicated_uri.normalized_user + end + duplicated_uri + end + + ## + # Destructive form of omit. + # + # @param [Symbol] *components The components to be omitted. + # + # @return [Addressable::URI] The URI with components omitted. + # + # @see Addressable::URI#omit + def omit!(*components) + replace_self(self.omit(*components)) + end + + ## + # Determines if the URI is an empty string. + # + # @return [TrueClass, FalseClass] + # Returns true if empty, false otherwise. + def empty? + return self.to_s.empty? + end + + ## + # Converts the URI to a String. + # + # @return [String] The URI's String representation. + def to_s + if self.scheme == nil && self.path != nil && !self.path.empty? && + self.path =~ NORMPATH + raise InvalidURIError, + "Cannot assemble URI string with ambiguous path: '#{self.path}'" + end + @uri_string ||= begin + uri_string = String.new + uri_string << "#{self.scheme}:" if self.scheme != nil + uri_string << "//#{self.authority}" if self.authority != nil + uri_string << self.path.to_s + uri_string << "?#{self.query}" if self.query != nil + uri_string << "##{self.fragment}" if self.fragment != nil + uri_string.force_encoding(Encoding::UTF_8) + uri_string + end + end + + ## + # URI's are glorified Strings. Allow implicit conversion. + alias_method :to_str, :to_s + + ## + # Returns a Hash of the URI components. + # + # @return [Hash] The URI as a Hash of components. + def to_hash + return { + :scheme => self.scheme, + :user => self.user, + :password => self.password, + :host => self.host, + :port => self.port, + :path => self.path, + :query => self.query, + :fragment => self.fragment + } + end + + ## + # Returns a String representation of the URI object's state. + # + # @return [String] The URI object's state, as a String. + def inspect + sprintf("#<%s:%#0x URI:%s>", self.class.to_s, self.object_id, self.to_s) + end + + ## + # This method allows you to make several changes to a URI simultaneously, + # which separately would cause validation errors, but in conjunction, + # are valid. The URI will be revalidated as soon as the entire block has + # been executed. + # + # @param [Proc] block + # A set of operations to perform on a given URI. + def defer_validation + raise LocalJumpError, "No block given." unless block_given? + @validation_deferred = true + yield + @validation_deferred = false + validate + ensure + @validation_deferred = false + end + + def encode_with(coder) + instance_variables.each do |ivar| + value = instance_variable_get(ivar) + if value != NONE + key = ivar.to_s.slice(1..-1) + coder[key] = value + end + end + nil + end + + def init_with(coder) + reset_ivs + coder.map.each do |key, value| + instance_variable_set("@#{key}", value) + end + nil + end + + protected + SELF_REF = '.' + PARENT = '..' + + RULE_2A = /\/\.\/|\/\.$/ + RULE_2B_2C = /\/([^\/]*)\/\.\.\/|\/([^\/]*)\/\.\.$/ + RULE_2D = /^\.\.?\/?/ + RULE_PREFIXED_PARENT = /^\/\.\.?\/|^(\/\.\.?)+\/?$/ + + ## + # Resolves paths to their simplest form. + # + # @param [String] path The path to normalize. + # + # @return [String] The normalized path. + def self.normalize_path(path) + # Section 5.2.4 of RFC 3986 + + return if path.nil? + normalized_path = path.dup + loop do + mod ||= normalized_path.gsub!(RULE_2A, SLASH) + + pair = normalized_path.match(RULE_2B_2C) + if pair + parent = pair[1] + current = pair[2] + else + parent = nil + current = nil + end + + regexp = "/#{Regexp.escape(parent.to_s)}/\\.\\./|" + regexp += "(/#{Regexp.escape(current.to_s)}/\\.\\.$)" + + if pair && ((parent != SELF_REF && parent != PARENT) || + (current != SELF_REF && current != PARENT)) + mod ||= normalized_path.gsub!(Regexp.new(regexp), SLASH) + end + + mod ||= normalized_path.gsub!(RULE_2D, EMPTY_STR) + # Non-standard, removes prefixed dotted segments from path. + mod ||= normalized_path.gsub!(RULE_PREFIXED_PARENT, SLASH) + break if mod.nil? + end + + normalized_path + end + + ## + # Ensures that the URI is valid. + def validate + return if !!@validation_deferred + if self.scheme != nil && self.ip_based? && + (self.host == nil || self.host.empty?) && + (self.path == nil || self.path.empty?) + raise InvalidURIError, + "Absolute URI missing hierarchical segment: '#{self.to_s}'" + end + if self.host == nil + if self.port != nil || + self.user != nil || + self.password != nil + raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'" + end + end + if self.path != nil && !self.path.empty? && self.path[0..0] != SLASH && + self.authority != nil + raise InvalidURIError, + "Cannot have a relative path with an authority set: '#{self.to_s}'" + end + if self.path != nil && !self.path.empty? && + self.path[0..1] == SLASH + SLASH && self.authority == nil + raise InvalidURIError, + "Cannot have a path with two leading slashes " + + "without an authority set: '#{self.to_s}'" + end + unreserved = CharacterClasses::UNRESERVED + sub_delims = CharacterClasses::SUB_DELIMS + if !self.host.nil? && (self.host =~ /[<>{}\/\\\?\#\@"[[:space:]]]/ || + (self.host[/^\[(.*)\]$/, 1] != nil && self.host[/^\[(.*)\]$/, 1] !~ + Regexp.new("^[#{unreserved}#{sub_delims}:]*$"))) + raise InvalidURIError, "Invalid character in host: '#{self.host.to_s}'" + end + return nil + end + + ## + # Replaces the internal state of self with the specified URI's state. + # Used in destructive operations to avoid massive code repetition. + # + # @param [Addressable::URI] uri The URI to replace self with. + # + # @return [Addressable::URI] self. + def replace_self(uri) + # Reset dependent values + reset_ivs + + @scheme = uri.scheme + @user = uri.user + @password = uri.password + @host = uri.host + @port = uri.port + @path = uri.path + @query = uri.query + @fragment = uri.fragment + return self + end + + ## + # Splits path string with "/" (slash). + # It is considered that there is empty string after last slash when + # path ends with slash. + # + # @param [String] path The path to split. + # + # @return [Array] An array of parts of path. + def split_path(path) + splitted = path.split(SLASH) + splitted << EMPTY_STR if path.end_with? SLASH + splitted + end + + ## + # Resets composite values for the entire URI + # + # @api private + def remove_composite_values + @uri_string = nil + @hash = nil + end + + ## + # Converts the string to be UTF-8 if it is not already UTF-8 + # + # @api private + def force_utf8_encoding_if_needed(str) + if str && str.encoding != Encoding::UTF_8 + str.force_encoding(Encoding::UTF_8) + end + end + + private + + ## + # Resets instance variables + # + # @api private + def reset_ivs + @scheme = nil + @user = nil + @normalized_scheme = NONE + @normalized_user = NONE + @uri_string = nil + @hash = nil + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @password = nil + @normalized_authority = nil + @port = nil + @normalized_password = NONE + @host = nil + @normalized_host = nil + @normalized_port = NONE + @path = EMPTY_STR + @normalized_path = nil + @normalized_query = NONE + @fragment = nil + @normalized_fragment = NONE + @query = nil + end + + NONE = Module.new.freeze + + private_constant :NONE + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/version.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/version.rb new file mode 100644 index 0000000..b1254e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.9.0/lib/addressable/version.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +# Used to prevent the class/module from being loaded more than once +if !defined?(Addressable::VERSION) + module Addressable + module VERSION + MAJOR = 2 + MINOR = 9 + TINY = 0 + + STRING = [MAJOR, MINOR, TINY].join('.') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/LICENSE b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/LICENSE new file mode 100644 index 0000000..a1f19ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/LICENSE @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/bigdecimal.gemspec b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/bigdecimal.gemspec new file mode 100644 index 0000000..114b6b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/bigdecimal.gemspec @@ -0,0 +1,62 @@ +# coding: utf-8 + +name = File.basename(__FILE__, '.*') +source_version = ["", "ext/#{name}/"].find do |dir| + begin + break File.foreach(File.join(__dir__, "#{dir}#{name}.c")) {|line| + break $1.sub("-", ".") if /^#define\s+#{name.upcase}_VERSION\s+"(.+)"/o =~ line + } + rescue Errno::ENOENT + end +end or raise "can't find #{name.upcase}_VERSION" + +Gem::Specification.new do |s| + s.name = name + s.version = source_version + s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"] + s.email = ["mrkn@mrkn.jp"] + + s.summary = "Arbitrary-precision decimal floating-point number library." + s.description = "This library provides arbitrary-precision decimal floating-point number class." + s.homepage = "https://github.com/ruby/bigdecimal" + s.licenses = ["Ruby", "BSD-2-Clause"] + + s.require_paths = %w[lib] + s.files = %w[ + LICENSE + bigdecimal.gemspec + lib/bigdecimal.rb + lib/bigdecimal/jacobian.rb + lib/bigdecimal/ludcmp.rb + lib/bigdecimal/math.rb + lib/bigdecimal/newton.rb + lib/bigdecimal/util.rb + sample/linear.rb + sample/nlsolve.rb + sample/pi.rb + sig/big_decimal_util.rbs + sig/big_decimal.rbs + sig/big_math.rbs + ] + if Gem::Platform === s.platform and s.platform =~ 'java' or RUBY_ENGINE == 'jruby' + s.platform = 'java' + else + s.extensions = %w[ext/bigdecimal/extconf.rb] + s.files += %w[ + ext/bigdecimal/bigdecimal.c + ext/bigdecimal/bigdecimal.h + ext/bigdecimal/bits.h + ext/bigdecimal/div.h + ext/bigdecimal/feature.h + ext/bigdecimal/missing.c + ext/bigdecimal/missing.h + ext/bigdecimal/ntt.h + ext/bigdecimal/missing/dtoa.c + ext/bigdecimal/static_assert.h + ] + end + + s.required_ruby_version = Gem::Requirement.new(">= 2.6.0") + + s.metadata["changelog_uri"] = s.homepage + "/blob/master/CHANGES.md" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/Makefile b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/Makefile new file mode 100644 index 0000000..d69f069 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/Makefile @@ -0,0 +1,274 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /Users/ben/.rubies/ruby-3.4.1/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /Users/ben/.rubies/ruby-3.4.1/include/ruby-3.4.0/arm64-darwin24 +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/Users/ben/.rubies/ruby-3.4.1 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(SDKROOT)$(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = clang +CXX = clang++ -std=gnu++11 +LIBRUBY = $(LIBRUBY_A) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) -fdeclspec $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wextra-tokens -Wdeprecated-declarations -Wdivision-by-zero -Wdiv-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wold-style-definition -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fno-common +CFLAGS = $(CCDLFLAGS) $(cflags) -pipe $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_BUILTIN___BUILTIN_CLZ -DHAVE_BUILTIN___BUILTIN_CLZL -DHAVE_BUILTIN___BUILTIN_CLZLL -DHAVE_FLOAT_H -DHAVE_MATH_H -DHAVE_STDBOOL_H -DHAVE_STDLIB_H -DHAVE_RUBY_ATOMIC_H -DHAVE_RUBY_INTERNAL_HAS_BUILTIN_H -DHAVE_RUBY_INTERNAL_STATIC_ASSERT_H -DHAVE_RB_COMPLEX_REAL -DHAVE_RB_COMPLEX_IMAG -DHAVE_RB_OPTS_EXCEPTION_P -DHAVE_RB_CATEGORY_WARN -DHAVE_CONST_RB_WARN_CATEGORY_DEPRECATED -DHAVE_CONST_RUBY_TYPED_EMBEDDABLE -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/libyaml/include -I/opt/homebrew/opt/gdbm/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) -fdeclspec $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -L/opt/homebrew/Cellar/readline/8.2.13/lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -L/opt/homebrew/Cellar/gdbm/1.24/lib +dldflags = -L/opt/homebrew/Cellar/readline/8.2.13/lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -L/opt/homebrew/Cellar/gdbm/1.24/lib -Wl,-undefined,dynamic_lookup -bundle_loader '$(BUILTRUBY)' +ARCH_FLAG = -arch arm64 +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -dynamic -bundle +LDSHAREDXX = $(CXX) -dynamic -bundle +POSTLINK = dsymutil $@ 2>/dev/null; { test -z '$(RUBY_CODESIGN)' || codesign -s '$(RUBY_CODESIGN)' $@; } +AR = ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby.3.4 +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = arm64-darwin24 +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir -p +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) /opt/homebrew/opt/readline/lib /opt/homebrew/opt/libyaml/lib /opt/homebrew/opt/gdbm/lib +LIBPATH = -L. -L$(libdir) -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/libyaml/lib -L/opt/homebrew/opt/gdbm/lib +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = -lpthread +ORIG_SRCS = bigdecimal.c missing.c +SRCS = $(ORIG_SRCS) +OBJS = bigdecimal.o missing.o +HDRS = $(srcdir)/bigdecimal.h $(srcdir)/bits.h $(srcdir)/div.h $(srcdir)/feature.h $(srcdir)/missing.h $(srcdir)/ntt.h $(srcdir)/static_assert.h +LOCAL_HDRS = +TARGET = bigdecimal +TARGET_NAME = bigdecimal +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).bundle +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) $(TARGET_SO:=.dSYM) +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time +BIGDECIMAL_RB = $(srcdir)/../../lib/bigdecimal.rb + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object $(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.c b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.c new file mode 100644 index 0000000..182d66f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.c @@ -0,0 +1,6207 @@ +/* + * + * Ruby BigDecimal(Variable decimal precision) extension library. + * + * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) + * + */ + +/* #define BIGDECIMAL_DEBUG 1 */ + +#include "bigdecimal.h" +#include "ruby/util.h" + +#ifndef BIGDECIMAL_DEBUG +# undef NDEBUG +# define NDEBUG +#endif +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "bits.h" +#include "ntt.h" +#include "div.h" +#include "static_assert.h" + +#define BIGDECIMAL_VERSION "4.1.2" + +/* Make sure VPMULT_BATCH_SIZE*BASE*BASE does not overflow DECDIG_DBL */ +#define VPMULT_BATCH_SIZE 16 +#define NTT_MULTIPLICATION_THRESHOLD 450 +#define NEWTON_RAPHSON_DIVISION_THRESHOLD 100 +#define SIGNED_VALUE_MAX INTPTR_MAX +#define SIGNED_VALUE_MIN INTPTR_MIN +#define MUL_OVERFLOW_SIGNED_VALUE_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, SIGNED_VALUE_MIN, SIGNED_VALUE_MAX) +#define ADD_OVERFLOW_SIGNED_VALUE_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, SIGNED_VALUE_MIN, SIGNED_VALUE_MAX) + +/* max_value = 0.9999_9999_9999E[exponent], exponent <= SIGNED_VALUE_MAX */ +#define VP_EXPONENT_MAX (SIGNED_VALUE_MAX / BASE_FIG) +/* min_value = 0.0001_0000_0000E[exponent], exponent-(BASE_FIG-1) >= SIGNED_VALUE_MIN */ +#define VP_EXPONENT_MIN ((SIGNED_VALUE_MIN + BASE_FIG - 1) / BASE_FIG) +#define EXPONENT_MAX (VP_EXPONENT_MAX * BASE_FIG) +#define EXPONENT_MIN (VP_EXPONENT_MIN * BASE_FIG - (BASE_FIG - 1)) + +VALUE rb_cBigDecimal; + +static ID id_BigDecimal_exception_mode; +static ID id_BigDecimal_rounding_mode; +static ID id_BigDecimal_precision_limit; + +static ID id_up; +static ID id_down; +static ID id_truncate; +static ID id_half_up; +static ID id_default; +static ID id_half_down; +static ID id_half_even; +static ID id_banker; +static ID id_ceiling; +static ID id_ceil; +static ID id_floor; +static ID id_to_r; +static ID id_eq; +static ID id_half; + +#define RBD_NUM_ROUNDING_MODES 11 + +static struct { + ID id; + uint8_t mode; +} rbd_rounding_modes[RBD_NUM_ROUNDING_MODES]; + +static inline BDVALUE +bdvalue_nonnullable(NULLABLE_BDVALUE v) +{ + assert(v.real_or_null != NULL); + return (BDVALUE) { v.bigdecimal_or_nil, v.real_or_null }; +} + +static inline NULLABLE_BDVALUE +bdvalue_nullable(BDVALUE v) +{ + return (NULLABLE_BDVALUE) { v.bigdecimal, v.real }; +} + +#define BASE_FIG BIGDECIMAL_COMPONENT_FIGURES +#define BASE BIGDECIMAL_BASE + +#define HALF_BASE (BASE/2) +#define BASE1 (BASE/10) + +#ifndef MAYBE_UNUSED +# define MAYBE_UNUSED(x) x +#endif + +#define BIGDECIMAL_POSITIVE_P(bd) ((bd)->sign > 0) +#define BIGDECIMAL_NEGATIVE_P(bd) ((bd)->sign < 0) + +/* + * ================== Memory allocation ============================ + */ + +#ifdef BIGDECIMAL_DEBUG +static size_t rbd_allocation_count = 0; /* Memory allocation counter */ +static inline void +atomic_allocation_count_inc(void) +{ + RUBY_ATOMIC_SIZE_INC(rbd_allocation_count); +} +static inline void +atomic_allocation_count_dec_nounderflow(void) +{ + if (rbd_allocation_count == 0) return; + RUBY_ATOMIC_SIZE_DEC(rbd_allocation_count); +} +static void +check_allocation_count_nonzero(void) +{ + if (rbd_allocation_count != 0) return; + rb_bug("[bigdecimal][rbd_free_struct] Too many memory free calls"); +} +#else +# define atomic_allocation_count_inc() /* nothing */ +# define atomic_allocation_count_dec_nounderflow() /* nothing */ +# define check_allocation_count_nonzero() /* nothing */ +#endif /* BIGDECIMAL_DEBUG */ + +/* VpMult VpDivd helpers */ +#define VPMULT_RESULT_PREC(a, b) (a->Prec + b->Prec) +/* To calculate VpDivd with n-digits precision, quotient needs n+2*BASE_FIG-1 digits space */ +/* In the worst precision case 0001_1111_1111 / 9999 = 0000_0001_1112, there are 2*BASE_FIG-1 leading zeros */ +#define VPDIVD_QUO_DIGITS(required_digits) ((required_digits) + 2 * BASE_FIG - 1) +/* Required r.MaxPrec for calculating VpDivd(c, r, a, b) */ +#define VPDIVD_REM_PREC(a, b, c) Max(a->Prec, b->Prec + c->MaxPrec - 1) + +static NULLABLE_BDVALUE +CreateFromString(const char *str, VALUE klass, bool strict_p, bool raise_exception); + +PUREFUNC(static inline size_t rbd_struct_size(size_t const)); + +static inline size_t +rbd_struct_size(size_t const internal_digits) +{ + size_t const frac_len = (internal_digits == 0) ? 1 : internal_digits; + return offsetof(Real, frac) + frac_len * sizeof(DECDIG); +} + +/* + * ================== Ruby Interface part ========================== + */ +#define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f) + +/* + * VP routines used in BigDecimal part + */ +static unsigned short VpGetException(void); +static void VpSetException(unsigned short f); +static void VpCheckException(Real *p, bool always); +static VALUE CheckGetValue(BDVALUE v); +static void VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v); +static int VpLimitRound(Real *c, size_t ixDigit); +static int VPrint(FILE *fp,const char *cntl_chr,Real *a); + +/* + * **** BigDecimal part **** + */ + +static VALUE BigDecimal_nan(void); +static VALUE BigDecimal_positive_infinity(void); +static VALUE BigDecimal_negative_infinity(void); +static VALUE BigDecimal_positive_zero(void); +static VALUE BigDecimal_negative_zero(void); +static VALUE BigDecimal_addsub_with_coerce(VALUE self, VALUE r, size_t prec, int operation); +static VALUE BigDecimal_mult_with_coerce(VALUE self, VALUE r, size_t prec); + +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# undef RUBY_TYPED_FROZEN_SHAREABLE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + +#ifdef RUBY_TYPED_EMBEDDABLE +# define HAVE_RUBY_TYPED_EMBEDDABLE 1 +#else +# ifdef HAVE_CONST_RUBY_TYPED_EMBEDDABLE +# define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE +# define HAVE_RUBY_TYPED_EMBEDDABLE 1 +# else +# define RUBY_TYPED_EMBEDDABLE 0 +# endif +#endif + +static size_t +BigDecimal_memsize(const void *ptr) +{ +#ifdef HAVE_RUBY_TYPED_EMBEDDABLE + return 0; // Entirely embedded +#else + const Real *pv = ptr; + return (sizeof(*pv) + pv->MaxPrec * sizeof(DECDIG)); +#endif +} + +static const rb_data_type_t BigDecimal_data_type = { + .wrap_struct_name = "BigDecimal", + .function = { + .dmark = 0, + .dfree = RUBY_DEFAULT_FREE, + .dsize = BigDecimal_memsize, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, +}; + +static VALUE +BigDecimal_allocate(size_t const internal_digits) +{ + const size_t size = rbd_struct_size(internal_digits); + VALUE bd = rb_data_typed_object_zalloc(rb_cBigDecimal, size, &BigDecimal_data_type); + Real *vp; + TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); + vp->MaxPrec = internal_digits; + RB_OBJ_FREEZE(bd); + return bd; +} + +static VALUE +BigDecimal_allocate_decimal_digits(size_t const decimal_digits) +{ + return BigDecimal_allocate(roomof(decimal_digits, BASE_FIG)); +} + +static Real * +VpPtr(VALUE obj) +{ + Real *vp; + TypedData_Get_Struct(obj, Real, &BigDecimal_data_type, vp); + return vp; +} + +MAYBE_UNUSED(static inline BDVALUE rbd_allocate_struct_zero_wrap(int sign, size_t const digits)); +#define NewZeroWrap rbd_allocate_struct_zero_wrap +static BDVALUE +rbd_allocate_struct_zero_wrap(int sign, size_t const digits) +{ + VALUE obj = BigDecimal_allocate_decimal_digits(digits); + Real *real = VpPtr(obj); + VpSetZero(real, sign); + return (BDVALUE) { obj, real }; +} + +static inline int +is_kind_of_BigDecimal(VALUE const v) +{ + return rb_typeddata_is_kind_of(v, &BigDecimal_data_type); +} + +NORETURN(static void cannot_be_coerced_into_BigDecimal(VALUE, VALUE)); + +static void +cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v) +{ + VALUE str; + + if (rb_special_const_p(v)) { + str = rb_inspect(v); + } + else { + str = rb_class_name(rb_obj_class(v)); + } + + str = rb_str_cat2(rb_str_dup(str), " can't be coerced into BigDecimal"); + rb_exc_raise(rb_exc_new3(exc_class, str)); +} + +static inline VALUE BigDecimal_div2(VALUE, VALUE, VALUE); +static VALUE rb_inum_convert_to_BigDecimal(VALUE val); +static VALUE rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); +static VALUE rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); +static VALUE rb_cstr_convert_to_BigDecimal(const char *c_str, int raise_exception); +static VALUE rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); + +static NULLABLE_BDVALUE +GetBDValueWithPrecInternal(VALUE v, size_t prec, int must) +{ + switch(TYPE(v)) { + case T_FLOAT: + v = rb_float_convert_to_BigDecimal(v, 0, true); + break; + + case T_RATIONAL: + v = rb_rational_convert_to_BigDecimal(v, prec, true); + break; + + case T_DATA: + if (!is_kind_of_BigDecimal(v)) { + goto SomeOneMayDoIt; + } + break; + + case T_FIXNUM: + case T_BIGNUM: { + v = rb_inum_convert_to_BigDecimal(v); + break; + } + + default: + goto SomeOneMayDoIt; + } + + Real *vp = VpPtr(v); + return (NULLABLE_BDVALUE) { v, vp }; + +SomeOneMayDoIt: + if (must) { + cannot_be_coerced_into_BigDecimal(rb_eTypeError, v); + } + return (NULLABLE_BDVALUE) { Qnil, NULL }; /* NULL means to coerce */ +} + +static inline NULLABLE_BDVALUE +GetBDValueWithPrec(VALUE v, size_t prec) +{ + return GetBDValueWithPrecInternal(v, prec, 0); +} + + +static inline BDVALUE +GetBDValueWithPrecMust(VALUE v, size_t prec) +{ + return bdvalue_nonnullable(GetBDValueWithPrecInternal(v, prec, 1)); +} + +// self must be a receiver of BigDecimal instance method or a gc guarded BigDecimal object. +static inline Real* +GetSelfVpValue(VALUE self) +{ + return GetBDValueWithPrecMust(self, 0).real; +} + +static inline BDVALUE +GetBDValueMust(VALUE v) +{ + return GetBDValueWithPrecMust(v, 0); +} + +/* call-seq: + * BigDecimal.double_fig -> integer + * + * Returns the number of digits a Float object is allowed to have; + * the result is system-dependent: + * + * BigDecimal.double_fig # => 16 + * + */ +static inline VALUE +BigDecimal_double_fig(VALUE self) +{ + return INT2FIX(BIGDECIMAL_DOUBLE_FIGURES); +} + +static void +VpCountPrecisionAndScale(Real *p, ssize_t *out_precision, ssize_t *out_scale) +{ + if (out_precision == NULL && out_scale == NULL) + return; + if (VpIsZero(p) || !VpIsDef(p)) { + zero: + if (out_precision) *out_precision = 0; + if (out_scale) *out_scale = 0; + return; + } + + DECDIG x; + + ssize_t n = p->Prec; /* The length of frac without zeros. */ + while (n > 0 && p->frac[n-1] == 0) --n; + if (n == 0) goto zero; + + int nlz = BASE_FIG; + for (x = p->frac[0]; x > 0; x /= 10) --nlz; + + int ntz = 0; + for (x = p->frac[n-1]; x > 0 && x % 10 == 0; x /= 10) ++ntz; + + /* + * Calculate the precision and the scale + * ------------------------------------- + * + * The most significant digit is frac[0], and the least significant digit + * is frac[Prec-1]. When the exponent is zero, the decimal point is + * located just before frac[0]. + * + * When the exponent is negative, the decimal point moves to leftward. + * In this case, the precision can be calculated by + * + * precision = BASE_FIG * (-exponent + n) - ntz, + * + * and the scale is the same as precision. + * + * 0 . 0000 0000 | frac[0] ... frac[n-1] | + * |<----------| exponent == -2 | + * |---------------------------------->| precision + * |---------------------------------->| scale + * + * + * Conversely, when the exponent is positive, the decimal point moves to + * rightward. In this case, the scale equals to + * + * BASE_FIG * (n - exponent) - ntz. + * + * the precision equals to + * + * scale + BASE_FIG * exponent - nlz. + * + * | frac[0] frac[1] . frac[2] ... frac[n-1] | + * |---------------->| exponent == 2 | + * | |---------------------->| scale + * |---------------------------------------->| precision + */ + + ssize_t ex = p->exponent; + + /* Count the number of decimal digits before frac[1]. */ + ssize_t n_digits_head = BASE_FIG; + if (ex < 0) { + n_digits_head += (-ex) * BASE_FIG; /* The number of leading zeros before frac[0]. */ + ex = 0; + } + else if (ex > 0) { + /* Count the number of decimal digits without the leading zeros in + * the most significant digit in the integral part. + */ + n_digits_head -= nlz; /* Make the number of digits */ + } + + if (out_precision) { + ssize_t precision = n_digits_head; + + /* Count the number of decimal digits after frac[0]. */ + if (ex > (ssize_t)n) { + /* In this case the number is an integer with some trailing zeros. */ + precision += (ex - 1) * BASE_FIG; + } + else if (n > 0) { + precision += (n - 1) * BASE_FIG; + + if (ex < (ssize_t)n) { + precision -= ntz; + } + } + + *out_precision = precision; + } + + if (out_scale) { + ssize_t scale = 0; + + if (p->exponent < 0) { + scale = n_digits_head + (n - 1) * BASE_FIG - ntz; + } + else if (n > p->exponent) { + scale = (n - p->exponent) * BASE_FIG - ntz; + } + + *out_scale = scale; + } +} + +static void +BigDecimal_count_precision_and_scale(VALUE self, ssize_t *out_precision, ssize_t *out_scale) +{ + BDVALUE v = GetBDValueMust(self); + VpCountPrecisionAndScale(v.real, out_precision, out_scale); + RB_GC_GUARD(v.bigdecimal); +} + +/* + * call-seq: + * precision -> integer + * + * Returns the number of decimal digits in +self+: + * + * BigDecimal("0").precision # => 0 + * BigDecimal("1").precision # => 1 + * BigDecimal("1.1").precision # => 2 + * BigDecimal("3.1415").precision # => 5 + * BigDecimal("-1e20").precision # => 21 + * BigDecimal("1e-20").precision # => 20 + * BigDecimal("Infinity").precision # => 0 + * BigDecimal("-Infinity").precision # => 0 + * BigDecimal("NaN").precision # => 0 + * + */ +static VALUE +BigDecimal_precision(VALUE self) +{ + ssize_t precision; + BigDecimal_count_precision_and_scale(self, &precision, NULL); + return SSIZET2NUM(precision); +} + +/* + * call-seq: + * scale -> integer + * + * Returns the number of decimal digits following the decimal digits in +self+. + * + * BigDecimal("0").scale # => 0 + * BigDecimal("1").scale # => 0 + * BigDecimal("1.1").scale # => 1 + * BigDecimal("3.1415").scale # => 4 + * BigDecimal("-1e20").scale # => 0 + * BigDecimal("1e-20").scale # => 20 + * BigDecimal("Infinity").scale # => 0 + * BigDecimal("-Infinity").scale # => 0 + * BigDecimal("NaN").scale # => 0 + */ +static VALUE +BigDecimal_scale(VALUE self) +{ + ssize_t scale; + BigDecimal_count_precision_and_scale(self, NULL, &scale); + return SSIZET2NUM(scale); +} + +/* + * call-seq: + * precision_scale -> [integer, integer] + * + * Returns a 2-length array; the first item is the result of + * BigDecimal#precision and the second one is of BigDecimal#scale. + * + * See BigDecimal#precision. + * See BigDecimal#scale. + */ +static VALUE +BigDecimal_precision_scale(VALUE self) +{ + ssize_t precision, scale; + BigDecimal_count_precision_and_scale(self, &precision, &scale); + return rb_assoc_new(SSIZET2NUM(precision), SSIZET2NUM(scale)); +} + +/* + * call-seq: + * n_significant_digits -> integer + * + * Returns the number of decimal significant digits in +self+. + * + * BigDecimal("0").n_significant_digits # => 0 + * BigDecimal("1").n_significant_digits # => 1 + * BigDecimal("1.1").n_significant_digits # => 2 + * BigDecimal("3.1415").n_significant_digits # => 5 + * BigDecimal("-1e20").n_significant_digits # => 1 + * BigDecimal("1e-20").n_significant_digits # => 1 + * BigDecimal("Infinity").n_significant_digits # => 0 + * BigDecimal("-Infinity").n_significant_digits # => 0 + * BigDecimal("NaN").n_significant_digits # => 0 + */ +static VALUE +BigDecimal_n_significant_digits(VALUE self) +{ + BDVALUE v = GetBDValueMust(self); + if (VpIsZero(v.real) || !VpIsDef(v.real)) { + return INT2FIX(0); + } + + ssize_t n = v.real->Prec; /* The length of frac without trailing zeros. */ + for (n = v.real->Prec; n > 0 && v.real->frac[n-1] == 0; --n); + if (n == 0) return INT2FIX(0); + + DECDIG x; + int nlz = BASE_FIG; + for (x = v.real->frac[0]; x > 0; x /= 10) --nlz; + + int ntz = 0; + for (x = v.real->frac[n-1]; x > 0 && x % 10 == 0; x /= 10) ++ntz; + + RB_GC_GUARD(v.bigdecimal); + ssize_t n_significant_digits = BASE_FIG*n - nlz - ntz; + return SSIZET2NUM(n_significant_digits); +} + +/* + * call-seq: + * hash -> integer + * + * Returns the integer hash value for +self+. + * + * Two instances of \BigDecimal have the same hash value if and only if + * they have equal: + * + * - Sign. + * - Fractional part. + * - Exponent. + * + */ +static VALUE +BigDecimal_hash(VALUE self) +{ + BDVALUE v = GetBDValueMust(self); + st_index_t hash = (st_index_t)v.real->sign; + /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */ + if(hash == 2 || hash == (st_index_t)-2) { + hash ^= rb_memhash(v.real->frac, sizeof(DECDIG)*v.real->Prec); + hash += v.real->exponent; + } + RB_GC_GUARD(v.bigdecimal); + return ST2FIX(hash); +} + +/* + * call-seq: + * _dump -> string + * + * Returns a string representing the marshalling of +self+. + * See module Marshal. + * + * inf = BigDecimal('Infinity') # => Infinity + * dumped = inf._dump # => "9:Infinity" + * BigDecimal._load(dumped) # => Infinity + * + */ +static VALUE +BigDecimal_dump(int argc, VALUE *argv, VALUE self) +{ + BDVALUE v; + char *psz; + VALUE dummy; + volatile VALUE dump; + size_t len; + + rb_scan_args(argc, argv, "01", &dummy); + v = GetBDValueMust(self); + dump = rb_str_new(0, VpNumOfChars(v.real, "E")+50); + psz = RSTRING_PTR(dump); + snprintf(psz, RSTRING_LEN(dump), "%"PRIuSIZE":", v.real->Prec*VpBaseFig()); + len = strlen(psz); + VpToString(v.real, psz+len, RSTRING_LEN(dump)-len, 0, 0); + rb_str_resize(dump, strlen(psz)); + + RB_GC_GUARD(v.bigdecimal); + return dump; +} + +/* + * Internal method used to provide marshalling support. See the Marshal module. + */ +static VALUE +BigDecimal_load(VALUE self, VALUE str) +{ + BDVALUE v; + unsigned char *pch; + unsigned char ch; + + pch = (unsigned char *)StringValueCStr(str); + /* First skip max prec. Don't trust the value. */ + while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') { + if(!ISDIGIT(ch)) { + rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string"); + } + } + v = bdvalue_nonnullable(CreateFromString((char *)pch, self, true, true)); + return CheckGetValue(v); +} + +static unsigned short +check_rounding_mode_option(VALUE const opts) +{ + VALUE mode; + char const *s; + long l; + + assert(RB_TYPE_P(opts, T_HASH)); + + if (NIL_P(opts)) + goto no_opt; + + mode = rb_hash_lookup2(opts, ID2SYM(id_half), Qundef); + if (mode == Qundef || NIL_P(mode)) + goto no_opt; + + if (SYMBOL_P(mode)) + mode = rb_sym2str(mode); + else if (!RB_TYPE_P(mode, T_STRING)) { + VALUE str_mode = rb_check_string_type(mode); + if (NIL_P(str_mode)) + goto invalid; + mode = str_mode; + } + s = RSTRING_PTR(mode); + l = RSTRING_LEN(mode); + switch (l) { + case 2: + if (strncasecmp(s, "up", 2) == 0) + return VP_ROUND_HALF_UP; + break; + case 4: + if (strncasecmp(s, "even", 4) == 0) + return VP_ROUND_HALF_EVEN; + else if (strncasecmp(s, "down", 4) == 0) + return VP_ROUND_HALF_DOWN; + break; + default: + break; + } + + invalid: + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", mode); + + no_opt: + return VpGetRoundMode(); +} + +static unsigned short +check_rounding_mode(VALUE const v) +{ + unsigned short sw; + ID id; + if (RB_TYPE_P(v, T_SYMBOL)) { + int i; + id = SYM2ID(v); + for (i = 0; i < RBD_NUM_ROUNDING_MODES; ++i) { + if (rbd_rounding_modes[i].id == id) { + return rbd_rounding_modes[i].mode; + } + } + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", v); + } + else { + sw = NUM2USHORT(v); + if (!VpIsRoundMode(sw)) { + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", v); + } + return sw; + } +} + +/* call-seq: + * BigDecimal.mode(mode, setting = nil) -> integer + * + * Returns an integer representing the mode settings + * for exception handling and rounding. + * + * These modes control exception handling: + * + * - \BigDecimal::EXCEPTION_NaN. + * - \BigDecimal::EXCEPTION_INFINITY. + * - \BigDecimal::EXCEPTION_UNDERFLOW. + * - \BigDecimal::EXCEPTION_OVERFLOW. + * - \BigDecimal::EXCEPTION_ZERODIVIDE. + * - \BigDecimal::EXCEPTION_ALL. + * + * Values for +setting+ for exception handling: + * + * - +true+: sets the given +mode+ to +true+. + * - +false+: sets the given +mode+ to +false+. + * - +nil+: does not modify the mode settings. + * + * You can use method BigDecimal.save_exception_mode + * to temporarily change, and then automatically restore, exception modes. + * + * For clarity, some examples below begin by setting all + * exception modes to +false+. + * + * This mode controls the way rounding is to be performed: + * + * - \BigDecimal::ROUND_MODE + * + * You can use method BigDecimal.save_rounding_mode + * to temporarily change, and then automatically restore, the rounding mode. + * + * NaNs + * + * Mode \BigDecimal::EXCEPTION_NaN controls behavior + * when a \BigDecimal NaN is created. + * + * Settings: + * + * - +false+ (default): Returns BigDecimal('NaN'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal('NaN') # => NaN + * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true) # => 2 + * BigDecimal('NaN') # Raises FloatDomainError + * + * Infinities + * + * Mode \BigDecimal::EXCEPTION_INFINITY controls behavior + * when a \BigDecimal Infinity or -Infinity is created. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal('Infinity') # => Infinity + * BigDecimal('-Infinity') # => -Infinity + * BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true) # => 1 + * BigDecimal('Infinity') # Raises FloatDomainError + * BigDecimal('-Infinity') # Raises FloatDomainError + * + * Underflow + * + * Mode \BigDecimal::EXCEPTION_UNDERFLOW controls behavior + * when a \BigDecimal underflow occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('0') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * def flow_under + * x = BigDecimal('0.1') + * 100.times { x *= x } + * end + * flow_under # => 100 + * BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true) # => 4 + * flow_under # Raises FloatDomainError + * + * Overflow + * + * Mode \BigDecimal::EXCEPTION_OVERFLOW controls behavior + * when a \BigDecimal overflow occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * def flow_over + * x = BigDecimal('10') + * 100.times { x *= x } + * end + * flow_over # => 100 + * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true) # => 1 + * flow_over # Raises FloatDomainError + * + * Zero Division + * + * Mode \BigDecimal::EXCEPTION_ZERODIVIDE controls behavior + * when a zero-division occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * one = BigDecimal('1') + * zero = BigDecimal('0') + * one / zero # => Infinity + * BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, true) # => 16 + * one / zero # Raises FloatDomainError + * + * All Exceptions + * + * Mode \BigDecimal::EXCEPTION_ALL controls all of the above: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true) # => 23 + * + * Rounding + * + * Mode \BigDecimal::ROUND_MODE controls the way rounding is to be performed; + * its +setting+ values are: + * + * - +ROUND_UP+: Round away from zero. + * Aliased as +:up+. + * - +ROUND_DOWN+: Round toward zero. + * Aliased as +:down+ and +:truncate+. + * - +ROUND_HALF_UP+: Round toward the nearest neighbor; + * if the neighbors are equidistant, round away from zero. + * Aliased as +:half_up+ and +:default+. + * - +ROUND_HALF_DOWN+: Round toward the nearest neighbor; + * if the neighbors are equidistant, round toward zero. + * Aliased as +:half_down+. + * - +ROUND_HALF_EVEN+ (Banker's rounding): Round toward the nearest neighbor; + * if the neighbors are equidistant, round toward the even neighbor. + * Aliased as +:half_even+ and +:banker+. + * - +ROUND_CEILING+: Round toward positive infinity. + * Aliased as +:ceiling+ and +:ceil+. + * - +ROUND_FLOOR+: Round toward negative infinity. + * Aliased as +:floor:+. + * + */ +static VALUE +BigDecimal_mode(int argc, VALUE *argv, VALUE self) +{ + VALUE which; + VALUE val; + unsigned long f,fo; + + rb_scan_args(argc, argv, "11", &which, &val); + f = (unsigned long)NUM2INT(which); + + if (f & VP_EXCEPTION_ALL) { + /* Exception mode setting */ + fo = VpGetException(); + if (val == Qnil) return INT2FIX(fo); + if (val != Qfalse && val!=Qtrue) { + rb_raise(rb_eArgError, "second argument must be true or false"); + return Qnil; /* Not reached */ + } + if (f & VP_EXCEPTION_INFINITY) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_INFINITY) : + (fo & (~VP_EXCEPTION_INFINITY)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_NaN) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_NaN) : + (fo & (~VP_EXCEPTION_NaN)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_UNDERFLOW) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_UNDERFLOW) : + (fo & (~VP_EXCEPTION_UNDERFLOW)))); + } + fo = VpGetException(); + if(f & VP_EXCEPTION_ZERODIVIDE) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_ZERODIVIDE) : + (fo & (~VP_EXCEPTION_ZERODIVIDE)))); + } + fo = VpGetException(); + return INT2FIX(fo); + } + if (VP_ROUND_MODE == f) { + /* Rounding mode setting */ + unsigned short sw; + fo = VpGetRoundMode(); + if (NIL_P(val)) return INT2FIX(fo); + sw = check_rounding_mode(val); + fo = VpSetRoundMode(sw); + return INT2FIX(fo); + } + rb_raise(rb_eTypeError, "first argument for BigDecimal.mode invalid"); + return Qnil; +} + +static size_t +GetAddSubPrec(Real *a, Real *b) +{ + if (VpIsZero(a) || VpIsZero(b)) return Max(a->Prec, b->Prec); + ssize_t min_a = a->exponent - a->Prec; + ssize_t min_b = b->exponent - b->Prec; + return Max(a->exponent, b->exponent) - Min(min_a, min_b); +} + +static inline SIGNED_VALUE +check_int_precision(VALUE v) +{ + SIGNED_VALUE n; +#if SIZEOF_VALUE <= SIZEOF_LONG + n = (SIGNED_VALUE)NUM2LONG(v); +#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG + n = (SIGNED_VALUE)NUM2LL(v); +#else +# error SIZEOF_VALUE is too large +#endif + if (n < 0) { + rb_raise(rb_eArgError, "negative precision"); + } + return n; +} + +static NULLABLE_BDVALUE +CreateFromString(const char *str, VALUE klass, bool strict_p, bool raise_exception) +{ + return VpAlloc(str, strict_p, raise_exception); +} + +void +VpMemCopy(Real *pv, Real const* const x) +{ + pv->MaxPrec = x->MaxPrec; + pv->Prec = x->Prec; + pv->exponent = x->exponent; + pv->sign = x->sign; + pv->flag = x->flag; + MEMCPY(pv->frac, x->frac, DECDIG, pv->MaxPrec); +} + +/* Returns True if the value is Not a Number. */ +static VALUE +BigDecimal_IsNaN(VALUE self) +{ + Real *p = GetSelfVpValue(self); + if (VpIsNaN(p)) return Qtrue; + return Qfalse; +} + +/* Returns nil, -1, or +1 depending on whether the value is finite, + * -Infinity, or +Infinity. + */ +static VALUE +BigDecimal_IsInfinite(VALUE self) +{ + Real *p = GetSelfVpValue(self); + if (VpIsPosInf(p)) return INT2FIX(1); + if (VpIsNegInf(p)) return INT2FIX(-1); + return Qnil; +} + +/* Returns True if the value is finite (not NaN or infinite). */ +static VALUE +BigDecimal_IsFinite(VALUE self) +{ + Real *p = GetSelfVpValue(self); + if (VpIsNaN(p)) return Qfalse; + if (VpIsInf(p)) return Qfalse; + return Qtrue; +} + +static void +BigDecimal_check_num(Real *p) +{ + VpCheckException(p, true); +} + +/* Returns the value as an Integer. + * + * If the BigDecimal is infinity or NaN, raises FloatDomainError. + */ +static VALUE +BigDecimal_to_i(VALUE self) +{ + BDVALUE v; + VALUE ret; + + v = GetBDValueMust(self); + BigDecimal_check_num(v.real); + + if (v.real->exponent <= 0) return INT2FIX(0); + if (v.real->exponent == 1) { + ret = LONG2NUM((long)(VpGetSign(v.real) * (DECDIG_DBL_SIGNED)v.real->frac[0])); + } + else { + VALUE fix = (ssize_t)v.real->Prec > v.real->exponent ? BigDecimal_fix(self) : self; + VALUE digits = RARRAY_AREF(BigDecimal_split(fix), 1); + ssize_t dpower = VpExponent10(v.real) - (ssize_t)RSTRING_LEN(digits); + ret = rb_funcall(digits, rb_intern("to_i"), 0); + + if (BIGDECIMAL_NEGATIVE_P(v.real)) { + ret = rb_funcall(ret, '*', 1, INT2FIX(-1)); + } + if (dpower) { + VALUE pow10 = rb_funcall(INT2FIX(10), rb_intern("**"), 1, SSIZET2NUM(dpower)); + // In Ruby < 3.4, int**int may return Float::INFINITY + if (RB_TYPE_P(pow10, T_FLOAT)) rb_raise(rb_eFloatDomainError, "Infinity"); + + ret = rb_funcall(ret, '*', 1, pow10); + } + } + + RB_GC_GUARD(v.bigdecimal); + return ret; +} + +/* Returns a new Float object having approximately the same value as the + * BigDecimal number. Normal accuracy limits and built-in errors of binary + * Float arithmetic apply. + */ +static VALUE +BigDecimal_to_f(VALUE self) +{ + double d; + SIGNED_VALUE e; + char *buf; + volatile VALUE str; + BDVALUE v = GetBDValueMust(self); + bool negative = BIGDECIMAL_NEGATIVE_P(v.real); + + if (VpVtoD(&d, &e, v.real) != 1) + return rb_float_new(d); + if (e > (SIGNED_VALUE)(DBL_MAX_10_EXP+BASE_FIG)) + goto overflow; + if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-DBL_DIG)) + goto underflow; + + str = rb_str_new(0, VpNumOfChars(v.real, "E")); + buf = RSTRING_PTR(str); + VpToString(v.real, buf, RSTRING_LEN(str), 0, 0); + + RB_GC_GUARD(v.bigdecimal); + + errno = 0; + d = strtod(buf, 0); + if (errno == ERANGE) { + if (d == 0.0) goto underflow; + if (fabs(d) >= HUGE_VAL) goto overflow; + } + return rb_float_new(d); + +overflow: + VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0); + if (negative) + return rb_float_new(VpGetDoubleNegInf()); + else + return rb_float_new(VpGetDoublePosInf()); + +underflow: + VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0); + if (negative) + return rb_float_new(-0.0); + else + return rb_float_new(0.0); +} + + +/* Converts a BigDecimal to a Rational. + */ +static VALUE +BigDecimal_to_r(VALUE self) +{ + BDVALUE v; + ssize_t sign, power, denomi_power; + VALUE a, digits, numerator; + + v = GetBDValueMust(self); + BigDecimal_check_num(v.real); + sign = VpGetSign(v.real); + power = VpExponent10(v.real); + RB_GC_GUARD(v.bigdecimal); + + a = BigDecimal_split(self); + digits = RARRAY_AREF(a, 1); + denomi_power = power - RSTRING_LEN(digits); + numerator = rb_funcall(digits, rb_intern("to_i"), 0); + + if (sign < 0) { + numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); + } + if (denomi_power < 0) { + return rb_Rational(numerator, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(-denomi_power))); + } + else { + return rb_Rational1(rb_funcall(numerator, '*', 1, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(denomi_power)))); + } +} + +static size_t +GetCoercePrec(Real *a, size_t prec) +{ + if (prec == 0) prec = a->Prec * BASE_FIG; + if (prec < 2 * BIGDECIMAL_DOUBLE_FIGURES) prec = 2 * BIGDECIMAL_DOUBLE_FIGURES; + return prec; +} + +/* The coerce method provides support for Ruby type coercion. It is not + * enabled by default. + * + * This means that binary operations like + * / or - can often be performed + * on a BigDecimal and an object of another type, if the other object can + * be coerced into a BigDecimal value. + * + * e.g. + * a = BigDecimal("1.0") + * b = a / 2.0 #=> 0.5 + * + * Note that coercing a String to a BigDecimal is not supported by default; + * it requires a special compile-time option when building Ruby. + */ +static VALUE +BigDecimal_coerce(VALUE self, VALUE other) +{ + Real* pv = VpPtr(self); + BDVALUE b = GetBDValueWithPrecMust(other, GetCoercePrec(pv, 0)); + return rb_assoc_new(CheckGetValue(b), self); +} + +/* + * call-seq: + * +big_decimal -> self + * + * Returns +self+: + * + * +BigDecimal(5) # => 0.5e1 + * +BigDecimal(-5) # => -0.5e1 + * + */ + +static VALUE +BigDecimal_uplus(VALUE self) +{ + return self; +} + +static bool +is_coerceable_to_BigDecimal(VALUE r) +{ + return is_kind_of_BigDecimal(r) || + RB_INTEGER_TYPE_P(r) || + RB_TYPE_P(r, T_FLOAT) || + RB_TYPE_P(r, T_RATIONAL); +} + + /* + * call-seq: + * self + value -> bigdecimal + * + * Returns the \BigDecimal sum of +self+ and +value+: + * + * b = BigDecimal('111111.111') # => 0.111111111e6 + * b + 2 # => 0.111113111e6 + * b + 2.0 # => 0.111113111e6 + * b + Rational(2, 1) # => 0.111113111e6 + * b + Complex(2, 0) # => (0.111113111e6+0i) + * + * See the {Note About Precision}[BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision]. + * + */ + +static VALUE +BigDecimal_add(VALUE self, VALUE r) +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '+'); + return BigDecimal_addsub_with_coerce(self, r, 0, +1); +} + +static VALUE +BigDecimal_addsub_with_coerce(VALUE self, VALUE r, size_t prec, int operation) +{ + BDVALUE a, b, c; + size_t mx; + + a = GetBDValueMust(self); + b = GetBDValueWithPrecMust(r, GetCoercePrec(a.real, prec)); + + if (VpIsNaN(a.real)) return CheckGetValue(a); + if (VpIsNaN(b.real)) return CheckGetValue(b); + + if (VpIsInf(a.real) || VpIsInf(b.real)) { + c = NewZeroWrap(1, BASE_FIG); + VpAddSub(c.real, a.real, b.real, operation); + } + else { + + // Optimization when exponent difference is large + // (1.234e+1000).add(5.678e-1000, 10) == (1.234e+1000).add(0.1e+990, 10) in every rounding mode + if (prec && !VpIsZero(a.real) && !VpIsZero(b.real)) { + size_t precRoom = roomof(prec, BASE_FIG); + if (a.real->exponent - (ssize_t)Max(a.real->Prec, precRoom) - 1 > b.real->exponent) { + BDVALUE b2 = NewZeroWrap(1, BASE_FIG); + VpSetOne(b2.real) + VpSetSign(b2.real, b.real->sign); + b2.real->exponent = a.real->exponent - (ssize_t)Max(a.real->Prec, precRoom) - 1; + b = b2; + } else if (b.real->exponent - (ssize_t)Max(b.real->Prec, precRoom) - 1 > a.real->exponent) { + BDVALUE a2 = NewZeroWrap(1, BASE_FIG); + VpSetOne(a2.real) + VpSetSign(a2.real, a.real->sign); + a2.real->exponent = b.real->exponent - (ssize_t)Max(b.real->Prec, precRoom) - 1; + a = a2; + } + } + + mx = GetAddSubPrec(a.real, b.real); + c = NewZeroWrap(1, (mx + 1) * BASE_FIG); + size_t pl = VpGetPrecLimit(); + if (prec) VpSetPrecLimit(prec); + // Let VpAddSub round the result + VpAddSub(c.real, a.real, b.real, operation); + if (prec) VpSetPrecLimit(pl); + } + + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return CheckGetValue(c); +} + + /* + * call-seq: + * self - value -> bigdecimal + * + * Returns the \BigDecimal difference of +self+ and +value+: + * + * b = BigDecimal('333333.333') # => 0.333333333e6 + * b - 2 # => 0.333331333e6 + * b - 2.0 # => 0.333331333e6 + * b - Rational(2, 1) # => 0.333331333e6 + * b - Complex(2, 0) # => (0.333331333e6+0i) + * + * See the {Note About Precision}[BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision]. + * + */ +static VALUE +BigDecimal_sub(VALUE self, VALUE r) +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '-'); + return BigDecimal_addsub_with_coerce(self, r, 0, -1); +} + +static VALUE +BigDecimalCmp(VALUE self, VALUE r,char op) +{ + SIGNED_VALUE e; + BDVALUE a = GetBDValueMust(self); + NULLABLE_BDVALUE b = GetBDValueWithPrec(r, GetCoercePrec(a.real, 0)); + + if (b.real_or_null == NULL) { + ID f = 0; + + switch (op) { + case '*': + return rb_num_coerce_cmp(self, r, rb_intern("<=>")); + + case '=': + return RTEST(rb_num_coerce_cmp(self, r, rb_intern("=="))) ? Qtrue : Qfalse; + + case 'G': + f = rb_intern(">="); + break; + + case 'L': + f = rb_intern("<="); + break; + + case '>': + /* fall through */ + case '<': + f = (ID)op; + break; + + default: + break; + } + return rb_num_coerce_relop(self, r, f); + } + e = VpComp(a.real, b.real_or_null); + + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal_or_nil); + + if (e == 999) + return (op == '*') ? Qnil : Qfalse; + switch (op) { + case '*': + return INT2FIX(e); /* any op */ + + case '=': + if (e == 0) return Qtrue; + return Qfalse; + + case 'G': + if (e >= 0) return Qtrue; + return Qfalse; + + case '>': + if (e > 0) return Qtrue; + return Qfalse; + + case 'L': + if (e <= 0) return Qtrue; + return Qfalse; + + case '<': + if (e < 0) return Qtrue; + return Qfalse; + + default: + break; + } + + rb_bug("Undefined operation in BigDecimalCmp()"); + + UNREACHABLE; +} + +/* Returns True if the value is zero. */ +static VALUE +BigDecimal_zero(VALUE self) +{ + Real *a = GetSelfVpValue(self); + return VpIsZero(a) ? Qtrue : Qfalse; +} + +/* Returns self if the value is non-zero, nil otherwise. */ +static VALUE +BigDecimal_nonzero(VALUE self) +{ + Real *a = GetSelfVpValue(self); + return VpIsZero(a) ? Qnil : self; +} + +/* The comparison operator. + * a <=> b is 0 if a == b, 1 if a > b, -1 if a < b. + */ +static VALUE +BigDecimal_comp(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '*'); +} + +/* + * Tests for value equality; returns true if the values are equal. + * + * The == and === operators and the eql? method have the same implementation + * for BigDecimal. + * + * Values may be coerced to perform the comparison: + * + * BigDecimal('1.0') == 1.0 #=> true + */ +static VALUE +BigDecimal_eq(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '='); +} + +/* call-seq: + * self < other -> true or false + * + * Returns +true+ if +self+ is less than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') # => 0.15e1 + * b < 2 # => true + * b < 2.0 # => true + * b < Rational(2, 1) # => true + * b < 1.5 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_lt(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '<'); +} + +/* call-seq: + * self <= other -> true or false + * + * Returns +true+ if +self+ is less or equal to than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') # => 0.15e1 + * b <= 2 # => true + * b <= 2.0 # => true + * b <= Rational(2, 1) # => true + * b <= 1.5 # => true + * b < 1 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_le(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, 'L'); +} + +/* call-seq: + * self > other -> true or false + * + * Returns +true+ if +self+ is greater than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') + * b > 1 # => true + * b > 1.0 # => true + * b > Rational(1, 1) # => true + * b > 2 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_gt(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '>'); +} + +/* call-seq: + * self >= other -> true or false + * + * Returns +true+ if +self+ is greater than or equal to +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') + * b >= 1 # => true + * b >= 1.0 # => true + * b >= Rational(1, 1) # => true + * b >= 1.5 # => true + * b > 2 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_ge(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, 'G'); +} + +/* + * call-seq: + * -self -> bigdecimal + * + * Returns the \BigDecimal negation of self: + * + * b0 = BigDecimal('1.5') + * b1 = -b0 # => -0.15e1 + * b2 = -b1 # => 0.15e1 + * + */ + +static VALUE +BigDecimal_neg(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, a.real->Prec * BASE_FIG); + VpAsgn(c.real, a.real, -10); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* + * call-seq: + * a * b -> bigdecimal + * + * Multiply by the specified value. + * + * The result precision will be the precision of the sum of each precision. + * + * See BigDecimal#mult. + */ +static VALUE +BigDecimal_mult(VALUE self, VALUE r) +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '*'); + return BigDecimal_mult_with_coerce(self, r, 0); +} + +static VALUE +BigDecimal_mult_with_coerce(VALUE self, VALUE r, size_t prec) +{ + BDVALUE a, b, c; + + a = GetBDValueMust(self); + b = GetBDValueWithPrecMust(r, GetCoercePrec(a.real, prec)); + + c = NewZeroWrap(1, VPMULT_RESULT_PREC(a.real, b.real) * BASE_FIG); + VpMult(c.real, a.real, b.real); + if (prec) { + VpLeftRound(c.real, VpGetRoundMode(), prec); + } + else { + VpLimitRound(c.real, 0); + } + + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return CheckGetValue(c); +} + +static bool BigDecimal_DoDivmod(VALUE self, VALUE r, NULLABLE_BDVALUE *div, NULLABLE_BDVALUE *mod, bool truncate); + +/* call-seq: + * a / b -> bigdecimal + * + * Divide by the specified value. + * + * The result precision will be the precision of the larger operand, + * but its minimum is 2*Float::DIG. + * + * See BigDecimal#div. + * See BigDecimal#quo. + */ +static VALUE +BigDecimal_div(VALUE self, VALUE r) +/* For c = self/r: with round operation */ +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '/'); + return BigDecimal_div2(self, r, INT2FIX(0)); +} + +static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self); + +/* call-seq: + * quo(value) -> bigdecimal + * quo(value, digits) -> bigdecimal + * + * Divide by the specified value. + * + * digits:: If specified and less than the number of significant digits of + * the result, the result is rounded to the given number of digits, + * according to the rounding mode indicated by BigDecimal.mode. + * + * If digits is 0 or omitted, the result is the same as for the + * / operator. + * + * See BigDecimal#/. + * See BigDecimal#div. + */ +static VALUE +BigDecimal_quo(int argc, VALUE *argv, VALUE self) +{ + VALUE value, digits, result; + SIGNED_VALUE n = -1; + + argc = rb_scan_args(argc, argv, "11", &value, &digits); + if (argc > 1) { + n = check_int_precision(digits); + } + + if (n > 0) { + result = BigDecimal_div2(self, value, digits); + } + else { + result = BigDecimal_div(self, value); + } + + return result; +} + +/* + * %: mod = a%b = a - (a.to_f/b).floor * b + * div = (a.to_f/b).floor + * In truncate mode, use truncate instead of floor. + */ +static bool +BigDecimal_DoDivmod(VALUE self, VALUE r, NULLABLE_BDVALUE *div, NULLABLE_BDVALUE *mod, bool truncate) +{ + BDVALUE a, b, dv, md, res; + NULLABLE_BDVALUE b2; + ssize_t a_exponent, b_exponent; + size_t mx, rx, pl; + + a = GetBDValueMust(self); + + b2 = GetBDValueWithPrec(r, GetCoercePrec(a.real, 0)); + if (!b2.real_or_null) return false; + b = bdvalue_nonnullable(b2); + + if (VpIsNaN(a.real) || VpIsNaN(b.real) || (VpIsInf(a.real) && VpIsInf(b.real))) { + VALUE nan = BigDecimal_nan(); + *div = *mod = (NULLABLE_BDVALUE) { nan, VpPtr(nan) }; + goto Done; + } + if (VpIsZero(b.real)) { + rb_raise(rb_eZeroDivError, "divided by 0"); + } + if (VpIsInf(a.real)) { + if (VpGetSign(a.real) == VpGetSign(b.real)) { + VALUE inf = BigDecimal_positive_infinity(); + *div = (NULLABLE_BDVALUE) { inf, VpPtr(inf) }; + } + else { + VALUE inf = BigDecimal_negative_infinity(); + *div = (NULLABLE_BDVALUE) { inf, VpPtr(inf) }; + } + VALUE nan = BigDecimal_nan(); + *mod = (NULLABLE_BDVALUE) { nan, VpPtr(nan) }; + goto Done; + } + if (VpIsZero(a.real)) { + VALUE zero = BigDecimal_positive_zero(); + *div = (NULLABLE_BDVALUE) { zero, VpPtr(zero) }; + *mod = bdvalue_nullable(a); + goto Done; + } + if (VpIsInf(b.real)) { + if (!truncate && VpGetSign(a.real) * VpGetSign(b.real) < 0) { + BDVALUE minus_one = NewZeroWrap(1, BASE_FIG); + VpSetOne(minus_one.real); + VpSetSign(minus_one.real, -1); + RB_GC_GUARD(minus_one.bigdecimal); + *div = bdvalue_nullable(minus_one); + *mod = bdvalue_nullable(b); + } else { + VALUE zero = BigDecimal_positive_zero(); + *div = (NULLABLE_BDVALUE) { zero, VpPtr(zero) }; + *mod = bdvalue_nullable(a); + } + goto Done; + } + + a_exponent = VpExponent10(a.real); + b_exponent = VpExponent10(b.real); + mx = a_exponent > b_exponent ? a_exponent - b_exponent + 1 : 1; + dv = NewZeroWrap(1, VPDIVD_QUO_DIGITS(mx)); + + /* res is reused for VpDivd remainder and VpMult result */ + rx = VPDIVD_REM_PREC(a.real, b.real, dv.real); + mx = VPMULT_RESULT_PREC(dv.real, b.real); + res = NewZeroWrap(1, Max(rx, mx) * BASE_FIG); + /* AddSub needs one more prec */ + md = NewZeroWrap(1, (res.real->MaxPrec + 1) * BASE_FIG); + + VpDivd(dv.real, res.real, a.real, b.real); + VpMidRound(dv.real, VP_ROUND_DOWN, 0); + VpMult(res.real, dv.real, b.real); + pl = VpGetPrecLimit(); + VpSetPrecLimit(0); + VpAddSub(md.real, a.real, res.real, -1); + VpSetPrecLimit(pl); + + if (!truncate && !VpIsZero(md.real) && (VpGetSign(a.real) * VpGetSign(b.real) < 0)) { + /* result adjustment for negative case */ + BDVALUE dv2 = NewZeroWrap(1, (dv.real->MaxPrec + 1) * BASE_FIG); + BDVALUE md2 = NewZeroWrap(1, (GetAddSubPrec(md.real, b.real) + 1) * BASE_FIG); + VpSetPrecLimit(0); + VpAddSub(dv2.real, dv.real, VpOne(), -1); + VpAddSub(md2.real, md.real, b.real, 1); + VpSetPrecLimit(pl); + *div = bdvalue_nullable(dv2); + *mod = bdvalue_nullable(md2); + RB_GC_GUARD(dv2.bigdecimal); + RB_GC_GUARD(md2.bigdecimal); + } + else { + *div = bdvalue_nullable(dv); + *mod = bdvalue_nullable(md); + } + +Done: + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + RB_GC_GUARD(dv.bigdecimal); + RB_GC_GUARD(md.bigdecimal); + RB_GC_GUARD(res.bigdecimal); + return true; +} + +/* call-seq: + * a % b + * a.modulo(b) + * + * Returns the modulus from dividing by b. + * + * See BigDecimal#divmod. + */ +static VALUE +BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ +{ + NULLABLE_BDVALUE div, mod; + + if (BigDecimal_DoDivmod(self, r, &div, &mod, false)) { + return CheckGetValue(bdvalue_nonnullable(mod)); + } + return DoSomeOne(self, r, '%'); +} + +/* call-seq: + * remainder(value) + * + * Returns the remainder from dividing by the value. + * + * x.remainder(y) means x-y*(x/y).truncate + */ +static VALUE +BigDecimal_remainder(VALUE self, VALUE r) /* remainder */ +{ + NULLABLE_BDVALUE div, mod = { Qnil, NULL }; + + if (BigDecimal_DoDivmod(self, r, &div, &mod, true)) { + return CheckGetValue(bdvalue_nonnullable(mod)); + } + return DoSomeOne(self, r, rb_intern("remainder")); +} + +/* call-seq: + * divmod(value) + * + * Divides by the specified value, and returns the quotient and modulus + * as BigDecimal numbers. The quotient is rounded towards negative infinity. + * + * For example: + * + * require 'bigdecimal' + * + * a = BigDecimal("42") + * b = BigDecimal("9") + * + * q, m = a.divmod(b) + * + * c = q * b + m + * + * a == c #=> true + * + * The quotient q is (a/b).floor, and the modulus is the amount that must be + * added to q * b to get a. + */ +static VALUE +BigDecimal_divmod(VALUE self, VALUE r) +{ + NULLABLE_BDVALUE div, mod; + + if (BigDecimal_DoDivmod(self, r, &div, &mod, false)) { + return rb_assoc_new(BigDecimal_to_i(CheckGetValue(bdvalue_nonnullable(div))), CheckGetValue(bdvalue_nonnullable(mod))); + } + return DoSomeOne(self,r,rb_intern("divmod")); +} + +/* + * Do the same manner as Float#div when n is nil. + * Do the same manner as BigDecimal#quo when n is 0. + */ +static inline VALUE +BigDecimal_div2(VALUE self, VALUE b, VALUE n) +{ + SIGNED_VALUE ix; + BDVALUE av, bv, cv, res; + + if (NIL_P(n)) { /* div in Float sense */ + NULLABLE_BDVALUE div; + NULLABLE_BDVALUE mod; + if (BigDecimal_DoDivmod(self, b, &div, &mod, false)) { + return BigDecimal_to_i(CheckGetValue(bdvalue_nonnullable(div))); + } + return DoSomeOne(self, b, rb_intern("div")); + } + + /* div in BigDecimal sense */ + ix = check_int_precision(n); + + av = GetBDValueMust(self); + bv = GetBDValueWithPrecMust(b, GetCoercePrec(av.real, ix)); + + if (ix == 0) { + ssize_t a_prec, b_prec, limit = VpGetPrecLimit(); + VpCountPrecisionAndScale(av.real, &a_prec, NULL); + VpCountPrecisionAndScale(bv.real, &b_prec, NULL); + ix = ((a_prec > b_prec) ? a_prec : b_prec) + BIGDECIMAL_DOUBLE_FIGURES; + if (2 * BIGDECIMAL_DOUBLE_FIGURES > ix) + ix = 2 * BIGDECIMAL_DOUBLE_FIGURES; + if (limit && limit < ix) ix = limit; + } + + // Needs to calculate 1 extra digit for rounding. + cv = NewZeroWrap(1, VPDIVD_QUO_DIGITS(ix + 1)); + res = NewZeroWrap(1, VPDIVD_REM_PREC(av.real, bv.real, cv.real) * BASE_FIG); + VpDivd(cv.real, res.real, av.real, bv.real); + + if (!VpIsZero(res.real)) { + // Remainder value affects rounding result. + // ROUND_UP cv = 0.1e0 with idx=10 will be: + // 0.1e0 if remainder == 0 + // 0.1000000001e0 if remainder != 0 + size_t idx = roomof(ix, BASE_FIG); + while (cv.real->Prec <= idx) cv.real->frac[cv.real->Prec++] = 0; + if (cv.real->frac[idx] == 0 || cv.real->frac[idx] == HALF_BASE) cv.real->frac[idx]++; + } + VpLeftRound(cv.real, VpGetRoundMode(), ix); + + RB_GC_GUARD(av.bigdecimal); + RB_GC_GUARD(bv.bigdecimal); + RB_GC_GUARD(res.bigdecimal); + return CheckGetValue(cv); +} + + /* + * Document-method: BigDecimal#div + * + * call-seq: + * div(value) -> integer + * div(value, digits) -> bigdecimal or integer + * + * Divide by the specified value. + * + * digits:: If specified and less than the number of significant digits of the + * result, the result is rounded to that number of digits, according + * to BigDecimal.mode. + * + * If digits is 0, the result is the same as for the / operator + * or #quo. + * + * If digits is not specified, the result is an integer, + * by analogy with Float#div; see also BigDecimal#divmod. + * + * See BigDecimal#/. + * See BigDecimal#quo. + * + * Examples: + * + * a = BigDecimal("4") + * b = BigDecimal("3") + * + * a.div(b, 3) # => 0.133e1 + * + * a.div(b, 0) # => 0.1333333333333333333e1 + * a / b # => 0.1333333333333333333e1 + * a.quo(b) # => 0.1333333333333333333e1 + * + * a.div(b) # => 1 + */ +static VALUE +BigDecimal_div3(int argc, VALUE *argv, VALUE self) +{ + VALUE b,n; + + rb_scan_args(argc, argv, "11", &b, &n); + + return BigDecimal_div2(self, b, n); +} + + /* + * call-seq: + * add(value, ndigits) -> new_bigdecimal + * + * Returns the \BigDecimal sum of +self+ and +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the sum, the sum is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * Examples: + * + * # Set the rounding mode. + * BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + * b = BigDecimal('111111.111') + * b.add(1, 0) # => 0.111112111e6 + * b.add(1, 3) # => 0.111e6 + * b.add(1, 6) # => 0.111112e6 + * b.add(1, 15) # => 0.111112111e6 + * b.add(1.0, 15) # => 0.111112111e6 + * b.add(Rational(1, 1), 15) # => 0.111112111e6 + * + */ + +static VALUE +BigDecimal_add2(VALUE self, VALUE b, VALUE n) +{ + return BigDecimal_addsub_with_coerce(self, b, check_int_precision(n), +1); +} + +/* call-seq: + * sub(value, digits) -> bigdecimal + * + * Subtract the specified value. + * + * e.g. + * c = a.sub(b,n) + * + * digits:: If specified and less than the number of significant digits of the + * result, the result is rounded to that number of digits, according + * to BigDecimal.mode. + * + */ +static VALUE +BigDecimal_sub2(VALUE self, VALUE b, VALUE n) +{ + return BigDecimal_addsub_with_coerce(self, b, check_int_precision(n), -1); +} + + /* + * call-seq: + * mult(other, ndigits) -> bigdecimal + * + * Returns the \BigDecimal product of +self+ and +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the sum, the sum is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * Examples: + * + * # Set the rounding mode. + * BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + * b = BigDecimal('555555.555') + * b.mult(3, 0) # => 0.1666666665e7 + * b.mult(3, 3) # => 0.167e7 + * b.mult(3, 6) # => 0.166667e7 + * b.mult(3, 15) # => 0.1666666665e7 + * b.mult(3.0, 0) # => 0.1666666665e7 + * b.mult(Rational(3, 1), 0) # => 0.1666666665e7 + * b.mult(Complex(3, 0), 0) # => (0.1666666665e7+0.0i) + * + */ + +static VALUE +BigDecimal_mult2(VALUE self, VALUE b, VALUE n) +{ + return BigDecimal_mult_with_coerce(self, b, check_int_precision(n)); +} + +/* + * call-seq: + * abs -> bigdecimal + * + * Returns the \BigDecimal absolute value of +self+: + * + * BigDecimal('5').abs # => 0.5e1 + * BigDecimal('-3').abs # => 0.3e1 + * + */ + +static VALUE +BigDecimal_abs(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, a.real->Prec * BASE_FIG); + VpAsgn(c.real, a.real, 10); + VpChangeSign(c.real, 1); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* Return the integer part of the number, as a BigDecimal. + */ +static VALUE +BigDecimal_fix(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, (a.real->Prec + 1) * BASE_FIG); + VpActiveRound(c.real, a.real, VP_ROUND_DOWN, 0); /* 0: round off */ + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* call-seq: + * round(n, mode) + * + * Round to the nearest integer (by default), returning the result as a + * BigDecimal if n is specified and positive, or as an Integer if it isn't. + * + * BigDecimal('3.14159').round #=> 3 + * BigDecimal('8.7').round #=> 9 + * BigDecimal('-9.9').round #=> -10 + * + * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal" + * BigDecimal('3.14159').round.class.name #=> "Integer" + * BigDecimal('3.14159').round(0).class.name #=> "Integer" + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that many digits to the left of the + * decimal point will be 0 in the result, and return value will be an Integer. + * + * BigDecimal('3.14159').round(3) #=> 3.142 + * BigDecimal('13345.234').round(-2) #=> 13300 + * + * The value of the optional mode argument can be used to determine how + * rounding is performed; see BigDecimal.mode. + */ +static VALUE +BigDecimal_round(int argc, VALUE *argv, VALUE self) +{ + BDVALUE c, a; + int iLoc = 0; + VALUE vLoc; + VALUE vRound; + int round_to_int = 0; + size_t mx; + + unsigned short sw = VpGetRoundMode(); + + switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) { + case 0: + iLoc = 0; + round_to_int = 1; + break; + case 1: + if (RB_TYPE_P(vLoc, T_HASH)) { + sw = check_rounding_mode_option(vLoc); + } + else { + iLoc = NUM2INT(vLoc); + if (iLoc < 1) round_to_int = 1; + } + break; + case 2: + iLoc = NUM2INT(vLoc); + if (RB_TYPE_P(vRound, T_HASH)) { + sw = check_rounding_mode_option(vRound); + } + else { + sw = check_rounding_mode(vRound); + } + break; + default: + break; + } + + a = GetBDValueMust(self); + mx = (a.real->Prec + 1) * BASE_FIG; + c = NewZeroWrap(1, mx); + + VpActiveRound(c.real, a.real, sw, iLoc); + + RB_GC_GUARD(a.bigdecimal); + + if (round_to_int) { + return BigDecimal_to_i(CheckGetValue(c)); + } + return CheckGetValue(c); +} + +static VALUE +BigDecimal_truncate_floor_ceil(int argc, VALUE *argv, VALUE self, unsigned short rounding_mode) +{ + BDVALUE c, a; + int iLoc; + VALUE vLoc; + size_t mx; + + if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { + iLoc = 0; + } + else { + iLoc = NUM2INT(vLoc); + } + + a = GetBDValueMust(self); + mx = (a.real->Prec + 1) * BASE_FIG; + c = NewZeroWrap(1, mx); + VpActiveRound(c.real, a.real, rounding_mode, iLoc); + + RB_GC_GUARD(a.bigdecimal); + + if (argc == 0) { + return BigDecimal_to_i(CheckGetValue(c)); + } + return CheckGetValue(c); +} + +/* call-seq: + * truncate(n) + * + * Truncate to the nearest integer (by default), returning the result as a + * BigDecimal. + * + * BigDecimal('3.14159').truncate #=> 3 + * BigDecimal('8.7').truncate #=> 8 + * BigDecimal('-9.9').truncate #=> -9 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that many digits to the left of the + * decimal point will be 0 in the result. + * + * BigDecimal('3.14159').truncate(3) #=> 3.141 + * BigDecimal('13345.234').truncate(-2) #=> 13300.0 + */ +static VALUE +BigDecimal_truncate(int argc, VALUE *argv, VALUE self) +{ + return BigDecimal_truncate_floor_ceil(argc, argv, self, VP_ROUND_DOWN); +} + +/* Return the fractional part of the number, as a BigDecimal. + */ +static VALUE +BigDecimal_frac(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, (a.real->Prec + 1) * BASE_FIG); + VpFrac(c.real, a.real); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* call-seq: + * floor(n) + * + * Return the largest integer less than or equal to the value, as a BigDecimal. + * + * BigDecimal('3.14159').floor #=> 3 + * BigDecimal('-9.1').floor #=> -10 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that + * many digits to the left of the decimal point will be 0 in the result. + * + * BigDecimal('3.14159').floor(3) #=> 3.141 + * BigDecimal('13345.234').floor(-2) #=> 13300.0 + */ +static VALUE +BigDecimal_floor(int argc, VALUE *argv, VALUE self) +{ + return BigDecimal_truncate_floor_ceil(argc, argv, self, VP_ROUND_FLOOR); +} + +/* call-seq: + * ceil(n) + * + * Return the smallest integer greater than or equal to the value, as a BigDecimal. + * + * BigDecimal('3.14159').ceil #=> 4 + * BigDecimal('-9.1').ceil #=> -9 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that + * many digits to the left of the decimal point will be 0 in the result. + * + * BigDecimal('3.14159').ceil(3) #=> 3.142 + * BigDecimal('13345.234').ceil(-2) #=> 13400.0 + */ +static VALUE +BigDecimal_ceil(int argc, VALUE *argv, VALUE self) +{ + return BigDecimal_truncate_floor_ceil(argc, argv, self, VP_ROUND_CEIL); +} + +/* call-seq: + * to_s(s) + * + * Converts the value to a string. + * + * The default format looks like 0.xxxxEnn. + * + * The optional parameter s consists of either an integer; or an optional '+' + * or ' ', followed by an optional number, followed by an optional 'E' or 'F'. + * + * If there is a '+' at the start of s, positive values are returned with + * a leading '+'. + * + * A space at the start of s returns positive values with a leading space. + * + * If s contains a number, a space is inserted after each group of that many + * digits, starting from '.' and counting outwards. + * + * If s ends with an 'E', scientific notation (0.xxxxEnn) is used. + * + * If s ends with an 'F', conventional floating point notation is used. + * + * Examples: + * + * BigDecimal('-1234567890123.45678901234567890').to_s('5F') + * #=> '-123 45678 90123.45678 90123 45678 9' + * + * BigDecimal('1234567890123.45678901234567890').to_s('+8F') + * #=> '+12345 67890123.45678901 23456789' + * + * BigDecimal('1234567890123.45678901234567890').to_s(' F') + * #=> ' 1234567890123.4567890123456789' + */ +static VALUE +BigDecimal_to_s(int argc, VALUE *argv, VALUE self) +{ + int fmt = 0; /* 0: E format, 1: F format */ + int fPlus = 0; /* 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ + BDVALUE v; + volatile VALUE str; + char *psz; + char ch; + size_t nc, mc = 0; + SIGNED_VALUE m; + VALUE f; + + v = GetBDValueMust(self); + + if (rb_scan_args(argc, argv, "01", &f) == 1) { + if (RB_TYPE_P(f, T_STRING)) { + psz = StringValueCStr(f); + if (*psz == ' ') { + fPlus = 1; + psz++; + } + else if (*psz == '+') { + fPlus = 2; + psz++; + } + while ((ch = *psz++) != 0) { + if (ISSPACE(ch)) { + continue; + } + if (!ISDIGIT(ch)) { + if (ch == 'F' || ch == 'f') { + fmt = 1; /* F format */ + } + break; + } + mc = mc*10 + ch - '0'; + } + } + else { + m = NUM2INT(f); + if (m <= 0) { + rb_raise(rb_eArgError, "argument must be positive"); + } + mc = (size_t)m; + } + } + if (fmt) { + nc = VpNumOfChars(v.real, "F"); + } + else { + nc = VpNumOfChars(v.real, "E"); + } + if (mc > 0) { + nc += (nc + mc - 1) / mc + 1; + } + + str = rb_usascii_str_new(0, nc); + psz = RSTRING_PTR(str); + + if (fmt) { + VpToFString(v.real, psz, RSTRING_LEN(str), mc, fPlus); + } + else { + VpToString (v.real, psz, RSTRING_LEN(str), mc, fPlus); + } + rb_str_resize(str, strlen(psz)); + + RB_GC_GUARD(v.bigdecimal); + return str; +} + +/* Splits a BigDecimal number into four parts, returned as an array of values. + * + * The first value represents the sign of the BigDecimal, and is -1 or 1, or 0 + * if the BigDecimal is Not a Number. + * + * The second value is a string representing the significant digits of the + * BigDecimal, with no leading zeros. + * + * The third value is the base used for arithmetic (currently always 10) as an + * Integer. + * + * The fourth value is an Integer exponent. + * + * If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the + * string of significant digits with no leading zeros, and n is the exponent. + * + * From these values, you can translate a BigDecimal to a float as follows: + * + * sign, significant_digits, base, exponent = a.split + * f = sign * "0.#{significant_digits}".to_f * (base ** exponent) + * + * (Note that the to_f method is provided as a more convenient way to translate + * a BigDecimal to a Float.) + */ +static VALUE +BigDecimal_split(VALUE self) +{ + BDVALUE v; + VALUE obj,str; + ssize_t e, s; + char *psz1; + + v = GetBDValueMust(self); + str = rb_str_new(0, VpNumOfChars(v.real, "E")); + psz1 = RSTRING_PTR(str); + VpSzMantissa(v.real, psz1, RSTRING_LEN(str)); + s = 1; + if(psz1[0] == '-') { + size_t len = strlen(psz1 + 1); + + memmove(psz1, psz1 + 1, len); + psz1[len] = '\0'; + s = -1; + } + if (psz1[0] == 'N') s = 0; /* NaN */ + e = VpExponent10(v.real); + obj = rb_ary_new2(4); + rb_ary_push(obj, INT2FIX(s)); + rb_ary_push(obj, str); + rb_str_resize(str, strlen(psz1)); + rb_ary_push(obj, INT2FIX(10)); + rb_ary_push(obj, SSIZET2NUM(e)); + + RB_GC_GUARD(v.bigdecimal); + return obj; +} + +/* Returns the exponent of the BigDecimal number, as an Integer. + * + * If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string + * of digits with no leading zeros, then n is the exponent. + */ +static VALUE +BigDecimal_exponent(VALUE self) +{ + ssize_t e = VpExponent10(GetSelfVpValue(self)); + return SSIZET2NUM(e); +} + +/* Returns a string representation of self. + * + * BigDecimal("1234.5678").inspect + * #=> "0.12345678e4" + */ +static VALUE +BigDecimal_inspect(VALUE self) +{ + BDVALUE v; + volatile VALUE str; + size_t nc; + + v = GetBDValueMust(self); + nc = VpNumOfChars(v.real, "E"); + + str = rb_str_new(0, nc); + VpToString(v.real, RSTRING_PTR(str), RSTRING_LEN(str), 0, 0); + rb_str_resize(str, strlen(RSTRING_PTR(str))); + + RB_GC_GUARD(v.bigdecimal); + return str; +} + +/* Returns self * 10**v without changing the precision. + * This method is currently for internal use. + * + * BigDecimal("0.123e10")._decimal_shift(20) #=> "0.123e30" + * BigDecimal("0.123e10")._decimal_shift(-20) #=> "0.123e-10" + */ +static VALUE +BigDecimal_decimal_shift(VALUE self, VALUE v) +{ + BDVALUE a, c; + ssize_t shift, exponentShift; + bool shiftDown; + size_t prec; + DECDIG ex, iex; + + a = GetBDValueMust(self); + shift = NUM2SSIZET(rb_to_int(v)); + + if (VpIsZero(a.real) || VpIsNaN(a.real) || VpIsInf(a.real) || shift == 0) return CheckGetValue(a); + + exponentShift = shift > 0 ? shift / BASE_FIG : (shift + 1) / BASE_FIG - 1; + shift -= exponentShift * BASE_FIG; + ex = 1; + for (int i = 0; i < shift; i++) ex *= 10; + shiftDown = a.real->frac[0] * (DECDIG_DBL)ex >= BASE; + iex = BASE / ex; + + prec = a.real->Prec + shiftDown; + c = NewZeroWrap(1, prec * BASE_FIG); + if (shift == 0) { + VpAsgn(c.real, a.real, 10); + } else if (shiftDown) { + DECDIG carry = 0; + exponentShift++; + for (size_t i = 0; i < a.real->Prec; i++) { + DECDIG v = a.real->frac[i]; + c.real->frac[i] = carry * ex + v / iex; + carry = v % iex; + } + c.real->frac[a.real->Prec] = carry * ex; + } else { + DECDIG carry = 0; + for (ssize_t i = a.real->Prec - 1; i >= 0; i--) { + DECDIG v = a.real->frac[i]; + c.real->frac[i] = v % iex * ex + carry; + carry = v / iex; + } + } + while (c.real->frac[prec - 1] == 0) prec--; + c.real->Prec = prec; + c.real->sign = a.real->sign; + c.real->exponent = a.real->exponent; + AddExponent(c.real, exponentShift); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +inline static int +is_zero(VALUE x) +{ + VALUE num; + + switch (TYPE(x)) { + case T_FIXNUM: + return FIX2LONG(x) == 0; + + case T_BIGNUM: + return Qfalse; + + case T_RATIONAL: + num = rb_rational_num(x); + return FIXNUM_P(num) && FIX2LONG(num) == 0; + + default: + break; + } + + return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(0))); +} + +/* :nodoc: */ +static VALUE +BigDecimal_clone(VALUE self) +{ + return self; +} + +#ifdef HAVE_RB_OPTS_EXCEPTION_P +int rb_opts_exception_p(VALUE opts, int default_value); +#define opts_exception_p(opts) rb_opts_exception_p((opts), 1) +#else +static int +opts_exception_p(VALUE opts) +{ + static ID kwds[1]; + VALUE exception; + if (!kwds[0]) { + kwds[0] = rb_intern_const("exception"); + } + if (!rb_get_kwargs(opts, kwds, 0, 1, &exception)) return 1; + switch (exception) { + case Qtrue: case Qfalse: + break; + default: + rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE, + exception); + } + return exception != Qfalse; +} +#endif + +static VALUE +check_exception(VALUE bd) +{ + assert(is_kind_of_BigDecimal(bd)); + + VpCheckException(VpPtr(bd), false); + + return bd; +} + +static VALUE +rb_uint64_convert_to_BigDecimal(uint64_t uval) +{ + VALUE bd; + Real *vp; + if (uval == 0) { + bd = BigDecimal_allocate(1); + vp = VpPtr(bd); + vp->Prec = 1; + vp->exponent = 1; + VpSetZero(vp, 1); + vp->frac[0] = 0; + } + else if (uval < BASE) { + bd = BigDecimal_allocate(1); + vp = VpPtr(bd); + vp->Prec = 1; + vp->exponent = 1; + VpSetSign(vp, 1); + vp->frac[0] = (DECDIG)uval; + } + else { + DECDIG buf[BIGDECIMAL_INT64_MAX_LENGTH] = {0,}; + DECDIG r = uval % BASE; + size_t len = 0, ntz = 0; + if (r == 0) { + // Count and skip trailing zeros + for (; r == 0 && uval > 0; ++ntz) { + uval /= BASE; + r = uval % BASE; + } + } + for (; uval > 0; ++len) { + // Store digits + buf[BIGDECIMAL_INT64_MAX_LENGTH - len - 1] = r; + uval /= BASE; + r = uval % BASE; + } + + const size_t exp = len + ntz; + bd = BigDecimal_allocate(len); + vp = VpPtr(bd); + vp->Prec = len; + vp->exponent = exp; + VpSetSign(vp, 1); + MEMCPY(vp->frac, buf + BIGDECIMAL_INT64_MAX_LENGTH - len, DECDIG, len); + } + + return bd; +} + +static VALUE +rb_int64_convert_to_BigDecimal(int64_t ival) +{ + const uint64_t uval = (ival < 0) ? (((uint64_t)-(ival+1))+1) : (uint64_t)ival; + VALUE bd = rb_uint64_convert_to_BigDecimal(uval); + if (ival < 0) { + Real *vp = VpPtr(bd); + VpSetSign(vp, -1); + } + return bd; +} + +static VALUE +rb_big_convert_to_BigDecimal(VALUE val) +{ + assert(RB_TYPE_P(val, T_BIGNUM)); + + int leading_zeros; + size_t size = rb_absint_size(val, &leading_zeros); + int sign = FIX2INT(rb_big_cmp(val, INT2FIX(0))); + if (sign < 0 && leading_zeros == 0) { + size += 1; + } + if (size <= sizeof(long)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LONG(val)); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULONG(val)); + } + } +#if defined(SIZEOF_LONG_LONG) && SIZEOF_LONG < SIZEOF_LONG_LONG + else if (size <= sizeof(LONG_LONG)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LL(val)); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULL(val)); + } + } +#endif + else { + VALUE str = rb_big2str(val, 10); + BDVALUE v = bdvalue_nonnullable(CreateFromString( + RSTRING_PTR(str), + rb_cBigDecimal, + true, + true + )); + RB_GC_GUARD(str); + return CheckGetValue(v); + } +} + +static VALUE +rb_inum_convert_to_BigDecimal(VALUE val) +{ + assert(RB_INTEGER_TYPE_P(val)); + if (FIXNUM_P(val)) { + return rb_int64_convert_to_BigDecimal(FIX2LONG(val)); + } + else { + return rb_big_convert_to_BigDecimal(val); + } +} + +static VALUE +rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + assert(RB_FLOAT_TYPE_P(val)); + + double d = RFLOAT_VALUE(val); + + if (isnan(d)) { + VALUE obj = BigDecimal_nan(); + return check_exception(obj); + } + else if (isinf(d)) { + VALUE obj; + if (d > 0) { + obj = BigDecimal_positive_infinity(); + } + else { + obj = BigDecimal_negative_infinity(); + } + return check_exception(obj); + } + else if (d == 0.0) { + if (1/d < 0.0) { + return BigDecimal_negative_zero(); + } + else { + return BigDecimal_positive_zero(); + } + } + + if (digs == SIZE_MAX) { + digs = 0; + } + else if (digs > BIGDECIMAL_DOUBLE_FIGURES) { + if (!raise_exception) + return Qnil; + rb_raise(rb_eArgError, "precision too large."); + } + + /* Use the same logic in flo_to_s to convert a float to a decimal string */ + char buf[BIGDECIMAL_DOUBLE_FIGURES + BASE_FIG + 2 + 1]; /* sizeof(buf) == 28 in the typical case */ + int decpt, negative_p; + char *e; + const int mode = digs == 0 ? 0 : 2; + char *p = BigDecimal_dtoa(d, mode, (int)digs, &decpt, &negative_p, &e); + int len10 = (int)(e - p); + if (len10 > BIGDECIMAL_DOUBLE_FIGURES) { + /* TODO: Presumably, rounding should be done here. */ + len10 = BIGDECIMAL_DOUBLE_FIGURES; + } + memcpy(buf, p, len10); + free(p); + + VALUE inum; + size_t RB_UNUSED_VAR(prec) = 0; + SIGNED_VALUE exp = 0; + if (decpt > 0) { + if (decpt < len10) { + /* + * len10 |---------------| + * : |-------| frac_len10 = len10 - decpt + * decpt |-------| |--| ntz10 = BASE_FIG - frac_len10 % BASE_FIG + * : : : + * 00 dd dddd.dddd dd 00 + * prec |-----.----.----.-----| prec = exp + roomof(frac_len, BASE_FIG) + * exp |-----.----| exp = roomof(decpt, BASE_FIG) + */ + const size_t frac_len10 = len10 - decpt; + const size_t ntz10 = BASE_FIG - frac_len10 % BASE_FIG; + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + exp = roomof(decpt, BASE_FIG); + prec = exp + roomof(frac_len10, BASE_FIG); + } + else { + /* + * decpt |-----------------------| + * len10 |----------| : + * : |------------| exp10 + * : : : + * 00 dd dddd dd 00 0000 0000.0 + * : : : : + * : |--| ntz10 = exp10 % BASE_FIG + * prec |-----.----.-----| : + * : |----.----| exp10 / BASE_FIG + * exp |-----.----.-----.----.----| + */ + const size_t exp10 = decpt - len10; + const size_t ntz10 = exp10 % BASE_FIG; + + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + prec = roomof(len10 + ntz10, BASE_FIG); + exp = prec + exp10 / BASE_FIG; + } + } + else if (decpt == 0) { + /* + * len10 |------------| + * : : + * 0.dddd dddd dd 00 + * : : : + * : |--| ntz10 = prec * BASE_FIG - len10 + * prec |----.----.-----| roomof(len10, BASE_FIG) + */ + prec = roomof(len10, BASE_FIG); + const size_t ntz10 = prec * BASE_FIG - len10; + + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + } + else { + /* + * len10 |---------------| + * : : + * decpt |-------| |--| ntz10 = prec * BASE_FIG - nlz10 - len10 + * : : : + * 0.0000 00 dd dddd dddd dd 00 + * : : : + * nlz10 |--| : decpt % BASE_FIG + * prec |-----.----.----.-----| roomof(decpt + len10, BASE_FIG) - exp + * exp |----| decpt / BASE_FIG + */ + decpt = -decpt; + + const size_t nlz10 = decpt % BASE_FIG; + exp = decpt / BASE_FIG; + prec = roomof(decpt + len10, BASE_FIG) - exp; + const size_t ntz10 = prec * BASE_FIG - nlz10 - len10; + + if (nlz10 > 0) { + memmove(buf + nlz10, buf, len10); + memset(buf, '0', nlz10); + } + memset(buf + nlz10 + len10, '0', ntz10); + buf[nlz10 + len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + exp = -exp; + } + + VALUE bd = rb_inum_convert_to_BigDecimal(inum); + Real *vp = VpPtr(bd); + assert(vp->Prec == prec); + vp->exponent = exp; + + if (negative_p) VpSetSign(vp, -1); + return bd; +} + +static VALUE +rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + assert(RB_TYPE_P(val, T_RATIONAL)); + + if (digs == SIZE_MAX) { + if (!raise_exception) + return Qnil; + rb_raise(rb_eArgError, + "can't omit precision for a %"PRIsVALUE".", + CLASS_OF(val)); + } + + VALUE num = rb_inum_convert_to_BigDecimal(rb_rational_num(val)); + VALUE d = BigDecimal_div2(num, rb_rational_den(val), SIZET2NUM(digs)); + return d; +} + +static VALUE +rb_cstr_convert_to_BigDecimal(const char *c_str, int raise_exception) +{ + NULLABLE_BDVALUE v = CreateFromString(c_str, rb_cBigDecimal, true, raise_exception); + if (v.bigdecimal_or_nil == Qnil) return Qnil; + return CheckGetValue(bdvalue_nonnullable(v)); +} + +static inline VALUE +rb_str_convert_to_BigDecimal(VALUE val, int raise_exception) +{ + const char *c_str = StringValueCStr(val); + return rb_cstr_convert_to_BigDecimal(c_str, raise_exception); +} + +static VALUE +rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + switch (val) { + case Qnil: + case Qtrue: + case Qfalse: + if (raise_exception) { + const char *cname = NIL_P(val) ? "nil" : + val == Qtrue ? "true" : + val == Qfalse ? "false" : + NULL; + rb_raise(rb_eTypeError, + "can't convert %s into BigDecimal", cname); + } + return Qnil; + + default: + break; + } + + if (is_kind_of_BigDecimal(val)) { + if (digs == SIZE_MAX) + return check_exception(val); + + Real *vp = VpPtr(val); + + VALUE copy = BigDecimal_allocate(vp->MaxPrec); + Real *vp_copy = VpPtr(copy); + + VpMemCopy(vp_copy, vp); + + RB_GC_GUARD(val); + + /* TODO: rounding */ + return check_exception(copy); + } + else if (RB_INTEGER_TYPE_P(val)) { + return rb_inum_convert_to_BigDecimal(val); + } + else if (RB_FLOAT_TYPE_P(val)) { + return rb_float_convert_to_BigDecimal(val, digs, raise_exception); + } + else if (RB_TYPE_P(val, T_RATIONAL)) { + return rb_rational_convert_to_BigDecimal(val, digs, raise_exception); + } + else if (RB_TYPE_P(val, T_COMPLEX)) { + VALUE im = rb_complex_imag(val); + if (!is_zero(im)) { + /* TODO: handle raise_exception */ + rb_raise(rb_eArgError, + "Unable to make a BigDecimal from non-zero imaginary number"); + } + return rb_convert_to_BigDecimal(rb_complex_real(val), digs, raise_exception); + } + else if (RB_TYPE_P(val, T_STRING)) { + return rb_str_convert_to_BigDecimal(val, raise_exception); + } + + /* TODO: chheck to_d */ + /* TODO: chheck to_int */ + + VALUE str = rb_check_convert_type(val, T_STRING, "String", "to_str"); + if (!RB_TYPE_P(str, T_STRING)) { + if (raise_exception) { + rb_raise(rb_eTypeError, + "can't convert %"PRIsVALUE" into BigDecimal", rb_obj_class(val)); + } + return Qnil; + } + return rb_str_convert_to_BigDecimal(str, raise_exception); +} + +/* call-seq: + * BigDecimal(value, exception: true) -> bigdecimal + * BigDecimal(value, ndigits, exception: true) -> bigdecimal + * + * Returns the \BigDecimal converted from +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the value, the result is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * When +ndigits+ is 0, the number of digits to correctly represent a float number + * is determined automatically. + * + * Returns +value+ converted to a \BigDecimal, depending on the type of +value+: + * + * - Integer, Float, Rational, Complex, or BigDecimal: converted directly: + * + * # Integer, Complex, Float, or BigDecimal value does not require ndigits; ignored if given. + * BigDecimal(2) # => 0.2e1 + * BigDecimal(Complex(2, 0)) # => 0.2e1 + * BigDecimal(BigDecimal(2)) # => 0.2e1 + * BigDecimal(2.0) # => 0.2e1 + * # Rational value requires ndigits. + * BigDecimal(Rational(2, 1), 0) # => 0.2e1 + * + * - String: converted by parsing if it contains an integer or floating-point literal; + * leading and trailing whitespace is ignored: + * + * # String does not require ndigits; ignored if given. + * BigDecimal('2') # => 0.2e1 + * BigDecimal('2.0') # => 0.2e1 + * BigDecimal('0.2e1') # => 0.2e1 + * BigDecimal(' 2.0 ') # => 0.2e1 + * + * - Other type that responds to method :to_str: + * first converted to a string, then converted to a \BigDecimal, as above. + * + * - Other type: + * + * - Raises an exception if keyword argument +exception+ is +true+. + * - Returns +nil+ if keyword argument +exception+ is +false+. + * + * Raises an exception if +value+ evaluates to a Float + * and +digits+ is larger than Float::DIG + 1. + * + */ +static VALUE +f_BigDecimal(int argc, VALUE *argv, VALUE self) +{ + VALUE val, digs_v, opts = Qnil; + argc = rb_scan_args(argc, argv, "11:", &val, &digs_v, &opts); + int exception = opts_exception_p(opts); + + size_t digs = SIZE_MAX; /* this means digs is omitted */ + if (argc > 1) { + digs_v = rb_to_int(digs_v); + if (FIXNUM_P(digs_v)) { + long n = FIX2LONG(digs_v); + if (n < 0) + goto negative_digs; + digs = (size_t)n; + } + else { + if (RBIGNUM_NEGATIVE_P(digs_v)) { + negative_digs: + if (!exception) + return Qnil; + rb_raise(rb_eArgError, "negative precision"); + } + digs = NUM2SIZET(digs_v); + } + } + + return rb_convert_to_BigDecimal(val, digs, exception); +} + +/* call-seq: + * BigDecimal.interpret_loosely(string) -> bigdecimal + * + * Returns the +BigDecimal+ converted loosely from +string+. + */ + +static VALUE +BigDecimal_s_interpret_loosely(VALUE klass, VALUE str) +{ + char const *c_str = StringValueCStr(str); + NULLABLE_BDVALUE v = CreateFromString(c_str, klass, false, true); + if (v.bigdecimal_or_nil == Qnil) + return Qnil; + else + return CheckGetValue(bdvalue_nonnullable(v)); +} + + /* + * call-seq: + * BigDecimal.limit(digits) + * + * Limit the number of significant digits in newly created BigDecimal + * numbers to the specified value. Rounding is performed as necessary, + * as specified by BigDecimal.mode. + * + * A limit of 0, the default, means no upper limit. + * + * The limit specified by this method takes less priority over any limit + * specified to instance methods such as ceil, floor, truncate, or round. + */ +static VALUE +BigDecimal_limit(int argc, VALUE *argv, VALUE self) +{ + VALUE nFig; + VALUE nCur = SIZET2NUM(VpGetPrecLimit()); + + if (rb_scan_args(argc, argv, "01", &nFig) == 1) { + int nf; + if (NIL_P(nFig)) return nCur; + nf = NUM2INT(nFig); + if (nf < 0) { + rb_raise(rb_eArgError, "argument must be positive"); + } + VpSetPrecLimit(nf); + } + return nCur; +} + +/* Returns the sign of the value. + * + * Returns a positive value if > 0, a negative value if < 0. + * It behaves the same with zeros - + * it returns a positive value for a positive zero (BigDecimal('0')) and + * a negative value for a negative zero (BigDecimal('-0')). + * + * The specific value returned indicates the type and sign of the BigDecimal, + * as follows: + * + * BigDecimal::SIGN_NaN:: value is Not a Number + * BigDecimal::SIGN_POSITIVE_ZERO:: value is +0 + * BigDecimal::SIGN_NEGATIVE_ZERO:: value is -0 + * BigDecimal::SIGN_POSITIVE_INFINITE:: value is +Infinity + * BigDecimal::SIGN_NEGATIVE_INFINITE:: value is -Infinity + * BigDecimal::SIGN_POSITIVE_FINITE:: value is positive + * BigDecimal::SIGN_NEGATIVE_FINITE:: value is negative + */ +static VALUE +BigDecimal_sign(VALUE self) +{ /* sign */ + int s = GetSelfVpValue(self)->sign; + return INT2FIX(s); +} + +/* + * call-seq: BigDecimal.save_exception_mode { ... } + * + * Execute the provided block, but preserve the exception mode + * + * BigDecimal.save_exception_mode do + * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) + * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) + * + * BigDecimal(BigDecimal('Infinity')) + * BigDecimal(BigDecimal('-Infinity')) + * BigDecimal(BigDecimal('NaN')) + * end + * + * For use with the BigDecimal::EXCEPTION_* + * + * See BigDecimal.mode + */ +static VALUE +BigDecimal_save_exception_mode(VALUE self) +{ + unsigned short const exception_mode = VpGetException(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetException(exception_mode); + if (state) rb_jump_tag(state); + return ret; +} + +/* + * call-seq: BigDecimal.save_rounding_mode { ... } + * + * Execute the provided block, but preserve the rounding mode + * + * BigDecimal.save_rounding_mode do + * BigDecimal.mode(BigDecimal::ROUND_MODE, :up) + * puts BigDecimal.mode(BigDecimal::ROUND_MODE) + * end + * + * For use with the BigDecimal::ROUND_* + * + * See BigDecimal.mode + */ +static VALUE +BigDecimal_save_rounding_mode(VALUE self) +{ + unsigned short const round_mode = VpGetRoundMode(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetRoundMode(round_mode); + if (state) rb_jump_tag(state); + return ret; +} + +/* + * call-seq: BigDecimal.save_limit { ... } + * + * Execute the provided block, but preserve the precision limit + * + * BigDecimal.limit(100) + * puts BigDecimal.limit + * BigDecimal.save_limit do + * BigDecimal.limit(200) + * puts BigDecimal.limit + * end + * puts BigDecimal.limit + * + */ +static VALUE +BigDecimal_save_limit(VALUE self) +{ + size_t const limit = VpGetPrecLimit(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetPrecLimit(limit); + if (state) rb_jump_tag(state); + return ret; +} + +static VALUE BIGDECIMAL_NAN = Qnil; + +static VALUE +BigDecimal_nan(void) +{ + return BIGDECIMAL_NAN; +} + +static VALUE BIGDECIMAL_POSITIVE_INFINITY = Qnil; + +static VALUE +BigDecimal_positive_infinity(void) +{ + return BIGDECIMAL_POSITIVE_INFINITY; +} + +static VALUE BIGDECIMAL_NEGATIVE_INFINITY = Qnil; + +static VALUE +BigDecimal_negative_infinity(void) +{ + return BIGDECIMAL_NEGATIVE_INFINITY; +} + +static VALUE BIGDECIMAL_POSITIVE_ZERO = Qnil; + +static VALUE +BigDecimal_positive_zero(void) +{ + return BIGDECIMAL_POSITIVE_ZERO; +} + +static VALUE BIGDECIMAL_NEGATIVE_ZERO = Qnil; + +static VALUE +BigDecimal_negative_zero(void) +{ + return BIGDECIMAL_NEGATIVE_ZERO; +} + +static inline VALUE +BigDecimal_literal(const char *str) +{ + VALUE arg = rb_str_new_cstr(str); + VALUE val = f_BigDecimal(1, &arg, rb_cBigDecimal); + rb_gc_register_mark_object(val); + return val; +} + +#define BIGDECIMAL_LITERAL(var, val) (BIGDECIMAL_ ## var = BigDecimal_literal(#val)) + +#ifdef BIGDECIMAL_USE_VP_TEST_METHODS +VALUE +BigDecimal_vpdivd_generic(VALUE self, VALUE r, VALUE cprec, void (*vpdivd_func)(Real*, Real*, Real*, Real*)) { + BDVALUE a, b, c, d; + size_t cn = NUM2INT(cprec); + a = GetBDValueMust(self); + b = GetBDValueMust(r); + c = NewZeroWrap(1, cn * BASE_FIG); + d = NewZeroWrap(1, VPDIVD_REM_PREC(a.real, b.real, c.real) * BASE_FIG); + vpdivd_func(c.real, d.real, a.real, b.real); + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return rb_assoc_new(c.bigdecimal, d.bigdecimal); +} + +void +VpDivdNormal(Real *c, Real *r, Real *a, Real *b) { + VpDivd(c, r, a, b); +} + +VALUE +BigDecimal_vpdivd(VALUE self, VALUE r, VALUE cprec) { + return BigDecimal_vpdivd_generic(self, r, cprec, VpDivdNormal); +} + +VALUE +BigDecimal_vpdivd_newton(VALUE self, VALUE r, VALUE cprec) { + return BigDecimal_vpdivd_generic(self, r, cprec, VpDivdNewton); +} + +VALUE +BigDecimal_newton_raphson_inverse(VALUE self, VALUE prec) { + return newton_raphson_inverse(self, NUM2SIZET(prec)); +} + +VALUE +BigDecimal_vpmult(VALUE self, VALUE v) { + BDVALUE a,b,c; + a = GetBDValueMust(self); + b = GetBDValueMust(v); + c = NewZeroWrap(1, VPMULT_RESULT_PREC(a.real, b.real) * BASE_FIG); + VpMult(c.real, a.real, b.real); + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return c.bigdecimal; +} + +VALUE +BigDecimal_nttmult(VALUE self, VALUE v) { + BDVALUE a,b,c; + a = GetBDValueMust(self); + b = GetBDValueMust(v); + c = NewZeroWrap(1, VPMULT_RESULT_PREC(a.real, b.real) * BASE_FIG); + ntt_multiply(a.real->Prec, b.real->Prec, a.real->frac, b.real->frac, c.real->frac); + VpSetSign(c.real, a.real->sign * b.real->sign); + c.real->exponent = a.real->exponent + b.real->exponent; + c.real->Prec = a.real->Prec + b.real->Prec; + VpNmlz(c.real); + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return c.bigdecimal; +} + +#endif /* BIGDECIMAL_USE_VP_TEST_METHODS */ + +/* Document-class: BigDecimal + * BigDecimal provides arbitrary-precision floating point decimal arithmetic. + * + * == Introduction + * + * Ruby provides built-in support for arbitrary precision integer arithmetic. + * + * For example: + * + * 42**13 #=> 1265437718438866624512 + * + * BigDecimal provides similar support for very large or very accurate floating + * point numbers. + * + * Decimal arithmetic is also useful for general calculation, because it + * provides the correct answers people expect--whereas normal binary floating + * point arithmetic often introduces subtle errors because of the conversion + * between base 10 and base 2. + * + * For example, try: + * + * sum = 0 + * 10_000.times do + * sum = sum + 0.0001 + * end + * print sum #=> 0.9999999999999062 + * + * and contrast with the output from: + * + * require 'bigdecimal' + * + * sum = BigDecimal("0") + * 10_000.times do + * sum = sum + BigDecimal("0.0001") + * end + * print sum #=> 0.1E1 + * + * Similarly: + * + * (BigDecimal("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true + * + * (1.2 - 1.0) == 0.2 #=> false + * + * == A Note About Precision + * + * For a calculation using a \BigDecimal and another +value+, + * the precision of the result depends on the type of +value+: + * + * - If +value+ is a \Float, + * the precision is Float::DIG + 1. + * - If +value+ is a \Rational, the precision is larger than Float::DIG + 1. + * - If +value+ is a \BigDecimal, the precision is +value+'s precision in the + * internal representation, which is platform-dependent. + * - If +value+ is other object, the precision is determined by the result of +BigDecimal(value)+. + * + * == Special features of accurate decimal arithmetic + * + * Because BigDecimal is more accurate than normal binary floating point + * arithmetic, it requires some special values. + * + * === Infinity + * + * BigDecimal sometimes needs to return infinity, for example if you divide + * a value by zero. + * + * BigDecimal("1.0") / BigDecimal("0.0") #=> Infinity + * BigDecimal("-1.0") / BigDecimal("0.0") #=> -Infinity + * + * You can represent infinite numbers to BigDecimal using the strings + * 'Infinity', '+Infinity' and + * '-Infinity' (case-sensitive) + * + * === Not a Number + * + * When a computation results in an undefined value, the special value +NaN+ + * (for 'not a number') is returned. + * + * Example: + * + * BigDecimal("0.0") / BigDecimal("0.0") #=> NaN + * + * You can also create undefined values. + * + * NaN is never considered to be the same as any other value, even NaN itself: + * + * n = BigDecimal('NaN') + * n == 0.0 #=> false + * n == n #=> false + * + * === Positive and negative zero + * + * If a computation results in a value which is too small to be represented as + * a BigDecimal within the currently specified limits of precision, zero must + * be returned. + * + * If the value which is too small to be represented is negative, a BigDecimal + * value of negative zero is returned. + * + * BigDecimal("1.0") / BigDecimal("-Infinity") #=> -0.0 + * + * If the value is positive, a value of positive zero is returned. + * + * BigDecimal("1.0") / BigDecimal("Infinity") #=> 0.0 + * + * (See BigDecimal.mode for how to specify limits of precision.) + * + * Note that +-0.0+ and +0.0+ are considered to be the same for the purposes of + * comparison. + * + * Note also that in mathematics, there is no particular concept of negative + * or positive zero; true mathematical zero has no sign. + * + * == bigdecimal/util + * + * When you require +bigdecimal/util+, the #to_d method will be + * available on BigDecimal and the native Integer, Float, Rational, + * String, Complex, and NilClass classes: + * + * require 'bigdecimal/util' + * + * 42.to_d # => 0.42e2 + * 0.5.to_d # => 0.5e0 + * (2/3r).to_d(3) # => 0.667e0 + * "0.5".to_d # => 0.5e0 + * Complex(0.1234567, 0).to_d(4) # => 0.1235e0 + * nil.to_d # => 0.0 + * + * == Methods for Working with \JSON + * + * - {::json_create}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-c-json_create]: + * Returns a new \BigDecimal object constructed from the given object. + * - {#as_json}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-i-as_json]: + * Returns a 2-element hash representing +self+. + * - {#to_json}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-i-to_json]: + * Returns a \JSON string representing +self+. + * + * These methods are provided by the {JSON gem}[https://github.com/flori/json]. To make these methods available: + * + * require 'json/add/bigdecimal' + * + * * == License + * + * Copyright (C) 2002 by Shigeo Kobayashi . + * + * BigDecimal is released under the Ruby and 2-clause BSD licenses. + * See LICENSE.txt for details. + * + * Maintained by mrkn and ruby-core members. + * + * Documented by zzak , mathew , and + * many other contributors. + */ +void +Init_bigdecimal(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + + id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode"); + id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode"); + id_BigDecimal_precision_limit = rb_intern_const("BigDecimal.precision_limit"); + + /* Initialize VP routines */ + VpInit(0UL); + + /* Class and method registration */ + rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric); + + /* Global function */ + rb_define_global_function("BigDecimal", f_BigDecimal, -1); + + /* Class methods */ + rb_undef_alloc_func(rb_cBigDecimal); + rb_undef_method(CLASS_OF(rb_cBigDecimal), "new"); + rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1); + rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1); + rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1); + rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0); + rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1); + + rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0); + rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0); + rb_define_singleton_method(rb_cBigDecimal, "save_limit", BigDecimal_save_limit, 0); + + /* Constants definition */ + + /* + * The version of bigdecimal library + */ + rb_define_const(rb_cBigDecimal, "VERSION", rb_str_new2(BIGDECIMAL_VERSION)); + + /* + * Base value used in internal calculations. On a 32 bit system, BASE + * is 10000, indicating that calculation is done in groups of 4 digits. + * (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't + * guarantee that two groups could always be multiplied together without + * overflow.) + */ + rb_define_const(rb_cBigDecimal, "BASE", INT2FIX((SIGNED_VALUE)BASE)); + + /* Exceptions */ + + /* + * 0xff: Determines whether overflow, underflow or zero divide result in + * an exception being thrown. See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_ALL", INT2FIX(VP_EXCEPTION_ALL)); + + /* + * 0x02: Determines what happens when the result of a computation is not a + * number (NaN). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_NaN", INT2FIX(VP_EXCEPTION_NaN)); + + /* + * 0x01: Determines what happens when the result of a computation is + * infinity. See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_INFINITY", INT2FIX(VP_EXCEPTION_INFINITY)); + + /* + * 0x04: Determines what happens when the result of a computation is an + * underflow (a result too small to be represented). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_UNDERFLOW", INT2FIX(VP_EXCEPTION_UNDERFLOW)); + + /* + * 0x01: Determines what happens when the result of a computation is an + * overflow (a result too large to be represented). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW", INT2FIX(VP_EXCEPTION_OVERFLOW)); + + /* + * 0x10: Determines what happens when a division by zero is performed. + * See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE", INT2FIX(VP_EXCEPTION_ZERODIVIDE)); + + /* + * 0x100: Determines what happens when a result must be rounded in order to + * fit in the appropriate number of significant digits. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_MODE", INT2FIX(VP_ROUND_MODE)); + + /* 1: Indicates that values should be rounded away from zero. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_UP", INT2FIX(VP_ROUND_UP)); + + /* 2: Indicates that values should be rounded towards zero. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_DOWN", INT2FIX(VP_ROUND_DOWN)); + + /* 3: Indicates that digits >= 5 should be rounded up, others rounded down. + * See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_UP", INT2FIX(VP_ROUND_HALF_UP)); + + /* 4: Indicates that digits >= 6 should be rounded up, others rounded down. + * See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_DOWN", INT2FIX(VP_ROUND_HALF_DOWN)); + /* 5: Round towards +Infinity. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_CEILING", INT2FIX(VP_ROUND_CEIL)); + + /* 6: Round towards -Infinity. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_FLOOR", INT2FIX(VP_ROUND_FLOOR)); + + /* 7: Round towards the even neighbor. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_EVEN", INT2FIX(VP_ROUND_HALF_EVEN)); + + /* 0: Indicates that a value is not a number. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NaN", INT2FIX(VP_SIGN_NaN)); + + /* 1: Indicates that a value is +0. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_ZERO", INT2FIX(VP_SIGN_POSITIVE_ZERO)); + + /* -1: Indicates that a value is -0. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_ZERO", INT2FIX(VP_SIGN_NEGATIVE_ZERO)); + + /* 2: Indicates that a value is positive and finite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_FINITE", INT2FIX(VP_SIGN_POSITIVE_FINITE)); + + /* -2: Indicates that a value is negative and finite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_FINITE", INT2FIX(VP_SIGN_NEGATIVE_FINITE)); + + /* 3: Indicates that a value is positive and infinite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_INFINITE", INT2FIX(VP_SIGN_POSITIVE_INFINITE)); + + /* -3: Indicates that a value is negative and infinite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE)); + + /* Positive zero value. */ + BIGDECIMAL_LITERAL(POSITIVE_ZERO, +0); + + /* Negative zero value. */ + BIGDECIMAL_LITERAL(NEGATIVE_ZERO, -0); + + /* Positive infinity[rdoc-ref:BigDecimal@Infinity] value. */ + rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_LITERAL(POSITIVE_INFINITY, +Infinity)); + + /* Negative infinity value. */ + BIGDECIMAL_LITERAL(NEGATIVE_INFINITY, -Infinity); + + /* '{Not a Number}[rdoc-ref:BigDecimal@Not+a+Number]' value. */ + rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_LITERAL(NAN, NaN)); + + /* instance methods */ + rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0); + rb_define_method(rb_cBigDecimal, "scale", BigDecimal_scale, 0); + rb_define_method(rb_cBigDecimal, "precision_scale", BigDecimal_precision_scale, 0); + rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0); + + rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2); + rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2); + rb_define_method(rb_cBigDecimal, "mult", BigDecimal_mult2, 2); + rb_define_method(rb_cBigDecimal, "div", BigDecimal_div3, -1); + rb_define_method(rb_cBigDecimal, "hash", BigDecimal_hash, 0); + rb_define_method(rb_cBigDecimal, "to_s", BigDecimal_to_s, -1); + rb_define_method(rb_cBigDecimal, "to_i", BigDecimal_to_i, 0); + rb_define_method(rb_cBigDecimal, "to_int", BigDecimal_to_i, 0); + rb_define_method(rb_cBigDecimal, "to_r", BigDecimal_to_r, 0); + rb_define_method(rb_cBigDecimal, "split", BigDecimal_split, 0); + rb_define_method(rb_cBigDecimal, "+", BigDecimal_add, 1); + rb_define_method(rb_cBigDecimal, "-", BigDecimal_sub, 1); + rb_define_method(rb_cBigDecimal, "+@", BigDecimal_uplus, 0); + rb_define_method(rb_cBigDecimal, "-@", BigDecimal_neg, 0); + rb_define_method(rb_cBigDecimal, "*", BigDecimal_mult, 1); + rb_define_method(rb_cBigDecimal, "/", BigDecimal_div, 1); + rb_define_method(rb_cBigDecimal, "quo", BigDecimal_quo, -1); + rb_define_method(rb_cBigDecimal, "%", BigDecimal_mod, 1); + rb_define_method(rb_cBigDecimal, "modulo", BigDecimal_mod, 1); + rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1); + rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1); + rb_define_method(rb_cBigDecimal, "clone", BigDecimal_clone, 0); + rb_define_method(rb_cBigDecimal, "dup", BigDecimal_clone, 0); + rb_define_method(rb_cBigDecimal, "to_f", BigDecimal_to_f, 0); + rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0); + rb_define_method(rb_cBigDecimal, "fix", BigDecimal_fix, 0); + rb_define_method(rb_cBigDecimal, "round", BigDecimal_round, -1); + rb_define_method(rb_cBigDecimal, "frac", BigDecimal_frac, 0); + rb_define_method(rb_cBigDecimal, "floor", BigDecimal_floor, -1); + rb_define_method(rb_cBigDecimal, "ceil", BigDecimal_ceil, -1); + rb_define_method(rb_cBigDecimal, "<=>", BigDecimal_comp, 1); + rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "===", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "eql?", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "<", BigDecimal_lt, 1); + rb_define_method(rb_cBigDecimal, "<=", BigDecimal_le, 1); + rb_define_method(rb_cBigDecimal, ">", BigDecimal_gt, 1); + rb_define_method(rb_cBigDecimal, ">=", BigDecimal_ge, 1); + rb_define_method(rb_cBigDecimal, "zero?", BigDecimal_zero, 0); + rb_define_method(rb_cBigDecimal, "nonzero?", BigDecimal_nonzero, 0); + rb_define_method(rb_cBigDecimal, "coerce", BigDecimal_coerce, 1); + rb_define_method(rb_cBigDecimal, "inspect", BigDecimal_inspect, 0); + rb_define_method(rb_cBigDecimal, "exponent", BigDecimal_exponent, 0); + rb_define_method(rb_cBigDecimal, "sign", BigDecimal_sign, 0); + rb_define_method(rb_cBigDecimal, "nan?", BigDecimal_IsNaN, 0); + rb_define_method(rb_cBigDecimal, "infinite?", BigDecimal_IsInfinite, 0); + rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0); + rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1); + rb_define_method(rb_cBigDecimal, "_decimal_shift", BigDecimal_decimal_shift, 1); + rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1); + +#ifdef BIGDECIMAL_USE_VP_TEST_METHODS + rb_define_method(rb_cBigDecimal, "vpdivd", BigDecimal_vpdivd, 2); + rb_define_method(rb_cBigDecimal, "vpdivd_newton", BigDecimal_vpdivd_newton, 2); + rb_define_method(rb_cBigDecimal, "newton_raphson_inverse", BigDecimal_newton_raphson_inverse, 1); + rb_define_method(rb_cBigDecimal, "vpmult", BigDecimal_vpmult, 1); + rb_define_method(rb_cBigDecimal, "nttmult", BigDecimal_nttmult, 1); +#endif /* BIGDECIMAL_USE_VP_TEST_METHODS */ + +#define ROUNDING_MODE(i, name, value) \ + id_##name = rb_intern_const(#name); \ + rbd_rounding_modes[i].id = id_##name; \ + rbd_rounding_modes[i].mode = value; + + ROUNDING_MODE(0, up, RBD_ROUND_UP); + ROUNDING_MODE(1, down, RBD_ROUND_DOWN); + ROUNDING_MODE(2, half_up, RBD_ROUND_HALF_UP); + ROUNDING_MODE(3, half_down, RBD_ROUND_HALF_DOWN); + ROUNDING_MODE(4, ceil, RBD_ROUND_CEIL); + ROUNDING_MODE(5, floor, RBD_ROUND_FLOOR); + ROUNDING_MODE(6, half_even, RBD_ROUND_HALF_EVEN); + + ROUNDING_MODE(7, default, RBD_ROUND_DEFAULT); + ROUNDING_MODE(8, truncate, RBD_ROUND_TRUNCATE); + ROUNDING_MODE(9, banker, RBD_ROUND_BANKER); + ROUNDING_MODE(10, ceiling, RBD_ROUND_CEILING); + +#undef ROUNDING_MODE + + id_to_r = rb_intern_const("to_r"); + id_eq = rb_intern_const("=="); + id_half = rb_intern_const("half"); + + (void)VPrint; /* suppress unused warning */ +} + +/* + * + * ============================================================================ + * + * vp_ routines begin from here. + * + * ============================================================================ + * + */ +#ifdef BIGDECIMAL_DEBUG +static int gfDebug = 1; /* Debug switch */ +#endif /* BIGDECIMAL_DEBUG */ + +static VALUE VpConstOne; /* constant 1.0 */ + +enum op_sw { + OP_SW_ADD = 1, /* + */ + OP_SW_SUB, /* - */ + OP_SW_MULT, /* * */ + OP_SW_DIV /* / */ +}; + +static int VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw); +static DECDIG VpAddAbs(Real *a,Real *b,Real *c); +static DECDIG VpSubAbs(Real *a,Real *b,Real *c); +static size_t VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv); +static void VpFormatSt(char *psz, size_t fFmt); +static int VpRdup(Real *m, size_t ind_m); + +#ifdef BIGDECIMAL_DEBUG +# ifdef HAVE_RB_EXT_RACTOR_SAFE +# error Need to make rewiting gnAlloc atomic +# endif +static int gnAlloc = 0; /* Memory allocation counter */ +#endif /* BIGDECIMAL_DEBUG */ + +/* + * EXCEPTION Handling. + */ + +#define bigdecimal_set_thread_local_exception_mode(mode) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_exception_mode, \ + INT2FIX((int)(mode)) \ + ) + +static unsigned short +VpGetException (void) +{ + VALUE const vmode = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_exception_mode + ); + + if (NIL_P(vmode)) { + bigdecimal_set_thread_local_exception_mode(BIGDECIMAL_EXCEPTION_MODE_DEFAULT); + return BIGDECIMAL_EXCEPTION_MODE_DEFAULT; + } + + return NUM2USHORT(vmode); +} + +static void +VpSetException(unsigned short f) +{ + bigdecimal_set_thread_local_exception_mode(f); +} + +static void +VpCheckException(Real *p, bool always) +{ + if (VpIsNaN(p)) { + VpException(VP_EXCEPTION_NaN, "Computation results in 'NaN' (Not a Number)", always); + } + else if (VpIsPosInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results in 'Infinity'", always); + } + else if (VpIsNegInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results in '-Infinity'", always); + } +} + +static VALUE +CheckGetValue(BDVALUE v) +{ + VpCheckException(v.real, false); + return v.bigdecimal; +} + +/* + * Precision limit. + */ + +#define bigdecimal_set_thread_local_precision_limit(limit) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_precision_limit, \ + SIZET2NUM(limit) \ + ) +#define BIGDECIMAL_PRECISION_LIMIT_DEFAULT ((size_t)0) + +/* These 2 functions added at v1.1.7 */ +VP_EXPORT size_t +VpGetPrecLimit(void) +{ + VALUE const vlimit = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_precision_limit + ); + + if (NIL_P(vlimit)) { + bigdecimal_set_thread_local_precision_limit(BIGDECIMAL_PRECISION_LIMIT_DEFAULT); + return BIGDECIMAL_PRECISION_LIMIT_DEFAULT; + } + + return NUM2SIZET(vlimit); +} + +VP_EXPORT void +VpSetPrecLimit(size_t n) +{ + bigdecimal_set_thread_local_precision_limit(n); +} + +/* + * Rounding mode. + */ + +#define bigdecimal_set_thread_local_rounding_mode(mode) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_rounding_mode, \ + INT2FIX((int)(mode)) \ + ) + +VP_EXPORT unsigned short +VpGetRoundMode(void) +{ + VALUE const vmode = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_rounding_mode + ); + + if (NIL_P(vmode)) { + bigdecimal_set_thread_local_rounding_mode(BIGDECIMAL_ROUNDING_MODE_DEFAULT); + return BIGDECIMAL_ROUNDING_MODE_DEFAULT; + } + + return NUM2USHORT(vmode); +} + +VP_EXPORT int +VpIsRoundMode(unsigned short n) +{ + switch (n) { + case VP_ROUND_UP: + case VP_ROUND_DOWN: + case VP_ROUND_HALF_UP: + case VP_ROUND_HALF_DOWN: + case VP_ROUND_CEIL: + case VP_ROUND_FLOOR: + case VP_ROUND_HALF_EVEN: + return 1; + + default: + return 0; + } +} + +VP_EXPORT unsigned short +VpSetRoundMode(unsigned short n) +{ + if (VpIsRoundMode(n)) { + bigdecimal_set_thread_local_rounding_mode(n); + return n; + } + + return VpGetRoundMode(); +} + +/* + * 0.0 & 1.0 generator + * These gZero_..... and gOne_..... can be any name + * referenced from nowhere except Zero() and One(). + * gZero_..... and gOne_..... must have global scope + * (to let the compiler know they may be changed in outside + * (... but not actually..)). + */ +volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0; + +static double +One(void) +{ + return gOne_ABCED9B4_CE73__00400511F31D; +} + +/* + ---------------------------------------------------------------- + Value of sign in Real structure is reserved for future use. + short sign; + ==0 : NaN + 1 : Positive zero + -1 : Negative zero + 2 : Positive number + -2 : Negative number + 3 : Positive infinite number + -3 : Negative infinite number + ---------------------------------------------------------------- +*/ + +VP_EXPORT double +VpGetDoubleNaN(void) /* Returns the value of NaN */ +{ + return nan(""); +} + +VP_EXPORT double +VpGetDoublePosInf(void) /* Returns the value of +Infinity */ +{ + return HUGE_VAL; +} + +VP_EXPORT double +VpGetDoubleNegInf(void) /* Returns the value of -Infinity */ +{ + return -HUGE_VAL; +} + +VP_EXPORT double +VpGetDoubleNegZero(void) /* Returns the value of -0 */ +{ + static double nzero = 1000.0; + if (nzero != 0.0) nzero = (One()/VpGetDoubleNegInf()); + return nzero; +} + +VP_EXPORT int +VpException(unsigned short f, const char *str,int always) +{ + unsigned short const exception_mode = VpGetException(); + + if (f == VP_EXCEPTION_OP) always = 1; + + if (always || (exception_mode & f)) { + switch(f) { + /* case VP_EXCEPTION_OVERFLOW: */ + case VP_EXCEPTION_ZERODIVIDE: + case VP_EXCEPTION_INFINITY: + case VP_EXCEPTION_NaN: + case VP_EXCEPTION_UNDERFLOW: + case VP_EXCEPTION_OP: + rb_raise(rb_eFloatDomainError, "%s", str); + break; + default: + rb_fatal("%s", str); + } + } + return 0; /* 0 Means VpException() raised no exception */ +} + +/* Throw exception or returns 0,when resulting c is Inf or NaN */ +/* sw=1:+ 2:- 3:* 4:/ */ +static int +VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw) +{ + if (VpIsNaN(a) || VpIsNaN(b)) { + /* at least a or b is NaN */ + VpSetNaN(c); + goto NaN; + } + + if (VpIsInf(a)) { + if (VpIsInf(b)) { + switch(sw) { + case OP_SW_ADD: /* + */ + if (VpGetSign(a) == VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + case OP_SW_SUB: /* - */ + if (VpGetSign(a) != VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + case OP_SW_MULT: /* * */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + goto Inf; + case OP_SW_DIV: /* / */ + VpSetNaN(c); + goto NaN; + } + VpSetNaN(c); + goto NaN; + } + /* Inf op Finite */ + switch(sw) { + case OP_SW_ADD: /* + */ + case OP_SW_SUB: /* - */ + VpSetInf(c, VpGetSign(a)); + break; + case OP_SW_MULT: /* * */ + if (VpIsZero(b)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case OP_SW_DIV: /* / */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; + } + + if (VpIsInf(b)) { + switch(sw) { + case OP_SW_ADD: /* + */ + VpSetInf(c, VpGetSign(b)); + break; + case OP_SW_SUB: /* - */ + VpSetInf(c, -VpGetSign(b)); + break; + case OP_SW_MULT: /* * */ + if (VpIsZero(a)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case OP_SW_DIV: /* / */ + VpSetZero(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; + } + return 1; /* Results OK */ + +Inf: + if (VpIsPosInf(c)) { + return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0); + } + else { + return VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 0); + } + +NaN: + return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); +} + +/* + ---------------------------------------------------------------- +*/ + +/* + * returns number of chars needed to represent vp in specified format. + */ +VP_EXPORT size_t +VpNumOfChars(Real *vp,const char *pszFmt) +{ + SIGNED_VALUE ex; + size_t nc; + + if (vp == NULL) return BASE_FIG*2+6; + if (!VpIsDef(vp)) return 32; /* not sure,may be OK */ + + switch(*pszFmt) { + case 'F': + nc = BASE_FIG*(vp->Prec + 1)+2; + ex = vp->exponent; + if (ex < 0) { + nc += BASE_FIG*(size_t)(-ex); + } + else { + if ((size_t)ex > vp->Prec) { + nc += BASE_FIG*((size_t)ex - vp->Prec); + } + } + break; + case 'E': + /* fall through */ + default: + nc = BASE_FIG * vp->Prec + 25; /* "-0."(3) + digits_chars + "e-"(2) + 64bit_exponent_chars(19) + null(1) */ + } + return nc; +} + +/* + * Initializer for Vp routines and constants used. + * [Input] + * BaseVal: Base value(assigned to BASE) for Vp calculation. + * It must be the form BaseVal=10**n.(n=1,2,3,...) + * If Base <= 0L,then the BASE will be calculated so + * that BASE is as large as possible satisfying the + * relation MaxVal <= BASE*(BASE+1). Where the value + * MaxVal is the largest value which can be represented + * by one DECDIG word in the computer used. + * + * [Returns] + * BIGDECIMAL_DOUBLE_FIGURES ... OK + */ +VP_EXPORT size_t +VpInit(DECDIG BaseVal) +{ + /* Setup +/- Inf NaN -0 */ + VpGetDoubleNegZero(); + + /* Const 1.0 */ + rb_global_variable(&VpConstOne); + VpConstOne = NewZeroWrap(1, 1).bigdecimal; + VpSetOne(VpPtr(VpConstOne)); + +#ifdef BIGDECIMAL_DEBUG + gnAlloc = 0; +#endif /* BIGDECIMAL_DEBUG */ + + return BIGDECIMAL_DOUBLE_FIGURES; +} + +VP_EXPORT Real * +VpOne(void) +{ + return VpPtr(VpConstOne); +} + +/* If exponent overflows,then raise exception or returns 0 */ +static int +AddExponent(Real *a, SIGNED_VALUE n) +{ + SIGNED_VALUE e = a->exponent; + SIGNED_VALUE m = e+n; + if (e > 0 && n > 0) { + if (n > VP_EXPONENT_MAX - e) goto overflow; + } else if (e < 0 && n < 0) { + if (n < VP_EXPONENT_MIN - e) goto underflow; + } else if (m > VP_EXPONENT_MAX) { + goto overflow; + } else if (m < VP_EXPONENT_MIN) { + goto underflow; + } + a->exponent = m; + return 1; + +/* Overflow/Underflow ==> Raise exception or returns 0 */ +underflow: + VpSetZero(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_UNDERFLOW, "Exponent underflow", 0); + +overflow: + VpSetInf(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0); +} + +NULLABLE_BDVALUE +bigdecimal_parse_special_string(const char *str) +{ + static const struct { + const char *str; + size_t len; + int sign; + } table[] = { + { SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE }, + { SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE }, + { SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE }, + { SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN } + }; + static const size_t table_length = sizeof(table) / sizeof(table[0]); + size_t i; + + for (i = 0; i < table_length; ++i) { + const char *p; + if (strncmp(str, table[i].str, table[i].len) != 0) { + continue; + } + + p = str + table[i].len; + while (*p && ISSPACE(*p)) ++p; + if (*p == '\0') { + VALUE obj = BigDecimal_allocate(1); + Real *vp = VpPtr(obj); + switch (table[i].sign) { + default: + UNREACHABLE; + return (NULLABLE_BDVALUE) { Qnil, NULL }; + case VP_SIGN_POSITIVE_INFINITE: + VpSetPosInf(vp); + break; + case VP_SIGN_NEGATIVE_INFINITE: + VpSetNegInf(vp); + break; + case VP_SIGN_NaN: + VpSetNaN(vp); + break; + } + return (NULLABLE_BDVALUE) { obj, vp }; + } + } + + return (NULLABLE_BDVALUE) { Qnil, NULL }; +} + +/* + * Allocates variable. + * [Input] + * szVal ... The value assigned(char). + * + * [Returns] + * NULLABLE_BDVALUE to the newly allocated variable. + * Null is returned if memory allocation failed, or any error occured. + */ +VP_EXPORT NULLABLE_BDVALUE +VpAlloc(const char *szVal, int strict_p, int exc) +{ + const char *orig_szVal = szVal; + size_t i, j, ni, ipf, nf, ipe, ne, exp_seen, nalloc; + char v, *psz; + int sign=1; + VALUE buf; + + /* Skipping leading spaces */ + while (ISSPACE(*szVal)) szVal++; + + /* Check on Inf & NaN */ + NULLABLE_BDVALUE special_bd = bigdecimal_parse_special_string(szVal); + if (special_bd.real_or_null != NULL) { + return special_bd; + } + + /* Skip leading `#`. + * It used to be a mark to indicate that an extra MaxPrec should be allocated, + * but now it has no effect. + */ + if (*szVal == '#') ++szVal; + + /* Scanning digits */ + + /* A buffer for keeping scanned digits */ + buf = rb_str_tmp_new(strlen(szVal) + 1); + psz = RSTRING_PTR(buf); + + /* cursor: i for psz, and j for szVal */ + i = j = 0; + + /* Scanning: sign part */ + v = psz[i] = szVal[j]; + if ((v == '-') || (v == '+')) { + sign = -(v == '-'); + ++i; + ++j; + } + + /* Scanning: integer part */ + ni = 0; /* number of digits in the integer part */ + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (ni > 0) { + v = szVal[j+1]; + if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + break; + } + } + goto invalid_value; + } + if (!ISDIGIT(v)) { + break; + } + ++ni; + ++i; + ++j; + } + + /* Scanning: fractional part */ + nf = 0; /* number of digits in the fractional part */ + ne = 0; /* number of digits in the exponential part */ + ipf = 0; /* index of the beginning of the fractional part */ + ipe = 0; /* index of the beginning of the exponential part */ + exp_seen = 0; + + if (v != '\0') { + /* Scanning fractional part */ + if ((psz[i] = szVal[j]) == '.') { + ++i; + ++j; + ipf = i; + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (nf > 0 && ISDIGIT(szVal[j+1])) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + break; + } + goto invalid_value; + } + if (!ISDIGIT(v)) break; + ++i; + ++j; + ++nf; + } + } + + /* Scanning exponential part */ + if (v != '\0') { + switch ((psz[i] = szVal[j])) { + case '\0': + break; + case 'e': case 'E': + case 'd': case 'D': + exp_seen = 1; + ++i; + ++j; + ipe = i; + v = psz[i] = szVal[j]; + if ((v == '-') || (v == '+')) { + ++i; + ++j; + } + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (ne > 0 && ISDIGIT(szVal[j+1])) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + if (ne == 0) { + exp_seen = 0; + } + break; + } + goto invalid_value; + } + if (!ISDIGIT(v)) break; + ++i; + ++j; + ++ne; + } + break; + default: + break; + } + } + + if (v != '\0') { + /* Scanning trailing spaces */ + while (ISSPACE(szVal[j])) ++j; + + /* Invalid character */ + if (szVal[j] && strict_p) { + goto invalid_value; + } + } + } + + psz[i] = '\0'; + + if (strict_p && ((ni == 0 && nf == 0) || (exp_seen && ne == 0))) { + VALUE str; + invalid_value: + if (!strict_p) { + BDVALUE res = rbd_allocate_struct_zero_wrap(1, 1); + return (NULLABLE_BDVALUE) { res.bigdecimal, res.real }; + } + if (!exc) { + return (NULLABLE_BDVALUE) { Qnil, NULL }; + } + str = rb_str_new2(orig_szVal); + rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str); + } + + nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */ + /* units for szVal[] */ + VALUE obj = BigDecimal_allocate(nalloc); + Real *vp = VpPtr(obj); + VpSetZero(vp, sign); + VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne); + rb_str_resize(buf, 0); + return (NULLABLE_BDVALUE) { obj, vp }; +} + +/* + * Assignment(c=a). + * [Input] + * a ... RHSV + * isw ... switch for assignment. + * c = a when isw > 0 + * c = -a when isw < 0 + * if c->MaxPrec < a->Prec,then round operation + * will be performed. + * [Output] + * c ... LHSV + */ +VP_EXPORT size_t +VpAsgn(Real *c, Real *a, int isw) +{ + size_t n; + if (VpIsNaN(a)) { + VpSetNaN(c); + return 0; + } + if (VpIsInf(a)) { + VpSetInf(c, isw * VpGetSign(a)); + return 0; + } + + /* check if the RHS is zero */ + if (!VpIsZero(a)) { + c->exponent = a->exponent; /* store exponent */ + VpSetSign(c, isw * VpGetSign(a)); /* set sign */ + n = (a->Prec < c->MaxPrec) ? (a->Prec) : (c->MaxPrec); + c->Prec = n; + memcpy(c->frac, a->frac, n * sizeof(DECDIG)); + /* Needs round ? */ + if (isw != 10 && isw != -10) { + /* Not in ActiveRound */ + if(c->Prec < a->Prec) { + VpInternalRound(c, n, (n>0) ? a->frac[n-1] : 0, a->frac[n]); + } + else { + VpLimitRound(c,0); + } + } + } + else { + /* The value of 'a' is zero. */ + VpSetZero(c, isw * VpGetSign(a)); + return 1; + } + return c->Prec * BASE_FIG; +} + +/* + * c = a + b when operation = 1 or 2 + * c = a - b when operation = -1 or -2. + * Returns number of significant digits of c + */ +VP_EXPORT size_t +VpAddSub(Real *c, Real *a, Real *b, int operation) +{ + short sw, isw, sign; + Real *a_ptr, *b_ptr; + size_t n, na, nb, i; + DECDIG mrv; + + if (!VpIsDefOP(c, a, b, (operation > 0) ? OP_SW_ADD : OP_SW_SUB)) return 0; /* No significant digits */ + + /* check if a or b is zero */ + if (VpIsZero(a)) { + /* a is zero,then assign b to c */ + if (!VpIsZero(b)) { + VpAsgn(c, b, operation); + } + else { + /* Both a and b are zero. */ + if (VpGetSign(a) < 0 && operation * VpGetSign(b) < 0) { + /* -0 -0 */ + VpSetZero(c, -1); + } + else { + VpSetZero(c, 1); + } + return 1; /* 0: 1 significant digits */ + } + return c->Prec * BASE_FIG; + } + if (VpIsZero(b)) { + /* b is zero,then assign a to c. */ + VpAsgn(c, a, 1); + return c->Prec*BASE_FIG; + } + + if (operation < 0) sw = -1; + else sw = 1; + + /* compare absolute value. As a result,|a_ptr|>=|b_ptr| */ + if (a->exponent > b->exponent) { + a_ptr = a; + b_ptr = b; + } /* |a|>|b| */ + else if (a->exponent < b->exponent) { + a_ptr = b; + b_ptr = a; + } /* |a|<|b| */ + else { + /* Exponent part of a and b is the same,then compare fraction */ + /* part */ + na = a->Prec; + nb = b->Prec; + n = Min(na, nb); + for (i=0; i < n; ++i) { + if (a->frac[i] > b->frac[i]) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (a->frac[i] < b->frac[i]) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + } + if (na > nb) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (na < nb) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + /* |a| == |b| */ + if (VpGetSign(a) + sw *VpGetSign(b) == 0) { + VpSetZero(c, 1); /* abs(a)=abs(b) and operation = '-' */ + return c->Prec * BASE_FIG; + } + a_ptr = a; + b_ptr = b; + } + +end_if: + isw = VpGetSign(a) + sw *VpGetSign(b); + /* + * isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1) + * = 2 ...( 1)+( 1),( 1)-(-1) + * =-2 ...(-1)+(-1),(-1)-( 1) + * If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|) + * else c =(Sign ofisw)(|a_ptr|+|b_ptr|) + */ + if (isw) { /* addition */ + VpSetSign(c, 1); + mrv = VpAddAbs(a_ptr, b_ptr, c); + sign = isw / 2; + } + else { /* subtraction */ + VpSetSign(c, 1); + mrv = VpSubAbs(a_ptr, b_ptr, c); + sign = a_ptr == a ? VpGetSign(a) : VpGetSign(a_ptr) * sw; + } + if (VpIsInf(c)) { + VpSetInf(c, sign); + } + else { + VpSetSign(c, sign); + VpInternalRound(c, 0, (c->Prec > 0) ? c->frac[c->Prec-1] : 0, mrv); + } + + return c->Prec * BASE_FIG; +} + +/* + * Addition of two values with variable precision + * a and b assuming abs(a)>abs(b). + * c = abs(a) + abs(b) ; where |a|>=|b| + */ +static DECDIG +VpAddAbs(Real *a, Real *b, Real *c) +{ + size_t word_shift; + size_t ap; + size_t bp; + size_t cp; + size_t a_pos; + size_t b_pos, b_pos_with_word_shift; + size_t c_pos; + DECDIG av, bv, carry, mrv; + + word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); + a_pos = ap; + b_pos = bp; + c_pos = cp; + + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; + + mrv = av + bv; /* Most right val. Used for round. */ + + /* Just assign the last few digits of b to c because a has no */ + /* corresponding digits to be added. */ + if (b_pos > 0) { + while (b_pos > 0 && b_pos + word_shift > a_pos) { + c->frac[--c_pos] = b->frac[--b_pos]; + } + } + if (b_pos == 0 && word_shift > a_pos) { + while (word_shift-- > a_pos) { + c->frac[--c_pos] = 0; + } + } + + /* Just assign the last few digits of a to c because b has no */ + /* corresponding digits to be added. */ + b_pos_with_word_shift = b_pos + word_shift; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; + } + carry = 0; /* set first carry be zero */ + + /* Now perform addition until every digits of b will be */ + /* exhausted. */ + while (b_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } + } + + /* Just assign the first few digits of a with considering */ + /* the carry obtained so far because b has been exhausted. */ + while (a_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } + } + if (c_pos) c->frac[c_pos - 1] += carry; + goto Exit; + +Assign_a: + VpAsgn(c, a, 1); + mrv = 0; + +Exit: + + return mrv; +} + +/* + * c = abs(a) - abs(b) + */ +static DECDIG +VpSubAbs(Real *a, Real *b, Real *c) +{ + size_t word_shift; + size_t ap; + size_t bp; + size_t cp; + size_t a_pos; + size_t b_pos, b_pos_with_word_shift; + size_t c_pos; + DECDIG av, bv, borrow, mrv; + + word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); + a_pos = ap; + b_pos = bp; + c_pos = cp; + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; + + if (av >= bv) { + mrv = av - bv; + borrow = 0; + } + else { + mrv = 0; + borrow = 1; + } + + /* Just assign the values which are the BASE subtracted by */ + /* each of the last few digits of the b because the a has no */ + /* corresponding digits to be subtracted. */ + if (b_pos + word_shift > a_pos) { + while (b_pos > 0 && b_pos + word_shift > a_pos) { + c->frac[--c_pos] = BASE - b->frac[--b_pos] - borrow; + borrow = 1; + } + if (b_pos == 0) { + while (word_shift > a_pos) { + --word_shift; + c->frac[--c_pos] = BASE - borrow; + borrow = 1; + } + } + } + /* Just assign the last few digits of a to c because b has no */ + /* corresponding digits to subtract. */ + + b_pos_with_word_shift = b_pos + word_shift; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; + } + + /* Now perform subtraction until every digits of b will be */ + /* exhausted. */ + while (b_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < b->frac[--b_pos] + borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 0; + } + } + + /* Just assign the first few digits of a with considering */ + /* the borrow obtained so far because b has been exhausted. */ + while (a_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - borrow; + borrow = 0; + } + } + if (c_pos) c->frac[c_pos - 1] -= borrow; + goto Exit; + +Assign_a: + VpAsgn(c, a, 1); + mrv = 0; + +Exit: + return mrv; +} + +/* + * Note: If(av+bv)>= HALF_BASE,then 1 will be added to the least significant + * digit of c(In case of addition). + * ------------------------- figure of output ----------------------------------- + * a = xxxxxxxxxxx + * b = xxxxxxxxxx + * c =xxxxxxxxxxxxxxx + * word_shift = | | + * right_word = | | (Total digits in RHSV) + * left_word = | | (Total digits in LHSV) + * a_pos = | + * b_pos = | + * c_pos = | + */ +static size_t +VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv) +{ + size_t left_word, right_word, word_shift; + + size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG; + + assert(a->exponent >= b->exponent); + + c->frac[0] = 0; + *av = *bv = 0; + + word_shift = (a->exponent - b->exponent); + left_word = b->Prec + word_shift; + right_word = Max(a->Prec, left_word); + left_word = c->MaxPrec - 1; /* -1 ... prepare for round up */ + + /* + * check if 'round' is needed. + */ + if (right_word > left_word) { /* round ? */ + /*--------------------------------- + * Actual size of a = xxxxxxAxx + * Actual size of b = xxxBxxxxx + * Max. size of c = xxxxxx + * Round off = |-----| + * c_pos = | + * right_word = | + * a_pos = | + */ + *c_pos = right_word = left_word + 1; /* Set resulting precision */ + /* be equal to that of c */ + if (a->Prec >= c->MaxPrec) { + /* + * a = xxxxxxAxxx + * c = xxxxxx + * a_pos = | + */ + *a_pos = left_word; + if (*a_pos <= round_limit) { + *av = a->frac[*a_pos]; /* av is 'A' shown in above. */ + } + } + else { + /* + * a = xxxxxxx + * c = xxxxxxxxxx + * a_pos = | + */ + *a_pos = a->Prec; + } + if (b->Prec + word_shift >= c->MaxPrec) { + /* + * a = xxxxxxxxx + * b = xxxxxxxBxxx + * c = xxxxxxxxxxx + * b_pos = | + */ + if (c->MaxPrec >= word_shift + 1) { + *b_pos = c->MaxPrec - word_shift - 1; + if (*b_pos + word_shift <= round_limit) { + *bv = b->frac[*b_pos]; + } + } + else { + *b_pos = -1L; + } + } + else { + /* + * a = xxxxxxxxxxxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxxxx + * b_pos = | + */ + *b_pos = b->Prec; + } + } + else { /* The MaxPrec of c - 1 > The Prec of a + b */ + /* + * a = xxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxx + * c_pos = | + */ + *b_pos = b->Prec; + *a_pos = a->Prec; + *c_pos = right_word + 1; + } + c->Prec = *c_pos; + c->exponent = a->exponent; + if (!AddExponent(c, 1)) return (size_t)-1L; + return word_shift; +} + +/* + * Return number of significant digits + * c = a * b , Where a = a0a1a2 ... an + * b = b0b1b2 ... bm + * c = c0c1c2 ... cl + * a0 a1 ... an * bm + * a0 a1 ... an * bm-1 + * . . . + * . . . + * a0 a1 .... an * b0 + * +_____________________________ + * c0 c1 c2 ...... cl + */ +VP_EXPORT size_t +VpMult(Real *c, Real *a, Real *b) +{ + ssize_t a_batch_max, b_batch_max; + DECDIG_DBL batch[VPMULT_BATCH_SIZE * 2 - 1]; + + if (!VpIsDefOP(c, a, b, OP_SW_MULT)) return 0; /* No significant digit */ + + if (VpIsZero(a) || VpIsZero(b)) { + /* at least a or b is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + return 1; /* 0: 1 significant digit */ + } + + if (VpIsOne(a)) { + VpAsgn(c, b, 10 * VpGetSign(a)); + goto Exit; + } + if (VpIsOne(b)) { + VpAsgn(c, a, 10 * VpGetSign(b)); + goto Exit; + } + if (b->Prec > a->Prec) { + /* Adjust so that digits(a)>digits(b) */ + Real *w = a; + a = b; + b = w; + } + + /* set LHSV c info */ + + c->exponent = a->exponent; /* set exponent */ + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); /* set sign */ + if (!AddExponent(c, b->exponent)) return 0; + + if (b->Prec >= NTT_MULTIPLICATION_THRESHOLD) { + ntt_multiply(a->Prec, b->Prec, a->frac, b->frac, c->frac); + c->Prec = a->Prec + b->Prec; + goto Cleanup; + } + + c->Prec = a->Prec + b->Prec; /* set precision */ + memset(c->frac, 0, c->Prec * sizeof(DECDIG)); /* Initialize c */ + + // Process VPMULT_BATCH_SIZE decdigits at a time to reduce the number of carry operations. + a_batch_max = (a->Prec - 1) / VPMULT_BATCH_SIZE; + b_batch_max = (b->Prec - 1) / VPMULT_BATCH_SIZE; + for (ssize_t ibatch = a_batch_max; ibatch >= 0; ibatch--) { + int isize = ibatch == a_batch_max ? (a->Prec - 1) % VPMULT_BATCH_SIZE + 1 : VPMULT_BATCH_SIZE; + for (ssize_t jbatch = b_batch_max; jbatch >= 0; jbatch--) { + int jsize = jbatch == b_batch_max ? (b->Prec - 1) % VPMULT_BATCH_SIZE + 1 : VPMULT_BATCH_SIZE; + memset(batch, 0, (isize + jsize - 1) * sizeof(DECDIG_DBL)); + + // Perform multiplication without carry calculation. + // BASE * BASE * VPMULT_BATCH_SIZE < 2**64 should be satisfied so that + // DECDIG_DBL can hold the intermediate sum without overflow. + for (int i = 0; i < isize; i++) { + for (int j = 0; j < jsize; j++) { + batch[i + j] += (DECDIG_DBL)a->frac[ibatch * VPMULT_BATCH_SIZE + i] * b->frac[jbatch * VPMULT_BATCH_SIZE + j]; + } + } + + // Add the batch result to c with carry calculation. + DECDIG_DBL carry = 0; + for (int k = isize + jsize - 2; k >= 0; k--) { + size_t l = (ibatch + jbatch) * VPMULT_BATCH_SIZE + k + 1; + DECDIG_DBL s = c->frac[l] + batch[k] + carry; + c->frac[l] = (DECDIG)(s % BASE); + carry = (DECDIG_DBL)(s / BASE); + } + + // Adding carry may exceed BASE, but it won't cause overflow of DECDIG. + // Exceeded value will be resolved in the carry operation of next (ibatch + jbatch - 1) batch. + // WARNING: This safety strongly relies on the current nested loop execution order. + c->frac[(ibatch + jbatch) * VPMULT_BATCH_SIZE] += (DECDIG)carry; + } + } + +Cleanup: + VpNmlz(c); + +Exit: + return c->Prec*BASE_FIG; +} + +/* + * c = a / b, remainder = r + * XXXX_YYYY_ZZZZ / 0001 = XXXX_YYYY_ZZZZ + * XXXX_YYYY_ZZZZ / 1111 = 000X_000Y_000Z + * 00XX_XXYY_YYZZ / 1000 = 0000_0XXX_XYYY + * 0001_0000_0000 / 9999 = 0000_0001_0001 + */ +VP_EXPORT size_t +VpDivd(Real *c, Real *r, Real *a, Real *b) +{ + size_t word_a, word_b, word_c, word_r; + size_t i, n, ind_a, ind_b, ind_c, ind_r; + size_t nLoop; + DECDIG_DBL q, b1, b1p1, b1b2, b1b2p1, r1r2; + DECDIG borrow1, borrow2; + DECDIG_DBL qb; + + VpSetNaN(r); + if (!VpIsDefOP(c, a, b, OP_SW_DIV)) goto Exit; + if (VpIsZero(a) && VpIsZero(b)) { + VpSetNaN(c); + return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); + } + if (VpIsZero(b)) { + VpSetInf(c, VpGetSign(a) * VpGetSign(b)); + return VpException(VP_EXCEPTION_ZERODIVIDE, "Divide by zero", 0); + } + if (VpIsZero(a)) { + /* numerator a is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + VpSetZero(r, VpGetSign(a) * VpGetSign(b)); + goto Exit; + } + + word_a = a->Prec; + word_b = b->Prec; + word_c = c->MaxPrec; + word_r = r->MaxPrec; + + if (word_a > word_r || word_b + word_c - 2 >= word_r) goto space_error; + + if (word_c >= NEWTON_RAPHSON_DIVISION_THRESHOLD && word_b >= NEWTON_RAPHSON_DIVISION_THRESHOLD) { + VpDivdNewton(c, r, a, b); + goto Exit; + } + + for (i = 0; i < word_a; ++i) r->frac[i] = a->frac[i]; + for (i = word_a; i < word_r; ++i) r->frac[i] = 0; + for (i = 0; i < word_c; ++i) c->frac[i] = 0; + + /* initial procedure */ + b1 = b1p1 = b->frac[0]; + if (b->Prec <= 1) { + b1b2p1 = b1b2 = b1p1 * BASE; + } + else { + b1p1 = b1 + 1; + b1b2p1 = b1b2 = b1 * BASE + b->frac[1]; + if (b->Prec > 2) ++b1b2p1; + } + + /* */ + /* loop start */ + nLoop = Min(word_c, word_r); + ind_c = 0; + while (ind_c < nLoop) { + if (r->frac[ind_c] == 0) { + ++ind_c; + continue; + } + r1r2 = (DECDIG_DBL)r->frac[ind_c] * BASE + (ind_c + 1 < word_r ? r->frac[ind_c + 1] : 0); + if (r1r2 == b1b2) { + /* The first two word digits is the same */ + ind_b = 2; + ind_a = ind_c + 2; + while (ind_b < word_b) { + if (r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1; + if (r->frac[ind_a] > b->frac[ind_b]) break; + ++ind_a; + ++ind_b; + } + /* The first few word digits of r and b is the same and */ + /* the first different word digit of w is greater than that */ + /* of b, so quotient is 1. */ + q = 1; + ++c->frac[ind_c]; + ind_r = b->Prec + ind_c - 1; + goto sub_mult; + } + /* The first two word digits is not the same, */ + /* then compare magnitude, and divide actually. */ + if (r1r2 >= b1b2p1) { + q = r1r2 / b1b2p1; /* q == (DECDIG)q */ + c->frac[ind_c] += (DECDIG)q; + ind_r = b->Prec + ind_c - 1; + goto sub_mult; + } + +div_b1p1: + if (ind_c + 1 >= word_c) goto out_side; + q = r1r2 / b1p1; /* q == (DECDIG)q */ + c->frac[ind_c + 1] += (DECDIG)q; + ind_r = b->Prec + ind_c; + +sub_mult: + borrow1 = borrow2 = 0; + ind_b = word_b - 1; + if (ind_r >= word_r) goto space_error; + n = ind_b; + for (i = 0; i <= n; ++i) { + /* now, perform r = r - q * b */ + qb = q * b->frac[ind_b]; + if (qb < BASE) borrow1 = 0; + else { + borrow1 = (DECDIG)(qb / BASE); + qb -= (DECDIG_DBL)borrow1 * BASE; /* get qb < BASE */ + } + if(r->frac[ind_r] < qb) { + r->frac[ind_r] += (DECDIG)(BASE - qb); + borrow2 = borrow2 + borrow1 + 1; + } + else { + r->frac[ind_r] -= (DECDIG)qb; + borrow2 += borrow1; + } + if (borrow2) { + if(r->frac[ind_r - 1] < borrow2) { + r->frac[ind_r - 1] += (BASE - borrow2); + borrow2 = 1; + } + else { + r->frac[ind_r - 1] -= borrow2; + borrow2 = 0; + } + } + --ind_r; + --ind_b; + } + + r->frac[ind_r] -= borrow2; + } + /* End of operation, now final arrangement */ +out_side: + c->Prec = word_c; + c->exponent = a->exponent; + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); + if (!AddExponent(c, 1)) return 0; + if (!AddExponent(c, -(b->exponent))) return 0; + + VpNmlz(c); /* normalize c */ + r->Prec = word_r; + r->exponent = a->exponent; + VpSetSign(r, VpGetSign(a)); + VpNmlz(r); /* normalize r(remainder) */ + goto Exit; + +space_error: + rb_bug("ERROR(VpDivd): space for remainder too small."); + +Exit: + return c->Prec * BASE_FIG; +} + +/* + * Input a = 00000xxxxxxxx En(5 preceding zeros) + * Output a = xxxxxxxx En-5 + */ +static int +VpNmlz(Real *a) +{ + size_t ind_a, i; + + if (!VpIsDef(a)) goto NoVal; + if (VpIsZero(a)) goto NoVal; + + ind_a = a->Prec; + while (ind_a--) { + if (a->frac[ind_a]) { + a->Prec = ind_a + 1; + i = 0; + while (a->frac[i] == 0) ++i; /* skip the first few zeros */ + if (i) { + a->Prec -= i; + if (!AddExponent(a, -(SIGNED_VALUE)i)) return 0; + memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(DECDIG)); + } + return 1; + } + } + /* a is zero(no non-zero digit) */ + VpSetZero(a, VpGetSign(a)); + return 0; + +NoVal: + a->frac[0] = 0; + a->Prec = 1; + return 0; +} + +/* + * VpComp = 0 ... if a=b, + * Pos ... a>b, + * Neg ... asign - b->sign; + else e = a->sign; + + if (e > 0) return 1; + else if (e < 0) return -1; + else return 0; + } + if (!VpIsDef(b)) { + e = -b->sign; + if (e > 0) return 1; + else return -1; + } + /* Zero check */ + if (VpIsZero(a)) { + if (VpIsZero(b)) return 0; /* both zero */ + val = -VpGetSign(b); + goto Exit; + } + if (VpIsZero(b)) { + val = VpGetSign(a); + goto Exit; + } + + /* compare sign */ + if (VpGetSign(a) > VpGetSign(b)) { + val = 1; /* a>b */ + goto Exit; + } + if (VpGetSign(a) < VpGetSign(b)) { + val = -1; /* aexponent > b->exponent) { + val = VpGetSign(a); + goto Exit; + } + if (a->exponent < b->exponent) { + val = -VpGetSign(b); + goto Exit; + } + + /* a and b have same exponent, then compare their significand. */ + mx = (a->Prec < b->Prec) ? a->Prec : b->Prec; + ind = 0; + while (ind < mx) { + if (a->frac[ind] > b->frac[ind]) { + val = VpGetSign(a); + goto Exit; + } + if (a->frac[ind] < b->frac[ind]) { + val = -VpGetSign(b); + goto Exit; + } + ++ind; + } + if (a->Prec > b->Prec) { + val = VpGetSign(a); + } + else if (a->Prec < b->Prec) { + val = -VpGetSign(b); + } + +Exit: + if (val > 1) val = 1; + else if (val < -1) val = -1; + + return (int)val; +} + +/* + * cntl_chr ... ASCIIZ Character, print control characters + * Available control codes: + * % ... VP variable. To print '%', use '%%'. + * \n ... new line + * \b ... backspace + * \t ... tab + * Note: % must not appear more than once + * a ... VP variable to be printed + */ +static int +VPrint(FILE *fp, const char *cntl_chr, Real *a) +{ + size_t i, j, nc, nd, ZeroSup, sep = 10; + DECDIG m, e, nn; + + j = 0; + nd = nc = 0; /* nd : number of digits in fraction part(every 10 digits, */ + /* nd<=10). */ + /* nc : number of characters printed */ + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + while (*(cntl_chr + j)) { + if (*(cntl_chr + j) == '%' && *(cntl_chr + j + 1) != '%') { + nc = 0; + if (VpIsNaN(a)) { + fprintf(fp, SZ_NaN); + nc += 8; + } + else if (VpIsPosInf(a)) { + fprintf(fp, SZ_INF); + nc += 8; + } + else if (VpIsNegInf(a)) { + fprintf(fp, SZ_NINF); + nc += 9; + } + else if (!VpIsZero(a)) { + if (BIGDECIMAL_NEGATIVE_P(a)) { + fprintf(fp, "-"); + ++nc; + } + nc += fprintf(fp, "0."); + switch (*(cntl_chr + j + 1)) { + default: + break; + + case '0': case 'z': + ZeroSup = 0; + ++j; + sep = cntl_chr[j] == 'z' ? BIGDECIMAL_COMPONENT_FIGURES : 10; + break; + } + for (i = 0; i < a->Prec; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */ + /* as 0.00xx will not */ + /* be printed. */ + ++nd; + ZeroSup = 0; /* Set to print succeeding zeros */ + } + if (nd >= sep) { /* print ' ' after every 10 digits */ + nd = 0; + nc += fprintf(fp, " "); + } + e = e - nn * m; + m /= 10; + } + } + nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a)); + nc += fprintf(fp, " (%"PRIdVALUE", %"PRIuSIZE", %"PRIuSIZE")", a->exponent, a->Prec, a->MaxPrec); + } + else { + nc += fprintf(fp, "0.0"); + } + } + else { + ++nc; + if (*(cntl_chr + j) == '\\') { + switch (*(cntl_chr + j + 1)) { + case 'n': + fprintf(fp, "\n"); + ++j; + break; + case 't': + fprintf(fp, "\t"); + ++j; + break; + case 'b': + fprintf(fp, "\n"); + ++j; + break; + default: + fprintf(fp, "%c", *(cntl_chr + j)); + break; + } + } + else { + fprintf(fp, "%c", *(cntl_chr + j)); + if (*(cntl_chr + j) == '%') ++j; + } + } + j++; + } + + return (int)nc; +} + +static void +VpFormatSt(char *psz, size_t fFmt) +{ + size_t iend, idig = 0, iexp = 0, nspaces; + char *p; + + if (fFmt == 0) return; + + iend = strlen(psz); + + if ((p = strchr(psz, '.'))) { + idig = (p - psz) + 1; + } + if ((p = strchr(psz, 'E')) || (p = strchr(psz, 'e'))) { + iexp = p - psz; + } + if (idig == 0 || idig > iexp) return; + + nspaces = (iexp - idig - 1) / fFmt; + p = psz + iend + 1; + for (size_t i = nspaces; i > 0; i--) { + char *src = psz + idig + i * fFmt; + char *dst = psz + idig + i * (fFmt + 1); + memmove(dst, src, p - src); + dst[-1] = ' '; + p = src; + } +} + +VP_EXPORT ssize_t +VpExponent10(Real *a) +{ + ssize_t ex; + size_t n; + + if (!VpHasVal(a)) return 0; + + ex = a->exponent * (ssize_t)BASE_FIG; + n = BASE1; + while ((a->frac[0] / n) == 0) { + --ex; + n /= 10; + } + return ex; +} + +VP_EXPORT void +VpSzMantissa(Real *a, char *buf, size_t buflen) +{ + size_t i, n, ZeroSup; + DECDIG_DBL m, e, nn; + + if (VpIsNaN(a)) { + snprintf(buf, buflen, SZ_NaN); + return; + } + if (VpIsPosInf(a)) { + snprintf(buf, buflen, SZ_INF); + return; + } + if (VpIsNegInf(a)) { + snprintf(buf, buflen, SZ_NINF); + return; + } + + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + if (!VpIsZero(a)) { + if (BIGDECIMAL_NEGATIVE_P(a)) *buf++ = '-'; + n = a->Prec; + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + *buf = (char)('0' + nn); + buf++; + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } + } + *buf = 0; + while (buf[-1] == '0') *(--buf) = 0; + } + else { + if (VpIsPosZero(a)) snprintf(buf, buflen, "0"); + else snprintf(buf, buflen, "-0"); + } +} + +VP_EXPORT int +VpToSpecialString(Real *a, char *buf, size_t buflen, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + if (VpIsNaN(a)) { + snprintf(buf, buflen, SZ_NaN); + return 1; + } + + if (VpIsPosInf(a)) { + if (fPlus == 1) { + *buf++ = ' '; + } + else if (fPlus == 2) { + *buf++ = '+'; + } + snprintf(buf, buflen, SZ_INF); + return 1; + } + if (VpIsNegInf(a)) { + snprintf(buf, buflen, SZ_NINF); + return 1; + } + if (VpIsZero(a)) { + if (VpIsPosZero(a)) { + if (fPlus == 1) snprintf(buf, buflen, " 0.0"); + else if (fPlus == 2) snprintf(buf, buflen, "+0.0"); + else snprintf(buf, buflen, "0.0"); + } + else snprintf(buf, buflen, "-0.0"); + return 1; + } + return 0; +} + +#define ULLTOA_BUFFER_SIZE 20 +static size_t Vp_ulltoa(unsigned long long number, char *buf) +{ + static const char digits[] = "0123456789"; + char* tmp = buf; + + do *tmp-- = digits[number % 10]; while (number /= 10); + return buf - tmp; +} + +VP_EXPORT void +VpToString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + char ulltoa_buf[ULLTOA_BUFFER_SIZE]; + char *ulltoa_buf_end = ulltoa_buf + ULLTOA_BUFFER_SIZE; + size_t i, n, ZeroSup; + DECDIG shift, m, e, nn; + char *p = buf; + size_t plen = buflen; + ssize_t ex; + + if (VpToSpecialString(a, buf, buflen, fPlus)) return; + + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + +#define ADVANCE(n) do { \ + if (plen < n) goto overflow; \ + p += n; \ + plen -= n; \ +} while (0) + + if (BIGDECIMAL_NEGATIVE_P(a)) { + *p = '-'; + ADVANCE(1); + } + else if (fPlus == 1) { + *p = ' '; + ADVANCE(1); + } + else if (fPlus == 2) { + *p = '+'; + ADVANCE(1); + } + + *p = '0'; ADVANCE(1); + *p = '.'; ADVANCE(1); + + n = a->Prec; + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + *p = (char)('0' + nn); + ADVANCE(1); + + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } + } + + ex = a->exponent * (ssize_t)BASE_FIG; + shift = BASE1; + while (a->frac[0] / shift == 0) { + --ex; + shift /= 10; + } + while (p - 1 > buf && p[-1] == '0') { + *(--p) = '\0'; + ++plen; + } + *p = 'e'; + ADVANCE(1); + + if (ex < 0) { + *p = '-'; + ADVANCE(1); + ex = -ex; + } + + size_t ex_n = Vp_ulltoa(ex, ulltoa_buf_end - 1); + if (ex_n > plen) goto overflow; + MEMCPY(p, ulltoa_buf_end - ex_n, char, ex_n); + ADVANCE(ex_n); + *p = '\0'; + ADVANCE(1); + + if (fFmt) VpFormatSt(buf, fFmt); + + overflow: + return; +#undef ADVANCE +} + +VP_EXPORT void +VpToFString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + size_t i, n; + DECDIG m, e; + char *p = buf; + size_t plen = buflen, delim = fFmt; + ssize_t ex; + + if (VpToSpecialString(a, buf, buflen, fPlus)) return; + +#define APPEND(c, group) do { \ + if (plen < 1) goto overflow; \ + if (group && delim == 0) { \ + *p = ' '; \ + p += 1; \ + plen -= 1; \ + } \ + if (plen < 1) goto overflow; \ + *p = c; \ + p += 1; \ + plen -= 1; \ + if (group) delim = (delim + 1) % fFmt; \ +} while (0) + + + if (BIGDECIMAL_NEGATIVE_P(a)) { + APPEND('-', false); + } + else if (fPlus == 1) { + APPEND(' ', false); + } + else if (fPlus == 2) { + APPEND('+', false); + } + + n = a->Prec; + ex = a->exponent; + if (ex <= 0) { + APPEND('0', false); + APPEND('.', false); + } + while (ex < 0) { + for (i=0; i < BASE_FIG; ++i) { + APPEND('0', fFmt > 0); + } + ++ex; + } + + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + if (i == 0 && ex > 0) { + for (delim = 0; e / m == 0; delim++) { + m /= 10; + } + if (fFmt > 0) { + delim = 2*fFmt - (ex * BASE_FIG - delim) % fFmt; + } + } + while (m && (e || (i < n - 1) || ex > 0)) { + APPEND((char)(e / m + '0'), fFmt > 0); + e %= m; + m /= 10; + } + if (--ex == 0) { + APPEND('.', false); + delim = fFmt; + } + } + + while (ex > 0) { + for (i=0; i < BASE_FIG; ++i) { + APPEND('0', fFmt > 0); + } + if (--ex == 0) { + APPEND('.', false); + } + } + + *p = '\0'; + if (p - 1 > buf && p[-1] == '.') { + snprintf(p, plen, "0"); + } + + overflow: + return; +#undef APPEND +} + +/* + * [Output] + * a[] ... variable to be assigned the value. + * [Input] + * int_chr[] ... integer part(may include '+/-'). + * ni ... number of characters in int_chr[],not including '+/-'. + * frac[] ... fraction part. + * nf ... number of characters in frac[]. + * exp_chr[] ... exponent part(including '+/-'). + * ne ... number of characters in exp_chr[],not including '+/-'. + */ +VP_EXPORT int +VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne) +{ + size_t i, j, ind_a, ma, mi, me; + SIGNED_VALUE e; + int sign, signe, exponent_overflow; + + /* get exponent part */ + e = 0; + ma = a->MaxPrec; + mi = ni; + me = ne; + signe = 1; + exponent_overflow = 0; + memset(a->frac, 0, ma * sizeof(DECDIG)); + if (ne > 0) { + i = 0; + if (exp_chr[0] == '-') { + signe = -1; + ++i; + ++me; + } + else if (exp_chr[0] == '+') { + ++i; + ++me; + } + while (i < me) { + int dig = exp_chr[i] - '0'; + if (MUL_OVERFLOW_SIGNED_VALUE_P(e, 10) || + ADD_OVERFLOW_SIGNED_VALUE_P(e * 10, signe * dig)) { + exponent_overflow = 1; + break; + } + e = e * 10 + signe * dig; + ++i; + } + } + + /* get integer part */ + i = 0; + sign = 1; + if (1 /*ni >= 0*/) { + if (int_chr[0] == '-') { + sign = -1; + ++i; + ++mi; + } + else if (int_chr[0] == '+') { + ++i; + ++mi; + } + } + /* skip leading zeros in integer part */ + while (i < mi && int_chr[i] == '0') { + ++i; + --ni; + } + + /* set actual exponent size. */ + if (ADD_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)ni)) { + exponent_overflow = 1; + } else { + e += ni; + } + + /* Adjust the exponent so that it is the multiple of BASE_FIG. */ + j = (BASE_FIG - e % BASE_FIG) % BASE_FIG; + if (ADD_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)j)) { + exponent_overflow = 1; + } else { + e += j; + } + + if (exponent_overflow || e < EXPONENT_MIN || e > EXPONENT_MAX) { + int zero = 1; + for ( ; i < mi && zero; i++) zero = int_chr[i] == '0'; + for (i = 0; i < nf && zero; i++) zero = frac[i] == '0'; + if (!zero && e > 0) { + VpSetInf(a, sign); + VpException(VP_EXCEPTION_INFINITY, "exponent overflow",0); + } + else VpSetZero(a, sign); + return 1; + } + + ind_a = 0; + while (i < mi) { + a->frac[ind_a] = 0; + while (j < BASE_FIG && i < mi) { + a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0'; + ++j; + ++i; + } + if (i < mi) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } + } + + /* get fraction part */ + + i = 0; + while (i < nf) { + while (j < BASE_FIG && i < nf) { + a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0'; + ++j; + ++i; + } + if (i < nf) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } + } + goto Final; + +over_flow: + rb_warn("Conversion from String to BigDecimal overflow (last few digits discarded)."); + +Final: + if (ind_a >= ma) ind_a = ma - 1; + while (j < BASE_FIG) { + a->frac[ind_a] = a->frac[ind_a] * 10; + ++j; + } + a->Prec = ind_a + 1; + a->exponent = e / (SIGNED_VALUE)BASE_FIG; + VpSetSign(a, sign); + VpNmlz(a); + return 1; +} + +/* + * [Input] + * *m ... Real + * [Output] + * *d ... fraction part of m(d = 0.xxxxxxx). where # of 'x's is fig. + * *e ... exponent of m. + * BIGDECIMAL_DOUBLE_FIGURES ... Number of digits in a double variable. + * + * m -> d*10**e, 0Prec); + *d = 0.0; + div = 1.; + while (ind_m < mm) { + div /= (double)BASE; + *d = *d + (double)m->frac[ind_m++] * div; + } + *e = m->exponent * (SIGNED_VALUE)BASE_FIG; + *d *= VpGetSign(m); + +Exit: + return f; +} + +/* + * Round relatively from the decimal point. + * f: rounding mode + * nf: digit location to round from the decimal point. + */ +VP_EXPORT int +VpMidRound(Real *y, unsigned short f, ssize_t nf) +{ + /* fracf: any positive digit under rounding position? */ + /* fracf_1further: any positive digits under one further than the rounding position? */ + /* exptoadd: number of digits needed to compensate negative nf */ + int fracf, fracf_1further; + ssize_t n,i,ix,ioffset, exptoadd; + DECDIG v, shifter; + DECDIG div; + + nf += y->exponent * (ssize_t)BASE_FIG; + exptoadd=0; + if (nf < 0) { + /* rounding position too left(large). */ + if (f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) { + VpSetZero(y, VpGetSign(y)); /* truncate everything */ + return 0; + } + exptoadd = -nf; + nf = 0; + } + + ix = nf / (ssize_t)BASE_FIG; + if ((size_t)ix >= y->Prec) return 0; /* rounding position too right(small). */ + v = y->frac[ix]; + + ioffset = nf - ix*(ssize_t)BASE_FIG; + n = (ssize_t)BASE_FIG - ioffset - 1; + for (shifter = 1, i = 0; i < n; ++i) shifter *= 10; + + /* so the representation used (in y->frac) is an array of DECDIG, where + each DECDIG contains a value between 0 and BASE-1, consisting of BASE_FIG + decimal places. + + (that numbers of decimal places are typed as ssize_t is somewhat confusing) + + nf is now position (in decimal places) of the digit from the start of + the array. + + ix is the position (in DECDIGs) of the DECDIG containing the decimal digit, + from the start of the array. + + v is the value of this DECDIG + + ioffset is the number of extra decimal places along of this decimal digit + within v. + + n is the number of decimal digits remaining within v after this decimal digit + shifter is 10**n, + + v % shifter are the remaining digits within v + v % (shifter * 10) are the digit together with the remaining digits within v + v / shifter are the digit's predecessors together with the digit + div = v / shifter / 10 is just the digit's precessors + (v / shifter) - div*10 is just the digit, which is what v ends up being reassigned to. + */ + + fracf = (v % (shifter * 10) > 0); + fracf_1further = ((v % shifter) > 0); + + v /= shifter; + div = v / 10; + v = v - div*10; + /* now v is just the digit required. + now fracf is whether the digit or any of the remaining digits within v are non-zero + now fracf_1further is whether any of the remaining digits within v are non-zero + */ + + /* now check all the remaining DECDIGs for zero-ness a whole DECDIG at a time. + if we spot any non-zeroness, that means that we found a positive digit under + rounding position, and we also found a positive digit under one further than + the rounding position, so both searches (to see if any such non-zero digit exists) + can stop */ + + for (i = ix + 1; (size_t)i < y->Prec; i++) { + if (y->frac[i] % BASE) { + fracf = fracf_1further = 1; + break; + } + } + + /* now fracf = does any positive digit exist under the rounding position? + now fracf_1further = does any positive digit exist under one further than the + rounding position? + now v = the first digit under the rounding position */ + + /* drop digits after pointed digit */ + memset(y->frac + ix + 1, 0, (y->Prec - (ix + 1)) * sizeof(DECDIG)); + + switch (f) { + case VP_ROUND_DOWN: /* Truncate */ + break; + case VP_ROUND_UP: /* Roundup */ + if (fracf) ++div; + break; + case VP_ROUND_HALF_UP: + if (v>=5) ++div; + break; + case VP_ROUND_HALF_DOWN: + if (v > 5 || (v == 5 && fracf_1further)) ++div; + break; + case VP_ROUND_CEIL: + if (fracf && BIGDECIMAL_POSITIVE_P(y)) ++div; + break; + case VP_ROUND_FLOOR: + if (fracf && BIGDECIMAL_NEGATIVE_P(y)) ++div; + break; + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + if (v > 5) ++div; + else if (v == 5) { + if (fracf_1further) { + ++div; + } + else { + if (ioffset == 0) { + /* v is the first decimal digit of its DECDIG; + need to grab the previous DECDIG if present + to check for evenness of the previous decimal + digit (which is same as that of the DECDIG since + base 10 has a factor of 2) */ + if (ix && (y->frac[ix-1] % 2)) ++div; + } + else { + if (div % 2) ++div; + } + } + } + break; + } + for (i = 0; i <= n; ++i) div *= 10; + if (div >= BASE) { + if (ix) { + y->frac[ix] = 0; + VpRdup(y, ix); + } + else { + short s = VpGetSign(y); + SIGNED_VALUE e = y->exponent; + VpSetOne(y); + VpSetSign(y, s); + y->exponent = e + 1; + } + } + else { + y->frac[ix] = div; + VpNmlz(y); + } + if (exptoadd > 0) { + y->exponent += (SIGNED_VALUE)(exptoadd / BASE_FIG); + exptoadd %= (ssize_t)BASE_FIG; + for (i = 0; i < exptoadd; i++) { + y->frac[0] *= 10; + if (y->frac[0] >= BASE) { + y->frac[0] /= BASE; + y->exponent++; + } + } + } + return 1; +} + +VP_EXPORT int +VpLeftRound(Real *y, unsigned short f, ssize_t nf) +/* + * Round from the left hand side of the digits. + */ +{ + DECDIG v; + if (!VpHasVal(y)) return 0; /* Unable to round */ + v = y->frac[0]; + nf -= y->exponent * (ssize_t)BASE_FIG; + while ((v /= 10) != 0) nf--; + nf += (ssize_t)BASE_FIG-1; + return VpMidRound(y, f, nf); +} + +VP_EXPORT int +VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf) +{ + /* First,assign whole value in truncation mode */ + if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */ + return VpMidRound(y, f, nf); +} + +static int +VpLimitRound(Real *c, size_t ixDigit) +{ + size_t ix = VpGetPrecLimit(); + if (!VpNmlz(c)) return -1; + if (!ix) return 0; + if (!ixDigit) ixDigit = c->Prec-1; + if ((ix + BASE_FIG - 1) / BASE_FIG > ixDigit + 1) return 0; + return VpLeftRound(c, VpGetRoundMode(), (ssize_t)ix); +} + +/* If I understand correctly, this is only ever used to round off the final decimal + digit of precision */ +static void +VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v) +{ + int f = 0; + + unsigned short const rounding_mode = VpGetRoundMode(); + + if (VpLimitRound(c, ixDigit)) return; + if (!v) return; + + v /= BASE1; + switch (rounding_mode) { + case VP_ROUND_DOWN: + break; + case VP_ROUND_UP: + if (v) f = 1; + break; + case VP_ROUND_HALF_UP: + if (v >= 5) f = 1; + break; + case VP_ROUND_HALF_DOWN: + /* this is ok - because this is the last digit of precision, + the case where v == 5 and some further digits are nonzero + will never occur */ + if (v >= 6) f = 1; + break; + case VP_ROUND_CEIL: + if (v && BIGDECIMAL_POSITIVE_P(c)) f = 1; + break; + case VP_ROUND_FLOOR: + if (v && BIGDECIMAL_NEGATIVE_P(c)) f = 1; + break; + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + /* as per VP_ROUND_HALF_DOWN, because this is the last digit of precision, + there is no case to worry about where v == 5 and some further digits are nonzero */ + if (v > 5) f = 1; + else if (v == 5 && vPrev % 2) f = 1; + break; + } + if (f) { + VpRdup(c, ixDigit); + VpNmlz(c); + } +} + +/* + * Rounds up m(plus one to final digit of m). + */ +static int +VpRdup(Real *m, size_t ind_m) +{ + DECDIG carry; + + if (!ind_m) ind_m = m->Prec; + + carry = 1; + while (carry > 0 && ind_m--) { + m->frac[ind_m] += carry; + if (m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE; + else carry = 0; + } + if (carry > 0) { /* Overflow,count exponent and set fraction part be 1 */ + if (!AddExponent(m, 1)) return 0; + m->Prec = m->frac[0] = 1; + } + else { + VpNmlz(m); + } + return 1; +} + +/* + * y = x - fix(x) + */ +VP_EXPORT void +VpFrac(Real *y, Real *x) +{ + size_t my, ind_y, ind_x; + + if (!VpHasVal(x)) { + VpAsgn(y, x, 10); + goto Exit; + } + + if (x->exponent > 0 && (size_t)x->exponent >= x->Prec) { + VpSetZero(y, VpGetSign(x)); + goto Exit; + } + else if (x->exponent <= 0) { + VpAsgn(y, x, 10); + goto Exit; + } + + /* satisfy: x->exponent > 0 */ + + y->Prec = x->Prec - (size_t)x->exponent; + y->Prec = Min(y->Prec, y->MaxPrec); + y->exponent = 0; + VpSetSign(y, VpGetSign(x)); + ind_y = 0; + my = y->Prec; + ind_x = x->exponent; + while (ind_y < my) { + y->frac[ind_y] = x->frac[ind_x]; + ++ind_y; + ++ind_x; + } + VpNmlz(y); + +Exit: + return; +} + +#ifdef BIGDECIMAL_DEBUG +int +VpVarCheck(Real * v) +/* + * Checks the validity of the Real variable v. + * [Input] + * v ... Real *, variable to be checked. + * [Returns] + * 0 ... correct v. + * other ... error + */ +{ + size_t i; + + if (v->MaxPrec == 0) { + printf("ERROR(VpVarCheck): Illegal Max. Precision(=%"PRIuSIZE")\n", + v->MaxPrec); + return 1; + } + if (v->Prec == 0 || v->Prec > v->MaxPrec) { + printf("ERROR(VpVarCheck): Illegal Precision(=%"PRIuSIZE")\n", v->Prec); + printf(" Max. Prec.=%"PRIuSIZE"\n", v->MaxPrec); + return 2; + } + for (i = 0; i < v->Prec; ++i) { + if (v->frac[i] >= BASE) { + printf("ERROR(VpVarCheck): Illegal fraction\n"); + printf(" Frac[%"PRIuSIZE"]=%"PRIuDECDIG"\n", i, v->frac[i]); + printf(" Prec. =%"PRIuSIZE"\n", v->Prec); + printf(" Exp. =%"PRIdVALUE"\n", v->exponent); + printf(" BASE =%"PRIuDECDIG"\n", BASE); + return 3; + } + } + return 0; +} +#endif /* BIGDECIMAL_DEBUG */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.h new file mode 100644 index 0000000..faa6626 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bigdecimal.h @@ -0,0 +1,298 @@ +/* + * + * Ruby BigDecimal(Variable decimal precision) extension library. + * + * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) + * + */ + +#ifndef RUBY_BIG_DECIMAL_H +#define RUBY_BIG_DECIMAL_H 1 + +#define RUBY_NO_OLD_COMPATIBILITY +#include "ruby/ruby.h" +#include "missing.h" + +#ifdef HAVE_FLOAT_H +# include +#endif + +#define DECDIG uint32_t +#define DECDIG_DBL uint64_t +#define DECDIG_DBL_SIGNED int64_t +#define SIZEOF_DECDIG 4 +#define PRI_DECDIG_PREFIX "" +#ifdef PRI_LL_PREFIX +# define PRI_DECDIG_DBL_PREFIX PRI_LL_PREFIX +#else +# define PRI_DECDIG_DBL_PREFIX "l" +#endif + +#define PRIdDECDIG PRI_DECDIG_PREFIX"d" +#define PRIiDECDIG PRI_DECDIG_PREFIX"i" +#define PRIoDECDIG PRI_DECDIG_PREFIX"o" +#define PRIuDECDIG PRI_DECDIG_PREFIX"u" +#define PRIxDECDIG PRI_DECDIG_PREFIX"x" +#define PRIXDECDIG PRI_DECDIG_PREFIX"X" + +#define PRIdDECDIG_DBL PRI_DECDIG_DBL_PREFIX"d" +#define PRIiDECDIG_DBL PRI_DECDIG_DBL_PREFIX"i" +#define PRIoDECDIG_DBL PRI_DECDIG_DBL_PREFIX"o" +#define PRIuDECDIG_DBL PRI_DECDIG_DBL_PREFIX"u" +#define PRIxDECDIG_DBL PRI_DECDIG_DBL_PREFIX"x" +#define PRIXDECDIG_DBL PRI_DECDIG_DBL_PREFIX"X" + +#define BIGDECIMAL_BASE ((DECDIG)1000000000U) +#define BIGDECIMAL_COMPONENT_FIGURES 9 +/* + * The number of components required for a 64-bit integer. + * + * INT64_MAX: 9_223372036_854775807 + * UINT64_MAX: 18_446744073_709551615 + */ +#define BIGDECIMAL_INT64_MAX_LENGTH 3 + +#define BIGDECIMAL_DOUBLE_FIGURES (1+DBL_DIG) + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +extern VALUE rb_cBigDecimal; + +/* + * NaN & Infinity + */ +#define SZ_NaN "NaN" +#define SZ_INF "Infinity" +#define SZ_PINF "+Infinity" +#define SZ_NINF "-Infinity" + +/* + * #define VP_EXPORT other than static to let VP_ routines + * be called from outside of this module. + */ +#define VP_EXPORT static + +/* Exception mode */ +#define VP_EXCEPTION_ALL ((unsigned short)0x00FF) +#define VP_EXCEPTION_INFINITY ((unsigned short)0x0001) +#define VP_EXCEPTION_NaN ((unsigned short)0x0002) +#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004) +#define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */ +#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010) + +/* Following 2 exceptions can't controlled by user */ +#define VP_EXCEPTION_OP ((unsigned short)0x0020) + +#define BIGDECIMAL_EXCEPTION_MODE_DEFAULT 0U + +/* This is used in BigDecimal#mode */ +#define VP_ROUND_MODE ((unsigned short)0x0100) + +/* Rounding mode */ +#define VP_ROUND_UP RBD_ROUND_UP +#define VP_ROUND_DOWN RBD_ROUND_DOWN +#define VP_ROUND_HALF_UP RBD_ROUND_HALF_UP +#define VP_ROUND_HALF_DOWN RBD_ROUND_HALF_DOWN +#define VP_ROUND_CEIL RBD_ROUND_CEIL +#define VP_ROUND_FLOOR RBD_ROUND_FLOOR +#define VP_ROUND_HALF_EVEN RBD_ROUND_HALF_EVEN + +enum rbd_rounding_mode { + RBD_ROUND_UP = 1, + RBD_ROUND_DOWN = 2, + RBD_ROUND_HALF_UP = 3, + RBD_ROUND_HALF_DOWN = 4, + RBD_ROUND_CEIL = 5, + RBD_ROUND_FLOOR = 6, + RBD_ROUND_HALF_EVEN = 7, + + RBD_ROUND_DEFAULT = RBD_ROUND_HALF_UP, + RBD_ROUND_TRUNCATE = RBD_ROUND_DOWN, + RBD_ROUND_BANKER = RBD_ROUND_HALF_EVEN, + RBD_ROUND_CEILING = RBD_ROUND_CEIL +}; + +#define BIGDECIMAL_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP + +/* Sign flag */ +#define VP_SIGN_NaN 0 /* NaN */ +#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */ +#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */ +#define VP_SIGN_POSITIVE_FINITE 2 /* Positive finite number */ +#define VP_SIGN_NEGATIVE_FINITE -2 /* Negative finite number */ +#define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */ +#define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */ + +/* The size of fraction part array */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define FLEXIBLE_ARRAY_SIZE /* */ +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define FLEXIBLE_ARRAY_SIZE 0 +#else +#define FLEXIBLE_ARRAY_SIZE 1 +#endif + +/* + * VP representation + * r = 0.xxxxxxxxx *BASE**exponent + */ +typedef struct { + size_t MaxPrec; /* Maximum precision size */ + /* This is the actual size of frac[] */ + /*(frac[0] to frac[MaxPrec] are available). */ + size_t Prec; /* Current precision size. */ + /* This indicates how much the */ + /* array frac[] is actually used. */ + SIGNED_VALUE exponent; /* Exponent part. */ + short sign; /* Attributes of the value. */ + /* + * ==0 : NaN + * 1 : Positive zero + * -1 : Negative zero + * 2 : Positive number + * -2 : Negative number + * 3 : Positive infinite number + * -3 : Negative infinite number + */ + short flag; /* Not used in vp_routines,space for user. */ + DECDIG frac[FLEXIBLE_ARRAY_SIZE]; /* Array of fraction part. */ +} Real; + +typedef struct { + VALUE bigdecimal; + Real *real; +} BDVALUE; + +typedef struct { + VALUE bigdecimal_or_nil; + Real *real_or_null; +} NULLABLE_BDVALUE; + +/* + * ------------------ + * EXPORTables. + * ------------------ + */ + +#define VpBaseFig() BIGDECIMAL_COMPONENT_FIGURES + +/* Zero,Inf,NaN (isinf(),isnan() used to check) */ +VP_EXPORT double VpGetDoubleNaN(void); +VP_EXPORT double VpGetDoublePosInf(void); +VP_EXPORT double VpGetDoubleNegInf(void); +VP_EXPORT double VpGetDoubleNegZero(void); + +/* These 2 functions added at v1.1.7 */ +VP_EXPORT size_t VpGetPrecLimit(void); +VP_EXPORT void VpSetPrecLimit(size_t n); + +/* Round mode */ +VP_EXPORT int VpIsRoundMode(unsigned short n); +VP_EXPORT unsigned short VpGetRoundMode(void); +VP_EXPORT unsigned short VpSetRoundMode(unsigned short n); + +VP_EXPORT int VpException(unsigned short f,const char *str,int always); +VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt); +VP_EXPORT size_t VpInit(DECDIG BaseVal); +VP_EXPORT NULLABLE_BDVALUE VpAlloc(const char *szVal, int strict_p, int exc); +VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw); +VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation); +VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b); +VP_EXPORT size_t VpDivd(Real *c,Real *r,Real *a,Real *b); +VP_EXPORT int VpNmlz(Real *a); +VP_EXPORT int VpComp(Real *a,Real *b); +VP_EXPORT ssize_t VpExponent10(Real *a); +VP_EXPORT void VpSzMantissa(Real *a, char *buf, size_t bufsize); +VP_EXPORT int VpToSpecialString(Real *a, char *buf, size_t bufsize, int fPlus); +VP_EXPORT void VpToString(Real *a, char *buf, size_t bufsize, size_t fFmt, int fPlus); +VP_EXPORT void VpToFString(Real *a, char *buf, size_t bufsize, size_t fFmt, int fPlus); +VP_EXPORT int VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne); +VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m); +VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il); +VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf); +VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf); +VP_EXPORT void VpFrac(Real *y, Real *x); +VP_EXPORT int AddExponent(Real *a, SIGNED_VALUE n); + +/* VP constants */ +VP_EXPORT Real *VpOne(void); + +/* + * **** BigDecimal part **** + */ +VP_EXPORT VALUE BigDecimal_lt(VALUE self, VALUE r); +VP_EXPORT VALUE BigDecimal_ge(VALUE self, VALUE r); +VP_EXPORT VALUE BigDecimal_exponent(VALUE self); +VP_EXPORT VALUE BigDecimal_fix(VALUE self); +VP_EXPORT VALUE BigDecimal_frac(VALUE self); +VP_EXPORT VALUE BigDecimal_add(VALUE self, VALUE b); +VP_EXPORT VALUE BigDecimal_sub(VALUE self, VALUE b); +VP_EXPORT VALUE BigDecimal_mult(VALUE self, VALUE b); +VP_EXPORT VALUE BigDecimal_add2(VALUE self, VALUE b, VALUE n); +VP_EXPORT VALUE BigDecimal_sub2(VALUE self, VALUE b, VALUE n); +VP_EXPORT VALUE BigDecimal_mult2(VALUE self, VALUE b, VALUE n); +VP_EXPORT VALUE BigDecimal_split(VALUE self); +VP_EXPORT VALUE BigDecimal_decimal_shift(VALUE self, VALUE v); +VP_EXPORT inline BDVALUE GetBDValueMust(VALUE v); +VP_EXPORT inline BDVALUE rbd_allocate_struct_zero_wrap(int sign, size_t const digits); +#define NewZeroWrap rbd_allocate_struct_zero_wrap + +/* + * ------------------ + * MACRO definitions. + * ------------------ + */ +#define Abs(a) (((a)>= 0)?(a):(-(a))) +#define Max(a, b) (((a)>(b))?(a):(b)) +#define Min(a, b) (((a)>(b))?(b):(a)) + +/* Sign */ + +/* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */ +#define VpGetSign(a) (((a)->sign>0)?1:(-1)) +/* Change sign of a to a>0,a<0 if s = 1,-1 respectively */ +#define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((ssize_t)(a)->sign);else (a)->sign=-(short)Abs((ssize_t)(a)->sign);} +/* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */ +#define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;} + +/* 1 */ +#define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;} + +/* ZEROs */ +#define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO) +#define VpIsNegZero(a) ((a)->sign==VP_SIGN_NEGATIVE_ZERO) +#define VpIsZero(a) (VpIsPosZero(a) || VpIsNegZero(a)) +#define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO) +#define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO) +#define VpSetZero(a,s) (void)(((s)>0)?VpSetPosZero(a):VpSetNegZero(a)) + +/* NaN */ +#define VpIsNaN(a) ((a)->sign==VP_SIGN_NaN) +#define VpSetNaN(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN) + +/* Infinity */ +#define VpIsPosInf(a) ((a)->sign==VP_SIGN_POSITIVE_INFINITE) +#define VpIsNegInf(a) ((a)->sign==VP_SIGN_NEGATIVE_INFINITE) +#define VpIsInf(a) (VpIsPosInf(a) || VpIsNegInf(a)) +#define VpIsDef(a) ( !(VpIsNaN(a)||VpIsInf(a)) ) +#define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE) +#define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE) +#define VpSetInf(a,s) (void)(((s)>0)?VpSetPosInf(a):VpSetNegInf(a)) +#define VpHasVal(a) (a->frac[0]) +#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1)) +#ifdef BIGDECIMAL_DEBUG +int VpVarCheck(Real * v); +#endif /* BIGDECIMAL_DEBUG */ + +#if defined(__cplusplus) +#if 0 +{ /* satisfy cc-mode */ +#endif +} /* extern "C" { */ +#endif +#endif /* RUBY_BIG_DECIMAL_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bits.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bits.h new file mode 100644 index 0000000..66efce4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/bits.h @@ -0,0 +1,144 @@ +#ifndef BIGDECIMAL_BITS_H +#define BIGDECIMAL_BITS_H + +#include "feature.h" +#include "static_assert.h" + +#if defined(__x86_64__) && defined(HAVE_X86INTRIN_H) +# include /* for _lzcnt_u64, etc. */ +#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H) +# include /* for the following intrinsics */ +#endif + +#if defined(_MSC_VER) && defined(__AVX2__) +# pragma intrinsic(__lzcnt) +# pragma intrinsic(__lzcnt64) +#endif + +#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0]))) +#define roomof(x, y) (((x) + (y) - 1) / (y)) +#define type_roomof(x, y) roomof(sizeof(x), sizeof(y)) + +#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ + (a) == 0 ? 0 : \ + (a) == -1 ? (b) < -(max) : \ + (a) > 0 ? \ + ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \ + ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b))) + +#define ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ + ((a) > 0) == ((b) > 0) && ((a) > 0 ? (max) - (a) < (b) : (min) - (a) > (b))) + +#ifdef HAVE_UINT128_T +# define bit_length(x) \ + (unsigned int) \ + (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ + sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \ + 128 - nlz_int128((uint128_t)(x))) +#else +# define bit_length(x) \ + (unsigned int) \ + (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ + 64 - nlz_int64((uint64_t)(x))) +#endif + +static inline unsigned nlz_int32(uint32_t x); +static inline unsigned nlz_int64(uint64_t x); +#ifdef HAVE_UINT128_T +static inline unsigned nlz_int128(uint128_t x); +#endif + +static inline unsigned int +nlz_int32(uint32_t x) +{ +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT) + /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC. + * AMD CPUs have had this instruction for decades (since K10) but for + * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum + * safety. */ + return (unsigned int)__lzcnt(x); + +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U32) + return (unsigned int)_lzcnt_u32(x); + +#elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE) + unsigned long r; + return _BitScanReverse(&r, x) ? (31 - (int)r) : 32; + +#elif __has_builtin(__builtin_clz) + STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32); + return x ? (unsigned int)__builtin_clz(x) : 32; + +#else + uint32_t y; + unsigned n = 32; + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (unsigned int)(n - x); +#endif +} + +static inline unsigned int +nlz_int64(uint64_t x) +{ +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64) + return (unsigned int)__lzcnt64(x); + +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64) + return (unsigned int)_lzcnt_u64(x); + +#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64) + unsigned long r; + return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64; + +#elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc)) + if (x == 0) { + return 64; + } + else if (sizeof(long) * CHAR_BIT == 64) { + return (unsigned int)__builtin_clzl((unsigned long)x); + } + else if (sizeof(long long) * CHAR_BIT == 64) { + return (unsigned int)__builtin_clzll((unsigned long long)x); + } + else { + /* :FIXME: Is there a way to make this branch a compile-time error? */ + __builtin_unreachable(); + } + +#else + uint64_t y; + unsigned int n = 64; + y = x >> 32; if (y) {n -= 32; x = y;} + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (unsigned int)(n - x); + +#endif +} + +#ifdef HAVE_UINT128_T +static inline unsigned int +nlz_int128(uint128_t x) +{ + uint64_t y = (uint64_t)(x >> 64); + + if (x == 0) { + return 128; + } + else if (y == 0) { + return (unsigned int)nlz_int64(x) + 64; + } + else { + return (unsigned int)nlz_int64(y); + } +} +#endif + +#endif /* BIGDECIMAL_BITS_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/div.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/div.h new file mode 100644 index 0000000..310a8b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/div.h @@ -0,0 +1,192 @@ +// Calculate the inverse of x using the Newton-Raphson method. +static VALUE +newton_raphson_inverse(VALUE x, size_t prec) { + BDVALUE bdone = NewZeroWrap(1, 1); + VpSetOne(bdone.real); + VALUE one = bdone.bigdecimal; + + // Initial approximation in 2 digits + BDVALUE bdx = GetBDValueMust(x); + BDVALUE inv0 = NewZeroWrap(1, 2 * BIGDECIMAL_COMPONENT_FIGURES); + VpSetOne(inv0.real); + DECDIG_DBL numerator = (DECDIG_DBL)BIGDECIMAL_BASE * 100; + DECDIG_DBL denominator = (DECDIG_DBL)bdx.real->frac[0] * 100 + (DECDIG_DBL)(bdx.real->Prec >= 2 ? bdx.real->frac[1] : 0) * 100 / BIGDECIMAL_BASE; + inv0.real->frac[0] = (DECDIG)(numerator / denominator); + inv0.real->frac[1] = (DECDIG)((numerator % denominator) * (BIGDECIMAL_BASE / 100) / denominator * 100); + inv0.real->Prec = 2; + inv0.real->exponent = 1 - bdx.real->exponent; + VpNmlz(inv0.real); + RB_GC_GUARD(bdx.bigdecimal); + VALUE inv = inv0.bigdecimal; + + int bl = 1; + while (((size_t)1 << bl) < prec) bl++; + + for (int i = bl; i >= 0; i--) { + size_t n = (prec >> i) + 2; + if (n > prec) n = prec; + // Newton-Raphson iteration: inv_next = inv + inv * (1 - x * inv) + VALUE one_minus_x_inv = BigDecimal_sub2( + one, + BigDecimal_mult(BigDecimal_mult2(x, one, SIZET2NUM(n + 1)), inv), + SIZET2NUM(SIZET2NUM(n / 2)) + ); + inv = BigDecimal_add2( + inv, + BigDecimal_mult(inv, one_minus_x_inv), + SIZET2NUM(n) + ); + } + return inv; +} + +// Calculates divmod by multiplying approximate reciprocal of y +static void +divmod_by_inv_mul(VALUE x, VALUE y, VALUE inv, VALUE *res_div, VALUE *res_mod) { + VALUE div = BigDecimal_fix(BigDecimal_mult(x, inv)); + VALUE mod = BigDecimal_sub(x, BigDecimal_mult(div, y)); + while (RTEST(BigDecimal_lt(mod, INT2FIX(0)))) { + mod = BigDecimal_add(mod, y); + div = BigDecimal_sub(div, INT2FIX(1)); + } + while (RTEST(BigDecimal_ge(mod, y))) { + mod = BigDecimal_sub(mod, y); + div = BigDecimal_add(div, INT2FIX(1)); + } + *res_div = div; + *res_mod = mod; +} + +static void +slice_copy(DECDIG *dest, Real *src, size_t rshift, size_t length) { + ssize_t start = src->exponent - (ssize_t)rshift - (ssize_t)length; + if (start >= (ssize_t)src->Prec) return; + if (start < 0) { + dest -= start; + length -= (size_t)(-start); + start = 0; + } + size_t max_length = (size_t)((ssize_t)src->Prec - start); + memcpy(dest, src->frac + start, Min(length, max_length) * sizeof(DECDIG)); +} + +/* Calculates divmod using Newton-Raphson method. + * x and y must be a BigDecimal representing an integer value. + * + * To calculate with low cost, we need to split x into blocks and perform divmod for each block. + * x_digits = remaining_digits(<= y_digits) + block_digits * num_blocks + * + * Example: + * xxx_xxxxx_xxxxx_xxxxx(18 digits) / yyyyy(5 digits) + * remaining_digits = 3, block_digits = 5, num_blocks = 3 + * repeating xxxxx_xxxxxx.divmod(yyyyy) calculation 3 times. + * + * In each divmod step, dividend is at most (y_digits + block_digits) digits and divisor is y_digits digits. + * Reciprocal of y needs block_digits + 1 precision. + */ +static void +divmod_newton(VALUE x, VALUE y, VALUE *div_out, VALUE *mod_out) { + size_t x_digits = NUM2SIZET(BigDecimal_exponent(x)); + size_t y_digits = NUM2SIZET(BigDecimal_exponent(y)); + if (x_digits <= y_digits) x_digits = y_digits + 1; + + size_t n = x_digits / y_digits; + size_t block_figs = (x_digits - y_digits) / n / BIGDECIMAL_COMPONENT_FIGURES + 1; + size_t block_digits = block_figs * BIGDECIMAL_COMPONENT_FIGURES; + size_t num_blocks = (x_digits - y_digits + block_digits - 1) / block_digits; + size_t y_figs = (y_digits - 1) / BIGDECIMAL_COMPONENT_FIGURES + 1; + VALUE yinv = newton_raphson_inverse(y, block_digits + 1); + + BDVALUE divident = NewZeroWrap(1, BIGDECIMAL_COMPONENT_FIGURES * (y_figs + block_figs)); + BDVALUE div_result = NewZeroWrap(1, BIGDECIMAL_COMPONENT_FIGURES * (num_blocks * block_figs + 1)); + BDVALUE bdx = GetBDValueMust(x); + + VALUE mod = BigDecimal_fix(BigDecimal_decimal_shift(x, SSIZET2NUM(-(ssize_t)(num_blocks * block_digits)))); + for (ssize_t i = (ssize_t)(num_blocks - 1); i >= 0; i--) { + memset(divident.real->frac, 0, (y_figs + block_figs) * sizeof(DECDIG)); + + BDVALUE bdmod = GetBDValueMust(mod); + slice_copy(divident.real->frac, bdmod.real, 0, y_figs); + slice_copy(divident.real->frac + y_figs, bdx.real, (size_t)i * block_figs, block_figs); + RB_GC_GUARD(bdmod.bigdecimal); + + VpSetSign(divident.real, 1); + divident.real->exponent = (ssize_t)(y_figs + block_figs); + divident.real->Prec = y_figs + block_figs; + VpNmlz(divident.real); + + VALUE div; + divmod_by_inv_mul(divident.bigdecimal, y, yinv, &div, &mod); + BDVALUE bddiv = GetBDValueMust(div); + slice_copy(div_result.real->frac + (num_blocks - (size_t)i - 1) * block_figs, bddiv.real, 0, block_figs + 1); + RB_GC_GUARD(bddiv.bigdecimal); + } + VpSetSign(div_result.real, 1); + div_result.real->exponent = (ssize_t)(num_blocks * block_figs + 1); + div_result.real->Prec = num_blocks * block_figs + 1; + VpNmlz(div_result.real); + RB_GC_GUARD(bdx.bigdecimal); + RB_GC_GUARD(divident.bigdecimal); + RB_GC_GUARD(div_result.bigdecimal); + *div_out = div_result.bigdecimal; + *mod_out = mod; +} + +static VALUE +VpDivdNewtonInner(VALUE args_ptr) +{ + Real **args = (Real**)args_ptr; + Real *c = args[0], *r = args[1], *a = args[2], *b = args[3]; + BDVALUE a2, b2, c2, r2; + VALUE div, mod, a2_frac = Qnil; + size_t div_prec = c->MaxPrec - 1; + size_t base_prec = b->Prec; + + a2 = NewZeroWrap(1, a->Prec * BIGDECIMAL_COMPONENT_FIGURES); + b2 = NewZeroWrap(1, b->Prec * BIGDECIMAL_COMPONENT_FIGURES); + VpAsgn(a2.real, a, 1); + VpAsgn(b2.real, b, 1); + VpSetSign(a2.real, 1); + VpSetSign(b2.real, 1); + a2.real->exponent = (ssize_t)(base_prec + div_prec); + b2.real->exponent = (ssize_t)base_prec; + + if ((ssize_t)a2.real->Prec > a2.real->exponent) { + a2_frac = BigDecimal_frac(a2.bigdecimal); + VpMidRound(a2.real, VP_ROUND_DOWN, 0); + } + divmod_newton(a2.bigdecimal, b2.bigdecimal, &div, &mod); + if (a2_frac != Qnil) mod = BigDecimal_add(mod, a2_frac); + + c2 = GetBDValueMust(div); + r2 = GetBDValueMust(mod); + VpAsgn(c, c2.real, VpGetSign(a) * VpGetSign(b)); + VpAsgn(r, r2.real, VpGetSign(a)); + AddExponent(c, a->exponent); + AddExponent(c, -b->exponent); + AddExponent(c, -(ssize_t)div_prec); + AddExponent(r, a->exponent); + AddExponent(r, -(ssize_t)(base_prec + div_prec)); + RB_GC_GUARD(a2.bigdecimal); + RB_GC_GUARD(a2.bigdecimal); + RB_GC_GUARD(c2.bigdecimal); + RB_GC_GUARD(r2.bigdecimal); + return Qnil; +} + +static VALUE +ensure_restore_prec_limit(VALUE limit) +{ + VpSetPrecLimit(NUM2SIZET(limit)); + return Qnil; +} + +static void +VpDivdNewton(Real *c, Real *r, Real *a, Real *b) +{ + Real *args[4] = {c, r, a, b}; + size_t pl = VpGetPrecLimit(); + VpSetPrecLimit(0); + // Ensure restoring prec limit because some methods used in VpDivdNewtonInner may raise an exception + rb_ensure(VpDivdNewtonInner, (VALUE)args, ensure_restore_prec_limit, SIZET2NUM(pl)); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/extconf.rb new file mode 100644 index 0000000..0b4baca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/extconf.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true +require 'mkmf' + +def have_builtin_func(name, check_expr, opt = "", &b) + checking_for checking_message(name.funcall_style, nil, opt) do + if try_compile(<= 3.3 +end + +if File.file?(File.expand_path('../lib/bigdecimal.rb', __FILE__)) + bigdecimal_rb = "$(srcdir)/lib/bigdecimal.rb" +else + bigdecimal_rb = "$(srcdir)/../../lib/bigdecimal.rb" +end + +$defs.push '-DBIGDECIMAL_USE_VP_TEST_METHODS' if ENV['BIGDECIMAL_USE_VP_TEST_METHODS'] == 'true' + +create_makefile('bigdecimal') {|mf| + mf << "BIGDECIMAL_RB = #{bigdecimal_rb}\n" +} diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/feature.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/feature.h new file mode 100644 index 0000000..f628514 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/feature.h @@ -0,0 +1,68 @@ +#ifndef BIGDECIMAL_HAS_FEATURE_H +#define BIGDECIMAL_HAS_FEATURE_H + +/* ======== __has_feature ======== */ + +#ifndef __has_feature +# define __has_feature(_) 0 +#endif + +/* ======== __has_extension ======== */ + +#ifndef __has_extension +# define __has_extension __has_feature +#endif + +/* ======== __has_builtin ======== */ + +#ifdef HAVE_RUBY_INTERNAL_HAS_BUILTIN_H +# include +#endif + +#ifdef RBIMPL_HAS_BUILTIN +# define BIGDECIMAL_HAS_BUILTIN(...) RBIMPL_HAS_BUILTIN(__VA_ARGS__) + +#else +# /* The following section is copied from CRuby's builtin.h */ +# +# ifdef __has_builtin +# if defined(__INTEL_COMPILER) +# /* :TODO: Intel C Compiler has __has_builtin (since 19.1 maybe?), and is +# * reportedly broken. We have to skip them. However the situation can +# * change. They might improve someday. We need to revisit here later. */ +# elif defined(__GNUC__) && ! __has_builtin(__builtin_alloca) +# /* FreeBSD's defines its own *broken* version of +# * __has_builtin. Cygwin copied that content to be a victim of the +# * broken-ness. We don't take them into account. */ +# else +# define HAVE___HAS_BUILTIN 1 +# endif +# endif +# +# if defined(HAVE___HAS_BUILTIN) +# define BIGDECIMAL_HAS_BUILTIN(_) __has_builtin(_) +# +# elif defined(__GNUC__) +# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 6)) +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 1 +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 1 +# else +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 0 +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 0 +# endif +# elif defined(_MSC_VER) +# define BIGDECIMAL_HAS_BUILTIN(_) 0 +# +# else +# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz HAVE_BUILTIN___BUILTIN_CLZ +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl HAVE_BUILTIN___BUILTIN_CLZL +# endif +#endif /* RBIMPL_HAS_BUILTIN */ + +#ifndef __has_builtin +# define __has_builtin(...) BIGDECIMAL_HAS_BUILTIN(__VA_ARGS__) +#endif + +#endif /* BIGDECIMAL_HAS_FEATURE_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.c b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.c new file mode 100644 index 0000000..1454c28 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.c @@ -0,0 +1,28 @@ +#include + +#ifdef HAVE_RUBY_ATOMIC_H +# include +#endif + +#ifdef RUBY_ATOMIC_PTR_CAS +# define ATOMIC_PTR_CAS(var, old, new) RUBY_ATOMIC_PTR_CAS(var, old, new) +#endif + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +/* GCC warns about unknown sanitizer, which is annoying. */ +# undef NO_SANITIZE +# define NO_SANITIZE(x, y) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ + __attribute__((__no_sanitize__(x))) y; \ + _Pragma("GCC diagnostic pop") \ + y +#endif + +#undef strtod +#define strtod BigDecimal_strtod +#undef dtoa +#define dtoa BigDecimal_dtoa +#undef hdtoa +#define hdtoa BigDecimal_hdtoa +#include "missing/dtoa.c" diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.h new file mode 100644 index 0000000..437d5bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing.h @@ -0,0 +1,106 @@ +#ifndef MISSING_H +#define MISSING_H 1 + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +#ifndef RB_UNUSED_VAR +# if defined(_MSC_VER) && _MSC_VER >= 1911 +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__has_cpp_attribute) && __has_cpp_attribute(maybe_unused) +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__has_c_attribute) && __has_c_attribute(maybe_unused) +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__GNUC__) +# define RB_UNUSED_VAR(x) x __attribute__ ((unused)) + +# else +# define RB_UNUSED_VAR(x) x +# endif +#endif /* RB_UNUSED_VAR */ + +#if defined(_MSC_VER) && _MSC_VER >= 1310 +# define HAVE___ASSUME 1 + +#elif defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300 +# define HAVE___ASSUME 1 +#endif + +#ifndef UNREACHABLE +# if __has_builtin(__builtin_unreachable) +# define UNREACHABLE __builtin_unreachable() + +# elif defined(HAVE___ASSUME) +# define UNREACHABLE __assume(0) + +# else +# define UNREACHABLE /* unreachable */ +# endif +#endif /* UNREACHABLE */ + +/* bool */ + +#ifndef __bool_true_false_are_defined +# include +#endif + +/* dtoa */ +char *BigDecimal_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve); + +/* complex */ + +#ifndef HAVE_RB_COMPLEX_REAL +static inline VALUE +rb_complex_real_fallback(VALUE cmp) +{ +#ifdef RCOMPLEX + return RCOMPLEX(cmp)->real; +#else + return rb_funcall(cmp, rb_intern("real"), 0); +#endif +} +#define rb_complex_real rb_complex_real_fallback +#endif + +#ifndef HAVE_RB_COMPLEX_IMAG +static inline VALUE +rb_complex_imag_fallback(VALUE cmp) +{ +# ifdef RCOMPLEX + return RCOMPLEX(cmp)->imag; +# else + return rb_funcall(cmp, rb_intern("imag"), 0); +# endif +} +#define rb_complex_imag rb_complex_imag_fallback +#endif + +/* st */ + +#ifndef ST2FIX +# undef RB_ST2FIX +# define RB_ST2FIX(h) LONG2FIX((long)(h)) +# define ST2FIX(h) RB_ST2FIX(h) +#endif + +/* warning */ + +#if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED) +# define rb_category_warn(category, ...) rb_warn(__VA_ARGS__) +#endif + +#if defined(__cplusplus) +#if 0 +{ /* satisfy cc-mode */ +#endif +} /* extern "C" { */ +#endif + +#endif /* MISSING_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing/dtoa.c b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing/dtoa.c new file mode 100644 index 0000000..ba8cd46 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/missing/dtoa.c @@ -0,0 +1,3509 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and strtod and dtoa should round accordingly. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and Honor_FLT_ROUNDS is not #defined. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. + * #define YES_ALIAS to permit aliasing certain double values with + * arrays of ULongs. This leads to slightly better code with + * some compilers and was always used prior to 19990916, but it + * is not strictly legal and can cause trouble with aggressively + * optimizing compilers (e.g., gcc 2.95.1 under -O2). + * #define USE_LOCALE to use the current locale's decimal_point value. + * #define SET_INEXACT if IEEE arithmetic is being used and extra + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). + * #define NO_ERRNO if strtod should not assign errno = ERANGE when + * the result overflows to +-Infinity or underflows to 0. + */ + +#ifdef WORDS_BIGENDIAN +#define IEEE_BIG_ENDIAN +#else +#define IEEE_LITTLE_ENDIAN +#endif + +#ifdef __vax__ +#define VAX +#undef IEEE_BIG_ENDIAN +#undef IEEE_LITTLE_ENDIAN +#endif + +#if defined(__arm__) && !defined(__VFP_FP__) +#define IEEE_BIG_ENDIAN +#undef IEEE_LITTLE_ENDIAN +#endif + +#undef Long +#undef ULong + +#include +#include +#include +#include + +#if (INT_MAX >> 30) && !(INT_MAX >> 31) +#define Long int +#define ULong unsigned int +#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31) +#define Long long int +#define ULong unsigned long int +#else +#error No 32bit integer +#endif + +#if defined(HAVE_LONG_LONG) && (HAVE_LONG_LONG) +#define Llong LONG_LONG +#else +#define NO_LONG_LONG +#endif + +#ifdef DEBUG +#include +#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);} +#endif + +#ifndef ISDIGIT +#include +#define ISDIGIT(c) isdigit(c) +#endif +#include +#include +#include + +#ifdef USE_LOCALE +#include +#endif + +#if defined(HAVE_STDCKDINT_H) || !defined(__has_include) +#elif __has_include() +# define HAVE_STDCKDINT_H 1 +#endif +#ifdef HAVE_STDCKDINT_H +# include +#endif + +#if !defined(ckd_add) +static inline int /* bool */ +ckd_add(int *result, int x, int y) +{ + if (x < 0) { + if (y < INT_MIN - x) return 1; + } + else if (x > 0) { + if (y > INT_MAX - x) return 1; + } + *result = x + y; + return 0; +} +#endif + +#ifdef MALLOC +extern void *MALLOC(size_t); +#else +#define MALLOC malloc +#endif +#ifdef FREE +extern void FREE(void*); +#else +#define FREE free +#endif +#ifndef NO_SANITIZE +#define NO_SANITIZE(x, y) y +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_BIG_ENDIAN +#define IEEE_Arith +#endif +#ifdef IEEE_LITTLE_ENDIAN +#define IEEE_Arith +#endif + +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#endif /*IEEE_Arith*/ + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include +#endif /* Bad_float_h */ + +#include + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +#ifndef hexdigit +static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; +#endif + +#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef YES_ALIAS +typedef double double_u; +# define dval(x) (x) +# ifdef IEEE_LITTLE_ENDIAN +# define word0(x) (((ULong *)&(x))[1]) +# define word1(x) (((ULong *)&(x))[0]) +# else +# define word0(x) (((ULong *)&(x))[0]) +# define word1(x) (((ULong *)&(x))[1]) +# endif +#else +typedef U double_u; +# ifdef IEEE_LITTLE_ENDIAN +# define word0(x) ((x).L[1]) +# define word1(x) ((x).L[0]) +# else +# define word0(x) ((x).L[0]) +# define word1(x) ((x).L[1]) +# endif +# define dval(x) ((x).d) +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__) +#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \ +((unsigned short *)(a))[0] = (unsigned short)(c), (a)++) +#else +#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \ +((unsigned short *)(a))[1] = (unsigned short)(c), (a)++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#ifdef Flush_Denorm /* debugging option */ +#undef Sudden_Underflow +#endif +#endif + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + +#else /* ifndef IEEE_Arith */ +#undef Check_FLT_ROUNDS +#undef Honor_FLT_ROUNDS +#undef SET_INEXACT +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) ((a) = rnd_prod((a), (b))) +#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b))) +extern double rnd_prod(double, double), rnd_quot(double, double); +#else +#define rounded_product(a,b) ((a) *= (b)) +#define rounded_quotient(a,b) ((a) /= (b)) +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Pack_32 +#define Pack_32 +#endif + +#define FFFFFFFF 0xffffffffUL + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#define MULTIPLE_THREADS 1 + +#ifndef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#else +#define ACQUIRE_DTOA_LOCK(n) /*unused right now*/ +#define FREE_DTOA_LOCK(n) /*unused right now*/ +#endif + +#ifndef ATOMIC_PTR_CAS +#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (void *)(old)) +#endif +#ifndef LIKELY +#define LIKELY(x) (x) +#endif +#ifndef UNLIKELY +#define UNLIKELY(x) (x) +#endif +#ifndef ASSUME +#define ASSUME(x) (void)(x) +#endif + +#define Kmax 15 + +struct Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +typedef struct Bigint Bigint; + +static Bigint * +Balloc(int k) +{ + int x; + Bigint *rv; + + x = 1 << k; + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); + if (!rv) return NULL; + rv->k = k; + rv->maxwds = x; + rv->sign = rv->wds = 0; + return rv; +} + +static void +Bclear(Bigint **vp) +{ + Bigint *v = *vp; + *vp = NULL; + if (v) FREE(v); +} +#define Bfree(v) Bclear(&(v)) + +#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \ +(y)->wds*sizeof(Long) + 2*sizeof(int)) + +static Bigint * +multadd(Bigint *b, int m, int a) /* multiply by m and add a */ +{ + int i, wds; + ULong *x; +#ifdef ULLong + ULLong carry, y; +#else + ULong carry, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } while (++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + if (!b1) { + Bfree(b); + return NULL; + } + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = (ULong)carry; + b->wds = wds; + } + return b; +} + +static Bigint * +s2b(const char *s, int nd0, int nd, ULong y9) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for (k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + if (!b) return NULL; + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + if (!b) return NULL; + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + if (!b) return NULL; + } while (++i < nd0); + s++; + } + else + s += 10; + for (; i < nd; i++) { + b = multadd(b, 10, *s++ - '0'); + if (!b) return NULL; + } + return b; +} + +static int +hi0bits(register ULong x) +{ + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +static int +lo0bits(ULong *y) +{ + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; +} + +static Bigint * +i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + if (!b) return NULL; + b->x[0] = i; + b->wds = 1; + return b; +} + +#define Bzero_p(b) (!(b)->x[0] && (b)->wds <= 1) + +static Bigint * +mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (Bzero_p(a) || Bzero_p(b)) { + c = Balloc(0); + if (!c) return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + if (!c) return NULL; + for (x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for (; xb < xbe; xc0++) { + if ((y = *xb++) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = (ULong)(z & FFFFFFFF); + } while (x < xae); + *xc = (ULong)carry; + } + } +#else +#ifdef Pack_32 + for (; xb < xbe; xb++, xc0++) { + if ((y = *xb & 0xffff) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } while (x < xae); + *xc = (ULong)carry; + } + if ((y = *xb >> 16) != 0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } while (x < xae); + *xc = z2; + } + } +#else + for (; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } while (x < xae); + *xc = (ULong)carry; + } + } +#endif +#endif + for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint * +pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3) != 0) { + b = multadd(b, p05[i-1], 0); + if (!b) return NULL; + } + +#define b_cache(var, addr, new_expr) \ + if ((var = addr) != 0) {} else { \ + Bigint *tmp = 0; \ + ACQUIRE_DTOA_LOCK(1); \ + if (!(var = addr) && (var = (new_expr)) != 0) { \ + var->next = 0; \ + tmp = ATOMIC_PTR_CAS(addr, NULL, var); \ + } \ + FREE_DTOA_LOCK(1); \ + if (UNLIKELY(tmp)) { \ + Bfree(var); \ + var = tmp; \ + } \ + else if (!var) { \ + Bfree(b); \ + return NULL; \ + } \ + } + + if (!(k >>= 2)) + return b; + /* first time */ + b_cache(p5, p5s, i2b(625)); + for (;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + if (!b) return NULL; + } + if (!(k >>= 1)) + break; + b_cache(p51, p5->next, mult(p5, p5)); + p5 = p51; + } + return b; +} + +static Bigint * +lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + if (!k || Bzero_p(b)) return b; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for (i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + if (!b1) { + Bfree(b); + return NULL; + } + x1 = b1->x; + for (i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } while (x < xe); + if ((*x1 = z) != 0) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } while (x < xe); + if (*x1 = z) + ++n1; + } +#endif + else + do { + *x1++ = *x++; + } while (x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int +cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for (;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +NO_SANITIZE("unsigned-integer-overflow", static Bigint * diff(Bigint *a, Bigint *b)); +static Bigint * +diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + if (!c) return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + if (!c) return NULL; + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } while (xb < xbe); + while (xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } while (xb < xbe); + while (xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } while (xb < xbe); + while (xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while (!*--xc) + wa--; + c->wds = wa; + return c; +} + +static double +ulp(double x_) +{ + register Long L; + double_u x, a; + dval(x) = x_; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(a); +} + +static double +b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + double_u d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif +ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#else +#undef d0 +#undef d1 +#endif + return dval(d); +} + +static Bigint * +d2b(double d_, int *e, int *bits) +{ + double_u d; + Bigint *b; + int de, k; + ULong *x, y, z; +#ifndef Sudden_Underflow + int i; +#endif +#ifdef VAX + ULong d0, d1; +#endif + dval(d) = d_; +#ifdef VAX + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + if (!b) return NULL; + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(d0 >> Exp_shift)) != 0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = d1) != 0) { + if ((k = lo0bits(&y)) != 0) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) ? 2 : 1; + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while (!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; +} +#undef d0 +#undef d1 + +static double +ratio(Bigint *a, Bigint *b) +{ + double_u da, db; + int k, ka, kb; + + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(da) *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(db) *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); +} + +static const double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif +}; + +static const double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +#ifdef Avoid_Underflow + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-53 */ +#else + 1e-256 +#endif +}; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +bigtens[] = { 1e16, 1e32 }; +static const double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +#ifndef IEEE_Arith +#undef INFNAN_CHECK +#endif + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + +static int +match(const char **sp, char *t) +{ + int c, d; + const char *s = *sp; + + while (d = *t++) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; +} + +#ifndef No_Hex_NaN +static void +hexnan(double *rvp, const char **sp) +{ + ULong c, x[2]; + const char *s; + int havedig, udx0, xshift; + + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + while (c = *(const unsigned char*)++s) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c += 10 - 'a'; + else if (c >= 'A' && c <= 'F') + c += 10 - 'A'; + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else + return; /* invalid form: don't change *sp */ + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) + x[0] = (x[0] << 4) | (x[1] >> 28); + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(*rvp) = Exp_mask | x[0]; + word1(*rvp) = x[1]; + } +} +#endif /*No_Hex_NaN*/ +#endif /* INFNAN_CHECK */ + +NO_SANITIZE("unsigned-integer-overflow", double strtod(const char *s00, char **se)); +double +strtod(const char *s00, char **se) +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + const char *s, *s0, *s1; + double aadj, adj; + double_u aadj1, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef USE_LOCALE + const char *s2; +#endif + + errno = 0; + sign = nz0 = nz = 0; + dval(rv) = 0.; + for (s = s00;;s++) + switch (*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } +break2: + if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { + s0 = ++s; + adj = 0; + aadj = 1.0; + nd0 = -4; + + if (!*++s || (!(s1 = strchr(hexdigit, *s)) && *s != '.')) goto ret0; + if (*s == '0') { + while (*++s == '0'); + if (!*s) goto ret; + s1 = strchr(hexdigit, *s); + } + if (s1 != NULL) { + do { + adj += aadj * ((s1 - hexdigit) & 15); + nd0 += 4; + aadj /= 16; + } while (*++s && (s1 = strchr(hexdigit, *s))); + } + + if ((*s == '.') && *++s && (s1 = strchr(hexdigit, *s))) { + if (nd0 < 0) { + while (*s == '0') { + s++; + nd0 -= 4; + } + } + for (; *s && (s1 = strchr(hexdigit, *s)); ++s) { + adj += aadj * ((s1 - hexdigit) & 15); + if ((aadj /= 16) == 0.0) { + while (*++s && strchr(hexdigit, *s)); + break; + } + } + } + + if (*s == 'P' || *s == 'p') { + dsign = 0x2C - *++s; /* +: 2B, -: 2D */ + if (abs(dsign) == 1) s++; + else dsign = 1; + + nd = 0; + c = *s; + if (c < '0' || '9' < c) goto ret0; + do { + nd *= 10; + nd += c; + nd -= '0'; + c = *++s; + /* Float("0x0."+("0"*267)+"1fp2095") */ + if (nd + dsign * nd0 > 2095) { + while ('0' <= c && c <= '9') c = *++s; + break; + } + } while ('0' <= c && c <= '9'); + nd0 += nd * dsign; + } + dval(rv) = ldexp(adj, nd0); + goto ret; + } + nz0 = 1; + while (*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < DBL_DIG + 2) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for (;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + c = *++s; + if (!ISDIGIT(c)) + goto dig_done; + if (!nd) { + for (; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for (; c >= '0' && c <= '9'; c = *++s) { +have_dig: + nz++; + if (nd > DBL_DIG * 4) { + continue; + } + if (c -= '0') { + nf += nz; + for (i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 2) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 2) + z = 10*z + c; + nz = 0; + } + } + } +dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch (c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while (c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while ((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + switch (c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + hexnan(&rv, &s); +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ +ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2; + dval(rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = bb = bd = bs = delta = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ +vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15) != 0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { +ovfl: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch (rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15) != 0) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = 2*P; + for (j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << (j-32); + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { +undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + if (!bd0) goto ret; + + for (;;) { + bd = Balloc(bd0->k); + if (!bd) goto retfree; + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + if (!bb) goto retfree; + bs = i2b(1); + if (!bs) goto retfree; + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + if (!bs) goto retfree; + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + if (!bb) goto retfree; + } + if (bb2 > 0) { + bb = lshift(bb, bb2); + if (!bb) goto retfree; + } + if (bd5 > 0) { + bd = pow5mult(bd, bd5); + if (!bd) goto retfree; + } + if (bd2 > 0) { + bd = lshift(bd, bd2); + if (!bd) goto retfree; + } + if (bs2 > 0) { + bs = lshift(bs, bs2); + if (!bs) goto retfree; + } + delta = diff(bb, bd); + if (!delta) goto retfree; + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (!delta) goto nomem; + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } +apply_adj: +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (!delta) goto retfree; + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { +drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = dval(aadj1) = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + dval(aadj1) = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + dval(aadj1) = -aadj; + } + } + else { + aadj *= 0.5; + dval(aadj1) = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch (Rounding) { + case 2: /* towards +infinity */ + dval(aadj1) -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + dval(aadj1) += 0.5; + } +#else + if (Flt_Rounds == 0) + dval(aadj1) += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = (int)aadj) <= 0) + z = 1; + aadj = z; + dval(aadj1) = dsign ? aadj : -aadj; + } + word0(aadj1) += (2*P+1)*Exp_msk1 - y; + } + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + dval(aadj1) = (double)(int)(aadj + 0.5); + if (!dsign) + dval(aadj1) = -dval(aadj1); + } + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif +cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif +retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); +ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); +} + +NO_SANITIZE("unsigned-integer-overflow", static int quorem(Bigint *b, Bigint *S)); +static int +quorem(Bigint *b, Bigint *S) +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } while (sx <= sxe); + if (!*bxe) { + bx = b->x; + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } while (sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +#ifndef MULTIPLE_THREADS +static char *dtoa_result; +#endif + +#ifndef MULTIPLE_THREADS +static char * +rv_alloc(int i) +{ + return dtoa_result = MALLOC(i); +} +#else +#define rv_alloc(i) MALLOC(i) +#endif + +static char * +nrv_alloc(const char *s, char **rve, size_t n) +{ + char *rv, *t; + + t = rv = rv_alloc(n); + if (!rv) return NULL; + while ((*t = *s++) != 0) t++; + if (rve) + *rve = t; + return rv; +} + +#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1) + +#ifndef MULTIPLE_THREADS +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + +static void +freedtoa(char *s) +{ + FREE(s); +} +#endif + +static const char INFSTR[] = "Infinity"; +static const char NANSTR[] = "NaN"; +static const char ZEROSTR[] = "0"; + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +char * +dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve) +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick, half = 0; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S; + double ds; + double_u d, d2, eps; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + + dval(d) = d_; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(d) && !(word0(d) & 0xfffff)) + return rv_strdup(INFSTR, rve); +#endif + return rv_strdup(NANSTR, rve); + } +#endif +#ifdef IBM + dval(d) += 0; /* normalize */ +#endif + if (!dval(d)) { + *decpt = 1; + return rv_strdup(ZEROSTR, rve); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); + if (!b) return NULL; +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { +#endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (j = 11 - hi0bits(word0(d2) & Frac_mask)) + dval(d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) + : word1(d) << (32 - i); + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = -1; + switch (mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + if (ckd_add(&i, ndigits, k + 1)) { /* k + 1 should be safe */ + Bfree(b); + return NULL; + } + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i+1); + if (!s) { + Bfree(b); + return NULL; + } + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for (; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if ((j1 = -k) != 0) { + dval(d) *= tens[j1 & 0xf]; + for (j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for (i = 0;;) { + L = (int)dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for (i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while (*--s == '0') ; + s++; + goto ret1; + } + half = 1; + if ((*(s-1) - '0') & 1) { + goto bump_up; + } + break; + } + } +#ifndef No_leftright + } +#endif +fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for (i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch (rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || (dval(d) == ds && (L & 1))) { +bump_up: + while (*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + if (!mhi) goto nomem; + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + if (!mhi) goto nomem; + b1 = mult(mhi, b); + Bfree(b); + b = b1; + if (!b) goto nomem; + } + if ((j = b5 - m5) != 0) { + b = pow5mult(b, j); + if (!b) goto nomem; + } + } + else { + b = pow5mult(b, b5); + if (!b) goto nomem; + } + } + S = i2b(1); + if (!S) goto nomem; + if (s5 > 0) { + S = pow5mult(S, s5); + if (!S) goto nomem; + } + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) + i = 32 - i; +#else + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) { + b = lshift(b, b2); + if (!b) goto nomem; + } + if (s2 > 0) { + S = lshift(S, s2); + if (!S) goto nomem; + } + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (!b) goto nomem; + if (leftright) { + mhi = multadd(mhi, 10, 0); + if (!mhi) goto nomem; + } + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ +no_digits: + k = -1 - ndigits; + goto ret; + } +one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) { + mhi = lshift(mhi, m2); + if (!mhi) goto nomem; + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + if (!mhi) goto nomem; + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + if (!mhi) goto nomem; + } + + for (i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + if (!delta) goto nomem; + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + )) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch (rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + if (!b) goto nomem; + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9') + goto round_9_up; + } +accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ +round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS +keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (!b) goto nomem; + if (mlo == mhi) { + mlo = mhi = multadd(mhi, 10, 0); + if (!mlo) goto nomem; + } + else { + mlo = multadd(mlo, 10, 0); + if (!mlo) goto nomem; + mhi = multadd(mhi, 10, 0); + if (!mhi) goto nomem; + } + } + } + else + for (i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + if (!b) goto nomem; + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch (rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + if (!b) goto nomem; + j = cmp(b, S); + if (j > 0 || (j == 0 && (dig & 1))) { + roundoff: + while (*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + if (!half || (*s - '0') & 1) + ++*s; + } + else { + while (*--s == '0') ; + } + s++; +ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } +ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + nomem: + if (S) Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + if (b) Bfree(b); + FREE(s0); + return NULL; +} + +/*- + * Copyright (c) 2004-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define DBL_MANH_SIZE 20 +#define DBL_MANL_SIZE 32 +#define DBL_ADJ (DBL_MAX_EXP - 2) +#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1) +#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1) +#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift))) +#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask)) +#define dmanl_get(u) ((uint32_t)word1(u)) + + +/* + * This procedure converts a double-precision number in IEEE format + * into a string of hexadecimal digits and an exponent of 2. Its + * behavior is bug-for-bug compatible with dtoa() in mode 2, with the + * following exceptions: + * + * - An ndigits < 0 causes it to use as many digits as necessary to + * represent the number exactly. + * - The additional xdigs argument should point to either the string + * "0123456789ABCDEF" or the string "0123456789abcdef", depending on + * which case is desired. + * - This routine does not repeat dtoa's mistake of setting decpt + * to 9999 in the case of an infinity or NaN. INT_MAX is used + * for this purpose instead. + * + * Note that the C99 standard does not specify what the leading digit + * should be for non-zero numbers. For instance, 0x1.3p3 is the same + * as 0x2.6p2 is the same as 0x4.cp3. This implementation always makes + * the leading digit a 1. This ensures that the exponent printed is the + * actual base-2 exponent, i.e., ilogb(d). + * + * Inputs: d, xdigs, ndigits + * Outputs: decpt, sign, rve + */ +char * +hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve) +{ + U u; + char *s, *s0; + int bufsize; + uint32_t manh, manl; + + u.d = d; + if (word0(u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + + if (isinf(d)) { /* FP_INFINITE */ + *decpt = INT_MAX; + return rv_strdup(INFSTR, rve); + } + else if (isnan(d)) { /* FP_NAN */ + *decpt = INT_MAX; + return rv_strdup(NANSTR, rve); + } + else if (d == 0.0) { /* FP_ZERO */ + *decpt = 1; + return rv_strdup(ZEROSTR, rve); + } + else if (dexp_get(u)) { /* FP_NORMAL */ + *decpt = dexp_get(u) - DBL_ADJ; + } + else { /* FP_SUBNORMAL */ + u.d *= 5.363123171977039e+154 /* 0x1p514 */; + *decpt = dexp_get(u) - (514 + DBL_ADJ); + } + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * If ndigits < 0, we are expected to auto-size, so we allocate + * enough space for all the digits. + */ + bufsize = (ndigits > 0) ? ndigits : SIGFIGS; + s0 = rv_alloc(bufsize+1); + if (!s0) return NULL; + + /* Round to the desired number of digits. */ + if (SIGFIGS > ndigits && ndigits > 0) { + float redux = 1.0f; + int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG; + dexp_set(u, offset); + u.d += redux; + u.d -= redux; + *decpt += dexp_get(u) - offset; + } + + manh = dmanh_get(u); + manl = dmanl_get(u); + *s0 = '1'; + for (s = s0 + 1; s < s0 + bufsize; s++) { + *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf]; + manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4)); + manl <<= 4; + } + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = SIGFIGS; s0[ndigits - 1] == '0'; ndigits--) + ; + } + + s = s0 + ndigits; + *s = '\0'; + if (rve != NULL) + *rve = s; + return (s0); +} + +#ifdef __cplusplus +#if 0 +{ /* satisfy cc-mode */ +#endif +} +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/ntt.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/ntt.h new file mode 100644 index 0000000..bbd8376 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/ntt.h @@ -0,0 +1,191 @@ +// NTT (Number Theoretic Transform) implementation for BigDecimal multiplication + +#define NTT_PRIMITIVE_ROOT 17 +#define NTT_PRIME_BASE1 24 +#define NTT_PRIME_BASE2 26 +#define NTT_PRIME_BASE3 29 +#define NTT_PRIME_SHIFT 27 +#define NTT_PRIME1 (((uint32_t)NTT_PRIME_BASE1 << NTT_PRIME_SHIFT) | 1) +#define NTT_PRIME2 (((uint32_t)NTT_PRIME_BASE2 << NTT_PRIME_SHIFT) | 1) +#define NTT_PRIME3 (((uint32_t)NTT_PRIME_BASE3 << NTT_PRIME_SHIFT) | 1) +#define MAX_NTT32_BITS 27 +#define NTT_DECDIG_BASE 1000000000 + +// Calculates base**ex % mod +static uint32_t +mod_pow(uint32_t base, uint32_t ex, uint32_t mod) { + uint32_t res = 1; + uint32_t bit = 1; + while (true) { + if (ex & bit) { + ex ^= bit; + res = ((uint64_t)res * base) % mod; + } + if (!ex) break; + base = ((uint64_t)base * base) % mod; + bit <<= 1; + } + return res; +} + +// Recursively performs butterfly operations of NTT +static void +ntt_recursive(int size_bits, uint32_t *input, uint32_t *output, uint32_t *tmp, int depth, uint32_t r, uint32_t prime) { + if (depth > 0) { + ntt_recursive(size_bits, input, tmp, output, depth - 1, ((uint64_t)r * r) % prime, prime); + } else { + tmp = input; + } + uint32_t size_half = (uint32_t)1 << (size_bits - 1); + uint32_t stride = (uint32_t)1 << (size_bits - depth - 1); + uint32_t n = size_half / stride; + uint32_t rn = 1, rm = prime - 1; + for (uint32_t i = 0; i < n; i++) { + uint32_t *aptr = tmp + i * 2 * stride; + uint32_t *bptr = aptr + stride; + uint32_t *out1 = output + stride * i; + uint32_t *out2 = out1 + size_half; + for (uint32_t k = 0; k < stride; k++) { + uint32_t a = aptr[k], b = bptr[k]; + out1[k] = (a + (uint64_t)rn * b) % prime; + out2[k] = (a + (uint64_t)rm * b) % prime; + } + rn = ((uint64_t)rn * r) % prime; + rm = ((uint64_t)rm * r) % prime; + } +} + +/* Perform NTT on input array. + * base, shift: Represent the prime number as (base << shift | 1) + * r_base: Primitive root of unity modulo prime + * size_bits: log2 of the size of the input array. Should be less or equal to shift + * input: input array of size (1 << size_bits) + */ +static void +ntt(int size_bits, uint32_t *input, uint32_t *output, uint32_t *tmp, int r_base, int base, int shift, int dir) { + uint32_t size = (uint32_t)1 << size_bits; + uint32_t prime = ((uint32_t)base << shift) | 1; + + // rmax**(1 << shift) % prime == 1 + // r**size % prime == 1 + uint32_t rmax = mod_pow((uint32_t)r_base, (uint32_t)base, prime); + uint32_t r = mod_pow(rmax, (uint32_t)1 << (shift - size_bits), prime); + + if (dir < 0) r = mod_pow(r, prime - 2, prime); + ntt_recursive(size_bits, input, output, tmp, size_bits - 1, r, prime); + if (dir < 0) { + uint32_t n_inv = mod_pow((uint32_t)size, prime - 2, prime); + for (uint32_t i = 0; i < size; i++) { + output[i] = ((uint64_t)output[i] * n_inv) % prime; + } + } +} + +/* Calculate c that satisfies: c % PRIME1 == mod1 && c % PRIME2 == mod2 && c % PRIME3 == mod3 + * c = (mod1 * 35002755423056150739595925972 + mod2 * 14584479687667766215746868453 + mod3 * 37919651490985126265126719818) % (PRIME1 * PRIME2 * PRIME3) + * Assume c <= 999999999**2*(1<<27) + */ +static inline void +mod_restore_prime_24_26_29_shift_27(uint32_t mod1, uint32_t mod2, uint32_t mod3, uint32_t *digits) { + // Use mixed radix notation to eliminate modulo by PRIME1 * PRIME2 * PRIME3 + // [DIG0, DIG1, DIG2] = DIG0 + DIG1 * PRIME1 + DIG2 * PRIME1 * PRIME2 + // DIG0: 0...PRIME1, DIG1: 0...PRIME2, DIG2: 0...PRIME3 + // 35002755423056150739595925972 = [1, 3489660916, 3113851359] + // 14584479687667766215746868453 = [0, 13, 1297437912] + // 37919651490985126265126719818 = [0, 0, 3373338954] + uint64_t c0 = mod1; + uint64_t c1 = (uint64_t)mod2 * 13 + (uint64_t)mod1 * 3489660916; + uint64_t c2 = (uint64_t)mod3 * 3373338954 % NTT_PRIME3 + (uint64_t)mod2 * 1297437912 % NTT_PRIME3 + (uint64_t)mod1 * 3113851359 % NTT_PRIME3; + c2 += c1 / NTT_PRIME2; + c1 %= NTT_PRIME2; + c2 %= NTT_PRIME3; + // Base conversion. c fits in 3 digits. + c1 += c2 % NTT_DECDIG_BASE * NTT_PRIME2; + c0 += c1 % NTT_DECDIG_BASE * NTT_PRIME1; + c1 /= NTT_DECDIG_BASE; + digits[0] = c0 % NTT_DECDIG_BASE; + c0 /= NTT_DECDIG_BASE; + c1 += c2 / NTT_DECDIG_BASE % NTT_DECDIG_BASE * NTT_PRIME2; + c0 += c1 % NTT_DECDIG_BASE * NTT_PRIME1; + c1 /= NTT_DECDIG_BASE; + digits[1] = c0 % NTT_DECDIG_BASE; + digits[2] = (uint32_t)(c0 / NTT_DECDIG_BASE + c1 % NTT_DECDIG_BASE * NTT_PRIME1); +} + +/* + * NTT multiplication + * Uses three NTTs with mod (24 << 27 | 1), (26 << 27 | 1), and (29 << 27 | 1) + */ +static void +ntt_multiply(size_t a_size, size_t b_size, uint32_t *a, uint32_t *b, uint32_t *c) { + if (a_size < b_size) { + ntt_multiply(b_size, a_size, b, a, c); + return; + } + + int ntt_size_bits = (int)bit_length(b_size - 1) + 1; + if (ntt_size_bits > MAX_NTT32_BITS) { + rb_raise(rb_eArgError, "Multiply size too large"); + } + + // To calculate large_a * small_b faster, split into several batches. + uint32_t ntt_size = (uint32_t)1 << ntt_size_bits; + uint32_t batch_size = ntt_size - (uint32_t)b_size; + uint32_t batch_count = (uint32_t)((a_size + batch_size - 1) / batch_size); + + uint32_t *mem = ruby_xcalloc(ntt_size * 9, sizeof(uint32_t)); + uint32_t *ntt1 = mem; + uint32_t *ntt2 = mem + ntt_size; + uint32_t *ntt3 = mem + ntt_size * 2; + uint32_t *tmp1 = mem + ntt_size * 3; + uint32_t *tmp2 = mem + ntt_size * 4; + uint32_t *tmp3 = mem + ntt_size * 5; + uint32_t *conv1 = mem + ntt_size * 6; + uint32_t *conv2 = mem + ntt_size * 7; + uint32_t *conv3 = mem + ntt_size * 8; + + // Calculate NTT for b in three primes. Result is reused for each batch of a. + memcpy(tmp1, b, b_size * sizeof(uint32_t)); + memset(tmp1 + b_size, 0, (ntt_size - b_size) * sizeof(uint32_t)); + ntt(ntt_size_bits, tmp1, ntt1, tmp2, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE1, NTT_PRIME_SHIFT, +1); + ntt(ntt_size_bits, tmp1, ntt2, tmp2, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE2, NTT_PRIME_SHIFT, +1); + ntt(ntt_size_bits, tmp1, ntt3, tmp2, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE3, NTT_PRIME_SHIFT, +1); + + memset(c, 0, (a_size + b_size) * sizeof(uint32_t)); + for (uint32_t idx = 0; idx < batch_count; idx++) { + uint32_t len = idx == batch_count - 1 ? (uint32_t)a_size - idx * batch_size : batch_size; + memcpy(tmp1, a + idx * batch_size, len * sizeof(uint32_t)); + memset(tmp1 + len, 0, (ntt_size - len) * sizeof(uint32_t)); + // Calculate convolution for this batch in three primes + ntt(ntt_size_bits, tmp1, tmp2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE1, NTT_PRIME_SHIFT, +1); + for (uint32_t i = 0; i < ntt_size; i++) tmp2[i] = ((uint64_t)tmp2[i] * ntt1[i]) % NTT_PRIME1; + ntt(ntt_size_bits, tmp2, conv1, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE1, NTT_PRIME_SHIFT, -1); + ntt(ntt_size_bits, tmp1, tmp2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE2, NTT_PRIME_SHIFT, +1); + for (uint32_t i = 0; i < ntt_size; i++) tmp2[i] = ((uint64_t)tmp2[i] * ntt2[i]) % NTT_PRIME2; + ntt(ntt_size_bits, tmp2, conv2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE2, NTT_PRIME_SHIFT, -1); + ntt(ntt_size_bits, tmp1, tmp2, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE3, NTT_PRIME_SHIFT, +1); + for (uint32_t i = 0; i < ntt_size; i++) tmp2[i] = ((uint64_t)tmp2[i] * ntt3[i]) % NTT_PRIME3; + ntt(ntt_size_bits, tmp2, conv3, tmp3, NTT_PRIMITIVE_ROOT, NTT_PRIME_BASE3, NTT_PRIME_SHIFT, -1); + + // Restore the original convolution value from three convolutions calculated in three primes. + // Each convolution value is maximum 999999999**2*(1<<27)/2 + for (uint32_t i = 0; i < ntt_size; i++) { + uint32_t dig[3]; + mod_restore_prime_24_26_29_shift_27(conv1[i], conv2[i], conv3[i], dig); + // Maximum values of dig[0], dig[1], and dig[2] are 999999999, 999999999 and 67108863 respectively + // Maximum overlapped sum (considering overlaps between 2 batches) is less than 4134217722 + // so this sum doesn't overflow uint32_t. + for (int j = 0; j < 3; j++) { + // Index check: if dig[j] is non-zero, assign index is within valid range. + if (dig[j]) c[idx * batch_size + i + 1 - (uint32_t)j] += dig[j]; + } + } + } + uint32_t carry = 0; + for (int32_t i = (int32_t)(a_size + b_size - 1); i >= 0; i--) { + uint32_t v = c[i] + carry; + c[i] = v % NTT_DECDIG_BASE; + carry = v / NTT_DECDIG_BASE; + } + ruby_xfree(mem); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/static_assert.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/static_assert.h new file mode 100644 index 0000000..9295729 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/ext/bigdecimal/static_assert.h @@ -0,0 +1,54 @@ +#ifndef BIGDECIMAL_STATIC_ASSERT_H +#define BIGDECIMAL_STATIC_ASSERT_H + +#include "feature.h" + +#ifdef HAVE_RUBY_INTERNAL_STATIC_ASSERT_H +# include +#endif + +#ifdef RBIMPL_STATIC_ASSERT +# define STATIC_ASSERT RBIMPL_STATIC_ASSERT +#endif + +#ifndef STATIC_ASSERT +# /* The following section is copied from CRuby's static_assert.h */ + +# if defined(__cplusplus) && defined(__cpp_static_assert) +# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */ +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER >= 1600 +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__INTEL_CXX11_MODE__) +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && __cplusplus >= 201103L +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && __has_extension(cxx_static_assert) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ static_assert + +# elif defined(__STDC_VERSION__) && __has_extension(c_static_assert) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert + +# elif defined(__STDC_VERSION__) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert +#endif + +# if defined(__DOXYGEN__) +# define STATIC_ASSERT static_assert + +# elif defined(BIGDECIMAL_STATIC_ASSERT0) +# define STATIC_ASSERT(name, expr) \ + BIGDECIMAL_STATIC_ASSERT0(expr, #name ": " #expr) + +# else +# define STATIC_ASSERT(name, expr) \ + typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)] +# endif +#endif /* STATIC_ASSERT */ + + +#endif /* BIGDECIMAL_STATIC_ASSERT_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.bundle b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.bundle new file mode 100755 index 0000000..5a56d47 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.rb new file mode 100644 index 0000000..5b492ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal.rb @@ -0,0 +1,404 @@ +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.bigdecimal.BigDecimalLibrary") + + class BigDecimal + def _decimal_shift(i) # :nodoc: + to_java.move_point_right(i).to_d + end + end +else + require 'bigdecimal.so' +end + +class BigDecimal + module Internal # :nodoc: + # Default extra precision for intermediate calculations + # This value is currently the same as BigDecimal.double_fig, but defined separately for future changes. + EXTRA_PREC = 16 + + # Coerce x to BigDecimal with the specified precision. + # TODO: some methods (example: BigMath.exp) require more precision than specified to coerce. + def self.coerce_to_bigdecimal(x, prec, method_name) # :nodoc: + case x + when BigDecimal + return x + when Integer, Float + return BigDecimal(x, 0) + when Rational + return BigDecimal(x, [prec, 2 * BigDecimal.double_fig].max) + end + raise ArgumentError, "#{x.inspect} can't be coerced into BigDecimal" + end + + def self.coerce_validate_prec(prec, method_name, accept_zero: false) # :nodoc: + unless Integer === prec + original = prec + # Emulate Integer.try_convert for ruby < 3.1 + if prec.respond_to?(:to_int) + prec = prec.to_int + else + raise TypeError, "no implicit conversion of #{original.class} into Integer" + end + raise TypeError, "can't convert #{original.class} to Integer" unless Integer === prec + end + + if accept_zero + raise ArgumentError, "Negative precision for #{method_name}" if prec < 0 + else + raise ArgumentError, "Zero or negative precision for #{method_name}" if prec <= 0 + end + prec + end + + def self.infinity_computation_result # :nodoc: + if BigDecimal.mode(BigDecimal::EXCEPTION_ALL).anybits?(BigDecimal::EXCEPTION_INFINITY) + raise FloatDomainError, "Computation results in 'Infinity'" + end + BigDecimal::INFINITY + end + + def self.underflow_computation_result # :nodoc: + if BigDecimal.mode(BigDecimal::EXCEPTION_ALL).anybits?(BigDecimal::EXCEPTION_UNDERFLOW) + raise FloatDomainError, 'Exponent underflow' + end + BigDecimal(0) + end + + def self.nan_computation_result # :nodoc: + if BigDecimal.mode(BigDecimal::EXCEPTION_ALL).anybits?(BigDecimal::EXCEPTION_NaN) + raise FloatDomainError, "Computation results to 'NaN'" + end + BigDecimal::NAN + end + + # Iteration for Newton's method with increasing precision + def self.newton_loop(prec, initial_precision: BigDecimal.double_fig / 2, safe_margin: 2) # :nodoc: + precs = [] + while prec > initial_precision + precs << prec + prec = (precs.last + 1) / 2 + safe_margin + end + precs.reverse_each do |p| + yield p + end + end + + # Calculates Math.log(x.to_f) considering large or small exponent + def self.float_log(x) # :nodoc: + Math.log(x._decimal_shift(-x.exponent).to_f) + x.exponent * Math.log(10) + end + + # Calculating Taylor series sum using binary splitting method + # Calculates f(x) = (x/d0)*(1+(x/d1)*(1+(x/d2)*(1+(x/d3)*(1+...)))) + # x.n_significant_digits or ds.size must be small to be performant. + def self.taylor_sum_binary_splitting(x, ds, prec) # :nodoc: + fs = ds.map {|d| [0, BigDecimal(d)] } + # fs = [[a0, a1], [b0, b1], [c0, c1], ...] + # f(x) = a0/a1+(x/a1)*(1+b0/b1+(x/b1)*(1+c0/c1+(x/c1)*(1+d0/d1+(x/d1)*(1+...)))) + while fs.size > 1 + # Merge two adjacent fractions + # from: (1 + a0/a1 + x/a1 * (1 + b0/b1 + x/b1 * rest)) + # to: (1 + (a0*b1+x*(b0+b1))/(a1*b1) + (x*x)/(a1*b1) * rest) + xn = xn ? xn.mult(xn, prec) : x + fs = fs.each_slice(2).map do |(a, b)| + b ||= [0, BigDecimal(1)._decimal_shift([xn.exponent, 0].max + 2)] + [ + (a[0] * b[1]).add(xn * (b[0] + b[1]), prec), + a[1].mult(b[1], prec) + ] + end + end + BigDecimal(fs[0][0]).div(fs[0][1], prec) + end + end + + # call-seq: + # self ** other -> bigdecimal + # + # Returns the \BigDecimal value of +self+ raised to power +other+: + # + # b = BigDecimal('3.14') + # b ** 2 # => 0.98596e1 + # b ** 2.0 # => 0.98596e1 + # b ** Rational(2, 1) # => 0.98596e1 + # + # Related: BigDecimal#power. + # + def **(y) + case y + when BigDecimal, Integer, Float, Rational + power(y) + when nil + raise TypeError, 'wrong argument type NilClass' + else + x, y = y.coerce(self) + x**y + end + end + + # call-seq: + # power(n) + # power(n, prec) + # + # Returns the value raised to the power of n. + # + # Also available as the operator **. + # + def power(y, prec = 0) + prec = Internal.coerce_validate_prec(prec, :power, accept_zero: true) + x = self + y = Internal.coerce_to_bigdecimal(y, prec.nonzero? || n_significant_digits, :power) + + return Internal.nan_computation_result if x.nan? || y.nan? + return BigDecimal(1) if y.zero? + + if y.infinite? + if x < 0 + return BigDecimal(0) if x < -1 && y.negative? + return BigDecimal(0) if x > -1 && y.positive? + raise Math::DomainError, 'Result undefined for negative base raised to infinite power' + elsif x < 1 + return y.positive? ? BigDecimal(0) : BigDecimal::Internal.infinity_computation_result + elsif x == 1 + return BigDecimal(1) + else + return y.positive? ? BigDecimal::Internal.infinity_computation_result : BigDecimal(0) + end + end + + if x.infinite? && y < 0 + # Computation result will be +0 or -0. Avoid overflow. + neg = x < 0 && y.frac.zero? && y % 2 == 1 + return neg ? -BigDecimal(0) : BigDecimal(0) + end + + if x.zero? + return BigDecimal(1) if y.zero? + return BigDecimal(0) if y > 0 + if y.frac.zero? && y % 2 == 1 && x.sign == -1 + return -BigDecimal::Internal.infinity_computation_result + else + return BigDecimal::Internal.infinity_computation_result + end + elsif x < 0 + if y.frac.zero? + if y % 2 == 0 + return (-x).power(y, prec) + else + return -(-x).power(y, prec) + end + else + raise Math::DomainError, 'Computation results in complex number' + end + elsif x == 1 + return BigDecimal(1) + end + + limit = BigDecimal.limit + frac_part = y.frac + + if frac_part.zero? && prec.zero? && limit.zero? + # Infinite precision calculation for `x ** int` and `x.power(int)` + int_part = y.fix.to_i + int_part = -int_part if (neg = int_part < 0) + ans = BigDecimal(1) + n = 1 + xn = x + while true + ans *= xn if int_part.allbits?(n) + n <<= 1 + break if n > int_part + xn *= xn + # Detect overflow/underflow before consuming infinite memory + if (xn.exponent.abs - 1) * int_part / n >= 0x7FFFFFFFFFFFFFFF + return ((xn.exponent > 0) ^ neg ? BigDecimal::Internal.infinity_computation_result : BigDecimal(0)) * (int_part.even? || x > 0 ? 1 : -1) + end + end + return neg ? BigDecimal(1) / ans : ans + end + + result_prec = prec.nonzero? || [x.n_significant_digits, y.n_significant_digits, BigDecimal.double_fig].max + BigDecimal.double_fig + result_prec = [result_prec, limit].min if prec.zero? && limit.nonzero? + + prec2 = result_prec + BigDecimal::Internal::EXTRA_PREC + + if y < 0 + inv = x.power(-y, prec2) + return BigDecimal(0) if inv.infinite? + return BigDecimal::Internal.infinity_computation_result if inv.zero? + return BigDecimal(1).div(inv, result_prec) + end + + if frac_part.zero? && y.exponent < Math.log(result_prec) * 5 + 20 + # Use exponentiation by squaring if y is an integer and not too large + pow_prec = prec2 + y.exponent + n = 1 + xn = x + ans = BigDecimal(1) + int_part = y.fix.to_i + while true + ans = ans.mult(xn, pow_prec) if int_part.allbits?(n) + n <<= 1 + break if n > int_part + xn = xn.mult(xn, pow_prec) + end + ans.mult(1, result_prec) + else + if x > 1 && x.finite? + # To calculate exp(z, prec), z needs prec+max(z.exponent, 0) precision if z > 0. + # Estimate (y*log(x)).exponent + logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).round + ylogx_exponent = y.exponent + logx_exponent + prec2 += [ylogx_exponent, 0].max + end + BigMath.exp(BigMath.log(x, prec2).mult(y, prec2), result_prec) + end + end + + # Returns the square root of the value. + # + # Result has at least prec significant digits. + # + def sqrt(prec) + prec = Internal.coerce_validate_prec(prec, :sqrt, accept_zero: true) + return Internal.infinity_computation_result if infinite? == 1 + + raise FloatDomainError, 'sqrt of negative value' if self < 0 + raise FloatDomainError, "sqrt of 'NaN'(Not a Number)" if nan? + return self if zero? + + if prec == 0 + limit = BigDecimal.limit + prec = n_significant_digits + BigDecimal.double_fig + prec = [limit, prec].min if limit.nonzero? + end + + ex = exponent / 2 + x = _decimal_shift(-2 * ex) + y = BigDecimal(Math.sqrt(x.to_f), 0) + Internal.newton_loop(prec + BigDecimal::Internal::EXTRA_PREC) do |p| + y = y.add(x.div(y, p), p).div(2, p) + end + y._decimal_shift(ex).mult(1, prec) + end +end + +# Core BigMath methods for BigDecimal (log, exp) are defined here. +# Other methods (sin, cos, atan) are defined in 'bigdecimal/math.rb'. +module BigMath + module_function + + # call-seq: + # BigMath.log(decimal, numeric) -> BigDecimal + # + # Computes the natural logarithm of +decimal+ to the specified number of + # digits of precision, +numeric+. + # + # If +decimal+ is zero or negative, raises Math::DomainError. + # + # If +decimal+ is positive infinity, returns Infinity. + # + # If +decimal+ is NaN, returns NaN. + # + def log(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :log) + raise Math::DomainError, 'Complex argument for BigMath.log' if Complex === x + + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log) + return BigDecimal::Internal.nan_computation_result if x.nan? + raise Math::DomainError, 'Negative argument for log' if x < 0 + return -BigDecimal::Internal.infinity_computation_result if x.zero? + return BigDecimal::Internal.infinity_computation_result if x.infinite? + return BigDecimal(0) if x == 1 + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + + # Reduce x to near 1 + if x > 1.01 || x < 0.99 + # log(x) = log(x/exp(logx_approx)) + logx_approx + logx_approx = BigDecimal(BigDecimal::Internal.float_log(x), 0) + x = x.div(exp(logx_approx, prec2), prec2) + else + logx_approx = BigDecimal(0) + end + + # Solve exp(y) - x = 0 with Newton's method + # Repeat: y -= (exp(y) - x) / exp(y) + y = BigDecimal(BigDecimal::Internal.float_log(x), 0) + exp_additional_prec = [-(x - 1).exponent, 0].max + BigDecimal::Internal.newton_loop(prec2) do |p| + expy = exp(y, p + exp_additional_prec) + y = y.sub(expy.sub(x, p).div(expy, p), p) + end + y.add(logx_approx, prec) + end + + private_class_method def _exp_binary_splitting(x, prec) # :nodoc: + return BigDecimal(1) if x.zero? + # Find k that satisfies x**k / k! < 10**(-prec) + log10 = Math.log(10) + logx = BigDecimal::Internal.float_log(x.abs) + step = (1..).bsearch { |k| Math.lgamma(k + 1)[0] - k * logx > prec * log10 } + # exp(x)-1 = x*(1+x/2*(1+x/3*(1+x/4*(1+x/5*(1+...))))) + 1 + BigDecimal::Internal.taylor_sum_binary_splitting(x, [*1..step], prec) + end + + # call-seq: + # BigMath.exp(decimal, numeric) -> BigDecimal + # + # Computes the value of e (the base of natural logarithms) raised to the + # power of +decimal+, to the specified number of digits of precision. + # + # If +decimal+ is infinity, returns Infinity. + # + # If +decimal+ is NaN, returns NaN. + # + def exp(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :exp) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :exp) + return BigDecimal::Internal.nan_computation_result if x.nan? + if x.infinite? || x.exponent >= 21 # exp(10**20) and exp(-10**20) overflows/underflows 64-bit exponent + if x.positive? + return BigDecimal::Internal.infinity_computation_result + elsif x.infinite? + # exp(-Infinity) is +0 by definition, this is not an underflow. + return BigDecimal(0) + else + return BigDecimal::Internal.underflow_computation_result + end + end + + return BigDecimal(1) if x.zero? + + # exp(x * 10**cnt) = exp(x)**(10**cnt) + cnt = x < -1 || x > 1 ? x.exponent : 0 + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + cnt + x = x._decimal_shift(-cnt) + + # Decimal form of bit-burst algorithm + # Calculate exp(x.xxxxxxxxxxxxxxxx) as + # exp(x.xx) * exp(0.00xx) * exp(0.0000xxxx) * exp(0.00000000xxxxxxxx) + x = x.mult(1, prec2) + n = 2 + y = BigDecimal(1) + BigDecimal.save_limit do + BigDecimal.limit(0) + while x != 0 do + partial_x = x.truncate(n) + x -= partial_x + y = y.mult(_exp_binary_splitting(partial_x, prec2), prec2) + n *= 2 + end + end + + # calculate exp(x * 10**cnt) from exp(x) + # exp(x * 10**k) = exp(x * 10**(k - 1)) ** 10 + cnt.times do + y2 = y.mult(y, prec2) + y5 = y2.mult(y2, prec2).mult(y, prec2) + y = y5.mult(y5, prec2) + end + + y.mult(1, prec) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/jacobian.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/jacobian.rb new file mode 100644 index 0000000..9a5e5be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/jacobian.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: false + +require 'bigdecimal' + +warn "'bigdecimal/jacobian' is deprecated and will be removed in a future release." + +# require 'bigdecimal/jacobian' +# +# Provides methods to compute the Jacobian matrix of a set of equations at a +# point x. In the methods below: +# +# f is an Object which is used to compute the Jacobian matrix of the equations. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# x is the point at which to compute the Jacobian. +# +# fx is f.values(x). +# +module Jacobian + module_function + + # Determines the equality of two numbers by comparing to zero, or using the epsilon value + def isEqual(a,b,zero=0.0,e=1.0e-8) + aa = a.abs + bb = b.abs + if aa == zero && bb == zero then + true + else + if ((a-b)/(aa+bb)).abs < e then + true + else + false + end + end + end + + + # Computes the derivative of +f[i]+ at +x[i]+. + # +fx+ is the value of +f+ at +x+. + def dfdxi(f,fx,x,i) + nRetry = 0 + n = x.size + xSave = x[i] + ok = 0 + ratio = f.ten*f.ten*f.ten + dx = x[i].abs/ratio + dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps) + dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps) + until ok>0 do + deriv = [] + nRetry += 1 + if nRetry > 100 + raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]" + end + dx = dx*f.two + x[i] += dx + fxNew = f.values(x) + for j in 0...n do + if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then + ok += 1 + deriv <<= (fxNew[j]-fx[j])/dx + else + deriv <<= f.zero + end + end + x[i] = xSave + end + deriv + end + + # Computes the Jacobian of +f+ at +x+. +fx+ is the value of +f+ at +x+. + def jacobian(f,fx,x) + n = x.size + dfdx = Array.new(n*n) + for i in 0...n do + df = dfdxi(f,fx,x,i) + for j in 0...n do + dfdx[j*n+i] = df[j] + end + end + dfdx + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/ludcmp.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/ludcmp.rb new file mode 100644 index 0000000..d112fc1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/ludcmp.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: false +require 'bigdecimal' + +warn "'bigdecimal/ludcmp' is deprecated and will be removed in a future release." + +# +# Solves a*x = b for x, using LU decomposition. +# +module LUSolve + module_function + + # Performs LU decomposition of the n by n matrix a. + def ludecomp(a,n,zero=0,one=1) + prec = BigDecimal.limit(nil) + ps = [] + scales = [] + for i in 0...n do # pick up largest(abs. val.) element in each row. + ps <<= i + nrmrow = zero + ixn = i*n + for j in 0...n do + biggst = a[ixn+j].abs + nrmrow = biggst if biggst>nrmrow + end + if nrmrow>zero then + scales <<= one.div(nrmrow,prec) + else + raise "Singular matrix" + end + end + n1 = n - 1 + for k in 0...n1 do # Gaussian elimination with partial pivoting. + biggst = zero; + for i in k...n do + size = a[ps[i]*n+k].abs*scales[ps[i]] + if size>biggst then + biggst = size + pividx = i + end + end + raise "Singular matrix" if biggst<=zero + if pividx!=k then + j = ps[k] + ps[k] = ps[pividx] + ps[pividx] = j + end + pivot = a[ps[k]*n+k] + for i in (k+1)...n do + psin = ps[i]*n + a[psin+k] = mult = a[psin+k].div(pivot,prec) + if mult!=zero then + pskn = ps[k]*n + for j in (k+1)...n do + a[psin+j] -= mult.mult(a[pskn+j],prec) + end + end + end + end + raise "Singular matrix" if a[ps[n1]*n+n1] == zero + ps + end + + # Solves a*x = b for x, using LU decomposition. + # + # a is a matrix, b is a constant vector, x is the solution vector. + # + # ps is the pivot, a vector which indicates the permutation of rows performed + # during LU decomposition. + def lusolve(a,b,ps,zero=0.0) + prec = BigDecimal.limit(nil) + n = ps.size + x = [] + for i in 0...n do + dot = zero + psin = ps[i]*n + for j in 0...i do + dot = a[psin+j].mult(x[j],prec) + dot + end + x <<= b[ps[i]] - dot + end + (n-1).downto(0) do |i| + dot = zero + psin = ps[i]*n + for j in (i+1)...n do + dot = a[psin+j].mult(x[j],prec) + dot + end + x[i] = (x[i]-dot).div(a[psin+i],prec) + end + x + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/math.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/math.rb new file mode 100644 index 0000000..1b3357c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/math.rb @@ -0,0 +1,927 @@ +# frozen_string_literal: true +require 'bigdecimal' + +# +#-- +# Contents: +# sqrt(x, prec) +# cbrt(x, prec) +# hypot(x, y, prec) +# sin (x, prec) +# cos (x, prec) +# tan (x, prec) +# asin(x, prec) +# acos(x, prec) +# atan(x, prec) +# atan2(y, x, prec) +# sinh (x, prec) +# cosh (x, prec) +# tanh (x, prec) +# asinh(x, prec) +# acosh(x, prec) +# atanh(x, prec) +# log2 (x, prec) +# log10(x, prec) +# log1p(x, prec) +# expm1(x, prec) +# erf (x, prec) +# erfc(x, prec) +# gamma(x, prec) +# lgamma(x, prec) +# frexp(x) +# ldexp(x, exponent) +# PI (prec) +# E (prec) == exp(1.0,prec) +# +# where: +# x, y ... BigDecimal number to be computed. +# prec ... Number of digits to be obtained. +#++ +# +# Provides mathematical functions. +# +# Example: +# +# require "bigdecimal/math" +# +# include BigMath +# +# a = BigDecimal((PI(49)/2).to_s) +# puts sin(a,100) # => 0.9999999999...9999999986e0 +# +module BigMath + module_function + + # call-seq: + # sqrt(decimal, numeric) -> BigDecimal + # + # Computes the square root of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # BigMath.sqrt(BigDecimal('2'), 32).to_s + # #=> "0.14142135623730950488016887242097e1" + # + def sqrt(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :sqrt) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sqrt) + x.sqrt(prec) + end + + + # Returns [sign, reduced_x] where reduced_x is in -pi/2..pi/2 + # and satisfies sin(x) = sign * sin(reduced_x) + # If add_half_pi is true, adds pi/2 to x before reduction. + # Precision of pi is adjusted to ensure reduced_x has the required precision. + private_class_method def _sin_periodic_reduction(x, prec, add_half_pi: false) # :nodoc: + return [1, x] if -Math::PI/2 <= x && x <= Math::PI/2 && !add_half_pi + + mod_prec = prec + BigDecimal::Internal::EXTRA_PREC + pi_extra_prec = [x.exponent, 0].max + BigDecimal::Internal::EXTRA_PREC + while true + pi = PI(mod_prec + pi_extra_prec) + half_pi = pi / 2 + div, mod = (add_half_pi ? x + pi : x + half_pi).divmod(pi) + mod -= half_pi + if mod.zero? || mod_prec + mod.exponent <= 0 + # mod is too small to estimate required pi precision + mod_prec = mod_prec * 3 / 2 + BigDecimal::Internal::EXTRA_PREC + elsif mod_prec + mod.exponent < prec + # Estimate required precision of pi + mod_prec = prec - mod.exponent + BigDecimal::Internal::EXTRA_PREC + else + return [div % 2 == 0 ? 1 : -1, mod.mult(1, prec)] + end + end + end + + private_class_method def _sin_binary_splitting(x, prec) # :nodoc: + return x if x.zero? + x2 = x.mult(x, prec) + # Find k that satisfies x2**k / (2k+1)! < 10**(-prec) + log10 = Math.log(10) + logx = BigDecimal::Internal.float_log(x.abs) + step = (1..).bsearch { |k| Math.lgamma(2 * k + 1)[0] - 2 * k * logx > prec * log10 } + # Construct denominator sequence for binary splitting + # sin(x) = x*(1-x2/(2*3)*(1-x2/(4*5)*(1-x2/(6*7)*(1-x2/(8*9)*(1-...))))) + ds = (1..step).map {|i| -(2 * i) * (2 * i + 1) } + x.mult(1 + BigDecimal::Internal.taylor_sum_binary_splitting(x2, ds, prec), prec) + end + + private_class_method def _sin_around_zero(x, prec) # :nodoc: + # Divide x into several parts + # sin(x.xxxxxxxx...) = sin(x.xx + 0.00xx + 0.0000xxxx + ...) + # Calculate sin of each part and restore sin(0.xxxxxxxx...) using addition theorem. + sin = BigDecimal(0) + cos = BigDecimal(1) + n = 2 + while x != 0 do + partial_x = x.truncate(n) + x -= partial_x + s = _sin_binary_splitting(partial_x, prec) + c = (1 - s * s).sqrt(prec) + sin, cos = (sin * c).add(cos * s, prec), (cos * c).sub(sin * s, prec) + n *= 2 + end + sin.clamp(BigDecimal(-1), BigDecimal(1)) + end + + # call-seq: + # cbrt(decimal, numeric) -> BigDecimal + # + # Computes the cube root of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # BigMath.cbrt(BigDecimal('2'), 32).to_s + # #=> "0.12599210498948731647672106072782e1" + # + def cbrt(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :cbrt) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :cbrt) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal::Internal.infinity_computation_result * x.infinite? if x.infinite? + return BigDecimal(0) if x.zero? + + x = -x if neg = x < 0 + ex = x.exponent / 3 + x = x._decimal_shift(-3 * ex) + y = BigDecimal(Math.cbrt(x.to_f), 0) + BigDecimal::Internal.newton_loop(prec + BigDecimal::Internal::EXTRA_PREC) do |p| + y = (2 * y + x.div(y, p).div(y, p)).div(3, p) + end + y._decimal_shift(ex).mult(neg ? -1 : 1, prec) + end + + # call-seq: + # hypot(x, y, numeric) -> BigDecimal + # + # Returns sqrt(x**2 + y**2) to the specified number of digits of + # precision, +numeric+. + # + # BigMath.hypot(BigDecimal('1'), BigDecimal('2'), 32).to_s + # #=> "0.22360679774997896964091736687313e1" + # + def hypot(x, y, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :hypot) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :hypot) + y = BigDecimal::Internal.coerce_to_bigdecimal(y, prec, :hypot) + return BigDecimal::Internal.nan_computation_result if x.nan? || y.nan? + return BigDecimal::Internal.infinity_computation_result if x.infinite? || y.infinite? + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + sqrt(x.mult(x, prec2) + y.mult(y, prec2), prec) + end + + # call-seq: + # sin(decimal, numeric) -> BigDecimal + # + # Computes the sine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.sin(BigMath.PI(5)/4, 32).to_s + # #=> "0.70710807985947359435812921837984e0" + # + def sin(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :sin) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sin) + return BigDecimal::Internal.nan_computation_result if x.infinite? || x.nan? + n = prec + BigDecimal::Internal::EXTRA_PREC + sign, x = _sin_periodic_reduction(x, n) + _sin_around_zero(x, n).mult(sign, prec) + end + + # call-seq: + # cos(decimal, numeric) -> BigDecimal + # + # Computes the cosine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.cos(BigMath.PI(16), 32).to_s + # #=> "-0.99999999999999999999999999999997e0" + # + def cos(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :cos) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :cos) + return BigDecimal::Internal.nan_computation_result if x.infinite? || x.nan? + n = prec + BigDecimal::Internal::EXTRA_PREC + sign, x = _sin_periodic_reduction(x, n, add_half_pi: true) + _sin_around_zero(x, n).mult(sign, prec) + end + + # call-seq: + # tan(decimal, numeric) -> BigDecimal + # + # Computes the tangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.tan(BigDecimal("0.0"), 4).to_s + # #=> "0.0" + # + # BigMath.tan(BigMath.PI(24) / 4, 32).to_s + # #=> "0.99999999999999999999999830836025e0" + # + def tan(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :tan) + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + sin(x, prec2).div(cos(x, prec2), prec) + end + + # call-seq: + # asin(decimal, numeric) -> BigDecimal + # + # Computes the arcsine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.asin(BigDecimal('0.5'), 32).to_s + # #=> "0.52359877559829887307710723054658e0" + # + def asin(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :asin) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :asin) + raise Math::DomainError, "Out of domain argument for asin" if x < -1 || x > 1 + return BigDecimal::Internal.nan_computation_result if x.nan? + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + cos = (1 - x**2).sqrt(prec2) + if cos.zero? + PI(prec2).div(x > 0 ? 2 : -2, prec) + else + atan(x.div(cos, prec2), prec) + end + end + + # call-seq: + # acos(decimal, numeric) -> BigDecimal + # + # Computes the arccosine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.acos(BigDecimal('0.5'), 32).to_s + # #=> "0.10471975511965977461542144610932e1" + # + def acos(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :acos) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :acos) + raise Math::DomainError, "Out of domain argument for acos" if x < -1 || x > 1 + return BigDecimal::Internal.nan_computation_result if x.nan? + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + return (PI(prec2) / 2).sub(asin(x, prec2), prec) if x < 0 + return PI(prec2).div(2, prec) if x.zero? + + sin = (1 - x**2).sqrt(prec2) + atan(sin.div(x, prec2), prec) + end + + # call-seq: + # atan(decimal, numeric) -> BigDecimal + # + # Computes the arctangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.atan(BigDecimal('-1'), 32).to_s + # #=> "-0.78539816339744830961566084581988e0" + # + def atan(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :atan) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :atan) + return BigDecimal::Internal.nan_computation_result if x.nan? + n = prec + BigDecimal::Internal::EXTRA_PREC + return PI(n).div(2 * x.infinite?, prec) if x.infinite? + + x = -x if neg = x < 0 + x = BigDecimal(1).div(x, n) if inv = x < -1 || x > 1 + + # Solve tan(y) - x = 0 with Newton's method + # Repeat: y -= (tan(y) - x) * cos(y)**2 + y = BigDecimal(Math.atan(x.to_f), 0) + BigDecimal::Internal.newton_loop(n) do |p| + s = sin(y, p) + c = (1 - s * s).sqrt(p) + y = y.sub(c * (s.sub(c * x.mult(1, p), p)), p) + end + y = PI(n) / 2 - y if inv + y.mult(neg ? -1 : 1, prec) + end + + # call-seq: + # atan2(decimal, decimal, numeric) -> BigDecimal + # + # Computes the arctangent of y and x to the specified number of digits of + # precision, +numeric+. + # + # BigMath.atan2(BigDecimal('-1'), BigDecimal('1'), 32).to_s + # #=> "-0.78539816339744830961566084581988e0" + # + def atan2(y, x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :atan2) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :atan2) + y = BigDecimal::Internal.coerce_to_bigdecimal(y, prec, :atan2) + return BigDecimal::Internal.nan_computation_result if x.nan? || y.nan? + + if x.infinite? || y.infinite? + one = BigDecimal(1) + zero = BigDecimal(0) + x = x.infinite? ? (x > 0 ? one : -one) : zero + y = y.infinite? ? (y > 0 ? one : -one) : y.sign * zero + end + + return x.sign >= 0 ? BigDecimal(0) : y.sign * PI(prec) if y.zero? + + y = -y if neg = y < 0 + xlarge = y.abs < x.abs + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + if x > 0 + v = xlarge ? atan(y.div(x, prec2), prec) : PI(prec2) / 2 - atan(x.div(y, prec2), prec2) + else + v = xlarge ? PI(prec2) - atan(-y.div(x, prec2), prec2) : PI(prec2) / 2 + atan(x.div(-y, prec2), prec2) + end + v.mult(neg ? -1 : 1, prec) + end + + # call-seq: + # sinh(decimal, numeric) -> BigDecimal + # + # Computes the hyperbolic sine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.sinh(BigDecimal('1'), 32).to_s + # #=> "0.11752011936438014568823818505956e1" + # + def sinh(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :sinh) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sinh) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal::Internal.infinity_computation_result * x.infinite? if x.infinite? + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + prec2 -= x.exponent if x.exponent < 0 + e = exp(x, prec2) + (e - BigDecimal(1).div(e, prec2)).div(2, prec) + end + + # call-seq: + # cosh(decimal, numeric) -> BigDecimal + # + # Computes the hyperbolic cosine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.cosh(BigDecimal('1'), 32).to_s + # #=> "0.15430806348152437784779056207571e1" + # + def cosh(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :cosh) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :cosh) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal::Internal.infinity_computation_result if x.infinite? + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + e = exp(x, prec2) + (e + BigDecimal(1).div(e, prec2)).div(2, prec) + end + + # call-seq: + # tanh(decimal, numeric) -> BigDecimal + # + # Computes the hyperbolic tangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.tanh(BigDecimal('1'), 32).to_s + # #=> "0.76159415595576488811945828260479e0" + # + def tanh(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :tanh) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :tanh) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal(x.infinite?) if x.infinite? + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + [-x.exponent, 0].max + e = exp(x, prec2) + einv = BigDecimal(1).div(e, prec2) + (e - einv).div(e + einv, prec) + end + + # call-seq: + # asinh(decimal, numeric) -> BigDecimal + # + # Computes the inverse hyperbolic sine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.asinh(BigDecimal('1'), 32).to_s + # #=> "0.88137358701954302523260932497979e0" + # + def asinh(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :asinh) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :asinh) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal::Internal.infinity_computation_result * x.infinite? if x.infinite? + return -asinh(-x, prec) if x < 0 + + sqrt_prec = prec + [-x.exponent, 0].max + BigDecimal::Internal::EXTRA_PREC + log(x + sqrt(x**2 + 1, sqrt_prec), prec) + end + + # call-seq: + # acosh(decimal, numeric) -> BigDecimal + # + # Computes the inverse hyperbolic cosine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.acosh(BigDecimal('2'), 32).to_s + # #=> "0.1316957896924816708625046347308e1" + # + def acosh(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :acosh) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :acosh) + raise Math::DomainError, "Out of domain argument for acosh" if x < 1 + return BigDecimal::Internal.infinity_computation_result if x.infinite? + return BigDecimal::Internal.nan_computation_result if x.nan? + + log(x + sqrt(x**2 - 1, prec + BigDecimal::Internal::EXTRA_PREC), prec) + end + + # call-seq: + # atanh(decimal, numeric) -> BigDecimal + # + # Computes the inverse hyperbolic tangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.atanh(BigDecimal('0.5'), 32).to_s + # #=> "0.54930614433405484569762261846126e0" + # + def atanh(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :atanh) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :atanh) + raise Math::DomainError, "Out of domain argument for atanh" if x < -1 || x > 1 + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal::Internal.infinity_computation_result if x == 1 + return -BigDecimal::Internal.infinity_computation_result if x == -1 + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + (log(x + 1, prec2) - log(1 - x, prec2)).div(2, prec) + end + + # call-seq: + # BigMath.log2(decimal, numeric) -> BigDecimal + # + # Computes the base 2 logarithm of +decimal+ to the specified number of + # digits of precision, +numeric+. + # + # If +decimal+ is zero or negative, raises Math::DomainError. + # + # If +decimal+ is positive infinity, returns Infinity. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.log2(BigDecimal('3'), 32).to_s + # #=> "0.15849625007211561814537389439478e1" + # + def log2(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :log2) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log2) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal::Internal.infinity_computation_result if x.infinite? == 1 + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC * 3 / 2 + v = log(x, prec2).div(log(BigDecimal(2), prec2), prec2) + # Perform half-up rounding to calculate log2(2**n)==n correctly in every rounding mode + v = v.round(prec + BigDecimal::Internal::EXTRA_PREC - (v.exponent < 0 ? v.exponent : 0), BigDecimal::ROUND_HALF_UP) + v.mult(1, prec) + end + + # call-seq: + # BigMath.log10(decimal, numeric) -> BigDecimal + # + # Computes the base 10 logarithm of +decimal+ to the specified number of + # digits of precision, +numeric+. + # + # If +decimal+ is zero or negative, raises Math::DomainError. + # + # If +decimal+ is positive infinity, returns Infinity. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.log10(BigDecimal('3'), 32).to_s + # #=> "0.47712125471966243729502790325512e0" + # + def log10(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :log10) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log10) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal::Internal.infinity_computation_result if x.infinite? == 1 + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC * 3 / 2 + v = log(x, prec2).div(log(BigDecimal(10), prec2), prec2) + # Perform half-up rounding to calculate log10(10**n)==n correctly in every rounding mode + v = v.round(prec + BigDecimal::Internal::EXTRA_PREC - (v.exponent < 0 ? v.exponent : 0), BigDecimal::ROUND_HALF_UP) + v.mult(1, prec) + end + + # call-seq: + # BigMath.log1p(decimal, numeric) -> BigDecimal + # + # Computes log(1 + decimal) to the specified number of digits of precision, +numeric+. + # + # BigMath.log1p(BigDecimal('0.1'), 32).to_s + # #=> "0.95310179804324860043952123280765e-1" + # + def log1p(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :log1p) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log1p) + raise Math::DomainError, 'Out of domain argument for log1p' if x < -1 + + return log(x + 1, prec) + end + + # call-seq: + # BigMath.expm1(decimal, numeric) -> BigDecimal + # + # Computes exp(decimal) - 1 to the specified number of digits of precision, +numeric+. + # + # BigMath.expm1(BigDecimal('0.1'), 32).to_s + # #=> "0.10517091807564762481170782649025e0" + # + def expm1(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :expm1) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :expm1) + return BigDecimal(-1) if x.infinite? == -1 + + exp_prec = prec + if x < -1 + # log10(exp(x)) = x * log10(e) + lg_e = 0.4342944819032518 + exp_prec = prec + (lg_e * x).ceil + BigDecimal::Internal::EXTRA_PREC + elsif x < 1 + exp_prec = prec - x.exponent + BigDecimal::Internal::EXTRA_PREC + else + exp_prec = prec + end + + return BigDecimal(-1) if exp_prec <= 0 + + exp(x, exp_prec).sub(1, prec) + end + + # call-seq: + # erf(decimal, numeric) -> BigDecimal + # + # Computes the error function of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.erf(BigDecimal('1'), 32).to_s + # #=> "0.84270079294971486934122063508261e0" + # + def erf(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :erf) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :erf) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal(x.infinite?) if x.infinite? + return BigDecimal(0) if x == 0 + return -erf(-x, prec) if x < 0 + return BigDecimal(1) if x > 5000000000 # erf(5000000000) > 1 - 1e-10000000000000000000 + + if x > 8 + xf = x.to_f + log10_erfc = -xf ** 2 / Math.log(10) - Math.log10(xf * Math::PI ** 0.5) + erfc_prec = [prec + log10_erfc.ceil, 1].max + erfc = _erfc_asymptotic(x, erfc_prec) + return BigDecimal(1).sub(erfc, prec) if erfc + end + + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + x_smallprec = x.mult(1, Integer.sqrt(prec2) / 2) + # Taylor series of x with small precision is fast + erf1 = _erf_taylor(x_smallprec, BigDecimal(0), BigDecimal(0), prec2) + # Taylor series converges quickly for small x + _erf_taylor(x - x_smallprec, x_smallprec, erf1, prec2).mult(1, prec) + end + + # call-seq: + # erfc(decimal, numeric) -> BigDecimal + # + # Computes the complementary error function of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.erfc(BigDecimal('10'), 32).to_s + # #=> "0.20884875837625447570007862949578e-44" + # + def erfc(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :erfc) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :erfc) + return BigDecimal::Internal.nan_computation_result if x.nan? + return BigDecimal(1 - x.infinite?) if x.infinite? + return BigDecimal(1).sub(erf(x, prec + BigDecimal::Internal::EXTRA_PREC), prec) if x < 0.5 + return BigDecimal::Internal.underflow_computation_result if x > 5000000000 # erfc(5000000000) < 1e-10000000000000000000 (underflow) + + if x >= 8 + y = _erfc_asymptotic(x, prec) + return y.mult(1, prec) if y + end + + # erfc(x) = 1 - erf(x) < exp(-x**2)/x/sqrt(pi) + # Precision of erf(x) needs about log10(exp(-x**2)/x/sqrt(pi)) extra digits + log10 = 2.302585092994046 + xf = x.to_f + high_prec = prec + BigDecimal::Internal::EXTRA_PREC + ((xf**2 + Math.log(xf) + Math.log(Math::PI)/2) / log10).ceil + BigDecimal(1).sub(erf(x, high_prec), prec) + end + + # Calculates erf(x + a) + private_class_method def _erf_taylor(x, a, erf_a, prec) # :nodoc: + return erf_a if x.zero? + # Let f(x+a) = erf(x+a)*exp((x+a)**2)*sqrt(pi)/2 + # = c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + ... + # f'(x+a) = 1+2*(x+a)*f(x+a) + # f'(x+a) = c1 + 2*c2*x + 3*c3*x**2 + 4*c4*x**3 + 5*c5*x**4 + ... + # = 1+2*(x+a)*(c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + ...) + # therefore, + # c0 = f(a) + # c1 = 2 * a * c0 + 1 + # c2 = (2 * c0 + 2 * a * c1) / 2 + # c3 = (2 * c1 + 2 * a * c2) / 3 + # c4 = (2 * c2 + 2 * a * c3) / 4 + # + # All coefficients are positive when a >= 0 + + scale = BigDecimal(2).div(sqrt(PI(prec), prec), prec) + c_prev = erf_a.div(scale.mult(exp(-a*a, prec), prec), prec) + c_next = (2 * a * c_prev).add(1, prec).mult(x, prec) + sum = c_prev.add(c_next, prec) + + 2.step do |k| + cn = (c_prev.mult(x, prec) + a * c_next).mult(2, prec).mult(x, prec).div(k, prec) + sum = sum.add(cn, prec) + c_prev, c_next = c_next, cn + break if [c_prev, c_next].all? { |c| c.zero? || (c.exponent < sum.exponent - prec) } + end + value = sum.mult(scale.mult(exp(-(x + a).mult(x + a, prec), prec), prec), prec) + value > 1 ? BigDecimal(1) : value + end + + private_class_method def _erfc_asymptotic(x, prec) # :nodoc: + # Let f(x) = erfc(x)*sqrt(pi)*exp(x**2)/2 + # f(x) satisfies the following differential equation: + # 2*x*f(x) = f'(x) + 1 + # From the above equation, we can derive the following asymptotic expansion: + # f(x) = (0..kmax).sum { (-1)**k * (2*k)! / 4**k / k! / x**(2*k)) } / x + + # This asymptotic expansion does not converge. + # But if there is a k that satisfies (2*k)! / 4**k / k! / x**(2*k) < 10**(-prec), + # It is enough to calculate erfc within the given precision. + # Using Stirling's approximation, we can simplify this condition to: + # sqrt(2)/2 + k*log(k) - k - 2*k*log(x) < -prec*log(10) + # and the left side is minimized when k = x**2. + prec += BigDecimal::Internal::EXTRA_PREC + xf = x.to_f + kmax = (1..(xf ** 2).floor).bsearch do |k| + Math.log(2) / 2 + k * Math.log(k) - k - 2 * k * Math.log(xf) < -prec * Math.log(10) + end + return unless kmax + + sum = BigDecimal(1) + # To calculate `exp(x2, prec)`, x2 needs extra log10(x**2) digits of precision + x2 = x.mult(x, prec + (2 * Math.log10(xf)).ceil) + d = BigDecimal(1) + (1..kmax).each do |k| + d = d.div(x2, prec).mult(1 - 2 * k, prec).div(2, prec) + sum = sum.add(d, prec) + end + sum.div(exp(x2, prec).mult(PI(prec).sqrt(prec), prec), prec).div(x, prec) + end + + # call-seq: + # BigMath.gamma(decimal, numeric) -> BigDecimal + # + # Computes the gamma function of +decimal+ to the specified number of + # digits of precision, +numeric+. + # + # BigMath.gamma(BigDecimal('0.5'), 32).to_s + # #=> "0.17724538509055160272981674833411e1" + # + def gamma(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :gamma) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :gamma) + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + if x < 0.5 + raise Math::DomainError, 'Numerical argument is out of domain - gamma' if x.frac.zero? + + # Euler's reflection formula: gamma(z) * gamma(1-z) = pi/sin(pi*z) + pi = PI(prec2) + sin = _sinpix(x, pi, prec2) + return pi.div(gamma(1 - x, prec2).mult(sin, prec2), prec) + elsif x.frac.zero? && x < 1000 * prec + return _gamma_positive_integer(x, prec2).mult(1, prec) + end + + a, sum = _gamma_spouge_sum_part(x, prec2) + (x + (a - 1)).power(x - 0.5, prec2).mult(BigMath.exp(1 - x, prec2), prec2).mult(sum, prec) + end + + # call-seq: + # BigMath.lgamma(decimal, numeric) -> [BigDecimal, Integer] + # + # Computes the natural logarithm of the absolute value of the gamma function + # of +decimal+ to the specified number of digits of precision, +numeric+ and its sign. + # + # BigMath.lgamma(BigDecimal('0.5'), 32) + # #=> [0.57236494292470008707171367567653e0, 1] + # + def lgamma(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :lgamma) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :lgamma) + prec2 = prec + BigDecimal::Internal::EXTRA_PREC + if x < 0.5 + return [BigDecimal::INFINITY, 1] if x.frac.zero? + + loop do + # Euler's reflection formula: gamma(z) * gamma(1-z) = pi/sin(pi*z) + pi = PI(prec2) + sin = _sinpix(x, pi, prec2) + log_gamma = BigMath.log(pi, prec2).sub(lgamma(1 - x, prec2).first + BigMath.log(sin.abs, prec2), prec) + return [log_gamma, sin > 0 ? 1 : -1] if prec2 + log_gamma.exponent > prec + BigDecimal::Internal::EXTRA_PREC + + # Retry with higher precision if loss of significance is too large + prec2 = prec2 * 3 / 2 + end + elsif x.frac.zero? && x < 1000 * prec + log_gamma = BigMath.log(_gamma_positive_integer(x, prec2), prec) + [log_gamma, 1] + else + # if x is close to 1 or 2, increase precision to reduce loss of significance + diff1_exponent = (x - 1).exponent + diff2_exponent = (x - 2).exponent + extremely_near_one = diff1_exponent < -prec2 + extremely_near_two = diff2_exponent < -prec2 + + if extremely_near_one || extremely_near_two + # If x is extreamely close to base = 1 or 2, linear interpolation is accurate enough. + # Taylor expansion at x = base is: (x - base) * digamma(base) + (x - base) ** 2 * trigamma(base) / 2 + ... + # And we can ignore (x - base) ** 2 and higher order terms. + base = extremely_near_one ? 1 : 2 + d = BigDecimal(1)._decimal_shift(1 - prec2) + log_gamma_d, sign = lgamma(base + d, prec2) + return [log_gamma_d.mult(x - base, prec2).div(d, prec), sign] + end + + prec2 += [-diff1_exponent, -diff2_exponent, 0].max + a, sum = _gamma_spouge_sum_part(x, prec2) + log_gamma = BigMath.log(sum, prec2).add((x - 0.5).mult(BigMath.log(x.add(a - 1, prec2), prec2), prec2) + 1 - x, prec) + [log_gamma, 1] + end + end + + # Returns sum part: sqrt(2*pi) and c[k]/(x+k) terms of Spouge's approximation + private_class_method def _gamma_spouge_sum_part(x, prec) # :nodoc: + x -= 1 + # Spouge's approximation + # x! = (x + a)**(x + 0.5) * exp(-x - a) * (sqrt(2 * pi) + (1..a - 1).sum{|k| c[k] / (x + k) } + epsilon) + # where c[k] = (-1)**k * (a - k)**(k - 0.5) * exp(a - k) / (k - 1)! + # and epsilon is bounded by a**(-0.5) * (2 * pi) ** (-a - 0.5) + + # Estimate required a for given precision + a = (prec / Math.log10(2 * Math::PI)).ceil + + # Calculate exponent of c[k] in low precision to estimate required precision + low_prec = 16 + log10f = Math.log(10) + x_low_prec = x.mult(1, low_prec) + loggamma_k = 0 + ck_exponents = (1..a-1).map do |k| + loggamma_k += Math.log10(k - 1) if k > 1 + -loggamma_k - k / log10f + (k - 0.5) * Math.log10(a - k) - BigDecimal::Internal.float_log(x_low_prec.add(k, low_prec)) / log10f + end + + # Estimate exponent of sum by Stirling's approximation + approx_sum_exponent = x < 1 ? -Math.log10(a) / 2 : Math.log10(2 * Math::PI) / 2 + x_low_prec.add(0.5, low_prec) * Math.log10(x_low_prec / x_low_prec.add(a, low_prec)) + + # Determine required precision of c[k] + prec2 = [ck_exponents.max.ceil - approx_sum_exponent.floor, 0].max + prec + + einv = BigMath.exp(-1, prec2) + sum = (PI(prec) * 2).sqrt(prec).mult(BigMath.exp(-a, prec), prec) + y = BigDecimal(1) + (1..a - 1).each do |k| + # c[k] = (-1)**k * (a - k)**(k - 0.5) * exp(-k) / (k-1)! / (x + k) + y = y.div(1 - k, prec2) if k > 1 + y = y.mult(einv, prec2) + z = y.mult(BigDecimal((a - k) ** k), prec2).div(BigDecimal(a - k).sqrt(prec2).mult(x.add(k, prec2), prec2), prec2) + # sum += c[k] / (x + k) + sum = sum.add(z, prec2) + end + [a, sum] + end + + private_class_method def _gamma_positive_integer(x, prec) # :nodoc: + return x if x == 1 + numbers = (1..x - 1).map {|i| BigDecimal(i) } + while numbers.size > 1 + numbers = numbers.each_slice(2).map {|a, b| b ? a.mult(b, prec) : a } + end + numbers.first + end + + # Returns sin(pi * x), for gamma reflection formula calculation + private_class_method def _sinpix(x, pi, prec) # :nodoc: + x = x % 2 + sign = x > 1 ? -1 : 1 + x %= 1 + x = 1 - x if x > 0.5 # to avoid sin(pi*x) loss of precision for x close to 1 + sign * sin(x.mult(pi, prec), prec) + end + + # call-seq: + # frexp(x) -> [BigDecimal, Integer] + # + # Decomposes +x+ into a normalized fraction and an integral power of ten. + # + # BigMath.frexp(BigDecimal(123.456)) + # #=> [0.123456e0, 3] + # + def frexp(x) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, 0, :frexp) + return [x, 0] unless x.finite? + + exponent = x.exponent + [x._decimal_shift(-exponent), exponent] + end + + # call-seq: + # ldexp(fraction, exponent) -> BigDecimal + # + # Inverse of +frexp+. + # Returns the value of fraction * 10**exponent. + # + # BigMath.ldexp(BigDecimal("0.123456e0"), 3) + # #=> 0.123456e3 + # + def ldexp(x, exponent) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, 0, :ldexp) + x.finite? ? x._decimal_shift(exponent) : x + end + + # call-seq: + # PI(numeric) -> BigDecimal + # + # Computes the value of pi to the specified number of digits of precision, + # +numeric+. + # + # BigMath.PI(32).to_s + # #=> "0.31415926535897932384626433832795e1" + # + def PI(prec) + # Gauss–Legendre algorithm + prec = BigDecimal::Internal.coerce_validate_prec(prec, :PI) + n = prec + BigDecimal::Internal::EXTRA_PREC + a = BigDecimal(1) + b = BigDecimal(0.5, 0).sqrt(n) + s = BigDecimal(0.25, 0) + t = 1 + while a != b && (a - b).exponent > 1 - n + c = (a - b).div(2, n) + a, b = (a + b).div(2, n), (a * b).sqrt(n) + s = s.sub(c * c * t, n) + t *= 2 + end + (a * b).div(s, prec) + end + + # call-seq: + # E(numeric) -> BigDecimal + # + # Computes e (the base of natural logarithms) to the specified number of + # digits of precision, +numeric+. + # + # BigMath.E(32).to_s + # #=> "0.27182818284590452353602874713527e1" + # + def E(prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :E) + exp(1, prec) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/newton.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/newton.rb new file mode 100644 index 0000000..bb70d47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/newton.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: false +require "bigdecimal/ludcmp" +require "bigdecimal/jacobian" + +warn "'bigdecimal/newton' is deprecated and will be removed in a future release." + +# +# newton.rb +# +# Solves the nonlinear algebraic equation system f = 0 by Newton's method. +# This program is not dependent on BigDecimal. +# +# To call: +# n = nlsolve(f,x) +# where n is the number of iterations required, +# x is the initial value vector +# f is an Object which is used to compute the values of the equations to be solved. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# On exit, x is the solution vector. +# +module Newton + include LUSolve + include Jacobian + module_function + + def norm(fv,zero=0.0) # :nodoc: + s = zero + n = fv.size + for i in 0...n do + s += fv[i]*fv[i] + end + s + end + + # See also Newton + def nlsolve(f,x) + nRetry = 0 + n = x.size + + f0 = f.values(x) + zero = f.zero + one = f.one + two = f.two + p5 = one/two + d = norm(f0,zero) + minfact = f.ten*f.ten*f.ten + minfact = one/minfact + e = f.eps + while d >= e do + nRetry += 1 + # Not yet converged. => Compute Jacobian matrix + dfdx = jacobian(f,f0,x) + # Solve dfdx*dx = -f0 to estimate dx + dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero) + fact = two + xs = x.dup + begin + fact *= p5 + if fact < minfact then + raise "Failed to reduce function values." + end + for i in 0...n do + x[i] = xs[i] - dx[i]*fact + end + f0 = f.values(x) + dn = norm(f0,zero) + end while(dn>=d) + d = dn + end + nRetry + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/util.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/util.rb new file mode 100644 index 0000000..7f2232d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/lib/bigdecimal/util.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: true +# +#-- +# bigdecimal/util extends various native classes to provide the #to_d method, +# and provides BigDecimal#to_d and BigDecimal#to_digits. +#++ + +require 'bigdecimal' + +class Integer < Numeric + # call-seq: + # int.to_d -> bigdecimal + # + # Returns the value of +int+ as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 42.to_d # => 0.42e2 + # + # See also Kernel.BigDecimal. + # + def to_d + BigDecimal(self) + end +end + + +class Float < Numeric + # call-seq: + # float.to_d -> bigdecimal + # float.to_d(precision) -> bigdecimal + # + # Returns the value of +float+ as a BigDecimal. + # The +precision+ parameter is used to determine the number of + # significant digits for the result. When +precision+ is set to +0+, + # the number of digits to represent the float being converted is determined + # automatically. + # The default +precision+ is +0+. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 0.5.to_d # => 0.5e0 + # 1.234.to_d # => 0.1234e1 + # 1.234.to_d(2) # => 0.12e1 + # + # See also Kernel.BigDecimal. + # + def to_d(precision=0) + BigDecimal(self, precision) + end +end + + +class String + # call-seq: + # str.to_d -> bigdecimal + # + # Returns the result of interpreting leading characters in +str+ + # as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # "0.5".to_d # => 0.5e0 + # "123.45e1".to_d # => 0.12345e4 + # "45.67 degrees".to_d # => 0.4567e2 + # + # See also Kernel.BigDecimal. + # + def to_d + BigDecimal.interpret_loosely(self) + end +end + + +class BigDecimal < Numeric + # call-seq: + # a.to_digits -> string + # + # Converts a BigDecimal to a String of the form "nnnnnn.mmm". + # This method is deprecated; use BigDecimal#to_s("F") instead. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_digits # => "3.14" + # + def to_digits + if self.nan? || self.infinite? || self.zero? + self.to_s + else + i = self.to_i.to_s + _,f,_,z = self.frac.split + i + "." + ("0"*(-z)) + f + end + end + + # call-seq: + # a.to_d -> bigdecimal + # + # Returns self. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_d # => 0.314e1 + # + def to_d + self + end +end + + +class Rational < Numeric + # call-seq: + # rat.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # + # The +precision+ parameter is used to determine the number of + # significant digits for the result. When +precision+ is set to +0+, + # the number of digits to represent the float being converted is determined + # automatically. + # The default +precision+ is +0+. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Rational(22, 7).to_d(3) # => 0.314e1 + # + # See also Kernel.BigDecimal. + # + def to_d(precision=0) + BigDecimal(self, precision) + end +end + + +class Complex < Numeric + # call-seq: + # cmp.to_d -> bigdecimal + # cmp.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # If the imaginary part is not +0+, an error is raised + # + # The +precision+ parameter is used to determine the number of + # significant digits for the result. When +precision+ is set to +0+, + # the number of digits to represent the float being converted is determined + # automatically. + # The default +precision+ is +0+. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Complex(0.1234567, 0).to_d(4) # => 0.1235e0 + # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1 + # Complex(1, 1).to_d # raises ArgumentError + # + # See also Kernel.BigDecimal. + # + def to_d(precision=0) + BigDecimal(self) unless self.imag.zero? # to raise error + + BigDecimal(self.real, precision) + end +end + + +class NilClass + # call-seq: + # nil.to_d -> bigdecimal + # + # Returns nil represented as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # nil.to_d # => 0.0 + # + def to_d + BigDecimal(0) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/linear.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/linear.rb new file mode 100644 index 0000000..0cfac03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/linear.rb @@ -0,0 +1,110 @@ +# +# linear.rb +# +# Solves linear equation system(A*x = b) by LU decomposition method. +# where A is a coefficient matrix,x is an answer vector,b is a constant vector. +# +# USAGE: +# ruby linear.rb [input file solved] +# + +# :stopdoc: +require "bigdecimal" + +# Requires gem matrix +require "matrix" + +class PrecisionSpecifiedValue + # NOTE: + # Change following PREC if needed. + + attr_reader :value + def initialize(value, prec) + @value = BigDecimal(value) + @prec = prec + end + + def unwrap(value) + PrecisionSpecifiedValue === value ? value.value : value + end + + def coerce(other) + [self.class.new(unwrap(other), @prec), self] + end + + def abs + self.class.new(@value.abs, @prec) + end + + def >(other) + @value > unwrap(other) + end + + def <(other) + @value < unwrap(other) + end + + def -(other) + self.class.new(@value.sub(unwrap(other), @prec), @prec) + end + + def +(other) + self.class.new(@value.add(unwrap(other), @prec), @prec) + end + + def *(other) + self.class.new(@value.mult(unwrap(other), @prec), @prec) + end + + def quo(other) + self.class.new(@value.div(unwrap(other), @prec), @prec) + end +end + +return if __FILE__ != $0 + +def rd_order(na) + printf("Number of equations ?") if(na <= 0) + ARGF.gets().to_i +end + +na = ARGV.size + +while (n=rd_order(na))>0 + a = [] + b = [] + if na <= 0 + # Read data from console. + printf("\nEnter coefficient matrix element A[i,j]\n") + for i in 0...n do + a << n.times.map do |j| + printf("A[%d,%d]? ",i,j); s = ARGF.gets + BigDecimal(s) + end + printf("Contatant vector element b[%d] ? ",i) + b << BigDecimal(ARGF.gets) + end + else + # Read data from specified file. + printf("Coefficient matrix and constant vector.\n") + for i in 0...n do + s = ARGF.gets + printf("%d) %s",i,s) + s = s.split + a << n.times.map {|j| BigDecimal(s[j]) } + b << BigDecimal(s[n]) + end + end + + prec = 100 + matrix = Matrix[*a.map {|row| row.map {|v| PrecisionSpecifiedValue.new(v, prec) } }] + vector = b.map {|v| PrecisionSpecifiedValue.new(v, prec) } + x = matrix.lup.solve(vector).map(&:value) + + printf("Answer(x[i] & (A*x-b)[i]) follows\n") + for i in 0...n do + printf("x[%d]=%s ",i,x[i].to_s) + diff = a[i].zip(x).sum {|aij, xj| aij*xj }.sub(b[i], 10) + printf(" & %s\n", diff.to_s) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/nlsolve.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/nlsolve.rb new file mode 100644 index 0000000..7953653 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/nlsolve.rb @@ -0,0 +1,57 @@ +# +# nlsolve.rb +# An example for solving nonlinear algebraic equation system. +# + +require "bigdecimal" +require_relative "linear" + +# Requires gem matrix +require "matrix" + +# :stopdoc: + +def func((x, y)) # defines functions solved + [ + x**2 + y**2 - 2, + (x - 1)**2 + (y + 1)**2 - 3 + ] +end + +def jacobian(x, f, delta, prec) + dim = x.size + dim.times.map do |i| + xplus = Array.new(dim) {|j| x[i] + (j == i ? delta : 0) } + xminus = Array.new(dim) {|j| x[i] - (j == i ? delta : 0) } + yplus = f.call(xplus) + yminus = f.call(xminus) + yplus.zip(yminus).map {|p, m| (p - m).div(2 * delta, prec) } + end.transpose +end + +def nlsolve(initial_x, prec:, max_iteration: 100, &f) + initial_x = initial_x.map {|v| BigDecimal(v) } + x = initial_x + delta = BigDecimal(0.01) + calc_prec = prec + 10 + max_iteration.times do |iteration| + # Newton step + jacobian = jacobian(x, f, delta, calc_prec) + matrix = Matrix[*jacobian.map {|row| row.map {|v| PrecisionSpecifiedValue.new(v, calc_prec) } }] + y = f.call(x) + vector = y.map {|v| PrecisionSpecifiedValue.new(v, calc_prec) } + dx = matrix.lup.solve(vector).map(&:value) + x_prev = x + x = x.zip(dx).map {|xi, di| xi.sub(di, prec) } + movement = x_prev.zip(x).map {|xn, xi| (xn - xi).abs }.max + delta = [movement, delta].min.mult(1, 10) + break if movement.zero? || movement.exponent < -prec + end + x +end + +initial_value = [1, 1] +ans = nlsolve(initial_value, prec: 100) {|x| func(x) } +diff = func(ans).map {|v| v.mult(1, 10) } +p(ans:) +p(diff:) diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/pi.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/pi.rb new file mode 100644 index 0000000..4b17ed0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sample/pi.rb @@ -0,0 +1,16 @@ +# +# pi.rb +# +# Calculates 3.1415.... (the number of times that a circle's diameter +# will fit around the circle) +# + +require "bigdecimal" +require "bigdecimal/math.rb" + +if ARGV.size == 1 + print "PI("+ARGV[0]+"):\n" + p BigMath.PI(ARGV[0].to_i) +else + print "TRY: ruby pi.rb 1000 \n" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal.rbs b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal.rbs new file mode 100644 index 0000000..a0d0e80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal.rbs @@ -0,0 +1,1502 @@ +class BigDecimal < Numeric + # BigDecimal::ROUND_MODE + type round_mode = 256 + type round_mode_integer = 1 | 2 | 3 | 4 | 5 | 6 | 7 + type round_mode_symbol = :up | :down | :half_up | :half_down | :half_even | :ceiling | :floor | :truncate | :banker | :default + + # + # Internal method used to provide marshalling support. See the Marshal module. + # + def self._load: (String) -> BigDecimal + + # + # Returns the number of digits a Float object is allowed to have; the result is + # system-dependent: + # + # BigDecimal.double_fig # => 16 + # + def self.double_fig: () -> Integer + + # + # + def self.interpret_loosely: (string) -> BigDecimal + + # + # Limit the number of significant digits in newly created BigDecimal numbers to + # the specified value. Rounding is performed as necessary, as specified by + # BigDecimal.mode. + # + # A limit of 0, the default, means no upper limit. + # + # The limit specified by this method takes less priority over any limit + # specified to instance methods such as ceil, floor, truncate, or round. + # + def self.limit: (?Integer? digits) -> Integer + + # + # Returns an integer representing the mode settings for exception handling and + # rounding. + # + # These modes control exception handling: + # + # * BigDecimal::EXCEPTION_NaN. + # * BigDecimal::EXCEPTION_INFINITY. + # * BigDecimal::EXCEPTION_UNDERFLOW. + # * BigDecimal::EXCEPTION_OVERFLOW. + # * BigDecimal::EXCEPTION_ZERODIVIDE. + # * BigDecimal::EXCEPTION_ALL. + # + # Values for `setting` for exception handling: + # + # * `true`: sets the given `mode` to `true`. + # * `false`: sets the given `mode` to `false`. + # * `nil`: does not modify the mode settings. + # + # You can use method BigDecimal.save_exception_mode to temporarily change, and + # then automatically restore, exception modes. + # + # For clarity, some examples below begin by setting all exception modes to + # `false`. + # + # This mode controls the way rounding is to be performed: + # + # * BigDecimal::ROUND_MODE + # + # You can use method BigDecimal.save_rounding_mode to temporarily change, and + # then automatically restore, the rounding mode. + # + # **NaNs** + # + # Mode BigDecimal::EXCEPTION_NaN controls behavior when a BigDecimal NaN is + # created. + # + # Settings: + # + # * `false` (default): Returns `BigDecimal('NaN')`. + # * `true`: Raises FloatDomainError. + # + # Examples: + # + # BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + # BigDecimal('NaN') # => NaN + # BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true) # => 2 + # BigDecimal('NaN') # Raises FloatDomainError + # + # **Infinities** + # + # Mode BigDecimal::EXCEPTION_INFINITY controls behavior when a BigDecimal + # Infinity or -Infinity is created. Settings: + # + # * `false` (default): Returns `BigDecimal('Infinity')` or + # `BigDecimal('-Infinity')`. + # * `true`: Raises FloatDomainError. + # + # Examples: + # + # BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + # BigDecimal('Infinity') # => Infinity + # BigDecimal('-Infinity') # => -Infinity + # BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true) # => 1 + # BigDecimal('Infinity') # Raises FloatDomainError + # BigDecimal('-Infinity') # Raises FloatDomainError + # + # **Underflow** + # + # Mode BigDecimal::EXCEPTION_UNDERFLOW controls behavior when a BigDecimal + # underflow occurs. Settings: + # + # * `false` (default): Returns `BigDecimal('0')` or `BigDecimal('-Infinity')`. + # * `true`: Raises FloatDomainError. + # + # Examples: + # + # BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + # def flow_under + # x = BigDecimal('0.1') + # 100.times { x *= x } + # end + # flow_under # => 100 + # BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true) # => 4 + # flow_under # Raises FloatDomainError + # + # **Overflow** + # + # Mode BigDecimal::EXCEPTION_OVERFLOW controls behavior when a BigDecimal + # overflow occurs. Settings: + # + # * `false` (default): Returns `BigDecimal('Infinity')` or + # `BigDecimal('-Infinity')`. + # * `true`: Raises FloatDomainError. + # + # Examples: + # + # BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + # def flow_over + # x = BigDecimal('10') + # 100.times { x *= x } + # end + # flow_over # => 100 + # BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true) # => 1 + # flow_over # Raises FloatDomainError + # + # **Zero Division** + # + # Mode BigDecimal::EXCEPTION_ZERODIVIDE controls behavior when a zero-division + # occurs. Settings: + # + # * `false` (default): Returns `BigDecimal('Infinity')` or + # `BigDecimal('-Infinity')`. + # * `true`: Raises FloatDomainError. + # + # Examples: + # + # BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + # one = BigDecimal('1') + # zero = BigDecimal('0') + # one / zero # => Infinity + # BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, true) # => 16 + # one / zero # Raises FloatDomainError + # + # **All Exceptions** + # + # Mode BigDecimal::EXCEPTION_ALL controls all of the above: + # + # BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + # BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true) # => 23 + # + # **Rounding** + # + # Mode BigDecimal::ROUND_MODE controls the way rounding is to be performed; its + # `setting` values are: + # + # * `ROUND_UP`: Round away from zero. Aliased as `:up`. + # * `ROUND_DOWN`: Round toward zero. Aliased as `:down` and `:truncate`. + # * `ROUND_HALF_UP`: Round toward the nearest neighbor; if the neighbors are + # equidistant, round away from zero. Aliased as `:half_up` and `:default`. + # * `ROUND_HALF_DOWN`: Round toward the nearest neighbor; if the neighbors are + # equidistant, round toward zero. Aliased as `:half_down`. + # * `ROUND_HALF_EVEN` (Banker's rounding): Round toward the nearest neighbor; + # if the neighbors are equidistant, round toward the even neighbor. Aliased + # as `:half_even` and `:banker`. + # * `ROUND_CEILING`: Round toward positive infinity. Aliased as `:ceiling` and + # `:ceil`. + # * `ROUND_FLOOR`: Round toward negative infinity. Aliased as `:floor:`. + # + def self.mode: (round_mode, ?(round_mode_integer | round_mode_symbol)) -> Integer + | (Integer exception_mode, ?bool? setting) -> Integer + + # + # Execute the provided block, but preserve the exception mode + # + # BigDecimal.save_exception_mode do + # BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) + # BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) + # + # BigDecimal(BigDecimal('Infinity')) + # BigDecimal(BigDecimal('-Infinity')) + # BigDecimal(BigDecimal('NaN')) + # end + # + # For use with the BigDecimal::EXCEPTION_* + # + # See BigDecimal.mode + # + def self.save_exception_mode: () { (?nil) -> void } -> void + + # + # Execute the provided block, but preserve the precision limit + # + # BigDecimal.limit(100) + # puts BigDecimal.limit + # BigDecimal.save_limit do + # BigDecimal.limit(200) + # puts BigDecimal.limit + # end + # puts BigDecimal.limit + # + def self.save_limit: () { (?nil) -> void } -> void + + # + # Execute the provided block, but preserve the rounding mode + # + # BigDecimal.save_rounding_mode do + # BigDecimal.mode(BigDecimal::ROUND_MODE, :up) + # puts BigDecimal.mode(BigDecimal::ROUND_MODE) + # end + # + # For use with the BigDecimal::ROUND_* + # + # See BigDecimal.mode + # + def self.save_rounding_mode: () { (?nil) -> void } -> void + + # + # Returns the modulus from dividing by b. + # + # See BigDecimal#divmod. + # + def %: (real | BigDecimal) -> BigDecimal + + # + # + def *: (real | BigDecimal) -> BigDecimal + | (Complex) -> Complex + + # + # Returns the BigDecimal value of `self` raised to power `other`: + # + # b = BigDecimal('3.14') + # b ** 2 # => 0.98596e1 + # b ** 2.0 # => 0.98596e1 + # b ** Rational(2, 1) # => 0.98596e1 + # + # Related: BigDecimal#power. + # + def **: (real | BigDecimal) -> BigDecimal + | (Complex) -> Complex + + # + # Returns the BigDecimal sum of `self` and `value`: + # + # b = BigDecimal('111111.111') # => 0.111111111e6 + # b + 2 # => 0.111113111e6 + # b + 2.0 # => 0.111113111e6 + # b + Rational(2, 1) # => 0.111113111e6 + # b + Complex(2, 0) # => (0.111113111e6+0i) + # + # See the [Note About + # Precision](BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision). + # + def +: (real | BigDecimal) -> BigDecimal + | (Complex) -> Complex + + # + # Returns `self`: + # + # +BigDecimal(5) # => 0.5e1 + # +BigDecimal(-5) # => -0.5e1 + # + def +@: () -> BigDecimal + + # + # Returns the BigDecimal difference of `self` and `value`: + # + # b = BigDecimal('333333.333') # => 0.333333333e6 + # b - 2 # => 0.333331333e6 + # b - 2.0 # => 0.333331333e6 + # b - Rational(2, 1) # => 0.333331333e6 + # b - Complex(2, 0) # => (0.333331333e6+0i) + # + # See the [Note About + # Precision](BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision). + # + def -: (real | BigDecimal) -> BigDecimal + | (Complex) -> Complex + + # + # Returns the BigDecimal negation of self: + # + # b0 = BigDecimal('1.5') + # b1 = -b0 # => -0.15e1 + # b2 = -b1 # => 0.15e1 + # + def -@: () -> BigDecimal + + # + # Divide by the specified value. + # + # The result precision will be the precision of the larger operand, but its + # minimum is 2*Float::DIG. + # + # See BigDecimal#div. See BigDecimal#quo. + # + def /: (real | BigDecimal) -> BigDecimal + | (Complex) -> Complex + + # + # Returns `true` if `self` is less than `other`, `false` otherwise: + # + # b = BigDecimal('1.5') # => 0.15e1 + # b < 2 # => true + # b < 2.0 # => true + # b < Rational(2, 1) # => true + # b < 1.5 # => false + # + # Raises an exception if the comparison cannot be made. + # + def <: (real | BigDecimal) -> bool + + # + # Returns `true` if `self` is less or equal to than `other`, `false` otherwise: + # + # b = BigDecimal('1.5') # => 0.15e1 + # b <= 2 # => true + # b <= 2.0 # => true + # b <= Rational(2, 1) # => true + # b <= 1.5 # => true + # b < 1 # => false + # + # Raises an exception if the comparison cannot be made. + # + def <=: (real | BigDecimal) -> bool + + # + # The comparison operator. a <=> b is 0 if a == b, 1 if a > b, -1 if a < b. + # + def <=>: (untyped) -> Integer? + + # + # Tests for value equality; returns true if the values are equal. + # + # The == and === operators and the eql? method have the same implementation for + # BigDecimal. + # + # Values may be coerced to perform the comparison: + # + # BigDecimal('1.0') == 1.0 #=> true + # + def ==: (untyped) -> bool + + # + # Tests for value equality; returns true if the values are equal. + # + # The == and === operators and the eql? method have the same implementation for + # BigDecimal. + # + # Values may be coerced to perform the comparison: + # + # BigDecimal('1.0') == 1.0 #=> true + # + def ===: (untyped) -> bool + + # + # Returns `true` if `self` is greater than `other`, `false` otherwise: + # + # b = BigDecimal('1.5') + # b > 1 # => true + # b > 1.0 # => true + # b > Rational(1, 1) # => true + # b > 2 # => false + # + # Raises an exception if the comparison cannot be made. + # + def >: (real | BigDecimal) -> bool + + # + # Returns `true` if `self` is greater than or equal to `other`, `false` + # otherwise: + # + # b = BigDecimal('1.5') + # b >= 1 # => true + # b >= 1.0 # => true + # b >= Rational(1, 1) # => true + # b >= 1.5 # => true + # b > 2 # => false + # + # Raises an exception if the comparison cannot be made. + # + def >=: (real | BigDecimal) -> bool + + # + # Returns a string representing the marshalling of `self`. See module Marshal. + # + # inf = BigDecimal('Infinity') # => Infinity + # dumped = inf._dump # => "9:Infinity" + # BigDecimal._load(dumped) # => Infinity + # + def _dump: (?untyped) -> String + + # + # Returns the BigDecimal absolute value of `self`: + # + # BigDecimal('5').abs # => 0.5e1 + # BigDecimal('-3').abs # => 0.3e1 + # + def abs: () -> BigDecimal + + # + # Returns the BigDecimal sum of `self` and `value` with a precision of `ndigits` + # decimal digits. + # + # When `ndigits` is less than the number of significant digits in the sum, the + # sum is rounded to that number of digits, according to the current rounding + # mode; see BigDecimal.mode. + # + # Examples: + # + # # Set the rounding mode. + # BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + # b = BigDecimal('111111.111') + # b.add(1, 0) # => 0.111112111e6 + # b.add(1, 3) # => 0.111e6 + # b.add(1, 6) # => 0.111112e6 + # b.add(1, 15) # => 0.111112111e6 + # b.add(1.0, 15) # => 0.111112111e6 + # b.add(Rational(1, 1), 15) # => 0.111112111e6 + # + def add: (real | BigDecimal value, Integer digits) -> BigDecimal + + # + # Return the smallest integer greater than or equal to the value, as a + # BigDecimal. + # + # BigDecimal('3.14159').ceil #=> 4 + # BigDecimal('-9.1').ceil #=> -9 + # + # If n is specified and positive, the fractional part of the result has no more + # than that many digits. + # + # If n is specified and negative, at least that many digits to the left of the + # decimal point will be 0 in the result. + # + # BigDecimal('3.14159').ceil(3) #=> 3.142 + # BigDecimal('13345.234').ceil(-2) #=> 13400.0 + # + def ceil: () -> Integer + | (int n) -> BigDecimal + + # + # + def clone: () -> self + + # + # The coerce method provides support for Ruby type coercion. It is not enabled + # by default. + # + # This means that binary operations like + * / or - can often be performed on a + # BigDecimal and an object of another type, if the other object can be coerced + # into a BigDecimal value. + # + # e.g. + # a = BigDecimal("1.0") + # b = a / 2.0 #=> 0.5 + # + # Note that coercing a String to a BigDecimal is not supported by default; it + # requires a special compile-time option when building Ruby. + # + def coerce: (Numeric) -> [ BigDecimal, BigDecimal ] + + # + # Divide by the specified value. + # + # digits + # : If specified and less than the number of significant digits of the result, + # the result is rounded to that number of digits, according to + # BigDecimal.mode. + # + # If digits is 0, the result is the same as for the / operator or #quo. + # + # If digits is not specified, the result is an integer, by analogy with + # Float#div; see also BigDecimal#divmod. + # + # + # See BigDecimal#/. See BigDecimal#quo. + # + # Examples: + # + # a = BigDecimal("4") + # b = BigDecimal("3") + # + # a.div(b, 3) # => 0.133e1 + # + # a.div(b, 0) # => 0.1333333333333333333e1 + # a / b # => 0.1333333333333333333e1 + # a.quo(b) # => 0.1333333333333333333e1 + # + # a.div(b) # => 1 + # + def div: (real | BigDecimal value) -> Integer + | (real | BigDecimal value, int digits) -> BigDecimal + + # + # Divides by the specified value, and returns the quotient and modulus as + # BigDecimal numbers. The quotient is rounded towards negative infinity. + # + # For example: + # + # require 'bigdecimal' + # + # a = BigDecimal("42") + # b = BigDecimal("9") + # + # q, m = a.divmod(b) + # + # c = q * b + m + # + # a == c #=> true + # + # The quotient q is (a/b).floor, and the modulus is the amount that must be + # added to q * b to get a. + # + def divmod: (real | BigDecimal) -> [ Integer, BigDecimal ] + + # + # + def dup: () -> self + + # + # Tests for value equality; returns true if the values are equal. + # + # The == and === operators and the eql? method have the same implementation for + # BigDecimal. + # + # Values may be coerced to perform the comparison: + # + # BigDecimal('1.0') == 1.0 #=> true + # + def eql?: (untyped) -> bool + + # + # Returns the exponent of the BigDecimal number, as an Integer. + # + # If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string of + # digits with no leading zeros, then n is the exponent. + # + def exponent: () -> Integer + + # + # Returns True if the value is finite (not NaN or infinite). + # + def finite?: () -> bool + + # + # Return the integer part of the number, as a BigDecimal. + # + def fix: () -> BigDecimal + + # + # Return the largest integer less than or equal to the value, as a BigDecimal. + # + # BigDecimal('3.14159').floor #=> 3 + # BigDecimal('-9.1').floor #=> -10 + # + # If n is specified and positive, the fractional part of the result has no more + # than that many digits. + # + # If n is specified and negative, at least that many digits to the left of the + # decimal point will be 0 in the result. + # + # BigDecimal('3.14159').floor(3) #=> 3.141 + # BigDecimal('13345.234').floor(-2) #=> 13300.0 + # + def floor: () -> Integer + | (int n) -> BigDecimal + + # + # Return the fractional part of the number, as a BigDecimal. + # + def frac: () -> BigDecimal + + # + # Returns the integer hash value for `self`. + # + # Two instances of BigDecimal have the same hash value if and only if they have + # equal: + # + # * Sign. + # * Fractional part. + # * Exponent. + # + def hash: () -> Integer + + # + # Returns nil, -1, or +1 depending on whether the value is finite, -Infinity, or + # +Infinity. + # + def infinite?: () -> Integer? + + # + # Returns a string representation of self. + # + # BigDecimal("1234.5678").inspect + # #=> "0.12345678e4" + # + def inspect: () -> String + + # + # Returns the modulus from dividing by b. + # + # See BigDecimal#divmod. + # + def modulo: (real | BigDecimal b) -> BigDecimal + + # + # Returns the BigDecimal product of `self` and `value` with a precision of + # `ndigits` decimal digits. + # + # When `ndigits` is less than the number of significant digits in the sum, the + # sum is rounded to that number of digits, according to the current rounding + # mode; see BigDecimal.mode. + # + # Examples: + # + # # Set the rounding mode. + # BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + # b = BigDecimal('555555.555') + # b.mult(3, 0) # => 0.1666666665e7 + # b.mult(3, 3) # => 0.167e7 + # b.mult(3, 6) # => 0.166667e7 + # b.mult(3, 15) # => 0.1666666665e7 + # b.mult(3.0, 0) # => 0.1666666665e7 + # b.mult(Rational(3, 1), 0) # => 0.1666666665e7 + # b.mult(Complex(3, 0), 0) # => (0.1666666665e7+0.0i) + # + def mult: (real | BigDecimal value, int digits) -> BigDecimal + + # + # Returns True if the value is Not a Number. + # + def nan?: () -> bool + + # + # Returns self if the value is non-zero, nil otherwise. + # + def nonzero?: () -> self? + + # + # Returns the value raised to the power of n. + # + # Also available as the operator **. + # + def power: (real | BigDecimal n, ?int prec) -> BigDecimal + + # + # Divide by the specified value. + # + # digits + # : If specified and less than the number of significant digits of the result, + # the result is rounded to the given number of digits, according to the + # rounding mode indicated by BigDecimal.mode. + # + # If digits is 0 or omitted, the result is the same as for the / operator. + # + # + # See BigDecimal#/. See BigDecimal#div. + # + def quo: (real | BigDecimal) -> BigDecimal + | (Complex) -> Complex + + # + # Returns the remainder from dividing by the value. + # + # x.remainder(y) means x-y*(x/y).truncate + # + def remainder: (real | BigDecimal) -> BigDecimal + + # + # Round to the nearest integer (by default), returning the result as a + # BigDecimal if n is specified, or as an Integer if it isn't. + # + # BigDecimal('3.14159').round #=> 3 + # BigDecimal('8.7').round #=> 9 + # BigDecimal('-9.9').round #=> -10 + # + # BigDecimal('3.14159').round(2).class.name #=> "BigDecimal" + # BigDecimal('3.14159').round.class.name #=> "Integer" + # + # If n is specified and positive, the fractional part of the result has no more + # than that many digits. + # + # If n is specified and negative, at least that many digits to the left of the + # decimal point will be 0 in the result, and return value will be an Integer. + # + # BigDecimal('3.14159').round(3) #=> 3.142 + # BigDecimal('13345.234').round(-2) #=> 13300 + # + # The value of the optional mode argument can be used to determine how rounding + # is performed; see BigDecimal.mode. + # + def round: () -> Integer + | (int n) -> (Integer | BigDecimal) + | (int n, round_mode_integer | round_mode_symbol) -> BigDecimal + | (?int n, half: :up | :down | :even) -> BigDecimal + + # + # Returns the sign of the value. + # + # Returns a positive value if > 0, a negative value if < 0. It behaves the same + # with zeros - it returns a positive value for a positive zero (BigDecimal('0')) + # and a negative value for a negative zero (BigDecimal('-0')). + # + # The specific value returned indicates the type and sign of the BigDecimal, as + # follows: + # + # BigDecimal::SIGN_NaN + # : value is Not a Number + # + # BigDecimal::SIGN_POSITIVE_ZERO + # : value is +0 + # + # BigDecimal::SIGN_NEGATIVE_ZERO + # : value is -0 + # + # BigDecimal::SIGN_POSITIVE_INFINITE + # : value is +Infinity + # + # BigDecimal::SIGN_NEGATIVE_INFINITE + # : value is -Infinity + # + # BigDecimal::SIGN_POSITIVE_FINITE + # : value is positive + # + # BigDecimal::SIGN_NEGATIVE_FINITE + # : value is negative + # + def sign: () -> Integer + + # + # Splits a BigDecimal number into four parts, returned as an array of values. + # + # The first value represents the sign of the BigDecimal, and is -1 or 1, or 0 if + # the BigDecimal is Not a Number. + # + # The second value is a string representing the significant digits of the + # BigDecimal, with no leading zeros. + # + # The third value is the base used for arithmetic (currently always 10) as an + # Integer. + # + # The fourth value is an Integer exponent. + # + # If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the + # string of significant digits with no leading zeros, and n is the exponent. + # + # From these values, you can translate a BigDecimal to a float as follows: + # + # sign, significant_digits, base, exponent = a.split + # f = sign * "0.#{significant_digits}".to_f * (base ** exponent) + # + # (Note that the to_f method is provided as a more convenient way to translate a + # BigDecimal to a Float.) + # + def split: () -> [ Integer, String, Integer, Integer ] + + # + # Returns the square root of the value. + # + # Result has at least prec significant digits. + # + def sqrt: (int n) -> BigDecimal + + # + # Subtract the specified value. + # + # e.g. + # c = a.sub(b,n) + # + # digits + # : If specified and less than the number of significant digits of the result, + # the result is rounded to that number of digits, according to + # BigDecimal.mode. + # + def sub: (real | BigDecimal value, int digits) -> BigDecimal + + # + # Returns a new Float object having approximately the same value as the + # BigDecimal number. Normal accuracy limits and built-in errors of binary Float + # arithmetic apply. + # + def to_f: () -> Float + + # + # Returns the value as an Integer. + # + # If the BigDecimal is infinity or NaN, raises FloatDomainError. + # + def to_i: () -> Integer + + # + # Returns the value as an Integer. + # + # If the BigDecimal is infinity or NaN, raises FloatDomainError. + # + def to_int: () -> Integer + + # + # Converts a BigDecimal to a Rational. + # + def to_r: () -> Rational + + # + # Converts the value to a string. + # + # The default format looks like 0.xxxxEnn. + # + # The optional parameter s consists of either an integer; or an optional '+' or + # ' ', followed by an optional number, followed by an optional 'E' or 'F'. + # + # If there is a '+' at the start of s, positive values are returned with a + # leading '+'. + # + # A space at the start of s returns positive values with a leading space. + # + # If s contains a number, a space is inserted after each group of that many + # digits, starting from '.' and counting outwards. + # + # If s ends with an 'E', engineering notation (0.xxxxEnn) is used. + # + # If s ends with an 'F', conventional floating point notation is used. + # + # Examples: + # + # BigDecimal('-1234567890123.45678901234567890').to_s('5F') + # #=> '-123 45678 90123.45678 90123 45678 9' + # + # BigDecimal('1234567890123.45678901234567890').to_s('+8F') + # #=> '+12345 67890123.45678901 23456789' + # + # BigDecimal('1234567890123.45678901234567890').to_s(' F') + # #=> ' 1234567890123.4567890123456789' + # + def to_s: (?String | int s) -> String + + # + # Truncate to the nearest integer (by default), returning the result as a + # BigDecimal. + # + # BigDecimal('3.14159').truncate #=> 3 + # BigDecimal('8.7').truncate #=> 8 + # BigDecimal('-9.9').truncate #=> -9 + # + # If n is specified and positive, the fractional part of the result has no more + # than that many digits. + # + # If n is specified and negative, at least that many digits to the left of the + # decimal point will be 0 in the result. + # + # BigDecimal('3.14159').truncate(3) #=> 3.141 + # BigDecimal('13345.234').truncate(-2) #=> 13300.0 + # + def truncate: () -> Integer + | (int n) -> BigDecimal + + # + # Returns True if the value is zero. + # + def zero?: () -> bool + + private + + def initialize_copy: (self) -> self + + # + # Base value used in internal calculations. On a 32 bit system, BASE is 10000, + # indicating that calculation is done in groups of 4 digits. (If it were larger, + # BASE**2 wouldn't fit in 32 bits, so you couldn't guarantee that two groups + # could always be multiplied together without overflow.) + # + BASE: Integer + + # + # Determines whether overflow, underflow or zero divide result in an exception + # being thrown. See BigDecimal.mode. + # + EXCEPTION_ALL: Integer + + # + # Determines what happens when the result of a computation is infinity. See + # BigDecimal.mode. + # + EXCEPTION_INFINITY: Integer + + # + # Determines what happens when the result of a computation is not a number + # (NaN). See BigDecimal.mode. + # + EXCEPTION_NaN: Integer + + # + # Determines what happens when the result of a computation is an overflow (a + # result too large to be represented). See BigDecimal.mode. + # + EXCEPTION_OVERFLOW: Integer + + # + # Determines what happens when the result of a computation is an underflow (a + # result too small to be represented). See BigDecimal.mode. + # + EXCEPTION_UNDERFLOW: Integer + + # + # Determines what happens when a division by zero is performed. See + # BigDecimal.mode. + # + EXCEPTION_ZERODIVIDE: Integer + + # + # Special value constants + # + INFINITY: BigDecimal + + NAN: BigDecimal + + # + # Round towards +Infinity. See BigDecimal.mode. + # + ROUND_CEILING: Integer + + # + # Indicates that values should be rounded towards zero. See BigDecimal.mode. + # + ROUND_DOWN: Integer + + # + # Round towards -Infinity. See BigDecimal.mode. + # + ROUND_FLOOR: Integer + + # + # Indicates that digits >= 6 should be rounded up, others rounded down. See + # BigDecimal.mode. + # + ROUND_HALF_DOWN: Integer + + # + # Round towards the even neighbor. See BigDecimal.mode. + # + ROUND_HALF_EVEN: Integer + + # + # Indicates that digits >= 5 should be rounded up, others rounded down. See + # BigDecimal.mode. + # + ROUND_HALF_UP: Integer + + # + # Determines what happens when a result must be rounded in order to fit in the + # appropriate number of significant digits. See BigDecimal.mode. + # + ROUND_MODE: round_mode + + # + # Indicates that values should be rounded away from zero. See BigDecimal.mode. + # + ROUND_UP: Integer + + # + # Indicates that a value is negative and finite. See BigDecimal.sign. + # + SIGN_NEGATIVE_FINITE: Integer + + # + # Indicates that a value is negative and infinite. See BigDecimal.sign. + # + SIGN_NEGATIVE_INFINITE: Integer + + # + # Indicates that a value is -0. See BigDecimal.sign. + # + SIGN_NEGATIVE_ZERO: Integer + + # + # Indicates that a value is not a number. See BigDecimal.sign. + # + SIGN_NaN: Integer + + # + # Indicates that a value is positive and finite. See BigDecimal.sign. + # + SIGN_POSITIVE_FINITE: Integer + + # + # Indicates that a value is positive and infinite. See BigDecimal.sign. + # + SIGN_POSITIVE_INFINITE: Integer + + # + # Indicates that a value is +0. See BigDecimal.sign. + # + SIGN_POSITIVE_ZERO: Integer + + # + # The version of bigdecimal library + # + VERSION: String +end + +%a{annotate:rdoc:skip} +module Kernel + private + + # + # Returns the BigDecimal converted from `value` with a precision of `ndigits` + # decimal digits. + # + # When `ndigits` is less than the number of significant digits in the value, the + # result is rounded to that number of digits, according to the current rounding + # mode; see BigDecimal.mode. + # + # When `ndigits` is 0, the number of digits to correctly represent a float + # number is determined automatically. + # + # Returns `value` converted to a BigDecimal, depending on the type of `value`: + # + # * Integer, Float, Rational, Complex, or BigDecimal: converted directly: + # + # # Integer, Complex, or BigDecimal value does not require ndigits; ignored if given. + # BigDecimal(2) # => 0.2e1 + # BigDecimal(Complex(2, 0)) # => 0.2e1 + # BigDecimal(BigDecimal(2)) # => 0.2e1 + # # Float or Rational value requires ndigits. + # BigDecimal(2.0, 0) # => 0.2e1 + # BigDecimal(Rational(2, 1), 0) # => 0.2e1 + # + # * String: converted by parsing if it contains an integer or floating-point + # literal; leading and trailing whitespace is ignored: + # + # # String does not require ndigits; ignored if given. + # BigDecimal('2') # => 0.2e1 + # BigDecimal('2.0') # => 0.2e1 + # BigDecimal('0.2e1') # => 0.2e1 + # BigDecimal(' 2.0 ') # => 0.2e1 + # + # * Other type that responds to method `:to_str`: first converted to a string, + # then converted to a BigDecimal, as above. + # + # * Other type: + # + # * Raises an exception if keyword argument `exception` is `true`. + # * Returns `nil` if keyword argument `exception` is `false`. + # + # Raises an exception if `value` evaluates to a Float and `digits` is larger + # than Float::DIG + 1. + # + def self?.BigDecimal: (real | string | BigDecimal initial, ?int digits, ?exception: bool) -> BigDecimal +end + +%a{annotate:rdoc:skip} +class Integer + # + # Performs division; for integer `numeric`, truncates the result to an integer: + # + # 4 / 3 # => 1 + # 4 / -3 # => -2 + # -4 / 3 # => -2 + # -4 / -3 # => 1 + # + # For other +numeric+, returns non-integer result: + # + # 4 / 3.0 # => 1.3333333333333333 + # 4 / Rational(3, 1) # => (4/3) + # 4 / Complex(3, 0) # => ((4/3)+0i) + # + def /: (BigDecimal) -> BigDecimal + | ... + + # + # Performs multiplication: + # + # 4 * 2 # => 8 + # 4 * -2 # => -8 + # -4 * 2 # => -8 + # 4 * 2.0 # => 8.0 + # 4 * Rational(1, 3) # => (4/3) + # 4 * Complex(2, 0) # => (8+0i) + # + def *: (BigDecimal) -> BigDecimal + | ... + + # + # Performs addition: + # + # 2 + 2 # => 4 + # -2 + 2 # => 0 + # -2 + -2 # => -4 + # 2 + 2.0 # => 4.0 + # 2 + Rational(2, 1) # => (4/1) + # 2 + Complex(2, 0) # => (4+0i) + # + def +: (BigDecimal) -> BigDecimal + | ... + + # + # Performs subtraction: + # + # 4 - 2 # => 2 + # -4 - 2 # => -6 + # -4 - -2 # => -2 + # 4 - 2.0 # => 2.0 + # 4 - Rational(2, 1) # => (2/1) + # 4 - Complex(2, 0) # => (2+0i) + # + def -: (BigDecimal) -> BigDecimal + | ... +end + +%a{annotate:rdoc:skip} +class Float + # + # Returns a new Float which is the result of dividing `self` by `other`: + # + # f = 3.14 + # f / 2 # => 1.57 + # f / 2.0 # => 1.57 + # f / Rational(2, 1) # => 1.57 + # f / Complex(2, 0) # => (1.57+0.0i) + # + def /: (BigDecimal) -> BigDecimal + | ... + + # + # Returns a new Float which is the product of `self` and `other`: + # + # f = 3.14 + # f * 2 # => 6.28 + # f * 2.0 # => 6.28 + # f * Rational(1, 2) # => 1.57 + # f * Complex(2, 0) # => (6.28+0.0i) + # + def *: (BigDecimal) -> BigDecimal + | ... + + # + # Returns a new Float which is the sum of `self` and `other`: + # + # f = 3.14 + # f + 1 # => 4.140000000000001 + # f + 1.0 # => 4.140000000000001 + # f + Rational(1, 1) # => 4.140000000000001 + # f + Complex(1, 0) # => (4.140000000000001+0i) + # + def +: (BigDecimal) -> BigDecimal + | ... + + # + # Returns a new Float which is the difference of `self` and `other`: + # + # f = 3.14 + # f - 1 # => 2.14 + # f - 1.0 # => 2.14 + # f - Rational(1, 1) # => 2.14 + # f - Complex(1, 0) # => (2.14+0i) + # + def -: (BigDecimal) -> BigDecimal + | ... +end + +%a{annotate:rdoc:skip} +class Rational + # + # Performs division. + # + # Rational(2, 3) / Rational(2, 3) #=> (1/1) + # Rational(900) / Rational(1) #=> (900/1) + # Rational(-2, 9) / Rational(-9, 2) #=> (4/81) + # Rational(9, 8) / 4 #=> (9/32) + # Rational(20, 9) / 9.8 #=> 0.22675736961451246 + # + def /: (BigDecimal) -> BigDecimal + | ... + + # + # Performs multiplication. + # + # Rational(2, 3) * Rational(2, 3) #=> (4/9) + # Rational(900) * Rational(1) #=> (900/1) + # Rational(-2, 9) * Rational(-9, 2) #=> (1/1) + # Rational(9, 8) * 4 #=> (9/2) + # Rational(20, 9) * 9.8 #=> 21.77777777777778 + # + def *: (BigDecimal) -> BigDecimal + | ... + + # + # Performs addition. + # + # Rational(2, 3) + Rational(2, 3) #=> (4/3) + # Rational(900) + Rational(1) #=> (901/1) + # Rational(-2, 9) + Rational(-9, 2) #=> (-85/18) + # Rational(9, 8) + 4 #=> (41/8) + # Rational(20, 9) + 9.8 #=> 12.022222222222222 + # + def +: (BigDecimal) -> BigDecimal + | ... + + # + # Performs subtraction. + # + # Rational(2, 3) - Rational(2, 3) #=> (0/1) + # Rational(900) - Rational(1) #=> (899/1) + # Rational(-2, 9) - Rational(-9, 2) #=> (77/18) + # Rational(9, 8) - 4 #=> (-23/8) + # Rational(20, 9) - 9.8 #=> -7.577777777777778 + # + def -: (BigDecimal) -> BigDecimal + | ... +end + +%a{annotate:rdoc:skip} +class Complex + # + # Returns the quotient of `self` and `numeric`: + # + # Complex.rect(2, 3) / Complex.rect(2, 3) # => (1+0i) + # Complex.rect(900) / Complex.rect(1) # => (900+0i) + # Complex.rect(-2, 9) / Complex.rect(-9, 2) # => ((36/85)-(77/85)*i) + # Complex.rect(9, 8) / 4 # => ((9/4)+2i) + # Complex.rect(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) + # + def /: (BigDecimal) -> Complex + | ... + + # + # Returns the product of `self` and `numeric`: + # + # Complex.rect(2, 3) * Complex.rect(2, 3) # => (-5+12i) + # Complex.rect(900) * Complex.rect(1) # => (900+0i) + # Complex.rect(-2, 9) * Complex.rect(-9, 2) # => (0-85i) + # Complex.rect(9, 8) * 4 # => (36+32i) + # Complex.rect(20, 9) * 9.8 # => (196.0+88.2i) + # + def *: (BigDecimal) -> Complex + | ... + + # + # Returns the sum of `self` and `numeric`: + # + # Complex.rect(2, 3) + Complex.rect(2, 3) # => (4+6i) + # Complex.rect(900) + Complex.rect(1) # => (901+0i) + # Complex.rect(-2, 9) + Complex.rect(-9, 2) # => (-11+11i) + # Complex.rect(9, 8) + 4 # => (13+8i) + # Complex.rect(20, 9) + 9.8 # => (29.8+9i) + # + def +: (BigDecimal) -> Complex + | ... + + # + # Returns the difference of `self` and `numeric`: + # + # Complex.rect(2, 3) - Complex.rect(2, 3) # => (0+0i) + # Complex.rect(900) - Complex.rect(1) # => (899+0i) + # Complex.rect(-2, 9) - Complex.rect(-9, 2) # => (7+7i) + # Complex.rect(9, 8) - 4 # => (5+8i) + # Complex.rect(20, 9) - 9.8 # => (10.2+9i) + # + def -: (BigDecimal) -> Complex + | ... +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal_util.rbs b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal_util.rbs new file mode 100644 index 0000000..4c5bfce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_decimal_util.rbs @@ -0,0 +1,158 @@ +%a{annotate:rdoc:skip} +class Integer + # + # Returns the value of `int` as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 42.to_d # => 0.42e2 + # + # See also Kernel.BigDecimal. + # + def to_d: () -> BigDecimal +end + +%a{annotate:rdoc:skip} +class Float + # + # Returns the value of `float` as a BigDecimal. The `precision` parameter is + # used to determine the number of significant digits for the result. When + # `precision` is set to `0`, the number of digits to represent the float being + # converted is determined automatically. The default `precision` is `0`. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 0.5.to_d # => 0.5e0 + # 1.234.to_d # => 0.1234e1 + # 1.234.to_d(2) # => 0.12e1 + # + # See also Kernel.BigDecimal. + # + def to_d: (?Integer precision) -> BigDecimal +end + +%a{annotate:rdoc:skip} +class String + # + # Returns the result of interpreting leading characters in `str` as a + # BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # "0.5".to_d # => 0.5e0 + # "123.45e1".to_d # => 0.12345e4 + # "45.67 degrees".to_d # => 0.4567e2 + # + # See also Kernel.BigDecimal. + # + def to_d: () -> BigDecimal +end + +%a{annotate:rdoc:skip} +class BigDecimal + # + # Converts a BigDecimal to a String of the form "nnnnnn.mmm". This method is + # deprecated; use BigDecimal#to_s("F") instead. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_digits # => "3.14" + # + def to_digits: () -> String + + # + # Returns self. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_d # => 0.314e1 + # + def to_d: () -> BigDecimal +end + +%a{annotate:rdoc:skip} +class Rational + # + # Returns the value as a BigDecimal. + # + # The `precision` parameter is used to determine the number of significant + # digits for the result. When `precision` is set to `0`, the number of digits to + # represent the float being converted is determined automatically. The default + # `precision` is `0`. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Rational(22, 7).to_d(3) # => 0.314e1 + # + # See also Kernel.BigDecimal. + # + def to_d: (Integer precision) -> BigDecimal +end + +%a{annotate:rdoc:skip} +class Complex + # + # Returns the value as a BigDecimal. If the imaginary part is not `0`, an error + # is raised + # + # The `precision` parameter is used to determine the number of significant + # digits for the result. When `precision` is set to `0`, the number of digits to + # represent the float being converted is determined automatically. The default + # `precision` is `0`. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Complex(0.1234567, 0).to_d(4) # => 0.1235e0 + # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1 + # Complex(1, 1).to_d # raises ArgumentError + # + # See also Kernel.BigDecimal. + # + def to_d: (*untyped args) -> BigDecimal +end + +%a{annotate:rdoc:skip} +class NilClass + # + # Returns nil represented as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # nil.to_d # => 0.0 + # + def to_d: () -> BigDecimal +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_math.rbs b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_math.rbs new file mode 100644 index 0000000..6d9fc48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-4.1.2/sig/big_math.rbs @@ -0,0 +1,423 @@ +# +# Core BigMath methods for BigDecimal (log, exp) are defined here. Other methods +# (sin, cos, atan) are defined in 'bigdecimal/math.rb'. +# +# +# Provides mathematical functions. +# +# Example: +# +# require "bigdecimal/math" +# +# include BigMath +# +# a = BigDecimal((PI(49)/2).to_s) +# puts sin(a,100) # => 0.9999999999...9999999986e0 +# +module BigMath + # + # Computes e (the base of natural logarithms) to the specified number of digits + # of precision, `numeric`. + # + # BigMath.E(32).to_s + # #=> "0.27182818284590452353602874713527e1" + # + def self?.E: (int prec) -> BigDecimal + + # + # Computes the value of pi to the specified number of digits of precision, + # `numeric`. + # + # BigMath.PI(32).to_s + # #=> "0.31415926535897932384626433832795e1" + # + def self?.PI: (int prec) -> BigDecimal + + # + # Computes the arccosine of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.acos(BigDecimal('0.5'), 32).to_s + # #=> "0.10471975511965977461542144610932e1" + # + def self?.acos: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the inverse hyperbolic cosine of `decimal` to the specified number of + # digits of precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.acosh(BigDecimal('2'), 32).to_s + # #=> "0.1316957896924816708625046347308e1" + # + def self?.acosh: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the arcsine of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.asin(BigDecimal('0.5'), 32).to_s + # #=> "0.52359877559829887307710723054658e0" + # + def self?.asin: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the inverse hyperbolic sine of `decimal` to the specified number of + # digits of precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.asinh(BigDecimal('1'), 32).to_s + # #=> "0.88137358701954302523260932497979e0" + # + def self?.asinh: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the arctangent of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.atan(BigDecimal('-1'), 32).to_s + # #=> "-0.78539816339744830961566084581988e0" + # + def self?.atan: (real | BigDecimal x, int prec) -> BigDecimal + + # + # Computes the arctangent of y and x to the specified number of digits of + # precision, `numeric`. + # + # BigMath.atan2(BigDecimal('-1'), BigDecimal('1'), 32).to_s + # #=> "-0.78539816339744830961566084581988e0" + # + def self?.atan2: (real | BigDecimal, real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the inverse hyperbolic tangent of `decimal` to the specified number + # of digits of precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.atanh(BigDecimal('0.5'), 32).to_s + # #=> "0.54930614433405484569762261846126e0" + # + def self?.atanh: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the cube root of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # BigMath.cbrt(BigDecimal('2'), 32).to_s + # #=> "0.12599210498948731647672106072782e1" + # + def self?.cbrt: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the cosine of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # If `decimal` is Infinity or NaN, returns NaN. + # + # BigMath.cos(BigMath.PI(16), 32).to_s + # #=> "-0.99999999999999999999999999999997e0" + # + def self?.cos: (real | BigDecimal x, int prec) -> BigDecimal + + # + # Computes the hyperbolic cosine of `decimal` to the specified number of digits + # of precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.cosh(BigDecimal('1'), 32).to_s + # #=> "0.15430806348152437784779056207571e1" + # + def self?.cosh: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the error function of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.erf(BigDecimal('1'), 32).to_s + # #=> "0.84270079294971486934122063508261e0" + # + def self?.erf: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the complementary error function of `decimal` to the specified number + # of digits of precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.erfc(BigDecimal('10'), 32).to_s + # #=> "0.20884875837625447570007862949578e-44" + # + def self?.erfc: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the value of e (the base of natural logarithms) raised to the power + # of `decimal`, to the specified number of digits of precision. + # + # If `decimal` is infinity, returns Infinity. + # + # If `decimal` is NaN, returns NaN. + # + def self?.exp: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes exp(decimal) - 1 to the specified number of digits of precision, + # `numeric`. + # + # BigMath.expm1(BigDecimal('0.1'), 32).to_s + # #=> "0.10517091807564762481170782649025e0" + # + def self?.expm1: (real | BigDecimal, int prec) -> BigDecimal + + # + # Decomposes `x` into a normalized fraction and an integral power of ten. + # + # BigMath.frexp(BigDecimal(123.456)) + # #=> [0.123456e0, 3] + # + def self?.frexp: (real | BigDecimal x) -> [ BigDecimal, Integer ] + + # + # Computes the gamma function of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # BigMath.gamma(BigDecimal('0.5'), 32).to_s + # #=> "0.17724538509055160272981674833411e1" + # + def self?.gamma: (real | BigDecimal, int prec) -> BigDecimal + + # + # Returns sqrt(x**2 + y**2) to the specified number of digits of precision, + # `numeric`. + # + # BigMath.hypot(BigDecimal('1'), BigDecimal('2'), 32).to_s + # #=> "0.22360679774997896964091736687313e1" + # + def self?.hypot: (real | BigDecimal, real | BigDecimal, int prec) -> BigDecimal + + # + # Inverse of `frexp`. Returns the value of fraction * 10**exponent. + # + # BigMath.ldexp(BigDecimal("0.123456e0"), 3) + # #=> 0.123456e3 + # + def self?.ldexp: (real | BigDecimal fraction, Integer exponent) -> BigDecimal + + # + # Computes the natural logarithm of the absolute value of the gamma function of + # `decimal` to the specified number of digits of precision, `numeric` and its + # sign. + # + # BigMath.lgamma(BigDecimal('0.5'), 32) + # #=> [0.57236494292470008707171367567653e0, 1] + # + def self?.lgamma: (real | BigDecimal, int prec) -> [ BigDecimal, Integer ] + + # + # Computes the natural logarithm of `decimal` to the specified number of digits + # of precision, `numeric`. + # + # If `decimal` is zero or negative, raises Math::DomainError. + # + # If `decimal` is positive infinity, returns Infinity. + # + # If `decimal` is NaN, returns NaN. + # + def self?.log: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the base 10 logarithm of `decimal` to the specified number of digits + # of precision, `numeric`. + # + # If `decimal` is zero or negative, raises Math::DomainError. + # + # If `decimal` is positive infinity, returns Infinity. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.log10(BigDecimal('3'), 32).to_s + # #=> "0.47712125471966243729502790325512e0" + # + def self?.log10: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes log(1 + decimal) to the specified number of digits of precision, + # `numeric`. + # + # BigMath.log1p(BigDecimal('0.1'), 32).to_s + # #=> "0.95310179804324860043952123280765e-1" + # + def self?.log1p: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the base 2 logarithm of `decimal` to the specified number of digits + # of precision, `numeric`. + # + # If `decimal` is zero or negative, raises Math::DomainError. + # + # If `decimal` is positive infinity, returns Infinity. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.log2(BigDecimal('3'), 32).to_s + # #=> "0.15849625007211561814537389439478e1" + # + def self?.log2: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the sine of `decimal` to the specified number of digits of precision, + # `numeric`. + # + # If `decimal` is Infinity or NaN, returns NaN. + # + # BigMath.sin(BigMath.PI(5)/4, 32).to_s + # #=> "0.70710807985947359435812921837984e0" + # + def self?.sin: (real | BigDecimal x, int prec) -> BigDecimal + + # + # Computes the hyperbolic sine of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.sinh(BigDecimal('1'), 32).to_s + # #=> "0.11752011936438014568823818505956e1" + # + def self?.sinh: (real | BigDecimal, int prec) -> BigDecimal + + # + # Computes the square root of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # BigMath.sqrt(BigDecimal('2'), 32).to_s + # #=> "0.14142135623730950488016887242097e1" + # + def self?.sqrt: (real | BigDecimal x, int prec) -> BigDecimal + + # + # Computes the tangent of `decimal` to the specified number of digits of + # precision, `numeric`. + # + # If `decimal` is Infinity or NaN, returns NaN. + # + # BigMath.tan(BigDecimal("0.0"), 4).to_s + # #=> "0.0" + # + # BigMath.tan(BigMath.PI(24) / 4, 32).to_s + # #=> "0.99999999999999999999999830836025e0" + # + def self?.tan: (real | BigDecimal x, int prec) -> BigDecimal + + # + # Computes the hyperbolic tangent of `decimal` to the specified number of digits + # of precision, `numeric`. + # + # If `decimal` is NaN, returns NaN. + # + # BigMath.tanh(BigDecimal('1'), 32).to_s + # #=> "0.76159415595576488811945828260479e0" + # + def self?.tanh: (real | BigDecimal, int prec) -> BigDecimal +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/CHANGELOG.md new file mode 100644 index 0000000..6461846 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/CHANGELOG.md @@ -0,0 +1,621 @@ +## Current + +## Release v1.3.8 (19 July 2026) + +concurrent-ruby: + +* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.8). + +## Release v1.3.7 (16 June 2026) + +concurrent-ruby: + +* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7). + +## Release v1.3.6 (13 December 2025) + +concurrent-ruby: + +* See the [release notes on GitHub](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.6). + +## Release v1.3.5, edge v0.7.2 (15 January 2025) + +concurrent-ruby: + +* (#1062) Remove dependency on logger. + +concurrent-ruby-edge: + +* (#1062) Remove dependency on logger. + +## Release v1.3.4 (10 August 2024) + +* (#1060) Fix bug with return value of `Concurrent.available_processor_count` when `cpu.cfs_quota_us` is -1. +* (#1058) Add `Concurrent.cpu_shares` that is cgroups aware. + +## Release v1.3.3 (9 June 2024) + +* (#1053) Improve the speed of `Concurrent.physical_processor_count` on Windows. + +## Release v1.3.2, edge v0.7.1 (7 June 2024) + +concurrent-ruby: + +* (#1051) Remove dependency on `win32ole`. + +concurrent-ruby-edge: + +* (#1052) Fix dependency on `concurrent-ruby` to allow the latest release. + +## Release v1.3.1 (29 May 2024) + +* Release 1.3.0 was broken when pushed to RubyGems. 1.3.1 is a packaging fix. + +## Release v1.3.0 (28 May 2024) + +* (#1042) Align Java Executor Service behavior for `shuttingdown?`, `shutdown?` +* (#1038) Add `Concurrent.available_processor_count` that is cgroups aware. + +## Release v1.2.3 (16 Jan 2024) + +* See [the GitHub release](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.2.3) for details. + +## Release v1.2.2 (24 Feb 2023) + +* (#993) Fix arguments passed to `Concurrent::Map`'s `default_proc`. + +## Release v1.2.1 (24 Feb 2023) + +* (#990) Add missing `require 'fiber'` for `FiberLocalVar`. +* (#989) Optimize `Concurrent::Map#[]` on CRuby by letting the backing Hash handle the `default_proc`. + +## Release v1.2.0 (23 Jan 2023) + +* (#962) Fix ReentrantReadWriteLock to use the same granularity for locals as for Mutex it uses. +* (#983) Add FiberLocalVar +* (#934) concurrent-ruby now supports requiring individual classes (public classes listed in the docs), e.g., `require 'concurrent/map'` +* (#976) Let `Promises.any_fulfilled_future` take an `Event` +* Improve documentation of various classes +* (#975) Set the Ruby compatibility version at 2.3 +* (#972) Remove Rubinius-related code + +## Release v1.1.10 (22 Mar 2022) + +concurrent-ruby: + +* (#951) Set the Ruby compatibility version at 2.2 +* (#939, #933) The `caller_runs` fallback policy no longer blocks reads from the job queue by worker threads +* (#938, #761, #652) You can now explicitly `prune_pool` a thread pool (Sylvain Joyeux) +* (#937, #757, #670) We switched the Yahoo stock API for demos to Alpha Vantage (Gustavo Caso) +* (#932, #931) We changed how `SafeTaskExecutor` handles local jump errors (Aaron Jensen) +* (#927) You can use keyword arguments in your initialize when using `Async` (Matt Larraz) +* (#926, #639) We removed timeout from `TimerTask` because it wasn't sound, and now it's a no-op with a warning (Jacob Atzen) +* (#919) If you double-lock a re-entrant read-write lock, we promote to locked for writing (zp yuan) +* (#915) `monotonic_time` now accepts an optional unit parameter, as Ruby's `clock_gettime` (Jean Boussier) + +## Release v1.1.9 (5 Jun 2021) + +concurrent-ruby: + +* (#866) Child promise state not set to :pending immediately after #execute when parent has completed +* (#905, #872) Fix RubyNonConcurrentPriorityQueue#delete method +* (2df0337d) Make sure locks are not shared on shared when objects are dup/cloned +* (#900, #906, #796, #847, #911) Fix Concurrent::Set tread-safety issues on CRuby +* (#907) Add new ConcurrentMap backend for TruffleRuby + +## Release v1.1.8 (20 January 2021) + +concurrent-ruby: + +* (#885) Fix race condition in TVar for stale reads +* (#884) RubyThreadLocalVar: Do not iterate over hash which might conflict with new pair addition + +## Release v1.1.7 (6 August 2020) + +concurrent-ruby: + +* (#879) Consider falsy value on `Concurrent::Map#compute_if_absent` for fast non-blocking path +* (#876) Reset Async queue on forking, makes Async fork-safe +* (#856) Avoid running problematic code in RubyThreadLocalVar on MRI that occasionally results in segfault +* (#853) Introduce ThreadPoolExecutor without a Queue + +## Release v1.1.6, edge v0.6.0 (10 Feb 2020) + +concurrent-ruby: + +* (#841) Concurrent.disable_at_exit_handlers! is no longer needed and was deprecated. +* (#841) AbstractExecutorService#auto_terminate= was deprecated and has no effect. + Set :auto_terminate option instead when executor is initialized. + +## Release v1.1.6.pre1, edge v0.6.0.pre1 (26 Jan 2020) + +concurrent-ruby: + +* (#828) Allow to name executors, the name is also used to name their threads +* (#838) Implement #dup and #clone for structs +* (#821) Safer finalizers for thread local variables +* Documentation fixes +* (#814) Use Ruby's Etc.nprocessors if available +* (#812) Fix directory structure not to mess with packaging tools +* (#840) Fix termination of pools on JRuby + +concurrent-ruby-edge: + +* Add WrappingExecutor (#830) + +## Release v1.1.5, edge v0.5.0 (10 Mar 2019) + +concurrent-ruby: + +* fix potential leak of context on JRuby and Java 7 + +concurrent-ruby-edge: + +* Add finalized Concurrent::Cancellation +* Add finalized Concurrent::Throttle +* Add finalized Concurrent::Promises::Channel +* Add new Concurrent::ErlangActor + +## Release v1.1.4 (14 Dec 2018) + +* (#780) Remove java_alias of 'submit' method of Runnable to let executor service work on java 11 +* (#776) Fix NameError on defining a struct with a name which is already taken in an ancestor + +## Release v1.1.3 (7 Nov 2018) + +* (#775) fix partial require of the gem (although not officially supported) + +## Release v1.1.2 (6 Nov 2018) + +* (#773) more defensive 1.9.3 support + +## Release v1.1.1, edge v0.4.1 (1 Nov 2018) + +* (#768) add support for 1.9.3 back + +## Release v1.1.0, edge v0.4.0 (31 OCt 2018) (yanked) + +* (#768) yanked because of issues with removed 1.9.3 support + +## Release v1.1.0.pre2, edge v0.4.0.pre2 (18 Sep 2018) + +concurrent-ruby: + +* fixed documentation and README links +* fix Set for TruffleRuby and Rubinius +* use properly supported TruffleRuby APIs + +concurrent-ruby-edge: + +* add Promises.zip_futures_over_on + +## Release v1.1.0.pre1, edge v0.4.0.pre1 (15 Aug 2018) + +concurrent-ruby: + +* requires at least Ruby 2.0 +* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/1.1.0/Concurrent/Promises.html) + are moved from `concurrent-ruby-edge` to `concurrent-ruby` +* Add support for TruffleRuby + * (#734) Fix Array/Hash/Set construction broken on TruffleRuby + * AtomicReference fixed +* CI stabilization +* remove sharp dependency edge -> core +* remove warnings +* documentation updates +* Exchanger is no longer documented as edge since it was already available in + `concurrent-ruby` +* (#644) Fix Map#each and #each_pair not returning enumerator outside of MRI +* (#659) Edge promises fail during error handling +* (#741) Raise on recursive Delay#value call +* (#727) #717 fix global IO executor on JRuby +* (#740) Drop support for CRuby 1.9, JRuby 1.7, Rubinius. +* (#737) Move AtomicMarkableReference out of Edge +* (#708) Prefer platform specific memory barriers +* (#735) Fix wrong expected exception in channel spec assertion +* (#729) Allow executor option in `Promise#then` +* (#725) fix timeout check to use timeout_interval +* (#719) update engine detection +* (#660) Add specs for Promise#zip/Promise.zip ordering +* (#654) Promise.zip execution changes +* (#666) Add thread safe set implementation +* (#651) #699 #to_s, #inspect should not output negative object IDs. +* (#685) Avoid RSpec warnings about raise_error +* (#680) Avoid RSpec monkey patching, persist spec results locally, use RSpec + v3.7.0 +* (#665) Initialize the monitor for new subarrays on Rubinius +* (#661) Fix error handling in edge promises + +concurrent-ruby-edge: + +* (#659) Edge promises fail during error handling +* Edge files clearly separated in `lib-edge` +* added ReInclude + +## Release v1.0.5, edge v0.3.1 (26 Feb 2017) + +concurrent-ruby: + +* Documentation for Event and Semaphore +* Use Unsafe#fullFence and #loadFence directly since the shortcuts were removed in JRuby +* Do not depend on org.jruby.util.unsafe.UnsafeHolder + +concurrent-ruby-edge: + +* (#620) Actors on Pool raise an error +* (#624) Delayed promises did not interact correctly with flatting + * Fix arguments yielded by callback methods +* Overridable default executor in promises factory methods +* Asking actor to terminate will always resolve to `true` + +## Release v1.0.4, edge v0.3.0 (27 Dec 2016) + +concurrent-ruby: + +* Nothing + +concurrent-ruby-edge: + +* New promises' API renamed, lots of improvements, edge bumped to 0.3.0 + * **Incompatible** with previous 0.2.3 version + * see https://github.com/ruby-concurrency/concurrent-ruby/pull/522 + +## Release v1.0.3 (17 Dec 2016) + +* Trigger execution of flattened delayed futures +* Avoid forking for processor_count if possible +* Semaphore Mutex and JRuby parity +* Adds Map#each as alias to Map#each_pair +* Fix uninitialized instance variables +* Make Fixnum, Bignum merger ready +* Allows Promise#then to receive an executor +* TimerSet now survives a fork +* Reject promise on any exception +* Allow ThreadLocalVar to be initialized with a block +* Support Alpha with `Concurrent::processor_count` +* Fixes format-security error when compiling ruby_193_compatible.h +* Concurrent::Atom#swap fixed: reraise the exceptions from block + +## Release v1.0.2 (2 May 2016) + +* Fix bug with `Concurrent::Map` MRI backend `#inspect` method +* Fix bug with `Concurrent::Map` MRI backend using `Hash#value?` +* Improved documentation and examples +* Minor updates to Edge + +## Release v1.0.1 (27 February 2016) + +* Fix "uninitialized constant Concurrent::ReentrantReadWriteLock" error. +* Better handling of `autoload` vs. `require`. +* Improved API for Edge `Future` zipping. +* Fix reference leak in Edge `Future` constructor . +* Fix bug which prevented thread pools from surviving a `fork`. +* Fix bug in which `TimerTask` did not correctly specify all its dependencies. +* Improved support for JRuby+Truffle +* Improved error messages. +* Improved documentation. +* Updated README and CONTRIBUTING. + +## Release v1.0.0 (13 November 2015) + +* Rename `attr_volatile_with_cas` to `attr_atomic` +* Add `clear_each` to `LockFreeStack` +* Update `AtomicReference` documentation +* Further updates and improvements to the synchronization layer. +* Performance and memory usage performance with `Actor` logging. +* Fixed `ThreadPoolExecutor` task count methods. +* Improved `Async` performance for both short and long-lived objects. +* Fixed bug in `LockFreeLinkedSet`. +* Fixed bug in which `Agent#await` triggered a validation failure. +* Further `Channel` updates. +* Adopted a project Code of Conduct +* Cleared interpreter warnings +* Fixed bug in `ThreadPoolExecutor` task count methods +* Fixed bug in 'LockFreeLinkedSet' +* Improved Java extension loading +* Handle Exception children in Edge::Future +* Continued improvements to channel +* Removed interpreter warnings. +* Shared constants now in `lib/concurrent/constants.rb` +* Refactored many tests. +* Improved synchronization layer/memory model documentation. +* Bug fix in Edge `Future#flat` +* Brand new `Channel` implementation in Edge gem. +* Simplification of `RubySingleThreadExecutor` +* `Async` improvements + - Each object uses its own `SingleThreadExecutor` instead of the global thread pool. + - No longer supports executor injection + - Much better documentation +* `Atom` updates + - No longer `Dereferenceable` + - Now `Observable` + - Added a `#reset` method +* Brand new `Agent` API and implementation. Now functionally equivalent to Clojure. +* Continued improvements to the synchronization layer +* Merged in the `thread_safe` gem + - `Concurrent::Array` + - `Concurrent::Hash` + - `Concurrent::Map` (formerly ThreadSafe::Cache) + - `Concurrent::Tuple` +* Minor improvements to Concurrent::Map +* Complete rewrite of `Exchanger` +* Removed all deprecated code (classes, methods, constants, etc.) +* Updated Agent, MutexAtomic, and BufferedChannel to inherit from Synchronization::Object. +* Many improved tests +* Some internal reorganization + +## Release v0.9.1 (09 August 2015) + +* Fixed a Rubiniux bug in synchronization object +* Fixed all interpreter warnings (except circular references) +* Fixed require statements when requiring `Atom` alone +* Significantly improved `ThreadLocalVar` on non-JRuby platforms +* Fixed error handling in Edge `Concurrent.zip` +* `AtomicFixnum` methods `#increment` and `#decrement` now support optional delta +* New `AtomicFixnum#update` method +* Minor optimizations in `ReadWriteLock` +* New `ReentrantReadWriteLock` class +* `ThreadLocalVar#bind` method is now public +* Refactored many tests + +## Release v0.9.0 (10 July 2015) + +* Updated `AtomicReference` + - `AtomicReference#try_update` now simply returns instead of raising exception + - `AtomicReference#try_update!` was added to raise exceptions if an update + fails. Note: this is the same behavior as the old `try_update` +* Pure Java implementations of + - `AtomicBoolean` + - `AtomicFixnum` + - `Semaphore` +* Fixed bug when pruning Ruby thread pools +* Fixed bug in time calculations within `ScheduledTask` +* Default `count` in `CountDownLatch` to 1 +* Use monotonic clock for all timers via `Concurrent.monotonic_time` + - Use `Process.clock_gettime(Process::CLOCK_MONOTONIC)` when available + - Fallback to `java.lang.System.nanoTime()` on unsupported JRuby versions + - Pure Ruby implementation for everything else + - Effects `Concurrent.timer`, `Concurrent.timeout`, `TimerSet`, `TimerTask`, and `ScheduledTask` +* Deprecated all clock-time based timer scheduling + - Only support scheduling by delay + - Effects `Concurrent.timer`, `TimerSet`, and `ScheduledTask` +* Added new `ReadWriteLock` class +* Consistent `at_exit` behavior for Java and Ruby thread pools. +* Added `at_exit` handler to Ruby thread pools (already in Java thread pools) + - Ruby handler stores the object id and retrieves from `ObjectSpace` + - JRuby disables `ObjectSpace` by default so that handler stores the object reference +* Added a `:stop_on_exit` option to thread pools to enable/disable `at_exit` handler +* Updated thread pool docs to better explain shutting down thread pools +* Simpler `:executor` option syntax for all abstractions which support this option +* Added `Executor#auto_terminate?` predicate method (for thread pools) +* Added `at_exit` handler to `TimerSet` +* Simplified auto-termination of the global executors + - Can now disable auto-termination of global executors + - Added shutdown/kill/wait_for_termination variants for global executors +* Can now disable auto-termination for *all* executors (the nuclear option) +* Simplified auto-termination of the global executors +* Deprecated terms "task pool" and "operation pool" + - New terms are "io executor" and "fast executor" + - New functions added with new names + - Deprecation warnings added to functions referencing old names +* Moved all thread pool related functions from `Concurrent::Configuration` to `Concurrent` + - Old functions still exist with deprecation warnings + - New functions have updated names as appropriate +* All high-level abstractions default to the "io executor" +* Fixed bug in `Actor` causing it to prematurely warm global thread pools on gem load + - This also fixed a `RejectedExecutionError` bug when running with minitest/autorun via JRuby +* Moved global logger up to the `Concurrent` namespace and refactored the code +* Optimized the performance of `Delay` + - Fixed a bug in which no executor option on construction caused block execution on a global thread pool +* Numerous improvements and bug fixes to `TimerSet` +* Fixed deadlock of `Future` when the handler raises Exception +* Added shared specs for more classes +* New concurrency abstractions including: + - `Atom` + - `Maybe` + - `ImmutableStruct` + - `MutableStruct` + - `SettableStruct` +* Created an Edge gem for unstable abstractions including + - `Actor` + - `Agent` + - `Channel` + - `Exchanger` + - `LazyRegister` + - **new Future Framework** - unified + implementation of Futures and Promises which combines Features of previous `Future`, + `Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively + new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`. + It offers better performance and does not block threads when not required. +* Actor framework changes: + - fixed reset loop in Pool + - Pool can use any actor as a worker, abstract worker class is no longer needed. + - Actor events not have format `[:event_name, *payload]` instead of just the Symbol. + - Actor now uses new Future/Promise Framework instead of `IVar` for better interoperability + - Behaviour definition array was simplified to `[BehaviourClass1, [BehaviourClass2, *initialization_args]]` + - Linking behavior responds to :linked message by returning array of linked actors + - Supervised behavior is removed in favour of just Linking + - RestartingContext is supervised by default now, `supervise: true` is not required any more + - Events can be private and public, so far only difference is that Linking will + pass to linked actors only public messages. Adding private :restarting and + :resetting events which are send before the actor restarts or resets allowing + to add callbacks to cleanup current child actors. + - Print also object_id in Reference to_s + - Add AbstractContext#default_executor to be able to override executor class wide + - Add basic IO example + - Documentation somewhat improved + - All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and + be sure that both jobs are processed first. +* Refactored `Channel` to use newer synchronization objects +* Added `#reset` and `#cancel` methods to `TimerSet` +* Added `#cancel` method to `Future` and `ScheduledTask` +* Refactored `TimerSet` to use `ScheduledTask` +* Updated `Async` with a factory that initializes the object +* Deprecated `Concurrent.timer` and `Concurrent.timeout` +* Reduced max threads on pure-Ruby thread pools (abends around 14751 threads) +* Moved many private/internal classes/modules into "namespace" modules +* Removed brute-force killing of threads in tests +* Fixed a thread pool bug when the operating system cannot allocate more threads + +## Release v0.8.0 (25 January 2015) + +* C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem. + Please see the README for more detail. +* Better variable isolation in `Promise` and `Future` via an `:args` option +* Continued to update intermittently failing tests + +## Release v0.7.2 (24 January 2015) + +* New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html) +* New `Promise.all?` and `Promise.any?` class methods +* Renamed `:overflow_policy` on thread pools to `:fallback_policy` +* Thread pools still accept the `:overflow_policy` option but display a warning +* Thread pools now implement `fallback_policy` behavior when not running (rather than universally rejecting tasks) +* Fixed minor `set_deref_options` constructor bug in `Promise` class +* Fixed minor `require` bug in `ThreadLocalVar` class +* Fixed race condition bug in `TimerSet` class +* Fixed race condition bug in `TimerSet` class +* Fixed signal bug in `TimerSet#post` method +* Numerous non-functional updates to clear warning when running in debug mode +* Fixed more intermittently failing tests +* Tests now run on new Travis build environment +* Multiple documentation updates + +## Release v0.7.1 (4 December 2014) + +Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release. + +* Added `flat_map` method to `Promise` +* Added `zip` method to `Promise` +* Fixed bug with logging in `Actor` +* Improvements to `Promise` tests +* Removed actor-experimental warning +* Added an `IndirectImmediateExecutor` class +* Allow disabling auto termination of global executors +* Fix thread leaking in `ThreadLocalVar` (uses `Ref` gem on non-JRuby systems) +* Fix thread leaking when pruning pure-Ruby thread pools +* Prevent `Actor` from using an `ImmediateExecutor` (causes deadlock) +* Added missing synchronizations to `TimerSet` +* Fixed bug with return value of `Concurrent::Actor::Utils::Pool#ask` +* Fixed timing bug in `TimerTask` +* Fixed bug when creating a `JavaThreadPoolExecutor` with minimum pool size of zero +* Removed confusing warning when not using native extensions +* Improved documentation + +## Release v0.7.0 (13 August 2014) + +* Merge the [atomic](https://github.com/ruby-concurrency/atomic) gem + - Pure Ruby `MutexAtomic` atomic reference class + - Platform native atomic reference classes `CAtomic`, `JavaAtomic`, and `RbxAtomic` + - Automated [build process](https://github.com/ruby-concurrency/rake-compiler-dev-box) + - Fat binary releases for [multiple platforms](https://rubygems.org/gems/concurrent-ruby/versions) including Windows (32/64), Linux (32/64), OS X (64-bit), Solaris (64-bit), and JRuby +* C native `CAtomicBoolean` +* C native `CAtomicFixnum` +* Refactored intermittently failing tests +* Added `dataflow!` and `dataflow_with!` methods to match `Future#value!` method +* Better handling of timeout in `Agent` +* Actor Improvements + - Fine-grained implementation using chain of behaviors. Each behavior is responsible for single aspect like: `Termination`, `Pausing`, `Linking`, `Supervising`, etc. Users can create custom Actors easily based on their needs. + - Supervision was added. `RestartingContext` will pause on error waiting on its supervisor to decide what to do next ( options are `:terminate!`, `:resume!`, `:reset!`, `:restart!`). Supervising behavior also supports strategies `:one_for_one` and `:one_for_all`. + - Linking was added to be able to monitor actor's events like: `:terminated`, `:paused`, `:restarted`, etc. + - Dead letter routing added. Rejected envelopes are collected in a configurable actor (default: `Concurrent::Actor.root.ask!(:dead_letter_routing)`) + - Old `Actor` class removed and replaced by new implementation previously called `Actress`. `Actress` was kept as an alias for `Actor` to keep compatibility. + - `Utils::Broadcast` actor which allows Publish–subscribe pattern. +* More executors for managing serialized operations + - `SerializedExecution` mixin module + - `SerializedExecutionDelegator` for serializing *any* executor +* Updated `Async` with serialized execution +* Updated `ImmediateExecutor` and `PerThreadExecutor` with full executor service lifecycle +* Added a `Delay` to root `Actress` initialization +* Minor bug fixes to thread pools +* Refactored many intermittently failing specs +* Removed Java interop warning `executor.rb:148 warning: ambiguous Java methods found, using submit(java.lang.Runnable)` +* Fixed minor bug in `RubyCachedThreadPool` overflow policy +* Updated tests to use [RSpec 3.0](http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3) +* Removed deprecated `Actor` class +* Better support for Rubinius + +## Release v0.6.1 (14 June 2014) + +* Many improvements to `Concurrent::Actress` +* Bug fixes to `Concurrent::RubyThreadPoolExecutor` +* Fixed several brittle tests +* Moved documentation to http://ruby-concurrency.github.io/concurrent-ruby/frames.html + +## Release v0.6.0 (25 May 2014) + +* Added `Concurrent::Observable` to encapsulate our thread safe observer sets +* Improvements to new `Channel` +* Major improvements to `CachedThreadPool` and `FixedThreadPool` +* Added `SingleThreadExecutor` +* Added `Current::timer` function +* Added `TimerSet` executor +* Added `AtomicBoolean` +* `ScheduledTask` refactoring +* Pure Ruby and JRuby-optimized `PriorityQueue` classes +* Updated `Agent` behavior to more closely match Clojure +* Observer sets support block callbacks to the `add_observer` method +* New algorithm for thread creation in `RubyThreadPoolExecutor` +* Minor API updates to `Event` +* Rewritten `TimerTask` now an `Executor` instead of a `Runnable` +* Fixed many brittle specs +* Renamed `FixedThreadPool` and `CachedThreadPool` to `RubyFixedThreadPool` and `RubyCachedThreadPool` +* Created JRuby optimized `JavaFixedThreadPool` and `JavaCachedThreadPool` +* Consolidated fixed thread pool tests into `spec/concurrent/fixed_thread_pool_shared.rb` and `spec/concurrent/cached_thread_pool_shared.rb` +* `FixedThreadPool` now subclasses `RubyFixedThreadPool` or `JavaFixedThreadPool` as appropriate +* `CachedThreadPool` now subclasses `RubyCachedThreadPool` or `JavaCachedThreadPool` as appropriate +* New `Delay` class +* `Concurrent::processor_count` helper function +* New `Async` module +* Renamed `NullThreadPool` to `PerThreadExecutor` +* Deprecated `Channel` (we are planning a new implementation based on [Go](http://golangtutorials.blogspot.com/2011/06/channels-in-go.html)) +* Added gem-level [configuration](http://robots.thoughtbot.com/mygem-configure-block) +* Deprecated `$GLOBAL_THREAD_POOL` in lieu of gem-level configuration +* Removed support for Ruby [1.9.2](https://www.ruby-lang.org/en/news/2013/12/17/maintenance-of-1-8-7-and-1-9-2/) +* New `RubyThreadPoolExecutor` and `JavaThreadPoolExecutor` classes +* All thread pools now extend the appropriate thread pool executor classes +* All thread pools now support `:overflow_policy` (based on Java's [reject policies](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html)) +* Deprecated `UsesGlobalThreadPool` in lieu of explicit `:executor` option (dependency injection) on `Future`, `Promise`, and `Agent` +* Added `Concurrent::dataflow_with(executor, *inputs)` method to support executor dependency injection for dataflow +* Software transactional memory with `TVar` and `Concurrent::atomically` +* First implementation of [new, high-performance](https://github.com/ruby-concurrency/concurrent-ruby/pull/49) `Channel` +* `Actor` is deprecated in favor of new experimental actor implementation [#73](https://github.com/ruby-concurrency/concurrent-ruby/pull/73). To avoid namespace collision it is living in `Actress` namespace until `Actor` is removed in next release. + +## Release v0.5.0 + +This is the most significant release of this gem since its inception. This release includes many improvements and optimizations. It also includes several bug fixes. The major areas of focus for this release were: + +* Stability improvements on Ruby versions with thread-level parallelism ([JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) +* Creation of new low-level concurrency abstractions +* Internal refactoring to use the new low-level abstractions + +Most of these updates had no effect on the gem API. There are a few notable exceptions which were unavoidable. Please read the [release notes](API-Updates-in-v0.5.0) for more information. + +Specific changes include: + +* New class `IVar` +* New class `MVar` +* New class `ThreadLocalVar` +* New class `AtomicFixnum` +* New class method `dataflow` +* New class `Condition` +* New class `CountDownLatch` +* New class `DependencyCounter` +* New class `SafeTaskExecutor` +* New class `CopyOnNotifyObserverSet` +* New class `CopyOnWriteObserverSet` +* `Future` updated with `execute` API +* `ScheduledTask` updated with `execute` API +* New `Promise` API +* `Future` now extends `IVar` +* `Postable#post?` now returns an `IVar` +* Thread safety fixes to `Dereferenceable` +* Thread safety fixes to `Obligation` +* Thread safety fixes to `Supervisor` +* Thread safety fixes to `Event` +* Various other thread safety (race condition) fixes +* Refactored brittle tests +* Implemented pending tests +* Added JRuby and Rubinius as Travis CI build targets +* Added [CodeClimate](https://codeclimate.com/) code review +* Improved YARD documentation diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Gemfile b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Gemfile new file mode 100644 index 0000000..1786c8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Gemfile @@ -0,0 +1,36 @@ +source 'https://rubygems.org' + +version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise +edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise + +no_path = ENV['NO_PATH'] +options = no_path ? {} : { path: '.' } + +gem 'concurrent-ruby', version, options +gem 'concurrent-ruby-edge', edge_version, options +gem 'concurrent-ruby-ext', version, options.merge(platform: :mri) + +group :development do + gem 'rake', '~> 13.0' + gem 'rake-compiler', '~> 1.0', '>= 1.0.7', '!= 1.2.4' + gem 'rake-compiler-dock', '~> 1.0' + gem 'pry', '~> 0.11', platforms: :mri +end + +group :documentation, optional: true do + gem 'yard', '~> 0.9.0', require: false + gem 'redcarpet', '~> 3.0', platforms: :mri # understands github markdown + gem 'md-ruby-eval', '~> 0.6' +end + +group :testing do + gem 'rspec', '~> 3.7' + gem 'timecop', '~> 0.9' + gem 'sigdump', require: false +end + +# made opt-in since it will not install on jruby 1.7 +group :coverage, optional: !ENV['COVERAGE'] do + gem 'simplecov', '~> 0.16.0', require: false + gem 'coveralls', '~> 0.8.2', require: false +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/LICENSE.txt new file mode 100644 index 0000000..1026f28 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) Jerry D'Antonio -- released under the MIT license. + +http://www.opensource.org/licenses/mit-license.php + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/README.md b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/README.md new file mode 100644 index 0000000..daf3eac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/README.md @@ -0,0 +1,409 @@ +# Concurrent Ruby + +[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby) +[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT) +[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby) + +Modern concurrency tools for Ruby. Inspired by +[Erlang](http://www.erlang.org/doc/reference_manual/processes.html), +[Clojure](http://clojure.org/concurrent_programming), +[Scala](http://akka.io/), +[Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell), +[F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx), +[C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx), +[Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html), +and classic concurrency patterns. + + + +The design goals of this gem are: + +* Be an 'unopinionated' toolbox that provides useful utilities without debating which is better + or why +* Remain free of external gem dependencies +* Stay true to the spirit of the languages providing inspiration +* But implement in a way that makes sense for Ruby +* Keep the semantics as idiomatic Ruby as possible +* Support features that make sense in Ruby +* Exclude features that don't make sense in Ruby +* Be small, lean, and loosely coupled +* Thread-safety +* Backward compatibility + +## Contributing + +**This gem depends on +[contributions](https://github.com/ruby-concurrency/concurrent-ruby/graphs/contributors) and we +appreciate your help. Would you like to contribute? Great! Have a look at +[issues with `looking-for-contributor` label](https://github.com/ruby-concurrency/concurrent-ruby/issues?q=is%3Aissue+is%3Aopen+label%3Alooking-for-contributor).** And if you pick something up let us know on the issue. + +You can also get started by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to concurrent-ruby on CodeTriage](https://www.codetriage.com/ruby-concurrency/concurrent-ruby). [![Open Source Helpers](https://www.codetriage.com/ruby-concurrency/concurrent-ruby/badges/users.svg)](https://www.codetriage.com/ruby-concurrency/concurrent-ruby) + +## Thread Safety + +*Concurrent Ruby makes one of the strongest thread safety guarantees of any Ruby concurrency +library, providing consistent behavior and guarantees on all three main Ruby interpreters +(MRI/CRuby, JRuby, TruffleRuby).* + +Every abstraction in this library is thread safe. Specific thread safety guarantees are documented +with each abstraction. + +It is critical to remember, however, that Ruby is a language of mutable references. *No* +concurrency library for Ruby can ever prevent the user from making thread safety mistakes (such as +sharing a mutable object between threads and modifying it on both threads) or from creating +deadlocks through incorrect use of locks. All the library can do is provide safe abstractions which +encourage safe practices. Concurrent Ruby provides more safe concurrency abstractions than any +other Ruby library, many of which support the mantra of +["Do not communicate by sharing memory; instead, share memory by communicating"](https://blog.golang.org/share-memory-by-communicating). +Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and +immutable variable types and data structures. + +We've also initiated discussion to document the [memory model](docs-source/synchronization.md) of Ruby which +would provide consistent behaviour and guarantees on all three main Ruby interpreters +(MRI/CRuby, JRuby, TruffleRuby). + +## Features & Documentation + +**The primary site for documentation is the automatically generated +[API documentation](http://ruby-concurrency.github.io/concurrent-ruby/index.html) which is up to +date with latest release.** This readme matches the master so may contain new stuff not yet +released. + +We also have a [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby). + +### Versioning + +* `concurrent-ruby` uses [Semantic Versioning](http://semver.org/) +* `concurrent-ruby-ext` has always same version as `concurrent-ruby` +* `concurrent-ruby-edge` will always be 0.y.z therefore following + [point 4](http://semver.org/#spec-item-4) applies *"Major version zero + (0.y.z) is for initial development. Anything may change at any time. The + public API should not be considered stable."* However we additionally use + following rules: + * Minor version increment means incompatible changes were made + * Patch version increment means only compatible changes were made + + +#### General-purpose Concurrency Abstractions + +* [Async](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Async.html): + A mixin module that provides simple asynchronous behavior to a class. Loosely based on Erlang's + [gen_server](http://www.erlang.org/doc/man/gen_server.html). +* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ScheduledTask.html): + Like a Future scheduled for a specific future time. +* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TimerTask.html): + A Thread that periodically wakes up to perform work at regular intervals. +* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html): + Unified implementation of futures and promises which combines features of previous `Future`, + `Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and (partially) `TimerTask` into a single + framework. It extensively uses the new synchronization layer to make all the features + **non-blocking** and **lock-free**, with the exception of obviously blocking operations like + `#wait`, `#value`. It also offers better performance. + +#### Thread-safe Value Objects, Structures, and Collections + +Collection classes that were originally part of the (deprecated) `thread_safe` gem: + +* [Array](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Array.html) A thread-safe + subclass of Ruby's standard [Array](http://ruby-doc.org/core/Array.html). +* [Hash](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Hash.html) A thread-safe + subclass of Ruby's standard [Hash](http://ruby-doc.org/core/Hash.html). +* [Set](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Set.html) A thread-safe + subclass of Ruby's standard [Set](http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html). +* [Map](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Map.html) A hash-like object + that should have much better performance characteristics, especially under high concurrency, + than `Concurrent::Hash`. +* [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Tuple.html) A fixed size + array with volatile (synchronized, thread safe) getters/setters. + +Value objects inspired by other languages: + +* [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Maybe.html) A thread-safe, + immutable object representing an optional value, based on + [Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html). + +Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core/Struct.html): + +* [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ImmutableStruct.html) + Immutable struct where values are set at construction and cannot be changed later. +* [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MutableStruct.html) + Synchronized, mutable struct where values can be safely changed at any time. +* [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/SettableStruct.html) + Synchronized, write-once struct where values can be set at most once, either at construction + or any time thereafter. + +Thread-safe variables: + +* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Agent.html): A way to + manage shared, mutable, *asynchronous*, independent state. Based on Clojure's + [Agent](http://clojure.org/agents). +* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Atom.html): A way to manage + shared, mutable, *synchronous*, independent state. Based on Clojure's + [Atom](http://clojure.org/atoms). +* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicBoolean.html) + A boolean value that can be updated atomically. +* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicFixnum.html) + A numeric value that can be updated atomically. +* [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicReference.html) + An object reference that may be updated atomically. +* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Exchanger.html) + A synchronization point at which threads can pair and swap elements within pairs. Based on + Java's [Exchanger](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html). +* [MVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MVar.html) A synchronized + single element container. Based on Haskell's + [MVar](https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent-MVar.html) and + Scala's [MVar](http://docs.typelevel.org/api/scalaz/nightly/index.html#scalaz.concurrent.MVar$). +* [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ThreadLocalVar.html) + A variable where the value is different for each thread. +* [TVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TVar.html) A transactional + variable implementing software transactional memory (STM). Based on Clojure's + [Ref](http://clojure.org/refs). + +#### Java-inspired ThreadPools and Other Executors + +* See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/master/file.thread_pools.html) + overview, which also contains a list of other Executors available. + +#### Thread Synchronization Classes and Algorithms + +* [CountDownLatch](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CountDownLatch.html) + A synchronization object that allows one thread to wait on multiple other threads. +* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CyclicBarrier.html) + A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. +* [Event](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Event.html) Old school + kernel-style event. +* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReadWriteLock.html) + A lock that supports multiple readers but only one writer. +* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReentrantReadWriteLock.html) + A read/write lock with reentrant and upgrade features. +* [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Semaphore.html) + A counting-based locking mechanism that uses permits. +* [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicMarkableReference.html) + +#### Deprecated + +Deprecated features are still available and bugs are being fixed, but new features will not be added. + +* ~~[Future](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Future.html): + An asynchronous operation that produces a value.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). + * ~~[.dataflow](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html#dataflow-class_method): + Built on Futures, Dataflow allows you to create a task that will be scheduled when all of + its data dependencies are available.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). +* ~~[Promise](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promise.html): Similar + to Futures, with more features.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). +* ~~[Delay](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Delay.html) Lazy evaluation + of a block yielding an immutable result. Based on Clojure's + [delay](https://clojuredocs.org/clojure.core/delay).~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). +* ~~[IVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/IVar.html) Similar to a + "future" but can be manually assigned once, after which it becomes immutable.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). + +### Edge Features + +These are available in the `concurrent-ruby-edge` companion gem. + +These features are under active development and may change frequently. They are expected not to +keep backward compatibility (they may also lack tests and documentation). Semantic versions will +be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to +`concurrent-ruby` when final. + +* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Actor.html): Implements + the Actor Model, where concurrent actors exchange messages. + *Status: Partial documentation and tests; depends on new future/promise framework; stability is good.* +* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Channel.html): + Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)). + Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional + inspiration from Clojure [core.async](https://clojure.github.io/core.async/). + *Status: Partial documentation and tests.* +* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LazyRegister.html) +* [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Edge/LockFreeLinkedSet.html) + *Status: will be moved to core soon.* +* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LockFreeStack.html) + *Status: missing documentation and tests.* +* [Promises::Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises/Channel.html) + A first in first out channel that accepts messages with push family of methods and returns + messages with pop family of methods. + Pop and push operations can be represented as futures, see `#pop_op` and `#push_op`. + The capacity of the channel can be limited to support back pressure, use capacity option in `#initialize`. + `#pop` method blocks ans `#pop_op` returns pending future if there is no message in the channel. + If the capacity is limited the `#push` method blocks and `#push_op` returns pending future. +* [Cancellation](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Cancellation.html) + The Cancellation abstraction provides cooperative cancellation. + + The standard methods `Thread#raise` of `Thread#kill` available in Ruby + are very dangerous (see linked the blog posts bellow). + Therefore concurrent-ruby provides an alternative. + + * + * + * + + It provides an object which represents a task which can be executed, + the task has to get the reference to the object and periodically cooperatively check that it is not cancelled. + Good practices to make tasks cancellable: + * check cancellation every cycle of a loop which does significant work, + * do all blocking actions in a loop with a timeout then on timeout check cancellation + and if ok block again with the timeout +* [Throttle](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Throttle.html) + A tool managing concurrency level of tasks. +* [ErlangActor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ErlangActor.html) + Actor implementation which precisely matches Erlang actor behaviour. + Requires at least Ruby 2.1 otherwise it's not loaded. +* [WrappingExecutor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/WrappingExecutor.html) + A delegating executor which modifies each task before the task is given to + the target executor it delegates to. + +## Supported Ruby versions + +* MRI 2.3 and above +* Latest JRuby 9000 +* Latest TruffleRuby + +## Usage + +Everything within this gem can be loaded simply by requiring it: + +```ruby +require 'concurrent' +``` + +You can also require a specific abstraction [part of the public documentation](https://ruby-concurrency.github.io/concurrent-ruby/master/index.html) since concurrent-ruby 1.2.0, for example: +```ruby +require 'concurrent/map' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/executor/fixed_thread_pool' +``` + +To use the tools in the Edge gem it must be required separately: + +```ruby +require 'concurrent-edge' +``` + +If the library does not behave as expected, `Concurrent.use_simple_logger(:DEBUG)` could +help to reveal the problem. + +## Installation + +```shell +gem install concurrent-ruby +``` + +or add the following line to Gemfile: + +```ruby +gem 'concurrent-ruby', require: 'concurrent' +``` + +and run `bundle install` from your shell. + +### Edge Gem Installation + +The Edge gem must be installed separately from the core gem: + +```shell +gem install concurrent-ruby-edge +``` + +or add the following line to Gemfile: + +```ruby +gem 'concurrent-ruby-edge', require: 'concurrent-edge' +``` + +and run `bundle install` from your shell. + + +### C Extensions for MRI + +Potential performance improvements may be achieved under MRI by installing optional C extensions. +To minimise installation errors the C extensions are available in the `concurrent-ruby-ext` +extension gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same +version. Simply install the extension gem too: + +```ruby +gem install concurrent-ruby-ext +``` + +or add the following line to Gemfile: + +```ruby +gem 'concurrent-ruby-ext' +``` + +and run `bundle install` from your shell. + +In code it is only necessary to + +```ruby +require 'concurrent' +``` + +The `concurrent-ruby` gem will automatically detect the presence of the `concurrent-ruby-ext` gem +and load the appropriate C extensions. + +#### Note For gem developers + +No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The +best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions. + +## Building the gem + +### Requirements + +* Recent CRuby +* JRuby, `rbenv install jruby-9.2.17.0` +* Set env variable `CONCURRENT_JRUBY_HOME` to point to it, e.g. `/usr/local/opt/rbenv/versions/jruby-9.2.17.0` +* Install Docker or Podman, required for Windows builds +* If `bundle config get path` is set, use `bundle config set --local path.system true` otherwise the `gem name, path: '.'` gems won't be found (Bundler limitation). + +### Publishing the Gem + +* Update `version.rb` +* Update the CHANGELOG +* Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the documentation. +* Commit (and push) the changes. +* Use `bundle exec rake release` to release the gem. + It consists of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps. + It will ask at the end before publishing anything. Steps can also be executed individually. + +## Maintainers + +* [Benoit Daloze](https://github.com/eregon) +* [Matthew Draper](https://github.com/matthewd) +* [Rafael França](https://github.com/rafaelfranca) +* [Charles Oliver Nutter](https://github.com/headius) +* [Ben Sheldon](https://github.com/bensheldon) +* [Samuel Williams](https://github.com/ioquatix) +* [Joshua Young](https://github.com/joshuay03) + +### Special Thanks to + +* [Jerry D'Antonio](https://github.com/jdantonio) for creating the gem +* [Brian Durand](https://github.com/bdurand) for the `ref` gem +* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems +* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem + +to the past maintainers + +* [Chris Seaton](https://github.com/chrisseaton) +* [Petr Chalupa](https://github.com/pitr-ch) +* [Michele Della Torre](https://github.com/mighe) +* [Paweł Obrok](https://github.com/obrok) +* [Lucas Allan](https://github.com/lucasallan) + +and to [Ruby Association](https://www.ruby.or.jp/en/) for sponsoring a project +["Enhancing Ruby’s concurrency tooling"](https://www.ruby.or.jp/en/news/20181106) in 2018. + +## License and Copyright + +*Concurrent Ruby* is free software released under the +[MIT License](http://www.opensource.org/licenses/MIT). + +The *Concurrent Ruby* [logo](https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/docs-source/logo/concurrent-ruby-logo-300x300.png) was +designed by [David Jones](https://twitter.com/zombyboy). It is Copyright © 2014 +[Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved. diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Rakefile b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Rakefile new file mode 100644 index 0000000..7c459fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/Rakefile @@ -0,0 +1,343 @@ +version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise +edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise + +core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec') +ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec') +edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.gemspec') + +require 'rake/javaextensiontask' + +ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && RUBY_ENGINE != 'jruby' + +Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext| + ext.ext_dir = 'ext/concurrent-ruby' + ext.lib_dir = 'lib/concurrent-ruby/concurrent' + ext.source_version = '8' + ext.target_version = '8' +end + +if RUBY_ENGINE == 'ruby' + require 'rake/extensiontask' + + Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext| + ext.ext_dir = 'ext/concurrent-ruby-ext' + ext.lib_dir = 'lib/concurrent-ruby/concurrent' + ext.source_pattern = '*.{c,h}' + + ext.cross_compile = true + ext.cross_platform = ['x86-mingw32', 'x64-mingw32'] + end +end + +def which?(executable) + !`which #{executable} 2>/dev/null`.empty? +end + +require 'rake_compiler_dock' +namespace :repackage do + desc '* with Windows fat distributions' + task :all do + Dir.chdir(__dir__) do + # store gems in vendor cache for docker + Bundler.with_original_env do + sh 'bundle package' + end + + # build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem + Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke + + # build all gem files + rack_compiler_dock_kwargs = {} + if which?('podman') and (!which?('docker') || `docker --version`.include?('podman')) + # podman and only podman available, so RakeCompilerDock will use podman, otherwise it uses docker + rack_compiler_dock_kwargs = { + options: ['--privileged'], # otherwise the directory in the image is empty + runas: false + } + end + %w[x86-mingw32 x64-mingw32].each do |plat| + RakeCompilerDock.sh( + "bundle install --local && bundle exec rake native:#{plat} gem --trace", + platform: plat, + **rack_compiler_dock_kwargs) + end + end + end +end + +require 'rubygems' +require 'rubygems/package_task' + +Gem::PackageTask.new(core_gemspec) {} if core_gemspec +Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && RUBY_ENGINE != 'jruby' +Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec + +CLEAN.include( + 'lib/concurrent-ruby/concurrent/concurrent_ruby_ext.*', + 'lib/concurrent-ruby/concurrent/2.*', + 'lib/concurrent-ruby/concurrent/*.jar') + +begin + require 'rspec' + require 'rspec/core/rake_task' + + RSpec::Core::RakeTask.new(:spec) + + namespace :spec do + desc '* Configured for ci' + RSpec::Core::RakeTask.new(:ci) do |t| + options = %w[ --color + --backtrace + --order defined + --format documentation ] + t.rspec_opts = [*options].join(' ') + end + + desc '* test packaged and installed gems instead of local files' + task :installed do + Bundler.with_original_env do + Dir.chdir(__dir__) do + sh "gem install pkg/concurrent-ruby-#{version}.gem" + sh "gem install pkg/concurrent-ruby-ext-#{version}.gem" if RUBY_ENGINE == 'ruby' + sh "gem install pkg/concurrent-ruby-edge-#{edge_version}.gem" + ENV['NO_PATH'] = 'true' + sh 'bundle update' + sh 'bundle exec rake spec:ci' + end + end + end + end + + desc 'executed in CI' + task :ci => [:compile, 'spec:ci'] + + desc 'run each spec file in a separate process to help find missing requires' + task 'spec:isolated' do + glob = "#{ENV['DIR'] || 'spec'}/**/*_spec.rb" + from = ENV['FROM'] + env = { 'ISOLATED' => 'true' } + Dir[glob].each do |spec| + next if from and from != spec + from = nil if from == spec + + sh env, 'rspec', spec + end + end + + task :default => [:clobber, :compile, :spec] +rescue LoadError => e + puts 'RSpec is not installed, skipping test task definitions: ' + e.message +end + +current_yard_version_name = version + +begin + require 'yard' + require 'md_ruby_eval' + require_relative 'support/yard_full_types' + + common_yard_options = ['--no-yardopts', + '--no-document', + '--no-private', + '--embed-mixins', + '--markup', 'markdown', + '--title', 'Concurrent Ruby', + '--template', 'default', + '--template-path', 'yard-template', + '--default-return', 'undocumented'] + + desc 'Generate YARD Documentation (signpost, master)' + task :yard => ['yard:signpost', 'yard:master'] + + namespace :yard do + + desc '* eval markdown files' + task :eval_md do + Dir.chdir File.join(__dir__, 'docs-source') do + sh 'bundle exec md-ruby-eval --auto' + end + end + + task :update_readme do + Dir.chdir __dir__ do + content = File.read(File.join('README.md')). + gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_| + case $1 + when 'LockFreeLinkedSet' + "{Concurrent::Edge::#{$1} #{$1}}" + when '.dataflow' + '{Concurrent.dataflow Concurrent.dataflow}' + when 'thread pool' + '{file:thread_pools.md thread pool}' + else + "{Concurrent::#{$1} #{$1}}" + end + end + FileUtils.mkpath 'tmp' + File.write 'tmp/README.md', content + end + end + + define_yard_task = -> name do + output_dir = "docs/#{name}" + + removal_name = "remove.#{name}" + task removal_name do + Dir.chdir __dir__ do + FileUtils.rm_rf output_dir + end + end + + desc "* of #{name} into subdir #{name}" + YARD::Rake::YardocTask.new(name) do |yard| + yard.options.push( + '--output-dir', output_dir, + '--main', 'tmp/README.md', + *common_yard_options) + yard.files = ['./lib/concurrent-ruby/**/*.rb', + './lib/concurrent-ruby-edge/**/*.rb', + './ext/concurrent_ruby_ext/**/*.c', + '-', + 'docs-source/thread_pools.md', + 'docs-source/promises.out.md', + 'docs-source/medium-example.out.rb', + 'LICENSE.txt', + 'CHANGELOG.md'] + end + Rake::Task[name].prerequisites.push removal_name, + # 'yard:eval_md', + 'yard:update_readme' + end + + define_yard_task.call current_yard_version_name + define_yard_task.call 'master' + + desc "* signpost for versions" + YARD::Rake::YardocTask.new(:signpost) do |yard| + yard.options.push( + '--output-dir', 'docs', + '--main', 'docs-source/signpost.md', + *common_yard_options) + yard.files = ['no-lib'] + end + end + +rescue LoadError => e + puts 'YARD is not installed, skipping documentation task definitions: ' + e.message +end + +desc 'build, test, and publish the gem' +task :release => ['release:checks', 'release:build', 'release:test', 'release:publish'] + +namespace :release do + # Depends on environment of @pitr-ch + + task :checks do + raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME'] + + Dir.chdir(__dir__) do + sh 'test -z "$(git status --porcelain)"' do |ok, res| + unless ok + begin + status = `git status --porcelain` + STDOUT.puts 'There are local changes that you might want to commit.', status, 'Continue? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + exit 1 if input == 'n' + end + end + sh 'git fetch' + sh 'test $(git show-ref --verify --hash refs/heads/master) = ' + + '$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res| + unless ok + begin + STDOUT.puts 'Local master branch is not pushed to origin.', 'Continue? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + exit 1 if input == 'n' + end + end + end + end + + desc '* build all *.gem files necessary for release' + task :build => [:clobber, 'repackage:all'] + + desc '* test actual installed gems instead of cloned repository on MRI and JRuby' + task :test do + raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME'] + + Dir.chdir(__dir__) do + puts "Testing with the installed gem" + + Bundler.with_original_env do + sh 'ruby -v' + sh 'bundle install' + sh 'bundle exec rake spec:installed' + + env = { "PATH" => "#{ENV.fetch('CONCURRENT_JRUBY_HOME')}/bin:#{ENV['PATH']}" } + sh env, 'ruby -v' + sh env, 'bundle install' + sh env, 'bundle exec rake spec:installed' + end + + puts 'Windows build is untested' + end + end + + desc '* do all nested steps' + task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps'] + + namespace :publish do + publish_base = nil + publish_edge = nil + + task :ask do + begin + STDOUT.puts 'Do you want to publish anything now? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + exit 1 if input == 'n' + + begin + STDOUT.puts 'Do you want to publish `concurrent-ruby`? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + publish_base = input == 'y' + + begin + STDOUT.puts 'Do you want to publish `concurrent-ruby-edge`? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + publish_edge = input == 'y' + end + + desc '** tag HEAD with current version and push to github' + task :tag => :ask do + Dir.chdir(__dir__) do + sh "git tag v#{version}" if publish_base + sh "git push origin v#{version}" if publish_base + sh "git tag edge-v#{edge_version}" if publish_edge + sh "git push origin edge-v#{edge_version}" if publish_edge + end + end + + desc '** push all *.gem files to rubygems' + task :rubygems => :ask do + Dir.chdir(__dir__) do + sh "gem push pkg/concurrent-ruby-#{version}.gem" if publish_base + sh "gem push pkg/concurrent-ruby-edge-#{edge_version}.gem" if publish_edge + sh "gem push pkg/concurrent-ruby-ext-#{version}.gem" if publish_base + sh "gem push pkg/concurrent-ruby-ext-#{version}-x64-mingw32.gem" if publish_base + sh "gem push pkg/concurrent-ruby-ext-#{version}-x86-mingw32.gem" if publish_base + end + end + + desc '** print post release steps' + task :post_steps do + puts + puts 'Manually: create a release on GitHub, use the "Generate release notes" button' + puts 'Manually: tweet' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/ConcurrentRubyService.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/ConcurrentRubyService.java new file mode 100644 index 0000000..fb6be96 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/ConcurrentRubyService.java @@ -0,0 +1,17 @@ +import org.jruby.Ruby; +import org.jruby.runtime.load.BasicLibraryService; + +import java.io.IOException; + +public class ConcurrentRubyService implements BasicLibraryService { + + public boolean basicLoad(final Ruby runtime) throws IOException { + new com.concurrent_ruby.ext.AtomicReferenceLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JavaAtomicBooleanLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JavaAtomicFixnumLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JavaSemaphoreLibrary().load(runtime, false); + new com.concurrent_ruby.ext.SynchronizationLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JRubyMapBackendLibrary().load(runtime, false); + return true; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java new file mode 100644 index 0000000..4265b56 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java @@ -0,0 +1,140 @@ +package com.concurrent_ruby.ext; + +import static org.jruby.runtime.Visibility.PRIVATE; + +import java.lang.reflect.Field; +import java.io.IOException; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; + +/** + * This library adds an atomic reference type to JRuby for use in the atomic + * library. We do a native version to avoid the implicit value coercion that + * normally happens through JI. + * + * @author headius + */ +public class AtomicReferenceLibrary implements Library { + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicReference", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + try { + sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class); + atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR); + } catch (Exception e) { + // leave it as Java 6/7 version + } + atomicCls.defineAnnotatedMethods(JRubyReference.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyReference(runtime, klazz); + } + }; + + private static final ObjectAllocator JRUBYREFERENCE8_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyReference8(runtime, klazz); + } + }; + + @JRubyClass(name="JRubyReference", parent="Object") + public static class JRubyReference extends RubyObject { + volatile IRubyObject reference; + + static final sun.misc.Unsafe UNSAFE; + static final long referenceOffset; + + static { + try { + UNSAFE = UnsafeHolder.U; + Class k = JRubyReference.class; + referenceOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("reference")); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public JRubyReference(Ruby runtime, RubyClass klass) { + super(runtime, klass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + UNSAFE.putObject(this, referenceOffset, context.nil); + return context.nil; + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + UNSAFE.putObject(this, referenceOffset, value); + return context.nil; + } + + @JRubyMethod(name = {"get", "value"}) + public IRubyObject get() { + return reference; + } + + @JRubyMethod(name = {"set", "value="}) + public IRubyObject set(IRubyObject newValue) { + UNSAFE.putObjectVolatile(this, referenceOffset, newValue); + return newValue; + } + + @JRubyMethod(name = "_compare_and_set", visibility = PRIVATE) + public IRubyObject compare_and_set(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) { + Ruby runtime = context.runtime; + return runtime.newBoolean(UNSAFE.compareAndSwapObject(this, referenceOffset, expectedValue, newValue)); + } + + @JRubyMethod(name = {"get_and_set", "swap"}) + public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) { + // less-efficient version for Java 6 and 7 + while (true) { + IRubyObject oldValue = get(); + if (UNSAFE.compareAndSwapObject(this, referenceOffset, oldValue, newValue)) { + return oldValue; + } + } + } + } + + private static final class UnsafeHolder { + private UnsafeHolder(){} + + public static final sun.misc.Unsafe U = loadUnsafe(); + + private static sun.misc.Unsafe loadUnsafe() { + try { + Class unsafeClass = Class.forName("sun.misc.Unsafe"); + Field f = unsafeClass.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (sun.misc.Unsafe) f.get(null); + } catch (Exception e) { + return null; + } + } + } + + public static class JRubyReference8 extends JRubyReference { + public JRubyReference8(Ruby runtime, RubyClass klass) { + super(runtime, klass); + } + + @Override + public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) { + // efficient version for Java 8 + return (IRubyObject)UNSAFE.getAndSetObject(this, referenceOffset, newValue); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java new file mode 100644 index 0000000..a09f916 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java @@ -0,0 +1,248 @@ +package com.concurrent_ruby.ext; + +import org.jruby.*; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMap; +import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8; +import com.concurrent_ruby.ext.jsr166e.nounsafe.*; +import org.jruby.runtime.Block; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; + +import java.io.IOException; +import java.util.Map; + +import static org.jruby.runtime.Visibility.PRIVATE; + +/** + * Native Java implementation to avoid the JI overhead. + * + * @author thedarkone + */ +public class JRubyMapBackendLibrary implements Library { + public void load(Ruby runtime, boolean wrap) throws IOException { + + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyModule thread_safeMod = concurrentMod.defineModuleUnder("Collection"); + RubyClass jrubyRefClass = thread_safeMod.defineClassUnder("JRubyMapBackend", runtime.getObject(), BACKEND_ALLOCATOR); + jrubyRefClass.setAllocator(BACKEND_ALLOCATOR); + jrubyRefClass.defineAnnotatedMethods(JRubyMapBackend.class); + } + + private static final ObjectAllocator BACKEND_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyMapBackend(runtime, klazz); + } + }; + + @JRubyClass(name="JRubyMapBackend", parent="Object") + public static class JRubyMapBackend extends RubyObject { + // Defaults used by the CHM + static final int DEFAULT_INITIAL_CAPACITY = 16; + static final float DEFAULT_LOAD_FACTOR = 0.75f; + + public static final boolean CAN_USE_UNSAFE_CHM = canUseUnsafeCHM(); + + private ConcurrentHashMap map; + + private static ConcurrentHashMap newCHM(int initialCapacity, float loadFactor) { + if (CAN_USE_UNSAFE_CHM) { + return new ConcurrentHashMapV8(initialCapacity, loadFactor); + } else { + return new com.concurrent_ruby.ext.jsr166e.nounsafe.ConcurrentHashMapV8(initialCapacity, loadFactor); + } + } + + private static ConcurrentHashMap newCHM() { + return newCHM(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); + } + + private static boolean canUseUnsafeCHM() { + try { + new com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8(); // force class load and initialization + return true; + } catch (Throwable t) { // ensuring we really do catch everything + // Doug's Unsafe setup errors always have this "Could not ini.." message + if (isCausedBySecurityException(t)) { + return false; + } + throw (t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t)); + } + } + + private static boolean isCausedBySecurityException(Throwable t) { + while (t != null) { + if ((t.getMessage() != null && t.getMessage().contains("Could not initialize intrinsics")) || t instanceof SecurityException) { + return true; + } + t = t.getCause(); + } + return false; + } + + public JRubyMapBackend(Ruby runtime, RubyClass klass) { + super(runtime, klass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + map = newCHM(); + return context.getRuntime().getNil(); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject options) { + map = toCHM(context, options); + return context.getRuntime().getNil(); + } + + private ConcurrentHashMap toCHM(ThreadContext context, IRubyObject options) { + Ruby runtime = context.getRuntime(); + if (!options.isNil() && options.respondsTo("[]")) { + IRubyObject rInitialCapacity = options.callMethod(context, "[]", runtime.newSymbol("initial_capacity")); + IRubyObject rLoadFactor = options.callMethod(context, "[]", runtime.newSymbol("load_factor")); + int initialCapacity = !rInitialCapacity.isNil() ? RubyNumeric.num2int(rInitialCapacity.convertToInteger()) : DEFAULT_INITIAL_CAPACITY; + float loadFactor = !rLoadFactor.isNil() ? (float)RubyNumeric.num2dbl(rLoadFactor.convertToFloat()) : DEFAULT_LOAD_FACTOR; + return newCHM(initialCapacity, loadFactor); + } else { + return newCHM(); + } + } + + @JRubyMethod(name = "[]", required = 1) + public IRubyObject op_aref(ThreadContext context, IRubyObject key) { + IRubyObject value; + return ((value = map.get(key)) == null) ? context.getRuntime().getNil() : value; + } + + @JRubyMethod(name = {"[]="}, required = 2) + public IRubyObject op_aset(IRubyObject key, IRubyObject value) { + map.put(key, value); + return value; + } + + @JRubyMethod + public IRubyObject put_if_absent(IRubyObject key, IRubyObject value) { + IRubyObject result = map.putIfAbsent(key, value); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject compute_if_absent(final ThreadContext context, final IRubyObject key, final Block block) { + return map.computeIfAbsent(key, new ConcurrentHashMap.Fun() { + @Override + public IRubyObject apply(IRubyObject key) { + return block.yieldSpecific(context); + } + }); + } + + @JRubyMethod + public IRubyObject compute_if_present(final ThreadContext context, final IRubyObject key, final Block block) { + IRubyObject result = map.computeIfPresent(key, new ConcurrentHashMap.BiFun() { + @Override + public IRubyObject apply(IRubyObject key, IRubyObject oldValue) { + IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); + return result.isNil() ? null : result; + } + }); + return result == null ? context.getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject compute(final ThreadContext context, final IRubyObject key, final Block block) { + IRubyObject result = map.compute(key, new ConcurrentHashMap.BiFun() { + @Override + public IRubyObject apply(IRubyObject key, IRubyObject oldValue) { + IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); + return result.isNil() ? null : result; + } + }); + return result == null ? context.getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject merge_pair(final ThreadContext context, final IRubyObject key, final IRubyObject value, final Block block) { + IRubyObject result = map.merge(key, value, new ConcurrentHashMap.BiFun() { + @Override + public IRubyObject apply(IRubyObject oldValue, IRubyObject newValue) { + IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); + return result.isNil() ? null : result; + } + }); + return result == null ? context.getRuntime().getNil() : result; + } + + @JRubyMethod + public RubyBoolean replace_pair(IRubyObject key, IRubyObject oldValue, IRubyObject newValue) { + return getRuntime().newBoolean(map.replace(key, oldValue, newValue)); + } + + @JRubyMethod(name = "key?", required = 1) + public RubyBoolean has_key_p(IRubyObject key) { + return map.containsKey(key) ? getRuntime().getTrue() : getRuntime().getFalse(); + } + + @JRubyMethod + public IRubyObject key(IRubyObject value) { + final IRubyObject key = map.findKey(value); + return key == null ? getRuntime().getNil() : key; + } + + @JRubyMethod + public IRubyObject replace_if_exists(IRubyObject key, IRubyObject value) { + IRubyObject result = map.replace(key, value); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject get_and_set(IRubyObject key, IRubyObject value) { + IRubyObject result = map.put(key, value); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject delete(IRubyObject key) { + IRubyObject result = map.remove(key); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public RubyBoolean delete_pair(IRubyObject key, IRubyObject value) { + return getRuntime().newBoolean(map.remove(key, value)); + } + + @JRubyMethod + public IRubyObject clear() { + map.clear(); + return this; + } + + @JRubyMethod + public IRubyObject each_pair(ThreadContext context, Block block) { + for (Map.Entry entry : map.entrySet()) { + block.yieldSpecific(context, entry.getKey(), entry.getValue()); + } + return this; + } + + @JRubyMethod + public RubyFixnum size(ThreadContext context) { + return context.getRuntime().newFixnum(map.size()); + } + + @JRubyMethod + public IRubyObject get_or_default(IRubyObject key, IRubyObject defaultValue) { + return map.getValueOrDefault(key, defaultValue); + } + + @JRubyMethod(visibility = PRIVATE) + public JRubyMapBackend initialize_copy(ThreadContext context, IRubyObject other) { + map = newCHM(); + return this; + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java new file mode 100644 index 0000000..b566076 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java @@ -0,0 +1,93 @@ +package com.concurrent_ruby.ext; + +import org.jruby.Ruby; +import org.jruby.RubyBoolean; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.RubyNil; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class JavaAtomicBooleanLibrary implements Library { + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicBoolean", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + atomicCls.defineAnnotatedMethods(JavaAtomicBoolean.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JavaAtomicBoolean(runtime, klazz); + } + }; + + @JRubyClass(name = "JavaAtomicBoolean", parent = "Object") + public static class JavaAtomicBoolean extends RubyObject { + + private AtomicBoolean atomicBoolean; + + public JavaAtomicBoolean(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + atomicBoolean = new AtomicBoolean(convertRubyBooleanToJavaBoolean(value)); + return context.nil; + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + atomicBoolean = new AtomicBoolean(); + return context.nil; + } + + @JRubyMethod(name = "value") + public IRubyObject value() { + return getRuntime().newBoolean(atomicBoolean.get()); + } + + @JRubyMethod(name = "true?") + public IRubyObject isAtomicTrue() { + return getRuntime().newBoolean(atomicBoolean.get()); + } + + @JRubyMethod(name = "false?") + public IRubyObject isAtomicFalse() { + return getRuntime().newBoolean((atomicBoolean.get() == false)); + } + + @JRubyMethod(name = "value=") + public IRubyObject setAtomic(ThreadContext context, IRubyObject newValue) { + atomicBoolean.set(convertRubyBooleanToJavaBoolean(newValue)); + return context.nil; + } + + @JRubyMethod(name = "make_true") + public IRubyObject makeTrue() { + return getRuntime().newBoolean(atomicBoolean.compareAndSet(false, true)); + } + + @JRubyMethod(name = "make_false") + public IRubyObject makeFalse() { + return getRuntime().newBoolean(atomicBoolean.compareAndSet(true, false)); + } + + private boolean convertRubyBooleanToJavaBoolean(IRubyObject newValue) { + if (newValue instanceof RubyBoolean.False || newValue instanceof RubyNil) { + return false; + } else { + return true; + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java new file mode 100644 index 0000000..672bfc0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java @@ -0,0 +1,113 @@ +package com.concurrent_ruby.ext; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicLong; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyFixnum; +import org.jruby.RubyModule; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; +import org.jruby.runtime.Block; + +public class JavaAtomicFixnumLibrary implements Library { + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicFixnum", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + + atomicCls.defineAnnotatedMethods(JavaAtomicFixnum.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JavaAtomicFixnum(runtime, klazz); + } + }; + + @JRubyClass(name = "JavaAtomicFixnum", parent = "Object") + public static class JavaAtomicFixnum extends RubyObject { + + private AtomicLong atomicLong; + + public JavaAtomicFixnum(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + this.atomicLong = new AtomicLong(0); + return context.nil; + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + this.atomicLong = new AtomicLong(rubyFixnumToLong(value)); + return context.nil; + } + + @JRubyMethod(name = "value") + public IRubyObject getValue() { + return getRuntime().newFixnum(atomicLong.get()); + } + + @JRubyMethod(name = "value=") + public IRubyObject setValue(ThreadContext context, IRubyObject newValue) { + atomicLong.set(rubyFixnumToLong(newValue)); + return context.nil; + } + + @JRubyMethod(name = {"increment", "up"}) + public IRubyObject increment() { + return getRuntime().newFixnum(atomicLong.incrementAndGet()); + } + + @JRubyMethod(name = {"increment", "up"}) + public IRubyObject increment(IRubyObject value) { + long delta = rubyFixnumToLong(value); + return getRuntime().newFixnum(atomicLong.addAndGet(delta)); + } + + @JRubyMethod(name = {"decrement", "down"}) + public IRubyObject decrement() { + return getRuntime().newFixnum(atomicLong.decrementAndGet()); + } + + @JRubyMethod(name = {"decrement", "down"}) + public IRubyObject decrement(IRubyObject value) { + long delta = rubyFixnumToLong(value); + return getRuntime().newFixnum(atomicLong.addAndGet(-delta)); + } + + @JRubyMethod(name = "compare_and_set") + public IRubyObject compareAndSet(ThreadContext context, IRubyObject expect, IRubyObject update) { + return getRuntime().newBoolean(atomicLong.compareAndSet(rubyFixnumToLong(expect), rubyFixnumToLong(update))); + } + + @JRubyMethod + public IRubyObject update(ThreadContext context, Block block) { + for (;;) { + long _oldValue = atomicLong.get(); + IRubyObject oldValue = getRuntime().newFixnum(_oldValue); + IRubyObject newValue = block.yield(context, oldValue); + if (atomicLong.compareAndSet(_oldValue, rubyFixnumToLong(newValue))) { + return newValue; + } + } + } + + private long rubyFixnumToLong(IRubyObject value) { + if (value instanceof RubyFixnum) { + RubyFixnum fixNum = (RubyFixnum) value; + return fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError("value must be a Fixnum"); + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java new file mode 100644 index 0000000..d887f25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java @@ -0,0 +1,189 @@ +package com.concurrent_ruby.ext; + +import java.io.IOException; +import java.util.concurrent.Semaphore; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyFixnum; +import org.jruby.RubyModule; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.Block; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +public class JavaSemaphoreLibrary { + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaSemaphore", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + + atomicCls.defineAnnotatedMethods(JavaSemaphore.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JavaSemaphore(runtime, klazz); + } + }; + + @JRubyClass(name = "JavaSemaphore", parent = "Object") + public static class JavaSemaphore extends RubyObject { + + private JRubySemaphore semaphore; + + public JavaSemaphore(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + this.semaphore = new JRubySemaphore(rubyFixnumInt(value, "count")); + return context.nil; + } + + @JRubyMethod + public IRubyObject acquire(ThreadContext context, final Block block) throws InterruptedException { + return this.acquire(context, 1, block); + } + + @JRubyMethod + public IRubyObject acquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException { + return this.acquire(context, rubyFixnumToPositiveInt(permits, "permits"), block); + } + + @JRubyMethod(name = "available_permits") + public IRubyObject availablePermits(ThreadContext context) { + return getRuntime().newFixnum(this.semaphore.availablePermits()); + } + + @JRubyMethod(name = "drain_permits") + public IRubyObject drainPermits(ThreadContext context) { + return getRuntime().newFixnum(this.semaphore.drainPermits()); + } + + @JRubyMethod(name = "try_acquire") + public IRubyObject tryAcquire(ThreadContext context, final Block block) throws InterruptedException { + int permitsInt = 1; + boolean acquired = semaphore.tryAcquire(permitsInt); + + return triedAcquire(context, permitsInt, acquired, block); + } + + @JRubyMethod(name = "try_acquire") + public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException { + int permitsInt = rubyFixnumToPositiveInt(permits, "permits"); + boolean acquired = semaphore.tryAcquire(permitsInt); + + return triedAcquire(context, permitsInt, acquired, block); + } + + @JRubyMethod(name = "try_acquire") + public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, IRubyObject timeout, final Block block) throws InterruptedException { + int permitsInt = rubyFixnumToPositiveInt(permits, "permits"); + boolean acquired = semaphore.tryAcquire( + permitsInt, + rubyNumericToLong(timeout, "timeout"), + java.util.concurrent.TimeUnit.SECONDS + ); + + return triedAcquire(context, permitsInt, acquired, block); + } + + @JRubyMethod + public IRubyObject release(ThreadContext context) { + this.semaphore.release(1); + return getRuntime().newBoolean(true); + } + + @JRubyMethod + public IRubyObject release(ThreadContext context, IRubyObject permits) { + this.semaphore.release(rubyFixnumToPositiveInt(permits, "permits")); + return getRuntime().newBoolean(true); + } + + @JRubyMethod(name = "reduce_permits") + public IRubyObject reducePermits(ThreadContext context, IRubyObject reduction) throws InterruptedException { + this.semaphore.publicReducePermits(rubyFixnumToNonNegativeInt(reduction, "reduction")); + return context.nil; + } + + private IRubyObject acquire(ThreadContext context, int permits, final Block block) throws InterruptedException { + this.semaphore.acquire(permits); + + if (!block.isGiven()) return context.nil; + + try { + return block.yieldSpecific(context); + } finally { + this.semaphore.release(permits); + } + } + + private IRubyObject triedAcquire(ThreadContext context, int permits, boolean acquired, final Block block) { + if (!block.isGiven()) return getRuntime().newBoolean(acquired); + if (!acquired) return context.nil; + + try { + return block.yieldSpecific(context); + } finally { + this.semaphore.release(permits); + } + } + + private int rubyFixnumInt(IRubyObject value, String paramName) { + if (value instanceof RubyFixnum) { + RubyFixnum fixNum = (RubyFixnum) value; + return (int) fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be integer"); + } + } + + private int rubyFixnumToNonNegativeInt(IRubyObject value, String paramName) { + if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() >= 0) { + RubyFixnum fixNum = (RubyFixnum) value; + return (int) fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be a non-negative integer"); + } + } + + private int rubyFixnumToPositiveInt(IRubyObject value, String paramName) { + if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() > 0) { + RubyFixnum fixNum = (RubyFixnum) value; + return (int) fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be an integer greater than zero"); + } + } + + private long rubyNumericToLong(IRubyObject value, String paramName) { + if (value instanceof RubyNumeric && ((RubyNumeric) value).getDoubleValue() > 0) { + RubyNumeric fixNum = (RubyNumeric) value; + return fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be a float greater than zero"); + } + } + + class JRubySemaphore extends Semaphore { + + public JRubySemaphore(int permits) { + super(permits); + } + + public JRubySemaphore(int permits, boolean value) { + super(permits, value); + } + + public void publicReducePermits(int i) { + reducePermits(i); + } + + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java new file mode 100644 index 0000000..f0c75ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java @@ -0,0 +1,292 @@ +package com.concurrent_ruby.ext; + +import org.jruby.Ruby; +import org.jruby.RubyBasicObject; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.RubyObject; +import org.jruby.RubyThread; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.Block; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.Visibility; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; +import sun.misc.Unsafe; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class SynchronizationLibrary implements Library { + + private static final Unsafe UNSAFE = loadUnsafe(); + private static final boolean FULL_FENCE = supportsFences(); + + private static Unsafe loadUnsafe() { + try { + Class ncdfe = Class.forName("sun.misc.Unsafe"); + Field f = ncdfe.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (Unsafe) f.get((java.lang.Object) null); + } catch (Exception var2) { + return null; + } catch (NoClassDefFoundError var3) { + return null; + } + } + + private static boolean supportsFences() { + if (UNSAFE == null) { + return false; + } else { + try { + Method m = UNSAFE.getClass().getDeclaredMethod("fullFence", new Class[0]); + if (m != null) { + return true; + } + } catch (Exception var1) { + // nothing + } + + return false; + } + } + + private static final ObjectAllocator OBJECT_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new Object(runtime, klazz); + } + }; + + private static final ObjectAllocator ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new AbstractLockableObject(runtime, klazz); + } + }; + + private static final ObjectAllocator JRUBY_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyLockableObject(runtime, klazz); + } + }; + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule synchronizationModule = runtime. + defineModule("Concurrent"). + defineModuleUnder("Synchronization"); + + RubyModule jrubyAttrVolatileModule = synchronizationModule.defineModuleUnder("JRubyAttrVolatile"); + jrubyAttrVolatileModule.defineAnnotatedMethods(JRubyAttrVolatile.class); + + defineClass(runtime, synchronizationModule, "AbstractObject", "Object", + Object.class, OBJECT_ALLOCATOR); + + defineClass(runtime, synchronizationModule, "Object", "AbstractLockableObject", + AbstractLockableObject.class, ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR); + + defineClass(runtime, synchronizationModule, "AbstractLockableObject", "JRubyLockableObject", + JRubyLockableObject.class, JRUBY_LOCKABLE_OBJECT_ALLOCATOR); + + defineClass(runtime, synchronizationModule, "Object", "JRuby", + JRuby.class, new ObjectAllocator() { + @Override + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRuby(runtime, klazz); + } + }); + } + + private RubyClass defineClass( + Ruby runtime, + RubyModule namespace, + String parentName, + String name, + Class javaImplementation, + ObjectAllocator allocator) { + final RubyClass parentClass = namespace.getClass(parentName); + + if (parentClass == null) { + System.out.println("not found " + parentName); + throw runtime.newRuntimeError(namespace.toString() + "::" + parentName + " is missing"); + } + + final RubyClass newClass = namespace.defineClassUnder(name, parentClass, allocator); + newClass.defineAnnotatedMethods(javaImplementation); + return newClass; + } + + // Facts: + // - all ivar reads are without any synchronisation of fences see + // https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/VariableAccessor.java#L110-110 + // - writes depend on UnsafeHolder.U, null -> SynchronizedVariableAccessor, !null -> StampedVariableAccessor + // SynchronizedVariableAccessor wraps with synchronized block, StampedVariableAccessor uses fullFence or + // volatilePut + // TODO (pitr 16-Sep-2015): what do we do in Java 9 ? + + // module JRubyAttrVolatile + public static class JRubyAttrVolatile { + + // volatile threadContext is used as a memory barrier per the JVM memory model happens-before semantic + // on volatile fields. any volatile field could have been used but using the thread context is an + // attempt to avoid code elimination. + private static volatile int volatileField; + + @JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject module) { + // Prevent reordering of ivar writes with publication of this instance + if (!FULL_FENCE) { + // Assuming that following volatile read and write is not eliminated it simulates fullFence. + // If it's eliminated it'll cause problems only on non-x86 platforms. + // http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_test_your_understanding + final int volatileRead = volatileField; + volatileField = context.getLine(); + } else { + UNSAFE.fullFence(); + } + return context.nil; + } + + @JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject instanceVariableGetVolatile( + ThreadContext context, + IRubyObject module, + IRubyObject self, + IRubyObject name) { + // Ensure we ses latest value with loadFence + if (!FULL_FENCE) { + // piggybacking on volatile read, simulating loadFence + final int volatileRead = volatileField; + return ((RubyBasicObject) self).instance_variable_get(context, name); + } else { + UNSAFE.loadFence(); + return ((RubyBasicObject) self).instance_variable_get(context, name); + } + } + + @JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject InstanceVariableSetVolatile( + ThreadContext context, + IRubyObject module, + IRubyObject self, + IRubyObject name, + IRubyObject value) { + // Ensure we make last update visible + if (!FULL_FENCE) { + // piggybacking on volatile write, simulating storeFence + final IRubyObject result = ((RubyBasicObject) self).instance_variable_set(name, value); + volatileField = context.getLine(); + return result; + } else { + // JRuby uses StampedVariableAccessor which calls fullFence + // so no additional steps needed. + // See https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/StampedVariableAccessor.java#L151-L159 + return ((RubyBasicObject) self).instance_variable_set(name, value); + } + } + } + + @JRubyClass(name = "Object", parent = "AbstractObject") + public static class Object extends RubyObject { + + public Object(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + } + + @JRubyClass(name = "AbstractLockableObject", parent = "Object") + public static class AbstractLockableObject extends Object { + + public AbstractLockableObject(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + } + + @JRubyClass(name = "JRubyLockableObject", parent = "AbstractLockableObject") + public static class JRubyLockableObject extends AbstractLockableObject { + + public JRubyLockableObject(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod(name = "synchronize", visibility = Visibility.PROTECTED) + public IRubyObject rubySynchronize(ThreadContext context, Block block) { + synchronized (this) { + return block.yield(context, null); + } + } + + @JRubyMethod(name = "ns_wait", optional = 1, visibility = Visibility.PROTECTED) + public IRubyObject nsWait(ThreadContext context, IRubyObject[] args) { + Ruby runtime = context.runtime; + if (args.length > 1) { + throw runtime.newArgumentError(args.length, 1); + } + Double timeout = null; + if (args.length > 0 && !args[0].isNil()) { + timeout = args[0].convertToFloat().getDoubleValue(); + if (timeout < 0) { + throw runtime.newArgumentError("time interval must be positive"); + } + } + if (Thread.interrupted()) { + throw runtime.newConcurrencyError("thread interrupted"); + } + boolean success = false; + try { + success = context.getThread().wait_timeout(this, timeout); + } catch (InterruptedException ie) { + throw runtime.newConcurrencyError(ie.getLocalizedMessage()); + } finally { + // An interrupt or timeout may have caused us to miss + // a notify that we consumed, so do another notify in + // case someone else is available to pick it up. + if (!success) { + this.notify(); + } + } + return this; + } + + @JRubyMethod(name = "ns_signal", visibility = Visibility.PROTECTED) + public IRubyObject nsSignal(ThreadContext context) { + notify(); + return this; + } + + @JRubyMethod(name = "ns_broadcast", visibility = Visibility.PROTECTED) + public IRubyObject nsBroadcast(ThreadContext context) { + notifyAll(); + return this; + } + } + + @JRubyClass(name = "JRuby") + public static class JRuby extends RubyObject { + public JRuby(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod(name = "sleep_interruptibly", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject sleepInterruptibly(final ThreadContext context, IRubyObject receiver, final Block block) { + try { + context.getThread().executeBlockingTask(new RubyThread.BlockingTask() { + @Override + public void run() throws InterruptedException { + block.call(context); + } + + @Override + public void wakeup() { + context.getThread().getNativeThread().interrupt(); + } + }); + } catch (InterruptedException e) { + throw context.runtime.newThreadError("interrupted in Concurrent::Synchronization::JRuby.sleep_interruptibly"); + } + return context.nil; + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java new file mode 100644 index 0000000..e11e15a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java @@ -0,0 +1,31 @@ +package com.concurrent_ruby.ext.jsr166e; + +import java.util.Map; +import java.util.Set; + +public interface ConcurrentHashMap { + /** Interface describing a function of one argument */ + public interface Fun { T apply(A a); } + /** Interface describing a function of two arguments */ + public interface BiFun { T apply(A a, B b); } + + public V get(K key); + public V put(K key, V value); + public V putIfAbsent(K key, V value); + public V computeIfAbsent(K key, Fun mf); + public V computeIfPresent(K key, BiFun mf); + public V compute(K key, BiFun mf); + public V merge(K key, V value, BiFun mf); + public boolean replace(K key, V oldVal, V newVal); + public V replace(K key, V value); + public boolean containsKey(K key); + public boolean remove(Object key, Object value); + public V remove(K key); + public void clear(); + public Set> entrySet(); + public int size(); + public V getValueOrDefault(Object key, V defaultValue); + + public boolean containsValue(V value); + public K findKey(V value); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java new file mode 100644 index 0000000..dc9901f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java @@ -0,0 +1,3863 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on the 1.79 version. + +package com.concurrent_ruby.ext.jsr166e; + +import org.jruby.RubyClass; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.exceptions.RaiseException; +import com.concurrent_ruby.ext.jsr166y.ThreadLocalRandom; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.Collection; +import java.util.Hashtable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Enumeration; +import java.util.ConcurrentModificationException; +import java.util.NoSuchElementException; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +import java.io.Serializable; + +/** + * A hash table supporting full concurrency of retrievals and + * high expected concurrency for updates. This class obeys the + * same functional specification as {@link java.util.Hashtable}, and + * includes versions of methods corresponding to each method of + * {@code Hashtable}. However, even though all operations are + * thread-safe, retrieval operations do not entail locking, + * and there is not any support for locking the entire table + * in a way that prevents all access. This class is fully + * interoperable with {@code Hashtable} in programs that rely on its + * thread safety but not on its synchronization details. + * + *

Retrieval operations (including {@code get}) generally do not + * block, so may overlap with update operations (including {@code put} + * and {@code remove}). Retrievals reflect the results of the most + * recently completed update operations holding upon their + * onset. (More formally, an update operation for a given key bears a + * happens-before relation with any (non-null) retrieval for + * that key reporting the updated value.) For aggregate operations + * such as {@code putAll} and {@code clear}, concurrent retrievals may + * reflect insertion or removal of only some entries. Similarly, + * Iterators and Enumerations return elements reflecting the state of + * the hash table at some point at or since the creation of the + * iterator/enumeration. They do not throw {@link + * ConcurrentModificationException}. However, iterators are designed + * to be used by only one thread at a time. Bear in mind that the + * results of aggregate status methods including {@code size}, {@code + * isEmpty}, and {@code containsValue} are typically useful only when + * a map is not undergoing concurrent updates in other threads. + * Otherwise the results of these methods reflect transient states + * that may be adequate for monitoring or estimation purposes, but not + * for program control. + * + *

The table is dynamically expanded when there are too many + * collisions (i.e., keys that have distinct hash codes but fall into + * the same slot modulo the table size), with the expected average + * effect of maintaining roughly two bins per mapping (corresponding + * to a 0.75 load factor threshold for resizing). There may be much + * variance around this average as mappings are added and removed, but + * overall, this maintains a commonly accepted time/space tradeoff for + * hash tables. However, resizing this or any other kind of hash + * table may be a relatively slow operation. When possible, it is a + * good idea to provide a size estimate as an optional {@code + * initialCapacity} constructor argument. An additional optional + * {@code loadFactor} constructor argument provides a further means of + * customizing initial table capacity by specifying the table density + * to be used in calculating the amount of space to allocate for the + * given number of elements. Also, for compatibility with previous + * versions of this class, constructors may optionally specify an + * expected {@code concurrencyLevel} as an additional hint for + * internal sizing. Note that using many keys with exactly the same + * {@code hashCode()} is a sure way to slow down performance of any + * hash table. + * + *

A {@link Set} projection of a ConcurrentHashMapV8 may be created + * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed + * (using {@link #keySet(Object)} when only keys are of interest, and the + * mapped values are (perhaps transiently) not used or all take the + * same mapping value. + * + *

A ConcurrentHashMapV8 can be used as scalable frequency map (a + * form of histogram or multiset) by using {@link LongAdder} values + * and initializing via {@link #computeIfAbsent}. For example, to add + * a count to a {@code ConcurrentHashMapV8 freqs}, you + * can use {@code freqs.computeIfAbsent(k -> new + * LongAdder()).increment();} + * + *

This class and its views and iterators implement all of the + * optional methods of the {@link Map} and {@link Iterator} + * interfaces. + * + *

Like {@link Hashtable} but unlike {@link HashMap}, this class + * does not allow {@code null} to be used as a key or value. + * + *

ConcurrentHashMapV8s support parallel operations using the {@link + * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts + * are available in class {@link ForkJoinTasks}). These operations are + * designed to be safely, and often sensibly, applied even with maps + * that are being concurrently updated by other threads; for example, + * when computing a snapshot summary of the values in a shared + * registry. There are three kinds of operation, each with four + * forms, accepting functions with Keys, Values, Entries, and (Key, + * Value) arguments and/or return values. (The first three forms are + * also available via the {@link #keySet()}, {@link #values()} and + * {@link #entrySet()} views). Because the elements of a + * ConcurrentHashMapV8 are not ordered in any particular way, and may be + * processed in different orders in different parallel executions, the + * correctness of supplied functions should not depend on any + * ordering, or on any other objects or values that may transiently + * change while computation is in progress; and except for forEach + * actions, should ideally be side-effect-free. + * + *

    + *
  • forEach: Perform a given action on each element. + * A variant form applies a given transformation on each element + * before performing the action.
  • + * + *
  • search: Return the first available non-null result of + * applying a given function on each element; skipping further + * search when a result is found.
  • + * + *
  • reduce: Accumulate each element. The supplied reduction + * function cannot rely on ordering (more formally, it should be + * both associative and commutative). There are five variants: + * + *
      + * + *
    • Plain reductions. (There is not a form of this method for + * (key, value) function arguments since there is no corresponding + * return type.)
    • + * + *
    • Mapped reductions that accumulate the results of a given + * function applied to each element.
    • + * + *
    • Reductions to scalar doubles, longs, and ints, using a + * given basis value.
    • + * + * + *
    + *
+ * + *

The concurrency properties of bulk operations follow + * from those of ConcurrentHashMapV8: Any non-null result returned + * from {@code get(key)} and related access methods bears a + * happens-before relation with the associated insertion or + * update. The result of any bulk operation reflects the + * composition of these per-element relations (but is not + * necessarily atomic with respect to the map as a whole unless it + * is somehow known to be quiescent). Conversely, because keys + * and values in the map are never null, null serves as a reliable + * atomic indicator of the current lack of any result. To + * maintain this property, null serves as an implicit basis for + * all non-scalar reduction operations. For the double, long, and + * int versions, the basis should be one that, when combined with + * any other value, returns that other value (more formally, it + * should be the identity element for the reduction). Most common + * reductions have these properties; for example, computing a sum + * with basis 0 or a minimum with basis MAX_VALUE. + * + *

Search and transformation functions provided as arguments + * should similarly return null to indicate the lack of any result + * (in which case it is not used). In the case of mapped + * reductions, this also enables transformations to serve as + * filters, returning null (or, in the case of primitive + * specializations, the identity basis) if the element should not + * be combined. You can create compound transformations and + * filterings by composing them yourself under this "null means + * there is nothing there now" rule before using them in search or + * reduce operations. + * + *

Methods accepting and/or returning Entry arguments maintain + * key-value associations. They may be useful for example when + * finding the key for the greatest value. Note that "plain" Entry + * arguments can be supplied using {@code new + * AbstractMap.SimpleEntry(k,v)}. + * + *

Bulk operations may complete abruptly, throwing an + * exception encountered in the application of a supplied + * function. Bear in mind when handling such exceptions that other + * concurrently executing functions could also have thrown + * exceptions, or would have done so if the first exception had + * not occurred. + * + *

Parallel speedups for bulk operations compared to sequential + * processing are common but not guaranteed. Operations involving + * brief functions on small maps may execute more slowly than + * sequential loops if the underlying work to parallelize the + * computation is more expensive than the computation itself. + * Similarly, parallelization may not lead to much actual parallelism + * if all processors are busy performing unrelated tasks. + * + *

All arguments to all task methods must be non-null. + * + *

jsr166e note: During transition, this class + * uses nested functional interfaces with different names but the + * same forms as those expected for JDK8. + * + *

This class is a member of the + * + * Java Collections Framework. + * + * @since 1.5 + * @author Doug Lea + * @param the type of keys maintained by this map + * @param the type of mapped values + */ +public class ConcurrentHashMapV8 + implements ConcurrentMap, Serializable, ConcurrentHashMap { + private static final long serialVersionUID = 7249069246763182397L; + + /** + * A partitionable iterator. A Spliterator can be traversed + * directly, but can also be partitioned (before traversal) by + * creating another Spliterator that covers a non-overlapping + * portion of the elements, and so may be amenable to parallel + * execution. + * + *

This interface exports a subset of expected JDK8 + * functionality. + * + *

Sample usage: Here is one (of the several) ways to compute + * the sum of the values held in a map using the ForkJoin + * framework. As illustrated here, Spliterators are well suited to + * designs in which a task repeatedly splits off half its work + * into forked subtasks until small enough to process directly, + * and then joins these subtasks. Variants of this style can also + * be used in completion-based designs. + * + *

+     * {@code ConcurrentHashMapV8 m = ...
+     * // split as if have 8 * parallelism, for load balance
+     * int n = m.size();
+     * int p = aForkJoinPool.getParallelism() * 8;
+     * int split = (n < p)? n : p;
+     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
+     * // ...
+     * static class SumValues extends RecursiveTask {
+     *   final Spliterator s;
+     *   final int split;             // split while > 1
+     *   final SumValues nextJoin;    // records forked subtasks to join
+     *   SumValues(Spliterator s, int depth, SumValues nextJoin) {
+     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
+     *   }
+     *   public Long compute() {
+     *     long sum = 0;
+     *     SumValues subtasks = null; // fork subtasks
+     *     for (int s = split >>> 1; s > 0; s >>>= 1)
+     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
+     *     while (s.hasNext())        // directly process remaining elements
+     *       sum += s.next();
+     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
+     *       sum += t.join();         // collect subtask results
+     *     return sum;
+     *   }
+     * }
+     * }
+ */ + public static interface Spliterator extends Iterator { + /** + * Returns a Spliterator covering approximately half of the + * elements, guaranteed not to overlap with those subsequently + * returned by this Spliterator. After invoking this method, + * the current Spliterator will not produce any of + * the elements of the returned Spliterator, but the two + * Spliterators together will produce all of the elements that + * would have been produced by this Spliterator had this + * method not been called. The exact number of elements + * produced by the returned Spliterator is not guaranteed, and + * may be zero (i.e., with {@code hasNext()} reporting {@code + * false}) if this Spliterator cannot be further split. + * + * @return a Spliterator covering approximately half of the + * elements + * @throws IllegalStateException if this Spliterator has + * already commenced traversing elements + */ + Spliterator split(); + } + + + /* + * Overview: + * + * The primary design goal of this hash table is to maintain + * concurrent readability (typically method get(), but also + * iterators and related methods) while minimizing update + * contention. Secondary goals are to keep space consumption about + * the same or better than java.util.HashMap, and to support high + * initial insertion rates on an empty table by many threads. + * + * Each key-value mapping is held in a Node. Because Node fields + * can contain special values, they are defined using plain Object + * types. Similarly in turn, all internal methods that use them + * work off Object types. And similarly, so do the internal + * methods of auxiliary iterator and view classes. All public + * generic typed methods relay in/out of these internal methods, + * supplying null-checks and casts as needed. This also allows + * many of the public methods to be factored into a smaller number + * of internal methods (although sadly not so for the five + * variants of put-related operations). The validation-based + * approach explained below leads to a lot of code sprawl because + * retry-control precludes factoring into smaller methods. + * + * The table is lazily initialized to a power-of-two size upon the + * first insertion. Each bin in the table normally contains a + * list of Nodes (most often, the list has only zero or one Node). + * Table accesses require volatile/atomic reads, writes, and + * CASes. Because there is no other way to arrange this without + * adding further indirections, we use intrinsics + * (sun.misc.Unsafe) operations. The lists of nodes within bins + * are always accurately traversable under volatile reads, so long + * as lookups check hash code and non-nullness of value before + * checking key equality. + * + * We use the top two bits of Node hash fields for control + * purposes -- they are available anyway because of addressing + * constraints. As explained further below, these top bits are + * used as follows: + * 00 - Normal + * 01 - Locked + * 11 - Locked and may have a thread waiting for lock + * 10 - Node is a forwarding node + * + * The lower 30 bits of each Node's hash field contain a + * transformation of the key's hash code, except for forwarding + * nodes, for which the lower bits are zero (and so always have + * hash field == MOVED). + * + * Insertion (via put or its variants) of the first node in an + * empty bin is performed by just CASing it to the bin. This is + * by far the most common case for put operations under most + * key/hash distributions. Other update operations (insert, + * delete, and replace) require locks. We do not want to waste + * the space required to associate a distinct lock object with + * each bin, so instead use the first node of a bin list itself as + * a lock. Blocking support for these locks relies on the builtin + * "synchronized" monitors. However, we also need a tryLock + * construction, so we overlay these by using bits of the Node + * hash field for lock control (see above), and so normally use + * builtin monitors only for blocking and signalling using + * wait/notifyAll constructions. See Node.tryAwaitLock. + * + * Using the first node of a list as a lock does not by itself + * suffice though: When a node is locked, any update must first + * validate that it is still the first node after locking it, and + * retry if not. Because new nodes are always appended to lists, + * once a node is first in a bin, it remains first until deleted + * or the bin becomes invalidated (upon resizing). However, + * operations that only conditionally update may inspect nodes + * until the point of update. This is a converse of sorts to the + * lazy locking technique described by Herlihy & Shavit. + * + * The main disadvantage of per-bin locks is that other update + * operations on other nodes in a bin list protected by the same + * lock can stall, for example when user equals() or mapping + * functions take a long time. However, statistically, under + * random hash codes, this is not a common problem. Ideally, the + * frequency of nodes in bins follows a Poisson distribution + * (http://en.wikipedia.org/wiki/Poisson_distribution) with a + * parameter of about 0.5 on average, given the resizing threshold + * of 0.75, although with a large variance because of resizing + * granularity. Ignoring variance, the expected occurrences of + * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The + * first values are: + * + * 0: 0.60653066 + * 1: 0.30326533 + * 2: 0.07581633 + * 3: 0.01263606 + * 4: 0.00157952 + * 5: 0.00015795 + * 6: 0.00001316 + * 7: 0.00000094 + * 8: 0.00000006 + * more: less than 1 in ten million + * + * Lock contention probability for two threads accessing distinct + * elements is roughly 1 / (8 * #elements) under random hashes. + * + * Actual hash code distributions encountered in practice + * sometimes deviate significantly from uniform randomness. This + * includes the case when N > (1<<30), so some keys MUST collide. + * Similarly for dumb or hostile usages in which multiple keys are + * designed to have identical hash codes. Also, although we guard + * against the worst effects of this (see method spread), sets of + * hashes may differ only in bits that do not impact their bin + * index for a given power-of-two mask. So we use a secondary + * strategy that applies when the number of nodes in a bin exceeds + * a threshold, and at least one of the keys implements + * Comparable. These TreeBins use a balanced tree to hold nodes + * (a specialized form of red-black trees), bounding search time + * to O(log N). Each search step in a TreeBin is around twice as + * slow as in a regular list, but given that N cannot exceed + * (1<<64) (before running out of addresses) this bounds search + * steps, lock hold times, etc, to reasonable constants (roughly + * 100 nodes inspected per operation worst case) so long as keys + * are Comparable (which is very common -- String, Long, etc). + * TreeBin nodes (TreeNodes) also maintain the same "next" + * traversal pointers as regular nodes, so can be traversed in + * iterators in the same way. + * + * The table is resized when occupancy exceeds a percentage + * threshold (nominally, 0.75, but see below). Only a single + * thread performs the resize (using field "sizeCtl", to arrange + * exclusion), but the table otherwise remains usable for reads + * and updates. Resizing proceeds by transferring bins, one by + * one, from the table to the next table. Because we are using + * power-of-two expansion, the elements from each bin must either + * stay at same index, or move with a power of two offset. We + * eliminate unnecessary node creation by catching cases where old + * nodes can be reused because their next fields won't change. On + * average, only about one-sixth of them need cloning when a table + * doubles. The nodes they replace will be garbage collectable as + * soon as they are no longer referenced by any reader thread that + * may be in the midst of concurrently traversing table. Upon + * transfer, the old table bin contains only a special forwarding + * node (with hash field "MOVED") that contains the next table as + * its key. On encountering a forwarding node, access and update + * operations restart, using the new table. + * + * Each bin transfer requires its bin lock. However, unlike other + * cases, a transfer can skip a bin if it fails to acquire its + * lock, and revisit it later (unless it is a TreeBin). Method + * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that + * have been skipped because of failure to acquire a lock, and + * blocks only if none are available (i.e., only very rarely). + * The transfer operation must also ensure that all accessible + * bins in both the old and new table are usable by any traversal. + * When there are no lock acquisition failures, this is arranged + * simply by proceeding from the last bin (table.length - 1) up + * towards the first. Upon seeing a forwarding node, traversals + * (see class Iter) arrange to move to the new table + * without revisiting nodes. However, when any node is skipped + * during a transfer, all earlier table bins may have become + * visible, so are initialized with a reverse-forwarding node back + * to the old table until the new ones are established. (This + * sometimes requires transiently locking a forwarding node, which + * is possible under the above encoding.) These more expensive + * mechanics trigger only when necessary. + * + * The traversal scheme also applies to partial traversals of + * ranges of bins (via an alternate Traverser constructor) + * to support partitioned aggregate operations. Also, read-only + * operations give up if ever forwarded to a null table, which + * provides support for shutdown-style clearing, which is also not + * currently implemented. + * + * Lazy table initialization minimizes footprint until first use, + * and also avoids resizings when the first operation is from a + * putAll, constructor with map argument, or deserialization. + * These cases attempt to override the initial capacity settings, + * but harmlessly fail to take effect in cases of races. + * + * The element count is maintained using a LongAdder, which avoids + * contention on updates but can encounter cache thrashing if read + * too frequently during concurrent access. To avoid reading so + * often, resizing is attempted either when a bin lock is + * contended, or upon adding to a bin already holding two or more + * nodes (checked before adding in the xIfAbsent methods, after + * adding in others). Under uniform hash distributions, the + * probability of this occurring at threshold is around 13%, + * meaning that only about 1 in 8 puts check threshold (and after + * resizing, many fewer do so). But this approximation has high + * variance for small table sizes, so we check on any collision + * for sizes <= 64. The bulk putAll operation further reduces + * contention by only committing count updates upon these size + * checks. + * + * Maintaining API and serialization compatibility with previous + * versions of this class introduces several oddities. Mainly: We + * leave untouched but unused constructor arguments referring to + * concurrencyLevel. We accept a loadFactor constructor argument, + * but apply it only to initial table capacity (which is the only + * time that we can guarantee to honor it.) We also declare an + * unused "Segment" class that is instantiated in minimal form + * only when serializing. + */ + + /* ---------------- Constants -------------- */ + + /** + * The largest possible table capacity. This value must be + * exactly 1<<30 to stay within Java array allocation and indexing + * bounds for power of two table sizes, and is further required + * because the top two bits of 32bit hash fields are used for + * control purposes. + */ + private static final int MAXIMUM_CAPACITY = 1 << 30; + + /** + * The default initial table capacity. Must be a power of 2 + * (i.e., at least 1) and at most MAXIMUM_CAPACITY. + */ + private static final int DEFAULT_CAPACITY = 16; + + /** + * The largest possible (non-power of two) array size. + * Needed by toArray and related methods. + */ + static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + /** + * The default concurrency level for this table. Unused but + * defined for compatibility with previous versions of this class. + */ + private static final int DEFAULT_CONCURRENCY_LEVEL = 16; + + /** + * The load factor for this table. Overrides of this value in + * constructors affect only the initial table capacity. The + * actual floating point value isn't normally used -- it is + * simpler to use expressions such as {@code n - (n >>> 2)} for + * the associated resizing threshold. + */ + private static final float LOAD_FACTOR = 0.75f; + + /** + * The buffer size for skipped bins during transfers. The + * value is arbitrary but should be large enough to avoid + * most locking stalls during resizes. + */ + private static final int TRANSFER_BUFFER_SIZE = 32; + + /** + * The bin count threshold for using a tree rather than list for a + * bin. The value reflects the approximate break-even point for + * using tree-based operations. + * Note that Doug's version defaults to 8, but when dealing with + * Ruby objects it is actually beneficial to avoid TreeNodes + * as long as possible as it usually means going into Ruby land. + */ + private static final int TREE_THRESHOLD = 16; + + /* + * Encodings for special uses of Node hash fields. See above for + * explanation. + */ + static final int MOVED = 0x80000000; // hash field for forwarding nodes + static final int LOCKED = 0x40000000; // set/tested only as a bit + static final int WAITING = 0xc0000000; // both bits set/tested together + static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash + + /* ---------------- Fields -------------- */ + + /** + * The array of bins. Lazily initialized upon first insertion. + * Size is always a power of two. Accessed directly by iterators. + */ + transient volatile Node[] table; + + /** + * The counter maintaining number of elements. + */ + private transient final LongAdder counter; + + /** + * Table initialization and resizing control. When negative, the + * table is being initialized or resized. Otherwise, when table is + * null, holds the initial table size to use upon creation, or 0 + * for default. After initialization, holds the next element count + * value upon which to resize the table. + */ + private transient volatile int sizeCtl; + + // views + private transient KeySetView keySet; + private transient ValuesView values; + private transient EntrySetView entrySet; + + /** For serialization compatibility. Null unless serialized; see below */ + private Segment[] segments; + + /* ---------------- Table element access -------------- */ + + /* + * Volatile access methods are used for table elements as well as + * elements of in-progress next table while resizing. Uses are + * null checked by callers, and implicitly bounds-checked, relying + * on the invariants that tab arrays have non-zero size, and all + * indices are masked with (tab.length - 1) which is never + * negative and always less than length. Note that, to be correct + * wrt arbitrary concurrency errors by users, bounds checks must + * operate on local variables, which accounts for some odd-looking + * inline assignments below. + */ + + static final Node tabAt(Node[] tab, int i) { // used by Iter + return (Node)UNSAFE.getObjectVolatile(tab, ((long)i< 1 ? 64 : 1; + + /** + * Spins a while if LOCKED bit set and this node is the first + * of its bin, and then sets WAITING bits on hash field and + * blocks (once) if they are still set. It is OK for this + * method to return even if lock is not available upon exit, + * which enables these simple single-wait mechanics. + * + * The corresponding signalling operation is performed within + * callers: Upon detecting that WAITING has been set when + * unlocking lock (via a failed CAS from non-waiting LOCKED + * state), unlockers acquire the sync lock and perform a + * notifyAll. + * + * The initial sanity check on tab and bounds is not currently + * necessary in the only usages of this method, but enables + * use in other future contexts. + */ + final void tryAwaitLock(Node[] tab, int i) { + if (tab != null && i >= 0 && i < tab.length) { // sanity check + int r = ThreadLocalRandom.current().nextInt(); // randomize spins + int spins = MAX_SPINS, h; + while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) { + if (spins >= 0) { + r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift + if (r >= 0 && --spins == 0) + Thread.yield(); // yield before block + } + else if (casHash(h, h | WAITING)) { + synchronized (this) { + if (tabAt(tab, i) == this && + (hash & WAITING) == WAITING) { + try { + wait(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } + else + notifyAll(); // possibly won race vs signaller + } + break; + } + } + } + } + + // Unsafe mechanics for casHash + private static final sun.misc.Unsafe UNSAFE; + private static final long hashOffset; + + static { + try { + UNSAFE = getUnsafe(); + Class k = Node.class; + hashOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("hash")); + } catch (Exception e) { + throw new Error(e); + } + } + } + + /* ---------------- TreeBins -------------- */ + + /** + * Nodes for use in TreeBins + */ + static final class TreeNode extends Node { + TreeNode parent; // red-black tree links + TreeNode left; + TreeNode right; + TreeNode prev; // needed to unlink next upon deletion + boolean red; + + TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) { + super(hash, key, val, next); + this.parent = parent; + } + } + + /** + * A specialized form of red-black tree for use in bins + * whose size exceeds a threshold. + * + * TreeBins use a special form of comparison for search and + * related operations (which is the main reason we cannot use + * existing collections such as TreeMaps). TreeBins contain + * Comparable elements, but may contain others, as well as + * elements that are Comparable but not necessarily Comparable + * for the same T, so we cannot invoke compareTo among them. To + * handle this, the tree is ordered primarily by hash value, then + * by getClass().getName() order, and then by Comparator order + * among elements of the same class. On lookup at a node, if + * elements are not comparable or compare as 0, both left and + * right children may need to be searched in the case of tied hash + * values. (This corresponds to the full list search that would be + * necessary if all elements were non-Comparable and had tied + * hashes.) The red-black balancing code is updated from + * pre-jdk-collections + * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) + * based in turn on Cormen, Leiserson, and Rivest "Introduction to + * Algorithms" (CLR). + * + * TreeBins also maintain a separate locking discipline than + * regular bins. Because they are forwarded via special MOVED + * nodes at bin heads (which can never change once established), + * we cannot use those nodes as locks. Instead, TreeBin + * extends AbstractQueuedSynchronizer to support a simple form of + * read-write lock. For update operations and table validation, + * the exclusive form of lock behaves in the same way as bin-head + * locks. However, lookups use shared read-lock mechanics to allow + * multiple readers in the absence of writers. Additionally, + * these lookups do not ever block: While the lock is not + * available, they proceed along the slow traversal path (via + * next-pointers) until the lock becomes available or the list is + * exhausted, whichever comes first. (These cases are not fast, + * but maximize aggregate expected throughput.) The AQS mechanics + * for doing this are straightforward. The lock state is held as + * AQS getState(). Read counts are negative; the write count (1) + * is positive. There are no signalling preferences among readers + * and writers. Since we don't need to export full Lock API, we + * just override the minimal AQS methods and use them directly. + */ + static final class TreeBin extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = 2249069246763182397L; + transient TreeNode root; // root of tree + transient TreeNode first; // head of next-pointer list + + /* AQS overrides */ + public final boolean isHeldExclusively() { return getState() > 0; } + public final boolean tryAcquire(int ignore) { + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + public final boolean tryRelease(int ignore) { + setExclusiveOwnerThread(null); + setState(0); + return true; + } + public final int tryAcquireShared(int ignore) { + for (int c;;) { + if ((c = getState()) > 0) + return -1; + if (compareAndSetState(c, c -1)) + return 1; + } + } + public final boolean tryReleaseShared(int ignore) { + int c; + do {} while (!compareAndSetState(c = getState(), c + 1)); + return c == -1; + } + + /** From CLR */ + private void rotateLeft(TreeNode p) { + if (p != null) { + TreeNode r = p.right, pp, rl; + if ((rl = p.right = r.left) != null) + rl.parent = p; + if ((pp = r.parent = p.parent) == null) + root = r; + else if (pp.left == p) + pp.left = r; + else + pp.right = r; + r.left = p; + p.parent = r; + } + } + + /** From CLR */ + private void rotateRight(TreeNode p) { + if (p != null) { + TreeNode l = p.left, pp, lr; + if ((lr = p.left = l.right) != null) + lr.parent = p; + if ((pp = l.parent = p.parent) == null) + root = l; + else if (pp.right == p) + pp.right = l; + else + pp.left = l; + l.right = p; + p.parent = l; + } + } + + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, Object k, TreeNode p) { + return getTreeNode(h, (RubyObject)k, p); + } + + /** + * Returns the TreeNode (or null if not found) for the given key + * starting at given root. + */ + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, RubyObject k, TreeNode p) { + RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>"); + while (p != null) { + int dir, ph; RubyObject pk; RubyClass pc; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = (RubyClass)pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pl, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + // try to continue iterating on the left side + else if ((pl = p.left) != null && h <= pl.hash) + dir = -1; + else // no matching node found + return null; + } + } + } + else + dir = (h < ph) ? -1 : 1; + p = (dir > 0) ? p.right : p.left; + } + return null; + } + + int rubyCompare(RubyObject l, RubyObject r) { + ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext(); + IRubyObject result; + try { + result = l.callMethod(context, "<=>", r); + } catch (RaiseException e) { + // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys + if (context.runtime.getNoMethodError().isInstance(e.getException())) { + return 0; + } + throw e; + } + + return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger()); + } + + /** + * Wrapper for getTreeNode used by CHM.get. Tries to obtain + * read-lock to call getTreeNode, but during failure to get + * lock, searches along next links. + */ + final Object getValue(int h, Object k) { + Node r = null; + int c = getState(); // Must read lock state first + for (Node e = first; e != null; e = e.next) { + if (c <= 0 && compareAndSetState(c, c - 1)) { + try { + r = getTreeNode(h, k, root); + } finally { + releaseShared(0); + } + break; + } + else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) { + r = e; + break; + } + else + c = getState(); + } + return r == null ? null : r.val; + } + + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, Object k, Object v) { + return putTreeNode(h, (RubyObject)k, v); + } + + /** + * Finds or adds a node. + * @return null if added + */ + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, RubyObject k, Object v) { + RubyClass c = k.getMetaClass(); + boolean kNotComparable = !k.respondsTo("<=>"); + TreeNode pp = root, p = null; + int dir = 0; + while (pp != null) { // find existing node or leaf to insert at + int ph; RubyObject pk; RubyClass pc; + p = pp; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + else // continue descending down the left subtree + dir = -1; + } + } + } + else + dir = (h < ph) ? -1 : 1; + pp = (dir > 0) ? p.right : p.left; + } + + TreeNode f = first; + TreeNode x = first = new TreeNode(h, (Object)k, v, f, p); + if (p == null) + root = x; + else { // attach and rebalance; adapted from CLR + TreeNode xp, xpp; + if (f != null) + f.prev = x; + if (dir <= 0) + p.left = x; + else + p.right = x; + x.red = true; + while (x != null && (xp = x.parent) != null && xp.red && + (xpp = xp.parent) != null) { + TreeNode xppl = xpp.left; + if (xp == xppl) { + TreeNode y = xpp.right; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.right) { + rotateLeft(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateRight(xpp); + } + } + } + } + else { + TreeNode y = xppl; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.left) { + rotateRight(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateLeft(xpp); + } + } + } + } + } + TreeNode r = root; + if (r != null && r.red) + r.red = false; + } + return null; + } + + /** + * Removes the given node, that must be present before this + * call. This is messier than typical red-black deletion code + * because we cannot swap the contents of an interior node + * with a leaf successor that is pinned by "next" pointers + * that are accessible independently of lock. So instead we + * swap the tree linkages. + */ + final void deleteTreeNode(TreeNode p) { + TreeNode next = (TreeNode)p.next; // unlink traversal pointers + TreeNode pred = p.prev; + if (pred == null) + first = next; + else + pred.next = next; + if (next != null) + next.prev = pred; + TreeNode replacement; + TreeNode pl = p.left; + TreeNode pr = p.right; + if (pl != null && pr != null) { + TreeNode s = pr, sl; + while ((sl = s.left) != null) // find successor + s = sl; + boolean c = s.red; s.red = p.red; p.red = c; // swap colors + TreeNode sr = s.right; + TreeNode pp = p.parent; + if (s == pr) { // p was s's direct parent + p.parent = s; + s.right = p; + } + else { + TreeNode sp = s.parent; + if ((p.parent = sp) != null) { + if (s == sp.left) + sp.left = p; + else + sp.right = p; + } + if ((s.right = pr) != null) + pr.parent = s; + } + p.left = null; + if ((p.right = sr) != null) + sr.parent = p; + if ((s.left = pl) != null) + pl.parent = s; + if ((s.parent = pp) == null) + root = s; + else if (p == pp.left) + pp.left = s; + else + pp.right = s; + replacement = sr; + } + else + replacement = (pl != null) ? pl : pr; + TreeNode pp = p.parent; + if (replacement == null) { + if (pp == null) { + root = null; + return; + } + replacement = p; + } + else { + replacement.parent = pp; + if (pp == null) + root = replacement; + else if (p == pp.left) + pp.left = replacement; + else + pp.right = replacement; + p.left = p.right = p.parent = null; + } + if (!p.red) { // rebalance, from CLR + TreeNode x = replacement; + while (x != null) { + TreeNode xp, xpl; + if (x.red || (xp = x.parent) == null) { + x.red = false; + break; + } + if (x == (xpl = xp.left)) { + TreeNode sib = xp.right; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateLeft(xp); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sr == null || !sr.red) && + (sl == null || !sl.red)) { + sib.red = true; + x = xp; + } + else { + if (sr == null || !sr.red) { + if (sl != null) + sl.red = false; + sib.red = true; + rotateRight(sib); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sr = sib.right) != null) + sr.red = false; + } + if (xp != null) { + xp.red = false; + rotateLeft(xp); + } + x = root; + } + } + } + else { // symmetric + TreeNode sib = xpl; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateRight(xp); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sl == null || !sl.red) && + (sr == null || !sr.red)) { + sib.red = true; + x = xp; + } + else { + if (sl == null || !sl.red) { + if (sr != null) + sr.red = false; + sib.red = true; + rotateLeft(sib); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sl = sib.left) != null) + sl.red = false; + } + if (xp != null) { + xp.red = false; + rotateRight(xp); + } + x = root; + } + } + } + } + } + if (p == replacement && (pp = p.parent) != null) { + if (p == pp.left) // detach pointers + pp.left = null; + else if (p == pp.right) + pp.right = null; + p.parent = null; + } + } + } + + /* ---------------- Collision reduction methods -------------- */ + + /** + * Spreads higher bits to lower, and also forces top 2 bits to 0. + * Because the table uses power-of-two masking, sets of hashes + * that vary only in bits above the current mask will always + * collide. (Among known examples are sets of Float keys holding + * consecutive whole numbers in small tables.) To counter this, + * we apply a transform that spreads the impact of higher bits + * downward. There is a tradeoff between speed, utility, and + * quality of bit-spreading. Because many common sets of hashes + * are already reasonably distributed across bits (so don't benefit + * from spreading), and because we use trees to handle large sets + * of collisions in bins, we don't need excessively high quality. + */ + private static final int spread(int h) { + h ^= (h >>> 18) ^ (h >>> 12); + return (h ^ (h >>> 10)) & HASH_BITS; + } + + /** + * Replaces a list bin with a tree bin. Call only when locked. + * Fails to replace if the given key is non-comparable or table + * is, or needs, resizing. + */ + private final void replaceWithTreeBin(Node[] tab, int index, Object key) { + if ((key instanceof Comparable) && + (tab.length >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) { + TreeBin t = new TreeBin(); + for (Node e = tabAt(tab, index); e != null; e = e.next) + t.putTreeNode(e.hash & HASH_BITS, e.key, e.val); + setTabAt(tab, index, new Node(MOVED, t, null, null)); + } + } + + /* ---------------- Internal access and update methods -------------- */ + + /** Implementation for get and containsKey */ + private final Object internalGet(Object k) { + int h = spread(k.hashCode()); + retry: for (Node[] tab = table; tab != null;) { + Node e, p; Object ek, ev; int eh; // locals to read fields once + for (e = tabAt(tab, (tab.length - 1) & h); e != null; e = e.next) { + if ((eh = e.hash) == MOVED) { + if ((ek = e.key) instanceof TreeBin) // search TreeBin + return ((TreeBin)ek).getValue(h, k); + else { // restart with new table + tab = (Node[])ek; + continue retry; + } + } + else if ((eh & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + } + break; + } + return null; + } + + /** + * Implementation for the four public remove/replace methods: + * Replaces node value with v, conditional upon match of cv if + * non-null. If resulting value is null, delete. + */ + private final Object internalReplace(Object k, Object v, Object cv) { + int h = spread(k.hashCode()); + Object oldVal = null; + for (Node[] tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null || + (f = tabAt(tab, i = (tab.length - 1) & h)) == null) + break; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + boolean deleted = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) { + Object pv = p.val; + if (cv == null || cv == pv || cv.equals(pv)) { + oldVal = pv; + if ((p.val = v) == null) { + deleted = true; + t.deleteTreeNode(p); + } + } + } + } + } finally { + t.release(0); + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & HASH_BITS) != h && f.next == null) // precheck + break; // rules out possible existence + else if ((fh & LOCKED) != 0) { + checkForResize(); // try resizing if can't get lock + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + boolean validated = false; + boolean deleted = false; + try { + if (tabAt(tab, i) == f) { + validated = true; + for (Node e = f, pred = null;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + ((ev = e.val) != null) && + ((ek = e.key) == k || k.equals(ek))) { + if (cv == null || cv == ev || cv.equals(ev)) { + oldVal = ev; + if ((e.val = v) == null) { + deleted = true; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + } + break; + } + pred = e; + if ((e = e.next) == null) + break; + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + } + return oldVal; + } + + /* + * Internal versions of the six insertion methods, each a + * little more complicated than the last. All have + * the same basic structure as the first (internalPut): + * 1. If table uninitialized, create + * 2. If bin empty, try to CAS new node + * 3. If bin stale, use new table + * 4. if bin converted to TreeBin, validate and relay to TreeBin methods + * 5. Lock and validate; if valid, scan and add or update + * + * The others interweave other checks and/or alternative actions: + * * Plain put checks for and performs resize after insertion. + * * putIfAbsent prescans for mapping without lock (and fails to add + * if present), which also makes pre-emptive resize checks worthwhile. + * * computeIfAbsent extends form used in putIfAbsent with additional + * mechanics to deal with, calls, potential exceptions and null + * returns from function call. + * * compute uses the same function-call mechanics, but without + * the prescans + * * merge acts as putIfAbsent in the absent case, but invokes the + * update function if present + * * putAll attempts to pre-allocate enough table space + * and more lazily performs count updates and checks. + * + * Someday when details settle down a bit more, it might be worth + * some factoring to reduce sprawl. + */ + + /** Implementation for put */ + private final Object internalPut(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; // no lock when adding to empty bin + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) { + oldVal = p.val; + p.val = v; + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { // needed in case equals() throws + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { // unlock and signal if needed + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length <= 64) + count = 2; + break; + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for putIfAbsent */ + private final Object internalPutIfAbsent(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) + oldVal = p.val; + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { // at least 2 nodes -- search and maybe resize + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length <= 64) + count = 2; + break; + } + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for computeIfAbsent */ + private final Object internalComputeIfAbsent(K k, + Fun mf) { + int h = spread(k.hashCode()); + Object val = null; + int count = 0; + for (Node[] tab = table;;) { + Node f; int i, fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + count = 1; + try { + if ((val = mf.apply(k)) != null) + node.val = val; + } finally { + if (val == null) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean added = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + val = p.val; + else if ((val = mf.apply(k)) != null) { + added = true; + count = 2; + t.putTreeNode(h, k, val); + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (!added) + return val; + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + boolean added = false; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + if ((val = mf.apply(k)) != null) { + added = true; + last.next = new Node(h, k, val, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (!added) + return val; + if (tab.length <= 64) + count = 2; + break; + } + } + } + } + if (val != null) { + counter.add(1L); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for compute */ + @SuppressWarnings("unchecked") private final Object internalCompute + (K k, boolean onlyIfPresent, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (Node[] tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (onlyIfPresent) + break; + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + try { + count = 1; + if ((val = mf.apply(k, null)) != null) { + node.val = val; + delta = 1; + } + } finally { + if (delta == 0) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + Object pv; + if (p == null) { + if (onlyIfPresent) + break; + pv = null; + } else + pv = p.val; + if ((val = mf.apply(k, (V)pv)) != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply(k, (V)ev); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + if (!onlyIfPresent && (val = mf.apply(k, null)) != null) { + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for merge */ + @SuppressWarnings("unchecked") private final Object internalMerge + (K k, V v, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + delta = 1; + val = v; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + val = (p == null) ? v : mf.apply((V)p.val, v); + if (val != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply((V)ev, v); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + val = v; + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for putAll */ + private final void internalPutAll(Map m) { + tryPresize(m.size()); + long delta = 0L; // number of uncommitted additions + boolean npe = false; // to throw exception on exit for nulls + try { // to clean up counts on other exceptions + for (Map.Entry entry : m.entrySet()) { + Object k, v; + if (entry == null || (k = entry.getKey()) == null || + (v = entry.getValue()) == null) { + npe = true; + break; + } + int h = spread(k.hashCode()); + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null){ + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + ++delta; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + p.val = v; + else { + t.putTreeNode(h, k, v); + ++delta; + } + } + } finally { + t.release(0); + } + if (validated) + break; + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); + delta = 0L; + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + int count = 0; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + ++delta; + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (count > 1) { + counter.add(delta); + delta = 0L; + checkForResize(); + } + break; + } + } + } + } + } finally { + if (delta != 0) + counter.add(delta); + } + if (npe) + throw new NullPointerException(); + } + + /* ---------------- Table Initialization and Resizing -------------- */ + + /** + * Returns a power of two table size for the given desired capacity. + * See Hackers Delight, sec 3.2 + */ + private static final int tableSizeFor(int c) { + int n = c - 1; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; + } + + /** + * Initializes table, using the size recorded in sizeCtl. + */ + private final Node[] initTable() { + Node[] tab; int sc; + while ((tab = table) == null) { + if ((sc = sizeCtl) < 0) + Thread.yield(); // lost initialization race; just spin + else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if ((tab = table) == null) { + int n = (sc > 0) ? sc : DEFAULT_CAPACITY; + tab = table = new Node[n]; + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + break; + } + } + return tab; + } + + /** + * If table is too small and not already resizing, creates next + * table and transfers bins. Rechecks occupancy after a transfer + * to see if another resize is already needed because resizings + * are lagging additions. + */ + private final void checkForResize() { + Node[] tab; int n, sc; + while ((tab = table) != null && + (n = tab.length) < MAXIMUM_CAPACITY && + (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc && + UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (tab == table) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + + /** + * Tries to presize table to accommodate the given number of elements. + * + * @param size number of elements (doesn't need to be perfectly accurate) + */ + private final void tryPresize(int size) { + int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : + tableSizeFor(size + (size >>> 1) + 1); + int sc; + while ((sc = sizeCtl) >= 0) { + Node[] tab = table; int n; + if (tab == null || (n = tab.length) == 0) { + n = (sc > c) ? sc : c; + if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (table == tab) { + table = new Node[n]; + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + } + } + else if (c <= sc || n >= MAXIMUM_CAPACITY) + break; + else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (table == tab) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + } + + /* + * Moves and/or copies the nodes in each bin to new table. See + * above for explanation. + * + * @return the new table + */ + private static final Node[] rebuild(Node[] tab) { + int n = tab.length; + Node[] nextTab = new Node[n << 1]; + Node fwd = new Node(MOVED, nextTab, null, null); + int[] buffer = null; // holds bins to revisit; null until needed + Node rev = null; // reverse forwarder; null until needed + int nbuffered = 0; // the number of bins in buffer list + int bufferIndex = 0; // buffer index of current buffered bin + int bin = n - 1; // current non-buffered bin or -1 if none + + for (int i = bin;;) { // start upwards sweep + int fh; Node f; + if ((f = tabAt(tab, i)) == null) { + if (bin >= 0) { // Unbuffered; no lock needed (or available) + if (!casTabAt(tab, i, f, fwd)) + continue; + } + else { // transiently use a locked forwarding node + Node g = new Node(MOVED|LOCKED, nextTab, null, null); + if (!casTabAt(tab, i, f, g)) + continue; + setTabAt(nextTab, i, null); + setTabAt(nextTab, i + n, null); + setTabAt(tab, i, fwd); + if (!g.casHash(MOVED|LOCKED, MOVED)) { + g.hash = MOVED; + synchronized (g) { g.notifyAll(); } + } + } + } + else if ((fh = f.hash) == MOVED) { + Object fk = f.key; + if (fk instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + splitTreeBin(nextTab, i, t); + setTabAt(tab, i, fwd); + } + } finally { + t.release(0); + } + if (!validated) + continue; + } + } + else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) { + boolean validated = false; + try { // split to lo and hi lists; copying as needed + if (tabAt(tab, i) == f) { + validated = true; + splitBin(nextTab, i, f); + setTabAt(tab, i, fwd); + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (!validated) + continue; + } + else { + if (buffer == null) // initialize buffer for revisits + buffer = new int[TRANSFER_BUFFER_SIZE]; + if (bin < 0 && bufferIndex > 0) { + int j = buffer[--bufferIndex]; + buffer[bufferIndex] = i; + i = j; // swap with another bin + continue; + } + if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) { + f.tryAwaitLock(tab, i); + continue; // no other options -- block + } + if (rev == null) // initialize reverse-forwarder + rev = new Node(MOVED, tab, null, null); + if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0) + continue; // recheck before adding to list + buffer[nbuffered++] = i; + setTabAt(nextTab, i, rev); // install place-holders + setTabAt(nextTab, i + n, rev); + } + + if (bin > 0) + i = --bin; + else if (buffer != null && nbuffered > 0) { + bin = -1; + i = buffer[bufferIndex = --nbuffered]; + } + else + return nextTab; + } + } + + /** + * Splits a normal bin with list headed by e into lo and hi parts; + * installs in given table. + */ + private static void splitBin(Node[] nextTab, int i, Node e) { + int bit = nextTab.length >>> 1; // bit to split on + int runBit = e.hash & bit; + Node lastRun = e, lo = null, hi = null; + for (Node p = e.next; p != null; p = p.next) { + int b = p.hash & bit; + if (b != runBit) { + runBit = b; + lastRun = p; + } + } + if (runBit == 0) + lo = lastRun; + else + hi = lastRun; + for (Node p = e; p != lastRun; p = p.next) { + int ph = p.hash & HASH_BITS; + Object pk = p.key, pv = p.val; + if ((ph & bit) == 0) + lo = new Node(ph, pk, pv, lo); + else + hi = new Node(ph, pk, pv, hi); + } + setTabAt(nextTab, i, lo); + setTabAt(nextTab, i + bit, hi); + } + + /** + * Splits a tree bin into lo and hi parts; installs in given table. + */ + private static void splitTreeBin(Node[] nextTab, int i, TreeBin t) { + int bit = nextTab.length >>> 1; + TreeBin lt = new TreeBin(); + TreeBin ht = new TreeBin(); + int lc = 0, hc = 0; + for (Node e = t.first; e != null; e = e.next) { + int h = e.hash & HASH_BITS; + Object k = e.key, v = e.val; + if ((h & bit) == 0) { + ++lc; + lt.putTreeNode(h, k, v); + } + else { + ++hc; + ht.putTreeNode(h, k, v); + } + } + Node ln, hn; // throw away trees if too small + if (lc <= (TREE_THRESHOLD >>> 1)) { + ln = null; + for (Node p = lt.first; p != null; p = p.next) + ln = new Node(p.hash, p.key, p.val, ln); + } + else + ln = new Node(MOVED, lt, null, null); + setTabAt(nextTab, i, ln); + if (hc <= (TREE_THRESHOLD >>> 1)) { + hn = null; + for (Node p = ht.first; p != null; p = p.next) + hn = new Node(p.hash, p.key, p.val, hn); + } + else + hn = new Node(MOVED, ht, null, null); + setTabAt(nextTab, i + bit, hn); + } + + /** + * Implementation for clear. Steps through each bin, removing all + * nodes. + */ + private final void internalClear() { + long delta = 0L; // negative number of deletions + int i = 0; + Node[] tab = table; + while (tab != null && i < tab.length) { + int fh; Object fk; + Node f = tabAt(tab, i); + if (f == null) + ++i; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + for (Node p = t.first; p != null; p = p.next) { + if (p.val != null) { // (currently always true) + p.val = null; + --delta; + } + } + t.first = null; + t.root = null; + ++i; + } + } finally { + t.release(0); + } + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); // opportunistically update count + delta = 0L; + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + for (Node e = f; e != null; e = e.next) { + if (e.val != null) { // (currently always true) + e.val = null; + --delta; + } + } + setTabAt(tab, i, null); + ++i; + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + } + } + if (delta != 0) + counter.add(delta); + } + + /* ----------------Table Traversal -------------- */ + + /** + * Encapsulates traversal for methods such as containsValue; also + * serves as a base class for other iterators and bulk tasks. + * + * At each step, the iterator snapshots the key ("nextKey") and + * value ("nextVal") of a valid node (i.e., one that, at point of + * snapshot, has a non-null user value). Because val fields can + * change (including to null, indicating deletion), field nextVal + * might not be accurate at point of use, but still maintains the + * weak consistency property of holding a value that was once + * valid. To support iterator.remove, the nextKey field is not + * updated (nulled out) when the iterator cannot advance. + * + * Internal traversals directly access these fields, as in: + * {@code while (it.advance() != null) { process(it.nextKey); }} + * + * Exported iterators must track whether the iterator has advanced + * (in hasNext vs next) (by setting/checking/nulling field + * nextVal), and then extract key, value, or key-value pairs as + * return values of next(). + * + * The iterator visits once each still-valid node that was + * reachable upon iterator construction. It might miss some that + * were added to a bin after the bin was visited, which is OK wrt + * consistency guarantees. Maintaining this property in the face + * of possible ongoing resizes requires a fair amount of + * bookkeeping state that is difficult to optimize away amidst + * volatile accesses. Even so, traversal maintains reasonable + * throughput. + * + * Normally, iteration proceeds bin-by-bin traversing lists. + * However, if the table has been resized, then all future steps + * must traverse both the bin at the current index as well as at + * (index + baseSize); and so on for further resizings. To + * paranoically cope with potential sharing by users of iterators + * across threads, iteration terminates if a bounds checks fails + * for a table read. + * + * This class extends ForkJoinTask to streamline parallel + * iteration in bulk operations (see BulkTask). This adds only an + * int of space overhead, which is close enough to negligible in + * cases where it is not needed to not worry about it. Because + * ForkJoinTask is Serializable, but iterators need not be, we + * need to add warning suppressions. + */ + @SuppressWarnings("serial") static class Traverser { + final ConcurrentHashMapV8 map; + Node next; // the next entry to use + K nextKey; // cached key field of next + V nextVal; // cached val field of next + Node[] tab; // current table; updated if resized + int index; // index of bin to use next + int baseIndex; // current index of initial table + int baseLimit; // index bound for initial table + int baseSize; // initial table size + + /** Creates iterator for all entries in the table. */ + Traverser(ConcurrentHashMapV8 map) { + this.map = map; + } + + /** Creates iterator for split() methods */ + Traverser(Traverser it) { + ConcurrentHashMapV8 m; Node[] t; + if ((m = this.map = it.map) == null) + t = null; + else if ((t = it.tab) == null && // force parent tab initialization + (t = it.tab = m.table) != null) + it.baseLimit = it.baseSize = t.length; + this.tab = t; + this.baseSize = it.baseSize; + it.baseLimit = this.index = this.baseIndex = + ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1; + } + + /** + * Advances next; returns nextVal or null if terminated. + * See above for explanation. + */ + final V advance() { + Node e = next; + V ev = null; + outer: do { + if (e != null) // advance past used/skipped node + e = e.next; + while (e == null) { // get to next non-null bin + ConcurrentHashMapV8 m; + Node[] t; int b, i, n; Object ek; // checks must use locals + if ((t = tab) != null) + n = t.length; + else if ((m = map) != null && (t = tab = m.table) != null) + n = baseLimit = baseSize = t.length; + else + break outer; + if ((b = baseIndex) >= baseLimit || + (i = index) < 0 || i >= n) + break outer; + if ((e = tabAt(t, i)) != null && e.hash == MOVED) { + if ((ek = e.key) instanceof TreeBin) + e = ((TreeBin)ek).first; + else { + tab = (Node[])ek; + continue; // restarts due to null val + } + } // visit upper slots if present + index = (i += baseSize) < n ? i : (baseIndex = b + 1); + } + nextKey = (K) e.key; + } while ((ev = (V) e.val) == null); // skip deleted or special nodes + next = e; + return nextVal = ev; + } + + public final void remove() { + Object k = nextKey; + if (k == null && (advance() == null || (k = nextKey) == null)) + throw new IllegalStateException(); + map.internalReplace(k, null, null); + } + + public final boolean hasNext() { + return nextVal != null || advance() != null; + } + + public final boolean hasMoreElements() { return hasNext(); } + public final void setRawResult(Object x) { } + public R getRawResult() { return null; } + public boolean exec() { return true; } + } + + /* ---------------- Public operations -------------- */ + + /** + * Creates a new, empty map with the default initial table size (16). + */ + public ConcurrentHashMapV8() { + this.counter = new LongAdder(); + } + + /** + * Creates a new, empty map with an initial table size + * accommodating the specified number of elements without the need + * to dynamically resize. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + */ + public ConcurrentHashMapV8(int initialCapacity) { + if (initialCapacity < 0) + throw new IllegalArgumentException(); + int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? + MAXIMUM_CAPACITY : + tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new map with the same mappings as the given map. + * + * @param m the map + */ + public ConcurrentHashMapV8(Map m) { + this.counter = new LongAdder(); + this.sizeCtl = DEFAULT_CAPACITY; + internalPutAll(m); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}) and + * initial table density ({@code loadFactor}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @throws IllegalArgumentException if the initial capacity of + * elements is negative or the load factor is nonpositive + * + * @since 1.6 + */ + public ConcurrentHashMapV8(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, 1); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}), table + * density ({@code loadFactor}), and number of concurrently + * updating threads ({@code concurrencyLevel}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @param concurrencyLevel the estimated number of concurrently + * updating threads. The implementation may use this value as + * a sizing hint. + * @throws IllegalArgumentException if the initial capacity is + * negative or the load factor or concurrencyLevel are + * nonpositive + */ + public ConcurrentHashMapV8(int initialCapacity, + float loadFactor, int concurrencyLevel) { + if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) + throw new IllegalArgumentException(); + if (initialCapacity < concurrencyLevel) // Use at least as many bins + initialCapacity = concurrencyLevel; // as estimated threads + long size = (long)(1.0 + (long)initialCapacity / loadFactor); + int cap = (size >= (long)MAXIMUM_CAPACITY) ? + MAXIMUM_CAPACITY : tableSizeFor((int)size); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @return the new set + */ + public static KeySetView newKeySet() { + return new KeySetView(new ConcurrentHashMapV8(), + Boolean.TRUE); + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + * @return the new set + */ + public static KeySetView newKeySet(int initialCapacity) { + return new KeySetView(new ConcurrentHashMapV8(initialCapacity), + Boolean.TRUE); + } + + /** + * {@inheritDoc} + */ + public boolean isEmpty() { + return counter.sum() <= 0L; // ignore transient negative values + } + + /** + * {@inheritDoc} + */ + public int size() { + long n = counter.sum(); + return ((n < 0L) ? 0 : + (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : + (int)n); + } + + /** + * Returns the number of mappings. This method should be used + * instead of {@link #size} because a ConcurrentHashMapV8 may + * contain more mappings than can be represented as an int. The + * value returned is a snapshot; the actual count may differ if + * there are ongoing concurrent insertions or removals. + * + * @return the number of mappings + */ + public long mappingCount() { + long n = counter.sum(); + return (n < 0L) ? 0L : n; // ignore transient negative values + } + + /** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + * + *

More formally, if this map contains a mapping from a key + * {@code k} to a value {@code v} such that {@code key.equals(k)}, + * then this method returns {@code v}; otherwise it returns + * {@code null}. (There can be at most one such mapping.) + * + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V get(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalGet(key); + } + + /** + * Returns the value to which the specified key is mapped, + * or the given defaultValue if this map contains no mapping for the key. + * + * @param key the key + * @param defaultValue the value to return if this map contains + * no mapping for the given key + * @return the mapping for the key, if present; else the defaultValue + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) { + if (key == null) + throw new NullPointerException(); + V v = (V) internalGet(key); + return v == null ? defaultValue : v; + } + + /** + * Tests if the specified object is a key in this table. + * + * @param key possible key + * @return {@code true} if and only if the specified object + * is a key in this table, as determined by the + * {@code equals} method; {@code false} otherwise + * @throws NullPointerException if the specified key is null + */ + public boolean containsKey(Object key) { + if (key == null) + throw new NullPointerException(); + return internalGet(key) != null; + } + + /** + * Returns {@code true} if this map maps one or more keys to the + * specified value. Note: This method may require a full traversal + * of the map, and is much slower than method {@code containsKey}. + * + * @param value value whose presence in this map is to be tested + * @return {@code true} if this map maps one or more keys to the + * specified value + * @throws NullPointerException if the specified value is null + */ + public boolean containsValue(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return true; + } + return false; + } + + public K findKey(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return it.nextKey; + } + return null; + } + + /** + * Legacy method testing if some key maps into the specified value + * in this table. This method is identical in functionality to + * {@link #containsValue}, and exists solely to ensure + * full compatibility with class {@link java.util.Hashtable}, + * which supported this method prior to introduction of the + * Java Collections framework. + * + * @param value a value to search for + * @return {@code true} if and only if some key maps to the + * {@code value} argument in this table as + * determined by the {@code equals} method; + * {@code false} otherwise + * @throws NullPointerException if the specified value is null + */ + public boolean contains(Object value) { + return containsValue(value); + } + + /** + * Maps the specified key to the specified value in this table. + * Neither the key nor the value can be null. + * + *

The value can be retrieved by calling the {@code get} method + * with a key that is equal to the original key. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V put(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPut(key, value); + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPutIfAbsent(key, value); + } + + /** + * Copies all of the mappings from the specified map to this one. + * These mappings replace any mappings that this map had for any of the + * keys currently in the specified map. + * + * @param m mappings to be stored in this map + */ + public void putAll(Map m) { + internalPutAll(m); + } + + /** + * If the specified key is not already associated with a value, + * computes its value using the given mappingFunction and enters + * it into the map unless null. This is equivalent to + *

 {@code
+     * if (map.containsKey(key))
+     *   return map.get(key);
+     * value = mappingFunction.apply(key);
+     * if (value != null)
+     *   map.put(key, value);
+     * return value;}
+ * + * except that the action is performed atomically. If the + * function returns {@code null} no mapping is recorded. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and no mapping is recorded. Some + * attempted update operations on this map by other threads may be + * blocked while computation is in progress, so the computation + * should be short and simple, and must not attempt to update any + * other mappings of this Map. The most appropriate usage is to + * construct a new object serving as an initial mapped value, or + * memoized result, as in: + * + *
 {@code
+     * map.computeIfAbsent(key, new Fun() {
+     *   public V map(K k) { return new Value(f(k)); }});}
+ * + * @param key key with which the specified value is to be associated + * @param mappingFunction the function to compute a value + * @return the current (existing or computed) value associated with + * the specified key, or null if the computed value is null + * @throws NullPointerException if the specified key or mappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the mappingFunction does so, + * in which case the mapping is left unestablished + */ + @SuppressWarnings("unchecked") public V computeIfAbsent + (K key, Fun mappingFunction) { + if (key == null || mappingFunction == null) + throw new NullPointerException(); + return (V)internalComputeIfAbsent(key, mappingFunction); + } + + /** + * If the given key is present, computes a new mapping value given a key and + * its current mapped value. This is equivalent to + *
 {@code
+     *   if (map.containsKey(key)) {
+     *     value = remappingFunction.apply(key, map.get(key));
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V computeIfPresent + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, true, remappingFunction); + } + + /** + * Computes a new mapping value given a key and + * its current mapped value (or {@code null} if there is no current + * mapping). This is equivalent to + *
 {@code
+     *   value = remappingFunction.apply(key, map.get(key));
+     *   if (value != null)
+     *     map.put(key, value);
+     *   else
+     *     map.remove(key);
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + *
 {@code
+     * Map map = ...;
+     * final String msg = ...;
+     * map.compute(key, new BiFun() {
+     *   public String apply(Key k, String v) {
+     *    return (v == null) ? msg : v + msg;});}}
+ * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V compute + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, false, remappingFunction); + } + + /** + * If the specified key is not already associated + * with a value, associate it with the given value. + * Otherwise, replace the value with the results of + * the given remapping function. This is equivalent to: + *
 {@code
+     *   if (!map.containsKey(key))
+     *     map.put(value);
+     *   else {
+     *     newValue = remappingFunction.apply(map.get(key), value);
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. + */ + @SuppressWarnings("unchecked") public V merge + (K key, V value, BiFun remappingFunction) { + if (key == null || value == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalMerge(key, value, remappingFunction); + } + + /** + * Removes the key (and its corresponding value) from this map. + * This method does nothing if the key is not in the map. + * + * @param key the key that needs to be removed + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V remove(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalReplace(key, null, null); + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if the specified key is null + */ + public boolean remove(Object key, Object value) { + if (key == null) + throw new NullPointerException(); + if (value == null) + return false; + return internalReplace(key, null, value) != null; + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if any of the arguments are null + */ + public boolean replace(K key, V oldValue, V newValue) { + if (key == null || oldValue == null || newValue == null) + throw new NullPointerException(); + return internalReplace(key, newValue, oldValue) != null; + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V replace(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalReplace(key, value, null); + } + + /** + * Removes all of the mappings from this map. + */ + public void clear() { + internalClear(); + } + + /** + * Returns a {@link Set} view of the keys contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. + * + * @return the set view + */ + public KeySetView keySet() { + KeySetView ks = keySet; + return (ks != null) ? ks : (keySet = new KeySetView(this, null)); + } + + /** + * Returns a {@link Set} view of the keys in this map, using the + * given common mapped value for any additions (i.e., {@link + * Collection#add} and {@link Collection#addAll}). This is of + * course only appropriate if it is acceptable to use the same + * value for all additions from this view. + * + * @param mappedValue the mapped value to use for any + * additions. + * @return the set view + * @throws NullPointerException if the mappedValue is null + */ + public KeySetView keySet(V mappedValue) { + if (mappedValue == null) + throw new NullPointerException(); + return new KeySetView(this, mappedValue); + } + + /** + * Returns a {@link Collection} view of the values contained in this map. + * The collection is backed by the map, so changes to the map are + * reflected in the collection, and vice-versa. + */ + public ValuesView values() { + ValuesView vs = values; + return (vs != null) ? vs : (values = new ValuesView(this)); + } + + /** + * Returns a {@link Set} view of the mappings contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or + * {@code addAll} operations. + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Set> entrySet() { + EntrySetView es = entrySet; + return (es != null) ? es : (entrySet = new EntrySetView(this)); + } + + /** + * Returns an enumeration of the keys in this table. + * + * @return an enumeration of the keys in this table + * @see #keySet() + */ + public Enumeration keys() { + return new KeyIterator(this); + } + + /** + * Returns an enumeration of the values in this table. + * + * @return an enumeration of the values in this table + * @see #values() + */ + public Enumeration elements() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the keys in this map. + * + * @return a partitionable iterator of the keys in this map + */ + public Spliterator keySpliterator() { + return new KeyIterator(this); + } + + /** + * Returns a partitionable iterator of the values in this map. + * + * @return a partitionable iterator of the values in this map + */ + public Spliterator valueSpliterator() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the entries in this map. + * + * @return a partitionable iterator of the entries in this map + */ + public Spliterator> entrySpliterator() { + return new EntryIterator(this); + } + + /** + * Returns the hash code value for this {@link Map}, i.e., + * the sum of, for each key-value pair in the map, + * {@code key.hashCode() ^ value.hashCode()}. + * + * @return the hash code value for this map + */ + public int hashCode() { + int h = 0; + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + h += it.nextKey.hashCode() ^ v.hashCode(); + } + return h; + } + + /** + * Returns a string representation of this map. The string + * representation consists of a list of key-value mappings (in no + * particular order) enclosed in braces ("{@code {}}"). Adjacent + * mappings are separated by the characters {@code ", "} (comma + * and space). Each key-value mapping is rendered as the key + * followed by an equals sign ("{@code =}") followed by the + * associated value. + * + * @return a string representation of this map + */ + public String toString() { + Traverser it = new Traverser(this); + StringBuilder sb = new StringBuilder(); + sb.append('{'); + Object v; + if ((v = it.advance()) != null) { + for (;;) { + Object k = it.nextKey; + sb.append(k == this ? "(this Map)" : k); + sb.append('='); + sb.append(v == this ? "(this Map)" : v); + if ((v = it.advance()) == null) + break; + sb.append(',').append(' '); + } + } + return sb.append('}').toString(); + } + + /** + * Compares the specified object with this map for equality. + * Returns {@code true} if the given object is a map with the same + * mappings as this map. This operation may return misleading + * results if either map is concurrently modified during execution + * of this method. + * + * @param o object to be compared for equality with this map + * @return {@code true} if the specified object is equal to this map + */ + public boolean equals(Object o) { + if (o != this) { + if (!(o instanceof Map)) + return false; + Map m = (Map) o; + Traverser it = new Traverser(this); + Object val; + while ((val = it.advance()) != null) { + Object v = m.get(it.nextKey); + if (v == null || (v != val && !v.equals(val))) + return false; + } + for (Map.Entry e : m.entrySet()) { + Object mk, mv, v; + if ((mk = e.getKey()) == null || + (mv = e.getValue()) == null || + (v = internalGet(mk)) == null || + (mv != v && !mv.equals(v))) + return false; + } + } + return true; + } + + /* ----------------Iterators -------------- */ + + @SuppressWarnings("serial") static final class KeyIterator extends Traverser + implements Spliterator, Enumeration { + KeyIterator(ConcurrentHashMapV8 map) { super(map); } + KeyIterator(Traverser it) { + super(it); + } + public KeyIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new KeyIterator(this); + } + @SuppressWarnings("unchecked") public final K next() { + if (nextVal == null && advance() == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return (K) k; + } + + public final K nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class ValueIterator extends Traverser + implements Spliterator, Enumeration { + ValueIterator(ConcurrentHashMapV8 map) { super(map); } + ValueIterator(Traverser it) { + super(it); + } + public ValueIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new ValueIterator(this); + } + + @SuppressWarnings("unchecked") public final V next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + nextVal = null; + return (V) v; + } + + public final V nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class EntryIterator extends Traverser + implements Spliterator> { + EntryIterator(ConcurrentHashMapV8 map) { super(map); } + EntryIterator(Traverser it) { + super(it); + } + public EntryIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new EntryIterator(this); + } + + @SuppressWarnings("unchecked") public final Map.Entry next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return new MapEntry((K)k, (V)v, map); + } + } + + /** + * Exported Entry for iterators + */ + static final class MapEntry implements Map.Entry { + final K key; // non-null + V val; // non-null + final ConcurrentHashMapV8 map; + MapEntry(K key, V val, ConcurrentHashMapV8 map) { + this.key = key; + this.val = val; + this.map = map; + } + public final K getKey() { return key; } + public final V getValue() { return val; } + public final int hashCode() { return key.hashCode() ^ val.hashCode(); } + public final String toString(){ return key + "=" + val; } + + public final boolean equals(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + (k == key || k.equals(key)) && + (v == val || v.equals(val))); + } + + /** + * Sets our entry's value and writes through to the map. The + * value to return is somewhat arbitrary here. Since we do not + * necessarily track asynchronous changes, the most recent + * "previous" value could be different from what we return (or + * could even have been removed in which case the put will + * re-establish). We do not and cannot guarantee more. + */ + public final V setValue(V value) { + if (value == null) throw new NullPointerException(); + V v = val; + val = value; + map.put(key, value); + return v; + } + } + + /* ---------------- Serialization Support -------------- */ + + /** + * Stripped-down version of helper class used in previous version, + * declared for the sake of serialization compatibility + */ + static class Segment implements Serializable { + private static final long serialVersionUID = 2249069246763182397L; + final float loadFactor; + Segment(float lf) { this.loadFactor = lf; } + } + + /** + * Saves the state of the {@code ConcurrentHashMapV8} instance to a + * stream (i.e., serializes it). + * @param s the stream + * @serialData + * the key (Object) and value (Object) + * for each key-value mapping, followed by a null pair. + * The key-value mappings are emitted in no particular order. + */ + @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + if (segments == null) { // for serialization compatibility + segments = (Segment[]) + new Segment[DEFAULT_CONCURRENCY_LEVEL]; + for (int i = 0; i < segments.length; ++i) + segments[i] = new Segment(LOAD_FACTOR); + } + s.defaultWriteObject(); + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + s.writeObject(it.nextKey); + s.writeObject(v); + } + s.writeObject(null); + s.writeObject(null); + segments = null; // throw away + } + + /** + * Reconstitutes the instance from a stream (that is, deserializes it). + * @param s the stream + */ + @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + this.segments = null; // unneeded + // initialize transient final field + UNSAFE.putObjectVolatile(this, counterOffset, new LongAdder()); + + // Create all nodes, then place in table once size is known + long size = 0L; + Node p = null; + for (;;) { + K k = (K) s.readObject(); + V v = (V) s.readObject(); + if (k != null && v != null) { + int h = spread(k.hashCode()); + p = new Node(h, k, v, p); + ++size; + } + else + break; + } + if (p != null) { + boolean init = false; + int n; + if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) + n = MAXIMUM_CAPACITY; + else { + int sz = (int)size; + n = tableSizeFor(sz + (sz >>> 1) + 1); + } + int sc = sizeCtl; + boolean collide = false; + if (n > sc && + UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (table == null) { + init = true; + Node[] tab = new Node[n]; + int mask = n - 1; + while (p != null) { + int j = p.hash & mask; + Node next = p.next; + Node q = p.next = tabAt(tab, j); + setTabAt(tab, j, p); + if (!collide && q != null && q.hash == p.hash) + collide = true; + p = next; + } + table = tab; + counter.add(size); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + if (collide) { // rescan and convert to TreeBins + Node[] tab = table; + for (int i = 0; i < tab.length; ++i) { + int c = 0; + for (Node e = tabAt(tab, i); e != null; e = e.next) { + if (++c > TREE_THRESHOLD && + (e.key instanceof Comparable)) { + replaceWithTreeBin(tab, i, e.key); + break; + } + } + } + } + } + if (!init) { // Can only happen if unsafely published. + while (p != null) { + internalPut(p.key, p.val); + p = p.next; + } + } + } + } + + + // ------------------------------------------------------- + + // Sams + /** Interface describing a void action of one argument */ + public interface Action { void apply(A a); } + /** Interface describing a void action of two arguments */ + public interface BiAction { void apply(A a, B b); } + /** Interface describing a function of one argument */ + public interface Generator { T apply(); } + /** Interface describing a function mapping its argument to a double */ + public interface ObjectToDouble { double apply(A a); } + /** Interface describing a function mapping its argument to a long */ + public interface ObjectToLong { long apply(A a); } + /** Interface describing a function mapping its argument to an int */ + public interface ObjectToInt {int apply(A a); } + /** Interface describing a function mapping two arguments to a double */ + public interface ObjectByObjectToDouble { double apply(A a, B b); } + /** Interface describing a function mapping two arguments to a long */ + public interface ObjectByObjectToLong { long apply(A a, B b); } + /** Interface describing a function mapping two arguments to an int */ + public interface ObjectByObjectToInt {int apply(A a, B b); } + /** Interface describing a function mapping a double to a double */ + public interface DoubleToDouble { double apply(double a); } + /** Interface describing a function mapping a long to a long */ + public interface LongToLong { long apply(long a); } + /** Interface describing a function mapping an int to an int */ + public interface IntToInt { int apply(int a); } + /** Interface describing a function mapping two doubles to a double */ + public interface DoubleByDoubleToDouble { double apply(double a, double b); } + /** Interface describing a function mapping two longs to a long */ + public interface LongByLongToLong { long apply(long a, long b); } + /** Interface describing a function mapping two ints to an int */ + public interface IntByIntToInt { int apply(int a, int b); } + + + /* ----------------Views -------------- */ + + /** + * Base class for views. + */ + static abstract class CHMView { + final ConcurrentHashMapV8 map; + CHMView(ConcurrentHashMapV8 map) { this.map = map; } + + /** + * Returns the map backing this view. + * + * @return the map backing this view + */ + public ConcurrentHashMapV8 getMap() { return map; } + + public final int size() { return map.size(); } + public final boolean isEmpty() { return map.isEmpty(); } + public final void clear() { map.clear(); } + + // implementations below rely on concrete classes supplying these + abstract public Iterator iterator(); + abstract public boolean contains(Object o); + abstract public boolean remove(Object o); + + private static final String oomeMsg = "Required array size too large"; + + public final Object[] toArray() { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int n = (int)sz; + Object[] r = new Object[n]; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = it.next(); + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + @SuppressWarnings("unchecked") public final T[] toArray(T[] a) { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int m = (int)sz; + T[] r = (a.length >= m) ? a : + (T[])java.lang.reflect.Array + .newInstance(a.getClass().getComponentType(), m); + int n = r.length; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = (T)it.next(); + } + if (a == r && i < n) { + r[i] = null; // null-terminate + return r; + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + public final int hashCode() { + int h = 0; + for (Iterator it = iterator(); it.hasNext();) + h += it.next().hashCode(); + return h; + } + + public final String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + Iterator it = iterator(); + if (it.hasNext()) { + for (;;) { + Object e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (!it.hasNext()) + break; + sb.append(',').append(' '); + } + } + return sb.append(']').toString(); + } + + public final boolean containsAll(Collection c) { + if (c != this) { + for (Iterator it = c.iterator(); it.hasNext();) { + Object e = it.next(); + if (e == null || !contains(e)) + return false; + } + } + return true; + } + + public final boolean removeAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + public final boolean retainAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (!c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in + * which additions may optionally be enabled by mapping to a + * common value. This class cannot be directly instantiated. See + * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()}, + * {@link #newKeySet(int)}. + */ + public static class KeySetView extends CHMView implements Set, java.io.Serializable { + private static final long serialVersionUID = 7249069246763182397L; + private final V value; + KeySetView(ConcurrentHashMapV8 map, V value) { // non-public + super(map); + this.value = value; + } + + /** + * Returns the default mapped value for additions, + * or {@code null} if additions are not supported. + * + * @return the default mapped value for additions, or {@code null} + * if not supported. + */ + public V getMappedValue() { return value; } + + // implement Set API + + public boolean contains(Object o) { return map.containsKey(o); } + public boolean remove(Object o) { return map.remove(o) != null; } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the keys of this map + */ + public Iterator iterator() { return new KeyIterator(map); } + public boolean add(K e) { + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + if (e == null) + throw new NullPointerException(); + return map.internalPutIfAbsent(e, v) == null; + } + public boolean addAll(Collection c) { + boolean added = false; + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + for (K e : c) { + if (e == null) + throw new NullPointerException(); + if (map.internalPutIfAbsent(e, v) == null) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Collection} of + * values, in which additions are disabled. This class cannot be + * directly instantiated. See {@link #values}, + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public static final class ValuesView extends CHMView + implements Collection { + ValuesView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { return map.containsValue(o); } + public final boolean remove(Object o) { + if (o != null) { + Iterator it = new ValueIterator(map); + while (it.hasNext()) { + if (o.equals(it.next())) { + it.remove(); + return true; + } + } + } + return false; + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the values of this map + */ + public final Iterator iterator() { + return new ValueIterator(map); + } + public final boolean add(V e) { + throw new UnsupportedOperationException(); + } + public final boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value) + * entries. This class cannot be directly instantiated. See + * {@link #entrySet}. + */ + public static final class EntrySetView extends CHMView + implements Set> { + EntrySetView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { + Object k, v, r; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (r = map.get(k)) != null && + (v = e.getValue()) != null && + (v == r || v.equals(r))); + } + public final boolean remove(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + map.remove(k, v)); + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the entries of this map + */ + public final Iterator> iterator() { + return new EntryIterator(map); + } + + public final boolean add(Entry e) { + K key = e.getKey(); + V value = e.getValue(); + if (key == null || value == null) + throw new NullPointerException(); + return map.internalPut(key, value) == null; + } + public final boolean addAll(Collection> c) { + boolean added = false; + for (Entry e : c) { + if (add(e)) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long counterOffset; + private static final long sizeCtlOffset; + private static final long ABASE; + private static final int ASHIFT; + + static { + int ss; + try { + UNSAFE = getUnsafe(); + Class k = ConcurrentHashMapV8.class; + counterOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("counter")); + sizeCtlOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("sizeCtl")); + Class sc = Node[].class; + ABASE = UNSAFE.arrayBaseOffset(sc); + ss = UNSAFE.arrayIndexScale(sc); + } catch (Exception e) { + throw new Error(e); + } + if ((ss & (ss-1)) != 0) + throw new Error("data type scale not a power of two"); + ASHIFT = 31 - Integer.numberOfLeadingZeros(ss); + } + + /** + * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. + * Replace with a simple call to Unsafe.getUnsafe when integrating + * into a jdk. + * + * @return a sun.misc.Unsafe + */ + private static sun.misc.Unsafe getUnsafe() { + try { + return sun.misc.Unsafe.getUnsafe(); + } catch (SecurityException se) { + try { + return java.security.AccessController.doPrivileged + (new java.security + .PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + java.lang.reflect.Field f = sun.misc + .Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (sun.misc.Unsafe) f.get(null); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java new file mode 100644 index 0000000..47a923c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java @@ -0,0 +1,203 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.9 version. + +package com.concurrent_ruby.ext.jsr166e; +import java.util.concurrent.atomic.AtomicLong; +import java.io.IOException; +import java.io.Serializable; +import java.io.ObjectInputStream; + +/** + * One or more variables that together maintain an initially zero + * {@code long} sum. When updates (method {@link #add}) are contended + * across threads, the set of variables may grow dynamically to reduce + * contention. Method {@link #sum} (or, equivalently, {@link + * #longValue}) returns the current total combined across the + * variables maintaining the sum. + * + *

This class is usually preferable to {@link AtomicLong} when + * multiple threads update a common sum that is used for purposes such + * as collecting statistics, not for fine-grained synchronization + * control. Under low update contention, the two classes have similar + * characteristics. But under high contention, expected throughput of + * this class is significantly higher, at the expense of higher space + * consumption. + * + *

This class extends {@link Number}, but does not define + * methods such as {@code hashCode} and {@code compareTo} because + * instances are expected to be mutated, and so are not useful as + * collection keys. + * + *

jsr166e note: This class is targeted to be placed in + * java.util.concurrent.atomic. + * + * @since 1.8 + * @author Doug Lea + */ +public class LongAdder extends Striped64 implements Serializable { + private static final long serialVersionUID = 7249069246863182397L; + + /** + * Version of plus for use in retryUpdate + */ + final long fn(long v, long x) { return v + x; } + + /** + * Creates a new adder with initial sum of zero. + */ + public LongAdder() { + } + + /** + * Adds the given value. + * + * @param x the value to add + */ + public void add(long x) { + Cell[] as; long b, v; HashCode hc; Cell a; int n; + if ((as = cells) != null || !casBase(b = base, b + x)) { + boolean uncontended = true; + int h = (hc = threadHashCode.get()).code; + if (as == null || (n = as.length) < 1 || + (a = as[(n - 1) & h]) == null || + !(uncontended = a.cas(v = a.value, v + x))) + retryUpdate(x, hc, uncontended); + } + } + + /** + * Equivalent to {@code add(1)}. + */ + public void increment() { + add(1L); + } + + /** + * Equivalent to {@code add(-1)}. + */ + public void decrement() { + add(-1L); + } + + /** + * Returns the current sum. The returned value is NOT an + * atomic snapshot: Invocation in the absence of concurrent + * updates returns an accurate result, but concurrent updates that + * occur while the sum is being calculated might not be + * incorporated. + * + * @return the sum + */ + public long sum() { + long sum = base; + Cell[] as = cells; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + sum += a.value; + } + } + return sum; + } + + /** + * Resets variables maintaining the sum to zero. This method may + * be a useful alternative to creating a new adder, but is only + * effective if there are no concurrent updates. Because this + * method is intrinsically racy, it should only be used when it is + * known that no threads are concurrently updating. + */ + public void reset() { + internalReset(0L); + } + + /** + * Equivalent in effect to {@link #sum} followed by {@link + * #reset}. This method may apply for example during quiescent + * points between multithreaded computations. If there are + * updates concurrent with this method, the returned value is + * not guaranteed to be the final value occurring before + * the reset. + * + * @return the sum + */ + public long sumThenReset() { + long sum = base; + Cell[] as = cells; + base = 0L; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) { + sum += a.value; + a.value = 0L; + } + } + } + return sum; + } + + /** + * Returns the String representation of the {@link #sum}. + * @return the String representation of the {@link #sum} + */ + public String toString() { + return Long.toString(sum()); + } + + /** + * Equivalent to {@link #sum}. + * + * @return the sum + */ + public long longValue() { + return sum(); + } + + /** + * Returns the {@link #sum} as an {@code int} after a narrowing + * primitive conversion. + */ + public int intValue() { + return (int)sum(); + } + + /** + * Returns the {@link #sum} as a {@code float} + * after a widening primitive conversion. + */ + public float floatValue() { + return (float)sum(); + } + + /** + * Returns the {@link #sum} as a {@code double} after a widening + * primitive conversion. + */ + public double doubleValue() { + return (double)sum(); + } + + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + s.defaultWriteObject(); + s.writeLong(sum()); + } + + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + busy = 0; + cells = null; + base = s.readLong(); + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java new file mode 100644 index 0000000..93a277f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java @@ -0,0 +1,342 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.5 version. + +package com.concurrent_ruby.ext.jsr166e; +import java.util.Random; + +/** + * A package-local class holding common representation and mechanics + * for classes supporting dynamic striping on 64bit values. The class + * extends Number so that concrete subclasses must publicly do so. + */ +abstract class Striped64 extends Number { + /* + * This class maintains a lazily-initialized table of atomically + * updated variables, plus an extra "base" field. The table size + * is a power of two. Indexing uses masked per-thread hash codes. + * Nearly all declarations in this class are package-private, + * accessed directly by subclasses. + * + * Table entries are of class Cell; a variant of AtomicLong padded + * to reduce cache contention on most processors. Padding is + * overkill for most Atomics because they are usually irregularly + * scattered in memory and thus don't interfere much with each + * other. But Atomic objects residing in arrays will tend to be + * placed adjacent to each other, and so will most often share + * cache lines (with a huge negative performance impact) without + * this precaution. + * + * In part because Cells are relatively large, we avoid creating + * them until they are needed. When there is no contention, all + * updates are made to the base field. Upon first contention (a + * failed CAS on base update), the table is initialized to size 2. + * The table size is doubled upon further contention until + * reaching the nearest power of two greater than or equal to the + * number of CPUS. Table slots remain empty (null) until they are + * needed. + * + * A single spinlock ("busy") is used for initializing and + * resizing the table, as well as populating slots with new Cells. + * There is no need for a blocking lock: When the lock is not + * available, threads try other slots (or the base). During these + * retries, there is increased contention and reduced locality, + * which is still better than alternatives. + * + * Per-thread hash codes are initialized to random values. + * Contention and/or table collisions are indicated by failed + * CASes when performing an update operation (see method + * retryUpdate). Upon a collision, if the table size is less than + * the capacity, it is doubled in size unless some other thread + * holds the lock. If a hashed slot is empty, and lock is + * available, a new Cell is created. Otherwise, if the slot + * exists, a CAS is tried. Retries proceed by "double hashing", + * using a secondary hash (Marsaglia XorShift) to try to find a + * free slot. + * + * The table size is capped because, when there are more threads + * than CPUs, supposing that each thread were bound to a CPU, + * there would exist a perfect hash function mapping threads to + * slots that eliminates collisions. When we reach capacity, we + * search for this mapping by randomly varying the hash codes of + * colliding threads. Because search is random, and collisions + * only become known via CAS failures, convergence can be slow, + * and because threads are typically not bound to CPUS forever, + * may not occur at all. However, despite these limitations, + * observed contention rates are typically low in these cases. + * + * It is possible for a Cell to become unused when threads that + * once hashed to it terminate, as well as in the case where + * doubling the table causes no thread to hash to it under + * expanded mask. We do not try to detect or remove such cells, + * under the assumption that for long-running instances, observed + * contention levels will recur, so the cells will eventually be + * needed again; and for short-lived ones, it does not matter. + */ + + /** + * Padded variant of AtomicLong supporting only raw accesses plus CAS. + * The value field is placed between pads, hoping that the JVM doesn't + * reorder them. + * + * JVM intrinsics note: It would be possible to use a release-only + * form of CAS here, if it were provided. + */ + static final class Cell { + volatile long p0, p1, p2, p3, p4, p5, p6; + volatile long value; + volatile long q0, q1, q2, q3, q4, q5, q6; + Cell(long x) { value = x; } + + final boolean cas(long cmp, long val) { + return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val); + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long valueOffset; + static { + try { + UNSAFE = getUnsafe(); + Class ak = Cell.class; + valueOffset = UNSAFE.objectFieldOffset + (ak.getDeclaredField("value")); + } catch (Exception e) { + throw new Error(e); + } + } + + } + + /** + * Holder for the thread-local hash code. The code is initially + * random, but may be set to a different value upon collisions. + */ + static final class HashCode { + static final Random rng = new Random(); + int code; + HashCode() { + int h = rng.nextInt(); // Avoid zero to allow xorShift rehash + code = (h == 0) ? 1 : h; + } + } + + /** + * The corresponding ThreadLocal class + */ + static final class ThreadHashCode extends ThreadLocal { + public HashCode initialValue() { return new HashCode(); } + } + + /** + * Static per-thread hash codes. Shared across all instances to + * reduce ThreadLocal pollution and because adjustments due to + * collisions in one table are likely to be appropriate for + * others. + */ + static final ThreadHashCode threadHashCode = new ThreadHashCode(); + + /** Number of CPUS, to place bound on table size */ + static final int NCPU = Runtime.getRuntime().availableProcessors(); + + /** + * Table of cells. When non-null, size is a power of 2. + */ + transient volatile Cell[] cells; + + /** + * Base value, used mainly when there is no contention, but also as + * a fallback during table initialization races. Updated via CAS. + */ + transient volatile long base; + + /** + * Spinlock (locked via CAS) used when resizing and/or creating Cells. + */ + transient volatile int busy; + + /** + * Package-private default constructor + */ + Striped64() { + } + + /** + * CASes the base field. + */ + final boolean casBase(long cmp, long val) { + return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val); + } + + /** + * CASes the busy field from 0 to 1 to acquire lock. + */ + final boolean casBusy() { + return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1); + } + + /** + * Computes the function of current and new value. Subclasses + * should open-code this update function for most uses, but the + * virtualized form is needed within retryUpdate. + * + * @param currentValue the current value (of either base or a cell) + * @param newValue the argument from a user update call + * @return result of the update function + */ + abstract long fn(long currentValue, long newValue); + + /** + * Handles cases of updates involving initialization, resizing, + * creating new Cells, and/or contention. See above for + * explanation. This method suffers the usual non-modularity + * problems of optimistic retry code, relying on rechecked sets of + * reads. + * + * @param x the value + * @param hc the hash code holder + * @param wasUncontended false if CAS failed before call + */ + final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { + int h = hc.code; + boolean collide = false; // True if last slot nonempty + for (;;) { + Cell[] as; Cell a; int n; long v; + if ((as = cells) != null && (n = as.length) > 0) { + if ((a = as[(n - 1) & h]) == null) { + if (busy == 0) { // Try to attach new Cell + Cell r = new Cell(x); // Optimistically create + if (busy == 0 && casBusy()) { + boolean created = false; + try { // Recheck under lock + Cell[] rs; int m, j; + if ((rs = cells) != null && + (m = rs.length) > 0 && + rs[j = (m - 1) & h] == null) { + rs[j] = r; + created = true; + } + } finally { + busy = 0; + } + if (created) + break; + continue; // Slot is now non-empty + } + } + collide = false; + } + else if (!wasUncontended) // CAS already known to fail + wasUncontended = true; // Continue after rehash + else if (a.cas(v = a.value, fn(v, x))) + break; + else if (n >= NCPU || cells != as) + collide = false; // At max size or stale + else if (!collide) + collide = true; + else if (busy == 0 && casBusy()) { + try { + if (cells == as) { // Expand table unless stale + Cell[] rs = new Cell[n << 1]; + for (int i = 0; i < n; ++i) + rs[i] = as[i]; + cells = rs; + } + } finally { + busy = 0; + } + collide = false; + continue; // Retry with expanded table + } + h ^= h << 13; // Rehash + h ^= h >>> 17; + h ^= h << 5; + } + else if (busy == 0 && cells == as && casBusy()) { + boolean init = false; + try { // Initialize table + if (cells == as) { + Cell[] rs = new Cell[2]; + rs[h & 1] = new Cell(x); + cells = rs; + init = true; + } + } finally { + busy = 0; + } + if (init) + break; + } + else if (casBase(v = base, fn(v, x))) + break; // Fall back on using base + } + hc.code = h; // Record index for next time + } + + + /** + * Sets base and all cells to the given value. + */ + final void internalReset(long initialValue) { + Cell[] as = cells; + base = initialValue; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + a.value = initialValue; + } + } + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long baseOffset; + private static final long busyOffset; + static { + try { + UNSAFE = getUnsafe(); + Class sk = Striped64.class; + baseOffset = UNSAFE.objectFieldOffset + (sk.getDeclaredField("base")); + busyOffset = UNSAFE.objectFieldOffset + (sk.getDeclaredField("busy")); + } catch (Exception e) { + throw new Error(e); + } + } + + /** + * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. + * Replace with a simple call to Unsafe.getUnsafe when integrating + * into a jdk. + * + * @return a sun.misc.Unsafe + */ + private static sun.misc.Unsafe getUnsafe() { + try { + return sun.misc.Unsafe.getUnsafe(); + } catch (SecurityException se) { + try { + return java.security.AccessController.doPrivileged + (new java.security + .PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + java.lang.reflect.Field f = sun.misc + .Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (sun.misc.Unsafe) f.get(null); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); + } + } + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java new file mode 100644 index 0000000..a4e73ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java @@ -0,0 +1,3800 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on the 1.79 version. + +package com.concurrent_ruby.ext.jsr166e.nounsafe; + +import org.jruby.RubyClass; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.exceptions.RaiseException; +import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMap; +import com.concurrent_ruby.ext.jsr166y.ThreadLocalRandom; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.Collection; +import java.util.Hashtable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Enumeration; +import java.util.ConcurrentModificationException; +import java.util.NoSuchElementException; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +import java.io.Serializable; + +/** + * A hash table supporting full concurrency of retrievals and + * high expected concurrency for updates. This class obeys the + * same functional specification as {@link java.util.Hashtable}, and + * includes versions of methods corresponding to each method of + * {@code Hashtable}. However, even though all operations are + * thread-safe, retrieval operations do not entail locking, + * and there is not any support for locking the entire table + * in a way that prevents all access. This class is fully + * interoperable with {@code Hashtable} in programs that rely on its + * thread safety but not on its synchronization details. + * + *

Retrieval operations (including {@code get}) generally do not + * block, so may overlap with update operations (including {@code put} + * and {@code remove}). Retrievals reflect the results of the most + * recently completed update operations holding upon their + * onset. (More formally, an update operation for a given key bears a + * happens-before relation with any (non-null) retrieval for + * that key reporting the updated value.) For aggregate operations + * such as {@code putAll} and {@code clear}, concurrent retrievals may + * reflect insertion or removal of only some entries. Similarly, + * Iterators and Enumerations return elements reflecting the state of + * the hash table at some point at or since the creation of the + * iterator/enumeration. They do not throw {@link + * ConcurrentModificationException}. However, iterators are designed + * to be used by only one thread at a time. Bear in mind that the + * results of aggregate status methods including {@code size}, {@code + * isEmpty}, and {@code containsValue} are typically useful only when + * a map is not undergoing concurrent updates in other threads. + * Otherwise the results of these methods reflect transient states + * that may be adequate for monitoring or estimation purposes, but not + * for program control. + * + *

The table is dynamically expanded when there are too many + * collisions (i.e., keys that have distinct hash codes but fall into + * the same slot modulo the table size), with the expected average + * effect of maintaining roughly two bins per mapping (corresponding + * to a 0.75 load factor threshold for resizing). There may be much + * variance around this average as mappings are added and removed, but + * overall, this maintains a commonly accepted time/space tradeoff for + * hash tables. However, resizing this or any other kind of hash + * table may be a relatively slow operation. When possible, it is a + * good idea to provide a size estimate as an optional {@code + * initialCapacity} constructor argument. An additional optional + * {@code loadFactor} constructor argument provides a further means of + * customizing initial table capacity by specifying the table density + * to be used in calculating the amount of space to allocate for the + * given number of elements. Also, for compatibility with previous + * versions of this class, constructors may optionally specify an + * expected {@code concurrencyLevel} as an additional hint for + * internal sizing. Note that using many keys with exactly the same + * {@code hashCode()} is a sure way to slow down performance of any + * hash table. + * + *

A {@link Set} projection of a ConcurrentHashMapV8 may be created + * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed + * (using {@link #keySet(Object)} when only keys are of interest, and the + * mapped values are (perhaps transiently) not used or all take the + * same mapping value. + * + *

A ConcurrentHashMapV8 can be used as scalable frequency map (a + * form of histogram or multiset) by using {@link LongAdder} values + * and initializing via {@link #computeIfAbsent}. For example, to add + * a count to a {@code ConcurrentHashMapV8 freqs}, you + * can use {@code freqs.computeIfAbsent(k -> new + * LongAdder()).increment();} + * + *

This class and its views and iterators implement all of the + * optional methods of the {@link Map} and {@link Iterator} + * interfaces. + * + *

Like {@link Hashtable} but unlike {@link HashMap}, this class + * does not allow {@code null} to be used as a key or value. + * + *

ConcurrentHashMapV8s support parallel operations using the {@link + * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts + * are available in class {@link ForkJoinTasks}). These operations are + * designed to be safely, and often sensibly, applied even with maps + * that are being concurrently updated by other threads; for example, + * when computing a snapshot summary of the values in a shared + * registry. There are three kinds of operation, each with four + * forms, accepting functions with Keys, Values, Entries, and (Key, + * Value) arguments and/or return values. (The first three forms are + * also available via the {@link #keySet()}, {@link #values()} and + * {@link #entrySet()} views). Because the elements of a + * ConcurrentHashMapV8 are not ordered in any particular way, and may be + * processed in different orders in different parallel executions, the + * correctness of supplied functions should not depend on any + * ordering, or on any other objects or values that may transiently + * change while computation is in progress; and except for forEach + * actions, should ideally be side-effect-free. + * + *

+ * + *

The concurrency properties of bulk operations follow + * from those of ConcurrentHashMapV8: Any non-null result returned + * from {@code get(key)} and related access methods bears a + * happens-before relation with the associated insertion or + * update. The result of any bulk operation reflects the + * composition of these per-element relations (but is not + * necessarily atomic with respect to the map as a whole unless it + * is somehow known to be quiescent). Conversely, because keys + * and values in the map are never null, null serves as a reliable + * atomic indicator of the current lack of any result. To + * maintain this property, null serves as an implicit basis for + * all non-scalar reduction operations. For the double, long, and + * int versions, the basis should be one that, when combined with + * any other value, returns that other value (more formally, it + * should be the identity element for the reduction). Most common + * reductions have these properties; for example, computing a sum + * with basis 0 or a minimum with basis MAX_VALUE. + * + *

Search and transformation functions provided as arguments + * should similarly return null to indicate the lack of any result + * (in which case it is not used). In the case of mapped + * reductions, this also enables transformations to serve as + * filters, returning null (or, in the case of primitive + * specializations, the identity basis) if the element should not + * be combined. You can create compound transformations and + * filterings by composing them yourself under this "null means + * there is nothing there now" rule before using them in search or + * reduce operations. + * + *

Methods accepting and/or returning Entry arguments maintain + * key-value associations. They may be useful for example when + * finding the key for the greatest value. Note that "plain" Entry + * arguments can be supplied using {@code new + * AbstractMap.SimpleEntry(k,v)}. + * + *

Bulk operations may complete abruptly, throwing an + * exception encountered in the application of a supplied + * function. Bear in mind when handling such exceptions that other + * concurrently executing functions could also have thrown + * exceptions, or would have done so if the first exception had + * not occurred. + * + *

Parallel speedups for bulk operations compared to sequential + * processing are common but not guaranteed. Operations involving + * brief functions on small maps may execute more slowly than + * sequential loops if the underlying work to parallelize the + * computation is more expensive than the computation itself. + * Similarly, parallelization may not lead to much actual parallelism + * if all processors are busy performing unrelated tasks. + * + *

All arguments to all task methods must be non-null. + * + *

jsr166e note: During transition, this class + * uses nested functional interfaces with different names but the + * same forms as those expected for JDK8. + * + *

This class is a member of the + * + * Java Collections Framework. + * + * @since 1.5 + * @author Doug Lea + * @param the type of keys maintained by this map + * @param the type of mapped values + */ +public class ConcurrentHashMapV8 + implements ConcurrentMap, Serializable, ConcurrentHashMap { + private static final long serialVersionUID = 7249069246763182397L; + + /** + * A partitionable iterator. A Spliterator can be traversed + * directly, but can also be partitioned (before traversal) by + * creating another Spliterator that covers a non-overlapping + * portion of the elements, and so may be amenable to parallel + * execution. + * + *

This interface exports a subset of expected JDK8 + * functionality. + * + *

Sample usage: Here is one (of the several) ways to compute + * the sum of the values held in a map using the ForkJoin + * framework. As illustrated here, Spliterators are well suited to + * designs in which a task repeatedly splits off half its work + * into forked subtasks until small enough to process directly, + * and then joins these subtasks. Variants of this style can also + * be used in completion-based designs. + * + *

+     * {@code ConcurrentHashMapV8 m = ...
+     * // split as if have 8 * parallelism, for load balance
+     * int n = m.size();
+     * int p = aForkJoinPool.getParallelism() * 8;
+     * int split = (n < p)? n : p;
+     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
+     * // ...
+     * static class SumValues extends RecursiveTask {
+     *   final Spliterator s;
+     *   final int split;             // split while > 1
+     *   final SumValues nextJoin;    // records forked subtasks to join
+     *   SumValues(Spliterator s, int depth, SumValues nextJoin) {
+     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
+     *   }
+     *   public Long compute() {
+     *     long sum = 0;
+     *     SumValues subtasks = null; // fork subtasks
+     *     for (int s = split >>> 1; s > 0; s >>>= 1)
+     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
+     *     while (s.hasNext())        // directly process remaining elements
+     *       sum += s.next();
+     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
+     *       sum += t.join();         // collect subtask results
+     *     return sum;
+     *   }
+     * }
+     * }
+ */ + public static interface Spliterator extends Iterator { + /** + * Returns a Spliterator covering approximately half of the + * elements, guaranteed not to overlap with those subsequently + * returned by this Spliterator. After invoking this method, + * the current Spliterator will not produce any of + * the elements of the returned Spliterator, but the two + * Spliterators together will produce all of the elements that + * would have been produced by this Spliterator had this + * method not been called. The exact number of elements + * produced by the returned Spliterator is not guaranteed, and + * may be zero (i.e., with {@code hasNext()} reporting {@code + * false}) if this Spliterator cannot be further split. + * + * @return a Spliterator covering approximately half of the + * elements + * @throws IllegalStateException if this Spliterator has + * already commenced traversing elements + */ + Spliterator split(); + } + + + /* + * Overview: + * + * The primary design goal of this hash table is to maintain + * concurrent readability (typically method get(), but also + * iterators and related methods) while minimizing update + * contention. Secondary goals are to keep space consumption about + * the same or better than java.util.HashMap, and to support high + * initial insertion rates on an empty table by many threads. + * + * Each key-value mapping is held in a Node. Because Node fields + * can contain special values, they are defined using plain Object + * types. Similarly in turn, all internal methods that use them + * work off Object types. And similarly, so do the internal + * methods of auxiliary iterator and view classes. All public + * generic typed methods relay in/out of these internal methods, + * supplying null-checks and casts as needed. This also allows + * many of the public methods to be factored into a smaller number + * of internal methods (although sadly not so for the five + * variants of put-related operations). The validation-based + * approach explained below leads to a lot of code sprawl because + * retry-control precludes factoring into smaller methods. + * + * The table is lazily initialized to a power-of-two size upon the + * first insertion. Each bin in the table normally contains a + * list of Nodes (most often, the list has only zero or one Node). + * Table accesses require volatile/atomic reads, writes, and + * CASes. Because there is no other way to arrange this without + * adding further indirections, we use intrinsics + * (sun.misc.Unsafe) operations. The lists of nodes within bins + * are always accurately traversable under volatile reads, so long + * as lookups check hash code and non-nullness of value before + * checking key equality. + * + * We use the top two bits of Node hash fields for control + * purposes -- they are available anyway because of addressing + * constraints. As explained further below, these top bits are + * used as follows: + * 00 - Normal + * 01 - Locked + * 11 - Locked and may have a thread waiting for lock + * 10 - Node is a forwarding node + * + * The lower 30 bits of each Node's hash field contain a + * transformation of the key's hash code, except for forwarding + * nodes, for which the lower bits are zero (and so always have + * hash field == MOVED). + * + * Insertion (via put or its variants) of the first node in an + * empty bin is performed by just CASing it to the bin. This is + * by far the most common case for put operations under most + * key/hash distributions. Other update operations (insert, + * delete, and replace) require locks. We do not want to waste + * the space required to associate a distinct lock object with + * each bin, so instead use the first node of a bin list itself as + * a lock. Blocking support for these locks relies on the builtin + * "synchronized" monitors. However, we also need a tryLock + * construction, so we overlay these by using bits of the Node + * hash field for lock control (see above), and so normally use + * builtin monitors only for blocking and signalling using + * wait/notifyAll constructions. See Node.tryAwaitLock. + * + * Using the first node of a list as a lock does not by itself + * suffice though: When a node is locked, any update must first + * validate that it is still the first node after locking it, and + * retry if not. Because new nodes are always appended to lists, + * once a node is first in a bin, it remains first until deleted + * or the bin becomes invalidated (upon resizing). However, + * operations that only conditionally update may inspect nodes + * until the point of update. This is a converse of sorts to the + * lazy locking technique described by Herlihy & Shavit. + * + * The main disadvantage of per-bin locks is that other update + * operations on other nodes in a bin list protected by the same + * lock can stall, for example when user equals() or mapping + * functions take a long time. However, statistically, under + * random hash codes, this is not a common problem. Ideally, the + * frequency of nodes in bins follows a Poisson distribution + * (http://en.wikipedia.org/wiki/Poisson_distribution) with a + * parameter of about 0.5 on average, given the resizing threshold + * of 0.75, although with a large variance because of resizing + * granularity. Ignoring variance, the expected occurrences of + * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The + * first values are: + * + * 0: 0.60653066 + * 1: 0.30326533 + * 2: 0.07581633 + * 3: 0.01263606 + * 4: 0.00157952 + * 5: 0.00015795 + * 6: 0.00001316 + * 7: 0.00000094 + * 8: 0.00000006 + * more: less than 1 in ten million + * + * Lock contention probability for two threads accessing distinct + * elements is roughly 1 / (8 * #elements) under random hashes. + * + * Actual hash code distributions encountered in practice + * sometimes deviate significantly from uniform randomness. This + * includes the case when N > (1<<30), so some keys MUST collide. + * Similarly for dumb or hostile usages in which multiple keys are + * designed to have identical hash codes. Also, although we guard + * against the worst effects of this (see method spread), sets of + * hashes may differ only in bits that do not impact their bin + * index for a given power-of-two mask. So we use a secondary + * strategy that applies when the number of nodes in a bin exceeds + * a threshold, and at least one of the keys implements + * Comparable. These TreeBins use a balanced tree to hold nodes + * (a specialized form of red-black trees), bounding search time + * to O(log N). Each search step in a TreeBin is around twice as + * slow as in a regular list, but given that N cannot exceed + * (1<<64) (before running out of addresses) this bounds search + * steps, lock hold times, etc, to reasonable constants (roughly + * 100 nodes inspected per operation worst case) so long as keys + * are Comparable (which is very common -- String, Long, etc). + * TreeBin nodes (TreeNodes) also maintain the same "next" + * traversal pointers as regular nodes, so can be traversed in + * iterators in the same way. + * + * The table is resized when occupancy exceeds a percentage + * threshold (nominally, 0.75, but see below). Only a single + * thread performs the resize (using field "sizeCtl", to arrange + * exclusion), but the table otherwise remains usable for reads + * and updates. Resizing proceeds by transferring bins, one by + * one, from the table to the next table. Because we are using + * power-of-two expansion, the elements from each bin must either + * stay at same index, or move with a power of two offset. We + * eliminate unnecessary node creation by catching cases where old + * nodes can be reused because their next fields won't change. On + * average, only about one-sixth of them need cloning when a table + * doubles. The nodes they replace will be garbage collectable as + * soon as they are no longer referenced by any reader thread that + * may be in the midst of concurrently traversing table. Upon + * transfer, the old table bin contains only a special forwarding + * node (with hash field "MOVED") that contains the next table as + * its key. On encountering a forwarding node, access and update + * operations restart, using the new table. + * + * Each bin transfer requires its bin lock. However, unlike other + * cases, a transfer can skip a bin if it fails to acquire its + * lock, and revisit it later (unless it is a TreeBin). Method + * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that + * have been skipped because of failure to acquire a lock, and + * blocks only if none are available (i.e., only very rarely). + * The transfer operation must also ensure that all accessible + * bins in both the old and new table are usable by any traversal. + * When there are no lock acquisition failures, this is arranged + * simply by proceeding from the last bin (table.length - 1) up + * towards the first. Upon seeing a forwarding node, traversals + * (see class Iter) arrange to move to the new table + * without revisiting nodes. However, when any node is skipped + * during a transfer, all earlier table bins may have become + * visible, so are initialized with a reverse-forwarding node back + * to the old table until the new ones are established. (This + * sometimes requires transiently locking a forwarding node, which + * is possible under the above encoding.) These more expensive + * mechanics trigger only when necessary. + * + * The traversal scheme also applies to partial traversals of + * ranges of bins (via an alternate Traverser constructor) + * to support partitioned aggregate operations. Also, read-only + * operations give up if ever forwarded to a null table, which + * provides support for shutdown-style clearing, which is also not + * currently implemented. + * + * Lazy table initialization minimizes footprint until first use, + * and also avoids resizings when the first operation is from a + * putAll, constructor with map argument, or deserialization. + * These cases attempt to override the initial capacity settings, + * but harmlessly fail to take effect in cases of races. + * + * The element count is maintained using a LongAdder, which avoids + * contention on updates but can encounter cache thrashing if read + * too frequently during concurrent access. To avoid reading so + * often, resizing is attempted either when a bin lock is + * contended, or upon adding to a bin already holding two or more + * nodes (checked before adding in the xIfAbsent methods, after + * adding in others). Under uniform hash distributions, the + * probability of this occurring at threshold is around 13%, + * meaning that only about 1 in 8 puts check threshold (and after + * resizing, many fewer do so). But this approximation has high + * variance for small table sizes, so we check on any collision + * for sizes <= 64. The bulk putAll operation further reduces + * contention by only committing count updates upon these size + * checks. + * + * Maintaining API and serialization compatibility with previous + * versions of this class introduces several oddities. Mainly: We + * leave untouched but unused constructor arguments referring to + * concurrencyLevel. We accept a loadFactor constructor argument, + * but apply it only to initial table capacity (which is the only + * time that we can guarantee to honor it.) We also declare an + * unused "Segment" class that is instantiated in minimal form + * only when serializing. + */ + + /* ---------------- Constants -------------- */ + + /** + * The largest possible table capacity. This value must be + * exactly 1<<30 to stay within Java array allocation and indexing + * bounds for power of two table sizes, and is further required + * because the top two bits of 32bit hash fields are used for + * control purposes. + */ + private static final int MAXIMUM_CAPACITY = 1 << 30; + + /** + * The default initial table capacity. Must be a power of 2 + * (i.e., at least 1) and at most MAXIMUM_CAPACITY. + */ + private static final int DEFAULT_CAPACITY = 16; + + /** + * The largest possible (non-power of two) array size. + * Needed by toArray and related methods. + */ + static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + /** + * The default concurrency level for this table. Unused but + * defined for compatibility with previous versions of this class. + */ + private static final int DEFAULT_CONCURRENCY_LEVEL = 16; + + /** + * The load factor for this table. Overrides of this value in + * constructors affect only the initial table capacity. The + * actual floating point value isn't normally used -- it is + * simpler to use expressions such as {@code n - (n >>> 2)} for + * the associated resizing threshold. + */ + private static final float LOAD_FACTOR = 0.75f; + + /** + * The buffer size for skipped bins during transfers. The + * value is arbitrary but should be large enough to avoid + * most locking stalls during resizes. + */ + private static final int TRANSFER_BUFFER_SIZE = 32; + + /** + * The bin count threshold for using a tree rather than list for a + * bin. The value reflects the approximate break-even point for + * using tree-based operations. + * Note that Doug's version defaults to 8, but when dealing with + * Ruby objects it is actually beneficial to avoid TreeNodes + * as long as possible as it usually means going into Ruby land. + */ + private static final int TREE_THRESHOLD = 16; + + /* + * Encodings for special uses of Node hash fields. See above for + * explanation. + */ + static final int MOVED = 0x80000000; // hash field for forwarding nodes + static final int LOCKED = 0x40000000; // set/tested only as a bit + static final int WAITING = 0xc0000000; // both bits set/tested together + static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash + + /* ---------------- Fields -------------- */ + + /** + * The array of bins. Lazily initialized upon first insertion. + * Size is always a power of two. Accessed directly by iterators. + */ + transient volatile AtomicReferenceArray table; + + /** + * The counter maintaining number of elements. + */ + private transient LongAdder counter; + + /** + * Table initialization and resizing control. When negative, the + * table is being initialized or resized. Otherwise, when table is + * null, holds the initial table size to use upon creation, or 0 + * for default. After initialization, holds the next element count + * value upon which to resize the table. + */ + private transient volatile int sizeCtl; + + // views + private transient KeySetView keySet; + private transient ValuesView values; + private transient EntrySetView entrySet; + + /** For serialization compatibility. Null unless serialized; see below */ + private Segment[] segments; + + static AtomicIntegerFieldUpdater SIZE_CTRL_UPDATER = AtomicIntegerFieldUpdater.newUpdater(ConcurrentHashMapV8.class, "sizeCtl"); + + /* ---------------- Table element access -------------- */ + + /* + * Volatile access methods are used for table elements as well as + * elements of in-progress next table while resizing. Uses are + * null checked by callers, and implicitly bounds-checked, relying + * on the invariants that tab arrays have non-zero size, and all + * indices are masked with (tab.length - 1) which is never + * negative and always less than length. Note that, to be correct + * wrt arbitrary concurrency errors by users, bounds checks must + * operate on local variables, which accounts for some odd-looking + * inline assignments below. + */ + + static final Node tabAt(AtomicReferenceArray tab, int i) { // used by Iter + return tab.get(i); + } + + private static final boolean casTabAt(AtomicReferenceArray tab, int i, Node c, Node v) { + return tab.compareAndSet(i, c, v); + } + + private static final void setTabAt(AtomicReferenceArray tab, int i, Node v) { + tab.set(i, v); + } + + /* ---------------- Nodes -------------- */ + + /** + * Key-value entry. Note that this is never exported out as a + * user-visible Map.Entry (see MapEntry below). Nodes with a hash + * field of MOVED are special, and do not contain user keys or + * values. Otherwise, keys are never null, and null val fields + * indicate that a node is in the process of being deleted or + * created. For purposes of read-only access, a key may be read + * before a val, but can only be used after checking val to be + * non-null. + */ + static class Node { + volatile int hash; + final Object key; + volatile Object val; + volatile Node next; + + static AtomicIntegerFieldUpdater HASH_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Node.class, "hash"); + + Node(int hash, Object key, Object val, Node next) { + this.hash = hash; + this.key = key; + this.val = val; + this.next = next; + } + + /** CompareAndSet the hash field */ + final boolean casHash(int cmp, int val) { + return HASH_UPDATER.compareAndSet(this, cmp, val); + } + + /** The number of spins before blocking for a lock */ + static final int MAX_SPINS = + Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1; + + /** + * Spins a while if LOCKED bit set and this node is the first + * of its bin, and then sets WAITING bits on hash field and + * blocks (once) if they are still set. It is OK for this + * method to return even if lock is not available upon exit, + * which enables these simple single-wait mechanics. + * + * The corresponding signalling operation is performed within + * callers: Upon detecting that WAITING has been set when + * unlocking lock (via a failed CAS from non-waiting LOCKED + * state), unlockers acquire the sync lock and perform a + * notifyAll. + * + * The initial sanity check on tab and bounds is not currently + * necessary in the only usages of this method, but enables + * use in other future contexts. + */ + final void tryAwaitLock(AtomicReferenceArray tab, int i) { + if (tab != null && i >= 0 && i < tab.length()) { // sanity check + int r = ThreadLocalRandom.current().nextInt(); // randomize spins + int spins = MAX_SPINS, h; + while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) { + if (spins >= 0) { + r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift + if (r >= 0 && --spins == 0) + Thread.yield(); // yield before block + } + else if (casHash(h, h | WAITING)) { + synchronized (this) { + if (tabAt(tab, i) == this && + (hash & WAITING) == WAITING) { + try { + wait(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } + else + notifyAll(); // possibly won race vs signaller + } + break; + } + } + } + } + } + + /* ---------------- TreeBins -------------- */ + + /** + * Nodes for use in TreeBins + */ + static final class TreeNode extends Node { + TreeNode parent; // red-black tree links + TreeNode left; + TreeNode right; + TreeNode prev; // needed to unlink next upon deletion + boolean red; + + TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) { + super(hash, key, val, next); + this.parent = parent; + } + } + + /** + * A specialized form of red-black tree for use in bins + * whose size exceeds a threshold. + * + * TreeBins use a special form of comparison for search and + * related operations (which is the main reason we cannot use + * existing collections such as TreeMaps). TreeBins contain + * Comparable elements, but may contain others, as well as + * elements that are Comparable but not necessarily Comparable + * for the same T, so we cannot invoke compareTo among them. To + * handle this, the tree is ordered primarily by hash value, then + * by getClass().getName() order, and then by Comparator order + * among elements of the same class. On lookup at a node, if + * elements are not comparable or compare as 0, both left and + * right children may need to be searched in the case of tied hash + * values. (This corresponds to the full list search that would be + * necessary if all elements were non-Comparable and had tied + * hashes.) The red-black balancing code is updated from + * pre-jdk-collections + * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) + * based in turn on Cormen, Leiserson, and Rivest "Introduction to + * Algorithms" (CLR). + * + * TreeBins also maintain a separate locking discipline than + * regular bins. Because they are forwarded via special MOVED + * nodes at bin heads (which can never change once established), + * we cannot use those nodes as locks. Instead, TreeBin + * extends AbstractQueuedSynchronizer to support a simple form of + * read-write lock. For update operations and table validation, + * the exclusive form of lock behaves in the same way as bin-head + * locks. However, lookups use shared read-lock mechanics to allow + * multiple readers in the absence of writers. Additionally, + * these lookups do not ever block: While the lock is not + * available, they proceed along the slow traversal path (via + * next-pointers) until the lock becomes available or the list is + * exhausted, whichever comes first. (These cases are not fast, + * but maximize aggregate expected throughput.) The AQS mechanics + * for doing this are straightforward. The lock state is held as + * AQS getState(). Read counts are negative; the write count (1) + * is positive. There are no signalling preferences among readers + * and writers. Since we don't need to export full Lock API, we + * just override the minimal AQS methods and use them directly. + */ + static final class TreeBin extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = 2249069246763182397L; + transient TreeNode root; // root of tree + transient TreeNode first; // head of next-pointer list + + /* AQS overrides */ + public final boolean isHeldExclusively() { return getState() > 0; } + public final boolean tryAcquire(int ignore) { + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + public final boolean tryRelease(int ignore) { + setExclusiveOwnerThread(null); + setState(0); + return true; + } + public final int tryAcquireShared(int ignore) { + for (int c;;) { + if ((c = getState()) > 0) + return -1; + if (compareAndSetState(c, c -1)) + return 1; + } + } + public final boolean tryReleaseShared(int ignore) { + int c; + do {} while (!compareAndSetState(c = getState(), c + 1)); + return c == -1; + } + + /** From CLR */ + private void rotateLeft(TreeNode p) { + if (p != null) { + TreeNode r = p.right, pp, rl; + if ((rl = p.right = r.left) != null) + rl.parent = p; + if ((pp = r.parent = p.parent) == null) + root = r; + else if (pp.left == p) + pp.left = r; + else + pp.right = r; + r.left = p; + p.parent = r; + } + } + + /** From CLR */ + private void rotateRight(TreeNode p) { + if (p != null) { + TreeNode l = p.left, pp, lr; + if ((lr = p.left = l.right) != null) + lr.parent = p; + if ((pp = l.parent = p.parent) == null) + root = l; + else if (pp.right == p) + pp.right = l; + else + pp.left = l; + l.right = p; + p.parent = l; + } + } + + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, Object k, TreeNode p) { + return getTreeNode(h, (RubyObject)k, p); + } + + /** + * Returns the TreeNode (or null if not found) for the given key + * starting at given root. + */ + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, RubyObject k, TreeNode p) { + RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>"); + while (p != null) { + int dir, ph; RubyObject pk; RubyClass pc; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = (RubyClass)pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pl, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + // try to continue iterating on the left side + else if ((pl = p.left) != null && h <= pl.hash) + dir = -1; + else // no matching node found + return null; + } + } + } + else + dir = (h < ph) ? -1 : 1; + p = (dir > 0) ? p.right : p.left; + } + return null; + } + + int rubyCompare(RubyObject l, RubyObject r) { + ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext(); + IRubyObject result; + try { + result = l.callMethod(context, "<=>", r); + } catch (RaiseException e) { + // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys + if (context.runtime.getNoMethodError().isInstance(e.getException())) { + return 0; + } + throw e; + } + + return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger()); + } + + /** + * Wrapper for getTreeNode used by CHM.get. Tries to obtain + * read-lock to call getTreeNode, but during failure to get + * lock, searches along next links. + */ + final Object getValue(int h, Object k) { + Node r = null; + int c = getState(); // Must read lock state first + for (Node e = first; e != null; e = e.next) { + if (c <= 0 && compareAndSetState(c, c - 1)) { + try { + r = getTreeNode(h, k, root); + } finally { + releaseShared(0); + } + break; + } + else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) { + r = e; + break; + } + else + c = getState(); + } + return r == null ? null : r.val; + } + + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, Object k, Object v) { + return putTreeNode(h, (RubyObject)k, v); + } + + /** + * Finds or adds a node. + * @return null if added + */ + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, RubyObject k, Object v) { + RubyClass c = k.getMetaClass(); + boolean kNotComparable = !k.respondsTo("<=>"); + TreeNode pp = root, p = null; + int dir = 0; + while (pp != null) { // find existing node or leaf to insert at + int ph; RubyObject pk; RubyClass pc; + p = pp; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + else // continue descending down the left subtree + dir = -1; + } + } + } + else + dir = (h < ph) ? -1 : 1; + pp = (dir > 0) ? p.right : p.left; + } + + TreeNode f = first; + TreeNode x = first = new TreeNode(h, (Object)k, v, f, p); + if (p == null) + root = x; + else { // attach and rebalance; adapted from CLR + TreeNode xp, xpp; + if (f != null) + f.prev = x; + if (dir <= 0) + p.left = x; + else + p.right = x; + x.red = true; + while (x != null && (xp = x.parent) != null && xp.red && + (xpp = xp.parent) != null) { + TreeNode xppl = xpp.left; + if (xp == xppl) { + TreeNode y = xpp.right; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.right) { + rotateLeft(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateRight(xpp); + } + } + } + } + else { + TreeNode y = xppl; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.left) { + rotateRight(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateLeft(xpp); + } + } + } + } + } + TreeNode r = root; + if (r != null && r.red) + r.red = false; + } + return null; + } + + /** + * Removes the given node, that must be present before this + * call. This is messier than typical red-black deletion code + * because we cannot swap the contents of an interior node + * with a leaf successor that is pinned by "next" pointers + * that are accessible independently of lock. So instead we + * swap the tree linkages. + */ + final void deleteTreeNode(TreeNode p) { + TreeNode next = (TreeNode)p.next; // unlink traversal pointers + TreeNode pred = p.prev; + if (pred == null) + first = next; + else + pred.next = next; + if (next != null) + next.prev = pred; + TreeNode replacement; + TreeNode pl = p.left; + TreeNode pr = p.right; + if (pl != null && pr != null) { + TreeNode s = pr, sl; + while ((sl = s.left) != null) // find successor + s = sl; + boolean c = s.red; s.red = p.red; p.red = c; // swap colors + TreeNode sr = s.right; + TreeNode pp = p.parent; + if (s == pr) { // p was s's direct parent + p.parent = s; + s.right = p; + } + else { + TreeNode sp = s.parent; + if ((p.parent = sp) != null) { + if (s == sp.left) + sp.left = p; + else + sp.right = p; + } + if ((s.right = pr) != null) + pr.parent = s; + } + p.left = null; + if ((p.right = sr) != null) + sr.parent = p; + if ((s.left = pl) != null) + pl.parent = s; + if ((s.parent = pp) == null) + root = s; + else if (p == pp.left) + pp.left = s; + else + pp.right = s; + replacement = sr; + } + else + replacement = (pl != null) ? pl : pr; + TreeNode pp = p.parent; + if (replacement == null) { + if (pp == null) { + root = null; + return; + } + replacement = p; + } + else { + replacement.parent = pp; + if (pp == null) + root = replacement; + else if (p == pp.left) + pp.left = replacement; + else + pp.right = replacement; + p.left = p.right = p.parent = null; + } + if (!p.red) { // rebalance, from CLR + TreeNode x = replacement; + while (x != null) { + TreeNode xp, xpl; + if (x.red || (xp = x.parent) == null) { + x.red = false; + break; + } + if (x == (xpl = xp.left)) { + TreeNode sib = xp.right; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateLeft(xp); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sr == null || !sr.red) && + (sl == null || !sl.red)) { + sib.red = true; + x = xp; + } + else { + if (sr == null || !sr.red) { + if (sl != null) + sl.red = false; + sib.red = true; + rotateRight(sib); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sr = sib.right) != null) + sr.red = false; + } + if (xp != null) { + xp.red = false; + rotateLeft(xp); + } + x = root; + } + } + } + else { // symmetric + TreeNode sib = xpl; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateRight(xp); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sl == null || !sl.red) && + (sr == null || !sr.red)) { + sib.red = true; + x = xp; + } + else { + if (sl == null || !sl.red) { + if (sr != null) + sr.red = false; + sib.red = true; + rotateLeft(sib); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sl = sib.left) != null) + sl.red = false; + } + if (xp != null) { + xp.red = false; + rotateRight(xp); + } + x = root; + } + } + } + } + } + if (p == replacement && (pp = p.parent) != null) { + if (p == pp.left) // detach pointers + pp.left = null; + else if (p == pp.right) + pp.right = null; + p.parent = null; + } + } + } + + /* ---------------- Collision reduction methods -------------- */ + + /** + * Spreads higher bits to lower, and also forces top 2 bits to 0. + * Because the table uses power-of-two masking, sets of hashes + * that vary only in bits above the current mask will always + * collide. (Among known examples are sets of Float keys holding + * consecutive whole numbers in small tables.) To counter this, + * we apply a transform that spreads the impact of higher bits + * downward. There is a tradeoff between speed, utility, and + * quality of bit-spreading. Because many common sets of hashes + * are already reasonably distributed across bits (so don't benefit + * from spreading), and because we use trees to handle large sets + * of collisions in bins, we don't need excessively high quality. + */ + private static final int spread(int h) { + h ^= (h >>> 18) ^ (h >>> 12); + return (h ^ (h >>> 10)) & HASH_BITS; + } + + /** + * Replaces a list bin with a tree bin. Call only when locked. + * Fails to replace if the given key is non-comparable or table + * is, or needs, resizing. + */ + private final void replaceWithTreeBin(AtomicReferenceArray tab, int index, Object key) { + if ((key instanceof Comparable) && + (tab.length() >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) { + TreeBin t = new TreeBin(); + for (Node e = tabAt(tab, index); e != null; e = e.next) + t.putTreeNode(e.hash & HASH_BITS, e.key, e.val); + setTabAt(tab, index, new Node(MOVED, t, null, null)); + } + } + + /* ---------------- Internal access and update methods -------------- */ + + /** Implementation for get and containsKey */ + private final Object internalGet(Object k) { + int h = spread(k.hashCode()); + retry: for (AtomicReferenceArray tab = table; tab != null;) { + Node e, p; Object ek, ev; int eh; // locals to read fields once + for (e = tabAt(tab, (tab.length() - 1) & h); e != null; e = e.next) { + if ((eh = e.hash) == MOVED) { + if ((ek = e.key) instanceof TreeBin) // search TreeBin + return ((TreeBin)ek).getValue(h, k); + else { // restart with new table + tab = (AtomicReferenceArray)ek; + continue retry; + } + } + else if ((eh & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + } + break; + } + return null; + } + + /** + * Implementation for the four public remove/replace methods: + * Replaces node value with v, conditional upon match of cv if + * non-null. If resulting value is null, delete. + */ + private final Object internalReplace(Object k, Object v, Object cv) { + int h = spread(k.hashCode()); + Object oldVal = null; + for (AtomicReferenceArray tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null || + (f = tabAt(tab, i = (tab.length() - 1) & h)) == null) + break; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + boolean deleted = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) { + Object pv = p.val; + if (cv == null || cv == pv || cv.equals(pv)) { + oldVal = pv; + if ((p.val = v) == null) { + deleted = true; + t.deleteTreeNode(p); + } + } + } + } + } finally { + t.release(0); + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & HASH_BITS) != h && f.next == null) // precheck + break; // rules out possible existence + else if ((fh & LOCKED) != 0) { + checkForResize(); // try resizing if can't get lock + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + boolean validated = false; + boolean deleted = false; + try { + if (tabAt(tab, i) == f) { + validated = true; + for (Node e = f, pred = null;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + ((ev = e.val) != null) && + ((ek = e.key) == k || k.equals(ek))) { + if (cv == null || cv == ev || cv.equals(ev)) { + oldVal = ev; + if ((e.val = v) == null) { + deleted = true; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + } + break; + } + pred = e; + if ((e = e.next) == null) + break; + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + } + return oldVal; + } + + /* + * Internal versions of the six insertion methods, each a + * little more complicated than the last. All have + * the same basic structure as the first (internalPut): + * 1. If table uninitialized, create + * 2. If bin empty, try to CAS new node + * 3. If bin stale, use new table + * 4. if bin converted to TreeBin, validate and relay to TreeBin methods + * 5. Lock and validate; if valid, scan and add or update + * + * The others interweave other checks and/or alternative actions: + * * Plain put checks for and performs resize after insertion. + * * putIfAbsent prescans for mapping without lock (and fails to add + * if present), which also makes pre-emptive resize checks worthwhile. + * * computeIfAbsent extends form used in putIfAbsent with additional + * mechanics to deal with, calls, potential exceptions and null + * returns from function call. + * * compute uses the same function-call mechanics, but without + * the prescans + * * merge acts as putIfAbsent in the absent case, but invokes the + * update function if present + * * putAll attempts to pre-allocate enough table space + * and more lazily performs count updates and checks. + * + * Someday when details settle down a bit more, it might be worth + * some factoring to reduce sprawl. + */ + + /** Implementation for put */ + private final Object internalPut(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; // no lock when adding to empty bin + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) { + oldVal = p.val; + p.val = v; + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { // needed in case equals() throws + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { // unlock and signal if needed + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length() <= 64) + count = 2; + break; + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for putIfAbsent */ + private final Object internalPutIfAbsent(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) + oldVal = p.val; + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { // at least 2 nodes -- search and maybe resize + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length() <= 64) + count = 2; + break; + } + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for computeIfAbsent */ + private final Object internalComputeIfAbsent(K k, + Fun mf) { + int h = spread(k.hashCode()); + Object val = null; + int count = 0; + for (AtomicReferenceArray tab = table;;) { + Node f; int i, fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + count = 1; + try { + if ((val = mf.apply(k)) != null) + node.val = val; + } finally { + if (val == null) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean added = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + val = p.val; + else if ((val = mf.apply(k)) != null) { + added = true; + count = 2; + t.putTreeNode(h, k, val); + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (!added) + return val; + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + boolean added = false; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + if ((val = mf.apply(k)) != null) { + added = true; + last.next = new Node(h, k, val, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (!added) + return val; + if (tab.length() <= 64) + count = 2; + break; + } + } + } + } + if (val != null) { + counter.add(1L); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for compute */ + @SuppressWarnings("unchecked") private final Object internalCompute + (K k, boolean onlyIfPresent, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (AtomicReferenceArray tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (onlyIfPresent) + break; + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + try { + count = 1; + if ((val = mf.apply(k, null)) != null) { + node.val = val; + delta = 1; + } + } finally { + if (delta == 0) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + Object pv; + if (p == null) { + if (onlyIfPresent) + break; + pv = null; + } else + pv = p.val; + if ((val = mf.apply(k, (V)pv)) != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply(k, (V)ev); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + if (!onlyIfPresent && (val = mf.apply(k, null)) != null) { + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length() <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for merge */ + @SuppressWarnings("unchecked") private final Object internalMerge + (K k, V v, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + delta = 1; + val = v; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + val = (p == null) ? v : mf.apply((V)p.val, v); + if (val != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply((V)ev, v); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + val = v; + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length() <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for putAll */ + private final void internalPutAll(Map m) { + tryPresize(m.size()); + long delta = 0L; // number of uncommitted additions + boolean npe = false; // to throw exception on exit for nulls + try { // to clean up counts on other exceptions + for (Map.Entry entry : m.entrySet()) { + Object k, v; + if (entry == null || (k = entry.getKey()) == null || + (v = entry.getValue()) == null) { + npe = true; + break; + } + int h = spread(k.hashCode()); + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null){ + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + ++delta; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + p.val = v; + else { + t.putTreeNode(h, k, v); + ++delta; + } + } + } finally { + t.release(0); + } + if (validated) + break; + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); + delta = 0L; + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + int count = 0; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + ++delta; + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (count > 1) { + counter.add(delta); + delta = 0L; + checkForResize(); + } + break; + } + } + } + } + } finally { + if (delta != 0) + counter.add(delta); + } + if (npe) + throw new NullPointerException(); + } + + /* ---------------- Table Initialization and Resizing -------------- */ + + /** + * Returns a power of two table size for the given desired capacity. + * See Hackers Delight, sec 3.2 + */ + private static final int tableSizeFor(int c) { + int n = c - 1; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; + } + + /** + * Initializes table, using the size recorded in sizeCtl. + */ + private final AtomicReferenceArray initTable() { + AtomicReferenceArray tab; int sc; + while ((tab = table) == null) { + if ((sc = sizeCtl) < 0) + Thread.yield(); // lost initialization race; just spin + else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if ((tab = table) == null) { + int n = (sc > 0) ? sc : DEFAULT_CAPACITY; + tab = table = new AtomicReferenceArray(n); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + break; + } + } + return tab; + } + + /** + * If table is too small and not already resizing, creates next + * table and transfers bins. Rechecks occupancy after a transfer + * to see if another resize is already needed because resizings + * are lagging additions. + */ + private final void checkForResize() { + AtomicReferenceArray tab; int n, sc; + while ((tab = table) != null && + (n = tab.length()) < MAXIMUM_CAPACITY && + (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc && + SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (tab == table) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + + /** + * Tries to presize table to accommodate the given number of elements. + * + * @param size number of elements (doesn't need to be perfectly accurate) + */ + private final void tryPresize(int size) { + int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : + tableSizeFor(size + (size >>> 1) + 1); + int sc; + while ((sc = sizeCtl) >= 0) { + AtomicReferenceArray tab = table; int n; + if (tab == null || (n = tab.length()) == 0) { + n = (sc > c) ? sc : c; + if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (table == tab) { + table = new AtomicReferenceArray(n); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + } + } + else if (c <= sc || n >= MAXIMUM_CAPACITY) + break; + else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (table == tab) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + } + + /* + * Moves and/or copies the nodes in each bin to new table. See + * above for explanation. + * + * @return the new table + */ + private static final AtomicReferenceArray rebuild(AtomicReferenceArray tab) { + int n = tab.length(); + AtomicReferenceArray nextTab = new AtomicReferenceArray(n << 1); + Node fwd = new Node(MOVED, nextTab, null, null); + int[] buffer = null; // holds bins to revisit; null until needed + Node rev = null; // reverse forwarder; null until needed + int nbuffered = 0; // the number of bins in buffer list + int bufferIndex = 0; // buffer index of current buffered bin + int bin = n - 1; // current non-buffered bin or -1 if none + + for (int i = bin;;) { // start upwards sweep + int fh; Node f; + if ((f = tabAt(tab, i)) == null) { + if (bin >= 0) { // Unbuffered; no lock needed (or available) + if (!casTabAt(tab, i, f, fwd)) + continue; + } + else { // transiently use a locked forwarding node + Node g = new Node(MOVED|LOCKED, nextTab, null, null); + if (!casTabAt(tab, i, f, g)) + continue; + setTabAt(nextTab, i, null); + setTabAt(nextTab, i + n, null); + setTabAt(tab, i, fwd); + if (!g.casHash(MOVED|LOCKED, MOVED)) { + g.hash = MOVED; + synchronized (g) { g.notifyAll(); } + } + } + } + else if ((fh = f.hash) == MOVED) { + Object fk = f.key; + if (fk instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + splitTreeBin(nextTab, i, t); + setTabAt(tab, i, fwd); + } + } finally { + t.release(0); + } + if (!validated) + continue; + } + } + else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) { + boolean validated = false; + try { // split to lo and hi lists; copying as needed + if (tabAt(tab, i) == f) { + validated = true; + splitBin(nextTab, i, f); + setTabAt(tab, i, fwd); + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (!validated) + continue; + } + else { + if (buffer == null) // initialize buffer for revisits + buffer = new int[TRANSFER_BUFFER_SIZE]; + if (bin < 0 && bufferIndex > 0) { + int j = buffer[--bufferIndex]; + buffer[bufferIndex] = i; + i = j; // swap with another bin + continue; + } + if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) { + f.tryAwaitLock(tab, i); + continue; // no other options -- block + } + if (rev == null) // initialize reverse-forwarder + rev = new Node(MOVED, tab, null, null); + if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0) + continue; // recheck before adding to list + buffer[nbuffered++] = i; + setTabAt(nextTab, i, rev); // install place-holders + setTabAt(nextTab, i + n, rev); + } + + if (bin > 0) + i = --bin; + else if (buffer != null && nbuffered > 0) { + bin = -1; + i = buffer[bufferIndex = --nbuffered]; + } + else + return nextTab; + } + } + + /** + * Splits a normal bin with list headed by e into lo and hi parts; + * installs in given table. + */ + private static void splitBin(AtomicReferenceArray nextTab, int i, Node e) { + int bit = nextTab.length() >>> 1; // bit to split on + int runBit = e.hash & bit; + Node lastRun = e, lo = null, hi = null; + for (Node p = e.next; p != null; p = p.next) { + int b = p.hash & bit; + if (b != runBit) { + runBit = b; + lastRun = p; + } + } + if (runBit == 0) + lo = lastRun; + else + hi = lastRun; + for (Node p = e; p != lastRun; p = p.next) { + int ph = p.hash & HASH_BITS; + Object pk = p.key, pv = p.val; + if ((ph & bit) == 0) + lo = new Node(ph, pk, pv, lo); + else + hi = new Node(ph, pk, pv, hi); + } + setTabAt(nextTab, i, lo); + setTabAt(nextTab, i + bit, hi); + } + + /** + * Splits a tree bin into lo and hi parts; installs in given table. + */ + private static void splitTreeBin(AtomicReferenceArray nextTab, int i, TreeBin t) { + int bit = nextTab.length() >>> 1; + TreeBin lt = new TreeBin(); + TreeBin ht = new TreeBin(); + int lc = 0, hc = 0; + for (Node e = t.first; e != null; e = e.next) { + int h = e.hash & HASH_BITS; + Object k = e.key, v = e.val; + if ((h & bit) == 0) { + ++lc; + lt.putTreeNode(h, k, v); + } + else { + ++hc; + ht.putTreeNode(h, k, v); + } + } + Node ln, hn; // throw away trees if too small + if (lc <= (TREE_THRESHOLD >>> 1)) { + ln = null; + for (Node p = lt.first; p != null; p = p.next) + ln = new Node(p.hash, p.key, p.val, ln); + } + else + ln = new Node(MOVED, lt, null, null); + setTabAt(nextTab, i, ln); + if (hc <= (TREE_THRESHOLD >>> 1)) { + hn = null; + for (Node p = ht.first; p != null; p = p.next) + hn = new Node(p.hash, p.key, p.val, hn); + } + else + hn = new Node(MOVED, ht, null, null); + setTabAt(nextTab, i + bit, hn); + } + + /** + * Implementation for clear. Steps through each bin, removing all + * nodes. + */ + private final void internalClear() { + long delta = 0L; // negative number of deletions + int i = 0; + AtomicReferenceArray tab = table; + while (tab != null && i < tab.length()) { + int fh; Object fk; + Node f = tabAt(tab, i); + if (f == null) + ++i; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + for (Node p = t.first; p != null; p = p.next) { + if (p.val != null) { // (currently always true) + p.val = null; + --delta; + } + } + t.first = null; + t.root = null; + ++i; + } + } finally { + t.release(0); + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); // opportunistically update count + delta = 0L; + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + for (Node e = f; e != null; e = e.next) { + if (e.val != null) { // (currently always true) + e.val = null; + --delta; + } + } + setTabAt(tab, i, null); + ++i; + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + } + } + if (delta != 0) + counter.add(delta); + } + + /* ----------------Table Traversal -------------- */ + + /** + * Encapsulates traversal for methods such as containsValue; also + * serves as a base class for other iterators and bulk tasks. + * + * At each step, the iterator snapshots the key ("nextKey") and + * value ("nextVal") of a valid node (i.e., one that, at point of + * snapshot, has a non-null user value). Because val fields can + * change (including to null, indicating deletion), field nextVal + * might not be accurate at point of use, but still maintains the + * weak consistency property of holding a value that was once + * valid. To support iterator.remove, the nextKey field is not + * updated (nulled out) when the iterator cannot advance. + * + * Internal traversals directly access these fields, as in: + * {@code while (it.advance() != null) { process(it.nextKey); }} + * + * Exported iterators must track whether the iterator has advanced + * (in hasNext vs next) (by setting/checking/nulling field + * nextVal), and then extract key, value, or key-value pairs as + * return values of next(). + * + * The iterator visits once each still-valid node that was + * reachable upon iterator construction. It might miss some that + * were added to a bin after the bin was visited, which is OK wrt + * consistency guarantees. Maintaining this property in the face + * of possible ongoing resizes requires a fair amount of + * bookkeeping state that is difficult to optimize away amidst + * volatile accesses. Even so, traversal maintains reasonable + * throughput. + * + * Normally, iteration proceeds bin-by-bin traversing lists. + * However, if the table has been resized, then all future steps + * must traverse both the bin at the current index as well as at + * (index + baseSize); and so on for further resizings. To + * paranoically cope with potential sharing by users of iterators + * across threads, iteration terminates if a bounds checks fails + * for a table read. + * + * This class extends ForkJoinTask to streamline parallel + * iteration in bulk operations (see BulkTask). This adds only an + * int of space overhead, which is close enough to negligible in + * cases where it is not needed to not worry about it. Because + * ForkJoinTask is Serializable, but iterators need not be, we + * need to add warning suppressions. + */ + @SuppressWarnings("serial") static class Traverser { + final ConcurrentHashMapV8 map; + Node next; // the next entry to use + K nextKey; // cached key field of next + V nextVal; // cached val field of next + AtomicReferenceArray tab; // current table; updated if resized + int index; // index of bin to use next + int baseIndex; // current index of initial table + int baseLimit; // index bound for initial table + int baseSize; // initial table size + + /** Creates iterator for all entries in the table. */ + Traverser(ConcurrentHashMapV8 map) { + this.map = map; + } + + /** Creates iterator for split() methods */ + Traverser(Traverser it) { + ConcurrentHashMapV8 m; AtomicReferenceArray t; + if ((m = this.map = it.map) == null) + t = null; + else if ((t = it.tab) == null && // force parent tab initialization + (t = it.tab = m.table) != null) + it.baseLimit = it.baseSize = t.length(); + this.tab = t; + this.baseSize = it.baseSize; + it.baseLimit = this.index = this.baseIndex = + ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1; + } + + /** + * Advances next; returns nextVal or null if terminated. + * See above for explanation. + */ + final V advance() { + Node e = next; + V ev = null; + outer: do { + if (e != null) // advance past used/skipped node + e = e.next; + while (e == null) { // get to next non-null bin + ConcurrentHashMapV8 m; + AtomicReferenceArray t; int b, i, n; Object ek; // checks must use locals + if ((t = tab) != null) + n = t.length(); + else if ((m = map) != null && (t = tab = m.table) != null) + n = baseLimit = baseSize = t.length(); + else + break outer; + if ((b = baseIndex) >= baseLimit || + (i = index) < 0 || i >= n) + break outer; + if ((e = tabAt(t, i)) != null && e.hash == MOVED) { + if ((ek = e.key) instanceof TreeBin) + e = ((TreeBin)ek).first; + else { + tab = (AtomicReferenceArray)ek; + continue; // restarts due to null val + } + } // visit upper slots if present + index = (i += baseSize) < n ? i : (baseIndex = b + 1); + } + nextKey = (K) e.key; + } while ((ev = (V) e.val) == null); // skip deleted or special nodes + next = e; + return nextVal = ev; + } + + public final void remove() { + Object k = nextKey; + if (k == null && (advance() == null || (k = nextKey) == null)) + throw new IllegalStateException(); + map.internalReplace(k, null, null); + } + + public final boolean hasNext() { + return nextVal != null || advance() != null; + } + + public final boolean hasMoreElements() { return hasNext(); } + public final void setRawResult(Object x) { } + public R getRawResult() { return null; } + public boolean exec() { return true; } + } + + /* ---------------- Public operations -------------- */ + + /** + * Creates a new, empty map with the default initial table size (16). + */ + public ConcurrentHashMapV8() { + this.counter = new LongAdder(); + } + + /** + * Creates a new, empty map with an initial table size + * accommodating the specified number of elements without the need + * to dynamically resize. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + */ + public ConcurrentHashMapV8(int initialCapacity) { + if (initialCapacity < 0) + throw new IllegalArgumentException(); + int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? + MAXIMUM_CAPACITY : + tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new map with the same mappings as the given map. + * + * @param m the map + */ + public ConcurrentHashMapV8(Map m) { + this.counter = new LongAdder(); + this.sizeCtl = DEFAULT_CAPACITY; + internalPutAll(m); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}) and + * initial table density ({@code loadFactor}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @throws IllegalArgumentException if the initial capacity of + * elements is negative or the load factor is nonpositive + * + * @since 1.6 + */ + public ConcurrentHashMapV8(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, 1); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}), table + * density ({@code loadFactor}), and number of concurrently + * updating threads ({@code concurrencyLevel}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @param concurrencyLevel the estimated number of concurrently + * updating threads. The implementation may use this value as + * a sizing hint. + * @throws IllegalArgumentException if the initial capacity is + * negative or the load factor or concurrencyLevel are + * nonpositive + */ + public ConcurrentHashMapV8(int initialCapacity, + float loadFactor, int concurrencyLevel) { + if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) + throw new IllegalArgumentException(); + if (initialCapacity < concurrencyLevel) // Use at least as many bins + initialCapacity = concurrencyLevel; // as estimated threads + long size = (long)(1.0 + (long)initialCapacity / loadFactor); + int cap = (size >= (long)MAXIMUM_CAPACITY) ? + MAXIMUM_CAPACITY : tableSizeFor((int)size); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @return the new set + */ + public static KeySetView newKeySet() { + return new KeySetView(new ConcurrentHashMapV8(), + Boolean.TRUE); + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + * @return the new set + */ + public static KeySetView newKeySet(int initialCapacity) { + return new KeySetView(new ConcurrentHashMapV8(initialCapacity), + Boolean.TRUE); + } + + /** + * {@inheritDoc} + */ + public boolean isEmpty() { + return counter.sum() <= 0L; // ignore transient negative values + } + + /** + * {@inheritDoc} + */ + public int size() { + long n = counter.sum(); + return ((n < 0L) ? 0 : + (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : + (int)n); + } + + /** + * Returns the number of mappings. This method should be used + * instead of {@link #size} because a ConcurrentHashMapV8 may + * contain more mappings than can be represented as an int. The + * value returned is a snapshot; the actual count may differ if + * there are ongoing concurrent insertions or removals. + * + * @return the number of mappings + */ + public long mappingCount() { + long n = counter.sum(); + return (n < 0L) ? 0L : n; // ignore transient negative values + } + + /** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + * + *

More formally, if this map contains a mapping from a key + * {@code k} to a value {@code v} such that {@code key.equals(k)}, + * then this method returns {@code v}; otherwise it returns + * {@code null}. (There can be at most one such mapping.) + * + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V get(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalGet(key); + } + + /** + * Returns the value to which the specified key is mapped, + * or the given defaultValue if this map contains no mapping for the key. + * + * @param key the key + * @param defaultValue the value to return if this map contains + * no mapping for the given key + * @return the mapping for the key, if present; else the defaultValue + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) { + if (key == null) + throw new NullPointerException(); + V v = (V) internalGet(key); + return v == null ? defaultValue : v; + } + + /** + * Tests if the specified object is a key in this table. + * + * @param key possible key + * @return {@code true} if and only if the specified object + * is a key in this table, as determined by the + * {@code equals} method; {@code false} otherwise + * @throws NullPointerException if the specified key is null + */ + public boolean containsKey(Object key) { + if (key == null) + throw new NullPointerException(); + return internalGet(key) != null; + } + + /** + * Returns {@code true} if this map maps one or more keys to the + * specified value. Note: This method may require a full traversal + * of the map, and is much slower than method {@code containsKey}. + * + * @param value value whose presence in this map is to be tested + * @return {@code true} if this map maps one or more keys to the + * specified value + * @throws NullPointerException if the specified value is null + */ + public boolean containsValue(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return true; + } + return false; + } + + public K findKey(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return it.nextKey; + } + return null; + } + + /** + * Legacy method testing if some key maps into the specified value + * in this table. This method is identical in functionality to + * {@link #containsValue}, and exists solely to ensure + * full compatibility with class {@link java.util.Hashtable}, + * which supported this method prior to introduction of the + * Java Collections framework. + * + * @param value a value to search for + * @return {@code true} if and only if some key maps to the + * {@code value} argument in this table as + * determined by the {@code equals} method; + * {@code false} otherwise + * @throws NullPointerException if the specified value is null + */ + public boolean contains(Object value) { + return containsValue(value); + } + + /** + * Maps the specified key to the specified value in this table. + * Neither the key nor the value can be null. + * + *

The value can be retrieved by calling the {@code get} method + * with a key that is equal to the original key. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V put(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPut(key, value); + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPutIfAbsent(key, value); + } + + /** + * Copies all of the mappings from the specified map to this one. + * These mappings replace any mappings that this map had for any of the + * keys currently in the specified map. + * + * @param m mappings to be stored in this map + */ + public void putAll(Map m) { + internalPutAll(m); + } + + /** + * If the specified key is not already associated with a value, + * computes its value using the given mappingFunction and enters + * it into the map unless null. This is equivalent to + *

 {@code
+     * if (map.containsKey(key))
+     *   return map.get(key);
+     * value = mappingFunction.apply(key);
+     * if (value != null)
+     *   map.put(key, value);
+     * return value;}
+ * + * except that the action is performed atomically. If the + * function returns {@code null} no mapping is recorded. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and no mapping is recorded. Some + * attempted update operations on this map by other threads may be + * blocked while computation is in progress, so the computation + * should be short and simple, and must not attempt to update any + * other mappings of this Map. The most appropriate usage is to + * construct a new object serving as an initial mapped value, or + * memoized result, as in: + * + *
 {@code
+     * map.computeIfAbsent(key, new Fun() {
+     *   public V map(K k) { return new Value(f(k)); }});}
+ * + * @param key key with which the specified value is to be associated + * @param mappingFunction the function to compute a value + * @return the current (existing or computed) value associated with + * the specified key, or null if the computed value is null + * @throws NullPointerException if the specified key or mappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the mappingFunction does so, + * in which case the mapping is left unestablished + */ + @SuppressWarnings("unchecked") public V computeIfAbsent + (K key, Fun mappingFunction) { + if (key == null || mappingFunction == null) + throw new NullPointerException(); + return (V)internalComputeIfAbsent(key, mappingFunction); + } + + /** + * If the given key is present, computes a new mapping value given a key and + * its current mapped value. This is equivalent to + *
 {@code
+     *   if (map.containsKey(key)) {
+     *     value = remappingFunction.apply(key, map.get(key));
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V computeIfPresent + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, true, remappingFunction); + } + + /** + * Computes a new mapping value given a key and + * its current mapped value (or {@code null} if there is no current + * mapping). This is equivalent to + *
 {@code
+     *   value = remappingFunction.apply(key, map.get(key));
+     *   if (value != null)
+     *     map.put(key, value);
+     *   else
+     *     map.remove(key);
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + *
 {@code
+     * Map map = ...;
+     * final String msg = ...;
+     * map.compute(key, new BiFun() {
+     *   public String apply(Key k, String v) {
+     *    return (v == null) ? msg : v + msg;});}}
+ * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V compute + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, false, remappingFunction); + } + + /** + * If the specified key is not already associated + * with a value, associate it with the given value. + * Otherwise, replace the value with the results of + * the given remapping function. This is equivalent to: + *
 {@code
+     *   if (!map.containsKey(key))
+     *     map.put(value);
+     *   else {
+     *     newValue = remappingFunction.apply(map.get(key), value);
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. + */ + @SuppressWarnings("unchecked") public V merge + (K key, V value, BiFun remappingFunction) { + if (key == null || value == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalMerge(key, value, remappingFunction); + } + + /** + * Removes the key (and its corresponding value) from this map. + * This method does nothing if the key is not in the map. + * + * @param key the key that needs to be removed + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V remove(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalReplace(key, null, null); + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if the specified key is null + */ + public boolean remove(Object key, Object value) { + if (key == null) + throw new NullPointerException(); + if (value == null) + return false; + return internalReplace(key, null, value) != null; + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if any of the arguments are null + */ + public boolean replace(K key, V oldValue, V newValue) { + if (key == null || oldValue == null || newValue == null) + throw new NullPointerException(); + return internalReplace(key, newValue, oldValue) != null; + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V replace(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalReplace(key, value, null); + } + + /** + * Removes all of the mappings from this map. + */ + public void clear() { + internalClear(); + } + + /** + * Returns a {@link Set} view of the keys contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. + * + * @return the set view + */ + public KeySetView keySet() { + KeySetView ks = keySet; + return (ks != null) ? ks : (keySet = new KeySetView(this, null)); + } + + /** + * Returns a {@link Set} view of the keys in this map, using the + * given common mapped value for any additions (i.e., {@link + * Collection#add} and {@link Collection#addAll}). This is of + * course only appropriate if it is acceptable to use the same + * value for all additions from this view. + * + * @param mappedValue the mapped value to use for any + * additions. + * @return the set view + * @throws NullPointerException if the mappedValue is null + */ + public KeySetView keySet(V mappedValue) { + if (mappedValue == null) + throw new NullPointerException(); + return new KeySetView(this, mappedValue); + } + + /** + * Returns a {@link Collection} view of the values contained in this map. + * The collection is backed by the map, so changes to the map are + * reflected in the collection, and vice-versa. + */ + public ValuesView values() { + ValuesView vs = values; + return (vs != null) ? vs : (values = new ValuesView(this)); + } + + /** + * Returns a {@link Set} view of the mappings contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or + * {@code addAll} operations. + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Set> entrySet() { + EntrySetView es = entrySet; + return (es != null) ? es : (entrySet = new EntrySetView(this)); + } + + /** + * Returns an enumeration of the keys in this table. + * + * @return an enumeration of the keys in this table + * @see #keySet() + */ + public Enumeration keys() { + return new KeyIterator(this); + } + + /** + * Returns an enumeration of the values in this table. + * + * @return an enumeration of the values in this table + * @see #values() + */ + public Enumeration elements() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the keys in this map. + * + * @return a partitionable iterator of the keys in this map + */ + public Spliterator keySpliterator() { + return new KeyIterator(this); + } + + /** + * Returns a partitionable iterator of the values in this map. + * + * @return a partitionable iterator of the values in this map + */ + public Spliterator valueSpliterator() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the entries in this map. + * + * @return a partitionable iterator of the entries in this map + */ + public Spliterator> entrySpliterator() { + return new EntryIterator(this); + } + + /** + * Returns the hash code value for this {@link Map}, i.e., + * the sum of, for each key-value pair in the map, + * {@code key.hashCode() ^ value.hashCode()}. + * + * @return the hash code value for this map + */ + public int hashCode() { + int h = 0; + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + h += it.nextKey.hashCode() ^ v.hashCode(); + } + return h; + } + + /** + * Returns a string representation of this map. The string + * representation consists of a list of key-value mappings (in no + * particular order) enclosed in braces ("{@code {}}"). Adjacent + * mappings are separated by the characters {@code ", "} (comma + * and space). Each key-value mapping is rendered as the key + * followed by an equals sign ("{@code =}") followed by the + * associated value. + * + * @return a string representation of this map + */ + public String toString() { + Traverser it = new Traverser(this); + StringBuilder sb = new StringBuilder(); + sb.append('{'); + Object v; + if ((v = it.advance()) != null) { + for (;;) { + Object k = it.nextKey; + sb.append(k == this ? "(this Map)" : k); + sb.append('='); + sb.append(v == this ? "(this Map)" : v); + if ((v = it.advance()) == null) + break; + sb.append(',').append(' '); + } + } + return sb.append('}').toString(); + } + + /** + * Compares the specified object with this map for equality. + * Returns {@code true} if the given object is a map with the same + * mappings as this map. This operation may return misleading + * results if either map is concurrently modified during execution + * of this method. + * + * @param o object to be compared for equality with this map + * @return {@code true} if the specified object is equal to this map + */ + public boolean equals(Object o) { + if (o != this) { + if (!(o instanceof Map)) + return false; + Map m = (Map) o; + Traverser it = new Traverser(this); + Object val; + while ((val = it.advance()) != null) { + Object v = m.get(it.nextKey); + if (v == null || (v != val && !v.equals(val))) + return false; + } + for (Map.Entry e : m.entrySet()) { + Object mk, mv, v; + if ((mk = e.getKey()) == null || + (mv = e.getValue()) == null || + (v = internalGet(mk)) == null || + (mv != v && !mv.equals(v))) + return false; + } + } + return true; + } + + /* ----------------Iterators -------------- */ + + @SuppressWarnings("serial") static final class KeyIterator extends Traverser + implements Spliterator, Enumeration { + KeyIterator(ConcurrentHashMapV8 map) { super(map); } + KeyIterator(Traverser it) { + super(it); + } + public KeyIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new KeyIterator(this); + } + @SuppressWarnings("unchecked") public final K next() { + if (nextVal == null && advance() == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return (K) k; + } + + public final K nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class ValueIterator extends Traverser + implements Spliterator, Enumeration { + ValueIterator(ConcurrentHashMapV8 map) { super(map); } + ValueIterator(Traverser it) { + super(it); + } + public ValueIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new ValueIterator(this); + } + + @SuppressWarnings("unchecked") public final V next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + nextVal = null; + return (V) v; + } + + public final V nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class EntryIterator extends Traverser + implements Spliterator> { + EntryIterator(ConcurrentHashMapV8 map) { super(map); } + EntryIterator(Traverser it) { + super(it); + } + public EntryIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new EntryIterator(this); + } + + @SuppressWarnings("unchecked") public final Map.Entry next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return new MapEntry((K)k, (V)v, map); + } + } + + /** + * Exported Entry for iterators + */ + static final class MapEntry implements Map.Entry { + final K key; // non-null + V val; // non-null + final ConcurrentHashMapV8 map; + MapEntry(K key, V val, ConcurrentHashMapV8 map) { + this.key = key; + this.val = val; + this.map = map; + } + public final K getKey() { return key; } + public final V getValue() { return val; } + public final int hashCode() { return key.hashCode() ^ val.hashCode(); } + public final String toString(){ return key + "=" + val; } + + public final boolean equals(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + (k == key || k.equals(key)) && + (v == val || v.equals(val))); + } + + /** + * Sets our entry's value and writes through to the map. The + * value to return is somewhat arbitrary here. Since we do not + * necessarily track asynchronous changes, the most recent + * "previous" value could be different from what we return (or + * could even have been removed in which case the put will + * re-establish). We do not and cannot guarantee more. + */ + public final V setValue(V value) { + if (value == null) throw new NullPointerException(); + V v = val; + val = value; + map.put(key, value); + return v; + } + } + + /* ---------------- Serialization Support -------------- */ + + /** + * Stripped-down version of helper class used in previous version, + * declared for the sake of serialization compatibility + */ + static class Segment implements Serializable { + private static final long serialVersionUID = 2249069246763182397L; + final float loadFactor; + Segment(float lf) { this.loadFactor = lf; } + } + + /** + * Saves the state of the {@code ConcurrentHashMapV8} instance to a + * stream (i.e., serializes it). + * @param s the stream + * @serialData + * the key (Object) and value (Object) + * for each key-value mapping, followed by a null pair. + * The key-value mappings are emitted in no particular order. + */ + @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + if (segments == null) { // for serialization compatibility + segments = (Segment[]) + new Segment[DEFAULT_CONCURRENCY_LEVEL]; + for (int i = 0; i < segments.length; ++i) + segments[i] = new Segment(LOAD_FACTOR); + } + s.defaultWriteObject(); + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + s.writeObject(it.nextKey); + s.writeObject(v); + } + s.writeObject(null); + s.writeObject(null); + segments = null; // throw away + } + + /** + * Reconstitutes the instance from a stream (that is, deserializes it). + * @param s the stream + */ + @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + this.segments = null; // unneeded + // initialize transient final field + this.counter = new LongAdder(); + + // Create all nodes, then place in table once size is known + long size = 0L; + Node p = null; + for (;;) { + K k = (K) s.readObject(); + V v = (V) s.readObject(); + if (k != null && v != null) { + int h = spread(k.hashCode()); + p = new Node(h, k, v, p); + ++size; + } + else + break; + } + if (p != null) { + boolean init = false; + int n; + if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) + n = MAXIMUM_CAPACITY; + else { + int sz = (int)size; + n = tableSizeFor(sz + (sz >>> 1) + 1); + } + int sc = sizeCtl; + boolean collide = false; + if (n > sc && + SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (table == null) { + init = true; + AtomicReferenceArray tab = new AtomicReferenceArray(n); + int mask = n - 1; + while (p != null) { + int j = p.hash & mask; + Node next = p.next; + Node q = p.next = tabAt(tab, j); + setTabAt(tab, j, p); + if (!collide && q != null && q.hash == p.hash) + collide = true; + p = next; + } + table = tab; + counter.add(size); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + if (collide) { // rescan and convert to TreeBins + AtomicReferenceArray tab = table; + for (int i = 0; i < tab.length(); ++i) { + int c = 0; + for (Node e = tabAt(tab, i); e != null; e = e.next) { + if (++c > TREE_THRESHOLD && + (e.key instanceof Comparable)) { + replaceWithTreeBin(tab, i, e.key); + break; + } + } + } + } + } + if (!init) { // Can only happen if unsafely published. + while (p != null) { + internalPut(p.key, p.val); + p = p.next; + } + } + } + } + + + // ------------------------------------------------------- + + // Sams + /** Interface describing a void action of one argument */ + public interface Action { void apply(A a); } + /** Interface describing a void action of two arguments */ + public interface BiAction { void apply(A a, B b); } + /** Interface describing a function of one argument */ + public interface Generator { T apply(); } + /** Interface describing a function mapping its argument to a double */ + public interface ObjectToDouble { double apply(A a); } + /** Interface describing a function mapping its argument to a long */ + public interface ObjectToLong { long apply(A a); } + /** Interface describing a function mapping its argument to an int */ + public interface ObjectToInt {int apply(A a); } + /** Interface describing a function mapping two arguments to a double */ + public interface ObjectByObjectToDouble { double apply(A a, B b); } + /** Interface describing a function mapping two arguments to a long */ + public interface ObjectByObjectToLong { long apply(A a, B b); } + /** Interface describing a function mapping two arguments to an int */ + public interface ObjectByObjectToInt {int apply(A a, B b); } + /** Interface describing a function mapping a double to a double */ + public interface DoubleToDouble { double apply(double a); } + /** Interface describing a function mapping a long to a long */ + public interface LongToLong { long apply(long a); } + /** Interface describing a function mapping an int to an int */ + public interface IntToInt { int apply(int a); } + /** Interface describing a function mapping two doubles to a double */ + public interface DoubleByDoubleToDouble { double apply(double a, double b); } + /** Interface describing a function mapping two longs to a long */ + public interface LongByLongToLong { long apply(long a, long b); } + /** Interface describing a function mapping two ints to an int */ + public interface IntByIntToInt { int apply(int a, int b); } + + + /* ----------------Views -------------- */ + + /** + * Base class for views. + */ + static abstract class CHMView { + final ConcurrentHashMapV8 map; + CHMView(ConcurrentHashMapV8 map) { this.map = map; } + + /** + * Returns the map backing this view. + * + * @return the map backing this view + */ + public ConcurrentHashMapV8 getMap() { return map; } + + public final int size() { return map.size(); } + public final boolean isEmpty() { return map.isEmpty(); } + public final void clear() { map.clear(); } + + // implementations below rely on concrete classes supplying these + abstract public Iterator iterator(); + abstract public boolean contains(Object o); + abstract public boolean remove(Object o); + + private static final String oomeMsg = "Required array size too large"; + + public final Object[] toArray() { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int n = (int)sz; + Object[] r = new Object[n]; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = it.next(); + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + @SuppressWarnings("unchecked") public final T[] toArray(T[] a) { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int m = (int)sz; + T[] r = (a.length >= m) ? a : + (T[])java.lang.reflect.Array + .newInstance(a.getClass().getComponentType(), m); + int n = r.length; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = (T)it.next(); + } + if (a == r && i < n) { + r[i] = null; // null-terminate + return r; + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + public final int hashCode() { + int h = 0; + for (Iterator it = iterator(); it.hasNext();) + h += it.next().hashCode(); + return h; + } + + public final String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + Iterator it = iterator(); + if (it.hasNext()) { + for (;;) { + Object e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (!it.hasNext()) + break; + sb.append(',').append(' '); + } + } + return sb.append(']').toString(); + } + + public final boolean containsAll(Collection c) { + if (c != this) { + for (Iterator it = c.iterator(); it.hasNext();) { + Object e = it.next(); + if (e == null || !contains(e)) + return false; + } + } + return true; + } + + public final boolean removeAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + public final boolean retainAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (!c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in + * which additions may optionally be enabled by mapping to a + * common value. This class cannot be directly instantiated. See + * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()}, + * {@link #newKeySet(int)}. + */ + public static class KeySetView extends CHMView implements Set, java.io.Serializable { + private static final long serialVersionUID = 7249069246763182397L; + private final V value; + KeySetView(ConcurrentHashMapV8 map, V value) { // non-public + super(map); + this.value = value; + } + + /** + * Returns the default mapped value for additions, + * or {@code null} if additions are not supported. + * + * @return the default mapped value for additions, or {@code null} + * if not supported. + */ + public V getMappedValue() { return value; } + + // implement Set API + + public boolean contains(Object o) { return map.containsKey(o); } + public boolean remove(Object o) { return map.remove(o) != null; } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the keys of this map + */ + public Iterator iterator() { return new KeyIterator(map); } + public boolean add(K e) { + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + if (e == null) + throw new NullPointerException(); + return map.internalPutIfAbsent(e, v) == null; + } + public boolean addAll(Collection c) { + boolean added = false; + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + for (K e : c) { + if (e == null) + throw new NullPointerException(); + if (map.internalPutIfAbsent(e, v) == null) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Collection} of + * values, in which additions are disabled. This class cannot be + * directly instantiated. See {@link #values}, + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public static final class ValuesView extends CHMView + implements Collection { + ValuesView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { return map.containsValue(o); } + public final boolean remove(Object o) { + if (o != null) { + Iterator it = new ValueIterator(map); + while (it.hasNext()) { + if (o.equals(it.next())) { + it.remove(); + return true; + } + } + } + return false; + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the values of this map + */ + public final Iterator iterator() { + return new ValueIterator(map); + } + public final boolean add(V e) { + throw new UnsupportedOperationException(); + } + public final boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value) + * entries. This class cannot be directly instantiated. See + * {@link #entrySet}. + */ + public static final class EntrySetView extends CHMView + implements Set> { + EntrySetView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { + Object k, v, r; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (r = map.get(k)) != null && + (v = e.getValue()) != null && + (v == r || v.equals(r))); + } + public final boolean remove(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + map.remove(k, v)); + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the entries of this map + */ + public final Iterator> iterator() { + return new EntryIterator(map); + } + + public final boolean add(Entry e) { + K key = e.getKey(); + V value = e.getValue(); + if (key == null || value == null) + throw new NullPointerException(); + return map.internalPut(key, value) == null; + } + public final boolean addAll(Collection> c) { + boolean added = false; + for (Entry e : c) { + if (add(e)) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java new file mode 100644 index 0000000..ecf552a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java @@ -0,0 +1,204 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.9 version. + +package com.concurrent_ruby.ext.jsr166e.nounsafe; + +import java.util.concurrent.atomic.AtomicLong; +import java.io.IOException; +import java.io.Serializable; +import java.io.ObjectInputStream; + +/** + * One or more variables that together maintain an initially zero + * {@code long} sum. When updates (method {@link #add}) are contended + * across threads, the set of variables may grow dynamically to reduce + * contention. Method {@link #sum} (or, equivalently, {@link + * #longValue}) returns the current total combined across the + * variables maintaining the sum. + * + *

This class is usually preferable to {@link AtomicLong} when + * multiple threads update a common sum that is used for purposes such + * as collecting statistics, not for fine-grained synchronization + * control. Under low update contention, the two classes have similar + * characteristics. But under high contention, expected throughput of + * this class is significantly higher, at the expense of higher space + * consumption. + * + *

This class extends {@link Number}, but does not define + * methods such as {@code hashCode} and {@code compareTo} because + * instances are expected to be mutated, and so are not useful as + * collection keys. + * + *

jsr166e note: This class is targeted to be placed in + * java.util.concurrent.atomic. + * + * @since 1.8 + * @author Doug Lea + */ +public class LongAdder extends Striped64 implements Serializable { + private static final long serialVersionUID = 7249069246863182397L; + + /** + * Version of plus for use in retryUpdate + */ + final long fn(long v, long x) { return v + x; } + + /** + * Creates a new adder with initial sum of zero. + */ + public LongAdder() { + } + + /** + * Adds the given value. + * + * @param x the value to add + */ + public void add(long x) { + Cell[] as; long b, v; HashCode hc; Cell a; int n; + if ((as = cells) != null || !casBase(b = base, b + x)) { + boolean uncontended = true; + int h = (hc = threadHashCode.get()).code; + if (as == null || (n = as.length) < 1 || + (a = as[(n - 1) & h]) == null || + !(uncontended = a.cas(v = a.value, v + x))) + retryUpdate(x, hc, uncontended); + } + } + + /** + * Equivalent to {@code add(1)}. + */ + public void increment() { + add(1L); + } + + /** + * Equivalent to {@code add(-1)}. + */ + public void decrement() { + add(-1L); + } + + /** + * Returns the current sum. The returned value is NOT an + * atomic snapshot: Invocation in the absence of concurrent + * updates returns an accurate result, but concurrent updates that + * occur while the sum is being calculated might not be + * incorporated. + * + * @return the sum + */ + public long sum() { + long sum = base; + Cell[] as = cells; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + sum += a.value; + } + } + return sum; + } + + /** + * Resets variables maintaining the sum to zero. This method may + * be a useful alternative to creating a new adder, but is only + * effective if there are no concurrent updates. Because this + * method is intrinsically racy, it should only be used when it is + * known that no threads are concurrently updating. + */ + public void reset() { + internalReset(0L); + } + + /** + * Equivalent in effect to {@link #sum} followed by {@link + * #reset}. This method may apply for example during quiescent + * points between multithreaded computations. If there are + * updates concurrent with this method, the returned value is + * not guaranteed to be the final value occurring before + * the reset. + * + * @return the sum + */ + public long sumThenReset() { + long sum = base; + Cell[] as = cells; + base = 0L; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) { + sum += a.value; + a.value = 0L; + } + } + } + return sum; + } + + /** + * Returns the String representation of the {@link #sum}. + * @return the String representation of the {@link #sum} + */ + public String toString() { + return Long.toString(sum()); + } + + /** + * Equivalent to {@link #sum}. + * + * @return the sum + */ + public long longValue() { + return sum(); + } + + /** + * Returns the {@link #sum} as an {@code int} after a narrowing + * primitive conversion. + */ + public int intValue() { + return (int)sum(); + } + + /** + * Returns the {@link #sum} as a {@code float} + * after a widening primitive conversion. + */ + public float floatValue() { + return (float)sum(); + } + + /** + * Returns the {@link #sum} as a {@code double} after a widening + * primitive conversion. + */ + public double doubleValue() { + return (double)sum(); + } + + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + s.defaultWriteObject(); + s.writeLong(sum()); + } + + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + busy = 0; + cells = null; + base = s.readLong(); + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java new file mode 100644 index 0000000..f521642 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java @@ -0,0 +1,291 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.5 version. + +package com.concurrent_ruby.ext.jsr166e.nounsafe; + +import java.util.Random; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; + +/** + * A package-local class holding common representation and mechanics + * for classes supporting dynamic striping on 64bit values. The class + * extends Number so that concrete subclasses must publicly do so. + */ +abstract class Striped64 extends Number { + /* + * This class maintains a lazily-initialized table of atomically + * updated variables, plus an extra "base" field. The table size + * is a power of two. Indexing uses masked per-thread hash codes. + * Nearly all declarations in this class are package-private, + * accessed directly by subclasses. + * + * Table entries are of class Cell; a variant of AtomicLong padded + * to reduce cache contention on most processors. Padding is + * overkill for most Atomics because they are usually irregularly + * scattered in memory and thus don't interfere much with each + * other. But Atomic objects residing in arrays will tend to be + * placed adjacent to each other, and so will most often share + * cache lines (with a huge negative performance impact) without + * this precaution. + * + * In part because Cells are relatively large, we avoid creating + * them until they are needed. When there is no contention, all + * updates are made to the base field. Upon first contention (a + * failed CAS on base update), the table is initialized to size 2. + * The table size is doubled upon further contention until + * reaching the nearest power of two greater than or equal to the + * number of CPUS. Table slots remain empty (null) until they are + * needed. + * + * A single spinlock ("busy") is used for initializing and + * resizing the table, as well as populating slots with new Cells. + * There is no need for a blocking lock: When the lock is not + * available, threads try other slots (or the base). During these + * retries, there is increased contention and reduced locality, + * which is still better than alternatives. + * + * Per-thread hash codes are initialized to random values. + * Contention and/or table collisions are indicated by failed + * CASes when performing an update operation (see method + * retryUpdate). Upon a collision, if the table size is less than + * the capacity, it is doubled in size unless some other thread + * holds the lock. If a hashed slot is empty, and lock is + * available, a new Cell is created. Otherwise, if the slot + * exists, a CAS is tried. Retries proceed by "double hashing", + * using a secondary hash (Marsaglia XorShift) to try to find a + * free slot. + * + * The table size is capped because, when there are more threads + * than CPUs, supposing that each thread were bound to a CPU, + * there would exist a perfect hash function mapping threads to + * slots that eliminates collisions. When we reach capacity, we + * search for this mapping by randomly varying the hash codes of + * colliding threads. Because search is random, and collisions + * only become known via CAS failures, convergence can be slow, + * and because threads are typically not bound to CPUS forever, + * may not occur at all. However, despite these limitations, + * observed contention rates are typically low in these cases. + * + * It is possible for a Cell to become unused when threads that + * once hashed to it terminate, as well as in the case where + * doubling the table causes no thread to hash to it under + * expanded mask. We do not try to detect or remove such cells, + * under the assumption that for long-running instances, observed + * contention levels will recur, so the cells will eventually be + * needed again; and for short-lived ones, it does not matter. + */ + + /** + * Padded variant of AtomicLong supporting only raw accesses plus CAS. + * The value field is placed between pads, hoping that the JVM doesn't + * reorder them. + * + * JVM intrinsics note: It would be possible to use a release-only + * form of CAS here, if it were provided. + */ + static final class Cell { + volatile long p0, p1, p2, p3, p4, p5, p6; + volatile long value; + volatile long q0, q1, q2, q3, q4, q5, q6; + + static AtomicLongFieldUpdater VALUE_UPDATER = AtomicLongFieldUpdater.newUpdater(Cell.class, "value"); + + Cell(long x) { value = x; } + + final boolean cas(long cmp, long val) { + return VALUE_UPDATER.compareAndSet(this, cmp, val); + } + + } + + /** + * Holder for the thread-local hash code. The code is initially + * random, but may be set to a different value upon collisions. + */ + static final class HashCode { + static final Random rng = new Random(); + int code; + HashCode() { + int h = rng.nextInt(); // Avoid zero to allow xorShift rehash + code = (h == 0) ? 1 : h; + } + } + + /** + * The corresponding ThreadLocal class + */ + static final class ThreadHashCode extends ThreadLocal { + public HashCode initialValue() { return new HashCode(); } + } + + /** + * Static per-thread hash codes. Shared across all instances to + * reduce ThreadLocal pollution and because adjustments due to + * collisions in one table are likely to be appropriate for + * others. + */ + static final ThreadHashCode threadHashCode = new ThreadHashCode(); + + /** Number of CPUS, to place bound on table size */ + static final int NCPU = Runtime.getRuntime().availableProcessors(); + + /** + * Table of cells. When non-null, size is a power of 2. + */ + transient volatile Cell[] cells; + + /** + * Base value, used mainly when there is no contention, but also as + * a fallback during table initialization races. Updated via CAS. + */ + transient volatile long base; + + /** + * Spinlock (locked via CAS) used when resizing and/or creating Cells. + */ + transient volatile int busy; + + AtomicLongFieldUpdater BASE_UPDATER = AtomicLongFieldUpdater.newUpdater(Striped64.class, "base"); + AtomicIntegerFieldUpdater BUSY_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy"); + + /** + * Package-private default constructor + */ + Striped64() { + } + + /** + * CASes the base field. + */ + final boolean casBase(long cmp, long val) { + return BASE_UPDATER.compareAndSet(this, cmp, val); + } + + /** + * CASes the busy field from 0 to 1 to acquire lock. + */ + final boolean casBusy() { + return BUSY_UPDATER.compareAndSet(this, 0, 1); + } + + /** + * Computes the function of current and new value. Subclasses + * should open-code this update function for most uses, but the + * virtualized form is needed within retryUpdate. + * + * @param currentValue the current value (of either base or a cell) + * @param newValue the argument from a user update call + * @return result of the update function + */ + abstract long fn(long currentValue, long newValue); + + /** + * Handles cases of updates involving initialization, resizing, + * creating new Cells, and/or contention. See above for + * explanation. This method suffers the usual non-modularity + * problems of optimistic retry code, relying on rechecked sets of + * reads. + * + * @param x the value + * @param hc the hash code holder + * @param wasUncontended false if CAS failed before call + */ + final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { + int h = hc.code; + boolean collide = false; // True if last slot nonempty + for (;;) { + Cell[] as; Cell a; int n; long v; + if ((as = cells) != null && (n = as.length) > 0) { + if ((a = as[(n - 1) & h]) == null) { + if (busy == 0) { // Try to attach new Cell + Cell r = new Cell(x); // Optimistically create + if (busy == 0 && casBusy()) { + boolean created = false; + try { // Recheck under lock + Cell[] rs; int m, j; + if ((rs = cells) != null && + (m = rs.length) > 0 && + rs[j = (m - 1) & h] == null) { + rs[j] = r; + created = true; + } + } finally { + busy = 0; + } + if (created) + break; + continue; // Slot is now non-empty + } + } + collide = false; + } + else if (!wasUncontended) // CAS already known to fail + wasUncontended = true; // Continue after rehash + else if (a.cas(v = a.value, fn(v, x))) + break; + else if (n >= NCPU || cells != as) + collide = false; // At max size or stale + else if (!collide) + collide = true; + else if (busy == 0 && casBusy()) { + try { + if (cells == as) { // Expand table unless stale + Cell[] rs = new Cell[n << 1]; + for (int i = 0; i < n; ++i) + rs[i] = as[i]; + cells = rs; + } + } finally { + busy = 0; + } + collide = false; + continue; // Retry with expanded table + } + h ^= h << 13; // Rehash + h ^= h >>> 17; + h ^= h << 5; + } + else if (busy == 0 && cells == as && casBusy()) { + boolean init = false; + try { // Initialize table + if (cells == as) { + Cell[] rs = new Cell[2]; + rs[h & 1] = new Cell(x); + cells = rs; + init = true; + } + } finally { + busy = 0; + } + if (init) + break; + } + else if (casBase(v = base, fn(v, x))) + break; // Fall back on using base + } + hc.code = h; // Record index for next time + } + + + /** + * Sets base and all cells to the given value. + */ + final void internalReset(long initialValue) { + Cell[] as = cells; + base = initialValue; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + a.value = initialValue; + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java new file mode 100644 index 0000000..3ea409f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java @@ -0,0 +1,199 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.16 version + +package com.concurrent_ruby.ext.jsr166y; + +import java.util.Random; + +/** + * A random number generator isolated to the current thread. Like the + * global {@link java.util.Random} generator used by the {@link + * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized + * with an internally generated seed that may not otherwise be + * modified. When applicable, use of {@code ThreadLocalRandom} rather + * than shared {@code Random} objects in concurrent programs will + * typically encounter much less overhead and contention. Use of + * {@code ThreadLocalRandom} is particularly appropriate when multiple + * tasks (for example, each a {@link ForkJoinTask}) use random numbers + * in parallel in thread pools. + * + *

Usages of this class should typically be of the form: + * {@code ThreadLocalRandom.current().nextX(...)} (where + * {@code X} is {@code Int}, {@code Long}, etc). + * When all usages are of this form, it is never possible to + * accidently share a {@code ThreadLocalRandom} across multiple threads. + * + *

This class also provides additional commonly used bounded random + * generation methods. + * + * @since 1.7 + * @author Doug Lea + */ +public class ThreadLocalRandom extends Random { + // same constants as Random, but must be redeclared because private + private static final long multiplier = 0x5DEECE66DL; + private static final long addend = 0xBL; + private static final long mask = (1L << 48) - 1; + + /** + * The random seed. We can't use super.seed. + */ + private long rnd; + + /** + * Initialization flag to permit calls to setSeed to succeed only + * while executing the Random constructor. We can't allow others + * since it would cause setting seed in one part of a program to + * unintentionally impact other usages by the thread. + */ + boolean initialized; + + // Padding to help avoid memory contention among seed updates in + // different TLRs in the common case that they are located near + // each other. + private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + /** + * The actual ThreadLocal + */ + private static final ThreadLocal localRandom = + new ThreadLocal() { + protected ThreadLocalRandom initialValue() { + return new ThreadLocalRandom(); + } + }; + + + /** + * Constructor called only by localRandom.initialValue. + */ + ThreadLocalRandom() { + super(); + initialized = true; + } + + /** + * Returns the current thread's {@code ThreadLocalRandom}. + * + * @return the current thread's {@code ThreadLocalRandom} + */ + public static ThreadLocalRandom current() { + return localRandom.get(); + } + + /** + * Throws {@code UnsupportedOperationException}. Setting seeds in + * this generator is not supported. + * + * @throws UnsupportedOperationException always + */ + public void setSeed(long seed) { + if (initialized) + throw new UnsupportedOperationException(); + rnd = (seed ^ multiplier) & mask; + } + + protected int next(int bits) { + rnd = (rnd * multiplier + addend) & mask; + return (int) (rnd >>> (48-bits)); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @throws IllegalArgumentException if least greater than or equal + * to bound + * @return the next value + */ + public int nextInt(int least, int bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextInt(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public long nextLong(long n) { + if (n <= 0) + throw new IllegalArgumentException("n must be positive"); + // Divide n by two until small enough for nextInt. On each + // iteration (at most 31 of them but usually much less), + // randomly choose both whether to include high bit in result + // (offset) and whether to continue with the lower vs upper + // half (which makes a difference only if odd). + long offset = 0; + while (n >= Integer.MAX_VALUE) { + int bits = next(2); + long half = n >>> 1; + long nextn = ((bits & 2) == 0) ? half : n - half; + if ((bits & 1) == 0) + offset += n - nextn; + n = nextn; + } + return offset + nextInt((int) n); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public long nextLong(long least, long bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextLong(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed {@code double} value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public double nextDouble(double n) { + if (n <= 0) + throw new IllegalArgumentException("n must be positive"); + return nextDouble() * n; + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public double nextDouble(double least, double bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextDouble() * (bound - least) + least; + } + + private static final long serialVersionUID = -5851777807851030925L; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent-ruby.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent-ruby.rb new file mode 100644 index 0000000..e9a3dea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent-ruby.rb @@ -0,0 +1,5 @@ +# This file is here so that there is a file with the same name as the gem that +# can be required by Bundler.require. Applications should normally +# require 'concurrent'. + +require_relative "concurrent" diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent.rb new file mode 100644 index 0000000..87de46f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent.rb @@ -0,0 +1,134 @@ +require 'concurrent/version' +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/configuration' + +require 'concurrent/atomics' +require 'concurrent/executors' +require 'concurrent/synchronization' + +require 'concurrent/atomic/atomic_markable_reference' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/agent' +require 'concurrent/atom' +require 'concurrent/array' +require 'concurrent/hash' +require 'concurrent/set' +require 'concurrent/map' +require 'concurrent/tuple' +require 'concurrent/async' +require 'concurrent/dataflow' +require 'concurrent/delay' +require 'concurrent/exchanger' +require 'concurrent/future' +require 'concurrent/immutable_struct' +require 'concurrent/ivar' +require 'concurrent/maybe' +require 'concurrent/mutable_struct' +require 'concurrent/mvar' +require 'concurrent/promise' +require 'concurrent/scheduled_task' +require 'concurrent/settable_struct' +require 'concurrent/timer_task' +require 'concurrent/tvar' +require 'concurrent/promises' + +require 'concurrent/thread_safe/synchronized_delegator' +require 'concurrent/thread_safe/util' + +require 'concurrent/options' + +# @!macro internal_implementation_note +# +# @note **Private Implementation:** This abstraction is a private, internal +# implementation detail. It should never be used directly. + +# @!macro monotonic_clock_warning +# +# @note Time calculations on all platforms and languages are sensitive to +# changes to the system clock. To alleviate the potential problems +# associated with changing the system clock while an application is running, +# most modern operating systems provide a monotonic clock that operates +# independently of the system clock. A monotonic clock cannot be used to +# determine human-friendly clock times. A monotonic clock is used exclusively +# for calculating time intervals. Not all Ruby platforms provide access to an +# operating system monotonic clock. On these platforms a pure-Ruby monotonic +# clock will be used as a fallback. An operating system monotonic clock is both +# faster and more reliable than the pure-Ruby implementation. The pure-Ruby +# implementation should be fast and reliable enough for most non-realtime +# operations. At this time the common Ruby platforms that provide access to an +# operating system monotonic clock are MRI 2.1 and above and JRuby (all versions). +# +# @see http://linux.die.net/man/3/clock_gettime Linux clock_gettime(3) + +# @!macro copy_options +# +# ## Copy Options +# +# Object references in Ruby are mutable. This can lead to serious +# problems when the {#value} of an object is a mutable reference. Which +# is always the case unless the value is a `Fixnum`, `Symbol`, or similar +# "primitive" data type. Each instance can be configured with a few +# options that can help protect the program from potentially dangerous +# operations. Each of these options can be optionally set when the object +# instance is created: +# +# * `:dup_on_deref` When true the object will call the `#dup` method on +# the `value` object every time the `#value` method is called +# (default: false) +# * `:freeze_on_deref` When true the object will call the `#freeze` +# method on the `value` object every time the `#value` method is called +# (default: false) +# * `:copy_on_deref` When given a `Proc` object the `Proc` will be run +# every time the `#value` method is called. The `Proc` will be given +# the current `value` as its only argument and the result returned by +# the block will be the return value of the `#value` call. When `nil` +# this option will be ignored (default: nil) +# +# When multiple deref options are set the order of operations is strictly defined. +# The order of deref operations is: +# * `:copy_on_deref` +# * `:dup_on_deref` +# * `:freeze_on_deref` +# +# Because of this ordering there is no need to `#freeze` an object created by a +# provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`. +# Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is +# as close to the behavior of a "pure" functional language (like Erlang, Clojure, +# or Haskell) as we are likely to get in Ruby. + +# @!macro deref_options +# +# @option opts [Boolean] :dup_on_deref (false) Call `#dup` before +# returning the data from {#value} +# @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before +# returning the data from {#value} +# @option opts [Proc] :copy_on_deref (nil) When calling the {#value} +# method, call the given proc passing the internal value as the sole +# argument then return the new value returned from the proc. + +# @!macro executor_and_deref_options +# +# @param [Hash] opts the options used to define the behavior at update and deref +# and to specify the executor on which to perform actions +# @option opts [Executor] :executor when set use the given `Executor` instance. +# Three special values are also supported: `:io` returns the global pool for +# long, blocking (IO) tasks, `:fast` returns the global pool for short, fast +# operations, and `:immediate` returns the global `ImmediateExecutor` object. +# @!macro deref_options + +# @!macro warn.edge +# @api Edge +# @note **Edge Features** are under active development and may change frequently. +# +# - Deprecations are not added before incompatible changes. +# - Edge version: _major_ is always 0, _minor_ bump means incompatible change, +# _patch_ bump means compatible change. +# - Edge features may also lack tests and documentation. +# - Features developed in `concurrent-ruby-edge` are expected to move +# to `concurrent-ruby` when finalised. + + +# {include:file:README.md} +module Concurrent +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/agent.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/agent.rb new file mode 100644 index 0000000..dc8a260 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/agent.rb @@ -0,0 +1,588 @@ +require 'concurrent/configuration' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/count_down_latch' +require 'concurrent/atomic/thread_local_var' +require 'concurrent/collection/copy_on_write_observer_set' +require 'concurrent/concern/observable' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # `Agent` is inspired by Clojure's [agent](http://clojure.org/agents) + # function. An agent is a shared, mutable variable providing independent, + # uncoordinated, *asynchronous* change of individual values. Best used when + # the value will undergo frequent, complex updates. Suitable when the result + # of an update does not need to be known immediately. `Agent` is (mostly) + # functionally equivalent to Clojure's agent, except where the runtime + # prevents parity. + # + # Agents are reactive, not autonomous - there is no imperative message loop + # and no blocking receive. The state of an Agent should be itself immutable + # and the `#value` of an Agent is always immediately available for reading by + # any thread without any messages, i.e. observation does not require + # cooperation or coordination. + # + # Agent action dispatches are made using the various `#send` methods. These + # methods always return immediately. At some point later, in another thread, + # the following will happen: + # + # 1. The given `action` will be applied to the state of the Agent and the + # `args`, if any were supplied. + # 2. The return value of `action` will be passed to the validator lambda, + # if one has been set on the Agent. + # 3. If the validator succeeds or if no validator was given, the return value + # of the given `action` will become the new `#value` of the Agent. See + # `#initialize` for details. + # 4. If any observers were added to the Agent, they will be notified. See + # `#add_observer` for details. + # 5. If during the `action` execution any other dispatches are made (directly + # or indirectly), they will be held until after the `#value` of the Agent + # has been changed. + # + # If any exceptions are thrown by an action function, no nested dispatches + # will occur, and the exception will be cached in the Agent itself. When an + # Agent has errors cached, any subsequent interactions will immediately throw + # an exception, until the agent's errors are cleared. Agent errors can be + # examined with `#error` and the agent restarted with `#restart`. + # + # The actions of all Agents get interleaved amongst threads in a thread pool. + # At any point in time, at most one action for each Agent is being executed. + # Actions dispatched to an agent from another single agent or thread will + # occur in the order they were sent, potentially interleaved with actions + # dispatched to the same agent from other sources. The `#send` method should + # be used for actions that are CPU limited, while the `#send_off` method is + # appropriate for actions that may block on IO. + # + # Unlike in Clojure, `Agent` cannot participate in `Concurrent::TVar` transactions. + # + # ## Example + # + # ``` + # def next_fibonacci(set = nil) + # return [0, 1] if set.nil? + # set + [set[-2..-1].reduce{|sum,x| sum + x }] + # end + # + # # create an agent with an initial value + # agent = Concurrent::Agent.new(next_fibonacci) + # + # # send a few update requests + # 5.times do + # agent.send{|set| next_fibonacci(set) } + # end + # + # # wait for them to complete + # agent.await + # + # # get the current value + # agent.value #=> [0, 1, 1, 2, 3, 5, 8] + # ``` + # + # ## Observation + # + # Agents support observers through the {Concurrent::Observable} mixin module. + # Notification of observers occurs every time an action dispatch returns and + # the new value is successfully validated. Observation will *not* occur if the + # action raises an exception, if validation fails, or when a {#restart} occurs. + # + # When notified the observer will receive three arguments: `time`, `old_value`, + # and `new_value`. The `time` argument is the time at which the value change + # occurred. The `old_value` is the value of the Agent when the action began + # processing. The `new_value` is the value to which the Agent was set when the + # action completed. Note that `old_value` and `new_value` may be the same. + # This is not an error. It simply means that the action returned the same + # value. + # + # ## Nested Actions + # + # It is possible for an Agent action to post further actions back to itself. + # The nested actions will be enqueued normally then processed *after* the + # outer action completes, in the order they were sent, possibly interleaved + # with action dispatches from other threads. Nested actions never deadlock + # with one another and a failure in a nested action will never affect the + # outer action. + # + # Nested actions can be called using the Agent reference from the enclosing + # scope or by passing the reference in as a "send" argument. Nested actions + # cannot be post using `self` from within the action block/proc/lambda; `self` + # in this context will not reference the Agent. The preferred method for + # dispatching nested actions is to pass the Agent as an argument. This allows + # Ruby to more effectively manage the closing scope. + # + # Prefer this: + # + # ``` + # agent = Concurrent::Agent.new(0) + # agent.send(agent) do |value, this| + # this.send {|v| v + 42 } + # 3.14 + # end + # agent.value #=> 45.14 + # ``` + # + # Over this: + # + # ``` + # agent = Concurrent::Agent.new(0) + # agent.send do |value| + # agent.send {|v| v + 42 } + # 3.14 + # end + # ``` + # + # @!macro agent_await_warning + # + # **NOTE** Never, *under any circumstances*, call any of the "await" methods + # ({#await}, {#await_for}, {#await_for!}, and {#wait}) from within an action + # block/proc/lambda. The call will block the Agent and will always fail. + # Calling either {#await} or {#wait} (with a timeout of `nil`) will + # hopelessly deadlock the Agent with no possibility of recovery. + # + # @!macro thread_safe_variable_comparison + # + # @see http://clojure.org/Agents Clojure Agents + # @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State + class Agent < Synchronization::LockableObject + include Concern::Observable + + ERROR_MODES = [:continue, :fail].freeze + private_constant :ERROR_MODES + + AWAIT_FLAG = ::Object.new + private_constant :AWAIT_FLAG + + AWAIT_ACTION = ->(value, latch) { latch.count_down; AWAIT_FLAG } + private_constant :AWAIT_ACTION + + DEFAULT_ERROR_HANDLER = ->(agent, error) { nil } + private_constant :DEFAULT_ERROR_HANDLER + + DEFAULT_VALIDATOR = ->(value) { true } + private_constant :DEFAULT_VALIDATOR + + Job = Struct.new(:action, :args, :executor, :caller) + private_constant :Job + + # Raised during action processing or any other time in an Agent's lifecycle. + class Error < StandardError + def initialize(message = nil) + message ||= 'agent must be restarted before jobs can post' + super(message) + end + end + + # Raised when a new value obtained during action processing or at `#restart` + # fails validation. + class ValidationError < Error + def initialize(message = nil) + message ||= 'invalid value' + super(message) + end + end + + # The error mode this Agent is operating in. See {#initialize} for details. + attr_reader :error_mode + + # Create a new `Agent` with the given initial value and options. + # + # The `:validator` option must be `nil` or a side-effect free proc/lambda + # which takes one argument. On any intended value change the validator, if + # provided, will be called. If the new value is invalid the validator should + # return `false` or raise an error. + # + # The `:error_handler` option must be `nil` or a proc/lambda which takes two + # arguments. When an action raises an error or validation fails, either by + # returning false or raising an error, the error handler will be called. The + # arguments to the error handler will be a reference to the agent itself and + # the error object which was raised. + # + # The `:error_mode` may be either `:continue` (the default if an error + # handler is given) or `:fail` (the default if error handler nil or not + # given). + # + # If an action being run by the agent throws an error or doesn't pass + # validation the error handler, if present, will be called. After the + # handler executes if the error mode is `:continue` the Agent will continue + # as if neither the action that caused the error nor the error itself ever + # happened. + # + # If the mode is `:fail` the Agent will become {#failed?} and will stop + # accepting new action dispatches. Any previously queued actions will be + # held until {#restart} is called. The {#value} method will still work, + # returning the value of the Agent before the error. + # + # @param [Object] initial the initial value + # @param [Hash] opts the configuration options + # + # @option opts [Symbol] :error_mode either `:continue` or `:fail` + # @option opts [nil, Proc] :error_handler the (optional) error handler + # @option opts [nil, Proc] :validator the (optional) validation procedure + def initialize(initial, opts = {}) + super() + synchronize { ns_initialize(initial, opts) } + end + + # The current value (state) of the Agent, irrespective of any pending or + # in-progress actions. The value is always available and is non-blocking. + # + # @return [Object] the current value + def value + @current.value # TODO (pitr 12-Sep-2015): broken unsafe read? + end + + alias_method :deref, :value + + # When {#failed?} and {#error_mode} is `:fail`, returns the error object + # which caused the failure, else `nil`. When {#error_mode} is `:continue` + # will *always* return `nil`. + # + # @return [nil, Error] the error which caused the failure when {#failed?} + def error + @error.value + end + + alias_method :reason, :error + + # @!macro agent_send + # + # Dispatches an action to the Agent and returns immediately. Subsequently, + # in a thread from a thread pool, the {#value} will be set to the return + # value of the action. Action dispatches are only allowed when the Agent + # is not {#failed?}. + # + # The action must be a block/proc/lambda which takes 1 or more arguments. + # The first argument is the current {#value} of the Agent. Any arguments + # passed to the send method via the `args` parameter will be passed to the + # action as the remaining arguments. The action must return the new value + # of the Agent. + # + # * {#send} and {#send!} should be used for actions that are CPU limited + # * {#send_off}, {#send_off!}, and {#<<} are appropriate for actions that + # may block on IO + # * {#send_via} and {#send_via!} are used when a specific executor is to + # be used for the action + # + # @param [Array] args zero or more arguments to be passed to + # the action + # @param [Proc] action the action dispatch to be enqueued + # + # @yield [agent, value, *args] process the old value and return the new + # @yieldparam [Object] value the current {#value} of the Agent + # @yieldparam [Array] args zero or more arguments to pass to the + # action + # @yieldreturn [Object] the new value of the Agent + # + # @!macro send_return + # @return [Boolean] true if the action is successfully enqueued, false if + # the Agent is {#failed?} + def send(*args, &action) + enqueue_action_job(action, args, Concurrent.global_fast_executor) + end + + # @!macro agent_send + # + # @!macro send_bang_return_and_raise + # @return [Boolean] true if the action is successfully enqueued + # @raise [Concurrent::Agent::Error] if the Agent is {#failed?} + def send!(*args, &action) + raise Error.new unless send(*args, &action) + true + end + + # @!macro agent_send + # @!macro send_return + def send_off(*args, &action) + enqueue_action_job(action, args, Concurrent.global_io_executor) + end + + alias_method :post, :send_off + + # @!macro agent_send + # @!macro send_bang_return_and_raise + def send_off!(*args, &action) + raise Error.new unless send_off(*args, &action) + true + end + + # @!macro agent_send + # @!macro send_return + # @param [Concurrent::ExecutorService] executor the executor on which the + # action is to be dispatched + def send_via(executor, *args, &action) + enqueue_action_job(action, args, executor) + end + + # @!macro agent_send + # @!macro send_bang_return_and_raise + # @param [Concurrent::ExecutorService] executor the executor on which the + # action is to be dispatched + def send_via!(executor, *args, &action) + raise Error.new unless send_via(executor, *args, &action) + true + end + + # Dispatches an action to the Agent and returns immediately. Subsequently, + # in a thread from a thread pool, the {#value} will be set to the return + # value of the action. Appropriate for actions that may block on IO. + # + # @param [Proc] action the action dispatch to be enqueued + # @return [Concurrent::Agent] self + # @see #send_off + def <<(action) + send_off(&action) + self + end + + # Blocks the current thread (indefinitely!) until all actions dispatched + # thus far, from this thread or nested by the Agent, have occurred. Will + # block when {#failed?}. Will never return if a failed Agent is {#restart} + # with `:clear_actions` true. + # + # Returns a reference to `self` to support method chaining: + # + # ``` + # current_value = agent.await.value + # ``` + # + # @return [Boolean] self + # + # @!macro agent_await_warning + def await + wait(nil) + self + end + + # Blocks the current thread until all actions dispatched thus far, from this + # thread or nested by the Agent, have occurred, or the timeout (in seconds) + # has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @return [Boolean] true if all actions complete before timeout else false + # + # @!macro agent_await_warning + def await_for(timeout) + wait(timeout.to_f) + end + + # Blocks the current thread until all actions dispatched thus far, from this + # thread or nested by the Agent, have occurred, or the timeout (in seconds) + # has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @return [Boolean] true if all actions complete before timeout + # + # @raise [Concurrent::TimeoutError] when timeout is reached + # + # @!macro agent_await_warning + def await_for!(timeout) + raise Concurrent::TimeoutError unless wait(timeout.to_f) + true + end + + # Blocks the current thread until all actions dispatched thus far, from this + # thread or nested by the Agent, have occurred, or the timeout (in seconds) + # has elapsed. Will block indefinitely when timeout is nil or not given. + # + # Provided mainly for consistency with other classes in this library. Prefer + # the various `await` methods instead. + # + # @param [Float] timeout the maximum number of seconds to wait + # @return [Boolean] true if all actions complete before timeout else false + # + # @!macro agent_await_warning + def wait(timeout = nil) + latch = Concurrent::CountDownLatch.new(1) + enqueue_await_job(latch) + latch.wait(timeout) + end + + # Is the Agent in a failed state? + # + # @see #restart + def failed? + !@error.value.nil? + end + + alias_method :stopped?, :failed? + + # When an Agent is {#failed?}, changes the Agent {#value} to `new_value` + # then un-fails the Agent so that action dispatches are allowed again. If + # the `:clear_actions` option is give and true, any actions queued on the + # Agent that were being held while it was failed will be discarded, + # otherwise those held actions will proceed. The `new_value` must pass the + # validator if any, or `restart` will raise an exception and the Agent will + # remain failed with its old {#value} and {#error}. Observers, if any, will + # not be notified of the new state. + # + # @param [Object] new_value the new value for the Agent once restarted + # @param [Hash] opts the configuration options + # @option opts [Symbol] :clear_actions true if all enqueued but unprocessed + # actions should be discarded on restart, else false (default: false) + # @return [Boolean] true + # + # @raise [Concurrent:AgentError] when not failed + def restart(new_value, opts = {}) + clear_actions = opts.fetch(:clear_actions, false) + synchronize do + raise Error.new('agent is not failed') unless failed? + raise ValidationError unless ns_validate(new_value) + @current.value = new_value + @error.value = nil + @queue.clear if clear_actions + ns_post_next_job unless @queue.empty? + end + true + end + + class << self + + # Blocks the current thread (indefinitely!) until all actions dispatched + # thus far to all the given Agents, from this thread or nested by the + # given Agents, have occurred. Will block when any of the agents are + # failed. Will never return if a failed Agent is restart with + # `:clear_actions` true. + # + # @param [Array] agents the Agents on which to wait + # @return [Boolean] true + # + # @!macro agent_await_warning + def await(*agents) + agents.each { |agent| agent.await } + true + end + + # Blocks the current thread until all actions dispatched thus far to all + # the given Agents, from this thread or nested by the given Agents, have + # occurred, or the timeout (in seconds) has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @param [Array] agents the Agents on which to wait + # @return [Boolean] true if all actions complete before timeout else false + # + # @!macro agent_await_warning + def await_for(timeout, *agents) + end_at = Concurrent.monotonic_time + timeout.to_f + ok = agents.length.times do |i| + break false if (delay = end_at - Concurrent.monotonic_time) < 0 + break false unless agents[i].await_for(delay) + end + !!ok + end + + # Blocks the current thread until all actions dispatched thus far to all + # the given Agents, from this thread or nested by the given Agents, have + # occurred, or the timeout (in seconds) has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @param [Array] agents the Agents on which to wait + # @return [Boolean] true if all actions complete before timeout + # + # @raise [Concurrent::TimeoutError] when timeout is reached + # @!macro agent_await_warning + def await_for!(timeout, *agents) + raise Concurrent::TimeoutError unless await_for(timeout, *agents) + true + end + end + + private + + def ns_initialize(initial, opts) + @error_mode = opts[:error_mode] + @error_handler = opts[:error_handler] + + if @error_mode && !ERROR_MODES.include?(@error_mode) + raise ArgumentError.new('unrecognized error mode') + elsif @error_mode.nil? + @error_mode = @error_handler ? :continue : :fail + end + + @error_handler ||= DEFAULT_ERROR_HANDLER + @validator = opts.fetch(:validator, DEFAULT_VALIDATOR) + @current = Concurrent::AtomicReference.new(initial) + @error = Concurrent::AtomicReference.new(nil) + @caller = Concurrent::ThreadLocalVar.new(nil) + @queue = [] + + self.observers = Collection::CopyOnNotifyObserverSet.new + end + + def enqueue_action_job(action, args, executor) + raise ArgumentError.new('no action given') unless action + job = Job.new(action, args, executor, @caller.value || Thread.current.object_id) + synchronize { ns_enqueue_job(job) } + end + + def enqueue_await_job(latch) + synchronize do + if (index = ns_find_last_job_for_thread) + job = Job.new(AWAIT_ACTION, [latch], Concurrent.global_immediate_executor, + Thread.current.object_id) + ns_enqueue_job(job, index+1) + else + latch.count_down + true + end + end + end + + def ns_enqueue_job(job, index = nil) + # a non-nil index means this is an await job + return false if index.nil? && failed? + index ||= @queue.length + @queue.insert(index, job) + # if this is the only job, post to executor + ns_post_next_job if @queue.length == 1 + true + end + + def ns_post_next_job + @queue.first.executor.post { execute_next_job } + end + + def execute_next_job + job = synchronize { @queue.first } + old_value = @current.value + + @caller.value = job.caller # for nested actions + new_value = job.action.call(old_value, *job.args) + @caller.value = nil + + return if new_value == AWAIT_FLAG + + if ns_validate(new_value) + @current.value = new_value + observers.notify_observers(Time.now, old_value, new_value) + else + handle_error(ValidationError.new) + end + rescue => error + handle_error(error) + ensure + synchronize do + @queue.shift + unless failed? || @queue.empty? + ns_post_next_job + end + end + end + + def ns_validate(value) + @validator.call(value) + rescue + false + end + + def handle_error(error) + # stop new jobs from posting + @error.value = error if @error_mode == :fail + @error_handler.call(self, error) + rescue + # do nothing + end + + def ns_find_last_job_for_thread + @queue.rindex { |job| job.caller == Thread.current.object_id } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/array.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/array.rb new file mode 100644 index 0000000..c8761af --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/array.rb @@ -0,0 +1,56 @@ +require 'concurrent/utility/engine' +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!macro concurrent_array + # + # A thread-safe subclass of Array. This version locks against the object + # itself for every method call, ensuring only one thread can be reading + # or writing at a time. This includes iteration methods like `#each`. + # + # @note `a += b` is **not** a **thread-safe** operation on + # `Concurrent::Array`. It reads array `a`, then it creates new `Concurrent::Array` + # which is concatenation of `a` and `b`, then it writes the concatenation to `a`. + # The read and write are independent operations they do not form a single atomic + # operation therefore when two `+=` operations are executed concurrently updates + # may be lost. Use `#concat` instead. + # + # @see http://ruby-doc.org/core/Array.html Ruby standard library `Array` + + # @!macro internal_implementation_note + ArrayImplementation = case + when Concurrent.on_cruby? + # Array is not fully thread-safe on CRuby, see + # https://github.com/ruby-concurrency/concurrent-ruby/issues/929 + # So we will need to add synchronization here + ::Array + + when Concurrent.on_jruby? + require 'jruby/synchronized' + + class JRubyArray < ::Array + include JRuby::Synchronized + end + JRubyArray + + when Concurrent.on_truffleruby? + require 'concurrent/thread_safe/util/data_structures' + + class TruffleRubyArray < ::Array + end + + ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubyArray + TruffleRubyArray + + else + warn 'Possibly unsupported Ruby implementation' + ::Array + end + private_constant :ArrayImplementation + + # @!macro concurrent_array + class Array < ArrayImplementation + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/async.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/async.rb new file mode 100644 index 0000000..97c5a6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/async.rb @@ -0,0 +1,449 @@ +require 'concurrent/configuration' +require 'concurrent/ivar' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # A mixin module that provides simple asynchronous behavior to a class, + # turning it into a simple actor. Loosely based on Erlang's + # [gen_server](http://www.erlang.org/doc/man/gen_server.html), but without + # supervision or linking. + # + # A more feature-rich {Concurrent::Actor} is also available when the + # capabilities of `Async` are too limited. + # + # ```cucumber + # Feature: + # As a stateful, plain old Ruby class + # I want safe, asynchronous behavior + # So my long-running methods don't block the main thread + # ``` + # + # The `Async` module is a way to mix simple yet powerful asynchronous + # capabilities into any plain old Ruby object or class, turning each object + # into a simple Actor. Method calls are processed on a background thread. The + # caller is free to perform other actions while processing occurs in the + # background. + # + # Method calls to the asynchronous object are made via two proxy methods: + # `async` (alias `cast`) and `await` (alias `call`). These proxy methods post + # the method call to the object's background thread and return a "future" + # which will eventually contain the result of the method call. + # + # This behavior is loosely patterned after Erlang's `gen_server` behavior. + # When an Erlang module implements the `gen_server` behavior it becomes + # inherently asynchronous. The `start` or `start_link` function spawns a + # process (similar to a thread but much more lightweight and efficient) and + # returns the ID of the process. Using the process ID, other processes can + # send messages to the `gen_server` via the `cast` and `call` methods. Unlike + # Erlang's `gen_server`, however, `Async` classes do not support linking or + # supervision trees. + # + # ## Basic Usage + # + # When this module is mixed into a class, objects of the class become inherently + # asynchronous. Each object gets its own background thread on which to post + # asynchronous method calls. Asynchronous method calls are executed in the + # background one at a time in the order they are received. + # + # To create an asynchronous class, simply mix in the `Concurrent::Async` module: + # + # ``` + # class Hello + # include Concurrent::Async + # + # def hello(name) + # "Hello, #{name}!" + # end + # end + # ``` + # + # Mixing this module into a class provides each object two proxy methods: + # `async` and `await`. These methods are thread safe with respect to the + # enclosing object. The former proxy allows methods to be called + # asynchronously by posting to the object's internal thread. The latter proxy + # allows a method to be called synchronously but does so safely with respect + # to any pending asynchronous method calls and ensures proper ordering. Both + # methods return a {Concurrent::IVar} which can be inspected for the result + # of the proxied method call. Calling a method with `async` will return a + # `:pending` `IVar` whereas `await` will return a `:complete` `IVar`. + # + # ``` + # class Echo + # include Concurrent::Async + # + # def echo(msg) + # print "#{msg}\n" + # end + # end + # + # horn = Echo.new + # horn.echo('zero') # synchronous, not thread-safe + # # returns the actual return value of the method + # + # horn.async.echo('one') # asynchronous, non-blocking, thread-safe + # # returns an IVar in the :pending state + # + # horn.await.echo('two') # synchronous, blocking, thread-safe + # # returns an IVar in the :complete state + # ``` + # + # ## Let It Fail + # + # The `async` and `await` proxy methods have built-in error protection based + # on Erlang's famous "let it fail" philosophy. Instance methods should not be + # programmed defensively. When an exception is raised by a delegated method + # the proxy will rescue the exception, expose it to the caller as the `reason` + # attribute of the returned future, then process the next method call. + # + # ## Calling Methods Internally + # + # External method calls should *always* use the `async` and `await` proxy + # methods. When one method calls another method, the `async` proxy should + # rarely be used and the `await` proxy should *never* be used. + # + # When an object calls one of its own methods using the `await` proxy the + # second call will be enqueued *behind* the currently running method call. + # Any attempt to wait on the result will fail as the second call will never + # run until after the current call completes. + # + # Calling a method using the `await` proxy from within a method that was + # itself called using `async` or `await` will irreversibly deadlock the + # object. Do *not* do this, ever. + # + # ## Instance Variables and Attribute Accessors + # + # Instance variables do not need to be thread-safe so long as they are private. + # Asynchronous method calls are processed in the order they are received and + # are processed one at a time. Therefore private instance variables can only + # be accessed by one thread at a time. This is inherently thread-safe. + # + # When using private instance variables within asynchronous methods, the best + # practice is to read the instance variable into a local variable at the start + # of the method then update the instance variable at the *end* of the method. + # This way, should an exception be raised during method execution the internal + # state of the object will not have been changed. + # + # ### Reader Attributes + # + # The use of `attr_reader` is discouraged. Internal state exposed externally, + # when necessary, should be done through accessor methods. The instance + # variables exposed by these methods *must* be thread-safe, or they must be + # called using the `async` and `await` proxy methods. These two approaches are + # subtly different. + # + # When internal state is accessed via the `async` and `await` proxy methods, + # the returned value represents the object's state *at the time the call is + # processed*, which may *not* be the state of the object at the time the call + # is made. + # + # To get the state *at the current* time, irrespective of an enqueued method + # calls, a reader method must be called directly. This is inherently unsafe + # unless the instance variable is itself thread-safe, preferably using one + # of the thread-safe classes within this library. Because the thread-safe + # classes within this library are internally-locking or non-locking, they can + # be safely used from within asynchronous methods without causing deadlocks. + # + # Generally speaking, the best practice is to *not* expose internal state via + # reader methods. The best practice is to simply use the method's return value. + # + # ### Writer Attributes + # + # Writer attributes should never be used with asynchronous classes. Changing + # the state externally, even when done in the thread-safe way, is not logically + # consistent. Changes to state need to be timed with respect to all asynchronous + # method calls which my be in-process or enqueued. The only safe practice is to + # pass all necessary data to each method as arguments and let the method update + # the internal state as necessary. + # + # ## Class Constants, Variables, and Methods + # + # ### Class Constants + # + # Class constants do not need to be thread-safe. Since they are read-only and + # immutable they may be safely read both externally and from within + # asynchronous methods. + # + # ### Class Variables + # + # Class variables should be avoided. Class variables represent shared state. + # Shared state is anathema to concurrency. Should there be a need to share + # state using class variables they *must* be thread-safe, preferably + # using the thread-safe classes within this library. When updating class + # variables, never assign a new value/object to the variable itself. Assignment + # is not thread-safe in Ruby. Instead, use the thread-safe update functions + # of the variable itself to change the value. + # + # The best practice is to *never* use class variables with `Async` classes. + # + # ### Class Methods + # + # Class methods which are pure functions are safe. Class methods which modify + # class variables should be avoided, for all the reasons listed above. + # + # ## An Important Note About Thread Safe Guarantees + # + # > Thread safe guarantees can only be made when asynchronous method calls + # > are not mixed with direct method calls. Use only direct method calls + # > when the object is used exclusively on a single thread. Use only + # > `async` and `await` when the object is shared between threads. Once you + # > call a method using `async` or `await`, you should no longer call methods + # > directly on the object. Use `async` and `await` exclusively from then on. + # + # @example + # + # class Echo + # include Concurrent::Async + # + # def echo(msg) + # print "#{msg}\n" + # end + # end + # + # horn = Echo.new + # horn.echo('zero') # synchronous, not thread-safe + # # returns the actual return value of the method + # + # horn.async.echo('one') # asynchronous, non-blocking, thread-safe + # # returns an IVar in the :pending state + # + # horn.await.echo('two') # synchronous, blocking, thread-safe + # # returns an IVar in the :complete state + # + # @see Concurrent::Actor + # @see https://en.wikipedia.org/wiki/Actor_model "Actor Model" at Wikipedia + # @see http://www.erlang.org/doc/man/gen_server.html Erlang gen_server + # @see http://c2.com/cgi/wiki?LetItCrash "Let It Crash" at http://c2.com/ + module Async + + # @!method self.new(*args, &block) + # + # Instantiate a new object and ensure proper initialization of the + # synchronization mechanisms. + # + # @param [Array] args Zero or more arguments to be passed to the + # object's initializer. + # @param [Proc] block Optional block to pass to the object's initializer. + # @return [Object] A properly initialized object of the asynchronous class. + + # Check for the presence of a method on an object and determine if a given + # set of arguments matches the required arity. + # + # @param [Object] obj the object to check against + # @param [Symbol] method the method to check the object for + # @param [Array] args zero or more arguments for the arity check + # + # @raise [NameError] the object does not respond to `method` method + # @raise [ArgumentError] the given `args` do not match the arity of `method` + # + # @note This check is imperfect because of the way Ruby reports the arity of + # methods with a variable number of arguments. It is possible to determine + # if too few arguments are given but impossible to determine if too many + # arguments are given. This check may also fail to recognize dynamic behavior + # of the object, such as methods simulated with `method_missing`. + # + # @see http://www.ruby-doc.org/core-2.1.1/Method.html#method-i-arity Method#arity + # @see http://ruby-doc.org/core-2.1.0/Object.html#method-i-respond_to-3F Object#respond_to? + # @see http://www.ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing BasicObject#method_missing + # + # @!visibility private + def self.validate_argc(obj, method, *args) + argc = args.length + arity = obj.method(method).arity + + if arity >= 0 && argc != arity + raise ArgumentError.new("wrong number of arguments (#{argc} for #{arity})") + elsif arity < 0 && (arity = (arity + 1).abs) > argc + raise ArgumentError.new("wrong number of arguments (#{argc} for #{arity}..*)") + end + end + + # @!visibility private + def self.included(base) + base.singleton_class.send(:alias_method, :original_new, :new) + base.extend(ClassMethods) + super(base) + end + + # @!visibility private + module ClassMethods + def new(*args, &block) + obj = original_new(*args, &block) + obj.send(:init_synchronization) + obj + end + ruby2_keywords :new if respond_to?(:ruby2_keywords, true) + end + private_constant :ClassMethods + + # Delegates asynchronous, thread-safe method calls to the wrapped object. + # + # @!visibility private + class AsyncDelegator < Synchronization::LockableObject + safe_initialization! + + # Create a new delegator object wrapping the given delegate. + # + # @param [Object] delegate the object to wrap and delegate method calls to + def initialize(delegate) + super() + @delegate = delegate + @queue = [] + @executor = Concurrent.global_io_executor + @ruby_pid = $$ + end + + # Delegates method calls to the wrapped object. + # + # @param [Symbol] method the method being called + # @param [Array] args zero or more arguments to the method + # + # @return [IVar] the result of the method call + # + # @raise [NameError] the object does not respond to `method` method + # @raise [ArgumentError] the given `args` do not match the arity of `method` + def method_missing(method, *args, &block) + super unless @delegate.respond_to?(method) + Async::validate_argc(@delegate, method, *args) + + ivar = Concurrent::IVar.new + synchronize do + reset_if_forked + @queue.push [ivar, method, args, block] + @executor.post { perform } if @queue.length == 1 + end + + ivar + end + + # Check whether the method is responsive + # + # @param [Symbol] method the method being called + def respond_to_missing?(method, include_private = false) + @delegate.respond_to?(method) || super + end + + # Perform all enqueued tasks. + # + # This method must be called from within the executor. It must not be + # called while already running. It will loop until the queue is empty. + def perform + loop do + ivar, method, args, block = synchronize { @queue.first } + break unless ivar # queue is empty + + begin + ivar.set(@delegate.send(method, *args, &block)) + rescue => error + ivar.fail(error) + end + + synchronize do + @queue.shift + return if @queue.empty? + end + end + end + + def reset_if_forked + if $$ != @ruby_pid + @queue.clear + @ruby_pid = $$ + end + end + end + private_constant :AsyncDelegator + + # Delegates synchronous, thread-safe method calls to the wrapped object. + # + # @!visibility private + class AwaitDelegator + + # Create a new delegator object wrapping the given delegate. + # + # @param [AsyncDelegator] delegate the object to wrap and delegate method calls to + def initialize(delegate) + @delegate = delegate + end + + # Delegates method calls to the wrapped object. + # + # @param [Symbol] method the method being called + # @param [Array] args zero or more arguments to the method + # + # @return [IVar] the result of the method call + # + # @raise [NameError] the object does not respond to `method` method + # @raise [ArgumentError] the given `args` do not match the arity of `method` + def method_missing(method, *args, &block) + ivar = @delegate.send(method, *args, &block) + ivar.wait + ivar + end + + # Check whether the method is responsive + # + # @param [Symbol] method the method being called + def respond_to_missing?(method, include_private = false) + @delegate.respond_to?(method) || super + end + end + private_constant :AwaitDelegator + + # Causes the chained method call to be performed asynchronously on the + # object's thread. The delegated method will return a future in the + # `:pending` state and the method call will have been scheduled on the + # object's thread. The final disposition of the method call can be obtained + # by inspecting the returned future. + # + # @!macro async_thread_safety_warning + # @note The method call is guaranteed to be thread safe with respect to + # all other method calls against the same object that are called with + # either `async` or `await`. The mutable nature of Ruby references + # (and object orientation in general) prevent any other thread safety + # guarantees. Do NOT mix direct method calls with delegated method calls. + # Use *only* delegated method calls when sharing the object between threads. + # + # @return [Concurrent::IVar] the pending result of the asynchronous operation + # + # @raise [NameError] the object does not respond to the requested method + # @raise [ArgumentError] the given `args` do not match the arity of + # the requested method + def async + @__async_delegator__ + end + alias_method :cast, :async + + # Causes the chained method call to be performed synchronously on the + # current thread. The delegated will return a future in either the + # `:fulfilled` or `:rejected` state and the delegated method will have + # completed. The final disposition of the delegated method can be obtained + # by inspecting the returned future. + # + # @!macro async_thread_safety_warning + # + # @return [Concurrent::IVar] the completed result of the synchronous operation + # + # @raise [NameError] the object does not respond to the requested method + # @raise [ArgumentError] the given `args` do not match the arity of the + # requested method + def await + @__await_delegator__ + end + alias_method :call, :await + + # Initialize the internal serializer and other stnchronization mechanisms. + # + # @note This method *must* be called immediately upon object construction. + # This is the only way thread-safe initialization can be guaranteed. + # + # @!visibility private + def init_synchronization + return self if defined?(@__async_initialized__) && @__async_initialized__ + @__async_initialized__ = true + @__async_delegator__ = AsyncDelegator.new(self) + @__await_delegator__ = AwaitDelegator.new(@__async_delegator__) + self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atom.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atom.rb new file mode 100644 index 0000000..f590a23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atom.rb @@ -0,0 +1,222 @@ +require 'concurrent/atomic/atomic_reference' +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/concern/observable' +require 'concurrent/synchronization/object' + +# @!macro thread_safe_variable_comparison +# +# ## Thread-safe Variable Classes +# +# Each of the thread-safe variable classes is designed to solve a different +# problem. In general: +# +# * *{Concurrent::Agent}:* Shared, mutable variable providing independent, +# uncoordinated, *asynchronous* change of individual values. Best used when +# the value will undergo frequent, complex updates. Suitable when the result +# of an update does not need to be known immediately. +# * *{Concurrent::Atom}:* Shared, mutable variable providing independent, +# uncoordinated, *synchronous* change of individual values. Best used when +# the value will undergo frequent reads but only occasional, though complex, +# updates. Suitable when the result of an update must be known immediately. +# * *{Concurrent::AtomicReference}:* A simple object reference that can be updated +# atomically. Updates are synchronous but fast. Best used when updates a +# simple set operations. Not suitable when updates are complex. +# {Concurrent::AtomicBoolean} and {Concurrent::AtomicFixnum} are similar +# but optimized for the given data type. +# * *{Concurrent::Exchanger}:* Shared, stateless synchronization point. Used +# when two or more threads need to exchange data. The threads will pair then +# block on each other until the exchange is complete. +# * *{Concurrent::MVar}:* Shared synchronization point. Used when one thread +# must give a value to another, which must take the value. The threads will +# block on each other until the exchange is complete. +# * *{Concurrent::ThreadLocalVar}:* Shared, mutable, isolated variable which +# holds a different value for each thread which has access. Often used as +# an instance variable in objects which must maintain different state +# for different threads. +# * *{Concurrent::TVar}:* Shared, mutable variables which provide +# *coordinated*, *synchronous*, change of *many* stated. Used when multiple +# value must change together, in an all-or-nothing transaction. + + +module Concurrent + + # Atoms provide a way to manage shared, synchronous, independent state. + # + # An atom is initialized with an initial value and an optional validation + # proc. At any time the value of the atom can be synchronously and safely + # changed. If a validator is given at construction then any new value + # will be checked against the validator and will be rejected if the + # validator returns false or raises an exception. + # + # There are two ways to change the value of an atom: {#compare_and_set} and + # {#swap}. The former will set the new value if and only if it validates and + # the current value matches the new value. The latter will atomically set the + # new value to the result of running the given block if and only if that + # value validates. + # + # ## Example + # + # ``` + # def next_fibonacci(set = nil) + # return [0, 1] if set.nil? + # set + [set[-2..-1].reduce{|sum,x| sum + x }] + # end + # + # # create an atom with an initial value + # atom = Concurrent::Atom.new(next_fibonacci) + # + # # send a few update requests + # 5.times do + # atom.swap{|set| next_fibonacci(set) } + # end + # + # # get the current value + # atom.value #=> [0, 1, 1, 2, 3, 5, 8] + # ``` + # + # ## Observation + # + # Atoms support observers through the {Concurrent::Observable} mixin module. + # Notification of observers occurs every time the value of the Atom changes. + # When notified the observer will receive three arguments: `time`, `old_value`, + # and `new_value`. The `time` argument is the time at which the value change + # occurred. The `old_value` is the value of the Atom when the change began + # The `new_value` is the value to which the Atom was set when the change + # completed. Note that `old_value` and `new_value` may be the same. This is + # not an error. It simply means that the change operation returned the same + # value. + # + # Unlike in Clojure, `Atom` cannot participate in {Concurrent::TVar} transactions. + # + # @!macro thread_safe_variable_comparison + # + # @see http://clojure.org/atoms Clojure Atoms + # @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State + class Atom < Synchronization::Object + include Concern::Observable + + safe_initialization! + attr_atomic(:value) + private :value=, :swap_value, :compare_and_set_value, :update_value + public :value + alias_method :deref, :value + + # @!method value + # The current value of the atom. + # + # @return [Object] The current value. + + # Create a new atom with the given initial value. + # + # @param [Object] value The initial value + # @param [Hash] opts The options used to configure the atom + # @option opts [Proc] :validator (nil) Optional proc used to validate new + # values. It must accept one and only one argument which will be the + # intended new value. The validator will return true if the new value + # is acceptable else return false (preferably) or raise an exception. + # + # @!macro deref_options + # + # @raise [ArgumentError] if the validator is not a `Proc` (when given) + def initialize(value, opts = {}) + super() + @Validator = opts.fetch(:validator, -> v { true }) + self.observers = Collection::CopyOnNotifyObserverSet.new + self.value = value + end + + # Atomically swaps the value of atom using the given block. The current + # value will be passed to the block, as will any arguments passed as + # arguments to the function. The new value will be validated against the + # (optional) validator proc given at construction. If validation fails the + # value will not be changed. + # + # Internally, {#swap} reads the current value, applies the block to it, and + # attempts to compare-and-set it in. Since another thread may have changed + # the value in the intervening time, it may have to retry, and does so in a + # spin loop. The net effect is that the value will always be the result of + # the application of the supplied block to a current value, atomically. + # However, because the block might be called multiple times, it must be free + # of side effects. + # + # @note The given block may be called multiple times, and thus should be free + # of side effects. + # + # @param [Object] args Zero or more arguments passed to the block. + # + # @yield [value, args] Calculates a new value for the atom based on the + # current value and any supplied arguments. + # @yieldparam value [Object] The current value of the atom. + # @yieldparam args [Object] All arguments passed to the function, in order. + # @yieldreturn [Object] The intended new value of the atom. + # + # @return [Object] The final value of the atom after all operations and + # validations are complete. + # + # @raise [ArgumentError] When no block is given. + def swap(*args) + raise ArgumentError.new('no block given') unless block_given? + + loop do + old_value = value + new_value = yield(old_value, *args) + begin + break old_value unless valid?(new_value) + break new_value if compare_and_set(old_value, new_value) + rescue + break old_value + end + end + end + + # Atomically sets the value of atom to the new value if and only if the + # current value of the atom is identical to the old value and the new + # value successfully validates against the (optional) validator given + # at construction. + # + # @param [Object] old_value The expected current value. + # @param [Object] new_value The intended new value. + # + # @return [Boolean] True if the value is changed else false. + def compare_and_set(old_value, new_value) + if valid?(new_value) && compare_and_set_value(old_value, new_value) + observers.notify_observers(Time.now, old_value, new_value) + true + else + false + end + end + + # Atomically sets the value of atom to the new value without regard for the + # current value so long as the new value successfully validates against the + # (optional) validator given at construction. + # + # @param [Object] new_value The intended new value. + # + # @return [Object] The final value of the atom after all operations and + # validations are complete. + def reset(new_value) + old_value = value + if valid?(new_value) + self.value = new_value + observers.notify_observers(Time.now, old_value, new_value) + new_value + else + old_value + end + end + + private + + # Is the new value valid? + # + # @param [Object] new_value The intended new value. + # @return [Boolean] false if the validator function returns false or raises + # an exception else true + def valid?(new_value) + @Validator.call(new_value) + rescue + false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb new file mode 100644 index 0000000..f775691 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb @@ -0,0 +1,127 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/atomic/mutex_atomic_boolean' + +module Concurrent + + ################################################################### + + # @!macro atomic_boolean_method_initialize + # + # Creates a new `AtomicBoolean` with the given initial value. + # + # @param [Boolean] initial the initial value + + # @!macro atomic_boolean_method_value_get + # + # Retrieves the current `Boolean` value. + # + # @return [Boolean] the current value + + # @!macro atomic_boolean_method_value_set + # + # Explicitly sets the value. + # + # @param [Boolean] value the new value to be set + # + # @return [Boolean] the current value + + # @!macro atomic_boolean_method_true_question + # + # Is the current value `true` + # + # @return [Boolean] true if the current value is `true`, else false + + # @!macro atomic_boolean_method_false_question + # + # Is the current value `false` + # + # @return [Boolean] true if the current value is `false`, else false + + # @!macro atomic_boolean_method_make_true + # + # Explicitly sets the value to true. + # + # @return [Boolean] true if value has changed, otherwise false + + # @!macro atomic_boolean_method_make_false + # + # Explicitly sets the value to false. + # + # @return [Boolean] true if value has changed, otherwise false + + ################################################################### + + # @!macro atomic_boolean_public_api + # + # @!method initialize(initial = false) + # @!macro atomic_boolean_method_initialize + # + # @!method value + # @!macro atomic_boolean_method_value_get + # + # @!method value=(value) + # @!macro atomic_boolean_method_value_set + # + # @!method true? + # @!macro atomic_boolean_method_true_question + # + # @!method false? + # @!macro atomic_boolean_method_false_question + # + # @!method make_true + # @!macro atomic_boolean_method_make_true + # + # @!method make_false + # @!macro atomic_boolean_method_make_false + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + AtomicBooleanImplementation = case + when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? + CAtomicBoolean + when Concurrent.on_jruby? + JavaAtomicBoolean + else + MutexAtomicBoolean + end + private_constant :AtomicBooleanImplementation + + # @!macro atomic_boolean + # + # A boolean value that can be updated atomically. Reads and writes to an atomic + # boolean and thread-safe and guaranteed to succeed. Reads and writes may block + # briefly but no explicit locking is required. + # + # @!macro thread_safe_variable_comparison + # + # Performance: + # + # ``` + # Testing with ruby 2.1.2 + # Testing with Concurrent::MutexAtomicBoolean... + # 2.790000 0.000000 2.790000 ( 2.791454) + # Testing with Concurrent::CAtomicBoolean... + # 0.740000 0.000000 0.740000 ( 0.740206) + # + # Testing with jruby 1.9.3 + # Testing with Concurrent::MutexAtomicBoolean... + # 5.240000 2.520000 7.760000 ( 3.683000) + # Testing with Concurrent::JavaAtomicBoolean... + # 3.340000 0.010000 3.350000 ( 0.855000) + # ``` + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean + # + # @!macro atomic_boolean_public_api + class AtomicBoolean < AtomicBooleanImplementation + # @return [String] Short string representation. + def to_s + format '%s value:%s>', super[0..-2], value + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb new file mode 100644 index 0000000..26cd05d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb @@ -0,0 +1,144 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/atomic/mutex_atomic_fixnum' + +module Concurrent + + ################################################################### + + # @!macro atomic_fixnum_method_initialize + # + # Creates a new `AtomicFixnum` with the given initial value. + # + # @param [Fixnum] initial the initial value + # @raise [ArgumentError] if the initial value is not a `Fixnum` + + # @!macro atomic_fixnum_method_value_get + # + # Retrieves the current `Fixnum` value. + # + # @return [Fixnum] the current value + + # @!macro atomic_fixnum_method_value_set + # + # Explicitly sets the value. + # + # @param [Fixnum] value the new value to be set + # + # @return [Fixnum] the current value + # + # @raise [ArgumentError] if the new value is not a `Fixnum` + + # @!macro atomic_fixnum_method_increment + # + # Increases the current value by the given amount (defaults to 1). + # + # @param [Fixnum] delta the amount by which to increase the current value + # + # @return [Fixnum] the current value after incrementation + + # @!macro atomic_fixnum_method_decrement + # + # Decreases the current value by the given amount (defaults to 1). + # + # @param [Fixnum] delta the amount by which to decrease the current value + # + # @return [Fixnum] the current value after decrementation + + # @!macro atomic_fixnum_method_compare_and_set + # + # Atomically sets the value to the given updated value if the current + # value == the expected value. + # + # @param [Fixnum] expect the expected value + # @param [Fixnum] update the new value + # + # @return [Boolean] true if the value was updated else false + + # @!macro atomic_fixnum_method_update + # + # Pass the current value to the given block, replacing it + # with the block's result. May retry if the value changes + # during the block's execution. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # + # @return [Object] the new value + + ################################################################### + + # @!macro atomic_fixnum_public_api + # + # @!method initialize(initial = 0) + # @!macro atomic_fixnum_method_initialize + # + # @!method value + # @!macro atomic_fixnum_method_value_get + # + # @!method value=(value) + # @!macro atomic_fixnum_method_value_set + # + # @!method increment(delta = 1) + # @!macro atomic_fixnum_method_increment + # + # @!method decrement(delta = 1) + # @!macro atomic_fixnum_method_decrement + # + # @!method compare_and_set(expect, update) + # @!macro atomic_fixnum_method_compare_and_set + # + # @!method update + # @!macro atomic_fixnum_method_update + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + AtomicFixnumImplementation = case + when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? + CAtomicFixnum + when Concurrent.on_jruby? + JavaAtomicFixnum + else + MutexAtomicFixnum + end + private_constant :AtomicFixnumImplementation + + # @!macro atomic_fixnum + # + # A numeric value that can be updated atomically. Reads and writes to an atomic + # fixnum and thread-safe and guaranteed to succeed. Reads and writes may block + # briefly but no explicit locking is required. + # + # @!macro thread_safe_variable_comparison + # + # Performance: + # + # ``` + # Testing with ruby 2.1.2 + # Testing with Concurrent::MutexAtomicFixnum... + # 3.130000 0.000000 3.130000 ( 3.136505) + # Testing with Concurrent::CAtomicFixnum... + # 0.790000 0.000000 0.790000 ( 0.785550) + # + # Testing with jruby 1.9.3 + # Testing with Concurrent::MutexAtomicFixnum... + # 5.460000 2.460000 7.920000 ( 3.715000) + # Testing with Concurrent::JavaAtomicFixnum... + # 4.520000 0.030000 4.550000 ( 1.187000) + # ``` + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicLong.html java.util.concurrent.atomic.AtomicLong + # + # @!macro atomic_fixnum_public_api + class AtomicFixnum < AtomicFixnumImplementation + # @return [String] Short string representation. + def to_s + format '%s value:%s>', super[0..-2], value + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb new file mode 100644 index 0000000..e16be65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb @@ -0,0 +1,167 @@ +require 'concurrent/errors' +require 'concurrent/synchronization/object' + +module Concurrent + # An atomic reference which maintains an object reference along with a mark bit + # that can be updated atomically. + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicMarkableReference.html + # java.util.concurrent.atomic.AtomicMarkableReference + class AtomicMarkableReference < ::Concurrent::Synchronization::Object + + attr_atomic(:reference) + private :reference, :reference=, :swap_reference, :compare_and_set_reference, :update_reference + + def initialize(value = nil, mark = false) + super() + self.reference = immutable_array(value, mark) + end + + # Atomically sets the value and mark to the given updated value and + # mark given both: + # - the current value == the expected value && + # - the current mark == the expected mark + # + # @param [Object] expected_val the expected value + # @param [Object] new_val the new value + # @param [Boolean] expected_mark the expected mark + # @param [Boolean] new_mark the new mark + # + # @return [Boolean] `true` if successful. A `false` return indicates + # that the actual value was not equal to the expected value or the + # actual mark was not equal to the expected mark + def compare_and_set(expected_val, new_val, expected_mark, new_mark) + # Memoize a valid reference to the current AtomicReference for + # later comparison. + current = reference + curr_val, curr_mark = current + + # Ensure that that the expected marks match. + return false unless expected_mark == curr_mark + + if expected_val.is_a? Numeric + # If the object is a numeric, we need to ensure we are comparing + # the numerical values + return false unless expected_val == curr_val + else + # Otherwise, we need to ensure we are comparing the object identity. + # Theoretically, this could be incorrect if a user monkey-patched + # `Object#equal?`, but they should know that they are playing with + # fire at that point. + return false unless expected_val.equal? curr_val + end + + prospect = immutable_array(new_val, new_mark) + + compare_and_set_reference current, prospect + end + + alias_method :compare_and_swap, :compare_and_set + + # Gets the current reference and marked values. + # + # @return [Array] the current reference and marked values + def get + reference + end + + # Gets the current value of the reference + # + # @return [Object] the current value of the reference + def value + reference[0] + end + + # Gets the current marked value + # + # @return [Boolean] the current marked value + def mark + reference[1] + end + + alias_method :marked?, :mark + + # _Unconditionally_ sets to the given value of both the reference and + # the mark. + # + # @param [Object] new_val the new value + # @param [Boolean] new_mark the new mark + # + # @return [Array] both the new value and the new mark + def set(new_val, new_mark) + self.reference = immutable_array(new_val, new_mark) + end + + # Pass the current value and marked state to the given block, replacing it + # with the block's results. May retry if the value changes during the + # block's execution. + # + # @yield [Object] Calculate a new value and marked state for the atomic + # reference using given (old) value and (old) marked + # @yieldparam [Object] old_val the starting value of the atomic reference + # @yieldparam [Boolean] old_mark the starting state of marked + # + # @return [Array] the new value and new mark + def update + loop do + old_val, old_mark = reference + new_val, new_mark = yield old_val, old_mark + + if compare_and_set old_val, new_val, old_mark, new_mark + return immutable_array(new_val, new_mark) + end + end + end + + # Pass the current value to the given block, replacing it + # with the block's result. Raise an exception if the update + # fails. + # + # @yield [Object] Calculate a new value and marked state for the atomic + # reference using given (old) value and (old) marked + # @yieldparam [Object] old_val the starting value of the atomic reference + # @yieldparam [Boolean] old_mark the starting state of marked + # + # @return [Array] the new value and marked state + # + # @raise [Concurrent::ConcurrentUpdateError] if the update fails + def try_update! + old_val, old_mark = reference + new_val, new_mark = yield old_val, old_mark + + unless compare_and_set old_val, new_val, old_mark, new_mark + fail ::Concurrent::ConcurrentUpdateError, + 'AtomicMarkableReference: Update failed due to race condition.', + 'Note: If you would like to guarantee an update, please use ' + + 'the `AtomicMarkableReference#update` method.' + end + + immutable_array(new_val, new_mark) + end + + # Pass the current value to the given block, replacing it with the + # block's result. Simply return nil if update fails. + # + # @yield [Object] Calculate a new value and marked state for the atomic + # reference using given (old) value and (old) marked + # @yieldparam [Object] old_val the starting value of the atomic reference + # @yieldparam [Boolean] old_mark the starting state of marked + # + # @return [Array] the new value and marked state, or nil if + # the update failed + def try_update + old_val, old_mark = reference + new_val, new_mark = yield old_val, old_mark + + return unless compare_and_set old_val, new_val, old_mark, new_mark + + immutable_array(new_val, new_mark) + end + + private + + def immutable_array(*args) + args.freeze + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb new file mode 100644 index 0000000..0b19b77 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb @@ -0,0 +1,142 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/atomic_reference/atomic_direct_update' +require 'concurrent/atomic_reference/numeric_cas_wrapper' +require 'concurrent/atomic_reference/mutex_atomic' + +# Shim for TruffleRuby::AtomicReference +if Concurrent.on_truffleruby? && !defined?(TruffleRuby::AtomicReference) + # @!visibility private + module TruffleRuby + AtomicReference = Truffle::AtomicReference + end +end + +module Concurrent + + # @!macro internal_implementation_note + AtomicReferenceImplementation = case + when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? + # @!visibility private + # @!macro internal_implementation_note + class CAtomicReference + include AtomicDirectUpdate + include AtomicNumericCompareAndSetWrapper + end + CAtomicReference + when Concurrent.on_jruby? + # @!visibility private + # @!macro internal_implementation_note + class JavaAtomicReference + include AtomicDirectUpdate + include AtomicNumericCompareAndSetWrapper + end + JavaAtomicReference + when Concurrent.on_truffleruby? + class TruffleRubyAtomicReference < TruffleRuby::AtomicReference + include AtomicDirectUpdate + if private_method_defined?(:compare_and_set_reference) + alias_method :_compare_and_set, :compare_and_set_reference + private :_compare_and_set + include AtomicNumericCompareAndSetWrapper + else + # AtomicNumericCompareAndSetWrapper behavior already in TruffleRuby::AtomicReference + alias_method :compare_and_swap, :compare_and_set + end + alias_method :value, :get + alias_method :value=, :set + alias_method :swap, :get_and_set + end + TruffleRubyAtomicReference + else + MutexAtomicReference + end + private_constant :AtomicReferenceImplementation + + # An object reference that may be updated atomically. All read and write + # operations have java volatile semantic. + # + # @!macro thread_safe_variable_comparison + # + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html + # + # @!method initialize(value = nil) + # @!macro atomic_reference_method_initialize + # @param [Object] value The initial value. + # + # @!method get + # @!macro atomic_reference_method_get + # Gets the current value. + # @return [Object] the current value + # + # @!method set(new_value) + # @!macro atomic_reference_method_set + # Sets to the given value. + # @param [Object] new_value the new value + # @return [Object] the new value + # + # @!method get_and_set(new_value) + # @!macro atomic_reference_method_get_and_set + # Atomically sets to the given value and returns the old value. + # @param [Object] new_value the new value + # @return [Object] the old value + # + # @!method compare_and_set(old_value, new_value) + # @!macro atomic_reference_method_compare_and_set + # + # Atomically sets the value to the given updated value if + # the current value == the expected value. + # + # @param [Object] old_value the expected value + # @param [Object] new_value the new value + # + # @return [Boolean] `true` if successful. A `false` return indicates + # that the actual value was not equal to the expected value. + # + # @!method update + # Pass the current value to the given block, replacing it + # with the block's result. May retry if the value changes + # during the block's execution. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # @return [Object] the new value + # + # @!method try_update + # Pass the current value to the given block, replacing it + # with the block's result. Return nil if the update fails. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # @note This method was altered to avoid raising an exception by default. + # Instead, this method now returns `nil` in case of failure. For more info, + # please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 + # @return [Object] the new value, or nil if update failed + # + # @!method try_update! + # Pass the current value to the given block, replacing it + # with the block's result. Raise an exception if the update + # fails. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # @note This behavior mimics the behavior of the original + # `AtomicReference#try_update` API. The reason this was changed was to + # avoid raising exceptions (which are inherently slow) by default. For more + # info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 + # @return [Object] the new value + # @raise [Concurrent::ConcurrentUpdateError] if the update fails + class AtomicReference < AtomicReferenceImplementation + + # @return [String] Short string representation. + def to_s + format '%s value:%s>', super[0..-2], get + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb new file mode 100644 index 0000000..d883aed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb @@ -0,0 +1,100 @@ +require 'concurrent/utility/engine' +require 'concurrent/atomic/mutex_count_down_latch' +require 'concurrent/atomic/java_count_down_latch' + +module Concurrent + + ################################################################### + + # @!macro count_down_latch_method_initialize + # + # Create a new `CountDownLatch` with the initial `count`. + # + # @param [new] count the initial count + # + # @raise [ArgumentError] if `count` is not an integer or is less than zero + + # @!macro count_down_latch_method_wait + # + # Block on the latch until the counter reaches zero or until `timeout` is reached. + # + # @param [Fixnum] timeout the number of seconds to wait for the counter or `nil` + # to block indefinitely + # @return [Boolean] `true` if the `count` reaches zero else false on `timeout` + + # @!macro count_down_latch_method_count_down + # + # Signal the latch to decrement the counter. Will signal all blocked threads when + # the `count` reaches zero. + + # @!macro count_down_latch_method_count + # + # The current value of the counter. + # + # @return [Fixnum] the current value of the counter + + ################################################################### + + # @!macro count_down_latch_public_api + # + # @!method initialize(count = 1) + # @!macro count_down_latch_method_initialize + # + # @!method wait(timeout = nil) + # @!macro count_down_latch_method_wait + # + # @!method count_down + # @!macro count_down_latch_method_count_down + # + # @!method count + # @!macro count_down_latch_method_count + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + CountDownLatchImplementation = case + when Concurrent.on_jruby? + JavaCountDownLatch + else + MutexCountDownLatch + end + private_constant :CountDownLatchImplementation + + # @!macro count_down_latch + # + # A synchronization object that allows one thread to wait on multiple other threads. + # The thread that will wait creates a `CountDownLatch` and sets the initial value + # (normally equal to the number of other threads). The initiating thread passes the + # latch to the other threads then waits for the other threads by calling the `#wait` + # method. Each of the other threads calls `#count_down` when done with its work. + # When the latch counter reaches zero the waiting thread is unblocked and continues + # with its work. A `CountDownLatch` can be used only once. Its value cannot be reset. + # + # @!macro count_down_latch_public_api + # @example Waiter and Decrementer + # latch = Concurrent::CountDownLatch.new(3) + # + # waiter = Thread.new do + # latch.wait() + # puts ("Waiter released") + # end + # + # decrementer = Thread.new do + # sleep(1) + # latch.count_down + # puts latch.count + # + # sleep(1) + # latch.count_down + # puts latch.count + # + # sleep(1) + # latch.count_down + # puts latch.count + # end + # + # [waiter, decrementer].each(&:join) + class CountDownLatch < CountDownLatchImplementation + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb new file mode 100644 index 0000000..9ebe29d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb @@ -0,0 +1,128 @@ +require 'concurrent/synchronization/lockable_object' +require 'concurrent/utility/native_integer' + +module Concurrent + + # A synchronization aid that allows a set of threads to all wait for each + # other to reach a common barrier point. + # @example + # barrier = Concurrent::CyclicBarrier.new(3) + # jobs = Array.new(3) { |i| -> { sleep i; p done: i } } + # process = -> (i) do + # # waiting to start at the same time + # barrier.wait + # # execute job + # jobs[i].call + # # wait for others to finish + # barrier.wait + # end + # threads = 2.times.map do |i| + # Thread.new(i, &process) + # end + # + # # use main as well + # process.call 2 + # + # # here we can be sure that all jobs are processed + class CyclicBarrier < Synchronization::LockableObject + + # @!visibility private + Generation = Struct.new(:status) + private_constant :Generation + + # Create a new `CyclicBarrier` that waits for `parties` threads + # + # @param [Fixnum] parties the number of parties + # @yield an optional block that will be executed that will be executed after + # the last thread arrives and before the others are released + # + # @raise [ArgumentError] if `parties` is not an integer or is less than zero + def initialize(parties, &block) + Utility::NativeInteger.ensure_integer_and_bounds parties + Utility::NativeInteger.ensure_positive_and_no_zero parties + + super(&nil) + synchronize { ns_initialize parties, &block } + end + + # @return [Fixnum] the number of threads needed to pass the barrier + def parties + synchronize { @parties } + end + + # @return [Fixnum] the number of threads currently waiting on the barrier + def number_waiting + synchronize { @number_waiting } + end + + # Blocks on the barrier until the number of waiting threads is equal to + # `parties` or until `timeout` is reached or `reset` is called + # If a block has been passed to the constructor, it will be executed once by + # the last arrived thread before releasing the others + # @param [Fixnum] timeout the number of seconds to wait for the counter or + # `nil` to block indefinitely + # @return [Boolean] `true` if the `count` reaches zero else false on + # `timeout` or on `reset` or if the barrier is broken + def wait(timeout = nil) + synchronize do + + return false unless @generation.status == :waiting + + @number_waiting += 1 + + if @number_waiting == @parties + @action.call if @action + ns_generation_done @generation, :fulfilled + true + else + generation = @generation + if ns_wait_until(timeout) { generation.status != :waiting } + generation.status == :fulfilled + else + ns_generation_done generation, :broken, false + false + end + end + end + end + + # resets the barrier to its initial state + # If there is at least one waiting thread, it will be woken up, the `wait` + # method will return false and the barrier will be broken + # If the barrier is broken, this method restores it to the original state + # + # @return [nil] + def reset + synchronize { ns_generation_done @generation, :reset } + end + + # A barrier can be broken when: + # - a thread called the `reset` method while at least one other thread was waiting + # - at least one thread timed out on `wait` method + # + # A broken barrier can be restored using `reset` it's safer to create a new one + # @return [Boolean] true if the barrier is broken otherwise false + def broken? + synchronize { @generation.status != :waiting } + end + + protected + + def ns_generation_done(generation, status, continue = true) + generation.status = status + ns_next_generation if continue + ns_broadcast + end + + def ns_next_generation + @generation = Generation.new(:waiting) + @number_waiting = 0 + end + + def ns_initialize(parties, &block) + @parties = parties + @action = block + ns_next_generation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/event.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/event.rb new file mode 100644 index 0000000..ccf84c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/event.rb @@ -0,0 +1,109 @@ +require 'thread' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # Old school kernel-style event reminiscent of Win32 programming in C++. + # + # When an `Event` is created it is in the `unset` state. Threads can choose to + # `#wait` on the event, blocking until released by another thread. When one + # thread wants to alert all blocking threads it calls the `#set` method which + # will then wake up all listeners. Once an `Event` has been set it remains set. + # New threads calling `#wait` will return immediately. An `Event` may be + # `#reset` at any time once it has been set. + # + # @see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682655.aspx + # @example + # event = Concurrent::Event.new + # + # t1 = Thread.new do + # puts "t1 is waiting" + # event.wait(1) + # puts "event occurred" + # end + # + # t2 = Thread.new do + # puts "t2 calling set" + # event.set + # end + # + # [t1, t2].each(&:join) + # + # # prints: + # # t1 is waiting + # # t2 calling set + # # event occurred + class Event < Synchronization::LockableObject + + # Creates a new `Event` in the unset state. Threads calling `#wait` on the + # `Event` will block. + def initialize + super + synchronize { ns_initialize } + end + + # Is the object in the set state? + # + # @return [Boolean] indicating whether or not the `Event` has been set + def set? + synchronize { @set } + end + + # Trigger the event, setting the state to `set` and releasing all threads + # waiting on the event. Has no effect if the `Event` has already been set. + # + # @return [Boolean] should always return `true` + def set + synchronize { ns_set } + end + + def try? + synchronize { @set ? false : ns_set } + end + + # Reset a previously set event back to the `unset` state. + # Has no effect if the `Event` has not yet been set. + # + # @return [Boolean] should always return `true` + def reset + synchronize do + if @set + @set = false + @iteration +=1 + end + true + end + end + + # Wait a given number of seconds for the `Event` to be set by another + # thread. Will wait forever when no `timeout` value is given. Returns + # immediately if the `Event` has already been set. + # + # @return [Boolean] true if the `Event` was set before timeout else false + def wait(timeout = nil) + synchronize do + unless @set + iteration = @iteration + ns_wait_until(timeout) { iteration < @iteration || @set } + else + true + end + end + end + + protected + + def ns_set + unless @set + @set = true + ns_broadcast + end + true + end + + def ns_initialize + @set = false + @iteration = 0 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb new file mode 100644 index 0000000..e90fc24 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb @@ -0,0 +1,109 @@ +require 'concurrent/constants' +require_relative 'locals' + +module Concurrent + + # A `FiberLocalVar` is a variable where the value is different for each fiber. + # Each variable may have a default value, but when you modify the variable only + # the current fiber will ever see that change. + # + # This is similar to Ruby's built-in fiber-local variables (`Thread.current[:name]`), + # but with these major advantages: + # * `FiberLocalVar` has its own identity, it doesn't need a Symbol. + # * Each Ruby's built-in fiber-local variable leaks some memory forever (it's a Symbol held forever on the fiber), + # so it's only OK to create a small amount of them. + # `FiberLocalVar` has no such issue and it is fine to create many of them. + # * Ruby's built-in fiber-local variables leak forever the value set on each fiber (unless set to nil explicitly). + # `FiberLocalVar` automatically removes the mapping for each fiber once the `FiberLocalVar` instance is GC'd. + # + # @example + # v = FiberLocalVar.new(14) + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # + # @example + # v = FiberLocalVar.new(14) + # + # Fiber.new do + # v.value #=> 14 + # v.value = 1 + # v.value #=> 1 + # end.resume + # + # Fiber.new do + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # end.resume + # + # v.value #=> 14 + class FiberLocalVar + LOCALS = FiberLocals.new + + # Creates a fiber local variable. + # + # @param [Object] default the default value when otherwise unset + # @param [Proc] default_block Optional block that gets called to obtain the + # default value for each fiber + def initialize(default = nil, &default_block) + if default && block_given? + raise ArgumentError, "Cannot use both value and block as default value" + end + + if block_given? + @default_block = default_block + @default = nil + else + @default_block = nil + @default = default + end + + @index = LOCALS.next_index(self) + end + + # Returns the value in the current fiber's copy of this fiber-local variable. + # + # @return [Object] the current value + def value + LOCALS.fetch(@index) { default } + end + + # Sets the current fiber's copy of this fiber-local variable to the specified value. + # + # @param [Object] value the value to set + # @return [Object] the new value + def value=(value) + LOCALS.set(@index, value) + end + + # Bind the given value to fiber local storage during + # execution of the given block. + # + # @param [Object] value the value to bind + # @yield the operation to be performed with the bound variable + # @return [Object] the value + def bind(value) + if block_given? + old_value = self.value + self.value = value + begin + yield + ensure + self.value = old_value + end + end + end + + protected + + # @!visibility private + def default + if @default_block + self.value = @default_block.call + else + @default + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb new file mode 100644 index 0000000..3c119bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb @@ -0,0 +1,43 @@ +if Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + + module Concurrent + + # @!macro count_down_latch + # @!visibility private + # @!macro internal_implementation_note + class JavaCountDownLatch + + # @!macro count_down_latch_method_initialize + def initialize(count = 1) + Utility::NativeInteger.ensure_integer_and_bounds(count) + Utility::NativeInteger.ensure_positive(count) + @latch = java.util.concurrent.CountDownLatch.new(count) + end + + # @!macro count_down_latch_method_wait + def wait(timeout = nil) + result = nil + if timeout.nil? + Synchronization::JRuby.sleep_interruptibly { @latch.await } + result = true + else + Synchronization::JRuby.sleep_interruptibly do + result = @latch.await(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) + end + end + result + end + + # @!macro count_down_latch_method_count_down + def count_down + @latch.countDown + end + + # @!macro count_down_latch_method_count + def count + @latch.getCount + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/locals.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/locals.rb new file mode 100644 index 0000000..0a276ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/locals.rb @@ -0,0 +1,189 @@ +require 'fiber' +require 'concurrent/utility/engine' +require 'concurrent/constants' + +module Concurrent + # @!visibility private + # @!macro internal_implementation_note + # + # An abstract implementation of local storage, with sub-classes for + # per-thread and per-fiber locals. + # + # Each execution context (EC, thread or fiber) has a lazily initialized array + # of local variable values. Each time a new local variable is created, we + # allocate an "index" for it. + # + # For example, if the allocated index is 1, that means slot #1 in EVERY EC's + # locals array will be used for the value of that variable. + # + # The good thing about using a per-EC structure to hold values, rather than + # a global, is that no synchronization is needed when reading and writing + # those values (since the structure is only ever accessed by a single + # thread). + # + # Of course, when a local variable is GC'd, 1) we need to recover its index + # for use by other new local variables (otherwise the locals arrays could + # get bigger and bigger with time), and 2) we need to null out all the + # references held in the now-unused slots (both to avoid blocking GC of those + # objects, and also to prevent "stale" values from being passed on to a new + # local when the index is reused). + # + # Because we need to null out freed slots, we need to keep references to + # ALL the locals arrays, so we can null out the appropriate slots in all of + # them. This is why we need to use a finalizer to clean up the locals array + # when the EC goes out of scope. + class AbstractLocals + def initialize + @free = [] + @lock = Mutex.new + @all_arrays = {} + @next = 0 + end + + def synchronize + @lock.synchronize { yield } + end + + if Concurrent.on_cruby? + def weak_synchronize + yield + end + else + alias_method :weak_synchronize, :synchronize + end + + def next_index(local) + index = synchronize do + if @free.empty? + @next += 1 + else + @free.pop + end + end + + # When the local goes out of scope, we should free the associated index + # and all values stored into it. + ObjectSpace.define_finalizer(local, local_finalizer(index)) + + index + end + + def free_index(index) + weak_synchronize do + # The cost of GC'ing a TLV is linear in the number of ECs using local + # variables. But that is natural! More ECs means more storage is used + # per local variable. So naturally more CPU time is required to free + # more storage. + # + # DO NOT use each_value which might conflict with new pair assignment + # into the hash in #set method. + @all_arrays.values.each do |locals| + locals[index] = nil + end + + # free index has to be published after the arrays are cleared: + @free << index + end + end + + def fetch(index) + locals = self.locals + value = locals ? locals[index] : nil + + if nil == value + yield + elsif NULL.equal?(value) + nil + else + value + end + end + + def set(index, value) + locals = self.locals! + locals[index] = (nil == value ? NULL : value) + + value + end + + private + + # When the local goes out of scope, clean up that slot across all locals currently assigned. + def local_finalizer(index) + proc do + free_index(index) + end + end + + # When a thread/fiber goes out of scope, remove the array from @all_arrays. + def thread_fiber_finalizer(array_object_id) + proc do + weak_synchronize do + @all_arrays.delete(array_object_id) + end + end + end + + # Returns the locals for the current scope, or nil if none exist. + def locals + raise NotImplementedError + end + + # Returns the locals for the current scope, creating them if necessary. + def locals! + raise NotImplementedError + end + end + + # @!visibility private + # @!macro internal_implementation_note + # An array-backed storage of indexed variables per thread. + class ThreadLocals < AbstractLocals + def locals + Thread.current.thread_variable_get(:concurrent_thread_locals) + end + + def locals! + thread = Thread.current + locals = thread.thread_variable_get(:concurrent_thread_locals) + + unless locals + locals = thread.thread_variable_set(:concurrent_thread_locals, []) + weak_synchronize do + @all_arrays[locals.object_id] = locals + end + # When the thread goes out of scope, we should delete the associated locals: + ObjectSpace.define_finalizer(thread, thread_fiber_finalizer(locals.object_id)) + end + + locals + end + end + + # @!visibility private + # @!macro internal_implementation_note + # An array-backed storage of indexed variables per fiber. + class FiberLocals < AbstractLocals + def locals + Thread.current[:concurrent_fiber_locals] + end + + def locals! + thread = Thread.current + locals = thread[:concurrent_fiber_locals] + + unless locals + locals = thread[:concurrent_fiber_locals] = [] + weak_synchronize do + @all_arrays[locals.object_id] = locals + end + # When the fiber goes out of scope, we should delete the associated locals: + ObjectSpace.define_finalizer(Fiber.current, thread_fiber_finalizer(locals.object_id)) + end + + locals + end + end + + private_constant :AbstractLocals, :ThreadLocals, :FiberLocals +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb new file mode 100644 index 0000000..c367d26 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb @@ -0,0 +1,29 @@ +require 'concurrent/utility/engine' +require_relative 'fiber_local_var' +require_relative 'thread_local_var' + +module Concurrent + # @!visibility private + def self.mutex_owned_per_thread? + return false if Concurrent.on_jruby? || Concurrent.on_truffleruby? + return RUBY_VERSION < "3.0" if Concurrent.on_cruby? + + mutex = Mutex.new + # Lock the mutex: + mutex.synchronize do + # Check if the mutex is still owned in a child fiber: + Fiber.new { mutex.owned? }.resume + end + end + + if mutex_owned_per_thread? + LockLocalVar = ThreadLocalVar + else + LockLocalVar = FiberLocalVar + end + + # Either {FiberLocalVar} or {ThreadLocalVar} depending on whether Mutex (and Monitor) + # are held, respectively, per Fiber or per Thread. + class LockLocalVar + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb new file mode 100644 index 0000000..015996b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb @@ -0,0 +1,68 @@ +require 'concurrent/synchronization/safe_initialization' + +module Concurrent + + # @!macro atomic_boolean + # @!visibility private + # @!macro internal_implementation_note + class MutexAtomicBoolean + extend Concurrent::Synchronization::SafeInitialization + + # @!macro atomic_boolean_method_initialize + def initialize(initial = false) + super() + @Lock = ::Mutex.new + @value = !!initial + end + + # @!macro atomic_boolean_method_value_get + def value + synchronize { @value } + end + + # @!macro atomic_boolean_method_value_set + def value=(value) + synchronize { @value = !!value } + end + + # @!macro atomic_boolean_method_true_question + def true? + synchronize { @value } + end + + # @!macro atomic_boolean_method_false_question + def false? + synchronize { !@value } + end + + # @!macro atomic_boolean_method_make_true + def make_true + synchronize { ns_make_value(true) } + end + + # @!macro atomic_boolean_method_make_false + def make_false + synchronize { ns_make_value(false) } + end + + protected + + # @!visibility private + def synchronize + if @Lock.owned? + yield + else + @Lock.synchronize { yield } + end + end + + private + + # @!visibility private + def ns_make_value(value) + old = @value + @value = value + old != @value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb new file mode 100644 index 0000000..0ca3955 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb @@ -0,0 +1,81 @@ +require 'concurrent/synchronization/safe_initialization' +require 'concurrent/utility/native_integer' + +module Concurrent + + # @!macro atomic_fixnum + # @!visibility private + # @!macro internal_implementation_note + class MutexAtomicFixnum + extend Concurrent::Synchronization::SafeInitialization + + # @!macro atomic_fixnum_method_initialize + def initialize(initial = 0) + super() + @Lock = ::Mutex.new + ns_set(initial) + end + + # @!macro atomic_fixnum_method_value_get + def value + synchronize { @value } + end + + # @!macro atomic_fixnum_method_value_set + def value=(value) + synchronize { ns_set(value) } + end + + # @!macro atomic_fixnum_method_increment + def increment(delta = 1) + synchronize { ns_set(@value + delta.to_i) } + end + + alias_method :up, :increment + + # @!macro atomic_fixnum_method_decrement + def decrement(delta = 1) + synchronize { ns_set(@value - delta.to_i) } + end + + alias_method :down, :decrement + + # @!macro atomic_fixnum_method_compare_and_set + def compare_and_set(expect, update) + synchronize do + if @value == expect.to_i + @value = update.to_i + true + else + false + end + end + end + + # @!macro atomic_fixnum_method_update + def update + synchronize do + @value = yield @value + end + end + + protected + + # @!visibility private + def synchronize + if @Lock.owned? + yield + else + @Lock.synchronize { yield } + end + end + + private + + # @!visibility private + def ns_set(value) + Utility::NativeInteger.ensure_integer_and_bounds value + @value = value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb new file mode 100644 index 0000000..29aa1ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb @@ -0,0 +1,44 @@ +require 'concurrent/synchronization/lockable_object' +require 'concurrent/utility/native_integer' + +module Concurrent + + # @!macro count_down_latch + # @!visibility private + # @!macro internal_implementation_note + class MutexCountDownLatch < Synchronization::LockableObject + + # @!macro count_down_latch_method_initialize + def initialize(count = 1) + Utility::NativeInteger.ensure_integer_and_bounds count + Utility::NativeInteger.ensure_positive count + + super() + synchronize { ns_initialize count } + end + + # @!macro count_down_latch_method_wait + def wait(timeout = nil) + synchronize { ns_wait_until(timeout) { @count == 0 } } + end + + # @!macro count_down_latch_method_count_down + def count_down + synchronize do + @count -= 1 if @count > 0 + ns_broadcast if @count == 0 + end + end + + # @!macro count_down_latch_method_count + def count + synchronize { @count } + end + + protected + + def ns_initialize(count) + @count = count + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb new file mode 100644 index 0000000..4347289 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb @@ -0,0 +1,131 @@ +require 'concurrent/synchronization/lockable_object' +require 'concurrent/utility/native_integer' + +module Concurrent + + # @!macro semaphore + # @!visibility private + # @!macro internal_implementation_note + class MutexSemaphore < Synchronization::LockableObject + + # @!macro semaphore_method_initialize + def initialize(count) + Utility::NativeInteger.ensure_integer_and_bounds count + + super() + synchronize { ns_initialize count } + end + + # @!macro semaphore_method_acquire + def acquire(permits = 1) + Utility::NativeInteger.ensure_integer_and_bounds permits + Utility::NativeInteger.ensure_positive permits + + synchronize do + try_acquire_timed(permits, nil) + end + + return unless block_given? + + begin + yield + ensure + release(permits) + end + end + + # @!macro semaphore_method_available_permits + def available_permits + synchronize { @free } + end + + # @!macro semaphore_method_drain_permits + # + # Acquires and returns all permits that are immediately available. + # + # @return [Integer] + def drain_permits + synchronize do + @free.tap { |_| @free = 0 } + end + end + + # @!macro semaphore_method_try_acquire + def try_acquire(permits = 1, timeout = nil) + Utility::NativeInteger.ensure_integer_and_bounds permits + Utility::NativeInteger.ensure_positive permits + + acquired = synchronize do + if timeout.nil? + try_acquire_now(permits) + else + try_acquire_timed(permits, timeout) + end + end + + return acquired unless block_given? + return unless acquired + + begin + yield + ensure + release(permits) + end + end + + # @!macro semaphore_method_release + def release(permits = 1) + Utility::NativeInteger.ensure_integer_and_bounds permits + Utility::NativeInteger.ensure_positive permits + + synchronize do + @free += permits + permits.times { ns_signal } + end + nil + end + + # Shrinks the number of available permits by the indicated reduction. + # + # @param [Fixnum] reduction Number of permits to remove. + # + # @raise [ArgumentError] if `reduction` is not an integer or is negative + # + # @raise [ArgumentError] if `@free` - `@reduction` is less than zero + # + # @return [nil] + # + # @!visibility private + def reduce_permits(reduction) + Utility::NativeInteger.ensure_integer_and_bounds reduction + Utility::NativeInteger.ensure_positive reduction + + synchronize { @free -= reduction } + nil + end + + protected + + # @!visibility private + def ns_initialize(count) + @free = count + end + + private + + # @!visibility private + def try_acquire_now(permits) + if @free >= permits + @free -= permits + true + else + false + end + end + + # @!visibility private + def try_acquire_timed(permits, timeout) + ns_wait_until(timeout) { try_acquire_now(permits) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb new file mode 100644 index 0000000..a9f0c48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb @@ -0,0 +1,268 @@ +require 'thread' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/errors' +require 'concurrent/synchronization/object' +require 'concurrent/synchronization/lock' + +module Concurrent + + # Ruby read-write lock implementation + # + # Allows any number of concurrent readers, but only one concurrent writer + # (And if the "write" lock is taken, any readers who come along will have to wait) + # + # If readers are already active when a writer comes along, the writer will wait for + # all the readers to finish before going ahead. + # Any additional readers that come when the writer is already waiting, will also + # wait (so writers are not starved). + # + # This implementation is based on `java.util.concurrent.ReentrantReadWriteLock`. + # + # @example + # lock = Concurrent::ReadWriteLock.new + # lock.with_read_lock { data.retrieve } + # lock.with_write_lock { data.modify! } + # + # @note Do **not** try to acquire the write lock while already holding a read lock + # **or** try to acquire the write lock while you already have it. + # This will lead to deadlock + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html java.util.concurrent.ReentrantReadWriteLock + class ReadWriteLock < Synchronization::Object + + # @!visibility private + WAITING_WRITER = 1 << 15 + + # @!visibility private + RUNNING_WRITER = 1 << 29 + + # @!visibility private + MAX_READERS = WAITING_WRITER - 1 + + # @!visibility private + MAX_WRITERS = RUNNING_WRITER - MAX_READERS - 1 + + safe_initialization! + + # Implementation notes: + # A goal is to make the uncontended path for both readers/writers lock-free + # Only if there is reader-writer or writer-writer contention, should locks be used + # Internal state is represented by a single integer ("counter"), and updated + # using atomic compare-and-swap operations + # When the counter is 0, the lock is free + # Each reader increments the counter by 1 when acquiring a read lock + # (and decrements by 1 when releasing the read lock) + # The counter is increased by (1 << 15) for each writer waiting to acquire the + # write lock, and by (1 << 29) if the write lock is taken + + # Create a new `ReadWriteLock` in the unlocked state. + def initialize + super() + @Counter = AtomicFixnum.new(0) # single integer which represents lock state + @Writer = AtomicReference.new(nil) # the thread currently holding the write lock + @ReadLock = Synchronization::Lock.new + @WriteLock = Synchronization::Lock.new + end + + # Execute a block operation within a read lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_read_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_read_lock + begin + yield + ensure + release_read_lock + end + end + + # Execute a block operation within a write lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_write_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_write_lock + begin + yield + ensure + release_write_lock + end + end + + # Acquire a read lock. If a write lock has been acquired will block until + # it is released. Will not block if other read locks have been acquired. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def acquire_read_lock + while true + c = @Counter.value + raise ResourceLimitError.new('Too many reader threads') if max_readers?(c) + + # If a writer is waiting when we first queue up, we need to wait + if waiting_writer?(c) + @ReadLock.wait_until { !waiting_writer? } + + # after a reader has waited once, they are allowed to "barge" ahead of waiting writers + # but if a writer is *running*, the reader still needs to wait (naturally) + while true + c = @Counter.value + if running_writer?(c) + @ReadLock.wait_until { !running_writer? } + else + return if @Counter.compare_and_set(c, c+1) + end + end + else + break if @Counter.compare_and_set(c, c+1) + end + end + true + end + + # Release a previously acquired read lock. + # + # @return [Boolean] true if the lock is successfully released + # + # @raise [Concurrent::IllegalOperationError] if no read lock is currently held. + def release_read_lock + while true + c = @Counter.value + raise IllegalOperationError, 'Cannot release a read lock which is not held' if running_readers(c) == 0 + + if @Counter.compare_and_set(c, c-1) + # If one or more writers were waiting, and we were the last reader, wake a writer up + if waiting_writer?(c) && running_readers(c) == 1 + @WriteLock.signal + end + break + end + end + true + end + + # Acquire a write lock. Will block and wait for all active readers and writers. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of writers + # is exceeded. + def acquire_write_lock + while true + c = @Counter.value + raise ResourceLimitError.new('Too many writer threads') if max_writers?(c) + + if c == 0 # no readers OR writers running + # if we successfully swap the RUNNING_WRITER bit on, then we can go ahead + break if @Counter.compare_and_set(0, RUNNING_WRITER) + elsif @Counter.compare_and_set(c, c+WAITING_WRITER) + while true + # Now we have successfully incremented, so no more readers will be able to increment + # (they will wait instead) + # However, readers OR writers could decrement right here, OR another writer could increment + @WriteLock.wait_until do + # So we have to do another check inside the synchronized section + # If a writer OR reader is running, then go to sleep + c = @Counter.value + !running_writer?(c) && !running_readers?(c) + end + + # We just came out of a wait + # If we successfully turn the RUNNING_WRITER bit on with an atomic swap, + # Then we are OK to stop waiting and go ahead + # Otherwise go back and wait again + c = @Counter.value + break if !running_writer?(c) && !running_readers?(c) && @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER) + end + break + end + end + @Writer.set(Thread.current) + true + end + + # Release a previously acquired write lock. + # + # @return [Boolean] true if the lock is successfully released + # + # @raise [Concurrent::IllegalOperationError] if the write lock is not held + # by the current thread. + def release_write_lock + unless @Writer.compare_and_set(Thread.current, nil) + raise IllegalOperationError, 'Cannot release a write lock which is not held by the current thread' + end + + c = @Counter.update { |counter| counter - RUNNING_WRITER } + @ReadLock.broadcast + @WriteLock.signal if waiting_writers(c) > 0 + true + end + + # Queries if the write lock is held by any thread. + # + # @return [Boolean] true if the write lock is held else false` + def write_locked? + @Counter.value >= RUNNING_WRITER + end + + # Queries whether any threads are waiting to acquire the read or write lock. + # + # @return [Boolean] true if any threads are waiting for a lock else false + def has_waiters? + waiting_writer?(@Counter.value) + end + + private + + # @!visibility private + def running_readers(c = @Counter.value) + c & MAX_READERS + end + + # @!visibility private + def running_readers?(c = @Counter.value) + (c & MAX_READERS) > 0 + end + + # @!visibility private + def running_writer?(c = @Counter.value) + c >= RUNNING_WRITER + end + + # @!visibility private + def waiting_writers(c = @Counter.value) + (c & MAX_WRITERS) / WAITING_WRITER + end + + # @!visibility private + def waiting_writer?(c = @Counter.value) + c >= WAITING_WRITER + end + + # @!visibility private + def max_readers?(c = @Counter.value) + (c & MAX_READERS) == MAX_READERS + end + + # @!visibility private + def max_writers?(c = @Counter.value) + (c & MAX_WRITERS) == MAX_WRITERS + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb new file mode 100644 index 0000000..e2718a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb @@ -0,0 +1,386 @@ +require 'thread' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/errors' +require 'concurrent/synchronization/object' +require 'concurrent/synchronization/lock' +require 'concurrent/atomic/lock_local_var' + +module Concurrent + + # Re-entrant read-write lock implementation + # + # Allows any number of concurrent readers, but only one concurrent writer + # (And while the "write" lock is taken, no read locks can be obtained either. + # Hence, the write lock can also be called an "exclusive" lock.) + # + # If another thread has taken a read lock, any thread which wants a write lock + # will block until all the readers release their locks. However, once a thread + # starts waiting to obtain a write lock, any additional readers that come along + # will also wait (so writers are not starved). + # + # A thread can acquire both a read and write lock at the same time. A thread can + # also acquire a read lock OR a write lock more than once. Only when the read (or + # write) lock is released as many times as it was acquired, will the thread + # actually let it go, allowing other threads which might have been waiting + # to proceed. Therefore the lock can be upgraded by first acquiring + # read lock and then write lock and that the lock can be downgraded by first + # having both read and write lock a releasing just the write lock. + # + # If both read and write locks are acquired by the same thread, it is not strictly + # necessary to release them in the same order they were acquired. In other words, + # the following code is legal: + # + # @example + # lock = Concurrent::ReentrantReadWriteLock.new + # lock.acquire_write_lock + # lock.acquire_read_lock + # lock.release_write_lock + # # At this point, the current thread is holding only a read lock, not a write + # # lock. So other threads can take read locks, but not a write lock. + # lock.release_read_lock + # # Now the current thread is not holding either a read or write lock, so + # # another thread could potentially acquire a write lock. + # + # This implementation was inspired by `java.util.concurrent.ReentrantReadWriteLock`. + # + # @example + # lock = Concurrent::ReentrantReadWriteLock.new + # lock.with_read_lock { data.retrieve } + # lock.with_write_lock { data.modify! } + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html java.util.concurrent.ReentrantReadWriteLock + class ReentrantReadWriteLock < Synchronization::Object + + # Implementation notes: + # + # A goal is to make the uncontended path for both readers/writers mutex-free + # Only if there is reader-writer or writer-writer contention, should mutexes be used + # Otherwise, a single CAS operation is all we need to acquire/release a lock + # + # Internal state is represented by a single integer ("counter"), and updated + # using atomic compare-and-swap operations + # When the counter is 0, the lock is free + # Each thread which has one OR MORE read locks increments the counter by 1 + # (and decrements by 1 when releasing the read lock) + # The counter is increased by (1 << 15) for each writer waiting to acquire the + # write lock, and by (1 << 29) if the write lock is taken + # + # Additionally, each thread uses a thread-local variable to count how many times + # it has acquired a read lock, AND how many times it has acquired a write lock. + # It uses a similar trick; an increment of 1 means a read lock was taken, and + # an increment of (1 << 15) means a write lock was taken + # This is what makes re-entrancy possible + # + # 2 rules are followed to ensure good liveness properties: + # 1) Once a writer has queued up and is waiting for a write lock, no other thread + # can take a lock without waiting + # 2) When a write lock is released, readers are given the "first chance" to wake + # up and acquire a read lock + # Following these rules means readers and writers tend to "take turns", so neither + # can starve the other, even under heavy contention + + # @!visibility private + READER_BITS = 15 + # @!visibility private + WRITER_BITS = 14 + + # Used with @Counter: + # @!visibility private + WAITING_WRITER = 1 << READER_BITS + # @!visibility private + RUNNING_WRITER = 1 << (READER_BITS + WRITER_BITS) + # @!visibility private + MAX_READERS = WAITING_WRITER - 1 + # @!visibility private + MAX_WRITERS = RUNNING_WRITER - MAX_READERS - 1 + + # Used with @HeldCount: + # @!visibility private + WRITE_LOCK_HELD = 1 << READER_BITS + # @!visibility private + READ_LOCK_MASK = WRITE_LOCK_HELD - 1 + # @!visibility private + WRITE_LOCK_MASK = MAX_WRITERS + + safe_initialization! + + # Create a new `ReentrantReadWriteLock` in the unlocked state. + def initialize + super() + @Counter = AtomicFixnum.new(0) # single integer which represents lock state + @ReadQueue = Synchronization::Lock.new # used to queue waiting readers + @WriteQueue = Synchronization::Lock.new # used to queue waiting writers + @HeldCount = LockLocalVar.new(0) # indicates # of R & W locks held by this thread + end + + # Execute a block operation within a read lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_read_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_read_lock + begin + yield + ensure + release_read_lock + end + end + + # Execute a block operation within a write lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_write_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_write_lock + begin + yield + ensure + release_write_lock + end + end + + # Acquire a read lock. If a write lock is held by another thread, will block + # until it is released. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # or per-thread reentrant acquires is exceeded. + def acquire_read_lock + if (held = @HeldCount.value) > 0 + raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK + + # If we already have a lock, there's no need to wait + if held & READ_LOCK_MASK == 0 + # But we do need to update the counter, if we were holding a write + # lock but not a read lock + @Counter.update { |c| c + 1 } + end + @HeldCount.value = held + 1 + return true + end + + while true + c = @Counter.value + raise ResourceLimitError.new('Too many reader threads') if max_readers?(c) + + # If a writer is waiting OR running when we first queue up, we need to wait + if waiting_or_running_writer?(c) + # Before going to sleep, check again with the ReadQueue mutex held + @ReadQueue.synchronize do + @ReadQueue.ns_wait if waiting_or_running_writer? + end + # Note: the above 'synchronize' block could have used #wait_until, + # but that waits repeatedly in a loop, checking the wait condition + # each time it wakes up (to protect against spurious wakeups) + # But we are already in a loop, which is only broken when we successfully + # acquire the lock! So we don't care about spurious wakeups, and would + # rather not pay the extra overhead of using #wait_until + + # After a reader has waited once, they are allowed to "barge" ahead of waiting writers + # But if a writer is *running*, the reader still needs to wait (naturally) + while true + c = @Counter.value + if running_writer?(c) + @ReadQueue.synchronize do + @ReadQueue.ns_wait if running_writer? + end + elsif @Counter.compare_and_set(c, c+1) + @HeldCount.value = held + 1 + return true + end + end + elsif @Counter.compare_and_set(c, c+1) + @HeldCount.value = held + 1 + return true + end + end + end + + # Try to acquire a read lock and return true if we succeed. If it cannot be + # acquired immediately, return false. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of per-thread + # reentrant acquires is exceeded. + def try_read_lock + if (held = @HeldCount.value) > 0 + raise ResourceLimitError.new('Too many reader holds on this thread') if (held & READ_LOCK_MASK) == READ_LOCK_MASK + + if held & READ_LOCK_MASK == 0 + # If we hold a write lock, but not a read lock... + @Counter.update { |c| c + 1 } + end + @HeldCount.value = held + 1 + return true + else + c = @Counter.value + if !waiting_or_running_writer?(c) && @Counter.compare_and_set(c, c+1) + @HeldCount.value = held + 1 + return true + end + end + false + end + + # Release a previously acquired read lock. + # + # @return [Boolean] true if the lock is successfully released + def release_read_lock + held = @HeldCount.value = @HeldCount.value - 1 + rlocks_held = held & READ_LOCK_MASK + if rlocks_held == 0 + c = @Counter.update { |counter| counter - 1 } + # If one or more writers were waiting, and we were the last reader, wake a writer up + if waiting_or_running_writer?(c) && running_readers(c) == 0 + @WriteQueue.signal + end + elsif rlocks_held == READ_LOCK_MASK + raise IllegalOperationError, "Cannot release a read lock which is not held" + end + true + end + + # Acquire a write lock. Will block and wait for all active readers and writers. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of writers + # is exceeded. + def acquire_write_lock + if (held = @HeldCount.value) >= WRITE_LOCK_HELD + # if we already have a write (exclusive) lock, there's no need to wait + @HeldCount.value = held + WRITE_LOCK_HELD + return true + end + + while true + c = @Counter.value + raise ResourceLimitError.new('Too many writer threads') if max_writers?(c) + + # To go ahead and take the lock without waiting, there must be no writer + # running right now, AND no writers who came before us still waiting to + # acquire the lock + # Additionally, if any read locks have been taken, we must hold all of them + if held > 0 && @Counter.compare_and_set(1, c+RUNNING_WRITER) + # If we are the only one reader and successfully swap the RUNNING_WRITER bit on, then we can go ahead + @HeldCount.value = held + WRITE_LOCK_HELD + return true + elsif @Counter.compare_and_set(c, c+WAITING_WRITER) + while true + # Now we have successfully incremented, so no more readers will be able to increment + # (they will wait instead) + # However, readers OR writers could decrement right here + @WriteQueue.synchronize do + # So we have to do another check inside the synchronized section + # If a writer OR another reader is running, then go to sleep + c = @Counter.value + @WriteQueue.ns_wait if running_writer?(c) || running_readers(c) != held + end + # Note: if you are thinking of replacing the above 'synchronize' block + # with #wait_until, read the comment in #acquire_read_lock first! + + # We just came out of a wait + # If we successfully turn the RUNNING_WRITER bit on with an atomic swap, + # then we are OK to stop waiting and go ahead + # Otherwise go back and wait again + c = @Counter.value + if !running_writer?(c) && + running_readers(c) == held && + @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER) + @HeldCount.value = held + WRITE_LOCK_HELD + return true + end + end + end + end + end + + # Try to acquire a write lock and return true if we succeed. If it cannot be + # acquired immediately, return false. + # + # @return [Boolean] true if the lock is successfully acquired + def try_write_lock + if (held = @HeldCount.value) >= WRITE_LOCK_HELD + @HeldCount.value = held + WRITE_LOCK_HELD + return true + else + c = @Counter.value + if !waiting_or_running_writer?(c) && + running_readers(c) == held && + @Counter.compare_and_set(c, c+RUNNING_WRITER) + @HeldCount.value = held + WRITE_LOCK_HELD + return true + end + end + false + end + + # Release a previously acquired write lock. + # + # @return [Boolean] true if the lock is successfully released + def release_write_lock + held = @HeldCount.value = @HeldCount.value - WRITE_LOCK_HELD + wlocks_held = held & WRITE_LOCK_MASK + if wlocks_held == 0 + c = @Counter.update { |counter| counter - RUNNING_WRITER } + @ReadQueue.broadcast + @WriteQueue.signal if waiting_writers(c) > 0 + elsif wlocks_held == WRITE_LOCK_MASK + raise IllegalOperationError, "Cannot release a write lock which is not held" + end + true + end + + private + + # @!visibility private + def running_readers(c = @Counter.value) + c & MAX_READERS + end + + # @!visibility private + def running_readers?(c = @Counter.value) + (c & MAX_READERS) > 0 + end + + # @!visibility private + def running_writer?(c = @Counter.value) + c >= RUNNING_WRITER + end + + # @!visibility private + def waiting_writers(c = @Counter.value) + (c & MAX_WRITERS) >> READER_BITS + end + + # @!visibility private + def waiting_or_running_writer?(c = @Counter.value) + c >= WAITING_WRITER + end + + # @!visibility private + def max_readers?(c = @Counter.value) + (c & MAX_READERS) == MAX_READERS + end + + # @!visibility private + def max_writers?(c = @Counter.value) + (c & MAX_WRITERS) == MAX_WRITERS + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/semaphore.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/semaphore.rb new file mode 100644 index 0000000..f0799f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/semaphore.rb @@ -0,0 +1,163 @@ +require 'concurrent/atomic/mutex_semaphore' + +module Concurrent + + ################################################################### + + # @!macro semaphore_method_initialize + # + # Create a new `Semaphore` with the initial `count`. + # + # @param [Fixnum] count the initial count + # + # @raise [ArgumentError] if `count` is not an integer + + # @!macro semaphore_method_acquire + # + # Acquires the given number of permits from this semaphore, + # blocking until all are available. If a block is given, + # yields to it and releases the permits afterwards. + # + # @param [Fixnum] permits Number of permits to acquire + # + # @raise [ArgumentError] if `permits` is not an integer or is less than zero + # + # @return [nil, BasicObject] Without a block, `nil` is returned. If a block + # is given, its return value is returned. + + # @!macro semaphore_method_available_permits + # + # Returns the current number of permits available in this semaphore. + # + # @return [Integer] + + # @!macro semaphore_method_drain_permits + # + # Acquires and returns all permits that are immediately available. + # + # @return [Integer] + + # @!macro semaphore_method_try_acquire + # + # Acquires the given number of permits from this semaphore, + # only if all are available at the time of invocation or within + # `timeout` interval. If a block is given, yields to it if the permits + # were successfully acquired, and releases them afterward, returning the + # block's return value. + # + # @param [Fixnum] permits the number of permits to acquire + # + # @param [Fixnum] timeout the number of seconds to wait for the counter + # or `nil` to return immediately + # + # @raise [ArgumentError] if `permits` is not an integer or is less than zero + # + # @return [true, false, nil, BasicObject] `false` if no permits are + # available, `true` when acquired a permit. If a block is given, the + # block's return value is returned if the permits were acquired; if not, + # `nil` is returned. + + # @!macro semaphore_method_release + # + # Releases the given number of permits, returning them to the semaphore. + # + # @param [Fixnum] permits Number of permits to return to the semaphore. + # + # @raise [ArgumentError] if `permits` is not a number or is less than zero + # + # @return [nil] + + ################################################################### + + # @!macro semaphore_public_api + # + # @!method initialize(count) + # @!macro semaphore_method_initialize + # + # @!method acquire(permits = 1) + # @!macro semaphore_method_acquire + # + # @!method available_permits + # @!macro semaphore_method_available_permits + # + # @!method drain_permits + # @!macro semaphore_method_drain_permits + # + # @!method try_acquire(permits = 1, timeout = nil) + # @!macro semaphore_method_try_acquire + # + # @!method release(permits = 1) + # @!macro semaphore_method_release + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + SemaphoreImplementation = if Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + JavaSemaphore + else + MutexSemaphore + end + private_constant :SemaphoreImplementation + + # @!macro semaphore + # + # A counting semaphore. Conceptually, a semaphore maintains a set of + # permits. Each {#acquire} blocks if necessary until a permit is + # available, and then takes it. Each {#release} adds a permit, potentially + # releasing a blocking acquirer. + # However, no actual permit objects are used; the Semaphore just keeps a + # count of the number available and acts accordingly. + # Alternatively, permits may be acquired within a block, and automatically + # released after the block finishes executing. + # + # @!macro semaphore_public_api + # @example + # semaphore = Concurrent::Semaphore.new(2) + # + # t1 = Thread.new do + # semaphore.acquire + # puts "Thread 1 acquired semaphore" + # end + # + # t2 = Thread.new do + # semaphore.acquire + # puts "Thread 2 acquired semaphore" + # end + # + # t3 = Thread.new do + # semaphore.acquire + # puts "Thread 3 acquired semaphore" + # end + # + # t4 = Thread.new do + # sleep(2) + # puts "Thread 4 releasing semaphore" + # semaphore.release + # end + # + # [t1, t2, t3, t4].each(&:join) + # + # # prints: + # # Thread 3 acquired semaphore + # # Thread 2 acquired semaphore + # # Thread 4 releasing semaphore + # # Thread 1 acquired semaphore + # + # @example + # semaphore = Concurrent::Semaphore.new(1) + # + # puts semaphore.available_permits + # semaphore.acquire do + # puts semaphore.available_permits + # end + # puts semaphore.available_permits + # + # # prints: + # # 1 + # # 0 + # # 1 + class Semaphore < SemaphoreImplementation + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb new file mode 100644 index 0000000..3b7e12b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb @@ -0,0 +1,111 @@ +require 'concurrent/constants' +require_relative 'locals' + +module Concurrent + + # A `ThreadLocalVar` is a variable where the value is different for each thread. + # Each variable may have a default value, but when you modify the variable only + # the current thread will ever see that change. + # + # This is similar to Ruby's built-in thread-local variables (`Thread#thread_variable_get`), + # but with these major advantages: + # * `ThreadLocalVar` has its own identity, it doesn't need a Symbol. + # * Each Ruby's built-in thread-local variable leaks some memory forever (it's a Symbol held forever on the thread), + # so it's only OK to create a small amount of them. + # `ThreadLocalVar` has no such issue and it is fine to create many of them. + # * Ruby's built-in thread-local variables leak forever the value set on each thread (unless set to nil explicitly). + # `ThreadLocalVar` automatically removes the mapping for each thread once the `ThreadLocalVar` instance is GC'd. + # + # @!macro thread_safe_variable_comparison + # + # @example + # v = ThreadLocalVar.new(14) + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # + # @example + # v = ThreadLocalVar.new(14) + # + # t1 = Thread.new do + # v.value #=> 14 + # v.value = 1 + # v.value #=> 1 + # end + # + # t2 = Thread.new do + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # end + # + # v.value #=> 14 + class ThreadLocalVar + LOCALS = ThreadLocals.new + + # Creates a thread local variable. + # + # @param [Object] default the default value when otherwise unset + # @param [Proc] default_block Optional block that gets called to obtain the + # default value for each thread + def initialize(default = nil, &default_block) + if default && block_given? + raise ArgumentError, "Cannot use both value and block as default value" + end + + if block_given? + @default_block = default_block + @default = nil + else + @default_block = nil + @default = default + end + + @index = LOCALS.next_index(self) + end + + # Returns the value in the current thread's copy of this thread-local variable. + # + # @return [Object] the current value + def value + LOCALS.fetch(@index) { default } + end + + # Sets the current thread's copy of this thread-local variable to the specified value. + # + # @param [Object] value the value to set + # @return [Object] the new value + def value=(value) + LOCALS.set(@index, value) + end + + # Bind the given value to thread local storage during + # execution of the given block. + # + # @param [Object] value the value to bind + # @yield the operation to be performed with the bound variable + # @return [Object] the value + def bind(value) + if block_given? + old_value = self.value + self.value = value + begin + yield + ensure + self.value = old_value + end + end + end + + protected + + # @!visibility private + def default + if @default_block + self.value = @default_block.call + else + @default + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb new file mode 100644 index 0000000..5d2d7ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb @@ -0,0 +1,37 @@ +require 'concurrent/errors' + +module Concurrent + + # Define update methods that use direct paths + # + # @!visibility private + # @!macro internal_implementation_note + module AtomicDirectUpdate + def update + true until compare_and_set(old_value = get, new_value = yield(old_value)) + new_value + end + + def try_update + old_value = get + new_value = yield old_value + + return unless compare_and_set old_value, new_value + + new_value + end + + def try_update! + old_value = get + new_value = yield old_value + unless compare_and_set(old_value, new_value) + if $VERBOSE + raise ConcurrentUpdateError, "Update failed" + else + raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE + end + end + new_value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb new file mode 100644 index 0000000..ecd1695 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb @@ -0,0 +1,66 @@ +require 'concurrent/atomic_reference/atomic_direct_update' +require 'concurrent/atomic_reference/numeric_cas_wrapper' +require 'concurrent/synchronization/safe_initialization' + +module Concurrent + + # @!visibility private + # @!macro internal_implementation_note + class MutexAtomicReference + extend Concurrent::Synchronization::SafeInitialization + include AtomicDirectUpdate + include AtomicNumericCompareAndSetWrapper + + # @!macro atomic_reference_method_initialize + def initialize(value = nil) + super() + @Lock = ::Mutex.new + @value = value + end + + # @!macro atomic_reference_method_get + def get + synchronize { @value } + end + alias_method :value, :get + + # @!macro atomic_reference_method_set + def set(new_value) + synchronize { @value = new_value } + end + alias_method :value=, :set + + # @!macro atomic_reference_method_get_and_set + def get_and_set(new_value) + synchronize do + old_value = @value + @value = new_value + old_value + end + end + alias_method :swap, :get_and_set + + # @!macro atomic_reference_method_compare_and_set + private def _compare_and_set(old_value, new_value) + synchronize do + if @value.equal? old_value + @value = new_value + true + else + false + end + end + end + + protected + + # @!visibility private + def synchronize + if @Lock.owned? + yield + else + @Lock.synchronize { yield } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb new file mode 100644 index 0000000..438592f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb @@ -0,0 +1,36 @@ +module Concurrent + + # Special "compare and set" handling of numeric values. + # + # @!visibility private + # @!macro internal_implementation_note + module AtomicNumericCompareAndSetWrapper + + # @!macro atomic_reference_method_compare_and_set + def compare_and_set(old_value, new_value) + if old_value.kind_of? Numeric + # NaN is never == to itself; match it explicitly so #update can terminate. + expected_nan = old_value.respond_to?(:nan?) && old_value.nan? + while true + old = get + + return false unless old.kind_of? Numeric + + if expected_nan + return false unless old.respond_to?(:nan?) && old.nan? + else + return false unless old == old_value + end + + result = _compare_and_set(old, new_value) + return result if result + end + else + _compare_and_set(old_value, new_value) + end + end + + alias_method :compare_and_swap, :compare_and_set + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomics.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomics.rb new file mode 100644 index 0000000..16cbe66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/atomics.rb @@ -0,0 +1,10 @@ +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/atomic/cyclic_barrier' +require 'concurrent/atomic/count_down_latch' +require 'concurrent/atomic/event' +require 'concurrent/atomic/read_write_lock' +require 'concurrent/atomic/reentrant_read_write_lock' +require 'concurrent/atomic/semaphore' +require 'concurrent/atomic/thread_local_var' diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb new file mode 100644 index 0000000..7c700bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb @@ -0,0 +1,107 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Collection + + # A thread safe observer set implemented using copy-on-read approach: + # observers are added and removed from a thread safe collection; every time + # a notification is required the internal data structure is copied to + # prevent concurrency issues + # + # @api private + class CopyOnNotifyObserverSet < Synchronization::LockableObject + + def initialize + super() + synchronize { ns_initialize } + end + + # @!macro observable_add_observer + def add_observer(observer = nil, func = :update, &block) + if observer.nil? && block.nil? + raise ArgumentError, 'should pass observer as a first argument or block' + elsif observer && block + raise ArgumentError.new('cannot provide both an observer and a block') + end + + if block + observer = block + func = :call + end + + synchronize do + @observers[observer] = func + observer + end + end + + # @!macro observable_delete_observer + def delete_observer(observer) + synchronize do + @observers.delete(observer) + observer + end + end + + # @!macro observable_delete_observers + def delete_observers + synchronize do + @observers.clear + self + end + end + + # @!macro observable_count_observers + def count_observers + synchronize { @observers.count } + end + + # Notifies all registered observers with optional args + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_observers(*args, &block) + observers = duplicate_observers + notify_to(observers, *args, &block) + self + end + + # Notifies all registered observers with optional args and deletes them. + # + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_and_delete_observers(*args, &block) + observers = duplicate_and_clear_observers + notify_to(observers, *args, &block) + self + end + + protected + + def ns_initialize + @observers = {} + end + + private + + def duplicate_and_clear_observers + synchronize do + observers = @observers.dup + @observers.clear + observers + end + end + + def duplicate_observers + synchronize { @observers.dup } + end + + def notify_to(observers, *args) + raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty? + observers.each do |observer, function| + args = yield if block_given? + observer.send(function, *args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb new file mode 100644 index 0000000..bcb6750 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb @@ -0,0 +1,111 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Collection + + # A thread safe observer set implemented using copy-on-write approach: + # every time an observer is added or removed the whole internal data structure is + # duplicated and replaced with a new one. + # + # @api private + class CopyOnWriteObserverSet < Synchronization::LockableObject + + def initialize + super() + synchronize { ns_initialize } + end + + # @!macro observable_add_observer + def add_observer(observer = nil, func = :update, &block) + if observer.nil? && block.nil? + raise ArgumentError, 'should pass observer as a first argument or block' + elsif observer && block + raise ArgumentError.new('cannot provide both an observer and a block') + end + + if block + observer = block + func = :call + end + + synchronize do + new_observers = @observers.dup + new_observers[observer] = func + @observers = new_observers + observer + end + end + + # @!macro observable_delete_observer + def delete_observer(observer) + synchronize do + new_observers = @observers.dup + new_observers.delete(observer) + @observers = new_observers + observer + end + end + + # @!macro observable_delete_observers + def delete_observers + self.observers = {} + self + end + + # @!macro observable_count_observers + def count_observers + observers.count + end + + # Notifies all registered observers with optional args + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_observers(*args, &block) + notify_to(observers, *args, &block) + self + end + + # Notifies all registered observers with optional args and deletes them. + # + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_and_delete_observers(*args, &block) + old = clear_observers_and_return_old + notify_to(old, *args, &block) + self + end + + protected + + def ns_initialize + @observers = {} + end + + private + + def notify_to(observers, *args) + raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty? + observers.each do |observer, function| + args = yield if block_given? + observer.send(function, *args) + end + end + + def observers + synchronize { @observers } + end + + def observers=(new_set) + synchronize { @observers = new_set } + end + + def clear_observers_and_return_old + synchronize do + old_observers = @observers + @observers = {} + old_observers + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb new file mode 100644 index 0000000..2be9e43 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb @@ -0,0 +1,84 @@ +if Concurrent.on_jruby? + + module Concurrent + module Collection + + + # @!macro priority_queue + # + # @!visibility private + # @!macro internal_implementation_note + class JavaNonConcurrentPriorityQueue + + # @!macro priority_queue_method_initialize + def initialize(opts = {}) + order = opts.fetch(:order, :max) + if [:min, :low].include?(order) + @queue = java.util.PriorityQueue.new(11) # 11 is the default initial capacity + else + @queue = java.util.PriorityQueue.new(11, java.util.Collections.reverseOrder()) + end + end + + # @!macro priority_queue_method_clear + def clear + @queue.clear + true + end + + # @!macro priority_queue_method_delete + def delete(item) + found = false + while @queue.remove(item) do + found = true + end + found + end + + # @!macro priority_queue_method_empty + def empty? + @queue.size == 0 + end + + # @!macro priority_queue_method_include + def include?(item) + @queue.contains(item) + end + alias_method :has_priority?, :include? + + # @!macro priority_queue_method_length + def length + @queue.size + end + alias_method :size, :length + + # @!macro priority_queue_method_peek + def peek + @queue.peek + end + + # @!macro priority_queue_method_pop + def pop + @queue.poll + end + alias_method :deq, :pop + alias_method :shift, :pop + + # @!macro priority_queue_method_push + def push(item) + raise ArgumentError.new('cannot enqueue nil') if item.nil? + @queue.add(item) + end + alias_method :<<, :push + alias_method :enq, :push + + # @!macro priority_queue_method_from_list + def self.from_list(list, opts = {}) + queue = new(opts) + list.each{|item| queue << item } + queue + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb new file mode 100644 index 0000000..3704410 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb @@ -0,0 +1,160 @@ +require 'concurrent/synchronization/object' + +module Concurrent + + # @!macro warn.edge + class LockFreeStack < Synchronization::Object + + safe_initialization! + + class Node + # TODO (pitr-ch 20-Dec-2016): Could be unified with Stack class? + + # @return [Node] + attr_reader :next_node + + # @return [Object] + attr_reader :value + + # @!visibility private + # allow to nil-ify to free GC when the entry is no longer relevant, not synchronised + attr_writer :value + + def initialize(value, next_node) + @value = value + @next_node = next_node + end + + singleton_class.send :alias_method, :[], :new + end + + # The singleton for empty node + EMPTY = Node[nil, nil] + def EMPTY.next_node + self + end + + attr_atomic(:head) + private :head, :head=, :swap_head, :compare_and_set_head, :update_head + + # @!visibility private + def self.of1(value) + new Node[value, EMPTY] + end + + # @!visibility private + def self.of2(value1, value2) + new Node[value1, Node[value2, EMPTY]] + end + + # @param [Node] head + def initialize(head = EMPTY) + super() + self.head = head + end + + # @param [Node] head + # @return [true, false] + def empty?(head = head()) + head.equal? EMPTY + end + + # @param [Node] head + # @param [Object] value + # @return [true, false] + def compare_and_push(head, value) + compare_and_set_head head, Node[value, head] + end + + # @param [Object] value + # @return [self] + def push(value) + while true + current_head = head + return self if compare_and_set_head current_head, Node[value, current_head] + end + end + + # @return [Node] + def peek + head + end + + # @param [Node] head + # @return [true, false] + def compare_and_pop(head) + compare_and_set_head head, head.next_node + end + + # @return [Object] + def pop + while true + current_head = head + return current_head.value if compare_and_set_head current_head, current_head.next_node + end + end + + # @param [Node] head + # @return [true, false] + def compare_and_clear(head) + compare_and_set_head head, EMPTY + end + + include Enumerable + + # @param [Node] head + # @return [self] + def each(head = nil) + return to_enum(:each, head) unless block_given? + it = head || peek + until it.equal?(EMPTY) + yield it.value + it = it.next_node + end + self + end + + # @return [true, false] + def clear + while true + current_head = head + return false if current_head == EMPTY + return true if compare_and_set_head current_head, EMPTY + end + end + + # @param [Node] head + # @return [true, false] + def clear_if(head) + compare_and_set_head head, EMPTY + end + + # @param [Node] head + # @param [Node] new_head + # @return [true, false] + def replace_if(head, new_head) + compare_and_set_head head, new_head + end + + # @return [self] + # @yield over the cleared stack + # @yieldparam [Object] value + def clear_each(&block) + while true + current_head = head + return self if current_head == EMPTY + if compare_and_set_head current_head, EMPTY + each current_head, &block + return self + end + end + end + + # @return [String] Short string representation. + def to_s + format '%s %s>', super[0..-2], to_a.to_s + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb new file mode 100644 index 0000000..e0cf999 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb @@ -0,0 +1,66 @@ +require 'thread' +require 'concurrent/collection/map/non_concurrent_map_backend' + +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class MriMapBackend < NonConcurrentMapBackend + + def initialize(options = nil, &default_proc) + super(options, &default_proc) + @write_lock = Mutex.new + end + + def []=(key, value) + @write_lock.synchronize { super } + end + + def compute_if_absent(key) + if NULL != (stored_value = @backend.fetch(key, NULL)) # fast non-blocking path for the most likely case + stored_value + else + @write_lock.synchronize { super } + end + end + + def compute_if_present(key) + @write_lock.synchronize { super } + end + + def compute(key) + @write_lock.synchronize { super } + end + + def merge_pair(key, value) + @write_lock.synchronize { super } + end + + def replace_pair(key, old_value, new_value) + @write_lock.synchronize { super } + end + + def replace_if_exists(key, new_value) + @write_lock.synchronize { super } + end + + def get_and_set(key, value) + @write_lock.synchronize { super } + end + + def delete(key) + @write_lock.synchronize { super } + end + + def delete_pair(key, value) + @write_lock.synchronize { super } + end + + def clear + @write_lock.synchronize { super } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb new file mode 100644 index 0000000..ca5fd9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb @@ -0,0 +1,148 @@ +require 'concurrent/constants' + +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class NonConcurrentMapBackend + + # WARNING: all public methods of the class must operate on the @backend + # directly without calling each other. This is important because of the + # SynchronizedMapBackend which uses a non-reentrant mutex for performance + # reasons. + def initialize(options = nil, &default_proc) + validate_options_hash!(options) if options.kind_of?(::Hash) + set_backend(default_proc) + @default_proc = default_proc + end + + def [](key) + @backend[key] + end + + def []=(key, value) + @backend[key] = value + end + + def compute_if_absent(key) + if NULL != (stored_value = @backend.fetch(key, NULL)) + stored_value + else + @backend[key] = yield + end + end + + def replace_pair(key, old_value, new_value) + if pair?(key, old_value) + @backend[key] = new_value + true + else + false + end + end + + def replace_if_exists(key, new_value) + if NULL != (stored_value = @backend.fetch(key, NULL)) + @backend[key] = new_value + stored_value + end + end + + def compute_if_present(key) + if NULL != (stored_value = @backend.fetch(key, NULL)) + store_computed_value(key, yield(stored_value)) + end + end + + def compute(key) + store_computed_value(key, yield(get_or_default(key, nil))) + end + + def merge_pair(key, value) + if NULL == (stored_value = @backend.fetch(key, NULL)) + @backend[key] = value + else + store_computed_value(key, yield(stored_value)) + end + end + + def get_and_set(key, value) + stored_value = get_or_default(key, nil) + @backend[key] = value + stored_value + end + + def key?(key) + @backend.key?(key) + end + + def delete(key) + @backend.delete(key) + end + + def delete_pair(key, value) + if pair?(key, value) + @backend.delete(key) + true + else + false + end + end + + def clear + @backend.clear + self + end + + def each_pair + dupped_backend.each_pair do |k, v| + yield k, v + end + self + end + + def size + @backend.size + end + + def get_or_default(key, default_value) + @backend.fetch(key, default_value) + end + + private + + def set_backend(default_proc) + if default_proc + @backend = ::Hash.new { |_h, key| default_proc.call(self, key) } + else + @backend = {} + end + end + + def initialize_copy(other) + super + set_backend(@default_proc) + self + end + + def dupped_backend + @backend.dup + end + + def pair?(key, expected_value) + NULL != (stored_value = @backend.fetch(key, NULL)) && expected_value.equal?(stored_value) + end + + def store_computed_value(key, new_value) + if new_value.nil? + @backend.delete(key) + nil + else + @backend[key] = new_value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb new file mode 100644 index 0000000..efa161e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb @@ -0,0 +1,85 @@ +require 'concurrent/collection/map/non_concurrent_map_backend' + +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class SynchronizedMapBackend < NonConcurrentMapBackend + + def initialize(*args, &block) + super + + # WARNING: Mutex is a non-reentrant lock, so the synchronized methods are + # not allowed to call each other. + @mutex = Mutex.new + end + + def [](key) + @mutex.synchronize { super } + end + + def []=(key, value) + @mutex.synchronize { super } + end + + def compute_if_absent(key) + @mutex.synchronize { super } + end + + def compute_if_present(key) + @mutex.synchronize { super } + end + + def compute(key) + @mutex.synchronize { super } + end + + def merge_pair(key, value) + @mutex.synchronize { super } + end + + def replace_pair(key, old_value, new_value) + @mutex.synchronize { super } + end + + def replace_if_exists(key, new_value) + @mutex.synchronize { super } + end + + def get_and_set(key, value) + @mutex.synchronize { super } + end + + def key?(key) + @mutex.synchronize { super } + end + + def delete(key) + @mutex.synchronize { super } + end + + def delete_pair(key, value) + @mutex.synchronize { super } + end + + def clear + @mutex.synchronize { super } + end + + def size + @mutex.synchronize { super } + end + + def get_or_default(key, default_value) + @mutex.synchronize { super } + end + + private + def dupped_backend + @mutex.synchronize { super } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb new file mode 100644 index 0000000..68a1b38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb @@ -0,0 +1,14 @@ +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class TruffleRubyMapBackend < TruffleRuby::ConcurrentMap + def initialize(options = nil) + options ||= {} + super(initial_capacity: options[:initial_capacity], load_factor: options[:load_factor]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb new file mode 100644 index 0000000..694cd7a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb @@ -0,0 +1,143 @@ +require 'concurrent/utility/engine' +require 'concurrent/collection/java_non_concurrent_priority_queue' +require 'concurrent/collection/ruby_non_concurrent_priority_queue' + +module Concurrent + module Collection + + # @!visibility private + # @!macro internal_implementation_note + NonConcurrentPriorityQueueImplementation = case + when Concurrent.on_jruby? + JavaNonConcurrentPriorityQueue + else + RubyNonConcurrentPriorityQueue + end + private_constant :NonConcurrentPriorityQueueImplementation + + # @!macro priority_queue + # + # A queue collection in which the elements are sorted based on their + # comparison (spaceship) operator `<=>`. Items are added to the queue + # at a position relative to their priority. On removal the element + # with the "highest" priority is removed. By default the sort order is + # from highest to lowest, but a lowest-to-highest sort order can be + # set on construction. + # + # The API is based on the `Queue` class from the Ruby standard library. + # + # The pure Ruby implementation, `RubyNonConcurrentPriorityQueue` uses a heap algorithm + # stored in an array. The algorithm is based on the work of Robert Sedgewick + # and Kevin Wayne. + # + # The JRuby native implementation is a thin wrapper around the standard + # library `java.util.NonConcurrentPriorityQueue`. + # + # When running under JRuby the class `NonConcurrentPriorityQueue` extends `JavaNonConcurrentPriorityQueue`. + # When running under all other interpreters it extends `RubyNonConcurrentPriorityQueue`. + # + # @note This implementation is *not* thread safe. + # + # @see http://en.wikipedia.org/wiki/Priority_queue + # @see http://ruby-doc.org/stdlib-2.0.0/libdoc/thread/rdoc/Queue.html + # + # @see http://algs4.cs.princeton.edu/24pq/index.php#2.6 + # @see http://algs4.cs.princeton.edu/24pq/MaxPQ.java.html + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html + # + # @!visibility private + class NonConcurrentPriorityQueue < NonConcurrentPriorityQueueImplementation + + alias_method :has_priority?, :include? + + alias_method :size, :length + + alias_method :deq, :pop + alias_method :shift, :pop + + alias_method :<<, :push + alias_method :enq, :push + + # @!method initialize(opts = {}) + # @!macro priority_queue_method_initialize + # + # Create a new priority queue with no items. + # + # @param [Hash] opts the options for creating the queue + # @option opts [Symbol] :order (:max) dictates the order in which items are + # stored: from highest to lowest when `:max` or `:high`; from lowest to + # highest when `:min` or `:low` + + # @!method clear + # @!macro priority_queue_method_clear + # + # Removes all of the elements from this priority queue. + + # @!method delete(item) + # @!macro priority_queue_method_delete + # + # Deletes all items from `self` that are equal to `item`. + # + # @param [Object] item the item to be removed from the queue + # @return [Object] true if the item is found else false + + # @!method empty? + # @!macro priority_queue_method_empty + # + # Returns `true` if `self` contains no elements. + # + # @return [Boolean] true if there are no items in the queue else false + + # @!method include?(item) + # @!macro priority_queue_method_include + # + # Returns `true` if the given item is present in `self` (that is, if any + # element == `item`), otherwise returns false. + # + # @param [Object] item the item to search for + # + # @return [Boolean] true if the item is found else false + + # @!method length + # @!macro priority_queue_method_length + # + # The current length of the queue. + # + # @return [Fixnum] the number of items in the queue + + # @!method peek + # @!macro priority_queue_method_peek + # + # Retrieves, but does not remove, the head of this queue, or returns `nil` + # if this queue is empty. + # + # @return [Object] the head of the queue or `nil` when empty + + # @!method pop + # @!macro priority_queue_method_pop + # + # Retrieves and removes the head of this queue, or returns `nil` if this + # queue is empty. + # + # @return [Object] the head of the queue or `nil` when empty + + # @!method push(item) + # @!macro priority_queue_method_push + # + # Inserts the specified element into this priority queue. + # + # @param [Object] item the item to insert onto the queue + + # @!method self.from_list(list, opts = {}) + # @!macro priority_queue_method_from_list + # + # Create a new priority queue from the given list. + # + # @param [Enumerable] list the list to build the queue from + # @param [Hash] opts the options for creating the queue + # + # @return [NonConcurrentPriorityQueue] the newly created and populated queue + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb new file mode 100644 index 0000000..322b4ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb @@ -0,0 +1,160 @@ +module Concurrent + module Collection + + # @!macro priority_queue + # + # @!visibility private + # @!macro internal_implementation_note + class RubyNonConcurrentPriorityQueue + + # @!macro priority_queue_method_initialize + def initialize(opts = {}) + order = opts.fetch(:order, :max) + @comparator = [:min, :low].include?(order) ? -1 : 1 + clear + end + + # @!macro priority_queue_method_clear + def clear + @queue = [nil] + @length = 0 + true + end + + # @!macro priority_queue_method_delete + def delete(item) + return false if empty? + original_length = @length + k = 1 + while k <= @length + if @queue[k] == item + swap(k, @length) + @length -= 1 + sink(k) || swim(k) + @queue.pop + else + k += 1 + end + end + @length != original_length + end + + # @!macro priority_queue_method_empty + def empty? + size == 0 + end + + # @!macro priority_queue_method_include + def include?(item) + @queue.include?(item) + end + alias_method :has_priority?, :include? + + # @!macro priority_queue_method_length + def length + @length + end + alias_method :size, :length + + # @!macro priority_queue_method_peek + def peek + empty? ? nil : @queue[1] + end + + # @!macro priority_queue_method_pop + def pop + return nil if empty? + max = @queue[1] + swap(1, @length) + @length -= 1 + sink(1) + @queue.pop + max + end + alias_method :deq, :pop + alias_method :shift, :pop + + # @!macro priority_queue_method_push + def push(item) + raise ArgumentError.new('cannot enqueue nil') if item.nil? + @length += 1 + @queue << item + swim(@length) + true + end + alias_method :<<, :push + alias_method :enq, :push + + # @!macro priority_queue_method_from_list + def self.from_list(list, opts = {}) + queue = new(opts) + list.each{|item| queue << item } + queue + end + + private + + # Exchange the values at the given indexes within the internal array. + # + # @param [Integer] x the first index to swap + # @param [Integer] y the second index to swap + # + # @!visibility private + def swap(x, y) + temp = @queue[x] + @queue[x] = @queue[y] + @queue[y] = temp + end + + # Are the items at the given indexes ordered based on the priority + # order specified at construction? + # + # @param [Integer] x the first index from which to retrieve a comparable value + # @param [Integer] y the second index from which to retrieve a comparable value + # + # @return [Boolean] true if the two elements are in the correct priority order + # else false + # + # @!visibility private + def ordered?(x, y) + (@queue[x] <=> @queue[y]) == @comparator + end + + # Percolate down to maintain heap invariant. + # + # @param [Integer] k the index at which to start the percolation + # + # @!visibility private + def sink(k) + success = false + + while (j = (2 * k)) <= @length do + j += 1 if j < @length && ! ordered?(j, j+1) + break if ordered?(k, j) + swap(k, j) + success = true + k = j + end + + success + end + + # Percolate up to maintain heap invariant. + # + # @param [Integer] k the index at which to start the percolation + # + # @!visibility private + def swim(k) + success = false + + while k > 1 && ! ordered?(k/2, k) do + swap(k, k/2) + k = k/2 + success = true + end + + success + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_timeout_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_timeout_queue.rb new file mode 100644 index 0000000..3cf5371 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/ruby_timeout_queue.rb @@ -0,0 +1,55 @@ +module Concurrent + module Collection + # @!visibility private + # @!macro ruby_timeout_queue + class RubyTimeoutQueue < ::Queue + def initialize(*args) + if RUBY_VERSION >= '3.2' + raise "#{self.class.name} is not needed on Ruby 3.2 or later, use ::Queue instead" + end + + super(*args) + + @mutex = Mutex.new + @cond_var = ConditionVariable.new + end + + def push(obj) + @mutex.synchronize do + super(obj) + @cond_var.signal + end + end + alias_method :enq, :push + alias_method :<<, :push + + def pop(non_block = false, timeout: nil) + if non_block && timeout + raise ArgumentError, "can't set a timeout if non_block is enabled" + end + + if non_block + super(true) + elsif timeout + @mutex.synchronize do + deadline = Concurrent.monotonic_time + timeout + while (now = Concurrent.monotonic_time) < deadline && empty? + @cond_var.wait(@mutex, deadline - now) + end + begin + return super(true) + rescue ThreadError + # still empty + nil + end + end + else + super(false) + end + end + alias_method :deq, :pop + alias_method :shift, :pop + end + private_constant :RubyTimeoutQueue + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/timeout_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/timeout_queue.rb new file mode 100644 index 0000000..7048c4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/collection/timeout_queue.rb @@ -0,0 +1,18 @@ +module Concurrent + module Collection + # @!visibility private + # @!macro internal_implementation_note + TimeoutQueueImplementation = if RUBY_VERSION >= '3.2' + ::Queue + else + require 'concurrent/collection/ruby_timeout_queue' + RubyTimeoutQueue + end + private_constant :TimeoutQueueImplementation + + # @!visibility private + # @!macro timeout_queue + class TimeoutQueue < TimeoutQueueImplementation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/deprecation.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/deprecation.rb new file mode 100644 index 0000000..35ae4b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/deprecation.rb @@ -0,0 +1,34 @@ +require 'concurrent/concern/logging' + +module Concurrent + module Concern + + # @!visibility private + # @!macro internal_implementation_note + module Deprecation + # TODO require additional parameter: a version. Display when it'll be removed based on that. Error if not removed. + include Concern::Logging + + def deprecated(message, strip = 2) + caller_line = caller(strip).first if strip > 0 + klass = if Module === self + self + else + self.class + end + message = if strip > 0 + format("[DEPRECATED] %s\ncalled on: %s", message, caller_line) + else + format('[DEPRECATED] %s', message) + end + log WARN, klass.to_s, message + end + + def deprecated_method(old_name, new_name) + deprecated "`#{old_name}` is deprecated and it'll removed in next release, use `#{new_name}` instead", 3 + end + + extend self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb new file mode 100644 index 0000000..dc172ba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb @@ -0,0 +1,73 @@ +module Concurrent + module Concern + + # Object references in Ruby are mutable. This can lead to serious problems when + # the `#value` of a concurrent object is a mutable reference. Which is always the + # case unless the value is a `Fixnum`, `Symbol`, or similar "primitive" data type. + # Most classes in this library that expose a `#value` getter method do so using the + # `Dereferenceable` mixin module. + # + # @!macro copy_options + module Dereferenceable + # NOTE: This module is going away in 2.0. In the mean time we need it to + # play nicely with the synchronization layer. This means that the + # including class SHOULD be synchronized and it MUST implement a + # `#synchronize` method. Not doing so will lead to runtime errors. + + # Return the value this object represents after applying the options specified + # by the `#set_deref_options` method. + # + # @return [Object] the current value of the object + def value + synchronize { apply_deref_options(@value) } + end + alias_method :deref, :value + + protected + + # Set the internal value of this object + # + # @param [Object] value the new value + def value=(value) + synchronize{ @value = value } + end + + # @!macro dereferenceable_set_deref_options + # Set the options which define the operations #value performs before + # returning data to the caller (dereferencing). + # + # @note Most classes that include this module will call `#set_deref_options` + # from within the constructor, thus allowing these options to be set at + # object creation. + # + # @param [Hash] opts the options defining dereference behavior. + # @option opts [String] :dup_on_deref (false) call `#dup` before returning the data + # @option opts [String] :freeze_on_deref (false) call `#freeze` before returning the data + # @option opts [String] :copy_on_deref (nil) call the given `Proc` passing + # the internal value and returning the value returned from the proc + def set_deref_options(opts = {}) + synchronize{ ns_set_deref_options(opts) } + end + + # @!macro dereferenceable_set_deref_options + # @!visibility private + def ns_set_deref_options(opts) + @dup_on_deref = opts[:dup_on_deref] || opts[:dup] + @freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze] + @copy_on_deref = opts[:copy_on_deref] || opts[:copy] + @do_nothing_on_deref = !(@dup_on_deref || @freeze_on_deref || @copy_on_deref) + nil + end + + # @!visibility private + def apply_deref_options(value) + return nil if value.nil? + return value if @do_nothing_on_deref + value = @copy_on_deref.call(value) if @copy_on_deref + value = value.dup if @dup_on_deref + value = value.freeze if @freeze_on_deref + value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/logging.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/logging.rb new file mode 100644 index 0000000..d1aae81 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/logging.rb @@ -0,0 +1,121 @@ +require 'concurrent/atomic/atomic_reference' + +module Concurrent + module Concern + + # Include where logging is needed + # + # @!visibility private + module Logging + # The same as Logger::Severity but we copy it here to avoid a dependency on the logger gem just for these 7 constants + DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN = 0, 1, 2, 3, 4, 5 + SEV_LABEL = %w[DEBUG INFO WARN ERROR FATAL ANY].freeze + + # Logs through {Concurrent.global_logger}, it can be overridden by setting @logger + # @param [Integer] level one of Concurrent::Concern::Logging constants + # @param [String] progname e.g. a path of an Actor + # @param [String, nil] message when nil block is used to generate the message + # @yieldreturn [String] a message + def log(level, progname, message = nil, &block) + logger = if defined?(@logger) && @logger + @logger + else + Concurrent.global_logger + end + logger.call level, progname, message, &block + rescue => error + $stderr.puts "`Concurrent.global_logger` failed to log #{[level, progname, message, block]}\n" + + "#{error.message} (#{error.class})\n#{error.backtrace.join "\n"}" + end + end + end +end + +module Concurrent + extend Concern::Logging + + # Create a simple logger with provided level and output. + def self.create_simple_logger(level = :FATAL, output = $stderr) + level = Concern::Logging.const_get(level) unless level.is_a?(Integer) + + # TODO (pitr-ch 24-Dec-2016): figure out why it had to be replaced, stdlogger was deadlocking + lambda do |severity, progname, message = nil, &block| + return false if severity < level + + message = block ? block.call : message + formatted_message = case message + when String + message + when Exception + format "%s (%s)\n%s", + message.message, message.class, (message.backtrace || []).join("\n") + else + message.inspect + end + + output.print format "[%s] %5s -- %s: %s\n", + Time.now.strftime('%Y-%m-%d %H:%M:%S.%L'), + Concern::Logging::SEV_LABEL[severity], + progname, + formatted_message + true + end + end + + # Use logger created by #create_simple_logger to log concurrent-ruby messages. + def self.use_simple_logger(level = :FATAL, output = $stderr) + Concurrent.global_logger = create_simple_logger level, output + end + + # Create a stdlib logger with provided level and output. + # If you use this deprecated method you might need to add logger to your Gemfile to avoid warnings from Ruby 3.3.5+. + # @deprecated + def self.create_stdlib_logger(level = :FATAL, output = $stderr) + require 'logger' + logger = Logger.new(output) + logger.level = level + logger.formatter = lambda do |severity, datetime, progname, msg| + formatted_message = case msg + when String + msg + when Exception + format "%s (%s)\n%s", + msg.message, msg.class, (msg.backtrace || []).join("\n") + else + msg.inspect + end + format "[%s] %5s -- %s: %s\n", + datetime.strftime('%Y-%m-%d %H:%M:%S.%L'), + severity, + progname, + formatted_message + end + + lambda do |loglevel, progname, message = nil, &block| + logger.add loglevel, message, progname, &block + end + end + + # Use logger created by #create_stdlib_logger to log concurrent-ruby messages. + # @deprecated + def self.use_stdlib_logger(level = :FATAL, output = $stderr) + Concurrent.global_logger = create_stdlib_logger level, output + end + + # TODO (pitr-ch 27-Dec-2016): remove deadlocking stdlib_logger methods + + # Suppresses all output when used for logging. + NULL_LOGGER = lambda { |level, progname, message = nil, &block| } + + # @!visibility private + GLOBAL_LOGGER = AtomicReference.new(create_simple_logger(:WARN)) + private_constant :GLOBAL_LOGGER + + def self.global_logger + GLOBAL_LOGGER.value + end + + def self.global_logger=(value) + GLOBAL_LOGGER.value = value + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/obligation.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/obligation.rb new file mode 100644 index 0000000..2c9ac12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/obligation.rb @@ -0,0 +1,220 @@ +require 'thread' +require 'timeout' + +require 'concurrent/atomic/event' +require 'concurrent/concern/dereferenceable' + +module Concurrent + module Concern + + module Obligation + include Concern::Dereferenceable + # NOTE: The Dereferenceable module is going away in 2.0. In the mean time + # we need it to place nicely with the synchronization layer. This means + # that the including class SHOULD be synchronized and it MUST implement a + # `#synchronize` method. Not doing so will lead to runtime errors. + + # Has the obligation been fulfilled? + # + # @return [Boolean] + def fulfilled? + state == :fulfilled + end + alias_method :realized?, :fulfilled? + + # Has the obligation been rejected? + # + # @return [Boolean] + def rejected? + state == :rejected + end + + # Is obligation completion still pending? + # + # @return [Boolean] + def pending? + state == :pending + end + + # Is the obligation still unscheduled? + # + # @return [Boolean] + def unscheduled? + state == :unscheduled + end + + # Has the obligation completed processing? + # + # @return [Boolean] + def complete? + [:fulfilled, :rejected].include? state + end + + # Is the obligation still awaiting completion of processing? + # + # @return [Boolean] + def incomplete? + ! complete? + end + + # The current value of the obligation. Will be `nil` while the state is + # pending or the operation has been rejected. + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Object] see Dereferenceable#deref + def value(timeout = nil) + wait timeout + deref + end + + # Wait until obligation is complete or the timeout has been reached. + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Obligation] self + def wait(timeout = nil) + event.wait(timeout) if timeout != 0 && incomplete? + self + end + + # Wait until obligation is complete or the timeout is reached. Will re-raise + # any exceptions raised during processing (but will not raise an exception + # on timeout). + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Obligation] self + # @raise [Exception] raises the reason when rejected + def wait!(timeout = nil) + wait(timeout).tap { raise self if rejected? } + end + alias_method :no_error!, :wait! + + # The current value of the obligation. Will be `nil` while the state is + # pending or the operation has been rejected. Will re-raise any exceptions + # raised during processing (but will not raise an exception on timeout). + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Object] see Dereferenceable#deref + # @raise [Exception] raises the reason when rejected + def value!(timeout = nil) + wait(timeout) + if rejected? + raise self + else + deref + end + end + + # The current state of the obligation. + # + # @return [Symbol] the current state + def state + synchronize { @state } + end + + # If an exception was raised during processing this will return the + # exception object. Will return `nil` when the state is pending or if + # the obligation has been successfully fulfilled. + # + # @return [Exception] the exception raised during processing or `nil` + def reason + synchronize { @reason } + end + + # @example allows Obligation to be risen + # rejected_ivar = Ivar.new.fail + # raise rejected_ivar + def exception(*args) + raise 'obligation is not rejected' unless rejected? + reason.exception(*args) + end + + protected + + # @!visibility private + def get_arguments_from(opts = {}) + [*opts.fetch(:args, [])] + end + + # @!visibility private + def init_obligation + @event = Event.new + @value = @reason = nil + end + + # @!visibility private + def event + @event + end + + # @!visibility private + def set_state(success, value, reason) + if success + @value = value + @state = :fulfilled + else + @reason = reason + @state = :rejected + end + end + + # @!visibility private + def state=(value) + synchronize { ns_set_state(value) } + end + + # Atomic compare and set operation + # State is set to `next_state` only if `current state == expected_current`. + # + # @param [Symbol] next_state + # @param [Symbol] expected_current + # + # @return [Boolean] true is state is changed, false otherwise + # + # @!visibility private + def compare_and_set_state(next_state, *expected_current) + synchronize do + if expected_current.include? @state + @state = next_state + true + else + false + end + end + end + + # Executes the block within mutex if current state is included in expected_states + # + # @return block value if executed, false otherwise + # + # @!visibility private + def if_state(*expected_states) + synchronize do + raise ArgumentError.new('no block given') unless block_given? + + if expected_states.include? @state + yield + else + false + end + end + end + + protected + + # Am I in the current state? + # + # @param [Symbol] expected The state to check against + # @return [Boolean] true if in the expected state else false + # + # @!visibility private + def ns_check_state?(expected) + @state == expected + end + + # @!visibility private + def ns_set_state(value) + @state = value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/observable.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/observable.rb new file mode 100644 index 0000000..b513271 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concern/observable.rb @@ -0,0 +1,110 @@ +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/collection/copy_on_write_observer_set' + +module Concurrent + module Concern + + # The [observer pattern](http://en.wikipedia.org/wiki/Observer_pattern) is one + # of the most useful design patterns. + # + # The workflow is very simple: + # - an `observer` can register itself to a `subject` via a callback + # - many `observers` can be registered to the same `subject` + # - the `subject` notifies all registered observers when its status changes + # - an `observer` can deregister itself when is no more interested to receive + # event notifications + # + # In a single threaded environment the whole pattern is very easy: the + # `subject` can use a simple data structure to manage all its subscribed + # `observer`s and every `observer` can react directly to every event without + # caring about synchronization. + # + # In a multi threaded environment things are more complex. The `subject` must + # synchronize the access to its data structure and to do so currently we're + # using two specialized ObserverSet: {Concurrent::Concern::CopyOnWriteObserverSet} + # and {Concurrent::Concern::CopyOnNotifyObserverSet}. + # + # When implementing and `observer` there's a very important rule to remember: + # **there are no guarantees about the thread that will execute the callback** + # + # Let's take this example + # ``` + # class Observer + # def initialize + # @count = 0 + # end + # + # def update + # @count += 1 + # end + # end + # + # obs = Observer.new + # [obj1, obj2, obj3, obj4].each { |o| o.add_observer(obs) } + # # execute [obj1, obj2, obj3, obj4] + # ``` + # + # `obs` is wrong because the variable `@count` can be accessed by different + # threads at the same time, so it should be synchronized (using either a Mutex + # or an AtomicFixum) + module Observable + + # @!macro observable_add_observer + # + # Adds an observer to this set. If a block is passed, the observer will be + # created by this method and no other params should be passed. + # + # @param [Object] observer the observer to add + # @param [Symbol] func the function to call on the observer during notification. + # Default is :update + # @return [Object] the added observer + def add_observer(observer = nil, func = :update, &block) + observers.add_observer(observer, func, &block) + end + + # As `#add_observer` but can be used for chaining. + # + # @param [Object] observer the observer to add + # @param [Symbol] func the function to call on the observer during notification. + # @return [Observable] self + def with_observer(observer = nil, func = :update, &block) + add_observer(observer, func, &block) + self + end + + # @!macro observable_delete_observer + # + # Remove `observer` as an observer on this object so that it will no + # longer receive notifications. + # + # @param [Object] observer the observer to remove + # @return [Object] the deleted observer + def delete_observer(observer) + observers.delete_observer(observer) + end + + # @!macro observable_delete_observers + # + # Remove all observers associated with this object. + # + # @return [Observable] self + def delete_observers + observers.delete_observers + self + end + + # @!macro observable_count_observers + # + # Return the number of observers associated with this object. + # + # @return [Integer] the observers count + def count_observers + observers.count_observers + end + + protected + + attr_accessor :observers + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concurrent_ruby.jar b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concurrent_ruby.jar new file mode 100644 index 0000000..380bcbd Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/concurrent_ruby.jar differ diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/configuration.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/configuration.rb new file mode 100644 index 0000000..5571d39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/configuration.rb @@ -0,0 +1,105 @@ +require 'thread' +require 'concurrent/delay' +require 'concurrent/errors' +require 'concurrent/concern/deprecation' +require 'concurrent/executor/immediate_executor' +require 'concurrent/executor/fixed_thread_pool' +require 'concurrent/executor/cached_thread_pool' +require 'concurrent/utility/processor_counter' + +module Concurrent + extend Concern::Deprecation + + autoload :Options, 'concurrent/options' + autoload :TimerSet, 'concurrent/executor/timer_set' + autoload :ThreadPoolExecutor, 'concurrent/executor/thread_pool_executor' + + # @!visibility private + GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor } + private_constant :GLOBAL_FAST_EXECUTOR + + # @!visibility private + GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor } + private_constant :GLOBAL_IO_EXECUTOR + + # @!visibility private + GLOBAL_TIMER_SET = Delay.new { TimerSet.new } + private_constant :GLOBAL_TIMER_SET + + # @!visibility private + GLOBAL_IMMEDIATE_EXECUTOR = ImmediateExecutor.new + private_constant :GLOBAL_IMMEDIATE_EXECUTOR + + # Disables AtExit handlers including pool auto-termination handlers. + # When disabled it will be the application programmer's responsibility + # to ensure that the handlers are shutdown properly prior to application + # exit by calling `AtExit.run` method. + # + # @note this option should be needed only because of `at_exit` ordering + # issues which may arise when running some of the testing frameworks. + # E.g. Minitest's test-suite runs itself in `at_exit` callback which + # executes after the pools are already terminated. Then auto termination + # needs to be disabled and called manually after test-suite ends. + # @note This method should *never* be called + # from within a gem. It should *only* be used from within the main + # application and even then it should be used only when necessary. + # @deprecated Has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841. + # + def self.disable_at_exit_handlers! + deprecated "Method #disable_at_exit_handlers! has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841." + end + + # Global thread pool optimized for short, fast *operations*. + # + # @return [ThreadPoolExecutor] the thread pool + def self.global_fast_executor + GLOBAL_FAST_EXECUTOR.value! + end + + # Global thread pool optimized for long, blocking (IO) *tasks*. + # + # @return [ThreadPoolExecutor] the thread pool + def self.global_io_executor + GLOBAL_IO_EXECUTOR.value! + end + + def self.global_immediate_executor + GLOBAL_IMMEDIATE_EXECUTOR + end + + # Global thread pool user for global *timers*. + # + # @return [Concurrent::TimerSet] the thread pool + def self.global_timer_set + GLOBAL_TIMER_SET.value! + end + + # General access point to global executors. + # @param [Symbol, Executor] executor_identifier symbols: + # - :fast - {Concurrent.global_fast_executor} + # - :io - {Concurrent.global_io_executor} + # - :immediate - {Concurrent.global_immediate_executor} + # @return [Executor] + def self.executor(executor_identifier) + Options.executor(executor_identifier) + end + + def self.new_fast_executor(opts = {}) + FixedThreadPool.new( + [2, Concurrent.processor_count].max, + auto_terminate: opts.fetch(:auto_terminate, true), + idletime: 60, # 1 minute + max_queue: 0, # unlimited + fallback_policy: :abort, # shouldn't matter -- 0 max queue + name: "fast" + ) + end + + def self.new_io_executor(opts = {}) + CachedThreadPool.new( + auto_terminate: opts.fetch(:auto_terminate, true), + fallback_policy: :abort, # shouldn't matter -- 0 max queue + name: "io" + ) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/constants.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/constants.rb new file mode 100644 index 0000000..38e01e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/constants.rb @@ -0,0 +1,8 @@ +module Concurrent + + # Various classes within allows for +nil+ values to be stored, + # so a special +NULL+ token is required to indicate the "nil-ness". + # @!visibility private + NULL = ::Object.new.freeze + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/dataflow.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/dataflow.rb new file mode 100644 index 0000000..d55f19d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/dataflow.rb @@ -0,0 +1,81 @@ +require 'concurrent/future' +require 'concurrent/atomic/atomic_fixnum' + +module Concurrent + + # @!visibility private + class DependencyCounter # :nodoc: + + def initialize(count, &block) + @counter = AtomicFixnum.new(count) + @block = block + end + + def update(time, value, reason) + if @counter.decrement == 0 + @block.call + end + end + end + + # Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available. + # {include:file:docs-source/dataflow.md} + # + # @param [Future] inputs zero or more `Future` operations that this dataflow depends upon + # + # @yield The operation to perform once all the dependencies are met + # @yieldparam [Future] inputs each of the `Future` inputs to the dataflow + # @yieldreturn [Object] the result of the block operation + # + # @return [Object] the result of all the operations + # + # @raise [ArgumentError] if no block is given + # @raise [ArgumentError] if any of the inputs are not `IVar`s + def dataflow(*inputs, &block) + dataflow_with(Concurrent.global_io_executor, *inputs, &block) + end + module_function :dataflow + + def dataflow_with(executor, *inputs, &block) + call_dataflow(:value, executor, *inputs, &block) + end + module_function :dataflow_with + + def dataflow!(*inputs, &block) + dataflow_with!(Concurrent.global_io_executor, *inputs, &block) + end + module_function :dataflow! + + def dataflow_with!(executor, *inputs, &block) + call_dataflow(:value!, executor, *inputs, &block) + end + module_function :dataflow_with! + + private + + def call_dataflow(method, executor, *inputs, &block) + raise ArgumentError.new('an executor must be provided') if executor.nil? + raise ArgumentError.new('no block given') unless block_given? + unless inputs.all? { |input| input.is_a? IVar } + raise ArgumentError.new("Not all dependencies are IVars.\nDependencies: #{ inputs.inspect }") + end + + result = Future.new(executor: executor) do + values = inputs.map { |input| input.send(method) } + block.call(*values) + end + + if inputs.empty? + result.execute + else + counter = DependencyCounter.new(inputs.size) { result.execute } + + inputs.each do |input| + input.add_observer counter + end + end + + result + end + module_function :call_dataflow +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/delay.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/delay.rb new file mode 100644 index 0000000..0d6d91a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/delay.rb @@ -0,0 +1,199 @@ +require 'thread' +require 'concurrent/concern/obligation' +require 'concurrent/executor/immediate_executor' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # This file has circular require issues. It must be autoloaded here. + autoload :Options, 'concurrent/options' + + # Lazy evaluation of a block yielding an immutable result. Useful for + # expensive operations that may never be needed. It may be non-blocking, + # supports the `Concern::Obligation` interface, and accepts the injection of + # custom executor upon which to execute the block. Processing of + # block will be deferred until the first time `#value` is called. + # At that time the caller can choose to return immediately and let + # the block execute asynchronously, block indefinitely, or block + # with a timeout. + # + # When a `Delay` is created its state is set to `pending`. The value and + # reason are both `nil`. The first time the `#value` method is called the + # enclosed operation will be run and the calling thread will block. Other + # threads attempting to call `#value` will block as well. Once the operation + # is complete the *value* will be set to the result of the operation or the + # *reason* will be set to the raised exception, as appropriate. All threads + # blocked on `#value` will return. Subsequent calls to `#value` will immediately + # return the cached value. The operation will only be run once. This means that + # any side effects created by the operation will only happen once as well. + # + # `Delay` includes the `Concurrent::Concern::Dereferenceable` mixin to support thread + # safety of the reference returned by `#value`. + # + # @!macro copy_options + # + # @!macro delay_note_regarding_blocking + # @note The default behavior of `Delay` is to block indefinitely when + # calling either `value` or `wait`, executing the delayed operation on + # the current thread. This makes the `timeout` value completely + # irrelevant. To enable non-blocking behavior, use the `executor` + # constructor option. This will cause the delayed operation to be + # execute on the given executor, allowing the call to timeout. + # + # @see Concurrent::Concern::Dereferenceable + class Delay < Synchronization::LockableObject + include Concern::Obligation + + # NOTE: Because the global thread pools are lazy-loaded with these objects + # there is a performance hit every time we post a new task to one of these + # thread pools. Subsequently it is critical that `Delay` perform as fast + # as possible post-completion. This class has been highly optimized using + # the benchmark script `examples/lazy_and_delay.rb`. Do NOT attempt to + # DRY-up this class or perform other refactoring with running the + # benchmarks and ensuring that performance is not negatively impacted. + + # Create a new `Delay` in the `:pending` state. + # + # @!macro executor_and_deref_options + # + # @yield the delayed operation to perform + # + # @raise [ArgumentError] if no block is given + def initialize(opts = {}, &block) + raise ArgumentError.new('no block given') unless block_given? + super(&nil) + synchronize { ns_initialize(opts, &block) } + end + + # Return the value this object represents after applying the options + # specified by the `#set_deref_options` method. If the delayed operation + # raised an exception this method will return nil. The exception object + # can be accessed via the `#reason` method. + # + # @param [Numeric] timeout the maximum number of seconds to wait + # @return [Object] the current value of the object + # + # @!macro delay_note_regarding_blocking + def value(timeout = nil) + if @executor # TODO (pitr 12-Sep-2015): broken unsafe read? + super + else + # this function has been optimized for performance and + # should not be modified without running new benchmarks + synchronize do + execute = @evaluation_started = true unless @evaluation_started + if execute + begin + set_state(true, @task.call, nil) + rescue => ex + set_state(false, nil, ex) + end + elsif incomplete? + raise IllegalOperationError, 'Recursive call to #value during evaluation of the Delay' + end + end + if @do_nothing_on_deref + @value + else + apply_deref_options(@value) + end + end + end + + # Return the value this object represents after applying the options + # specified by the `#set_deref_options` method. If the delayed operation + # raised an exception, this method will raise that exception (even when) + # the operation has already been executed). + # + # @param [Numeric] timeout the maximum number of seconds to wait + # @return [Object] the current value of the object + # @raise [Exception] when `#rejected?` raises `#reason` + # + # @!macro delay_note_regarding_blocking + def value!(timeout = nil) + if @executor + super + else + result = value + raise @reason if @reason + result + end + end + + # Return the value this object represents after applying the options + # specified by the `#set_deref_options` method. + # + # @param [Integer] timeout (nil) the maximum number of seconds to wait for + # the value to be computed. When `nil` the caller will block indefinitely. + # + # @return [Object] self + # + # @!macro delay_note_regarding_blocking + def wait(timeout = nil) + if @executor + execute_task_once + super(timeout) + else + value + end + self + end + + # Reconfigures the block returning the value if still `#incomplete?` + # + # @yield the delayed operation to perform + # @return [true, false] if success + def reconfigure(&block) + synchronize do + raise ArgumentError.new('no block given') unless block_given? + unless @evaluation_started + @task = block + true + else + false + end + end + end + + protected + + def ns_initialize(opts, &block) + init_obligation + set_deref_options(opts) + @executor = opts[:executor] + + @task = block + @state = :pending + @evaluation_started = false + end + + private + + # @!visibility private + def execute_task_once # :nodoc: + # this function has been optimized for performance and + # should not be modified without running new benchmarks + execute = task = nil + synchronize do + execute = @evaluation_started = true unless @evaluation_started + task = @task + end + + if execute + executor = Options.executor_from_options(executor: @executor) + executor.post do + begin + result = task.call + success = true + rescue => ex + reason = ex + end + synchronize do + set_state(success, result, reason) + event.set + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/errors.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/errors.rb new file mode 100644 index 0000000..74f1fc3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/errors.rb @@ -0,0 +1,74 @@ +module Concurrent + + Error = Class.new(StandardError) + + # Raised when errors occur during configuration. + ConfigurationError = Class.new(Error) + + # Raised when an asynchronous operation is cancelled before execution. + CancelledOperationError = Class.new(Error) + + # Raised when a lifecycle method (such as `stop`) is called in an improper + # sequence or when the object is in an inappropriate state. + LifecycleError = Class.new(Error) + + # Raised when an attempt is made to violate an immutability guarantee. + ImmutabilityError = Class.new(Error) + + # Raised when an operation is attempted which is not legal given the + # receiver's current state + IllegalOperationError = Class.new(Error) + + # Raised when an object's methods are called when it has not been + # properly initialized. + InitializationError = Class.new(Error) + + # Raised when an object with a start/stop lifecycle has been started an + # excessive number of times. Often used in conjunction with a restart + # policy or strategy. + MaxRestartFrequencyError = Class.new(Error) + + # Raised when an attempt is made to modify an immutable object + # (such as an `IVar`) after its final state has been set. + class MultipleAssignmentError < Error + attr_reader :inspection_data + + def initialize(message = nil, inspection_data = nil) + @inspection_data = inspection_data + super message + end + + def inspect + format '%s %s>', super[0..-2], @inspection_data.inspect + end + end + + # Raised by an `Executor` when it is unable to process a given task, + # possibly because of a reject policy or other internal error. + RejectedExecutionError = Class.new(Error) + + # Raised when any finite resource, such as a lock counter, exceeds its + # maximum limit/threshold. + ResourceLimitError = Class.new(Error) + + # Raised when an operation times out. + TimeoutError = Class.new(Error) + + # Aggregates multiple exceptions. + class MultipleErrors < Error + attr_reader :errors + + def initialize(errors, message = "#{errors.size} errors") + @errors = errors + super [*message, + *errors.map { |e| [format('%s (%s)', e.message, e.class), *e.backtrace] }.flatten(1) + ].join("\n") + end + end + + # @!macro internal_implementation_note + class ConcurrentUpdateError < ThreadError + # frozen pre-allocated backtrace to speed ConcurrentUpdateError + CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/exchanger.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/exchanger.rb new file mode 100644 index 0000000..a5405d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/exchanger.rb @@ -0,0 +1,353 @@ +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/maybe' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/count_down_latch' +require 'concurrent/utility/engine' +require 'concurrent/utility/monotonic_time' + +module Concurrent + + # @!macro exchanger + # + # A synchronization point at which threads can pair and swap elements within + # pairs. Each thread presents some object on entry to the exchange method, + # matches with a partner thread, and receives its partner's object on return. + # + # @!macro thread_safe_variable_comparison + # + # This implementation is very simple, using only a single slot for each + # exchanger (unlike more advanced implementations which use an "arena"). + # This approach will work perfectly fine when there are only a few threads + # accessing a single `Exchanger`. Beyond a handful of threads the performance + # will degrade rapidly due to contention on the single slot, but the algorithm + # will remain correct. + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html java.util.concurrent.Exchanger + # @example + # + # exchanger = Concurrent::Exchanger.new + # + # threads = [ + # Thread.new { puts "first: " << exchanger.exchange('foo', 1) }, #=> "first: bar" + # Thread.new { puts "second: " << exchanger.exchange('bar', 1) } #=> "second: foo" + # ] + # threads.each {|t| t.join(2) } + + # @!visibility private + class AbstractExchanger < Synchronization::Object + + # @!visibility private + CANCEL = ::Object.new + private_constant :CANCEL + + def initialize + super + end + + # @!macro exchanger_method_do_exchange + # + # Waits for another thread to arrive at this exchange point (unless the + # current thread is interrupted), and then transfers the given object to + # it, receiving its object in return. The timeout value indicates the + # approximate number of seconds the method should block while waiting + # for the exchange. When the timeout value is `nil` the method will + # block indefinitely. + # + # @param [Object] value the value to exchange with another thread + # @param [Numeric, nil] timeout in seconds, `nil` blocks indefinitely + # + # @!macro exchanger_method_exchange + # + # In some edge cases when a `timeout` is given a return value of `nil` may be + # ambiguous. Specifically, if `nil` is a valid value in the exchange it will + # be impossible to tell whether `nil` is the actual return value or if it + # signifies timeout. When `nil` is a valid value in the exchange consider + # using {#exchange!} or {#try_exchange} instead. + # + # @return [Object] the value exchanged by the other thread or `nil` on timeout + def exchange(value, timeout = nil) + (value = do_exchange(value, timeout)) == CANCEL ? nil : value + end + + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_exchange_bang + # + # On timeout a {Concurrent::TimeoutError} exception will be raised. + # + # @return [Object] the value exchanged by the other thread + # @raise [Concurrent::TimeoutError] on timeout + def exchange!(value, timeout = nil) + if (value = do_exchange(value, timeout)) == CANCEL + raise Concurrent::TimeoutError + else + value + end + end + + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_try_exchange + # + # The return value will be a {Concurrent::Maybe} set to `Just` on success or + # `Nothing` on timeout. + # + # @return [Concurrent::Maybe] on success a `Just` maybe will be returned with + # the item exchanged by the other thread as `#value`; on timeout a + # `Nothing` maybe will be returned with {Concurrent::TimeoutError} as `#reason` + # + # @example + # + # exchanger = Concurrent::Exchanger.new + # + # result = exchanger.exchange(:foo, 0.5) + # + # if result.just? + # puts result.value #=> :bar + # else + # puts 'timeout' + # end + def try_exchange(value, timeout = nil) + if (value = do_exchange(value, timeout)) == CANCEL + Concurrent::Maybe.nothing(Concurrent::TimeoutError) + else + Concurrent::Maybe.just(value) + end + end + + private + + # @!macro exchanger_method_do_exchange + # + # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout + def do_exchange(value, timeout) + raise NotImplementedError + end + end + + # @!macro internal_implementation_note + # @!visibility private + class RubyExchanger < AbstractExchanger + # A simplified version of java.util.concurrent.Exchanger written by + # Doug Lea, Bill Scherer, and Michael Scott with assistance from members + # of JCP JSR-166 Expert Group and released to the public domain. It does + # not include the arena or the multi-processor spin loops. + # http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/Exchanger.java + + safe_initialization! + + class Node < Concurrent::Synchronization::Object + attr_atomic :value + safe_initialization! + + def initialize(item) + super() + @Item = item + @Latch = Concurrent::CountDownLatch.new + self.value = nil + end + + def latch + @Latch + end + + def item + @Item + end + end + private_constant :Node + + def initialize + super + end + + private + + attr_atomic(:slot) + + # @!macro exchanger_method_do_exchange + # + # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout + def do_exchange(value, timeout) + + # ALGORITHM + # + # From the original Java version: + # + # > The basic idea is to maintain a "slot", which is a reference to + # > a Node containing both an Item to offer and a "hole" waiting to + # > get filled in. If an incoming "occupying" thread sees that the + # > slot is null, it CAS'es (compareAndSets) a Node there and waits + # > for another to invoke exchange. That second "fulfilling" thread + # > sees that the slot is non-null, and so CASes it back to null, + # > also exchanging items by CASing the hole, plus waking up the + # > occupying thread if it is blocked. In each case CAS'es may + # > fail because a slot at first appears non-null but is null upon + # > CAS, or vice-versa. So threads may need to retry these + # > actions. + # + # This version: + # + # An exchange occurs between an "occupier" thread and a "fulfiller" thread. + # The "slot" is used to setup this interaction. The first thread in the + # exchange puts itself into the slot (occupies) and waits for a fulfiller. + # The second thread removes the occupier from the slot and attempts to + # perform the exchange. Removing the occupier also frees the slot for + # another occupier/fulfiller pair. + # + # Because the occupier and the fulfiller are operating independently and + # because there may be contention with other threads, any failed operation + # indicates contention. Both the occupier and the fulfiller operate within + # spin loops. Any failed actions along the happy path will cause the thread + # to repeat the loop and try again. + # + # When a timeout value is given the thread must be cognizant of time spent + # in the spin loop. The remaining time is checked every loop. When the time + # runs out the thread will exit. + # + # A "node" is the data structure used to perform the exchange. Only the + # occupier's node is necessary. It's the node used for the exchange. + # Each node has an "item," a "hole" (self), and a "latch." The item is the + # node's initial value. It never changes. It's what the fulfiller returns on + # success. The occupier's hole is where the fulfiller put its item. It's the + # item that the occupier returns on success. The latch is used for synchronization. + # Because a thread may act as either an occupier or fulfiller (or possibly + # both in periods of high contention) every thread creates a node when + # the exchange method is first called. + # + # The following steps occur within the spin loop. If any actions fail + # the thread will loop and try again, so long as there is time remaining. + # If time runs out the thread will return CANCEL. + # + # Check the slot for an occupier: + # + # * If the slot is empty try to occupy + # * If the slot is full try to fulfill + # + # Attempt to occupy: + # + # * Attempt to CAS myself into the slot + # * Go to sleep and wait to be woken by a fulfiller + # * If the sleep is successful then the fulfiller completed its happy path + # - Return the value from my hole (the value given by the fulfiller) + # * When the sleep fails (time ran out) attempt to cancel the operation + # - Attempt to CAS myself out of the hole + # - If successful there is no contention + # - Return CANCEL + # - On failure, I am competing with a fulfiller + # - Attempt to CAS my hole to CANCEL + # - On success + # - Let the fulfiller deal with my cancel + # - Return CANCEL + # - On failure the fulfiller has completed its happy path + # - Return th value from my hole (the fulfiller's value) + # + # Attempt to fulfill: + # + # * Attempt to CAS the occupier out of the slot + # - On failure loop again + # * Attempt to CAS my item into the occupier's hole + # - On failure the occupier is trying to cancel + # - Loop again + # - On success we are on the happy path + # - Wake the sleeping occupier + # - Return the occupier's item + + value = NULL if value.nil? # The sentinel allows nil to be a valid value + me = Node.new(value) # create my node in case I need to occupy + end_at = Concurrent.monotonic_time + timeout.to_f # The time to give up + + result = loop do + other = slot + if other && compare_and_set_slot(other, nil) + # try to fulfill + if other.compare_and_set_value(nil, value) + # happy path + other.latch.count_down + break other.item + end + elsif other.nil? && compare_and_set_slot(nil, me) + # try to occupy + timeout = end_at - Concurrent.monotonic_time if timeout + if me.latch.wait(timeout) + # happy path + break me.value + else + # attempt to remove myself from the slot + if compare_and_set_slot(me, nil) + break CANCEL + elsif !me.compare_and_set_value(nil, CANCEL) + # I've failed to block the fulfiller + break me.value + end + end + end + break CANCEL if timeout && Concurrent.monotonic_time >= end_at + end + + result == NULL ? nil : result + end + end + + if Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + + # @!macro internal_implementation_note + # @!visibility private + class JavaExchanger < AbstractExchanger + + def initialize + @exchanger = java.util.concurrent.Exchanger.new + end + + private + + # @!macro exchanger_method_do_exchange + # + # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout + def do_exchange(value, timeout) + result = nil + if timeout.nil? + Synchronization::JRuby.sleep_interruptibly do + result = @exchanger.exchange(value) + end + else + Synchronization::JRuby.sleep_interruptibly do + result = @exchanger.exchange(value, 1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) + end + end + result + rescue java.util.concurrent.TimeoutException + CANCEL + end + end + end + + # @!visibility private + # @!macro internal_implementation_note + ExchangerImplementation = case + when Concurrent.on_jruby? + JavaExchanger + else + RubyExchanger + end + private_constant :ExchangerImplementation + + # @!macro exchanger + class Exchanger < ExchangerImplementation + + # @!method initialize + # Creates exchanger instance + + # @!method exchange(value, timeout = nil) + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_exchange + + # @!method exchange!(value, timeout = nil) + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_exchange_bang + + # @!method try_exchange(value, timeout = nil) + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_try_exchange + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb new file mode 100644 index 0000000..ac42953 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb @@ -0,0 +1,131 @@ +require 'concurrent/errors' +require 'concurrent/concern/deprecation' +require 'concurrent/executor/executor_service' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # @!macro abstract_executor_service_public_api + # @!visibility private + class AbstractExecutorService < Synchronization::LockableObject + include ExecutorService + include Concern::Deprecation + + # The set of possible fallback policies that may be set at thread pool creation. + FALLBACK_POLICIES = [:abort, :discard, :caller_runs].freeze + + # @!macro executor_service_attr_reader_fallback_policy + attr_reader :fallback_policy + + attr_reader :name + + # Create a new thread pool. + def initialize(opts = {}, &block) + super(&nil) + synchronize do + @auto_terminate = opts.fetch(:auto_terminate, true) + @name = opts.fetch(:name) if opts.key?(:name) + ns_initialize(opts, &block) + end + end + + def to_s + name ? "#{super[0..-2]} name: #{name}>" : super + end + + # @!macro executor_service_method_shutdown + def shutdown + raise NotImplementedError + end + + # @!macro executor_service_method_kill + def kill + raise NotImplementedError + end + + # @!macro executor_service_method_wait_for_termination + def wait_for_termination(timeout = nil) + raise NotImplementedError + end + + # @!macro executor_service_method_running_question + def running? + synchronize { ns_running? } + end + + # @!macro executor_service_method_shuttingdown_question + def shuttingdown? + synchronize { ns_shuttingdown? } + end + + # @!macro executor_service_method_shutdown_question + def shutdown? + synchronize { ns_shutdown? } + end + + # @!macro executor_service_method_auto_terminate_question + def auto_terminate? + synchronize { @auto_terminate } + end + + # @!macro executor_service_method_auto_terminate_setter + def auto_terminate=(value) + deprecated "Method #auto_terminate= has no effect. Set :auto_terminate option when executor is initialized." + end + + private + + # Returns an action which executes the `fallback_policy` once the queue + # size reaches `max_queue`. The reason for the indirection of an action + # is so that the work can be deferred outside of synchronization. + # + # @param [Array] args the arguments to the task which is being handled. + # + # @!visibility private + def fallback_action(*args) + case fallback_policy + when :abort + lambda { raise RejectedExecutionError } + when :discard + lambda { false } + when :caller_runs + lambda { + begin + yield(*args) + rescue => ex + # let it fail + log DEBUG, ex + end + true + } + else + lambda { fail "Unknown fallback policy #{fallback_policy}" } + end + end + + def ns_execute(*args, &task) + raise NotImplementedError + end + + # @!macro executor_service_method_ns_shutdown_execution + # + # Callback method called when an orderly shutdown has completed. + # The default behavior is to signal all waiting threads. + def ns_shutdown_execution + # do nothing + end + + # @!macro executor_service_method_ns_kill_execution + # + # Callback method called when the executor has been killed. + # The default behavior is to do nothing. + def ns_kill_execution + # do nothing + end + + def ns_auto_terminate? + @auto_terminate + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb new file mode 100644 index 0000000..de50ed1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb @@ -0,0 +1,62 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/thread_pool_executor' + +module Concurrent + + # A thread pool that dynamically grows and shrinks to fit the current workload. + # New threads are created as needed, existing threads are reused, and threads + # that remain idle for too long are killed and removed from the pool. These + # pools are particularly suited to applications that perform a high volume of + # short-lived tasks. + # + # On creation a `CachedThreadPool` has zero running threads. New threads are + # created on the pool as new operations are `#post`. The size of the pool + # will grow until `#max_length` threads are in the pool or until the number + # of threads exceeds the number of running and pending operations. When a new + # operation is post to the pool the first available idle thread will be tasked + # with the new operation. + # + # Should a thread crash for any reason the thread will immediately be removed + # from the pool. Similarly, threads which remain idle for an extended period + # of time will be killed and reclaimed. Thus these thread pools are very + # efficient at reclaiming unused resources. + # + # The API and behavior of this class are based on Java's `CachedThreadPool` + # + # @!macro thread_pool_options + class CachedThreadPool < ThreadPoolExecutor + + # @!macro cached_thread_pool_method_initialize + # + # Create a new thread pool. + # + # @param [Hash] opts the options defining pool behavior. + # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy + # + # @raise [ArgumentError] if `fallback_policy` is not a known policy + # + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool-- + def initialize(opts = {}) + defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT } + overrides = { min_threads: 0, + max_threads: DEFAULT_MAX_POOL_SIZE, + max_queue: DEFAULT_MAX_QUEUE_SIZE } + super(defaults.merge(opts).merge(overrides)) + end + + private + + # @!macro cached_thread_pool_method_initialize + # @!visibility private + def ns_initialize(opts) + super(opts) + if Concurrent.on_jruby? + @max_queue = 0 + @executor = java.util.concurrent.Executors.newCachedThreadPool( + DaemonThreadFactory.new(ns_auto_terminate?)) + @executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new) + @executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/executor_service.rb new file mode 100644 index 0000000..7e34491 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/executor_service.rb @@ -0,0 +1,185 @@ +require 'concurrent/concern/logging' + +module Concurrent + + ################################################################### + + # @!macro executor_service_method_post + # + # Submit a task to the executor for asynchronous processing. + # + # @param [Array] args zero or more arguments to be passed to the task + # + # @yield the asynchronous task to perform + # + # @return [Boolean] `true` if the task is queued, `false` if the executor + # is not running + # + # @raise [ArgumentError] if no task is given + + # @!macro executor_service_method_left_shift + # + # Submit a task to the executor for asynchronous processing. + # + # @param [Proc] task the asynchronous task to perform + # + # @return [self] returns itself + + # @!macro executor_service_method_can_overflow_question + # + # Does the task queue have a maximum size? + # + # @return [Boolean] True if the task queue has a maximum size else false. + + # @!macro executor_service_method_serialized_question + # + # Does this executor guarantee serialization of its operations? + # + # @return [Boolean] True if the executor guarantees that all operations + # will be post in the order they are received and no two operations may + # occur simultaneously. Else false. + + ################################################################### + + # @!macro executor_service_public_api + # + # @!method post(*args, &task) + # @!macro executor_service_method_post + # + # @!method <<(task) + # @!macro executor_service_method_left_shift + # + # @!method can_overflow? + # @!macro executor_service_method_can_overflow_question + # + # @!method serialized? + # @!macro executor_service_method_serialized_question + + ################################################################### + + # @!macro executor_service_attr_reader_fallback_policy + # @return [Symbol] The fallback policy in effect. Either `:abort`, `:discard`, or `:caller_runs`. + + # @!macro executor_service_method_shutdown + # + # Begin an orderly shutdown. Tasks already in the queue will be executed, + # but no new tasks will be accepted. Has no additional effect if the + # thread pool is not running. + + # @!macro executor_service_method_kill + # + # Begin an immediate shutdown. In-progress tasks will be allowed to + # complete but enqueued tasks will be dismissed and no new tasks + # will be accepted. Has no additional effect if the thread pool is + # not running. + + # @!macro executor_service_method_wait_for_termination + # + # Block until executor shutdown is complete or until `timeout` seconds have + # passed. + # + # @note Does not initiate shutdown or termination. Either `shutdown` or `kill` + # must be called before this method (or on another thread). + # + # @param [Integer] timeout the maximum number of seconds to wait for shutdown to complete + # + # @return [Boolean] `true` if shutdown complete or false on `timeout` + + # @!macro executor_service_method_running_question + # + # Is the executor running? + # + # @return [Boolean] `true` when running, `false` when shutting down or shutdown + + # @!macro executor_service_method_shuttingdown_question + # + # Is the executor shuttingdown? + # + # @return [Boolean] `true` when not running and not shutdown, else `false` + + # @!macro executor_service_method_shutdown_question + # + # Is the executor shutdown? + # + # @return [Boolean] `true` when shutdown, `false` when shutting down or running + + # @!macro executor_service_method_auto_terminate_question + # + # Is the executor auto-terminate when the application exits? + # + # @return [Boolean] `true` when auto-termination is enabled else `false`. + + # @!macro executor_service_method_auto_terminate_setter + # + # + # Set the auto-terminate behavior for this executor. + # @deprecated Has no effect + # @param [Boolean] value The new auto-terminate value to set for this executor. + # @return [Boolean] `true` when auto-termination is enabled else `false`. + + ################################################################### + + # @!macro abstract_executor_service_public_api + # + # @!macro executor_service_public_api + # + # @!attribute [r] fallback_policy + # @!macro executor_service_attr_reader_fallback_policy + # + # @!method shutdown + # @!macro executor_service_method_shutdown + # + # @!method kill + # @!macro executor_service_method_kill + # + # @!method wait_for_termination(timeout = nil) + # @!macro executor_service_method_wait_for_termination + # + # @!method running? + # @!macro executor_service_method_running_question + # + # @!method shuttingdown? + # @!macro executor_service_method_shuttingdown_question + # + # @!method shutdown? + # @!macro executor_service_method_shutdown_question + # + # @!method auto_terminate? + # @!macro executor_service_method_auto_terminate_question + # + # @!method auto_terminate=(value) + # @!macro executor_service_method_auto_terminate_setter + + ################################################################### + + # @!macro executor_service_public_api + # @!visibility private + module ExecutorService + include Concern::Logging + + # @!macro executor_service_method_post + def post(*args, &task) + raise NotImplementedError + end + + # @!macro executor_service_method_left_shift + def <<(task) + post(&task) + self + end + + # @!macro executor_service_method_can_overflow_question + # + # @note Always returns `false` + def can_overflow? + false + end + + # @!macro executor_service_method_serialized_question + # + # @note Always returns `false` + def serialized? + false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb new file mode 100644 index 0000000..b73cff8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb @@ -0,0 +1,222 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/thread_pool_executor' + +module Concurrent + + # @!macro thread_pool_executor_constant_default_max_pool_size + # Default maximum number of threads that will be created in the pool. + + # @!macro thread_pool_executor_constant_default_min_pool_size + # Default minimum number of threads that will be retained in the pool. + + # @!macro thread_pool_executor_constant_default_max_queue_size + # Default maximum number of tasks that may be added to the task queue. + + # @!macro thread_pool_executor_constant_default_thread_timeout + # Default maximum number of seconds a thread in the pool may remain idle + # before being reclaimed. + + # @!macro thread_pool_executor_constant_default_synchronous + # Default value of the :synchronous option. + + # @!macro thread_pool_executor_attr_reader_max_length + # The maximum number of threads that may be created in the pool. + # @return [Integer] The maximum number of threads that may be created in the pool. + + # @!macro thread_pool_executor_attr_reader_min_length + # The minimum number of threads that may be retained in the pool. + # @return [Integer] The minimum number of threads that may be retained in the pool. + + # @!macro thread_pool_executor_attr_reader_largest_length + # The largest number of threads that have been created in the pool since construction. + # @return [Integer] The largest number of threads that have been created in the pool since construction. + + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + # The number of tasks that have been scheduled for execution on the pool since construction. + # @return [Integer] The number of tasks that have been scheduled for execution on the pool since construction. + + # @!macro thread_pool_executor_attr_reader_completed_task_count + # The number of tasks that have been completed by the pool since construction. + # @return [Integer] The number of tasks that have been completed by the pool since construction. + + # @!macro thread_pool_executor_method_active_count + # The number of threads that are actively executing tasks. + # @return [Integer] The number of threads that are actively executing tasks. + + # @!macro thread_pool_executor_attr_reader_idletime + # The number of seconds that a thread may be idle before being reclaimed. + # @return [Integer] The number of seconds that a thread may be idle before being reclaimed. + + # @!macro thread_pool_executor_attr_reader_synchronous + # Whether or not a value of 0 for :max_queue option means the queue must perform direct hand-off or rather unbounded queue. + # @return [true, false] + + # @!macro thread_pool_executor_attr_reader_max_queue + # The maximum number of tasks that may be waiting in the work queue at any one time. + # When the queue size reaches `max_queue` subsequent tasks will be rejected in + # accordance with the configured `fallback_policy`. + # + # @return [Integer] The maximum number of tasks that may be waiting in the work queue at any one time. + # When the queue size reaches `max_queue` subsequent tasks will be rejected in + # accordance with the configured `fallback_policy`. + + # @!macro thread_pool_executor_attr_reader_length + # The number of threads currently in the pool. + # @return [Integer] The number of threads currently in the pool. + + # @!macro thread_pool_executor_attr_reader_queue_length + # The number of tasks in the queue awaiting execution. + # @return [Integer] The number of tasks in the queue awaiting execution. + + # @!macro thread_pool_executor_attr_reader_remaining_capacity + # Number of tasks that may be enqueued before reaching `max_queue` and rejecting + # new tasks. A value of -1 indicates that the queue may grow without bound. + # + # @return [Integer] Number of tasks that may be enqueued before reaching `max_queue` and rejecting + # new tasks. A value of -1 indicates that the queue may grow without bound. + + # @!macro thread_pool_executor_method_prune_pool + # Prune the thread pool of unneeded threads + # + # What is being pruned is controlled by the min_threads and idletime + # parameters passed at pool creation time + # + # This is a no-op on all pool implementations as they prune themselves + # automatically, and has been deprecated. + + # @!macro thread_pool_executor_public_api + # + # @!macro abstract_executor_service_public_api + # + # @!attribute [r] max_length + # @!macro thread_pool_executor_attr_reader_max_length + # + # @!attribute [r] min_length + # @!macro thread_pool_executor_attr_reader_min_length + # + # @!attribute [r] largest_length + # @!macro thread_pool_executor_attr_reader_largest_length + # + # @!attribute [r] scheduled_task_count + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + # + # @!attribute [r] completed_task_count + # @!macro thread_pool_executor_attr_reader_completed_task_count + # + # @!attribute [r] idletime + # @!macro thread_pool_executor_attr_reader_idletime + # + # @!attribute [r] max_queue + # @!macro thread_pool_executor_attr_reader_max_queue + # + # @!attribute [r] length + # @!macro thread_pool_executor_attr_reader_length + # + # @!attribute [r] queue_length + # @!macro thread_pool_executor_attr_reader_queue_length + # + # @!attribute [r] remaining_capacity + # @!macro thread_pool_executor_attr_reader_remaining_capacity + # + # @!method can_overflow? + # @!macro executor_service_method_can_overflow_question + # + # @!method prune_pool + # @!macro thread_pool_executor_method_prune_pool + + + + + # @!macro thread_pool_options + # + # **Thread Pool Options** + # + # Thread pools support several configuration options: + # + # * `idletime`: The number of seconds that a thread may be idle before being reclaimed. + # * `name`: The name of the executor (optional). Printed in the executor's `#to_s` output and + # a `-worker-` name is given to its threads if supported by used Ruby + # implementation. `` is uniq for each thread. + # * `max_queue`: The maximum number of tasks that may be waiting in the work queue at + # any one time. When the queue size reaches `max_queue` and no new threads can be created, + # subsequent tasks will be rejected in accordance with the configured `fallback_policy`. + # * `auto_terminate`: When true (default), the threads started will be marked as daemon. + # * `fallback_policy`: The policy defining how rejected tasks are handled. + # + # Three fallback policies are supported: + # + # * `:abort`: Raise a `RejectedExecutionError` exception and discard the task. + # * `:discard`: Discard the task and return false. + # * `:caller_runs`: Execute the task on the calling thread. + # + # **Shutting Down Thread Pools** + # + # Killing a thread pool while tasks are still being processed, either by calling + # the `#kill` method or at application exit, will have unpredictable results. There + # is no way for the thread pool to know what resources are being used by the + # in-progress tasks. When those tasks are killed the impact on those resources + # cannot be predicted. The *best* practice is to explicitly shutdown all thread + # pools using the provided methods: + # + # * Call `#shutdown` to initiate an orderly termination of all in-progress tasks + # * Call `#wait_for_termination` with an appropriate timeout interval an allow + # the orderly shutdown to complete + # * Call `#kill` *only when* the thread pool fails to shutdown in the allotted time + # + # On some runtime platforms (most notably the JVM) the application will not + # exit until all thread pools have been shutdown. To prevent applications from + # "hanging" on exit, all threads can be marked as daemon according to the + # `:auto_terminate` option. + # + # ```ruby + # pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon + # pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon + # ``` + # + # @note Failure to properly shutdown a thread pool can lead to unpredictable results. + # Please read *Shutting Down Thread Pools* for more information. + # + # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Java Tutorials: Thread Pools + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html Java ExecutorService interface + # @see https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon-boolean- + + + + + + # @!macro fixed_thread_pool + # + # A thread pool that reuses a fixed number of threads operating off an unbounded queue. + # At any point, at most `num_threads` will be active processing tasks. When all threads are busy new + # tasks `#post` to the thread pool are enqueued until a thread becomes available. + # Should a thread crash for any reason the thread will immediately be removed + # from the pool and replaced. + # + # The API and behavior of this class are based on Java's `FixedThreadPool` + # + # @!macro thread_pool_options + class FixedThreadPool < ThreadPoolExecutor + + # @!macro fixed_thread_pool_method_initialize + # + # Create a new thread pool. + # + # @param [Integer] num_threads the number of threads to allocate + # @param [Hash] opts the options defining pool behavior. + # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy + # + # @raise [ArgumentError] if `num_threads` is less than or equal to zero + # @raise [ArgumentError] if `fallback_policy` is not a known policy + # + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int- + def initialize(num_threads, opts = {}) + raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1 + defaults = { max_queue: DEFAULT_MAX_QUEUE_SIZE, + idletime: DEFAULT_THREAD_IDLETIMEOUT } + overrides = { min_threads: num_threads, + max_threads: num_threads } + super(defaults.merge(opts).merge(overrides)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb new file mode 100644 index 0000000..282df7a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb @@ -0,0 +1,66 @@ +require 'concurrent/atomic/event' +require 'concurrent/executor/abstract_executor_service' +require 'concurrent/executor/serial_executor_service' + +module Concurrent + + # An executor service which runs all operations on the current thread, + # blocking as necessary. Operations are performed in the order they are + # received and no two operations can be performed simultaneously. + # + # This executor service exists mainly for testing an debugging. When used + # it immediately runs every `#post` operation on the current thread, blocking + # that thread until the operation is complete. This can be very beneficial + # during testing because it makes all operations deterministic. + # + # @note Intended for use primarily in testing and debugging. + class ImmediateExecutor < AbstractExecutorService + include SerialExecutorService + + # Creates a new executor + def initialize + @stopped = Concurrent::Event.new + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + task.call(*args) + true + end + + # @!macro executor_service_method_left_shift + def <<(task) + post(&task) + self + end + + # @!macro executor_service_method_running_question + def running? + ! shutdown? + end + + # @!macro executor_service_method_shuttingdown_question + def shuttingdown? + false + end + + # @!macro executor_service_method_shutdown_question + def shutdown? + @stopped.set? + end + + # @!macro executor_service_method_shutdown + def shutdown + @stopped.set + true + end + alias_method :kill, :shutdown + + # @!macro executor_service_method_wait_for_termination + def wait_for_termination(timeout = nil) + @stopped.wait(timeout) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb new file mode 100644 index 0000000..4f9769f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb @@ -0,0 +1,44 @@ +require 'concurrent/executor/immediate_executor' +require 'concurrent/executor/simple_executor_service' + +module Concurrent + # An executor service which runs all operations on a new thread, blocking + # until it completes. Operations are performed in the order they are received + # and no two operations can be performed simultaneously. + # + # This executor service exists mainly for testing an debugging. When used it + # immediately runs every `#post` operation on a new thread, blocking the + # current thread until the operation is complete. This is similar to how the + # ImmediateExecutor works, but the operation has the full stack of the new + # thread at its disposal. This can be helpful when the operations will spawn + # more operations on the same executor and so on - such a situation might + # overflow the single stack in case of an ImmediateExecutor, which is + # inconsistent with how it would behave for a threaded executor. + # + # @note Intended for use primarily in testing and debugging. + class IndirectImmediateExecutor < ImmediateExecutor + # Creates a new executor + def initialize + super + @internal_executor = SimpleExecutorService.new + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new("no block given") unless block_given? + return false unless running? + + event = Concurrent::Event.new + @internal_executor.post do + begin + task.call(*args) + ensure + event.set + end + end + event.wait + + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb new file mode 100644 index 0000000..96991a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb @@ -0,0 +1,101 @@ +require 'concurrent/utility/engine' + +if Concurrent.on_jruby? + require 'concurrent/errors' + require 'concurrent/executor/abstract_executor_service' + + module Concurrent + + # @!macro abstract_executor_service_public_api + # @!visibility private + class JavaExecutorService < AbstractExecutorService + java_import 'java.lang.Runnable' + + FALLBACK_POLICY_CLASSES = { + abort: java.util.concurrent.ThreadPoolExecutor::AbortPolicy, + discard: java.util.concurrent.ThreadPoolExecutor::DiscardPolicy, + caller_runs: java.util.concurrent.ThreadPoolExecutor::CallerRunsPolicy + }.freeze + private_constant :FALLBACK_POLICY_CLASSES + + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return fallback_action(*args, &task).call unless running? + @executor.submit Job.new(args, task) + true + rescue Java::JavaUtilConcurrent::RejectedExecutionException + raise RejectedExecutionError + end + + def wait_for_termination(timeout = nil) + if timeout.nil? + ok = @executor.awaitTermination(60, java.util.concurrent.TimeUnit::SECONDS) until ok + true + else + @executor.awaitTermination(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) + end + end + + def shutdown + synchronize do + @executor.shutdown + nil + end + end + + def kill + synchronize do + @executor.shutdownNow + wait_for_termination + nil + end + end + + private + + def ns_running? + !(ns_shuttingdown? || ns_shutdown?) + end + + def ns_shuttingdown? + @executor.isShutdown && !@executor.isTerminated + end + + def ns_shutdown? + @executor.isTerminated + end + + class Job + include Runnable + def initialize(args, block) + @args = args + @block = block + end + + def run + @block.call(*@args) + end + end + private_constant :Job + end + + class DaemonThreadFactory + # hide include from YARD + send :include, java.util.concurrent.ThreadFactory + + def initialize(daemonize = true) + @daemonize = daemonize + @java_thread_factory = java.util.concurrent.Executors.defaultThreadFactory + end + + def newThread(runnable) + thread = @java_thread_factory.newThread(runnable) + thread.setDaemon(@daemonize) + return thread + end + end + + private_constant :DaemonThreadFactory + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb new file mode 100644 index 0000000..7aa24f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb @@ -0,0 +1,30 @@ +if Concurrent.on_jruby? + + require 'concurrent/executor/java_executor_service' + require 'concurrent/executor/serial_executor_service' + + module Concurrent + + # @!macro single_thread_executor + # @!macro abstract_executor_service_public_api + # @!visibility private + class JavaSingleThreadExecutor < JavaExecutorService + include SerialExecutorService + + # @!macro single_thread_executor_method_initialize + def initialize(opts = {}) + super(opts) + end + + private + + def ns_initialize(opts) + @executor = java.util.concurrent.Executors.newSingleThreadExecutor( + DaemonThreadFactory.new(ns_auto_terminate?) + ) + @fallback_policy = opts.fetch(:fallback_policy, :discard) + raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.keys.include?(@fallback_policy) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb new file mode 100644 index 0000000..a89fde2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb @@ -0,0 +1,147 @@ +if Concurrent.on_jruby? + + require 'concurrent/executor/java_executor_service' + + module Concurrent + + # @!macro thread_pool_executor + # @!macro thread_pool_options + # @!visibility private + class JavaThreadPoolExecutor < JavaExecutorService + include Concern::Deprecation + + # @!macro thread_pool_executor_constant_default_max_pool_size + DEFAULT_MAX_POOL_SIZE = java.lang.Integer::MAX_VALUE # 2147483647 + + # @!macro thread_pool_executor_constant_default_min_pool_size + DEFAULT_MIN_POOL_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_max_queue_size + DEFAULT_MAX_QUEUE_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_thread_timeout + DEFAULT_THREAD_IDLETIMEOUT = 60 + + # @!macro thread_pool_executor_constant_default_synchronous + DEFAULT_SYNCHRONOUS = false + + # @!macro thread_pool_executor_attr_reader_max_length + attr_reader :max_length + + # @!macro thread_pool_executor_attr_reader_max_queue + attr_reader :max_queue + + # @!macro thread_pool_executor_attr_reader_synchronous + attr_reader :synchronous + + # @!macro thread_pool_executor_method_initialize + def initialize(opts = {}) + super(opts) + end + + # @!macro executor_service_method_can_overflow_question + def can_overflow? + @max_queue != 0 + end + + # @!macro thread_pool_executor_attr_reader_min_length + def min_length + @executor.getCorePoolSize + end + + # @!macro thread_pool_executor_attr_reader_max_length + def max_length + @executor.getMaximumPoolSize + end + + # @!macro thread_pool_executor_attr_reader_length + def length + @executor.getPoolSize + end + + # @!macro thread_pool_executor_attr_reader_largest_length + def largest_length + @executor.getLargestPoolSize + end + + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + def scheduled_task_count + @executor.getTaskCount + end + + # @!macro thread_pool_executor_attr_reader_completed_task_count + def completed_task_count + @executor.getCompletedTaskCount + end + + # @!macro thread_pool_executor_method_active_count + def active_count + @executor.getActiveCount + end + + # @!macro thread_pool_executor_attr_reader_idletime + def idletime + @executor.getKeepAliveTime(java.util.concurrent.TimeUnit::SECONDS) + end + + # @!macro thread_pool_executor_attr_reader_queue_length + def queue_length + @executor.getQueue.size + end + + # @!macro thread_pool_executor_attr_reader_remaining_capacity + def remaining_capacity + @max_queue == 0 ? -1 : @executor.getQueue.remainingCapacity + end + + # @!macro executor_service_method_running_question + def running? + super && !@executor.isTerminating + end + + # @!macro thread_pool_executor_method_prune_pool + def prune_pool + deprecated "#prune_pool has no effect and will be removed in the next release." + end + + private + + def ns_initialize(opts) + min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i + max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i + idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i + @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i + @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS) + @fallback_policy = opts.fetch(:fallback_policy, :abort) + + raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0 + raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if max_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if max_length > DEFAULT_MAX_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if min_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length + raise ArgumentError.new("#{fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.include?(@fallback_policy) + + if @max_queue == 0 + if @synchronous + queue = java.util.concurrent.SynchronousQueue.new + else + queue = java.util.concurrent.LinkedBlockingQueue.new + end + else + queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue) + end + + @executor = java.util.concurrent.ThreadPoolExecutor.new( + min_length, + max_length, + idletime, + java.util.concurrent.TimeUnit::SECONDS, + queue, + DaemonThreadFactory.new(ns_auto_terminate?), + FALLBACK_POLICY_CLASSES[@fallback_policy].new) + + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb new file mode 100644 index 0000000..1f7301b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb @@ -0,0 +1,82 @@ +require 'concurrent/executor/abstract_executor_service' +require 'concurrent/atomic/event' + +module Concurrent + + # @!macro abstract_executor_service_public_api + # @!visibility private + class RubyExecutorService < AbstractExecutorService + safe_initialization! + + def initialize(*args, &block) + super + @StopEvent = Event.new + @StoppedEvent = Event.new + end + + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + deferred_action = synchronize { + if running? + ns_execute(*args, &task) + else + fallback_action(*args, &task) + end + } + if deferred_action + deferred_action.call + else + true + end + end + + def shutdown + synchronize do + break unless running? + stop_event.set + ns_shutdown_execution + end + true + end + + def kill + synchronize do + break if shutdown? + stop_event.set + ns_kill_execution + stopped_event.set + end + true + end + + def wait_for_termination(timeout = nil) + stopped_event.wait(timeout) + end + + private + + def stop_event + @StopEvent + end + + def stopped_event + @StoppedEvent + end + + def ns_shutdown_execution + stopped_event.set + end + + def ns_running? + !stop_event.set? + end + + def ns_shuttingdown? + !(ns_running? || ns_shutdown?) + end + + def ns_shutdown? + stopped_event.set? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb new file mode 100644 index 0000000..6d9f88c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb @@ -0,0 +1,23 @@ +require 'concurrent/executor/ruby_thread_pool_executor' +require 'concurrent/executor/serial_executor_service' + +module Concurrent + + # @!macro single_thread_executor + # @!macro abstract_executor_service_public_api + # @!visibility private + class RubySingleThreadExecutor < RubyThreadPoolExecutor + include SerialExecutorService + + # @!macro single_thread_executor_method_initialize + def initialize(opts = {}) + super( + min_threads: 1, + max_threads: 1, + max_queue: 0, + idletime: DEFAULT_THREAD_IDLETIMEOUT, + fallback_policy: opts.fetch(:fallback_policy, :discard), + ) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb new file mode 100644 index 0000000..28bbdca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb @@ -0,0 +1,396 @@ +require 'thread' +require 'concurrent/atomic/event' +require 'concurrent/concern/logging' +require 'concurrent/executor/ruby_executor_service' +require 'concurrent/utility/monotonic_time' +require 'concurrent/collection/timeout_queue' + +module Concurrent + + # @!macro thread_pool_executor + # @!macro thread_pool_options + # @!visibility private + class RubyThreadPoolExecutor < RubyExecutorService + include Concern::Deprecation + + # @!macro thread_pool_executor_constant_default_max_pool_size + DEFAULT_MAX_POOL_SIZE = 2_147_483_647 # java.lang.Integer::MAX_VALUE + + # @!macro thread_pool_executor_constant_default_min_pool_size + DEFAULT_MIN_POOL_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_max_queue_size + DEFAULT_MAX_QUEUE_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_thread_timeout + DEFAULT_THREAD_IDLETIMEOUT = 60 + + # @!macro thread_pool_executor_constant_default_synchronous + DEFAULT_SYNCHRONOUS = false + + # @!macro thread_pool_executor_attr_reader_max_length + attr_reader :max_length + + # @!macro thread_pool_executor_attr_reader_min_length + attr_reader :min_length + + # @!macro thread_pool_executor_attr_reader_idletime + attr_reader :idletime + + # @!macro thread_pool_executor_attr_reader_max_queue + attr_reader :max_queue + + # @!macro thread_pool_executor_attr_reader_synchronous + attr_reader :synchronous + + # @!macro thread_pool_executor_method_initialize + def initialize(opts = {}) + super(opts) + end + + # @!macro thread_pool_executor_attr_reader_largest_length + def largest_length + synchronize { @largest_length } + end + + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + def scheduled_task_count + synchronize { @scheduled_task_count } + end + + # @!macro thread_pool_executor_attr_reader_completed_task_count + def completed_task_count + synchronize { @completed_task_count } + end + + # @!macro thread_pool_executor_method_active_count + def active_count + synchronize do + @pool.length - @ready.length + end + end + + # @!macro executor_service_method_can_overflow_question + def can_overflow? + synchronize { ns_limited_queue? } + end + + # @!macro thread_pool_executor_attr_reader_length + def length + synchronize { @pool.length } + end + + # @!macro thread_pool_executor_attr_reader_queue_length + def queue_length + synchronize { @queue.length } + end + + # @!macro thread_pool_executor_attr_reader_remaining_capacity + def remaining_capacity + synchronize do + if ns_limited_queue? + @max_queue - @queue.length + else + -1 + end + end + end + + # removes the worker if it can be pruned + # + # @return [true, false] if the worker was pruned + # + # @!visibility private + def prune_worker(worker) + synchronize do + if ns_prunable_capacity > 0 + remove_worker worker + true + else + false + end + end + end + + # @!visibility private + def remove_worker(worker) + synchronize do + ns_remove_ready_worker worker + ns_remove_busy_worker worker + end + end + + # @!visibility private + def ready_worker(worker, last_message) + synchronize { ns_ready_worker worker, last_message } + end + + # @!visibility private + def worker_died(worker) + synchronize { ns_worker_died worker } + end + + # @!visibility private + def worker_task_completed + synchronize { @completed_task_count += 1 } + end + + # @!macro thread_pool_executor_method_prune_pool + def prune_pool + deprecated "#prune_pool has no effect and will be removed in next the release, see https://github.com/ruby-concurrency/concurrent-ruby/pull/1082." + end + + private + + # @!visibility private + def ns_initialize(opts) + @min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i + @max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i + @idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i + @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i + @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS) + @fallback_policy = opts.fetch(:fallback_policy, :abort) + + raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0 + raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICIES.include?(@fallback_policy) + raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @max_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if @max_length > DEFAULT_MAX_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @min_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length + + @pool = [] # all workers + @ready = [] # used as a stash (most idle worker is at the start) + @queue = [] # used as queue + # @ready or @queue is empty at all times + @scheduled_task_count = 0 + @completed_task_count = 0 + @largest_length = 0 + @workers_counter = 0 + @ruby_pid = $$ # detects if Ruby has forked + end + + # @!visibility private + def ns_limited_queue? + @max_queue != 0 + end + + # @!visibility private + def ns_execute(*args, &task) + ns_reset_if_forked + + if ns_assign_worker(*args, &task) || ns_enqueue(*args, &task) + @scheduled_task_count += 1 + nil + else + fallback_action(*args, &task) + end + end + + # @!visibility private + def ns_shutdown_execution + ns_reset_if_forked + + if @pool.empty? + # nothing to do + stopped_event.set + end + + if @queue.empty? + # no more tasks will be accepted, just stop all workers + @pool.each(&:stop) + end + end + + # @!visibility private + def ns_kill_execution + # TODO log out unprocessed tasks in queue + # TODO try to shutdown first? + @pool.each(&:kill) + @pool.clear + @ready.clear + end + + # tries to assign task to a worker, tries to get one from @ready or to create new one + # @return [true, false] if task is assigned to a worker + # + # @!visibility private + def ns_assign_worker(*args, &task) + # keep growing if the pool is not at the minimum yet + worker, _ = (@ready.pop if @pool.size >= @min_length) || ns_add_busy_worker + if worker + worker << [task, args] + true + else + false + end + rescue ThreadError + # Raised when the operating system refuses to create the new thread + return false + end + + # tries to enqueue task + # @return [true, false] if enqueued + # + # @!visibility private + def ns_enqueue(*args, &task) + return false if @synchronous + + if !ns_limited_queue? || @queue.size < @max_queue + @queue << [task, args] + true + else + false + end + end + + # @!visibility private + def ns_worker_died(worker) + ns_remove_busy_worker worker + replacement_worker = ns_add_busy_worker + ns_ready_worker replacement_worker, Concurrent.monotonic_time, false if replacement_worker + end + + # creates new worker which has to receive work to do after it's added + # @return [nil, Worker] nil of max capacity is reached + # + # @!visibility private + def ns_add_busy_worker + return if @pool.size >= @max_length + + @workers_counter += 1 + @pool << (worker = Worker.new(self, @workers_counter)) + @largest_length = @pool.length if @pool.length > @largest_length + worker + end + + # handle ready worker, giving it new job or assigning back to @ready + # + # @!visibility private + def ns_ready_worker(worker, last_message, success = true) + task_and_args = @queue.shift + if task_and_args + worker << task_and_args + else + # stop workers when !running?, do not return them to @ready + if running? + raise unless last_message + @ready.push([worker, last_message]) + else + worker.stop + end + end + end + + # removes a worker which is not tracked in @ready + # + # @!visibility private + def ns_remove_busy_worker(worker) + @pool.delete(worker) + stopped_event.set if @pool.empty? && !running? + true + end + + # @!visibility private + def ns_remove_ready_worker(worker) + if index = @ready.index { |rw, _| rw == worker } + @ready.delete_at(index) + end + true + end + + # @return [Integer] number of excess idle workers which can be removed without + # going below min_length, or all workers if not running + # + # @!visibility private + def ns_prunable_capacity + if running? + [@pool.size - @min_length, @ready.size].min + else + @pool.size + end + end + + # @!visibility private + def ns_reset_if_forked + if $$ != @ruby_pid + @queue.clear + @ready.clear + @pool.clear + @scheduled_task_count = 0 + @completed_task_count = 0 + @largest_length = 0 + @workers_counter = 0 + @ruby_pid = $$ + end + end + + # @!visibility private + class Worker + include Concern::Logging + + def initialize(pool, id) + # instance variables accessed only under pool's lock so no need to sync here again + @queue = Collection::TimeoutQueue.new + @pool = pool + @thread = create_worker @queue, pool, pool.idletime + + if @thread.respond_to?(:name=) + @thread.name = [pool.name, 'worker', id].compact.join('-') + end + end + + def <<(message) + @queue << message + end + + def stop + @queue << :stop + end + + def kill + @thread.kill + end + + private + + def create_worker(queue, pool, idletime) + Thread.new(queue, pool, idletime) do |my_queue, my_pool, my_idletime| + catch(:stop) do + prunable = true + + loop do + timeout = prunable && my_pool.running? ? my_idletime : nil + case message = my_queue.pop(timeout: timeout) + when nil + throw :stop if my_pool.prune_worker(self) + prunable = false + when :stop + my_pool.remove_worker(self) + throw :stop + else + task, args = message + run_task my_pool, task, args + my_pool.ready_worker(self, Concurrent.monotonic_time) + prunable = true + end + end + end + end + end + + def run_task(pool, task, args) + task.call(*args) + pool.worker_task_completed + rescue => ex + # let it fail + log DEBUG, ex + rescue Exception => ex + log ERROR, ex + pool.worker_died(self) + throw :stop + end + end + + private_constant :Worker + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb new file mode 100644 index 0000000..f796b85 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb @@ -0,0 +1,35 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # A simple utility class that executes a callable and returns and array of three elements: + # success - indicating if the callable has been executed without errors + # value - filled by the callable result if it has been executed without errors, nil otherwise + # reason - the error risen by the callable if it has been executed with errors, nil otherwise + class SafeTaskExecutor < Synchronization::LockableObject + + def initialize(task, opts = {}) + @task = task + @exception_class = opts.fetch(:rescue_exception, false) ? Exception : StandardError + super() # ensures visibility + end + + # @return [Array] + def execute(*args) + success = true + value = reason = nil + + synchronize do + begin + value = @task.call(*args) + success = true + rescue @exception_class => ex + reason = ex + success = false + end + end + + [success, value, reason] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb new file mode 100644 index 0000000..f1c38ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb @@ -0,0 +1,34 @@ +require 'concurrent/executor/executor_service' + +module Concurrent + + # Indicates that the including `ExecutorService` guarantees + # that all operations will occur in the order they are post and that no + # two operations may occur simultaneously. This module provides no + # functionality and provides no guarantees. That is the responsibility + # of the including class. This module exists solely to allow the including + # object to be interrogated for its serialization status. + # + # @example + # class Foo + # include Concurrent::SerialExecutor + # end + # + # foo = Foo.new + # + # foo.is_a? Concurrent::ExecutorService #=> true + # foo.is_a? Concurrent::SerialExecutor #=> true + # foo.serialized? #=> true + # + # @!visibility private + module SerialExecutorService + include ExecutorService + + # @!macro executor_service_method_serialized_question + # + # @note Always returns `true` + def serialized? + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb new file mode 100644 index 0000000..4db7c7f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb @@ -0,0 +1,107 @@ +require 'concurrent/errors' +require 'concurrent/concern/logging' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # Ensures passed jobs in a serialized order never running at the same time. + class SerializedExecution < Synchronization::LockableObject + include Concern::Logging + + def initialize() + super() + synchronize { ns_initialize } + end + + Job = Struct.new(:executor, :args, :block) do + def call + block.call(*args) + end + end + + # Submit a task to the executor for asynchronous processing. + # + # @param [Executor] executor to be used for this job + # + # @param [Array] args zero or more arguments to be passed to the task + # + # @yield the asynchronous task to perform + # + # @return [Boolean] `true` if the task is queued, `false` if the executor + # is not running + # + # @raise [ArgumentError] if no task is given + def post(executor, *args, &task) + posts [[executor, args, task]] + true + end + + # As {#post} but allows to submit multiple tasks at once, it's guaranteed that they will not + # be interleaved by other tasks. + # + # @param [Array, Proc)>] posts array of triplets where + # first is a {ExecutorService}, second is array of args for task, third is a task (Proc) + def posts(posts) + # if can_overflow? + # raise ArgumentError, 'SerializedExecution does not support thread-pools which can overflow' + # end + + return nil if posts.empty? + + jobs = posts.map { |executor, args, task| Job.new executor, args, task } + + job_to_post = synchronize do + if @being_executed + @stash.push(*jobs) + nil + else + @being_executed = true + @stash.push(*jobs[1..-1]) + jobs.first + end + end + + call_job job_to_post if job_to_post + true + end + + private + + def ns_initialize + @being_executed = false + @stash = [] + end + + def call_job(job) + did_it_run = begin + job.executor.post { work(job) } + true + rescue RejectedExecutionError => ex + false + end + + # TODO not the best idea to run it myself + unless did_it_run + begin + work job + rescue => ex + # let it fail + log DEBUG, ex + end + end + end + + # ensures next job is executed if any is stashed + def work(job) + job.call + ensure + synchronize do + job = @stash.shift || (@being_executed = false) + end + + # TODO maybe be able to tell caching pool to just enqueue this job, because the current one end at the end + # of this block + call_job job if job + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb new file mode 100644 index 0000000..8197781 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb @@ -0,0 +1,28 @@ +require 'delegate' +require 'concurrent/executor/serial_executor_service' +require 'concurrent/executor/serialized_execution' + +module Concurrent + + # A wrapper/delegator for any `ExecutorService` that + # guarantees serialized execution of tasks. + # + # @see [SimpleDelegator](http://www.ruby-doc.org/stdlib-2.1.2/libdoc/delegate/rdoc/SimpleDelegator.html) + # @see Concurrent::SerializedExecution + class SerializedExecutionDelegator < SimpleDelegator + include SerialExecutorService + + def initialize(executor) + @executor = executor + @serializer = SerializedExecution.new + super(executor) + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + @serializer.post(@executor, *args, &task) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb new file mode 100644 index 0000000..0bc62af --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb @@ -0,0 +1,103 @@ +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/atomic/event' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/ruby_executor_service' + +module Concurrent + + # An executor service in which every operation spawns a new, + # independently operating thread. + # + # This is perhaps the most inefficient executor service in this + # library. It exists mainly for testing an debugging. Thread creation + # and management is expensive in Ruby and this executor performs no + # resource pooling. This can be very beneficial during testing and + # debugging because it decouples the using code from the underlying + # executor implementation. In production this executor will likely + # lead to suboptimal performance. + # + # @note Intended for use primarily in testing and debugging. + class SimpleExecutorService < RubyExecutorService + + # @!macro executor_service_method_post + def self.post(*args) + raise ArgumentError.new('no block given') unless block_given? + Thread.new(*args) do + Thread.current.abort_on_exception = false + yield(*args) + end + true + end + + # @!macro executor_service_method_left_shift + def self.<<(task) + post(&task) + self + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + @count.increment + Thread.new(*args) do + Thread.current.abort_on_exception = false + begin + yield(*args) + ensure + @count.decrement + @stopped.set if @running.false? && @count.value == 0 + end + end + end + + # @!macro executor_service_method_left_shift + def <<(task) + post(&task) + self + end + + # @!macro executor_service_method_running_question + def running? + @running.true? + end + + # @!macro executor_service_method_shuttingdown_question + def shuttingdown? + @running.false? && ! @stopped.set? + end + + # @!macro executor_service_method_shutdown_question + def shutdown? + @stopped.set? + end + + # @!macro executor_service_method_shutdown + def shutdown + @running.make_false + @stopped.set if @count.value == 0 + true + end + + # @!macro executor_service_method_kill + def kill + @running.make_false + @stopped.set + true + end + + # @!macro executor_service_method_wait_for_termination + def wait_for_termination(timeout = nil) + @stopped.wait(timeout) + end + + private + + def ns_initialize(*args) + @running = Concurrent::AtomicBoolean.new(true) + @stopped = Concurrent::Event.new + @count = Concurrent::AtomicFixnum.new(0) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb new file mode 100644 index 0000000..220eb0f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb @@ -0,0 +1,57 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/ruby_single_thread_executor' + +module Concurrent + + if Concurrent.on_jruby? + require 'concurrent/executor/java_single_thread_executor' + end + + SingleThreadExecutorImplementation = case + when Concurrent.on_jruby? + JavaSingleThreadExecutor + else + RubySingleThreadExecutor + end + private_constant :SingleThreadExecutorImplementation + + # @!macro single_thread_executor + # + # A thread pool with a single thread an unlimited queue. Should the thread + # die for any reason it will be removed and replaced, thus ensuring that + # the executor will always remain viable and available to process jobs. + # + # A common pattern for background processing is to create a single thread + # on which an infinite loop is run. The thread's loop blocks on an input + # source (perhaps blocking I/O or a queue) and processes each input as it + # is received. This pattern has several issues. The thread itself is highly + # susceptible to errors during processing. Also, the thread itself must be + # constantly monitored and restarted should it die. `SingleThreadExecutor` + # encapsulates all these behaviors. The task processor is highly resilient + # to errors from within tasks. Also, should the thread die it will + # automatically be restarted. + # + # The API and behavior of this class are based on Java's `SingleThreadExecutor`. + # + # @!macro abstract_executor_service_public_api + class SingleThreadExecutor < SingleThreadExecutorImplementation + + # @!macro single_thread_executor_method_initialize + # + # Create a new thread pool. + # + # @option opts [Symbol] :fallback_policy (:discard) the policy for handling new + # tasks that are received when the queue size has reached + # `max_queue` or the executor has shut down + # + # @raise [ArgumentError] if `:fallback_policy` is not one of the values specified + # in `FALLBACK_POLICIES` + # + # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html + + # @!method initialize(opts = {}) + # @!macro single_thread_executor_method_initialize + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb new file mode 100644 index 0000000..253d46a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb @@ -0,0 +1,88 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/ruby_thread_pool_executor' + +module Concurrent + + if Concurrent.on_jruby? + require 'concurrent/executor/java_thread_pool_executor' + end + + ThreadPoolExecutorImplementation = case + when Concurrent.on_jruby? + JavaThreadPoolExecutor + else + RubyThreadPoolExecutor + end + private_constant :ThreadPoolExecutorImplementation + + # @!macro thread_pool_executor + # + # An abstraction composed of one or more threads and a task queue. Tasks + # (blocks or `proc` objects) are submitted to the pool and added to the queue. + # The threads in the pool remove the tasks and execute them in the order + # they were received. + # + # A `ThreadPoolExecutor` will automatically adjust the pool size according + # to the bounds set by `min-threads` and `max-threads`. When a new task is + # submitted and fewer than `min-threads` threads are running, a new thread + # is created to handle the request, even if other worker threads are idle. + # If there are more than `min-threads` but less than `max-threads` threads + # running, a new thread will be created only if the queue is full. + # + # Threads that are idle for too long will be garbage collected, down to the + # configured minimum options. Should a thread crash it, too, will be garbage collected. + # + # `ThreadPoolExecutor` is based on the Java class of the same name. From + # the official Java documentation; + # + # > Thread pools address two different problems: they usually provide + # > improved performance when executing large numbers of asynchronous tasks, + # > due to reduced per-task invocation overhead, and they provide a means + # > of bounding and managing the resources, including threads, consumed + # > when executing a collection of tasks. Each ThreadPoolExecutor also + # > maintains some basic statistics, such as the number of completed tasks. + # > + # > To be useful across a wide range of contexts, this class provides many + # > adjustable parameters and extensibility hooks. However, programmers are + # > urged to use the more convenient Executors factory methods + # > [CachedThreadPool] (unbounded thread pool, with automatic thread reclamation), + # > [FixedThreadPool] (fixed size thread pool) and [SingleThreadExecutor] (single + # > background thread), that preconfigure settings for the most common usage + # > scenarios. + # + # @!macro thread_pool_options + # + # @!macro thread_pool_executor_public_api + class ThreadPoolExecutor < ThreadPoolExecutorImplementation + + # @!macro thread_pool_executor_method_initialize + # + # Create a new thread pool. + # + # @param [Hash] opts the options which configure the thread pool. + # + # @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum + # number of threads to be created + # @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted + # and fewer than `min_threads` are running, a new thread is created + # @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum + # number of seconds a thread may be idle before being reclaimed + # @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum + # number of tasks allowed in the work queue at any one time; a value of + # zero means the queue may grow without bound + # @option opts [Symbol] :fallback_policy (:abort) the policy for handling new + # tasks that are received when the queue size has reached + # `max_queue` or the executor has shut down + # @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0 + # for :max_queue means the queue must perform direct hand-off rather than unbounded. + # @raise [ArgumentError] if `:max_threads` is less than one + # @raise [ArgumentError] if `:min_threads` is less than zero + # @raise [ArgumentError] if `:fallback_policy` is not one of the values specified + # in `FALLBACK_POLICIES` + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html + + # @!method initialize(opts = {}) + # @!macro thread_pool_executor_method_initialize + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/timer_set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/timer_set.rb new file mode 100644 index 0000000..b936c7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executor/timer_set.rb @@ -0,0 +1,179 @@ +require 'concurrent/scheduled_task' +require 'concurrent/atomic/event' +require 'concurrent/collection/non_concurrent_priority_queue' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/single_thread_executor' +require 'concurrent/errors' +require 'concurrent/options' + +module Concurrent + + # Executes a collection of tasks, each after a given delay. A master task + # monitors the set and schedules each task for execution at the appropriate + # time. Tasks are run on the global thread pool or on the supplied executor. + # Each task is represented as a `ScheduledTask`. + # + # @see Concurrent::ScheduledTask + # + # @!macro monotonic_clock_warning + class TimerSet < RubyExecutorService + + # Create a new set of timed tasks. + # + # @!macro executor_options + # + # @param [Hash] opts the options used to specify the executor on which to perform actions + # @option opts [Executor] :executor when set use the given `Executor` instance. + # Three special values are also supported: `:task` returns the global task pool, + # `:operation` returns the global operation pool, and `:immediate` returns a new + # `ImmediateExecutor` object. + def initialize(opts = {}) + super(opts) + end + + # Post a task to be execute run after a given delay (in seconds). If the + # delay is less than 1/100th of a second the task will be immediately post + # to the executor. + # + # @param [Float] delay the number of seconds to wait for before executing the task. + # @param [Array] args the arguments passed to the task on execution. + # + # @yield the task to be performed. + # + # @return [Concurrent::ScheduledTask, false] IVar representing the task if the post + # is successful; false after shutdown. + # + # @raise [ArgumentError] if the intended execution time is not in the future. + # @raise [ArgumentError] if no block is given. + def post(delay, *args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + opts = { executor: @task_executor, + args: args, + timer_set: self } + task = ScheduledTask.execute(delay, opts, &task) # may raise exception + task.unscheduled? ? false : task + end + + # Begin an immediate shutdown. In-progress tasks will be allowed to + # complete but enqueued tasks will be dismissed and no new tasks + # will be accepted. Has no additional effect if the thread pool is + # not running. + def kill + shutdown + @timer_executor.kill + end + + private :<< + + private + + # Initialize the object. + # + # @param [Hash] opts the options to create the object with. + # @!visibility private + def ns_initialize(opts) + @queue = Collection::NonConcurrentPriorityQueue.new(order: :min) + @task_executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + @timer_executor = SingleThreadExecutor.new + @condition = Event.new + @ruby_pid = $$ # detects if Ruby has forked + end + + # Post the task to the internal queue. + # + # @note This is intended as a callback method from ScheduledTask + # only. It is not intended to be used directly. Post a task + # by using the `SchedulesTask#execute` method. + # + # @!visibility private + def post_task(task) + synchronize { ns_post_task(task) } + end + + # @!visibility private + def ns_post_task(task) + return false unless ns_running? + ns_reset_if_forked + if (task.initial_delay) <= 0.01 + task.executor.post { task.process_task } + else + @queue.push(task) + # only post the process method when the queue is empty + @timer_executor.post(&method(:process_tasks)) if @queue.length == 1 + @condition.set + end + true + end + + # Remove the given task from the queue. + # + # @note This is intended as a callback method from `ScheduledTask` + # only. It is not intended to be used directly. Cancel a task + # by using the `ScheduledTask#cancel` method. + # + # @!visibility private + def remove_task(task) + synchronize { @queue.delete(task) } + end + + # `ExecutorService` callback called during shutdown. + # + # @!visibility private + def ns_shutdown_execution + ns_reset_if_forked + @queue.clear + @condition.set + @condition.reset + @timer_executor.shutdown + stopped_event.set + end + + def ns_reset_if_forked + if $$ != @ruby_pid + @queue.clear + @condition.reset + @ruby_pid = $$ + end + end + + # Run a loop and execute tasks in the scheduled order and at the approximate + # scheduled time. If no tasks remain the thread will exit gracefully so that + # garbage collection can occur. If there are no ready tasks it will sleep + # for up to 60 seconds waiting for the next scheduled task. + # + # @!visibility private + def process_tasks + loop do + task = synchronize { @condition.reset; @queue.peek } + break unless task + + now = Concurrent.monotonic_time + diff = task.schedule_time - now + + if diff <= 0 + # We need to remove the task from the queue before passing + # it to the executor, to avoid race conditions where we pass + # the peek'ed task to the executor and then pop a different + # one that's been added in the meantime. + # + # Note that there's no race condition between the peek and + # this pop - this pop could retrieve a different task from + # the peek, but that task would be due to fire now anyway + # (because @queue is a priority queue, and this thread is + # the only reader, so whatever timer is at the head of the + # queue now must have the same pop time, or a closer one, as + # when we peeked). + task = synchronize { @queue.pop } + begin + task.executor.post { task.process_task } + rescue RejectedExecutionError + # ignore and continue + end + else + @condition.wait([diff, 60].min) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executors.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executors.rb new file mode 100644 index 0000000..5d5cd39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/executors.rb @@ -0,0 +1,19 @@ +require 'concurrent/executor/abstract_executor_service' +require 'concurrent/executor/cached_thread_pool' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/fixed_thread_pool' +require 'concurrent/executor/immediate_executor' +require 'concurrent/executor/indirect_immediate_executor' +require 'concurrent/executor/java_executor_service' +require 'concurrent/executor/java_single_thread_executor' +require 'concurrent/executor/java_thread_pool_executor' +require 'concurrent/executor/ruby_executor_service' +require 'concurrent/executor/ruby_single_thread_executor' +require 'concurrent/executor/ruby_thread_pool_executor' +require 'concurrent/executor/safe_task_executor' +require 'concurrent/executor/serial_executor_service' +require 'concurrent/executor/serialized_execution' +require 'concurrent/executor/serialized_execution_delegator' +require 'concurrent/executor/single_thread_executor' +require 'concurrent/executor/thread_pool_executor' +require 'concurrent/executor/timer_set' diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/future.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/future.rb new file mode 100644 index 0000000..1af182e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/future.rb @@ -0,0 +1,141 @@ +require 'thread' +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/ivar' +require 'concurrent/executor/safe_task_executor' + +require 'concurrent/options' + +# TODO (pitr-ch 14-Mar-2017): deprecate, Future, Promise, etc. + + +module Concurrent + + # {include:file:docs-source/future.md} + # + # @!macro copy_options + # + # @see http://ruby-doc.org/stdlib-2.1.1/libdoc/observer/rdoc/Observable.html Ruby Observable module + # @see http://clojuredocs.org/clojure_core/clojure.core/future Clojure's future function + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html java.util.concurrent.Future + class Future < IVar + + # Create a new `Future` in the `:unscheduled` state. + # + # @yield the asynchronous operation to perform + # + # @!macro executor_and_deref_options + # + # @option opts [object, Array] :args zero or more arguments to be passed the task + # block on execution + # + # @raise [ArgumentError] if no block is given + def initialize(opts = {}, &block) + raise ArgumentError.new('no block given') unless block_given? + super(NULL, opts.merge(__task_from_block__: block), &nil) + end + + # Execute an `:unscheduled` `Future`. Immediately sets the state to `:pending` and + # passes the block to a new thread/thread pool for eventual execution. + # Does nothing if the `Future` is in any state other than `:unscheduled`. + # + # @return [Future] a reference to `self` + # + # @example Instance and execute in separate steps + # future = Concurrent::Future.new{ sleep(1); 42 } + # future.state #=> :unscheduled + # future.execute + # future.state #=> :pending + # + # @example Instance and execute in one line + # future = Concurrent::Future.new{ sleep(1); 42 }.execute + # future.state #=> :pending + def execute + if compare_and_set_state(:pending, :unscheduled) + @executor.post{ safe_execute(@task, @args) } + self + end + end + + # Create a new `Future` object with the given block, execute it, and return the + # `:pending` object. + # + # @yield the asynchronous operation to perform + # + # @!macro executor_and_deref_options + # + # @option opts [object, Array] :args zero or more arguments to be passed the task + # block on execution + # + # @raise [ArgumentError] if no block is given + # + # @return [Future] the newly created `Future` in the `:pending` state + # + # @example + # future = Concurrent::Future.execute{ sleep(1); 42 } + # future.state #=> :pending + def self.execute(opts = {}, &block) + Future.new(opts, &block).execute + end + + # @!macro ivar_set_method + def set(value = NULL, &block) + check_for_block_or_value!(block_given?, value) + synchronize do + if @state != :unscheduled + raise MultipleAssignmentError + else + @task = block || Proc.new { value } + end + end + execute + end + + # Attempt to cancel the operation if it has not already processed. + # The operation can only be cancelled while still `pending`. It cannot + # be cancelled once it has begun processing or has completed. + # + # @return [Boolean] was the operation successfully cancelled. + def cancel + if compare_and_set_state(:cancelled, :pending) + complete(false, nil, CancelledOperationError.new) + true + else + false + end + end + + # Has the operation been successfully cancelled? + # + # @return [Boolean] + def cancelled? + state == :cancelled + end + + # Wait the given number of seconds for the operation to complete. + # On timeout attempt to cancel the operation. + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Boolean] true if the operation completed before the timeout + # else false + def wait_or_cancel(timeout) + wait(timeout) + if complete? + true + else + cancel + false + end + end + + protected + + def ns_initialize(value, opts) + super + @state = :unscheduled + @task = opts[:__task_from_block__] + @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + @args = get_arguments_from(opts) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/hash.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/hash.rb new file mode 100644 index 0000000..db0208e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/hash.rb @@ -0,0 +1,52 @@ +require 'concurrent/utility/engine' +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!macro concurrent_hash + # + # A thread-safe subclass of Hash. This version locks against the object + # itself for every method call, ensuring only one thread can be reading + # or writing at a time. This includes iteration methods like `#each`, + # which takes the lock repeatedly when reading an item. + # + # @see http://ruby-doc.org/core/Hash.html Ruby standard library `Hash` + + # @!macro internal_implementation_note + HashImplementation = case + when Concurrent.on_cruby? + # Hash is not fully thread-safe on CRuby, see + # https://bugs.ruby-lang.org/issues/19237 + # https://github.com/ruby/ruby/commit/ffd52412ab + # https://github.com/ruby-concurrency/concurrent-ruby/issues/929 + # So we will need to add synchronization here (similar to Concurrent::Map). + ::Hash + + when Concurrent.on_jruby? + require 'jruby/synchronized' + + class JRubyHash < ::Hash + include JRuby::Synchronized + end + JRubyHash + + when Concurrent.on_truffleruby? + require 'concurrent/thread_safe/util/data_structures' + + class TruffleRubyHash < ::Hash + end + + ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubyHash + TruffleRubyHash + + else + warn 'Possibly unsupported Ruby implementation' + ::Hash + end + private_constant :HashImplementation + + # @!macro concurrent_hash + class Hash < HashImplementation + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/immutable_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/immutable_struct.rb new file mode 100644 index 0000000..48462e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/immutable_struct.rb @@ -0,0 +1,101 @@ +require 'concurrent/synchronization/abstract_struct' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # A thread-safe, immutable variation of Ruby's standard `Struct`. + # + # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` + module ImmutableStruct + include Synchronization::AbstractStruct + + def self.included(base) + base.safe_initialization! + end + + # @!macro struct_values + def values + ns_values + end + + alias_method :to_a, :values + + # @!macro struct_values_at + def values_at(*indexes) + ns_values_at(indexes) + end + + # @!macro struct_inspect + def inspect + ns_inspect + end + + alias_method :to_s, :inspect + + # @!macro struct_merge + def merge(other, &block) + ns_merge(other, &block) + end + + # @!macro struct_to_h + def to_h + ns_to_h + end + + # @!macro struct_get + def [](member) + ns_get(member) + end + + # @!macro struct_equality + def ==(other) + ns_equality(other) + end + + # @!macro struct_each + def each(&block) + return enum_for(:each) unless block_given? + ns_each(&block) + end + + # @!macro struct_each_pair + def each_pair(&block) + return enum_for(:each_pair) unless block_given? + ns_each_pair(&block) + end + + # @!macro struct_select + def select(&block) + return enum_for(:select) unless block_given? + ns_select(&block) + end + + private + + # @!visibility private + def initialize_copy(original) + super(original) + ns_initialize_copy + end + + # @!macro struct_new + def self.new(*args, &block) + clazz_name = nil + if args.length == 0 + raise ArgumentError.new('wrong number of arguments (0 for 1+)') + elsif args.length > 0 && args.first.is_a?(String) + clazz_name = args.shift + end + FACTORY.define_struct(clazz_name, args, &block) + end + + FACTORY = Class.new(Synchronization::LockableObject) do + def define_struct(name, members, &block) + synchronize do + Synchronization::AbstractStruct.define_struct_class(ImmutableStruct, Synchronization::Object, name, members, &block) + end + end + end.new + private_constant :FACTORY + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/ivar.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/ivar.rb new file mode 100644 index 0000000..4165038 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/ivar.rb @@ -0,0 +1,208 @@ +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/collection/copy_on_write_observer_set' +require 'concurrent/concern/obligation' +require 'concurrent/concern/observable' +require 'concurrent/executor/safe_task_executor' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # An `IVar` is like a future that you can assign. As a future is a value that + # is being computed that you can wait on, an `IVar` is a value that is waiting + # to be assigned, that you can wait on. `IVars` are single assignment and + # deterministic. + # + # Then, express futures as an asynchronous computation that assigns an `IVar`. + # The `IVar` becomes the primitive on which [futures](Future) and + # [dataflow](Dataflow) are built. + # + # An `IVar` is a single-element container that is normally created empty, and + # can only be set once. The I in `IVar` stands for immutable. Reading an + # `IVar` normally blocks until it is set. It is safe to set and read an `IVar` + # from different threads. + # + # If you want to have some parallel task set the value in an `IVar`, you want + # a `Future`. If you want to create a graph of parallel tasks all executed + # when the values they depend on are ready you want `dataflow`. `IVar` is + # generally a low-level primitive. + # + # ## Examples + # + # Create, set and get an `IVar` + # + # ```ruby + # ivar = Concurrent::IVar.new + # ivar.set 14 + # ivar.value #=> 14 + # ivar.set 2 # would now be an error + # ``` + # + # ## See Also + # + # 1. For the theory: Arvind, R. Nikhil, and K. Pingali. + # [I-Structures: Data structures for parallel computing](http://dl.acm.org/citation.cfm?id=69562). + # In Proceedings of Workshop on Graph Reduction, 1986. + # 2. For recent application: + # [DataDrivenFuture in Habanero Java from Rice](http://www.cs.rice.edu/~vs3/hjlib/doc/edu/rice/hj/api/HjDataDrivenFuture.html). + class IVar < Synchronization::LockableObject + include Concern::Obligation + include Concern::Observable + + # Create a new `IVar` in the `:pending` state with the (optional) initial value. + # + # @param [Object] value the initial value + # @param [Hash] opts the options to create a message with + # @option opts [String] :dup_on_deref (false) call `#dup` before returning + # the data + # @option opts [String] :freeze_on_deref (false) call `#freeze` before + # returning the data + # @option opts [String] :copy_on_deref (nil) call the given `Proc` passing + # the internal value and returning the value returned from the proc + def initialize(value = NULL, opts = {}, &block) + if value != NULL && block_given? + raise ArgumentError.new('provide only a value or a block') + end + super(&nil) + synchronize { ns_initialize(value, opts, &block) } + end + + # Add an observer on this object that will receive notification on update. + # + # Upon completion the `IVar` will notify all observers in a thread-safe way. + # The `func` method of the observer will be called with three arguments: the + # `Time` at which the `Future` completed the asynchronous operation, the + # final `value` (or `nil` on rejection), and the final `reason` (or `nil` on + # fulfillment). + # + # @param [Object] observer the object that will be notified of changes + # @param [Symbol] func symbol naming the method to call when this + # `Observable` has changes` + def add_observer(observer = nil, func = :update, &block) + raise ArgumentError.new('cannot provide both an observer and a block') if observer && block + direct_notification = false + + if block + observer = block + func = :call + end + + synchronize do + if event.set? + direct_notification = true + else + observers.add_observer(observer, func) + end + end + + observer.send(func, Time.now, self.value, reason) if direct_notification + observer + end + + # @!macro ivar_set_method + # Set the `IVar` to a value and wake or notify all threads waiting on it. + # + # @!macro ivar_set_parameters_and_exceptions + # @param [Object] value the value to store in the `IVar` + # @yield A block operation to use for setting the value + # @raise [ArgumentError] if both a value and a block are given + # @raise [Concurrent::MultipleAssignmentError] if the `IVar` has already + # been set or otherwise completed + # + # @return [IVar] self + def set(value = NULL) + check_for_block_or_value!(block_given?, value) + raise MultipleAssignmentError unless compare_and_set_state(:processing, :pending) + + begin + value = yield if block_given? + complete_without_notification(true, value, nil) + rescue => ex + complete_without_notification(false, nil, ex) + end + + notify_observers(self.value, reason) + self + end + + # @!macro ivar_fail_method + # Set the `IVar` to failed due to some error and wake or notify all threads waiting on it. + # + # @param [Object] reason for the failure + # @raise [Concurrent::MultipleAssignmentError] if the `IVar` has already + # been set or otherwise completed + # @return [IVar] self + def fail(reason = StandardError.new) + complete(false, nil, reason) + end + + # Attempt to set the `IVar` with the given value or block. Return a + # boolean indicating the success or failure of the set operation. + # + # @!macro ivar_set_parameters_and_exceptions + # + # @return [Boolean] true if the value was set else false + def try_set(value = NULL, &block) + set(value, &block) + true + rescue MultipleAssignmentError + false + end + + protected + + # @!visibility private + def ns_initialize(value, opts) + value = yield if block_given? + init_obligation + self.observers = Collection::CopyOnWriteObserverSet.new + set_deref_options(opts) + + @state = :pending + if value != NULL + ns_complete_without_notification(true, value, nil) + end + end + + # @!visibility private + def safe_execute(task, args = []) + if compare_and_set_state(:processing, :pending) + success, val, reason = SafeTaskExecutor.new(task, rescue_exception: true).execute(*@args) + complete(success, val, reason) + yield(success, val, reason) if block_given? + end + end + + # @!visibility private + def complete(success, value, reason) + complete_without_notification(success, value, reason) + notify_observers(self.value, reason) + self + end + + # @!visibility private + def complete_without_notification(success, value, reason) + synchronize { ns_complete_without_notification(success, value, reason) } + self + end + + # @!visibility private + def notify_observers(value, reason) + observers.notify_and_delete_observers{ [Time.now, value, reason] } + end + + # @!visibility private + def ns_complete_without_notification(success, value, reason) + raise MultipleAssignmentError if [:fulfilled, :rejected].include? @state + set_state(success, value, reason) + event.set + end + + # @!visibility private + def check_for_block_or_value!(block_given, value) # :nodoc: + if (block_given && value != NULL) || (! block_given && value == NULL) + raise ArgumentError.new('must set with either a value or a block') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/map.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/map.rb new file mode 100644 index 0000000..b263f83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/map.rb @@ -0,0 +1,350 @@ +require 'thread' +require 'concurrent/constants' +require 'concurrent/utility/engine' + +module Concurrent + # @!visibility private + module Collection + + # @!visibility private + MapImplementation = case + when Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + # noinspection RubyResolve + JRubyMapBackend + when Concurrent.on_cruby? + require 'concurrent/collection/map/mri_map_backend' + MriMapBackend + when Concurrent.on_truffleruby? + if defined?(::TruffleRuby::ConcurrentMap) + require 'concurrent/collection/map/truffleruby_map_backend' + TruffleRubyMapBackend + else + require 'concurrent/collection/map/synchronized_map_backend' + SynchronizedMapBackend + end + else + warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation' + require 'concurrent/collection/map/synchronized_map_backend' + SynchronizedMapBackend + end + end + + # `Concurrent::Map` is a hash-like object and should have much better performance + # characteristics, especially under high concurrency, than `Concurrent::Hash`. + # However, `Concurrent::Map `is not strictly semantically equivalent to a ruby `Hash` + # -- for instance, it does not necessarily retain ordering by insertion time as `Hash` + # does. For most uses it should do fine though, and we recommend you consider + # `Concurrent::Map` instead of `Concurrent::Hash` for your concurrency-safe hash needs. + class Map < Collection::MapImplementation + + # @!macro map.atomic_method + # This method is atomic. + + # @!macro map.atomic_method_with_block + # This method is atomic. + # @note Atomic methods taking a block do not allow the `self` instance + # to be used within the block. Doing so will cause a deadlock. + + # @!method []=(key, value) + # Set a value with key + # @param [Object] key + # @param [Object] value + # @return [Object] the new value + + # @!method compute_if_absent(key) + # Compute and store new value for key if the key is absent. + # @param [Object] key + # @yield new value + # @yieldreturn [Object] new value + # @return [Object] new value or current value + # @!macro map.atomic_method_with_block + + # @!method compute_if_present(key) + # Compute and store new value for key if the key is present. + # @param [Object] key + # @yield new value + # @yieldparam old_value [Object] + # @yieldreturn [Object, nil] new value, when nil the key is removed + # @return [Object, nil] new value or nil + # @!macro map.atomic_method_with_block + + # @!method compute(key) + # Compute and store new value for key. + # @param [Object] key + # @yield compute new value from old one + # @yieldparam old_value [Object, nil] old_value, or nil when key is absent + # @yieldreturn [Object, nil] new value, when nil the key is removed + # @return [Object, nil] new value or nil + # @!macro map.atomic_method_with_block + + # @!method merge_pair(key, value) + # If the key is absent, the value is stored, otherwise new value is + # computed with a block. + # @param [Object] key + # @param [Object] value + # @yield compute new value from old one + # @yieldparam old_value [Object] old value + # @yieldreturn [Object, nil] new value, when nil the key is removed + # @return [Object, nil] new value or nil + # @!macro map.atomic_method_with_block + + # @!method replace_pair(key, old_value, new_value) + # Replaces old_value with new_value if key exists and current value + # matches old_value + # @param [Object] key + # @param [Object] old_value + # @param [Object] new_value + # @return [true, false] true if replaced + # @!macro map.atomic_method + + # @!method replace_if_exists(key, new_value) + # Replaces current value with new_value if key exists + # @param [Object] key + # @param [Object] new_value + # @return [Object, nil] old value or nil + # @!macro map.atomic_method + + # @!method get_and_set(key, value) + # Get the current value under key and set new value. + # @param [Object] key + # @param [Object] value + # @return [Object, nil] old value or nil when the key was absent + # @!macro map.atomic_method + + # @!method delete(key) + # Delete key and its value. + # @param [Object] key + # @return [Object, nil] old value or nil when the key was absent + # @!macro map.atomic_method + + # @!method delete_pair(key, value) + # Delete pair and its value if current value equals the provided value. + # @param [Object] key + # @param [Object] value + # @return [true, false] true if deleted + # @!macro map.atomic_method + + # NonConcurrentMapBackend handles default_proc natively + unless defined?(Collection::NonConcurrentMapBackend) and self < Collection::NonConcurrentMapBackend + + # @param [Hash, nil] options options to set the :initial_capacity or :load_factor. Ignored on some Rubies. + # @param [Proc] default_proc Optional block to compute the default value if the key is not set, like `Hash#default_proc` + def initialize(options = nil, &default_proc) + if options.kind_of?(::Hash) + validate_options_hash!(options) + else + options = nil + end + + super(options) + @default_proc = default_proc + end + + # Get a value with key + # @param [Object] key + # @return [Object] the value + def [](key) + if value = super # non-falsy value is an existing mapping, return it right away + value + # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call + # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrect +nil+ value + # would be returned) + # note: nil == value check is not technically necessary + elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL)) + @default_proc.call(self, key) + else + value + end + end + end + + alias_method :get, :[] + alias_method :put, :[]= + + # Get a value with key, or default_value when key is absent, + # or fail when no default_value is given. + # @param [Object] key + # @param [Object] default_value + # @yield default value for a key + # @yieldparam key [Object] + # @yieldreturn [Object] default value + # @return [Object] the value or default value + # @raise [KeyError] when key is missing and no default_value is provided + # @!macro map_method_not_atomic + # @note The "fetch-then-act" methods of `Map` are not atomic. `Map` is intended + # to be use as a concurrency primitive with strong happens-before + # guarantees. It is not intended to be used as a high-level abstraction + # supporting complex operations. All read and write operations are + # thread safe, but no guarantees are made regarding race conditions + # between the fetch operation and yielding to the block. Additionally, + # this method does not support recursion. This is due to internal + # constraints that are very unlikely to change in the near future. + def fetch(key, default_value = NULL) + if NULL != (value = get_or_default(key, NULL)) + value + elsif block_given? + yield key + elsif NULL != default_value + default_value + else + raise_fetch_no_key + end + end + + # Fetch value with key, or store default value when key is absent, + # or fail when no default_value is given. This is a two step operation, + # therefore not atomic. The store can overwrite other concurrently + # stored value. + # @param [Object] key + # @param [Object] default_value + # @yield default value for a key + # @yieldparam key [Object] + # @yieldreturn [Object] default value + # @return [Object] the value or default value + def fetch_or_store(key, default_value = NULL) + fetch(key) do + put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value)) + end + end + + # Insert value into map with key if key is absent in one atomic step. + # @param [Object] key + # @param [Object] value + # @return [Object, nil] the previous value when key was present or nil when there was no key + def put_if_absent(key, value) + computed = false + result = compute_if_absent(key) do + computed = true + value + end + computed ? nil : result + end unless method_defined?(:put_if_absent) + + # Is the value stored in the map. Iterates over all values. + # @param [Object] value + # @return [true, false] + def value?(value) + each_value do |v| + return true if value.equal?(v) + end + false + end + + # All keys + # @return [::Array] keys + def keys + arr = [] + each_pair { |k, v| arr << k } + arr + end unless method_defined?(:keys) + + # All values + # @return [::Array] values + def values + arr = [] + each_pair { |k, v| arr << v } + arr + end unless method_defined?(:values) + + # Iterates over each key. + # @yield for each key in the map + # @yieldparam key [Object] + # @return [self] + # @!macro map.atomic_method_with_block + def each_key + each_pair { |k, v| yield k } + end unless method_defined?(:each_key) + + # Iterates over each value. + # @yield for each value in the map + # @yieldparam value [Object] + # @return [self] + # @!macro map.atomic_method_with_block + def each_value + each_pair { |k, v| yield v } + end unless method_defined?(:each_value) + + # Iterates over each key value pair. + # @yield for each key value pair in the map + # @yieldparam key [Object] + # @yieldparam value [Object] + # @return [self] + # @!macro map.atomic_method_with_block + def each_pair + return enum_for :each_pair unless block_given? + super + end + + alias_method :each, :each_pair unless method_defined?(:each) + + # Find key of a value. + # @param [Object] value + # @return [Object, nil] key or nil when not found + def key(value) + each_pair { |k, v| return k if v == value } + nil + end unless method_defined?(:key) + + # Is map empty? + # @return [true, false] + def empty? + each_pair { |k, v| return false } + true + end unless method_defined?(:empty?) + + # The size of map. + # @return [Integer] size + def size + count = 0 + each_pair { |k, v| count += 1 } + count + end unless method_defined?(:size) + + # @!visibility private + def marshal_dump + raise TypeError, "can't dump hash with default proc" if @default_proc + h = {} + each_pair { |k, v| h[k] = v } + h + end + + # @!visibility private + def marshal_load(hash) + initialize + populate_from(hash) + end + + undef :freeze + + # @!visibility private + def inspect + format '%s entries=%d default_proc=%s>', to_s[0..-2], size.to_s, @default_proc.inspect + end + + private + + def raise_fetch_no_key + raise KeyError, 'key not found' + end + + def initialize_copy(other) + super + populate_from(other) + end + + def populate_from(hash) + hash.each_pair { |k, v| self[k] = v } + self + end + + def validate_options_hash!(options) + if (initial_capacity = options[:initial_capacity]) && (!initial_capacity.kind_of?(Integer) || initial_capacity < 0) + raise ArgumentError, ":initial_capacity must be a positive Integer" + end + if (load_factor = options[:load_factor]) && (!load_factor.kind_of?(Numeric) || load_factor <= 0 || load_factor > 1) + raise ArgumentError, ":load_factor must be a number between 0 and 1" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/maybe.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/maybe.rb new file mode 100644 index 0000000..317c82b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/maybe.rb @@ -0,0 +1,229 @@ +require 'concurrent/synchronization/object' + +module Concurrent + + # A `Maybe` encapsulates an optional value. A `Maybe` either contains a value + # of (represented as `Just`), or it is empty (represented as `Nothing`). Using + # `Maybe` is a good way to deal with errors or exceptional cases without + # resorting to drastic measures such as exceptions. + # + # `Maybe` is a replacement for the use of `nil` with better type checking. + # + # For compatibility with {Concurrent::Concern::Obligation} the predicate and + # accessor methods are aliased as `fulfilled?`, `rejected?`, `value`, and + # `reason`. + # + # ## Motivation + # + # A common pattern in languages with pattern matching, such as Erlang and + # Haskell, is to return *either* a value *or* an error from a function + # Consider this Erlang code: + # + # ```erlang + # case file:consult("data.dat") of + # {ok, Terms} -> do_something_useful(Terms); + # {error, Reason} -> lager:error(Reason) + # end. + # ``` + # + # In this example the standard library function `file:consult` returns a + # [tuple](http://erlang.org/doc/reference_manual/data_types.html#id69044) + # with two elements: an [atom](http://erlang.org/doc/reference_manual/data_types.html#id64134) + # (similar to a ruby symbol) and a variable containing ancillary data. On + # success it returns the atom `ok` and the data from the file. On failure it + # returns `error` and a string with an explanation of the problem. With this + # pattern there is no ambiguity regarding success or failure. If the file is + # empty the return value cannot be misinterpreted as an error. And when an + # error occurs the return value provides useful information. + # + # In Ruby we tend to return `nil` when an error occurs or else we raise an + # exception. Both of these idioms are problematic. Returning `nil` is + # ambiguous because `nil` may also be a valid value. It also lacks + # information pertaining to the nature of the error. Raising an exception + # is both expensive and usurps the normal flow of control. All of these + # problems can be solved with the use of a `Maybe`. + # + # A `Maybe` is unambiguous with regard to whether or not it contains a value. + # When `Just` it contains a value, when `Nothing` it does not. When `Just` + # the value it contains may be `nil`, which is perfectly valid. When + # `Nothing` the reason for the lack of a value is contained as well. The + # previous Erlang example can be duplicated in Ruby in a principled way by + # having functions return `Maybe` objects: + # + # ```ruby + # result = MyFileUtils.consult("data.dat") # returns a Maybe + # if result.just? + # do_something_useful(result.value) # or result.just + # else + # logger.error(result.reason) # or result.nothing + # end + # ``` + # + # @example Returning a Maybe from a Function + # module MyFileUtils + # def self.consult(path) + # file = File.open(path, 'r') + # Concurrent::Maybe.just(file.read) + # rescue => ex + # return Concurrent::Maybe.nothing(ex) + # ensure + # file.close if file + # end + # end + # + # maybe = MyFileUtils.consult('bogus.file') + # maybe.just? #=> false + # maybe.nothing? #=> true + # maybe.reason #=> # + # + # maybe = MyFileUtils.consult('README.md') + # maybe.just? #=> true + # maybe.nothing? #=> false + # maybe.value #=> "# Concurrent Ruby\n[![Gem Version..." + # + # @example Using Maybe with a Block + # result = Concurrent::Maybe.from do + # Client.find(10) # Client is an ActiveRecord model + # end + # + # # -- if the record was found + # result.just? #=> true + # result.value #=> # + # + # # -- if the record was not found + # result.just? #=> false + # result.reason #=> ActiveRecord::RecordNotFound + # + # @example Using Maybe with the Null Object Pattern + # # In a Rails controller... + # result = ClientService.new(10).find # returns a Maybe + # render json: result.or(NullClient.new) + # + # @see https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html Haskell Data.Maybe + # @see https://github.com/purescript/purescript-maybe/blob/master/docs/Data.Maybe.md PureScript Data.Maybe + class Maybe < Synchronization::Object + include Comparable + safe_initialization! + + # Indicates that the given attribute has not been set. + # When `Just` the {#nothing} getter will return `NONE`. + # When `Nothing` the {#just} getter will return `NONE`. + NONE = ::Object.new.freeze + + # The value of a `Maybe` when `Just`. Will be `NONE` when `Nothing`. + attr_reader :just + + # The reason for the `Maybe` when `Nothing`. Will be `NONE` when `Just`. + attr_reader :nothing + + private_class_method :new + + # Create a new `Maybe` using the given block. + # + # Runs the given block passing all function arguments to the block as block + # arguments. If the block runs to completion without raising an exception + # a new `Just` is created with the value set to the return value of the + # block. If the block raises an exception a new `Nothing` is created with + # the reason being set to the raised exception. + # + # @param [Array] args Zero or more arguments to pass to the block. + # @yield The block from which to create a new `Maybe`. + # @yieldparam [Array] args Zero or more block arguments passed as + # arguments to the function. + # + # @return [Maybe] The newly created object. + # + # @raise [ArgumentError] when no block given. + def self.from(*args) + raise ArgumentError.new('no block given') unless block_given? + begin + value = yield(*args) + return new(value, NONE) + rescue => ex + return new(NONE, ex) + end + end + + # Create a new `Just` with the given value. + # + # @param [Object] value The value to set for the new `Maybe` object. + # + # @return [Maybe] The newly created object. + def self.just(value) + return new(value, NONE) + end + + # Create a new `Nothing` with the given (optional) reason. + # + # @param [Exception] error The reason to set for the new `Maybe` object. + # When given a string a new `StandardError` will be created with the + # argument as the message. When no argument is given a new + # `StandardError` with an empty message will be created. + # + # @return [Maybe] The newly created object. + def self.nothing(error = '') + if error.is_a?(Exception) + nothing = error + else + nothing = StandardError.new(error.to_s) + end + return new(NONE, nothing) + end + + # Is this `Maybe` a `Just` (successfully fulfilled with a value)? + # + # @return [Boolean] True if `Just` or false if `Nothing`. + def just? + ! nothing? + end + alias :fulfilled? :just? + + # Is this `Maybe` a `nothing` (rejected with an exception upon fulfillment)? + # + # @return [Boolean] True if `Nothing` or false if `Just`. + def nothing? + @nothing != NONE + end + alias :rejected? :nothing? + + alias :value :just + + alias :reason :nothing + + # Comparison operator. + # + # @return [Integer] 0 if self and other are both `Nothing`; + # -1 if self is `Nothing` and other is `Just`; + # 1 if self is `Just` and other is nothing; + # `self.just <=> other.just` if both self and other are `Just`. + def <=>(other) + if nothing? + other.nothing? ? 0 : -1 + else + other.nothing? ? 1 : just <=> other.just + end + end + + # Return either the value of self or the given default value. + # + # @return [Object] The value of self when `Just`; else the given default. + def or(other) + just? ? just : other + end + + private + + # Create a new `Maybe` with the given attributes. + # + # @param [Object] just The value when `Just` else `NONE`. + # @param [Exception, Object] nothing The exception when `Nothing` else `NONE`. + # + # @return [Maybe] The new `Maybe`. + # + # @!visibility private + def initialize(just, nothing) + @just = just + @nothing = nothing + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mutable_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mutable_struct.rb new file mode 100644 index 0000000..5d0e9b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mutable_struct.rb @@ -0,0 +1,239 @@ +require 'concurrent/synchronization/abstract_struct' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # An thread-safe variation of Ruby's standard `Struct`. Values can be set at + # construction or safely changed at any time during the object's lifecycle. + # + # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` + module MutableStruct + include Synchronization::AbstractStruct + + # @!macro struct_new + # + # Factory for creating new struct classes. + # + # ``` + # new([class_name] [, member_name]+>) -> StructClass click to toggle source + # new([class_name] [, member_name]+>) {|StructClass| block } -> StructClass + # new(value, ...) -> obj + # StructClass[value, ...] -> obj + # ``` + # + # The first two forms are used to create a new struct subclass `class_name` + # that can contain a value for each member_name . This subclass can be + # used to create instances of the structure like any other Class . + # + # If the `class_name` is omitted an anonymous struct class will be created. + # Otherwise, the name of this struct will appear as a constant in the struct class, + # so it must be unique for all structs under this base class and must start with a + # capital letter. Assigning a struct class to a constant also gives the class + # the name of the constant. + # + # If a block is given it will be evaluated in the context of `StructClass`, passing + # the created class as a parameter. This is the recommended way to customize a struct. + # Subclassing an anonymous struct creates an extra anonymous class that will never be used. + # + # The last two forms create a new instance of a struct subclass. The number of value + # parameters must be less than or equal to the number of attributes defined for the + # struct. Unset parameters default to nil. Passing more parameters than number of attributes + # will raise an `ArgumentError`. + # + # @see http://ruby-doc.org/core/Struct.html#method-c-new Ruby standard library `Struct#new` + + # @!macro struct_values + # + # Returns the values for this struct as an Array. + # + # @return [Array] the values for this struct + # + def values + synchronize { ns_values } + end + alias_method :to_a, :values + + # @!macro struct_values_at + # + # Returns the struct member values for each selector as an Array. + # + # A selector may be either an Integer offset or a Range of offsets (as in `Array#values_at`). + # + # @param [Fixnum, Range] indexes the index(es) from which to obatin the values (in order) + def values_at(*indexes) + synchronize { ns_values_at(indexes) } + end + + # @!macro struct_inspect + # + # Describe the contents of this struct in a string. + # + # @return [String] the contents of this struct in a string + def inspect + synchronize { ns_inspect } + end + alias_method :to_s, :inspect + + # @!macro struct_merge + # + # Returns a new struct containing the contents of `other` and the contents + # of `self`. If no block is specified, the value for entries with duplicate + # keys will be that of `other`. Otherwise the value for each duplicate key + # is determined by calling the block with the key, its value in `self` and + # its value in `other`. + # + # @param [Hash] other the hash from which to set the new values + # @yield an options block for resolving duplicate keys + # @yieldparam [String, Symbol] member the name of the member which is duplicated + # @yieldparam [Object] selfvalue the value of the member in `self` + # @yieldparam [Object] othervalue the value of the member in `other` + # + # @return [Synchronization::AbstractStruct] a new struct with the new values + # + # @raise [ArgumentError] of given a member that is not defined in the struct + def merge(other, &block) + synchronize { ns_merge(other, &block) } + end + + # @!macro struct_to_h + # + # Returns a hash containing the names and values for the struct’s members. + # + # @return [Hash] the names and values for the struct’s members + def to_h + synchronize { ns_to_h } + end + + # @!macro struct_get + # + # Attribute Reference + # + # @param [Symbol, String, Integer] member the string or symbol name of the member + # for which to obtain the value or the member's index + # + # @return [Object] the value of the given struct member or the member at the given index. + # + # @raise [NameError] if the member does not exist + # @raise [IndexError] if the index is out of range. + def [](member) + synchronize { ns_get(member) } + end + + # @!macro struct_equality + # + # Equality + # + # @return [Boolean] true if other has the same struct subclass and has + # equal member values (according to `Object#==`) + def ==(other) + synchronize { ns_equality(other) } + end + + # @!macro struct_each + # + # Yields the value of each struct member in order. If no block is given + # an enumerator is returned. + # + # @yield the operation to be performed on each struct member + # @yieldparam [Object] value each struct value (in order) + def each(&block) + return enum_for(:each) unless block_given? + synchronize { ns_each(&block) } + end + + # @!macro struct_each_pair + # + # Yields the name and value of each struct member in order. If no block is + # given an enumerator is returned. + # + # @yield the operation to be performed on each struct member/value pair + # @yieldparam [Object] member each struct member (in order) + # @yieldparam [Object] value each struct value (in order) + def each_pair(&block) + return enum_for(:each_pair) unless block_given? + synchronize { ns_each_pair(&block) } + end + + # @!macro struct_select + # + # Yields each member value from the struct to the block and returns an Array + # containing the member values from the struct for which the given block + # returns a true value (equivalent to `Enumerable#select`). + # + # @yield the operation to be performed on each struct member + # @yieldparam [Object] value each struct value (in order) + # + # @return [Array] an array containing each value for which the block returns true + def select(&block) + return enum_for(:select) unless block_given? + synchronize { ns_select(&block) } + end + + # @!macro struct_set + # + # Attribute Assignment + # + # Sets the value of the given struct member or the member at the given index. + # + # @param [Symbol, String, Integer] member the string or symbol name of the member + # for which to obtain the value or the member's index + # + # @return [Object] the value of the given struct member or the member at the given index. + # + # @raise [NameError] if the name does not exist + # @raise [IndexError] if the index is out of range. + def []=(member, value) + if member.is_a? Integer + length = synchronize { @values.length } + if member >= length + raise IndexError.new("offset #{member} too large for struct(size:#{length})") + end + synchronize { @values[member] = value } + else + send("#{member}=", value) + end + rescue NoMethodError + raise NameError.new("no member '#{member}' in struct") + end + + private + + # @!visibility private + def initialize_copy(original) + synchronize do + super(original) + ns_initialize_copy + end + end + + # @!macro struct_new + def self.new(*args, &block) + clazz_name = nil + if args.length == 0 + raise ArgumentError.new('wrong number of arguments (0 for 1+)') + elsif args.length > 0 && args.first.is_a?(String) + clazz_name = args.shift + end + FACTORY.define_struct(clazz_name, args, &block) + end + + FACTORY = Class.new(Synchronization::LockableObject) do + def define_struct(name, members, &block) + synchronize do + clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, &block) + members.each_with_index do |member, index| + clazz.send :remove_method, member + clazz.send(:define_method, member) do + synchronize { @values[index] } + end + clazz.send(:define_method, "#{member}=") do |value| + synchronize { @values[index] = value } + end + end + clazz + end + end + end.new + private_constant :FACTORY + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mvar.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mvar.rb new file mode 100644 index 0000000..9777ba3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/mvar.rb @@ -0,0 +1,242 @@ +require 'concurrent/concern/dereferenceable' +require 'concurrent/synchronization/object' + +module Concurrent + + # An `MVar` is a synchronized single element container. They are empty or + # contain one item. Taking a value from an empty `MVar` blocks, as does + # putting a value into a full one. You can either think of them as blocking + # queue of length one, or a special kind of mutable variable. + # + # On top of the fundamental `#put` and `#take` operations, we also provide a + # `#modify` that is atomic with respect to operations on the same instance. + # These operations all support timeouts. + # + # We also support non-blocking operations `#try_put!` and `#try_take!`, a + # `#set!` that ignores existing values, a `#value` that returns the value + # without removing it or returns `MVar::EMPTY`, and a `#modify!` that yields + # `MVar::EMPTY` if the `MVar` is empty and can be used to set `MVar::EMPTY`. + # You shouldn't use these operations in the first instance. + # + # `MVar` is a [Dereferenceable](Dereferenceable). + # + # `MVar` is related to M-structures in Id, `MVar` in Haskell and `SyncVar` in Scala. + # + # Note that unlike the original Haskell paper, our `#take` is blocking. This is how + # Haskell and Scala do it today. + # + # @!macro copy_options + # + # ## See Also + # + # 1. P. Barth, R. Nikhil, and Arvind. [M-Structures: Extending a parallel, non- strict, functional language with state](http://dl.acm.org/citation.cfm?id=652538). In Proceedings of the 5th + # ACM Conference on Functional Programming Languages and Computer Architecture (FPCA), 1991. + # + # 2. S. Peyton Jones, A. Gordon, and S. Finne. [Concurrent Haskell](http://dl.acm.org/citation.cfm?id=237794). + # In Proceedings of the 23rd Symposium on Principles of Programming Languages + # (PoPL), 1996. + class MVar < Synchronization::Object + include Concern::Dereferenceable + safe_initialization! + + # Unique value that represents that an `MVar` was empty + EMPTY = ::Object.new + + # Unique value that represents that an `MVar` timed out before it was able + # to produce a value. + TIMEOUT = ::Object.new + + # Create a new `MVar`, either empty or with an initial value. + # + # @param [Hash] opts the options controlling how the future will be processed + # + # @!macro deref_options + def initialize(value = EMPTY, opts = {}) + @value = value + @mutex = Mutex.new + @empty_condition = ConditionVariable.new + @full_condition = ConditionVariable.new + set_deref_options(opts) + end + + # Remove the value from an `MVar`, leaving it empty, and blocking if there + # isn't a value. A timeout can be set to limit the time spent blocked, in + # which case it returns `TIMEOUT` if the time is exceeded. + # @return [Object] the value that was taken, or `TIMEOUT` + def take(timeout = nil) + @mutex.synchronize do + wait_for_full(timeout) + + # If we timed out we'll still be empty + if unlocked_full? + value = @value + @value = EMPTY + @empty_condition.signal + apply_deref_options(value) + else + TIMEOUT + end + end + end + + # acquires lock on the from an `MVAR`, yields the value to provided block, + # and release lock. A timeout can be set to limit the time spent blocked, + # in which case it returns `TIMEOUT` if the time is exceeded. + # @return [Object] the value returned by the block, or `TIMEOUT` + def borrow(timeout = nil) + @mutex.synchronize do + wait_for_full(timeout) + + # If we timed out we'll still be empty + if unlocked_full? + yield @value + else + TIMEOUT + end + end + end + + # Put a value into an `MVar`, blocking if there is already a value until + # it is empty. A timeout can be set to limit the time spent blocked, in + # which case it returns `TIMEOUT` if the time is exceeded. + # @return [Object] the value that was put, or `TIMEOUT` + def put(value, timeout = nil) + @mutex.synchronize do + wait_for_empty(timeout) + + # If we timed out we won't be empty + if unlocked_empty? + @value = value + @full_condition.signal + apply_deref_options(value) + else + TIMEOUT + end + end + end + + # Atomically `take`, yield the value to a block for transformation, and then + # `put` the transformed value. Returns the pre-transform value. A timeout can + # be set to limit the time spent blocked, in which case it returns `TIMEOUT` + # if the time is exceeded. + # @return [Object] the pre-transform value, or `TIMEOUT` + def modify(timeout = nil) + raise ArgumentError.new('no block given') unless block_given? + + @mutex.synchronize do + wait_for_full(timeout) + + # If we timed out we'll still be empty + if unlocked_full? + value = @value + @value = yield value + @full_condition.signal + apply_deref_options(value) + else + TIMEOUT + end + end + end + + # Non-blocking version of `take`, that returns `EMPTY` instead of blocking. + def try_take! + @mutex.synchronize do + if unlocked_full? + value = @value + @value = EMPTY + @empty_condition.signal + apply_deref_options(value) + else + EMPTY + end + end + end + + # Non-blocking version of `put`, that returns whether or not it was successful. + def try_put!(value) + @mutex.synchronize do + if unlocked_empty? + @value = value + @full_condition.signal + true + else + false + end + end + end + + # Non-blocking version of `put` that will overwrite an existing value. + def set!(value) + @mutex.synchronize do + old_value = @value + @value = value + @full_condition.signal + apply_deref_options(old_value) + end + end + + # Non-blocking version of `modify` that will yield with `EMPTY` if there is no value yet. + def modify! + raise ArgumentError.new('no block given') unless block_given? + + @mutex.synchronize do + value = @value + @value = yield value + if unlocked_empty? + @empty_condition.signal + else + @full_condition.signal + end + apply_deref_options(value) + end + end + + # Returns if the `MVar` is currently empty. + def empty? + @mutex.synchronize { @value == EMPTY } + end + + # Returns if the `MVar` currently contains a value. + def full? + !empty? + end + + protected + + def synchronize(&block) + @mutex.synchronize(&block) + end + + private + + def unlocked_empty? + @value == EMPTY + end + + def unlocked_full? + ! unlocked_empty? + end + + def wait_for_full(timeout) + wait_while(@full_condition, timeout) { unlocked_empty? } + end + + def wait_for_empty(timeout) + wait_while(@empty_condition, timeout) { unlocked_full? } + end + + def wait_while(condition, timeout) + if timeout.nil? + while yield + condition.wait(@mutex) + end + else + stop = Concurrent.monotonic_time + timeout + while yield && timeout > 0.0 + condition.wait(@mutex, timeout) + timeout = stop - Concurrent.monotonic_time + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/options.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/options.rb new file mode 100644 index 0000000..bdd22a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/options.rb @@ -0,0 +1,42 @@ +require 'concurrent/configuration' + +module Concurrent + + # @!visibility private + module Options + + # Get the requested `Executor` based on the values set in the options hash. + # + # @param [Hash] opts the options defining the requested executor + # @option opts [Executor] :executor when set use the given `Executor` instance. + # Three special values are also supported: `:fast` returns the global fast executor, + # `:io` returns the global io executor, and `:immediate` returns a new + # `ImmediateExecutor` object. + # + # @return [Executor, nil] the requested thread pool, or nil when no option specified + # + # @!visibility private + def self.executor_from_options(opts = {}) # :nodoc: + if identifier = opts.fetch(:executor, nil) + executor(identifier) + else + nil + end + end + + def self.executor(executor_identifier) + case executor_identifier + when :fast + Concurrent.global_fast_executor + when :io + Concurrent.global_io_executor + when :immediate + Concurrent.global_immediate_executor + when Concurrent::ExecutorService + executor_identifier + else + raise ArgumentError, "executor not recognized by '#{executor_identifier}'" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promise.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promise.rb new file mode 100644 index 0000000..8df80b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promise.rb @@ -0,0 +1,580 @@ +require 'thread' +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/ivar' +require 'concurrent/executor/safe_task_executor' + +require 'concurrent/options' + +module Concurrent + + PromiseExecutionError = Class.new(StandardError) + + # Promises are inspired by the JavaScript [Promises/A](http://wiki.commonjs.org/wiki/Promises/A) + # and [Promises/A+](http://promises-aplus.github.io/promises-spec/) specifications. + # + # > A promise represents the eventual value returned from the single + # > completion of an operation. + # + # Promises are similar to futures and share many of the same behaviours. + # Promises are far more robust, however. Promises can be chained in a tree + # structure where each promise may have zero or more children. Promises are + # chained using the `then` method. The result of a call to `then` is always + # another promise. Promises are resolved asynchronously (with respect to the + # main thread) but in a strict order: parents are guaranteed to be resolved + # before their children, children before their younger siblings. The `then` + # method takes two parameters: an optional block to be executed upon parent + # resolution and an optional callable to be executed upon parent failure. The + # result of each promise is passed to each of its children upon resolution. + # When a promise is rejected all its children will be summarily rejected and + # will receive the reason. + # + # Promises have several possible states: *:unscheduled*, *:pending*, + # *:processing*, *:rejected*, or *:fulfilled*. These are also aggregated as + # `#incomplete?` and `#complete?`. When a Promise is created it is set to + # *:unscheduled*. Once the `#execute` method is called the state becomes + # *:pending*. Once a job is pulled from the thread pool's queue and is given + # to a thread for processing (often immediately upon `#post`) the state + # becomes *:processing*. The future will remain in this state until processing + # is complete. A future that is in the *:unscheduled*, *:pending*, or + # *:processing* is considered `#incomplete?`. A `#complete?` Promise is either + # *:rejected*, indicating that an exception was thrown during processing, or + # *:fulfilled*, indicating success. If a Promise is *:fulfilled* its `#value` + # will be updated to reflect the result of the operation. If *:rejected* the + # `reason` will be updated with a reference to the thrown exception. The + # predicate methods `#unscheduled?`, `#pending?`, `#rejected?`, and + # `#fulfilled?` can be called at any time to obtain the state of the Promise, + # as can the `#state` method, which returns a symbol. + # + # Retrieving the value of a promise is done through the `value` (alias: + # `deref`) method. Obtaining the value of a promise is a potentially blocking + # operation. When a promise is *rejected* a call to `value` will return `nil` + # immediately. When a promise is *fulfilled* a call to `value` will + # immediately return the current value. When a promise is *pending* a call to + # `value` will block until the promise is either *rejected* or *fulfilled*. A + # *timeout* value can be passed to `value` to limit how long the call will + # block. If `nil` the call will block indefinitely. If `0` the call will not + # block. Any other integer or float value will indicate the maximum number of + # seconds to block. + # + # Promises run on the global thread pool. + # + # @!macro copy_options + # + # ### Examples + # + # Start by requiring promises + # + # ```ruby + # require 'concurrent/promise' + # ``` + # + # Then create one + # + # ```ruby + # p = Concurrent::Promise.execute do + # # do something + # 42 + # end + # ``` + # + # Promises can be chained using the `then` method. The `then` method accepts a + # block and an executor, to be executed on fulfillment, and a callable argument to be executed + # on rejection. The result of the each promise is passed as the block argument + # to chained promises. + # + # ```ruby + # p = Concurrent::Promise.new{10}.then{|x| x * 2}.then{|result| result - 10 }.execute + # ``` + # + # And so on, and so on, and so on... + # + # ```ruby + # p = Concurrent::Promise.fulfill(20). + # then{|result| result - 10 }. + # then{|result| result * 3 }. + # then(executor: different_executor){|result| result % 5 }.execute + # ``` + # + # The initial state of a newly created Promise depends on the state of its parent: + # - if parent is *unscheduled* the child will be *unscheduled* + # - if parent is *pending* the child will be *pending* + # - if parent is *fulfilled* the child will be *pending* + # - if parent is *rejected* the child will be *pending* (but will ultimately be *rejected*) + # + # Promises are executed asynchronously from the main thread. By the time a + # child Promise finishes initialization it may be in a different state than its + # parent (by the time a child is created its parent may have completed + # execution and changed state). Despite being asynchronous, however, the order + # of execution of Promise objects in a chain (or tree) is strictly defined. + # + # There are multiple ways to create and execute a new `Promise`. Both ways + # provide identical behavior: + # + # ```ruby + # # create, operate, then execute + # p1 = Concurrent::Promise.new{ "Hello World!" } + # p1.state #=> :unscheduled + # p1.execute + # + # # create and immediately execute + # p2 = Concurrent::Promise.new{ "Hello World!" }.execute + # + # # execute during creation + # p3 = Concurrent::Promise.execute{ "Hello World!" } + # ``` + # + # Once the `execute` method is called a `Promise` becomes `pending`: + # + # ```ruby + # p = Concurrent::Promise.execute{ "Hello, world!" } + # p.state #=> :pending + # p.pending? #=> true + # ``` + # + # Wait a little bit, and the promise will resolve and provide a value: + # + # ```ruby + # p = Concurrent::Promise.execute{ "Hello, world!" } + # sleep(0.1) + # + # p.state #=> :fulfilled + # p.fulfilled? #=> true + # p.value #=> "Hello, world!" + # ``` + # + # If an exception occurs, the promise will be rejected and will provide + # a reason for the rejection: + # + # ```ruby + # p = Concurrent::Promise.execute{ raise StandardError.new("Here comes the Boom!") } + # sleep(0.1) + # + # p.state #=> :rejected + # p.rejected? #=> true + # p.reason #=> "#" + # ``` + # + # #### Rejection + # + # When a promise is rejected all its children will be rejected and will + # receive the rejection `reason` as the rejection callable parameter: + # + # ```ruby + # p = Concurrent::Promise.execute { Thread.pass; raise StandardError } + # + # c1 = p.then(-> reason { 42 }) + # c2 = p.then(-> reason { raise 'Boom!' }) + # + # c1.wait.state #=> :fulfilled + # c1.value #=> 42 + # c2.wait.state #=> :rejected + # c2.reason #=> # + # ``` + # + # Once a promise is rejected it will continue to accept children that will + # receive immediately rejection (they will be executed asynchronously). + # + # #### Aliases + # + # The `then` method is the most generic alias: it accepts a block to be + # executed upon parent fulfillment and a callable to be executed upon parent + # rejection. At least one of them should be passed. The default block is `{ + # |result| result }` that fulfills the child with the parent value. The + # default callable is `{ |reason| raise reason }` that rejects the child with + # the parent reason. + # + # - `on_success { |result| ... }` is the same as `then {|result| ... }` + # - `rescue { |reason| ... }` is the same as `then(Proc.new { |reason| ... } )` + # - `rescue` is aliased by `catch` and `on_error` + class Promise < IVar + + # Initialize a new Promise with the provided options. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @option opts [Promise] :parent the parent `Promise` when building a chain/tree + # @option opts [Proc] :on_fulfill fulfillment handler + # @option opts [Proc] :on_reject rejection handler + # @option opts [object, Array] :args zero or more arguments to be passed + # the task block on execution + # + # @yield The block operation to be performed asynchronously. + # + # @raise [ArgumentError] if no block is given + # + # @see http://wiki.commonjs.org/wiki/Promises/A + # @see http://promises-aplus.github.io/promises-spec/ + def initialize(opts = {}, &block) + opts.delete_if { |k, v| v.nil? } + super(NULL, opts.merge(__promise_body_from_block__: block), &nil) + end + + # Create a new `Promise` and fulfill it immediately. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @raise [ArgumentError] if no block is given + # + # @return [Promise] the newly created `Promise` + def self.fulfill(value, opts = {}) + Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, true, value, nil) } + end + + # Create a new `Promise` and reject it immediately. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @raise [ArgumentError] if no block is given + # + # @return [Promise] the newly created `Promise` + def self.reject(reason, opts = {}) + Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, false, nil, reason) } + end + + # Execute an `:unscheduled` `Promise`. Immediately sets the state to `:pending` and + # passes the block to a new thread/thread pool for eventual execution. + # Does nothing if the `Promise` is in any state other than `:unscheduled`. + # + # @return [Promise] a reference to `self` + def execute + if root? + if compare_and_set_state(:pending, :unscheduled) + set_pending + realize(@promise_body) + end + else + compare_and_set_state(:pending, :unscheduled) + @parent.execute + end + self + end + + # @!macro ivar_set_method + # + # @raise [Concurrent::PromiseExecutionError] if not the root promise + def set(value = NULL, &block) + raise PromiseExecutionError.new('supported only on root promise') unless root? + check_for_block_or_value!(block_given?, value) + synchronize do + if @state != :unscheduled + raise MultipleAssignmentError + else + @promise_body = block || Proc.new { |result| value } + end + end + execute + end + + # @!macro ivar_fail_method + # + # @raise [Concurrent::PromiseExecutionError] if not the root promise + def fail(reason = StandardError.new) + set { raise reason } + end + + # Create a new `Promise` object with the given block, execute it, and return the + # `:pending` object. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @return [Promise] the newly created `Promise` in the `:pending` state + # + # @raise [ArgumentError] if no block is given + # + # @example + # promise = Concurrent::Promise.execute{ sleep(1); 42 } + # promise.state #=> :pending + def self.execute(opts = {}, &block) + new(opts, &block).execute + end + + # Chain a new promise off the current promise. + # + # @return [Promise] the new promise + # @yield The block operation to be performed asynchronously. + # @overload then(rescuer, executor, &block) + # @param [Proc] rescuer An optional rescue block to be executed if the + # promise is rejected. + # @param [ThreadPool] executor An optional thread pool executor to be used + # in the new Promise + # @overload then(rescuer, executor: executor, &block) + # @param [Proc] rescuer An optional rescue block to be executed if the + # promise is rejected. + # @param [ThreadPool] executor An optional thread pool executor to be used + # in the new Promise + def then(*args, &block) + if args.last.is_a?(::Hash) + executor = args.pop[:executor] + rescuer = args.first + else + rescuer, executor = args + end + + executor ||= @executor + + raise ArgumentError.new('rescuers and block are both missing') if rescuer.nil? && !block_given? + block = Proc.new { |result| result } unless block_given? + child = Promise.new( + parent: self, + executor: executor, + on_fulfill: block, + on_reject: rescuer + ) + + synchronize do + child.state = :pending if @state == :pending + child.on_fulfill(apply_deref_options(@value)) if @state == :fulfilled + child.on_reject(@reason) if @state == :rejected + @children << child + end + + child + end + + # Chain onto this promise an action to be undertaken on success + # (fulfillment). + # + # @yield The block to execute + # + # @return [Promise] self + def on_success(&block) + raise ArgumentError.new('no block given') unless block_given? + self.then(&block) + end + + # Chain onto this promise an action to be undertaken on failure + # (rejection). + # + # @yield The block to execute + # + # @return [Promise] self + def rescue(&block) + self.then(block) + end + + alias_method :catch, :rescue + alias_method :on_error, :rescue + + # Yield the successful result to the block that returns a promise. If that + # promise is also successful the result is the result of the yielded promise. + # If either part fails the whole also fails. + # + # @example + # Promise.execute { 1 }.flat_map { |v| Promise.execute { v + 2 } }.value! #=> 3 + # + # @return [Promise] + def flat_map(&block) + child = Promise.new( + parent: self, + executor: ImmediateExecutor.new, + ) + + on_error { |e| child.on_reject(e) } + on_success do |result1| + begin + inner = block.call(result1) + inner.execute + inner.on_success { |result2| child.on_fulfill(result2) } + inner.on_error { |e| child.on_reject(e) } + rescue => e + child.on_reject(e) + end + end + + child + end + + # Builds a promise that produces the result of promises in an Array + # and fails if any of them fails. + # + # @overload zip(*promises) + # @param [Array] promises + # + # @overload zip(*promises, opts) + # @param [Array] promises + # @param [Hash] opts the configuration options + # @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance. + # @option opts [Boolean] :execute (true) execute promise before returning + # + # @return [Promise] + def self.zip(*promises) + opts = promises.last.is_a?(::Hash) ? promises.pop.dup : {} + opts[:executor] ||= ImmediateExecutor.new + zero = if !opts.key?(:execute) || opts.delete(:execute) + fulfill([], opts) + else + Promise.new(opts) { [] } + end + + promises.reduce(zero) do |p1, p2| + p1.flat_map do |results| + p2.then do |next_result| + results << next_result + end + end + end + end + + # Builds a promise that produces the result of self and others in an Array + # and fails if any of them fails. + # + # @overload zip(*promises) + # @param [Array] others + # + # @overload zip(*promises, opts) + # @param [Array] others + # @param [Hash] opts the configuration options + # @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance. + # @option opts [Boolean] :execute (true) execute promise before returning + # + # @return [Promise] + def zip(*others) + self.class.zip(self, *others) + end + + # Aggregates a collection of promises and executes the `then` condition + # if all aggregated promises succeed. Executes the `rescue` handler with + # a `Concurrent::PromiseExecutionError` if any of the aggregated promises + # fail. Upon execution will execute any of the aggregate promises that + # were not already executed. + # + # @!macro promise_self_aggregate + # + # The returned promise will not yet have been executed. Additional `#then` + # and `#rescue` handlers may still be provided. Once the returned promise + # is execute the aggregate promises will be also be executed (if they have + # not been executed already). The results of the aggregate promises will + # be checked upon completion. The necessary `#then` and `#rescue` blocks + # on the aggregating promise will then be executed as appropriate. If the + # `#rescue` handlers are executed the raises exception will be + # `Concurrent::PromiseExecutionError`. + # + # @param [Array] promises Zero or more promises to aggregate + # @return [Promise] an unscheduled (not executed) promise that aggregates + # the promises given as arguments + def self.all?(*promises) + aggregate(:all?, *promises) + end + + # Aggregates a collection of promises and executes the `then` condition + # if any aggregated promises succeed. Executes the `rescue` handler with + # a `Concurrent::PromiseExecutionError` if any of the aggregated promises + # fail. Upon execution will execute any of the aggregate promises that + # were not already executed. + # + # @!macro promise_self_aggregate + def self.any?(*promises) + aggregate(:any?, *promises) + end + + protected + + def ns_initialize(value, opts) + super + + @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + @args = get_arguments_from(opts) + + @parent = opts.fetch(:parent) { nil } + @on_fulfill = opts.fetch(:on_fulfill) { Proc.new { |result| result } } + @on_reject = opts.fetch(:on_reject) { Proc.new { |reason| raise reason } } + + @promise_body = opts[:__promise_body_from_block__] || Proc.new { |result| result } + @state = :unscheduled + @children = [] + end + + # Aggregate a collection of zero or more promises under a composite promise, + # execute the aggregated promises and collect them into a standard Ruby array, + # call the given Ruby `Ennnumerable` predicate (such as `any?`, `all?`, `none?`, + # or `one?`) on the collection checking for the success or failure of each, + # then executing the composite's `#then` handlers if the predicate returns + # `true` or executing the composite's `#rescue` handlers if the predicate + # returns false. + # + # @!macro promise_self_aggregate + def self.aggregate(method, *promises) + composite = Promise.new do + completed = promises.collect do |promise| + promise.execute if promise.unscheduled? + promise.wait + promise + end + unless completed.empty? || completed.send(method){|promise| promise.fulfilled? } + raise PromiseExecutionError + end + end + composite + end + + # @!visibility private + def set_pending + synchronize do + @state = :pending + @children.each { |c| c.set_pending } + end + end + + # @!visibility private + def root? # :nodoc: + @parent.nil? + end + + # @!visibility private + def on_fulfill(result) + realize Proc.new { @on_fulfill.call(result) } + nil + end + + # @!visibility private + def on_reject(reason) + realize Proc.new { @on_reject.call(reason) } + nil + end + + # @!visibility private + def notify_child(child) + if_state(:fulfilled) { child.on_fulfill(apply_deref_options(@value)) } + if_state(:rejected) { child.on_reject(@reason) } + end + + # @!visibility private + def complete(success, value, reason) + children_to_notify = synchronize do + set_state!(success, value, reason) + @children.dup + end + + children_to_notify.each { |child| notify_child(child) } + observers.notify_and_delete_observers{ [Time.now, self.value, reason] } + end + + # @!visibility private + def realize(task) + @executor.post do + success, value, reason = SafeTaskExecutor.new(task, rescue_exception: true).execute(*@args) + complete(success, value, reason) + end + end + + # @!visibility private + def set_state!(success, value, reason) + set_state(success, value, reason) + event.set + end + + # @!visibility private + def synchronized_set_state!(success, value, reason) + synchronize { set_state!(success, value, reason) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promises.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promises.rb new file mode 100644 index 0000000..baad27d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/promises.rb @@ -0,0 +1,2184 @@ +require 'concurrent/synchronization/object' +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/collection/lock_free_stack' +require 'concurrent/configuration' +require 'concurrent/errors' +require 'concurrent/re_include' +require 'concurrent/utility/monotonic_time' + +module Concurrent + + # {include:file:docs-source/promises-main.md} + module Promises + + # @!macro promises.param.default_executor + # @param [Executor, :io, :fast] default_executor Instance of an executor or a name of the + # global executor. Default executor propagates to chained futures unless overridden with + # executor parameter or changed with {AbstractEventFuture#with_default_executor}. + # + # @!macro promises.param.executor + # @param [Executor, :io, :fast] executor Instance of an executor or a name of the + # global executor. The task is executed on it, default executor remains unchanged. + # + # @!macro promises.param.args + # @param [Object] args arguments which are passed to the task when it's executed. + # (It might be prepended with other arguments, see the @yield section). + # + # @!macro promises.shortcut.on + # Shortcut of {#$0_on} with default `:io` executor supplied. + # @see #$0_on + # + # @!macro promises.shortcut.using + # Shortcut of {#$0_using} with default `:io` executor supplied. + # @see #$0_using + # + # @!macro promise.param.task-future + # @yieldreturn will become result of the returned Future. + # Its returned value becomes {Future#value} fulfilling it, + # raised exception becomes {Future#reason} rejecting it. + # + # @!macro promise.param.callback + # @yieldreturn is forgotten. + + # Container of all {Future}, {Event} factory methods. They are never constructed directly with + # new. + module FactoryMethods + extend ReInclude + extend self + + module Configuration + # @return [Executor, :io, :fast] the executor which is used when none is supplied + # to a factory method. The method can be overridden in the receivers of + # `include FactoryMethod` + def default_executor + :io + end + end + + include Configuration + + # @!macro promises.shortcut.on + # @return [ResolvableEvent] + def resolvable_event + resolvable_event_on default_executor + end + + # Creates a resolvable event, user is responsible for resolving the event once + # by calling {Promises::ResolvableEvent#resolve}. + # + # @!macro promises.param.default_executor + # @return [ResolvableEvent] + def resolvable_event_on(default_executor = self.default_executor) + ResolvableEventPromise.new(default_executor).future + end + + # @!macro promises.shortcut.on + # @return [ResolvableFuture] + def resolvable_future + resolvable_future_on default_executor + end + + # Creates resolvable future, user is responsible for resolving the future once by + # {Promises::ResolvableFuture#resolve}, {Promises::ResolvableFuture#fulfill}, + # or {Promises::ResolvableFuture#reject} + # + # @!macro promises.param.default_executor + # @return [ResolvableFuture] + def resolvable_future_on(default_executor = self.default_executor) + ResolvableFuturePromise.new(default_executor).future + end + + # @!macro promises.shortcut.on + # @return [Future] + def future(*args, &task) + future_on(default_executor, *args, &task) + end + + # Constructs a new Future which will be resolved after block is evaluated on default executor. + # Evaluation begins immediately. + # + # @!macro promises.param.default_executor + # @!macro promises.param.args + # @yield [*args] to the task. + # @!macro promise.param.task-future + # @return [Future] + def future_on(default_executor, *args, &task) + ImmediateEventPromise.new(default_executor).future.then(*args, &task) + end + + # Creates a resolved future with will be either fulfilled with the given value or rejected with + # the given reason. + # + # @param [true, false] fulfilled + # @param [Object] value + # @param [Object] reason + # @!macro promises.param.default_executor + # @return [Future] + def resolved_future(fulfilled, value, reason, default_executor = self.default_executor) + ImmediateFuturePromise.new(default_executor, fulfilled, value, reason).future + end + + # Creates a resolved future which will be fulfilled with the given value. + # + # @!macro promises.param.default_executor + # @param [Object] value + # @return [Future] + def fulfilled_future(value, default_executor = self.default_executor) + resolved_future true, value, nil, default_executor + end + + # Creates a resolved future which will be rejected with the given reason. + # + # @!macro promises.param.default_executor + # @param [Object] reason + # @return [Future] + def rejected_future(reason, default_executor = self.default_executor) + resolved_future false, nil, reason, default_executor + end + + # Creates resolved event. + # + # @!macro promises.param.default_executor + # @return [Event] + def resolved_event(default_executor = self.default_executor) + ImmediateEventPromise.new(default_executor).event + end + + # General constructor. Behaves differently based on the argument's type. It's provided for convenience + # but it's better to be explicit. + # + # @see rejected_future, resolved_event, fulfilled_future + # @!macro promises.param.default_executor + # @return [Event, Future] + # + # @overload make_future(nil, default_executor = self.default_executor) + # @param [nil] nil + # @return [Event] resolved event. + # + # @overload make_future(a_future, default_executor = self.default_executor) + # @param [Future] a_future + # @return [Future] a future which will be resolved when a_future is. + # + # @overload make_future(an_event, default_executor = self.default_executor) + # @param [Event] an_event + # @return [Event] an event which will be resolved when an_event is. + # + # @overload make_future(exception, default_executor = self.default_executor) + # @param [Exception] exception + # @return [Future] a rejected future with the exception as its reason. + # + # @overload make_future(value, default_executor = self.default_executor) + # @param [Object] value when none of the above overloads fits + # @return [Future] a fulfilled future with the value. + def make_future(argument = nil, default_executor = self.default_executor) + case argument + when AbstractEventFuture + # returning wrapper would change nothing + argument + when Exception + rejected_future argument, default_executor + when nil + resolved_event default_executor + else + fulfilled_future argument, default_executor + end + end + + # @!macro promises.shortcut.on + # @return [Future, Event] + def delay(*args, &task) + delay_on default_executor, *args, &task + end + + # Creates a new event or future which is resolved only after it is touched, + # see {Concurrent::AbstractEventFuture#touch}. + # + # @!macro promises.param.default_executor + # @overload delay_on(default_executor, *args, &task) + # If task is provided it returns a {Future} representing the result of the task. + # @!macro promises.param.args + # @yield [*args] to the task. + # @!macro promise.param.task-future + # @return [Future] + # @overload delay_on(default_executor) + # If no task is provided, it returns an {Event} + # @return [Event] + def delay_on(default_executor, *args, &task) + event = DelayPromise.new(default_executor).event + task ? event.chain(*args, &task) : event + end + + # @!macro promises.shortcut.on + # @return [Future, Event] + def schedule(intended_time, *args, &task) + schedule_on default_executor, intended_time, *args, &task + end + + # Creates a new event or future which is resolved in intended_time. + # + # @!macro promises.param.default_executor + # @!macro promises.param.intended_time + # @param [Numeric, Time] intended_time `Numeric` means to run in `intended_time` seconds. + # `Time` means to run on `intended_time`. + # @overload schedule_on(default_executor, intended_time, *args, &task) + # If task is provided it returns a {Future} representing the result of the task. + # @!macro promises.param.args + # @yield [*args] to the task. + # @!macro promise.param.task-future + # @return [Future] + # @overload schedule_on(default_executor, intended_time) + # If no task is provided, it returns an {Event} + # @return [Event] + def schedule_on(default_executor, intended_time, *args, &task) + event = ScheduledPromise.new(default_executor, intended_time).event + task ? event.chain(*args, &task) : event + end + + # @!macro promises.shortcut.on + # @return [Future] + def zip_futures(*futures_and_or_events) + zip_futures_on default_executor, *futures_and_or_events + end + + # Creates a new future which is resolved after all futures_and_or_events are resolved. + # Its value is an array of zipped future values. Its reason is an array of reasons for rejection. + # If there is an error it rejects. + # @!macro promises.event-conversion + # If event is supplied, which does not have value and can be only resolved, it's + # represented as `:fulfilled` with value `nil`. + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Future] + def zip_futures_on(default_executor, *futures_and_or_events) + ZipFuturesPromise.new_blocked_by(futures_and_or_events, default_executor).future + end + + alias_method :zip, :zip_futures + + # @!macro promises.shortcut.on + # @return [Event] + def zip_events(*futures_and_or_events) + zip_events_on default_executor, *futures_and_or_events + end + + # Creates a new event which is resolved after all futures_and_or_events are resolved. + # (Future is resolved when fulfilled or rejected.) + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Event] + def zip_events_on(default_executor, *futures_and_or_events) + ZipEventsPromise.new_blocked_by(futures_and_or_events, default_executor).event + end + + # @!macro promises.shortcut.on + # @return [Future] + def any_resolved_future(*futures_and_or_events) + any_resolved_future_on default_executor, *futures_and_or_events + end + + alias_method :any, :any_resolved_future + + # Creates a new future which is resolved after the first futures_and_or_events is resolved. + # Its result equals the result of the first resolved future. + # @!macro promises.any-touch + # If resolved it does not propagate {Concurrent::AbstractEventFuture#touch}, leaving delayed + # futures un-executed if they are not required any more. + # @!macro promises.event-conversion + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Future] + def any_resolved_future_on(default_executor, *futures_and_or_events) + AnyResolvedFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future + end + + # @!macro promises.shortcut.on + # @return [Future] + def any_fulfilled_future(*futures_and_or_events) + any_fulfilled_future_on default_executor, *futures_and_or_events + end + + # Creates a new future which is resolved after the first futures_and_or_events is fulfilled. + # Its result equals the result of the first resolved future or if all futures_and_or_events reject, + # it has reason of the last rejected future. + # @!macro promises.any-touch + # @!macro promises.event-conversion + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Future] + def any_fulfilled_future_on(default_executor, *futures_and_or_events) + AnyFulfilledFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future + end + + # @!macro promises.shortcut.on + # @return [Event] + def any_event(*futures_and_or_events) + any_event_on default_executor, *futures_and_or_events + end + + # Creates a new event which becomes resolved after the first futures_and_or_events resolves. + # @!macro promises.any-touch + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Event] + def any_event_on(default_executor, *futures_and_or_events) + AnyResolvedEventPromise.new_blocked_by(futures_and_or_events, default_executor).event + end + + # TODO consider adding first(count, *futures) + # TODO consider adding zip_by(slice, *futures) processing futures in slices + # TODO or rather a generic aggregator taking a function + end + + module InternalStates + # @!visibility private + class State + def resolved? + raise NotImplementedError + end + + def to_sym + raise NotImplementedError + end + end + + # @!visibility private + class Pending < State + def resolved? + false + end + + def to_sym + :pending + end + end + + # @!visibility private + class Reserved < Pending + end + + # @!visibility private + class ResolvedWithResult < State + def resolved? + true + end + + def to_sym + :resolved + end + + def result + [fulfilled?, value, reason] + end + + def fulfilled? + raise NotImplementedError + end + + def value + raise NotImplementedError + end + + def reason + raise NotImplementedError + end + + def apply + raise NotImplementedError + end + end + + # @!visibility private + class Fulfilled < ResolvedWithResult + + def initialize(value) + @Value = value + end + + def fulfilled? + true + end + + def apply(args, block) + block.call value, *args + end + + def value + @Value + end + + def reason + nil + end + + def to_sym + :fulfilled + end + end + + # @!visibility private + class FulfilledArray < Fulfilled + def apply(args, block) + block.call(*value, *args) + end + end + + # @!visibility private + class Rejected < ResolvedWithResult + def initialize(reason) + @Reason = reason + end + + def fulfilled? + false + end + + def value + nil + end + + def reason + @Reason + end + + def to_sym + :rejected + end + + def apply(args, block) + block.call reason, *args + end + end + + # @!visibility private + class PartiallyRejected < ResolvedWithResult + def initialize(value, reason) + super() + @Value = value + @Reason = reason + end + + def fulfilled? + false + end + + def to_sym + :rejected + end + + def value + @Value + end + + def reason + @Reason + end + + def apply(args, block) + block.call(*reason, *args) + end + end + + # @!visibility private + PENDING = Pending.new + # @!visibility private + RESERVED = Reserved.new + # @!visibility private + RESOLVED = Fulfilled.new(nil) + + def RESOLVED.to_sym + :resolved + end + end + + private_constant :InternalStates + + # @!macro promises.shortcut.event-future + # @see Event#$0 + # @see Future#$0 + + # @!macro promises.param.timeout + # @param [Numeric] timeout the maximum time in second to wait. + + # @!macro promises.warn.blocks + # @note This function potentially blocks current thread until the Future is resolved. + # Be careful it can deadlock. Try to chain instead. + + # Common ancestor of {Event} and {Future} classes, many shared methods are defined here. + class AbstractEventFuture < Synchronization::Object + safe_initialization! + attr_atomic(:internal_state) + private :internal_state=, :swap_internal_state, :compare_and_set_internal_state, :update_internal_state + # @!method internal_state + # @!visibility private + + include InternalStates + + def initialize(promise, default_executor) + super() + @Lock = Mutex.new + @Condition = ConditionVariable.new + @Promise = promise + @DefaultExecutor = default_executor + @Callbacks = LockFreeStack.new + @Waiters = AtomicFixnum.new 0 + self.internal_state = PENDING + end + + private :initialize + + # Returns its state. + # @return [Symbol] + # + # @overload an_event.state + # @return [:pending, :resolved] + # @overload a_future.state + # Both :fulfilled, :rejected implies :resolved. + # @return [:pending, :fulfilled, :rejected] + def state + internal_state.to_sym + end + + # Is it in pending state? + # @return [Boolean] + def pending? + !internal_state.resolved? + end + + # Is it in resolved state? + # @return [Boolean] + def resolved? + internal_state.resolved? + end + + # Propagates touch. Requests all the delayed futures, which it depends on, to be + # executed. This method is called by any other method requiring resolved state, like {#wait}. + # @return [self] + def touch + @Promise.touch + self + end + + # @!macro promises.touches + # Calls {Concurrent::AbstractEventFuture#touch}. + + # @!macro promises.method.wait + # Wait (block the Thread) until receiver is {#resolved?}. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.param.timeout + # @return [self, true, false] self implies timeout was not used, true implies timeout was used + # and it was resolved, false implies it was not resolved within timeout. + def wait(timeout = nil) + result = wait_until_resolved(timeout) + timeout ? result : self + end + + # Returns default executor. + # @return [Executor] default executor + # @see #with_default_executor + # @see FactoryMethods#future_on + # @see FactoryMethods#resolvable_future + # @see FactoryMethods#any_fulfilled_future_on + # @see similar + def default_executor + @DefaultExecutor + end + + # @!macro promises.shortcut.on + # @return [Future] + def chain(*args, &task) + chain_on @DefaultExecutor, *args, &task + end + + # Chains the task to be executed asynchronously on executor after it is resolved. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @return [Future] + # @!macro promise.param.task-future + # + # @overload an_event.chain_on(executor, *args, &task) + # @yield [*args] to the task. + # @overload a_future.chain_on(executor, *args, &task) + # @yield [fulfilled, value, reason, *args] to the task. + # @yieldparam [true, false] fulfilled + # @yieldparam [Object] value + # @yieldparam [Object] reason + def chain_on(executor, *args, &task) + ChainPromise.new_blocked_by1(self, executor, executor, args, &task).future + end + + # @return [String] Short string representation. + def to_s + format '%s %s>', super[0..-2], state + end + + alias_method :inspect, :to_s + + # Resolves the resolvable when receiver is resolved. + # + # @param [Resolvable] resolvable + # @return [self] + def chain_resolvable(resolvable) + on_resolution! { resolvable.resolve_with internal_state } + end + + alias_method :tangle, :chain_resolvable + + # @!macro promises.shortcut.using + # @return [self] + def on_resolution(*args, &callback) + on_resolution_using @DefaultExecutor, *args, &callback + end + + # Stores the callback to be executed synchronously on resolving thread after it is + # resolved. + # + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # + # @overload an_event.on_resolution!(*args, &callback) + # @yield [*args] to the callback. + # @overload a_future.on_resolution!(*args, &callback) + # @yield [fulfilled, value, reason, *args] to the callback. + # @yieldparam [true, false] fulfilled + # @yieldparam [Object] value + # @yieldparam [Object] reason + def on_resolution!(*args, &callback) + add_callback :callback_on_resolution, args, callback + end + + # Stores the callback to be executed asynchronously on executor after it is resolved. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # + # @overload an_event.on_resolution_using(executor, *args, &callback) + # @yield [*args] to the callback. + # @overload a_future.on_resolution_using(executor, *args, &callback) + # @yield [fulfilled, value, reason, *args] to the callback. + # @yieldparam [true, false] fulfilled + # @yieldparam [Object] value + # @yieldparam [Object] reason + def on_resolution_using(executor, *args, &callback) + add_callback :async_callback_on_resolution, executor, args, callback + end + + # @!macro promises.method.with_default_executor + # Crates new object with same class with the executor set as its new default executor. + # Any futures depending on it will use the new default executor. + # @!macro promises.shortcut.event-future + # @abstract + # @return [AbstractEventFuture] + def with_default_executor(executor) + raise NotImplementedError + end + + # @!visibility private + def resolve_with(state, raise_on_reassign = true, reserved = false) + if compare_and_set_internal_state(reserved ? RESERVED : PENDING, state) + # go to synchronized block only if there were waiting threads + @Lock.synchronize { @Condition.broadcast } unless @Waiters.value == 0 + call_callbacks state + else + return rejected_resolution(raise_on_reassign, state) + end + self + end + + # For inspection. + # @!visibility private + # @return [Array] + def blocks + @Callbacks.each_with_object([]) do |(method, args), promises| + promises.push(args[0]) if method == :callback_notify_blocked + end + end + + # For inspection. + # @!visibility private + def callbacks + @Callbacks.each.to_a + end + + # For inspection. + # @!visibility private + def promise + @Promise + end + + # For inspection. + # @!visibility private + def touched? + promise.touched? + end + + # For inspection. + # @!visibility private + def waiting_threads + @Waiters.each.to_a + end + + # @!visibility private + def add_callback_notify_blocked(promise, index) + add_callback :callback_notify_blocked, promise, index + end + + # @!visibility private + def add_callback_clear_delayed_node(node) + add_callback(:callback_clear_delayed_node, node) + end + + # @!visibility private + def with_hidden_resolvable + # TODO (pitr-ch 10-Dec-2018): documentation, better name if in edge + self + end + + private + + def add_callback(method, *args) + state = internal_state + if state.resolved? + call_callback method, state, args + else + @Callbacks.push [method, args] + state = internal_state + # take back if it was resolved in the meanwhile + call_callbacks state if state.resolved? + end + self + end + + def callback_clear_delayed_node(state, node) + node.value = nil + end + + # @return [Boolean] + def wait_until_resolved(timeout) + return true if resolved? + + touch + + @Lock.synchronize do + @Waiters.increment + begin + if timeout + start = Concurrent.monotonic_time + until resolved? + break if @Condition.wait(@Lock, timeout) == nil # nil means timeout + timeout -= (Concurrent.monotonic_time - start) + break if timeout <= 0 + end + else + until resolved? + @Condition.wait(@Lock, timeout) + end + end + ensure + # JRuby may raise ConcurrencyError + @Waiters.decrement + end + end + resolved? + end + + def call_callback(method, state, args) + self.send method, state, *args + end + + def call_callbacks(state) + method, args = @Callbacks.pop + while method + call_callback method, state, args + method, args = @Callbacks.pop + end + end + + def with_async(executor, *args, &block) + Concurrent.executor(executor).post(*args, &block) + end + + def async_callback_on_resolution(state, executor, args, callback) + with_async(executor, state, args, callback) do |st, ar, cb| + callback_on_resolution st, ar, cb + end + end + + def callback_notify_blocked(state, promise, index) + promise.on_blocker_resolution self, index + end + end + + # Represents an event which will happen in future (will be resolved). The event is either + # pending or resolved. It should be always resolved. Use {Future} to communicate rejections and + # cancellation. + class Event < AbstractEventFuture + + alias_method :then, :chain + + + # @!macro promises.method.zip + # Creates a new event or a future which will be resolved when receiver and other are. + # Returns an event if receiver and other are events, otherwise returns a future. + # If just one of the parties is Future then the result + # of the returned future is equal to the result of the supplied future. If both are futures + # then the result is as described in {FactoryMethods#zip_futures_on}. + # + # @return [Future, Event] + def zip(other) + if other.is_a?(Future) + ZipFutureEventPromise.new_blocked_by2(other, self, @DefaultExecutor).future + else + ZipEventEventPromise.new_blocked_by2(self, other, @DefaultExecutor).event + end + end + + alias_method :&, :zip + + # Creates a new event which will be resolved when the first of receiver, `event_or_future` + # resolves. + # + # @return [Event] + def any(event_or_future) + AnyResolvedEventPromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).event + end + + alias_method :|, :any + + # Creates new event dependent on receiver which will not evaluate until touched, see {#touch}. + # In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated. + # + # @return [Event] + def delay + event = DelayPromise.new(@DefaultExecutor).event + ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event + end + + # @!macro promise.method.schedule + # Creates new event dependent on receiver scheduled to execute on/in intended_time. + # In time is interpreted from the moment the receiver is resolved, therefore it inserts + # delay into the chain. + # + # @!macro promises.param.intended_time + # @return [Event] + def schedule(intended_time) + chain do + event = ScheduledPromise.new(@DefaultExecutor, intended_time).event + ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event + end.flat_event + end + + # Converts event to a future. The future is fulfilled when the event is resolved, the future may never fail. + # + # @return [Future] + def to_future + future = Promises.resolvable_future + ensure + chain_resolvable(future) + end + + # Returns self, since this is event + # @return [Event] + def to_event + self + end + + # @!macro promises.method.with_default_executor + # @return [Event] + def with_default_executor(executor) + EventWrapperPromise.new_blocked_by1(self, executor).event + end + + private + + def rejected_resolution(raise_on_reassign, state) + raise Concurrent::MultipleAssignmentError.new('Event can be resolved only once') if raise_on_reassign + return false + end + + def callback_on_resolution(state, args, callback) + callback.call(*args) + end + end + + # Represents a value which will become available in future. May reject with a reason instead, + # e.g. when the tasks raises an exception. + class Future < AbstractEventFuture + SET_BACKTRACE_LOCATIONS_SUPPORTED = RUBY_VERSION >= '3.4' + + # Is it in fulfilled state? + # @return [Boolean] + def fulfilled? + state = internal_state + state.resolved? && state.fulfilled? + end + + # Is it in rejected state? + # @return [Boolean] + def rejected? + state = internal_state + state.resolved? && !state.fulfilled? + end + + # @!macro promises.warn.nil + # @note Make sure returned `nil` is not confused with timeout, no value when rejected, + # no reason when fulfilled, etc. + # Use more exact methods if needed, like {#wait}, {#value!}, {#result}, etc. + + # @!macro promises.method.value + # Return value of the future. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.warn.nil + # @!macro promises.param.timeout + # @!macro promises.param.timeout_value + # @param [Object] timeout_value a value returned by the method when it times out + # @return [Object, nil, timeout_value] the value of the Future when fulfilled, + # timeout_value on timeout, + # nil on rejection. + def value(timeout = nil, timeout_value = nil) + if wait_until_resolved timeout + internal_state.value + else + timeout_value + end + end + + # Returns reason of future's rejection. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.warn.nil + # @!macro promises.param.timeout + # @!macro promises.param.timeout_value + # @return [Object, timeout_value] the reason, or timeout_value on timeout, or nil on fulfillment. + def reason(timeout = nil, timeout_value = nil) + if wait_until_resolved timeout + internal_state.reason + else + timeout_value + end + end + + # Returns triplet fulfilled?, value, reason. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.param.timeout + # @return [Array(Boolean, Object, Object), nil] triplet of fulfilled?, value, reason, or nil + # on timeout. + def result(timeout = nil) + internal_state.result if wait_until_resolved timeout + end + + # @!macro promises.method.wait + # @raise [Exception] {#reason} on rejection + def wait!(timeout = nil) + result = wait_until_resolved!(timeout) + timeout ? result : self + end + + # @!macro promises.method.value + # @return [Object, nil, timeout_value] the value of the Future when fulfilled, + # or nil on rejection, + # or timeout_value on timeout. + # @raise [Exception] {#reason} on rejection + def value!(timeout = nil, timeout_value = nil) + if wait_until_resolved! timeout + internal_state.value + else + timeout_value + end + end + + # Allows rejected Future to be risen with `raise` method. + # If the reason is not an exception `Runtime.new(reason)` is returned. + # + # @example + # raise Promises.rejected_future(StandardError.new("boom")) + # raise Promises.rejected_future("or just boom") + # @raise [Concurrent::Error] when raising not rejected future + # @return [Exception] + def exception(*args) + raise Concurrent::Error, 'it is not rejected' unless rejected? + raise ArgumentError unless args.size <= 1 + reason = Array(internal_state.reason).flatten.compact + callsites = SET_BACKTRACE_LOCATIONS_SUPPORTED ? caller_locations : caller + if reason.size > 1 + ex = Concurrent::MultipleErrors.new reason + ex.set_backtrace(callsites) + ex + else + ex = if reason[0].respond_to? :exception + reason[0].exception(*args) + else + RuntimeError.new(reason[0]).exception(*args) + end + if SET_BACKTRACE_LOCATIONS_SUPPORTED && (locations = ex.backtrace_locations) + ex.set_backtrace locations + callsites + else + ex.set_backtrace Array(ex.backtrace) + callsites.map(&:to_s) + end + ex + end + end + + # @!macro promises.shortcut.on + # @return [Future] + def then(*args, &task) + then_on @DefaultExecutor, *args, &task + end + + # Chains the task to be executed asynchronously on executor after it fulfills. Does not run + # the task if it rejects. It will resolve though, triggering any dependent futures. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.task-future + # @return [Future] + # @yield [value, *args] to the task. + def then_on(executor, *args, &task) + ThenPromise.new_blocked_by1(self, executor, executor, args, &task).future + end + + # @!macro promises.shortcut.on + # @return [Future] + def rescue(*args, &task) + rescue_on @DefaultExecutor, *args, &task + end + + # Chains the task to be executed asynchronously on executor after it rejects. Does not run + # the task if it fulfills. It will resolve though, triggering any dependent futures. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.task-future + # @return [Future] + # @yield [reason, *args] to the task. + def rescue_on(executor, *args, &task) + RescuePromise.new_blocked_by1(self, executor, executor, args, &task).future + end + + # @!macro promises.method.zip + # @return [Future] + def zip(other) + if other.is_a?(Future) + ZipFuturesPromise.new_blocked_by2(self, other, @DefaultExecutor).future + else + ZipFutureEventPromise.new_blocked_by2(self, other, @DefaultExecutor).future + end + end + + alias_method :&, :zip + + # Creates a new event which will be resolved when the first of receiver, `event_or_future` + # resolves. Returning future will have value nil if event_or_future is event and resolves + # first. + # + # @return [Future] + def any(event_or_future) + AnyResolvedFuturePromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).future + end + + alias_method :|, :any + + # Creates new future dependent on receiver which will not evaluate until touched, see {#touch}. + # In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated. + # + # @return [Future] + def delay + event = DelayPromise.new(@DefaultExecutor).event + ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future + end + + # @!macro promise.method.schedule + # @return [Future] + def schedule(intended_time) + chain do + event = ScheduledPromise.new(@DefaultExecutor, intended_time).event + ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future + end.flat + end + + # @!macro promises.method.with_default_executor + # @return [Future] + def with_default_executor(executor) + FutureWrapperPromise.new_blocked_by1(self, executor).future + end + + # Creates new future which will have result of the future returned by receiver. If receiver + # rejects it will have its rejection. + # + # @param [Integer] level how many levels of futures should flatten + # @return [Future] + def flat_future(level = 1) + FlatFuturePromise.new_blocked_by1(self, level, @DefaultExecutor).future + end + + alias_method :flat, :flat_future + + # Creates new event which will be resolved when the returned event by receiver is. + # Be careful if the receiver rejects it will just resolve since Event does not hold reason. + # + # @return [Event] + def flat_event + FlatEventPromise.new_blocked_by1(self, @DefaultExecutor).event + end + + # @!macro promises.shortcut.using + # @return [self] + def on_fulfillment(*args, &callback) + on_fulfillment_using @DefaultExecutor, *args, &callback + end + + # Stores the callback to be executed synchronously on resolving thread after it is + # fulfilled. Does nothing on rejection. + # + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [value, *args] to the callback. + def on_fulfillment!(*args, &callback) + add_callback :callback_on_fulfillment, args, callback + end + + # Stores the callback to be executed asynchronously on executor after it is + # fulfilled. Does nothing on rejection. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [value, *args] to the callback. + def on_fulfillment_using(executor, *args, &callback) + add_callback :async_callback_on_fulfillment, executor, args, callback + end + + # @!macro promises.shortcut.using + # @return [self] + def on_rejection(*args, &callback) + on_rejection_using @DefaultExecutor, *args, &callback + end + + # Stores the callback to be executed synchronously on resolving thread after it is + # rejected. Does nothing on fulfillment. + # + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [reason, *args] to the callback. + def on_rejection!(*args, &callback) + add_callback :callback_on_rejection, args, callback + end + + # Stores the callback to be executed asynchronously on executor after it is + # rejected. Does nothing on fulfillment. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [reason, *args] to the callback. + def on_rejection_using(executor, *args, &callback) + add_callback :async_callback_on_rejection, executor, args, callback + end + + # Allows to use futures as green threads. The receiver has to evaluate to a future which + # represents what should be done next. It basically flattens indefinitely until non Future + # values is returned which becomes result of the returned future. Any encountered exception + # will become reason of the returned future. + # + # @return [Future] + # @param [#call(value)] run_test + # an object which when called returns either Future to keep running with + # or nil, then the run completes with the value. + # The run_test can be used to extract the Future from deeper structure, + # or to distinguish Future which is a resulting value from a future + # which is suppose to continue running. + # @example + # body = lambda do |v| + # v += 1 + # v < 5 ? Promises.future(v, &body) : v + # end + # Promises.future(0, &body).run.value! # => 5 + def run(run_test = method(:run_test)) + RunFuturePromise.new_blocked_by1(self, @DefaultExecutor, run_test).future + end + + # @!visibility private + def apply(args, block) + internal_state.apply args, block + end + + # Converts future to event which is resolved when future is resolved by fulfillment or rejection. + # + # @return [Event] + def to_event + event = Promises.resolvable_event + ensure + chain_resolvable(event) + end + + # Returns self, since this is a future + # @return [Future] + def to_future + self + end + + # @return [String] Short string representation. + def to_s + if resolved? + format '%s with %s>', super[0..-2], (fulfilled? ? value : reason).inspect + else + super + end + end + + alias_method :inspect, :to_s + + private + + def run_test(v) + v if v.is_a?(Future) + end + + def rejected_resolution(raise_on_reassign, state) + if raise_on_reassign + if internal_state == RESERVED + raise Concurrent::MultipleAssignmentError.new( + "Future can be resolved only once. It is already reserved.") + else + raise Concurrent::MultipleAssignmentError.new( + "Future can be resolved only once. It's #{result}, trying to set #{state.result}.", + current_result: result, + new_result: state.result) + end + end + return false + end + + def wait_until_resolved!(timeout = nil) + result = wait_until_resolved(timeout) + raise self if rejected? + result + end + + def async_callback_on_fulfillment(state, executor, args, callback) + with_async(executor, state, args, callback) do |st, ar, cb| + callback_on_fulfillment st, ar, cb + end + end + + def async_callback_on_rejection(state, executor, args, callback) + with_async(executor, state, args, callback) do |st, ar, cb| + callback_on_rejection st, ar, cb + end + end + + def callback_on_fulfillment(state, args, callback) + state.apply args, callback if state.fulfilled? + end + + def callback_on_rejection(state, args, callback) + state.apply args, callback unless state.fulfilled? + end + + def callback_on_resolution(state, args, callback) + callback.call(*state.result, *args) + end + + end + + # Marker module of Future, Event resolved manually. + module Resolvable + include InternalStates + end + + # A Event which can be resolved by user. + class ResolvableEvent < Event + include Resolvable + + # @!macro raise_on_reassign + # @raise [MultipleAssignmentError] when already resolved and raise_on_reassign is true. + + # @!macro promise.param.raise_on_reassign + # @param [Boolean] raise_on_reassign should method raise exception if already resolved + # @return [self, false] false is returned when raise_on_reassign is false and the receiver + # is already resolved. + # + + # Makes the event resolved, which triggers all dependent futures. + # + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + # @param [true, false] reserved + # Set to true if the resolvable is {#reserve}d by you, + # marks resolution of reserved resolvable events and futures explicitly. + # Advanced feature, ignore unless you use {Resolvable#reserve} from edge. + def resolve(raise_on_reassign = true, reserved = false) + resolve_with RESOLVED, raise_on_reassign, reserved + end + + # Creates new event wrapping receiver, effectively hiding the resolve method. + # + # @return [Event] + def with_hidden_resolvable + @with_hidden_resolvable ||= EventWrapperPromise.new_blocked_by1(self, @DefaultExecutor).event + end + + # Behaves as {AbstractEventFuture#wait} but has one additional optional argument + # resolve_on_timeout. + # + # @param [true, false] resolve_on_timeout + # If it times out and the argument is true it will also resolve the event. + # @return [self, true, false] + # @see AbstractEventFuture#wait + def wait(timeout = nil, resolve_on_timeout = false) + super(timeout) or if resolve_on_timeout + # if it fails to resolve it was resolved in the meantime + # so return true as if there was no timeout + !resolve(false) + else + false + end + end + end + + # A Future which can be resolved by user. + class ResolvableFuture < Future + include Resolvable + + # Makes the future resolved with result of triplet `fulfilled?`, `value`, `reason`, + # which triggers all dependent futures. + # + # @param [true, false] fulfilled + # @param [Object] value + # @param [Object] reason + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + def resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false) + resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason), raise_on_reassign, reserved) + end + + # Makes the future fulfilled with `value`, + # which triggers all dependent futures. + # + # @param [Object] value + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + def fulfill(value, raise_on_reassign = true, reserved = false) + resolve_with Fulfilled.new(value), raise_on_reassign, reserved + end + + # Makes the future rejected with `reason`, + # which triggers all dependent futures. + # + # @param [Object] reason + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + def reject(reason, raise_on_reassign = true, reserved = false) + resolve_with Rejected.new(reason), raise_on_reassign, reserved + end + + # Evaluates the block and sets its result as future's value fulfilling, if the block raises + # an exception the future rejects with it. + # + # @yield [*args] to the block. + # @yieldreturn [Object] value + # @return [self] + def evaluate_to(*args, &block) + promise.evaluate_to(*args, block) + end + + # Evaluates the block and sets its result as future's value fulfilling, if the block raises + # an exception the future rejects with it. + # + # @yield [*args] to the block. + # @yieldreturn [Object] value + # @return [self] + # @raise [Exception] also raise reason on rejection. + def evaluate_to!(*args, &block) + promise.evaluate_to(*args, block).wait! + end + + # @!macro promises.resolvable.resolve_on_timeout + # @param [::Array(true, Object, nil), ::Array(false, nil, Exception), nil] resolve_on_timeout + # If it times out and the argument is not nil it will also resolve the future + # to the provided resolution. + + # Behaves as {AbstractEventFuture#wait} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [self, true, false] + # @see AbstractEventFuture#wait + def wait(timeout = nil, resolve_on_timeout = nil) + super(timeout) or if resolve_on_timeout + # if it fails to resolve it was resolved in the meantime + # so return true as if there was no timeout + !resolve(*resolve_on_timeout, false) + else + false + end + end + + # Behaves as {Future#wait!} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [self, true, false] + # @raise [Exception] {#reason} on rejection + # @see Future#wait! + def wait!(timeout = nil, resolve_on_timeout = nil) + super(timeout) or if resolve_on_timeout + if resolve(*resolve_on_timeout, false) + false + else + # if it fails to resolve it was resolved in the meantime + # so return true as if there was no timeout + raise self if rejected? + true + end + else + false + end + end + + # Behaves as {Future#value} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [Object, timeout_value, nil] + # @see Future#value + def value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) + if wait_until_resolved timeout + internal_state.value + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + return internal_state.value + end + end + timeout_value + end + end + + # Behaves as {Future#value!} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [Object, timeout_value, nil] + # @raise [Exception] {#reason} on rejection + # @see Future#value! + def value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) + if wait_until_resolved! timeout + internal_state.value + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + raise self if rejected? + return internal_state.value + end + end + timeout_value + end + end + + # Behaves as {Future#reason} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [Exception, timeout_value, nil] + # @see Future#reason + def reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) + if wait_until_resolved timeout + internal_state.reason + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + return internal_state.reason + end + end + timeout_value + end + end + + # Behaves as {Future#result} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [::Array(Boolean, Object, Exception), nil] + # @see Future#result + def result(timeout = nil, resolve_on_timeout = nil) + if wait_until_resolved timeout + internal_state.result + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + internal_state.result + end + end + # otherwise returns nil + end + end + + # Creates new future wrapping receiver, effectively hiding the resolve method and similar. + # + # @return [Future] + def with_hidden_resolvable + @with_hidden_resolvable ||= FutureWrapperPromise.new_blocked_by1(self, @DefaultExecutor).future + end + end + + # @abstract + # @private + class AbstractPromise < Synchronization::Object + safe_initialization! + include InternalStates + + def initialize(future) + super() + @Future = future + end + + def future + @Future + end + + alias_method :event, :future + + def default_executor + future.default_executor + end + + def state + future.state + end + + def touch + end + + def to_s + format '%s %s>', super[0..-2], @Future + end + + alias_method :inspect, :to_s + + def delayed_because + nil + end + + private + + def resolve_with(new_state, raise_on_reassign = true) + @Future.resolve_with(new_state, raise_on_reassign) + end + + # @return [Future] + def evaluate_to(*args, block) + resolve_with Fulfilled.new(block.call(*args)) + rescue Exception => error + resolve_with Rejected.new(error) + raise error unless error.is_a?(StandardError) + end + end + + class ResolvableEventPromise < AbstractPromise + def initialize(default_executor) + super ResolvableEvent.new(self, default_executor) + end + end + + class ResolvableFuturePromise < AbstractPromise + def initialize(default_executor) + super ResolvableFuture.new(self, default_executor) + end + + public :evaluate_to + end + + # @abstract + class InnerPromise < AbstractPromise + end + + # @abstract + class BlockedPromise < InnerPromise + + private_class_method :new + + def self.new_blocked_by1(blocker, *args, &block) + blocker_delayed = blocker.promise.delayed_because + promise = new(blocker_delayed, 1, *args, &block) + blocker.add_callback_notify_blocked promise, 0 + promise + end + + def self.new_blocked_by2(blocker1, blocker2, *args, &block) + blocker_delayed1 = blocker1.promise.delayed_because + blocker_delayed2 = blocker2.promise.delayed_because + delayed = if blocker_delayed1 && blocker_delayed2 + # TODO (pitr-ch 23-Dec-2016): use arrays when we know it will not grow (only flat adds delay) + LockFreeStack.of2(blocker_delayed1, blocker_delayed2) + else + blocker_delayed1 || blocker_delayed2 + end + promise = new(delayed, 2, *args, &block) + blocker1.add_callback_notify_blocked promise, 0 + blocker2.add_callback_notify_blocked promise, 1 + promise + end + + def self.new_blocked_by(blockers, *args, &block) + delayed = blockers.reduce(nil) { |d, f| add_delayed d, f.promise.delayed_because } + promise = new(delayed, blockers.size, *args, &block) + blockers.each_with_index { |f, i| f.add_callback_notify_blocked promise, i } + promise + end + + def self.add_delayed(delayed1, delayed2) + if delayed1 && delayed2 + delayed1.push delayed2 + delayed1 + else + delayed1 || delayed2 + end + end + + def initialize(delayed, blockers_count, future) + super(future) + @Delayed = delayed + @Countdown = AtomicFixnum.new blockers_count + end + + def on_blocker_resolution(future, index) + countdown = process_on_blocker_resolution(future, index) + resolvable = resolvable?(countdown, future, index) + + on_resolvable(future, index) if resolvable + end + + def delayed_because + @Delayed + end + + def touch + clear_and_propagate_touch + end + + # for inspection only + def blocked_by + blocked_by = [] + ObjectSpace.each_object(AbstractEventFuture) { |o| blocked_by.push o if o.blocks.include? self } + blocked_by + end + + private + + def clear_and_propagate_touch(stack_or_element = @Delayed) + return if stack_or_element.nil? + + if stack_or_element.is_a? LockFreeStack + stack_or_element.clear_each { |element| clear_and_propagate_touch element } + else + stack_or_element.touch unless stack_or_element.nil? # if still present + end + end + + # @return [true,false] if resolvable + def resolvable?(countdown, future, index) + countdown.zero? + end + + def process_on_blocker_resolution(future, index) + @Countdown.decrement + end + + def on_resolvable(resolved_future, index) + raise NotImplementedError + end + end + + # @abstract + class BlockedTaskPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor, executor, args, &task) + raise ArgumentError, 'no block given' unless block_given? + super delayed, 1, Future.new(self, default_executor) + @Executor = executor + @Task = task + @Args = args + end + + def executor + @Executor + end + end + + class ThenPromise < BlockedTaskPromise + private + + def initialize(delayed, blockers_count, default_executor, executor, args, &task) + super delayed, blockers_count, default_executor, executor, args, &task + end + + def on_resolvable(resolved_future, index) + if resolved_future.fulfilled? + Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| + evaluate_to lambda { future.apply args, task } + end + else + resolve_with resolved_future.internal_state + end + end + end + + class RescuePromise < BlockedTaskPromise + private + + def initialize(delayed, blockers_count, default_executor, executor, args, &task) + super delayed, blockers_count, default_executor, executor, args, &task + end + + def on_resolvable(resolved_future, index) + if resolved_future.rejected? + Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| + evaluate_to lambda { future.apply args, task } + end + else + resolve_with resolved_future.internal_state + end + end + end + + class ChainPromise < BlockedTaskPromise + private + + def on_resolvable(resolved_future, index) + if Future === resolved_future + Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| + evaluate_to(*future.result, *args, task) + end + else + Concurrent.executor(@Executor).post(@Args, @Task) do |args, task| + evaluate_to(*args, task) + end + end + end + end + + # will be immediately resolved + class ImmediateEventPromise < InnerPromise + def initialize(default_executor) + super Event.new(self, default_executor).resolve_with(RESOLVED) + end + end + + class ImmediateFuturePromise < InnerPromise + def initialize(default_executor, fulfilled, value, reason) + super Future.new(self, default_executor). + resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason)) + end + end + + class AbstractFlatPromise < BlockedPromise + + def initialize(delayed_because, blockers_count, event_or_future) + delayed = LockFreeStack.of1(self) + super(delayed, blockers_count, event_or_future) + # noinspection RubyArgCount + @Touched = AtomicBoolean.new false + @DelayedBecause = delayed_because || LockFreeStack.new + + event_or_future.add_callback_clear_delayed_node delayed.peek + end + + def touch + if @Touched.make_true + clear_and_propagate_touch @DelayedBecause + end + end + + private + + def touched? + @Touched.value + end + + def on_resolvable(resolved_future, index) + resolve_with resolved_future.internal_state + end + + def resolvable?(countdown, future, index) + !@Future.internal_state.resolved? && super(countdown, future, index) + end + + def add_delayed_of(future) + delayed = future.promise.delayed_because + if touched? + clear_and_propagate_touch delayed + else + BlockedPromise.add_delayed @DelayedBecause, delayed + clear_and_propagate_touch @DelayedBecause if touched? + end + end + + end + + class FlatEventPromise < AbstractFlatPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, 2, Event.new(self, default_executor) + end + + def process_on_blocker_resolution(future, index) + countdown = super(future, index) + if countdown.nonzero? + internal_state = future.internal_state + + unless internal_state.fulfilled? + resolve_with RESOLVED + return countdown + end + + value = internal_state.value + case value + when AbstractEventFuture + add_delayed_of value + value.add_callback_notify_blocked self, nil + countdown + else + resolve_with RESOLVED + end + end + countdown + end + + end + + class FlatFuturePromise < AbstractFlatPromise + + private + + def initialize(delayed, blockers_count, levels, default_executor) + raise ArgumentError, 'levels has to be higher than 0' if levels < 1 + # flat promise may result to a future having delayed futures, therefore we have to have empty stack + # to be able to add new delayed futures + super delayed || LockFreeStack.new, 1 + levels, Future.new(self, default_executor) + end + + def process_on_blocker_resolution(future, index) + countdown = super(future, index) + if countdown.nonzero? + internal_state = future.internal_state + + unless internal_state.fulfilled? + resolve_with internal_state + return countdown + end + + value = internal_state.value + case value + when AbstractEventFuture + add_delayed_of value + value.add_callback_notify_blocked self, nil + countdown + else + evaluate_to(lambda { raise TypeError, "returned value #{value.inspect} is not a Future" }) + end + end + countdown + end + + end + + class RunFuturePromise < AbstractFlatPromise + + private + + def initialize(delayed, blockers_count, default_executor, run_test) + super delayed, 1, Future.new(self, default_executor) + @RunTest = run_test + end + + def process_on_blocker_resolution(future, index) + internal_state = future.internal_state + + unless internal_state.fulfilled? + resolve_with internal_state + return 0 + end + + value = internal_state.value + continuation_future = @RunTest.call value + + if continuation_future + add_delayed_of continuation_future + continuation_future.add_callback_notify_blocked self, nil + else + resolve_with internal_state + end + + 1 + end + end + + class ZipEventEventPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 2, Event.new(self, default_executor) + end + + private + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED + end + end + + class ZipFutureEventPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 2, Future.new(self, default_executor) + @result = nil + end + + private + + def process_on_blocker_resolution(future, index) + # first blocking is future, take its result + @result = future.internal_state if index == 0 + # super has to be called after above to piggyback on volatile @Countdown + super future, index + end + + def on_resolvable(resolved_future, index) + resolve_with @result + end + end + + class EventWrapperPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 1, Event.new(self, default_executor) + end + + private + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED + end + end + + class FutureWrapperPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 1, Future.new(self, default_executor) + end + + private + + def on_resolvable(resolved_future, index) + resolve_with resolved_future.internal_state + end + end + + class ZipFuturesPromise < BlockedPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super(delayed, blockers_count, Future.new(self, default_executor)) + @Resolutions = ::Array.new(blockers_count, nil) + + on_resolvable nil, nil if blockers_count == 0 + end + + def process_on_blocker_resolution(future, index) + # TODO (pitr-ch 18-Dec-2016): Can we assume that array will never break under parallel access when never re-sized? + @Resolutions[index] = future.internal_state # has to be set before countdown in super + super future, index + end + + def on_resolvable(resolved_future, index) + all_fulfilled = true + values = ::Array.new(@Resolutions.size) + reasons = ::Array.new(@Resolutions.size) + + @Resolutions.each_with_index do |internal_state, i| + fulfilled, values[i], reasons[i] = internal_state.result + all_fulfilled &&= fulfilled + end + + if all_fulfilled + resolve_with FulfilledArray.new(values) + else + resolve_with PartiallyRejected.new(values, reasons) + end + end + end + + class ZipEventsPromise < BlockedPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, blockers_count, Event.new(self, default_executor) + + on_resolvable nil, nil if blockers_count == 0 + end + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED + end + end + + # @abstract + class AbstractAnyPromise < BlockedPromise + end + + class AnyResolvedEventPromise < AbstractAnyPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, blockers_count, Event.new(self, default_executor) + end + + def resolvable?(countdown, future, index) + true + end + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED, false + end + end + + class AnyResolvedFuturePromise < AbstractAnyPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, blockers_count, Future.new(self, default_executor) + end + + def resolvable?(countdown, future, index) + true + end + + def on_resolvable(resolved_future, index) + resolve_with resolved_future.internal_state, false + end + end + + class AnyFulfilledFuturePromise < AnyResolvedFuturePromise + + private + + def resolvable?(countdown, event_or_future, index) + (event_or_future.is_a?(Event) ? event_or_future.resolved? : event_or_future.fulfilled?) || + # inlined super from BlockedPromise + countdown.zero? + end + end + + class DelayPromise < InnerPromise + + def initialize(default_executor) + event = Event.new(self, default_executor) + @Delayed = LockFreeStack.of1(self) + super event + event.add_callback_clear_delayed_node @Delayed.peek + end + + def touch + @Future.resolve_with RESOLVED + end + + def delayed_because + @Delayed + end + + end + + class ScheduledPromise < InnerPromise + def intended_time + @IntendedTime + end + + def inspect + "#{to_s[0..-2]} intended_time: #{@IntendedTime}>" + end + + private + + def initialize(default_executor, intended_time) + super Event.new(self, default_executor) + + @IntendedTime = intended_time + + in_seconds = begin + now = Time.now + schedule_time = if @IntendedTime.is_a? Time + @IntendedTime + else + now + @IntendedTime + end + [0, schedule_time.to_f - now.to_f].max + end + + Concurrent.global_timer_set.post(in_seconds) do + @Future.resolve_with RESOLVED + end + end + end + + extend FactoryMethods + + private_constant :AbstractPromise, + :ResolvableEventPromise, + :ResolvableFuturePromise, + :InnerPromise, + :BlockedPromise, + :BlockedTaskPromise, + :ThenPromise, + :RescuePromise, + :ChainPromise, + :ImmediateEventPromise, + :ImmediateFuturePromise, + :AbstractFlatPromise, + :FlatFuturePromise, + :FlatEventPromise, + :RunFuturePromise, + :ZipEventEventPromise, + :ZipFutureEventPromise, + :EventWrapperPromise, + :FutureWrapperPromise, + :ZipFuturesPromise, + :ZipEventsPromise, + :AbstractAnyPromise, + :AnyResolvedFuturePromise, + :AnyFulfilledFuturePromise, + :AnyResolvedEventPromise, + :DelayPromise, + :ScheduledPromise + + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/re_include.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/re_include.rb new file mode 100644 index 0000000..600bc6a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/re_include.rb @@ -0,0 +1,60 @@ +module Concurrent + + # Methods form module A included to a module B, which is already included into class C, + # will not be visible in the C class. If this module is extended to B then A's methods + # are correctly made visible to C. + # + # @example + # module A + # def a + # :a + # end + # end + # + # module B1 + # end + # + # class C1 + # include B1 + # end + # + # module B2 + # extend Concurrent::ReInclude + # end + # + # class C2 + # include B2 + # end + # + # B1.send :include, A + # B2.send :include, A + # + # C1.new.respond_to? :a # => false + # C2.new.respond_to? :a # => true + # + # @!visibility private + module ReInclude + # @!visibility private + def included(base) + (@re_include_to_bases ||= []) << [:include, base] + super(base) + end + + # @!visibility private + def extended(base) + (@re_include_to_bases ||= []) << [:extend, base] + super(base) + end + + # @!visibility private + def include(*modules) + result = super(*modules) + modules.reverse.each do |module_being_included| + (@re_include_to_bases ||= []).each do |method, mod| + mod.send method, module_being_included + end + end + result + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/scheduled_task.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/scheduled_task.rb new file mode 100644 index 0000000..efe9e19 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/scheduled_task.rb @@ -0,0 +1,331 @@ +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/configuration' +require 'concurrent/ivar' +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/utility/monotonic_time' + +require 'concurrent/options' + +module Concurrent + + # `ScheduledTask` is a close relative of `Concurrent::Future` but with one + # important difference: A `Future` is set to execute as soon as possible + # whereas a `ScheduledTask` is set to execute after a specified delay. This + # implementation is loosely based on Java's + # [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html). + # It is a more feature-rich variant of {Concurrent.timer}. + # + # The *intended* schedule time of task execution is set on object construction + # with the `delay` argument. The delay is a numeric (floating point or integer) + # representing a number of seconds in the future. Any other value or a numeric + # equal to or less than zero will result in an exception. The *actual* schedule + # time of task execution is set when the `execute` method is called. + # + # The constructor can also be given zero or more processing options. Currently + # the only supported options are those recognized by the + # [Dereferenceable](Dereferenceable) module. + # + # The final constructor argument is a block representing the task to be performed. + # If no block is given an `ArgumentError` will be raised. + # + # **States** + # + # `ScheduledTask` mixes in the [Obligation](Obligation) module thus giving it + # "future" behavior. This includes the expected lifecycle states. `ScheduledTask` + # has one additional state, however. While the task (block) is being executed the + # state of the object will be `:processing`. This additional state is necessary + # because it has implications for task cancellation. + # + # **Cancellation** + # + # A `:pending` task can be cancelled using the `#cancel` method. A task in any + # other state, including `:processing`, cannot be cancelled. The `#cancel` + # method returns a boolean indicating the success of the cancellation attempt. + # A cancelled `ScheduledTask` cannot be restarted. It is immutable. + # + # **Obligation and Observation** + # + # The result of a `ScheduledTask` can be obtained either synchronously or + # asynchronously. `ScheduledTask` mixes in both the [Obligation](Obligation) + # module and the + # [Observable](http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html) + # module from the Ruby standard library. With one exception `ScheduledTask` + # behaves identically to [Future](Observable) with regard to these modules. + # + # @!macro copy_options + # + # @example Basic usage + # + # require 'concurrent/scheduled_task' + # require 'csv' + # require 'open-uri' + # + # class Ticker + # def get_year_end_closing(symbol, year, api_key) + # uri = "https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=#{symbol}&apikey=#{api_key}&datatype=csv" + # data = [] + # csv = URI.parse(uri).read + # if csv.include?('call frequency') + # return :rate_limit_exceeded + # end + # CSV.parse(csv, headers: true) do |row| + # data << row['close'].to_f if row['timestamp'].include?(year.to_s) + # end + # year_end = data.first + # year_end + # rescue => e + # p e + # end + # end + # + # api_key = ENV['ALPHAVANTAGE_KEY'] + # abort(error_message) unless api_key + # + # # Future + # price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013, api_key) } + # price.state #=> :pending + # price.pending? #=> true + # price.value(0) #=> nil (does not block) + # + # sleep(1) # do other stuff + # + # price.value #=> 63.65 (after blocking if necessary) + # price.state #=> :fulfilled + # price.fulfilled? #=> true + # price.value #=> 63.65 + # + # @example Successful task execution + # + # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' } + # task.state #=> :unscheduled + # task.execute + # task.state #=> pending + # + # # wait for it... + # sleep(3) + # + # task.unscheduled? #=> false + # task.pending? #=> false + # task.fulfilled? #=> true + # task.rejected? #=> false + # task.value #=> 'What does the fox say?' + # + # @example One line creation and execution + # + # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }.execute + # task.state #=> pending + # + # task = Concurrent::ScheduledTask.execute(2){ 'What do you get when you multiply 6 by 9?' } + # task.state #=> pending + # + # @example Failed task execution + # + # task = Concurrent::ScheduledTask.execute(2){ raise StandardError.new('Call me maybe?') } + # task.pending? #=> true + # + # # wait for it... + # sleep(3) + # + # task.unscheduled? #=> false + # task.pending? #=> false + # task.fulfilled? #=> false + # task.rejected? #=> true + # task.value #=> nil + # task.reason #=> # + # + # @example Task execution with observation + # + # observer = Class.new{ + # def update(time, value, reason) + # puts "The task completed at #{time} with value '#{value}'" + # end + # }.new + # + # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' } + # task.add_observer(observer) + # task.execute + # task.pending? #=> true + # + # # wait for it... + # sleep(3) + # + # #>> The task completed at 2013-11-07 12:26:09 -0500 with value 'What does the fox say?' + # + # @!macro monotonic_clock_warning + # + # @see Concurrent.timer + class ScheduledTask < IVar + include Comparable + + # The executor on which to execute the task. + # @!visibility private + attr_reader :executor + + # Schedule a task for execution at a specified future time. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @yield the task to be performed + # + # @!macro executor_and_deref_options + # + # @option opts [object, Array] :args zero or more arguments to be passed the task + # block on execution + # + # @raise [ArgumentError] When no block is given + # @raise [ArgumentError] When given a time that is in the past + def initialize(delay, opts = {}, &task) + raise ArgumentError.new('no block given') unless block_given? + raise ArgumentError.new('seconds must be greater than zero') if delay.to_f < 0.0 + + super(NULL, opts, &nil) + + synchronize do + ns_set_state(:unscheduled) + @parent = opts.fetch(:timer_set, Concurrent.global_timer_set) + @args = get_arguments_from(opts) + @delay = delay.to_f + @task = task + @time = nil + @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + self.observers = Collection::CopyOnNotifyObserverSet.new + end + end + + # The `delay` value given at instantiation. + # + # @return [Float] the initial delay. + def initial_delay + synchronize { @delay } + end + + # The monotonic time at which the the task is scheduled to be executed. + # + # @return [Float] the schedule time or nil if `unscheduled` + def schedule_time + synchronize { @time } + end + + # Comparator which orders by schedule time. + # + # @!visibility private + def <=>(other) + schedule_time <=> other.schedule_time + end + + # Has the task been cancelled? + # + # @return [Boolean] true if the task is in the given state else false + def cancelled? + synchronize { ns_check_state?(:cancelled) } + end + + # In the task execution in progress? + # + # @return [Boolean] true if the task is in the given state else false + def processing? + synchronize { ns_check_state?(:processing) } + end + + # Cancel this task and prevent it from executing. A task can only be + # cancelled if it is pending or unscheduled. + # + # @return [Boolean] true if successfully cancelled else false + def cancel + if compare_and_set_state(:cancelled, :pending, :unscheduled) + complete(false, nil, CancelledOperationError.new) + # To avoid deadlocks this call must occur outside of #synchronize + # Changing the state above should prevent redundant calls + @parent.send(:remove_task, self) + else + false + end + end + + # Reschedule the task using the original delay and the current time. + # A task can only be reset while it is `:pending`. + # + # @return [Boolean] true if successfully rescheduled else false + def reset + synchronize{ ns_reschedule(@delay) } + end + + # Reschedule the task using the given delay and the current time. + # A task can only be reset while it is `:pending`. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @return [Boolean] true if successfully rescheduled else false + # + # @raise [ArgumentError] When given a time that is in the past + def reschedule(delay) + delay = delay.to_f + raise ArgumentError.new('seconds must be greater than zero') if delay < 0.0 + synchronize{ ns_reschedule(delay) } + end + + # Execute an `:unscheduled` `ScheduledTask`. Immediately sets the state to `:pending` + # and starts counting down toward execution. Does nothing if the `ScheduledTask` is + # in any state other than `:unscheduled`. + # + # @return [ScheduledTask] a reference to `self` + def execute + if compare_and_set_state(:pending, :unscheduled) + synchronize{ ns_schedule(@delay) } + end + self + end + + # Create a new `ScheduledTask` object with the given block, execute it, and return the + # `:pending` object. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @!macro executor_and_deref_options + # + # @return [ScheduledTask] the newly created `ScheduledTask` in the `:pending` state + # + # @raise [ArgumentError] if no block is given + def self.execute(delay, opts = {}, &task) + new(delay, opts, &task).execute + end + + # Execute the task. + # + # @!visibility private + def process_task + safe_execute(@task, @args) + end + + protected :set, :try_set, :fail, :complete + + protected + + # Schedule the task using the given delay and the current time. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @return [Boolean] true if successfully rescheduled else false + # + # @!visibility private + def ns_schedule(delay) + @delay = delay + @time = Concurrent.monotonic_time + @delay + @parent.send(:post_task, self) + end + + # Reschedule the task using the given delay and the current time. + # A task can only be reset while it is `:pending`. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @return [Boolean] true if successfully rescheduled else false + # + # @!visibility private + def ns_reschedule(delay) + return false unless ns_check_state?(:pending) + @parent.send(:remove_task, self) && ns_schedule(delay) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/set.rb new file mode 100644 index 0000000..eee4eff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/set.rb @@ -0,0 +1,64 @@ +require 'concurrent/utility/engine' +require 'concurrent/thread_safe/util' +require 'set' + +module Concurrent + + # @!macro concurrent_set + # + # A thread-safe subclass of Set. This version locks against the object + # itself for every method call, ensuring only one thread can be reading + # or writing at a time. This includes iteration methods like `#each`. + # + # @note `a += b` is **not** a **thread-safe** operation on + # `Concurrent::Set`. It reads Set `a`, then it creates new `Concurrent::Set` + # which is union of `a` and `b`, then it writes the union to `a`. + # The read and write are independent operations they do not form a single atomic + # operation therefore when two `+=` operations are executed concurrently updates + # may be lost. Use `#merge` instead. + # + # @see http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html Ruby standard library `Set` + + # @!macro internal_implementation_note + SetImplementation = case + when Concurrent.on_cruby? + # The CRuby implementation of Set is written in Ruby itself and is + # not thread safe for certain methods. + require 'monitor' + require 'concurrent/thread_safe/util/data_structures' + + class CRubySet < ::Set + end + + ThreadSafe::Util.make_synchronized_on_cruby CRubySet + CRubySet + + when Concurrent.on_jruby? + require 'jruby/synchronized' + + class JRubySet < ::Set + include JRuby::Synchronized + end + + JRubySet + + when Concurrent.on_truffleruby? + require 'concurrent/thread_safe/util/data_structures' + + class TruffleRubySet < ::Set + end + + ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubySet + TruffleRubySet + + else + warn 'Possibly unsupported Ruby implementation' + ::Set + end + private_constant :SetImplementation + + # @!macro concurrent_set + class Set < SetImplementation + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/settable_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/settable_struct.rb new file mode 100644 index 0000000..99b8561 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/settable_struct.rb @@ -0,0 +1,139 @@ +require 'concurrent/errors' +require 'concurrent/synchronization/abstract_struct' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # An thread-safe, write-once variation of Ruby's standard `Struct`. + # Each member can have its value set at most once, either at construction + # or any time thereafter. Attempting to assign a value to a member + # that has already been set will result in a `Concurrent::ImmutabilityError`. + # + # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` + # @see http://en.wikipedia.org/wiki/Final_(Java) Java `final` keyword + module SettableStruct + include Synchronization::AbstractStruct + + # @!macro struct_values + def values + synchronize { ns_values } + end + alias_method :to_a, :values + + # @!macro struct_values_at + def values_at(*indexes) + synchronize { ns_values_at(indexes) } + end + + # @!macro struct_inspect + def inspect + synchronize { ns_inspect } + end + alias_method :to_s, :inspect + + # @!macro struct_merge + def merge(other, &block) + synchronize { ns_merge(other, &block) } + end + + # @!macro struct_to_h + def to_h + synchronize { ns_to_h } + end + + # @!macro struct_get + def [](member) + synchronize { ns_get(member) } + end + + # @!macro struct_equality + def ==(other) + synchronize { ns_equality(other) } + end + + # @!macro struct_each + def each(&block) + return enum_for(:each) unless block_given? + synchronize { ns_each(&block) } + end + + # @!macro struct_each_pair + def each_pair(&block) + return enum_for(:each_pair) unless block_given? + synchronize { ns_each_pair(&block) } + end + + # @!macro struct_select + def select(&block) + return enum_for(:select) unless block_given? + synchronize { ns_select(&block) } + end + + # @!macro struct_set + # + # @raise [Concurrent::ImmutabilityError] if the given member has already been set + def []=(member, value) + if member.is_a? Integer + length = synchronize { @values.length } + if member >= length + raise IndexError.new("offset #{member} too large for struct(size:#{length})") + end + synchronize do + unless @values[member].nil? + raise Concurrent::ImmutabilityError.new('struct member has already been set') + end + @values[member] = value + end + else + send("#{member}=", value) + end + rescue NoMethodError + raise NameError.new("no member '#{member}' in struct") + end + + private + + # @!visibility private + def initialize_copy(original) + synchronize do + super(original) + ns_initialize_copy + end + end + + # @!macro struct_new + def self.new(*args, &block) + clazz_name = nil + if args.length == 0 + raise ArgumentError.new('wrong number of arguments (0 for 1+)') + elsif args.length > 0 && args.first.is_a?(String) + clazz_name = args.shift + end + FACTORY.define_struct(clazz_name, args, &block) + end + + FACTORY = Class.new(Synchronization::LockableObject) do + def define_struct(name, members, &block) + synchronize do + clazz = Synchronization::AbstractStruct.define_struct_class(SettableStruct, Synchronization::LockableObject, name, members, &block) + members.each_with_index do |member, index| + clazz.send :remove_method, member if clazz.instance_methods.include? member + clazz.send(:define_method, member) do + synchronize { @values[index] } + end + clazz.send(:define_method, "#{member}=") do |value| + synchronize do + unless @values[index].nil? + raise Concurrent::ImmutabilityError.new('struct member has already been set') + end + @values[index] = value + end + end + end + clazz + end + end + end.new + private_constant :FACTORY + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization.rb new file mode 100644 index 0000000..6d8cf4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization.rb @@ -0,0 +1,13 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/synchronization/object' +require 'concurrent/synchronization/lockable_object' +require 'concurrent/synchronization/condition' +require 'concurrent/synchronization/lock' + +module Concurrent + # @!visibility private + module Synchronization + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb new file mode 100644 index 0000000..d9050b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb @@ -0,0 +1,102 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first +require 'concurrent/utility/monotonic_time' +require 'concurrent/synchronization/object' + +module Concurrent + module Synchronization + + # @!visibility private + class AbstractLockableObject < Synchronization::Object + + protected + + # @!macro synchronization_object_method_synchronize + # + # @yield runs the block synchronized against this object, + # equivalent of java's `synchronize(this) {}` + # @note can by made public in descendants if required by `public :synchronize` + def synchronize + raise NotImplementedError + end + + # @!macro synchronization_object_method_ns_wait_until + # + # Wait until condition is met or timeout passes, + # protects against spurious wake-ups. + # @param [Numeric, nil] timeout in seconds, `nil` means no timeout + # @yield condition to be met + # @yieldreturn [true, false] + # @return [true, false] if condition met + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def wait_until(timeout = nil, &condition) + # synchronize { ns_wait_until(timeout, &condition) } + # end + # ``` + def ns_wait_until(timeout = nil, &condition) + if timeout + wait_until = Concurrent.monotonic_time + timeout + loop do + now = Concurrent.monotonic_time + condition_result = condition.call + return condition_result if now >= wait_until || condition_result + ns_wait wait_until - now + end + else + ns_wait timeout until condition.call + true + end + end + + # @!macro synchronization_object_method_ns_wait + # + # Wait until another thread calls #signal or #broadcast, + # spurious wake-ups can happen. + # + # @param [Numeric, nil] timeout in seconds, `nil` means no timeout + # @return [self] + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def wait(timeout = nil) + # synchronize { ns_wait(timeout) } + # end + # ``` + def ns_wait(timeout = nil) + raise NotImplementedError + end + + # @!macro synchronization_object_method_ns_signal + # + # Signal one waiting thread. + # @return [self] + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def signal + # synchronize { ns_signal } + # end + # ``` + def ns_signal + raise NotImplementedError + end + + # @!macro synchronization_object_method_ns_broadcast + # + # Broadcast to all waiting threads. + # @return [self] + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def broadcast + # synchronize { ns_broadcast } + # end + # ``` + def ns_broadcast + raise NotImplementedError + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb new file mode 100644 index 0000000..7cd2dec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb @@ -0,0 +1,22 @@ +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + class AbstractObject + def initialize + # nothing to do + end + + # @!visibility private + # @abstract + def full_memory_barrier + raise NotImplementedError + end + + def self.attr_volatile(*names) + raise NotImplementedError + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb new file mode 100644 index 0000000..28816c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb @@ -0,0 +1,171 @@ +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + module AbstractStruct + + # @!visibility private + def initialize(*values) + super() + ns_initialize(*values) + end + + # @!macro struct_length + # + # Returns the number of struct members. + # + # @return [Fixnum] the number of struct members + def length + self.class::MEMBERS.length + end + alias_method :size, :length + + # @!macro struct_members + # + # Returns the struct members as an array of symbols. + # + # @return [Array] the struct members as an array of symbols + def members + self.class::MEMBERS.dup + end + + protected + + # @!macro struct_values + # + # @!visibility private + def ns_values + @values.dup + end + + # @!macro struct_values_at + # + # @!visibility private + def ns_values_at(indexes) + @values.values_at(*indexes) + end + + # @!macro struct_to_h + # + # @!visibility private + def ns_to_h + length.times.reduce({}){|memo, i| memo[self.class::MEMBERS[i]] = @values[i]; memo} + end + + # @!macro struct_get + # + # @!visibility private + def ns_get(member) + if member.is_a? Integer + if member >= @values.length + raise IndexError.new("offset #{member} too large for struct(size:#{@values.length})") + end + @values[member] + else + send(member) + end + rescue NoMethodError + raise NameError.new("no member '#{member}' in struct") + end + + # @!macro struct_equality + # + # @!visibility private + def ns_equality(other) + self.class == other.class && self.values == other.values + end + + # @!macro struct_each + # + # @!visibility private + def ns_each + values.each{|value| yield value } + end + + # @!macro struct_each_pair + # + # @!visibility private + def ns_each_pair + @values.length.times do |index| + yield self.class::MEMBERS[index], @values[index] + end + end + + # @!macro struct_select + # + # @!visibility private + def ns_select + values.select{|value| yield value } + end + + # @!macro struct_inspect + # + # @!visibility private + def ns_inspect + struct = pr_underscore(self.class.ancestors[1]) + clazz = ((self.class.to_s =~ /^#" + end + + # @!macro struct_merge + # + # @!visibility private + def ns_merge(other, &block) + self.class.new(*self.to_h.merge(other, &block).values) + end + + # @!visibility private + def ns_initialize_copy + @values = @values.map do |val| + begin + val.clone + rescue TypeError + val + end + end + end + + # @!visibility private + def pr_underscore(clazz) + word = clazz.to_s.dup # dup string to workaround JRuby 9.2.0.0 bug https://github.com/jruby/jruby/issues/5229 + word.gsub!(/::/, '/') + word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2') + word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') + word.tr!("-", "_") + word.downcase! + word + end + + # @!visibility private + def self.define_struct_class(parent, base, name, members, &block) + clazz = Class.new(base || Object) do + include parent + self.const_set(:MEMBERS, members.collect{|member| member.to_s.to_sym}.freeze) + def ns_initialize(*values) + raise ArgumentError.new('struct size differs') if values.length > length + @values = values.fill(nil, values.length..length-1) + end + end + unless name.nil? + begin + parent.send :remove_const, name if parent.const_defined?(name, false) + parent.const_set(name, clazz) + clazz + rescue NameError + raise NameError.new("identifier #{name} needs to be constant") + end + end + members.each_with_index do |member, index| + clazz.send :remove_method, member if clazz.instance_methods(false).include? member + clazz.send(:define_method, member) do + @values[index] + end + end + clazz.class_exec(&block) unless block.nil? + clazz.singleton_class.send :alias_method, :[], :new + clazz + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/condition.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/condition.rb new file mode 100644 index 0000000..5daa68b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/condition.rb @@ -0,0 +1,62 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # TODO (pitr-ch 04-Dec-2016): should be in edge + class Condition < LockableObject + safe_initialization! + + # TODO (pitr 12-Sep-2015): locks two objects, improve + # TODO (pitr 26-Sep-2015): study + # http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/concurrent/locks/AbstractQueuedSynchronizer.java#AbstractQueuedSynchronizer.Node + + singleton_class.send :alias_method, :private_new, :new + private_class_method :new + + def initialize(lock) + super() + @Lock = lock + end + + def wait(timeout = nil) + @Lock.synchronize { ns_wait(timeout) } + end + + def ns_wait(timeout = nil) + synchronize { super(timeout) } + end + + def wait_until(timeout = nil, &condition) + @Lock.synchronize { ns_wait_until(timeout, &condition) } + end + + def ns_wait_until(timeout = nil, &condition) + synchronize { super(timeout, &condition) } + end + + def signal + @Lock.synchronize { ns_signal } + end + + def ns_signal + synchronize { super } + end + + def broadcast + @Lock.synchronize { ns_broadcast } + end + + def ns_broadcast + synchronize { super } + end + end + + class LockableObject < LockableObjectImplementation + def new_condition + Condition.private_new(self) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb new file mode 100644 index 0000000..139e08d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb @@ -0,0 +1,29 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +module Concurrent + module Synchronization + case + when Concurrent.on_cruby? + def self.full_memory_barrier + # relying on undocumented behavior of CRuby, GVL acquire has lock which ensures visibility of ivars + # https://github.com/ruby/ruby/blob/ruby_2_2/thread_pthread.c#L204-L211 + end + + when Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + def self.full_memory_barrier + JRubyAttrVolatile.full_memory_barrier + end + + when Concurrent.on_truffleruby? + def self.full_memory_barrier + TruffleRuby.full_memory_barrier + end + + else + warn 'Possibly unsupported Ruby implementation' + def self.full_memory_barrier + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb new file mode 100644 index 0000000..7693046 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb @@ -0,0 +1,15 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +module Concurrent + module Synchronization + + if Concurrent.on_jruby? + + # @!visibility private + # @!macro internal_implementation_note + class JRubyLockableObject < AbstractLockableObject + + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lock.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lock.rb new file mode 100644 index 0000000..f90e0b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lock.rb @@ -0,0 +1,38 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # TODO (pitr-ch 04-Dec-2016): should be in edge + class Lock < LockableObject + # TODO use JavaReentrantLock on JRuby + + public :synchronize + + def wait(timeout = nil) + synchronize { ns_wait(timeout) } + end + + public :ns_wait + + def wait_until(timeout = nil, &condition) + synchronize { ns_wait_until(timeout, &condition) } + end + + public :ns_wait_until + + def signal + synchronize { ns_signal } + end + + public :ns_signal + + def broadcast + synchronize { ns_broadcast } + end + + public :ns_broadcast + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb new file mode 100644 index 0000000..08d2ff6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb @@ -0,0 +1,75 @@ +require 'concurrent/utility/engine' +require 'concurrent/synchronization/abstract_lockable_object' +require 'concurrent/synchronization/mutex_lockable_object' +require 'concurrent/synchronization/jruby_lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + LockableObjectImplementation = case + when Concurrent.on_cruby? + MutexLockableObject + when Concurrent.on_jruby? + JRubyLockableObject + when Concurrent.on_truffleruby? + MutexLockableObject + else + warn 'Possibly unsupported Ruby implementation' + MonitorLockableObject + end + private_constant :LockableObjectImplementation + + # Safe synchronization under any Ruby implementation. + # It provides methods like {#synchronize}, {#wait}, {#signal} and {#broadcast}. + # Provides a single layer which can improve its implementation over time without changes needed to + # the classes using it. Use {Synchronization::Object} not this abstract class. + # + # @note this object does not support usage together with + # [`Thread#wakeup`](http://ruby-doc.org/core/Thread.html#method-i-wakeup) + # and [`Thread#raise`](http://ruby-doc.org/core/Thread.html#method-i-raise). + # `Thread#sleep` and `Thread#wakeup` will work as expected but mixing `Synchronization::Object#wait` and + # `Thread#wakeup` will not work on all platforms. + # + # @see Event implementation as an example of this class use + # + # @example simple + # class AnClass < Synchronization::Object + # def initialize + # super + # synchronize { @value = 'asd' } + # end + # + # def value + # synchronize { @value } + # end + # end + # + # @!visibility private + class LockableObject < LockableObjectImplementation + + # TODO (pitr 12-Sep-2015): make private for c-r, prohibit subclassing + # TODO (pitr 12-Sep-2015): we inherit too much ourselves :/ + + # @!method initialize(*args, &block) + # @!macro synchronization_object_method_initialize + + # @!method synchronize + # @!macro synchronization_object_method_synchronize + + # @!method wait_until(timeout = nil, &condition) + # @!macro synchronization_object_method_ns_wait_until + + # @!method wait(timeout = nil) + # @!macro synchronization_object_method_ns_wait + + # @!method signal + # @!macro synchronization_object_method_ns_signal + + # @!method broadcast + # @!macro synchronization_object_method_ns_broadcast + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb new file mode 100644 index 0000000..acc9745 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb @@ -0,0 +1,89 @@ +require 'concurrent/synchronization/abstract_lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + module ConditionSignalling + protected + + def ns_signal + @__Condition__.signal + self + end + + def ns_broadcast + @__Condition__.broadcast + self + end + end + + + # @!visibility private + # @!macro internal_implementation_note + class MutexLockableObject < AbstractLockableObject + include ConditionSignalling + + safe_initialization! + + def initialize + super() + @__Lock__ = ::Mutex.new + @__Condition__ = ::ConditionVariable.new + end + + def initialize_copy(other) + super + @__Lock__ = ::Mutex.new + @__Condition__ = ::ConditionVariable.new + end + + protected + + def synchronize + if @__Lock__.owned? + yield + else + @__Lock__.synchronize { yield } + end + end + + def ns_wait(timeout = nil) + @__Condition__.wait @__Lock__, timeout + self + end + end + + # @!visibility private + # @!macro internal_implementation_note + class MonitorLockableObject < AbstractLockableObject + include ConditionSignalling + + safe_initialization! + + def initialize + super() + @__Lock__ = ::Monitor.new + @__Condition__ = @__Lock__.new_cond + end + + def initialize_copy(other) + super + @__Lock__ = ::Monitor.new + @__Condition__ = @__Lock__.new_cond + end + + protected + + def synchronize # TODO may be a problem with lock.synchronize { lock.wait } + @__Lock__.synchronize { yield } + end + + def ns_wait(timeout = nil) + @__Condition__.wait timeout + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/object.rb new file mode 100644 index 0000000..5921907 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/object.rb @@ -0,0 +1,151 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/synchronization/safe_initialization' +require 'concurrent/synchronization/volatile' +require 'concurrent/atomic/atomic_reference' + +module Concurrent + module Synchronization + + # Abstract object providing final, volatile, ans CAS extensions to build other concurrent abstractions. + # - final instance variables see {Object.safe_initialization!} + # - volatile instance variables see {Object.attr_volatile} + # - volatile instance variables see {Object.attr_atomic} + # @!visibility private + class Object < AbstractObject + include Volatile + + # TODO make it a module if possible + + # @!method self.attr_volatile(*names) + # Creates methods for reading and writing (as `attr_accessor` does) to a instance variable with + # volatile (Java) semantic. The instance variable should be accessed only through generated methods. + # + # @param [::Array] names of the instance variables to be volatile + # @return [::Array] names of defined method names + + # Has to be called by children. + def initialize + super + __initialize_atomic_fields__ + end + + def self.safe_initialization! + extend SafeInitialization unless safe_initialization? + end + + def self.safe_initialization? + self.singleton_class < SafeInitialization + end + + # For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains + # any instance variables with CamelCase names and isn't {.safe_initialization?}. + # @raise when offend found + # @return [true] + def self.ensure_safe_initialization_when_final_fields_are_present + Object.class_eval do + def self.new(*args, &block) + object = super(*args, &block) + ensure + has_final_field = object.instance_variables.any? { |v| v.to_s =~ /^@[A-Z]/ } + if has_final_field && !safe_initialization? + raise "there was an instance of #{object.class} with final field but not marked with safe_initialization!" + end + end + end + true + end + + # Creates methods for reading and writing to a instance variable with + # volatile (Java) semantic as {.attr_volatile} does. + # The instance variable should be accessed only through generated methods. + # This method generates following methods: `value`, `value=(new_value) #=> new_value`, + # `swap_value(new_value) #=> old_value`, + # `compare_and_set_value(expected, value) #=> true || false`, `update_value(&block)`. + # @param [::Array] names of the instance variables to be volatile with CAS. + # @return [::Array] names of defined method names. + # @!macro attr_atomic + # @!method $1 + # @return [Object] The $1. + # @!method $1=(new_$1) + # Set the $1. + # @return [Object] new_$1. + # @!method swap_$1(new_$1) + # Set the $1 to new_$1 and return the old $1. + # @return [Object] old $1 + # @!method compare_and_set_$1(expected_$1, new_$1) + # Sets the $1 to new_$1 if the current $1 is expected_$1 + # @return [true, false] + # @!method update_$1(&block) + # Updates the $1 using the block. + # @yield [Object] Calculate a new $1 using given (old) $1 + # @yieldparam [Object] old $1 + # @return [Object] new $1 + def self.attr_atomic(*names) + @__atomic_fields__ ||= [] + @__atomic_fields__ += names + safe_initialization! + define_initialize_atomic_fields + + names.each do |name| + ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}" + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + #{ivar}.get + end + + def #{name}=(value) + #{ivar}.set value + end + + def swap_#{name}(value) + #{ivar}.swap value + end + + def compare_and_set_#{name}(expected, value) + #{ivar}.compare_and_set expected, value + end + + def update_#{name}(&block) + #{ivar}.update(&block) + end + RUBY + end + names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] } + end + + # @param [true, false] inherited should inherited volatile with CAS fields be returned? + # @return [::Array] Returns defined volatile with CAS fields on this class. + def self.atomic_attributes(inherited = true) + @__atomic_fields__ ||= [] + ((superclass.atomic_attributes if superclass.respond_to?(:atomic_attributes) && inherited) || []) + @__atomic_fields__ + end + + # @return [true, false] is the attribute with name atomic? + def self.atomic_attribute?(name) + atomic_attributes.include? name + end + + private + + def self.define_initialize_atomic_fields + assignments = @__atomic_fields__.map do |name| + "@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }} = Concurrent::AtomicReference.new(nil)" + end.join("\n") + + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def __initialize_atomic_fields__ + super + #{assignments} + end + RUBY + end + + private_class_method :define_initialize_atomic_fields + + def __initialize_atomic_fields__ + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb new file mode 100644 index 0000000..f785e35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb @@ -0,0 +1,36 @@ +require 'concurrent/synchronization/full_memory_barrier' + +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + # + # By extending this module, a class and all its children are marked to be constructed safely. Meaning that + # all writes (ivar initializations) are made visible to all readers of newly constructed object. It ensures + # same behaviour as Java's final fields. + # + # Due to using Kernel#extend, the module is not included again if already present in the ancestors, + # which avoids extra overhead. + # + # @example + # class AClass < Concurrent::Synchronization::Object + # extend Concurrent::Synchronization::SafeInitialization + # + # def initialize + # @AFinalValue = 'value' # published safely, #foo will never return nil + # end + # + # def foo + # @AFinalValue + # end + # end + module SafeInitialization + def new(*args, &block) + super(*args, &block) + ensure + Concurrent::Synchronization.full_memory_barrier + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/volatile.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/volatile.rb new file mode 100644 index 0000000..46e8ba6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/synchronization/volatile.rb @@ -0,0 +1,101 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first +require 'concurrent/utility/engine' +require 'concurrent/synchronization/full_memory_barrier' + +module Concurrent + module Synchronization + + # Volatile adds the attr_volatile class method when included. + # + # @example + # class Foo + # include Concurrent::Synchronization::Volatile + # + # attr_volatile :bar + # + # def initialize + # self.bar = 1 + # end + # end + # + # foo = Foo.new + # foo.bar + # => 1 + # foo.bar = 2 + # => 2 + # + # @!visibility private + module Volatile + def self.included(base) + base.extend(ClassMethods) + end + + def full_memory_barrier + Synchronization.full_memory_barrier + end + + module ClassMethods + if Concurrent.on_cruby? + def attr_volatile(*names) + names.each do |name| + ivar = :"@volatile_#{name}" + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + #{ivar} + end + + def #{name}=(value) + #{ivar} = value + end + RUBY + end + names.map { |n| [n, :"#{n}="] }.flatten + end + + elsif Concurrent.on_jruby? + def attr_volatile(*names) + names.each do |name| + ivar = :"@volatile_#{name}" + + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_get_volatile(self, :#{ivar}) + end + + def #{name}=(value) + ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_set_volatile(self, :#{ivar}, value) + end + RUBY + + end + names.map { |n| [n, :"#{n}="] }.flatten + end + + else + warn 'Possibly unsupported Ruby implementation' unless Concurrent.on_truffleruby? + + def attr_volatile(*names) + names.each do |name| + ivar = :"@volatile_#{name}" + + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + ::Concurrent::Synchronization.full_memory_barrier + #{ivar} + end + + def #{name}=(value) + #{ivar} = value + ::Concurrent::Synchronization.full_memory_barrier + end + RUBY + end + + names.map { |n| [n, :"#{n}="] }.flatten + end + end + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb new file mode 100644 index 0000000..019d843 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb @@ -0,0 +1,47 @@ +require 'delegate' +require 'monitor' + +module Concurrent + # This class provides a trivial way to synchronize all calls to a given object + # by wrapping it with a `Delegator` that performs `Monitor#enter/exit` calls + # around the delegated `#send`. Example: + # + # array = [] # not thread-safe on many impls + # array = SynchronizedDelegator.new([]) # thread-safe + # + # A simple `Monitor` provides a very coarse-grained way to synchronize a given + # object, in that it will cause synchronization for methods that have no need + # for it, but this is a trivial way to get thread-safety where none may exist + # currently on some implementations. + # + # This class is currently being considered for inclusion into stdlib, via + # https://bugs.ruby-lang.org/issues/8556 + # + # @!visibility private + class SynchronizedDelegator < SimpleDelegator + def setup + @old_abort = Thread.abort_on_exception + Thread.abort_on_exception = true + end + + def teardown + Thread.abort_on_exception = @old_abort + end + + def initialize(obj) + __setobj__(obj) + @monitor = Monitor.new + end + + def method_missing(method, *args, &block) + monitor = @monitor + begin + monitor.enter + super + ensure + monitor.exit + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util.rb new file mode 100644 index 0000000..c67084a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util.rb @@ -0,0 +1,16 @@ +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # TODO (pitr-ch 15-Oct-2016): migrate to Utility::NativeInteger + FIXNUM_BIT_SIZE = (0.size * 8) - 2 + MAX_INT = (2 ** FIXNUM_BIT_SIZE) - 1 + # TODO (pitr-ch 15-Oct-2016): migrate to Utility::ProcessorCounter + CPU_COUNT = 16 # is there a way to determine this? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb new file mode 100644 index 0000000..852b403 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb @@ -0,0 +1,74 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/thread_safe/util/striped64' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # A Ruby port of the Doug Lea's jsr166e.LongAdder class version 1.8 + # available in public domain. + # + # Original source code available here: + # http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8 + # + # One or more variables that together maintain an initially zero + # sum. When updates (method +add+) are contended across threads, + # the set of variables may grow dynamically to reduce contention. + # Method +sum+ returns the current total combined across the + # variables maintaining the sum. + # + # This class is usually preferable to single +Atomic+ reference when + # multiple threads update a common sum that is used for purposes such + # as collecting statistics, not for fine-grained synchronization + # control. Under low update contention, the two classes have similar + # characteristics. But under high contention, expected throughput of + # this class is significantly higher, at the expense of higher space + # consumption. + # + # @!visibility private + class Adder < Striped64 + # Adds the given value. + def add(x) + if (current_cells = cells) || !cas_base_computed {|current_base| current_base + x} + was_uncontended = true + hash = hash_code + unless current_cells && (cell = current_cells.volatile_get_by_hash(hash)) && (was_uncontended = cell.cas_computed {|current_value| current_value + x}) + retry_update(x, hash, was_uncontended) {|current_value| current_value + x} + end + end + end + + def increment + add(1) + end + + def decrement + add(-1) + end + + # Returns the current sum. The returned value is _NOT_ an + # atomic snapshot: Invocation in the absence of concurrent + # updates returns an accurate result, but concurrent updates that + # occur while the sum is being calculated might not be + # incorporated. + def sum + x = base + if current_cells = cells + current_cells.each do |cell| + x += cell.value if cell + end + end + x + end + + def reset + internal_reset(0) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb new file mode 100644 index 0000000..01eb98f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb @@ -0,0 +1,52 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/utility/engine' + +# Shim for TruffleRuby.synchronized +if Concurrent.on_truffleruby? && !TruffleRuby.respond_to?(:synchronized) + module TruffleRuby + def self.synchronized(object, &block) + Truffle::System.synchronized(object, &block) + end + end +end + +module Concurrent + module ThreadSafe + module Util + def self.make_synchronized_on_cruby(klass) + klass.class_eval do + def initialize(*args, &block) + @_monitor = Monitor.new + super + end + + def initialize_copy(other) + # make sure a copy is not sharing a monitor with the original object! + @_monitor = Monitor.new + super + end + end + + klass.superclass.instance_methods(false).each do |method| + klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args) + monitor = @_monitor + monitor or raise("BUG: Internal monitor was not properly initialized. Please report this to the concurrent-ruby developers.") + monitor.synchronize { super } + end + RUBY + end + end + + def self.make_synchronized_on_truffleruby(klass) + klass.superclass.instance_methods(false).each do |method| + klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args, &block) + TruffleRuby.synchronized(self) { super(*args, &block) } + end + RUBY + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb new file mode 100644 index 0000000..b54be39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb @@ -0,0 +1,38 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/tuple' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # @!visibility private + class PowerOfTwoTuple < Concurrent::Tuple + + def initialize(size) + raise ArgumentError, "size must be a power of 2 (#{size.inspect} provided)" unless size > 0 && size & (size - 1) == 0 + super(size) + end + + def hash_to_index(hash) + (size - 1) & hash + end + + def volatile_get_by_hash(hash) + volatile_get(hash_to_index(hash)) + end + + def volatile_set_by_hash(hash, value) + volatile_set(hash_to_index(hash), value) + end + + def next_in_size_table + self.class.new(size << 1) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb new file mode 100644 index 0000000..4169c3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb @@ -0,0 +1,246 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/thread_safe/util/power_of_two_tuple' +require 'concurrent/thread_safe/util/volatile' +require 'concurrent/thread_safe/util/xor_shift_random' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # A Ruby port of the Doug Lea's jsr166e.Striped64 class version 1.6 + # available in public domain. + # + # Original source code available here: + # http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.6 + # + # Class holding common representation and mechanics for classes supporting + # dynamic striping on 64bit values. + # + # This class maintains a lazily-initialized table of atomically updated + # variables, plus an extra +base+ field. The table size is a power of two. + # Indexing uses masked per-thread hash codes. Nearly all methods on this + # class are private, accessed directly by subclasses. + # + # Table entries are of class +Cell+; a variant of AtomicLong padded to + # reduce cache contention on most processors. Padding is overkill for most + # Atomics because they are usually irregularly scattered in memory and thus + # don't interfere much with each other. But Atomic objects residing in + # arrays will tend to be placed adjacent to each other, and so will most + # often share cache lines (with a huge negative performance impact) without + # this precaution. + # + # In part because +Cell+s are relatively large, we avoid creating them until + # they are needed. When there is no contention, all updates are made to the + # +base+ field. Upon first contention (a failed CAS on +base+ update), the + # table is initialized to size 2. The table size is doubled upon further + # contention until reaching the nearest power of two greater than or equal + # to the number of CPUS. Table slots remain empty (+nil+) until they are + # needed. + # + # A single spinlock (+busy+) is used for initializing and resizing the + # table, as well as populating slots with new +Cell+s. There is no need for + # a blocking lock: When the lock is not available, threads try other slots + # (or the base). During these retries, there is increased contention and + # reduced locality, which is still better than alternatives. + # + # Per-thread hash codes are initialized to random values. Contention and/or + # table collisions are indicated by failed CASes when performing an update + # operation (see method +retry_update+). Upon a collision, if the table size + # is less than the capacity, it is doubled in size unless some other thread + # holds the lock. If a hashed slot is empty, and lock is available, a new + # +Cell+ is created. Otherwise, if the slot exists, a CAS is tried. Retries + # proceed by "double hashing", using a secondary hash (XorShift) to try to + # find a free slot. + # + # The table size is capped because, when there are more threads than CPUs, + # supposing that each thread were bound to a CPU, there would exist a + # perfect hash function mapping threads to slots that eliminates collisions. + # When we reach capacity, we search for this mapping by randomly varying the + # hash codes of colliding threads. Because search is random, and collisions + # only become known via CAS failures, convergence can be slow, and because + # threads are typically not bound to CPUS forever, may not occur at all. + # However, despite these limitations, observed contention rates are + # typically low in these cases. + # + # It is possible for a +Cell+ to become unused when threads that once hashed + # to it terminate, as well as in the case where doubling the table causes no + # thread to hash to it under expanded mask. We do not try to detect or + # remove such cells, under the assumption that for long-running instances, + # observed contention levels will recur, so the cells will eventually be + # needed again; and for short-lived ones, it does not matter. + # + # @!visibility private + class Striped64 + + # Padded variant of AtomicLong supporting only raw accesses plus CAS. + # The +value+ field is placed between pads, hoping that the JVM doesn't + # reorder them. + # + # Optimisation note: It would be possible to use a release-only + # form of CAS here, if it were provided. + # + # @!visibility private + class Cell < Concurrent::AtomicReference + + alias_method :cas, :compare_and_set + + def cas_computed + cas(current_value = value, yield(current_value)) + end + + # @!visibility private + def self.padding + # TODO: this only adds padding after the :value slot, need to find a way to add padding before the slot + # TODO (pitr-ch 28-Jul-2018): the padding instance vars may not be created + # hide from yardoc in a method + attr_reader :padding_0, :padding_1, :padding_2, :padding_3, :padding_4, :padding_5, :padding_6, :padding_7, :padding_8, :padding_9, :padding_10, :padding_11 + end + padding + end + + extend Volatile + attr_volatile :cells, # Table of cells. When non-null, size is a power of 2. + :base, # Base value, used mainly when there is no contention, but also as a fallback during table initialization races. Updated via CAS. + :busy # Spinlock (locked via CAS) used when resizing and/or creating Cells. + + alias_method :busy?, :busy + + def initialize + super() + self.busy = false + self.base = 0 + end + + # Handles cases of updates involving initialization, resizing, + # creating new Cells, and/or contention. See above for + # explanation. This method suffers the usual non-modularity + # problems of optimistic retry code, relying on rechecked sets of + # reads. + # + # Arguments: + # [+x+] + # the value + # [+hash_code+] + # hash code used + # [+x+] + # false if CAS failed before call + def retry_update(x, hash_code, was_uncontended) # :yields: current_value + hash = hash_code + collided = false # True if last slot nonempty + while true + if current_cells = cells + if !(cell = current_cells.volatile_get_by_hash(hash)) + if busy? + collided = false + else # Try to attach new Cell + if try_to_install_new_cell(Cell.new(x), hash) # Optimistically create and try to insert new cell + break + else + redo # Slot is now non-empty + end + end + elsif !was_uncontended # CAS already known to fail + was_uncontended = true # Continue after rehash + elsif cell.cas_computed {|current_value| yield current_value} + break + elsif current_cells.size >= CPU_COUNT || cells != current_cells # At max size or stale + collided = false + elsif collided && expand_table_unless_stale(current_cells) + collided = false + redo # Retry with expanded table + else + collided = true + end + hash = XorShiftRandom.xorshift(hash) + + elsif try_initialize_cells(x, hash) || cas_base_computed {|current_base| yield current_base} + break + end + end + self.hash_code = hash + end + + private + # Static per-thread hash code key. Shared across all instances to + # reduce Thread locals pollution and because adjustments due to + # collisions in one table are likely to be appropriate for + # others. + THREAD_LOCAL_KEY = "#{name}.hash_code".to_sym + + # A thread-local hash code accessor. The code is initially + # random, but may be set to a different value upon collisions. + def hash_code + Thread.current[THREAD_LOCAL_KEY] ||= XorShiftRandom.get + end + + def hash_code=(hash) + Thread.current[THREAD_LOCAL_KEY] = hash + end + + # Sets base and all +cells+ to the given value. + def internal_reset(initial_value) + current_cells = cells + self.base = initial_value + if current_cells + current_cells.each do |cell| + cell.value = initial_value if cell + end + end + end + + def cas_base_computed + cas_base(current_base = base, yield(current_base)) + end + + def free? + !busy? + end + + def try_initialize_cells(x, hash) + if free? && !cells + try_in_busy do + unless cells # Recheck under lock + new_cells = PowerOfTwoTuple.new(2) + new_cells.volatile_set_by_hash(hash, Cell.new(x)) + self.cells = new_cells + end + end + end + end + + def expand_table_unless_stale(current_cells) + try_in_busy do + if current_cells == cells # Recheck under lock + new_cells = current_cells.next_in_size_table + current_cells.each_with_index {|x, i| new_cells.volatile_set(i, x)} + self.cells = new_cells + end + end + end + + def try_to_install_new_cell(new_cell, hash) + try_in_busy do + # Recheck under lock + if (current_cells = cells) && !current_cells.volatile_get(i = current_cells.hash_to_index(hash)) + current_cells.volatile_set(i, new_cell) + end + end + end + + def try_in_busy + if cas_busy(false, true) + begin + yield + ensure + self.busy = false + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb new file mode 100644 index 0000000..cdac2a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb @@ -0,0 +1,75 @@ +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # @!visibility private + module Volatile + + # Provides +volatile+ (in the JVM's sense) attribute accessors implemented + # atop of +Concurrent::AtomicReference+. + # + # Usage: + # class Foo + # extend Concurrent::ThreadSafe::Util::Volatile + # attr_volatile :foo, :bar + # + # def initialize(bar) + # super() # must super() into parent initializers before using the volatile attribute accessors + # self.bar = bar + # end + # + # def hello + # my_foo = foo # volatile read + # self.foo = 1 # volatile write + # cas_foo(1, 2) # => true | a strong CAS + # end + # end + def attr_volatile(*attr_names) + return if attr_names.empty? + include(Module.new do + atomic_ref_setup = attr_names.map {|attr_name| "@__#{attr_name} = Concurrent::AtomicReference.new"} + initialize_copy_setup = attr_names.zip(atomic_ref_setup).map do |attr_name, ref_setup| + "#{ref_setup}(other.instance_variable_get(:@__#{attr_name}).get)" + end + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def initialize(*) + super + #{atomic_ref_setup.join('; ')} + end + + def initialize_copy(other) + super + #{initialize_copy_setup.join('; ')} + end + RUBY_EVAL + + attr_names.each do |attr_name| + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{attr_name} + @__#{attr_name}.get + end + + def #{attr_name}=(value) + @__#{attr_name}.set(value) + end + + def compare_and_set_#{attr_name}(old_value, new_value) + @__#{attr_name}.compare_and_set(old_value, new_value) + end + RUBY_EVAL + + alias_method :"cas_#{attr_name}", :"compare_and_set_#{attr_name}" + alias_method :"lazy_set_#{attr_name}", :"#{attr_name}=" + end + end) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb new file mode 100644 index 0000000..c231d18 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb @@ -0,0 +1,50 @@ +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # A xorshift random number (positive +Fixnum+s) generator, provides + # reasonably cheap way to generate thread local random numbers without + # contending for the global +Kernel.rand+. + # + # Usage: + # x = XorShiftRandom.get # uses Kernel.rand to generate an initial seed + # while true + # if (x = XorShiftRandom.xorshift).odd? # thread-locally generate a next random number + # do_something_at_random + # end + # end + module XorShiftRandom + extend self + MAX_XOR_SHIFTABLE_INT = MAX_INT - 1 + + # Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+. + def get + Kernel.rand(MAX_XOR_SHIFTABLE_INT) + 1 # 0 can't be xorshifted + end + + # xorshift based on: http://www.jstatsoft.org/v08/i14/paper + if 0.size == 4 + # using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (3,1,14) to minimise Bignum overflows + def xorshift(x) + x ^= x >> 3 + x ^= (x << 1) & MAX_INT # cut-off Bignum overflow + x ^= x >> 14 + end + else + # using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows + def xorshift(x) + x ^= x >> 1 + x ^= (x << 1) & MAX_INT # cut-off Bignum overflow + x ^= x >> 54 + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/timer_task.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/timer_task.rb new file mode 100644 index 0000000..d1eb556 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/timer_task.rb @@ -0,0 +1,366 @@ +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/concern/dereferenceable' +require 'concurrent/concern/observable' +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/ruby_executor_service' +require 'concurrent/executor/safe_task_executor' +require 'concurrent/scheduled_task' + +module Concurrent + + # A very common concurrency pattern is to run a thread that performs a task at + # regular intervals. The thread that performs the task sleeps for the given + # interval then wakes up and performs the task. Lather, rinse, repeat... This + # pattern causes two problems. First, it is difficult to test the business + # logic of the task because the task itself is tightly coupled with the + # concurrency logic. Second, an exception raised while performing the task can + # cause the entire thread to abend. In a long-running application where the + # task thread is intended to run for days/weeks/years a crashed task thread + # can pose a significant problem. `TimerTask` alleviates both problems. + # + # When a `TimerTask` is launched it starts a thread for monitoring the + # execution interval. The `TimerTask` thread does not perform the task, + # however. Instead, the TimerTask launches the task on a separate thread. + # Should the task experience an unrecoverable crash only the task thread will + # crash. This makes the `TimerTask` very fault tolerant. Additionally, the + # `TimerTask` thread can respond to the success or failure of the task, + # performing logging or ancillary operations. + # + # One other advantage of `TimerTask` is that it forces the business logic to + # be completely decoupled from the concurrency logic. The business logic can + # be tested separately then passed to the `TimerTask` for scheduling and + # running. + # + # A `TimerTask` supports two different types of interval calculations. + # A fixed delay will always wait the same amount of time between the + # completion of one task and the start of the next. A fixed rate will + # attempt to maintain a constant rate of execution regardless of the + # duration of the task. For example, if a fixed rate task is scheduled + # to run every 60 seconds but the task itself takes 10 seconds to + # complete, the next task will be scheduled to run 50 seconds after + # the start of the previous task. If the task takes 70 seconds to + # complete, the next task will be start immediately after the previous + # task completes. Tasks will not be executed concurrently. + # + # In some cases it may be necessary for a `TimerTask` to affect its own + # execution cycle. To facilitate this, a reference to the TimerTask instance + # is passed as an argument to the provided block every time the task is + # executed. + # + # The `TimerTask` class includes the `Dereferenceable` mixin module so the + # result of the last execution is always available via the `#value` method. + # Dereferencing options can be passed to the `TimerTask` during construction or + # at any later time using the `#set_deref_options` method. + # + # `TimerTask` supports notification through the Ruby standard library + # {http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html + # Observable} module. On execution the `TimerTask` will notify the observers + # with three arguments: time of execution, the result of the block (or nil on + # failure), and any raised exceptions (or nil on success). + # + # @!macro copy_options + # + # @example Basic usage + # task = Concurrent::TimerTask.new{ puts 'Boom!' } + # task.execute + # + # task.execution_interval #=> 60 (default) + # + # # wait 60 seconds... + # #=> 'Boom!' + # + # task.shutdown #=> true + # + # @example Configuring `:execution_interval` + # task = Concurrent::TimerTask.new(execution_interval: 5) do + # puts 'Boom!' + # end + # + # task.execution_interval #=> 5 + # + # @example Immediate execution with `:run_now` + # task = Concurrent::TimerTask.new(run_now: true){ puts 'Boom!' } + # task.execute + # + # #=> 'Boom!' + # + # @example Configuring `:interval_type` with either :fixed_delay or :fixed_rate, default is :fixed_delay + # task = Concurrent::TimerTask.new(execution_interval: 5, interval_type: :fixed_rate) do + # puts 'Boom!' + # end + # task.interval_type #=> :fixed_rate + # + # @example Last `#value` and `Dereferenceable` mixin + # task = Concurrent::TimerTask.new( + # dup_on_deref: true, + # execution_interval: 5 + # ){ Time.now } + # + # task.execute + # Time.now #=> 2013-11-07 18:06:50 -0500 + # sleep(10) + # task.value #=> 2013-11-07 18:06:55 -0500 + # + # @example Controlling execution from within the block + # timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task| + # task.execution_interval.to_i.times{ print 'Boom! ' } + # print "\n" + # task.execution_interval += 1 + # if task.execution_interval > 5 + # puts 'Stopping...' + # task.shutdown + # end + # end + # + # timer_task.execute + # #=> Boom! + # #=> Boom! Boom! + # #=> Boom! Boom! Boom! + # #=> Boom! Boom! Boom! Boom! + # #=> Boom! Boom! Boom! Boom! Boom! + # #=> Stopping... + # + # @example Observation + # class TaskObserver + # def update(time, result, ex) + # if result + # print "(#{time}) Execution successfully returned #{result}\n" + # else + # print "(#{time}) Execution failed with error #{ex}\n" + # end + # end + # end + # + # task = Concurrent::TimerTask.new(execution_interval: 1){ 42 } + # task.add_observer(TaskObserver.new) + # task.execute + # sleep 4 + # + # #=> (2013-10-13 19:08:58 -0400) Execution successfully returned 42 + # #=> (2013-10-13 19:08:59 -0400) Execution successfully returned 42 + # #=> (2013-10-13 19:09:00 -0400) Execution successfully returned 42 + # task.shutdown + # + # task = Concurrent::TimerTask.new(execution_interval: 1){ sleep } + # task.add_observer(TaskObserver.new) + # task.execute + # + # #=> (2013-10-13 19:07:25 -0400) Execution timed out + # #=> (2013-10-13 19:07:27 -0400) Execution timed out + # #=> (2013-10-13 19:07:29 -0400) Execution timed out + # task.shutdown + # + # task = Concurrent::TimerTask.new(execution_interval: 1){ raise StandardError } + # task.add_observer(TaskObserver.new) + # task.execute + # + # #=> (2013-10-13 19:09:37 -0400) Execution failed with error StandardError + # #=> (2013-10-13 19:09:38 -0400) Execution failed with error StandardError + # #=> (2013-10-13 19:09:39 -0400) Execution failed with error StandardError + # task.shutdown + # + # @see http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html + # @see http://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html + class TimerTask < RubyExecutorService + include Concern::Dereferenceable + include Concern::Observable + + # Default `:execution_interval` in seconds. + EXECUTION_INTERVAL = 60 + + # Maintain the interval between the end of one execution and the start of the next execution. + FIXED_DELAY = :fixed_delay + + # Maintain the interval between the start of one execution and the start of the next. + # If execution time exceeds the interval, the next execution will start immediately + # after the previous execution finishes. Executions will not run concurrently. + FIXED_RATE = :fixed_rate + + # Default `:interval_type` + DEFAULT_INTERVAL_TYPE = FIXED_DELAY + + # Create a new TimerTask with the given task and configuration. + # + # @!macro timer_task_initialize + # @param [Hash] opts the options defining task execution. + # @option opts [Float] :execution_interval number of seconds between + # task executions (default: EXECUTION_INTERVAL) + # @option opts [Boolean] :run_now Whether to run the task immediately + # upon instantiation or to wait until the first # execution_interval + # has passed (default: false) + # @options opts [Symbol] :interval_type method to calculate the interval + # between executions, can be either :fixed_rate or :fixed_delay. + # (default: :fixed_delay) + # @option opts [Executor] executor, default is `global_io_executor` + # + # @!macro deref_options + # + # @raise ArgumentError when no block is given. + # + # @yield to the block after :execution_interval seconds have passed since + # the last yield + # @yieldparam task a reference to the `TimerTask` instance so that the + # block can control its own lifecycle. Necessary since `self` will + # refer to the execution context of the block rather than the running + # `TimerTask`. + # + # @return [TimerTask] the new `TimerTask` + def initialize(opts = {}, &task) + raise ArgumentError.new('no block given') unless block_given? + super + set_deref_options opts + end + + # Is the executor running? + # + # @return [Boolean] `true` when running, `false` when shutting down or shutdown + def running? + @running.true? + end + + # Execute a previously created `TimerTask`. + # + # @return [TimerTask] a reference to `self` + # + # @example Instance and execute in separate steps + # task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" } + # task.running? #=> false + # task.execute + # task.running? #=> true + # + # @example Instance and execute in one line + # task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" }.execute + # task.running? #=> true + def execute + synchronize do + if @running.false? + @running.make_true + @age.increment + schedule_next_task(@run_now ? 0 : @execution_interval) + end + end + self + end + + # Create and execute a new `TimerTask`. + # + # @!macro timer_task_initialize + # + # @example + # task = Concurrent::TimerTask.execute(execution_interval: 10){ print "Hello World\n" } + # task.running? #=> true + def self.execute(opts = {}, &task) + TimerTask.new(opts, &task).execute + end + + # @!attribute [rw] execution_interval + # @return [Fixnum] Number of seconds after the task completes before the + # task is performed again. + def execution_interval + synchronize { @execution_interval } + end + + # @!attribute [rw] execution_interval + # @return [Fixnum] Number of seconds after the task completes before the + # task is performed again. + def execution_interval=(value) + if (value = value.to_f) <= 0.0 + raise ArgumentError.new('must be greater than zero') + else + synchronize { @execution_interval = value } + end + end + + # @!attribute [r] interval_type + # @return [Symbol] method to calculate the interval between executions + attr_reader :interval_type + + # @!attribute [rw] timeout_interval + # @return [Fixnum] Number of seconds the task can run before it is + # considered to have failed. + def timeout_interval + warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly' + end + + # @!attribute [rw] timeout_interval + # @return [Fixnum] Number of seconds the task can run before it is + # considered to have failed. + def timeout_interval=(value) + warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly' + end + + private :post, :<< + + private + + def ns_initialize(opts, &task) + set_deref_options(opts) + + self.execution_interval = opts[:execution] || opts[:execution_interval] || EXECUTION_INTERVAL + if opts[:interval_type] && ![FIXED_DELAY, FIXED_RATE].include?(opts[:interval_type]) + raise ArgumentError.new('interval_type must be either :fixed_delay or :fixed_rate') + end + if opts[:timeout] || opts[:timeout_interval] + warn 'TimeTask timeouts are now ignored as these were not able to be implemented correctly' + end + + @run_now = opts[:now] || opts[:run_now] + @interval_type = opts[:interval_type] || DEFAULT_INTERVAL_TYPE + @task = Concurrent::SafeTaskExecutor.new(task) + @executor = opts[:executor] || Concurrent.global_io_executor + @running = Concurrent::AtomicBoolean.new(false) + @age = Concurrent::AtomicFixnum.new(0) + @value = nil + + self.observers = Collection::CopyOnNotifyObserverSet.new + end + + # @!visibility private + def ns_shutdown_execution + @running.make_false + super + end + + # @!visibility private + def ns_kill_execution + @running.make_false + super + end + + # @!visibility private + def schedule_next_task(interval = execution_interval) + ScheduledTask.execute(interval, executor: @executor, args: [Concurrent::Event.new, @age.value], &method(:execute_task)) + nil + end + + # @!visibility private + def execute_task(completion, age_when_scheduled) + return nil unless @running.true? + return nil unless @age.value == age_when_scheduled + + start_time = Concurrent.monotonic_time + _success, value, reason = @task.execute(self) + if completion.try? + self.value = value + schedule_next_task(calculate_next_interval(start_time)) + time = Time.now + observers.notify_observers do + [time, self.value, reason] + end + end + nil + end + + # @!visibility private + def calculate_next_interval(start_time) + if @interval_type == FIXED_RATE + run_time = Concurrent.monotonic_time - start_time + [execution_interval - run_time, 0].max + else # FIXED_DELAY + execution_interval + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tuple.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tuple.rb new file mode 100644 index 0000000..56212cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tuple.rb @@ -0,0 +1,82 @@ +require 'concurrent/atomic/atomic_reference' + +module Concurrent + + # A fixed size array with volatile (synchronized, thread safe) getters/setters. + # Mixes in Ruby's `Enumerable` module for enhanced search, sort, and traversal. + # + # @example + # tuple = Concurrent::Tuple.new(16) + # + # tuple.set(0, :foo) #=> :foo | volatile write + # tuple.get(0) #=> :foo | volatile read + # tuple.compare_and_set(0, :foo, :bar) #=> true | strong CAS + # tuple.cas(0, :foo, :baz) #=> false | strong CAS + # tuple.get(0) #=> :bar | volatile read + # + # @see https://en.wikipedia.org/wiki/Tuple Tuple entry at Wikipedia + # @see http://www.erlang.org/doc/reference_manual/data_types.html#id70396 Erlang Tuple + # @see http://ruby-doc.org/core-2.2.2/Enumerable.html Enumerable + class Tuple + include Enumerable + + # The (fixed) size of the tuple. + attr_reader :size + + # Create a new tuple of the given size. + # + # @param [Integer] size the number of elements in the tuple + def initialize(size) + @size = size + @tuple = tuple = ::Array.new(size) + i = 0 + while i < size + tuple[i] = Concurrent::AtomicReference.new + i += 1 + end + end + + # Get the value of the element at the given index. + # + # @param [Integer] i the index from which to retrieve the value + # @return [Object] the value at the given index or nil if the index is out of bounds + def get(i) + return nil if i >= @size || i < 0 + @tuple[i].get + end + alias_method :volatile_get, :get + + # Set the element at the given index to the given value + # + # @param [Integer] i the index for the element to set + # @param [Object] value the value to set at the given index + # + # @return [Object] the new value of the element at the given index or nil if the index is out of bounds + def set(i, value) + return nil if i >= @size || i < 0 + @tuple[i].set(value) + end + alias_method :volatile_set, :set + + # Set the value at the given index to the new value if and only if the current + # value matches the given old value. + # + # @param [Integer] i the index for the element to set + # @param [Object] old_value the value to compare against the current value + # @param [Object] new_value the value to set at the given index + # + # @return [Boolean] true if the value at the given element was set else false + def compare_and_set(i, old_value, new_value) + return false if i >= @size || i < 0 + @tuple[i].compare_and_set(old_value, new_value) + end + alias_method :cas, :compare_and_set + + # Calls the given block once for each element in self, passing that element as a parameter. + # + # @yieldparam [Object] ref the `Concurrent::AtomicReference` object at the current index + def each + @tuple.each {|ref| yield ref.get} + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tvar.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tvar.rb new file mode 100644 index 0000000..5d02ef0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/tvar.rb @@ -0,0 +1,222 @@ +require 'set' +require 'concurrent/synchronization/object' + +module Concurrent + + # A `TVar` is a transactional variable - a single-element container that + # is used as part of a transaction - see `Concurrent::atomically`. + # + # @!macro thread_safe_variable_comparison + # + # {include:file:docs-source/tvar.md} + class TVar < Synchronization::Object + safe_initialization! + + # Create a new `TVar` with an initial value. + def initialize(value) + @value = value + @lock = Mutex.new + end + + # Get the value of a `TVar`. + def value + Concurrent::atomically do + Transaction::current.read(self) + end + end + + # Set the value of a `TVar`. + def value=(value) + Concurrent::atomically do + Transaction::current.write(self, value) + end + end + + # @!visibility private + def unsafe_value # :nodoc: + @value + end + + # @!visibility private + def unsafe_value=(value) # :nodoc: + @value = value + end + + # @!visibility private + def unsafe_lock # :nodoc: + @lock + end + + end + + # Run a block that reads and writes `TVar`s as a single atomic transaction. + # With respect to the value of `TVar` objects, the transaction is atomic, in + # that it either happens or it does not, consistent, in that the `TVar` + # objects involved will never enter an illegal state, and isolated, in that + # transactions never interfere with each other. You may recognise these + # properties from database transactions. + # + # There are some very important and unusual semantics that you must be aware of: + # + # * Most importantly, the block that you pass to atomically may be executed + # more than once. In most cases your code should be free of + # side-effects, except for via TVar. + # + # * If an exception escapes an atomically block it will abort the transaction. + # + # * It is undefined behaviour to use callcc or Fiber with atomically. + # + # * If you create a new thread within an atomically, it will not be part of + # the transaction. Creating a thread counts as a side-effect. + # + # Transactions within transactions are flattened to a single transaction. + # + # @example + # a = new TVar(100_000) + # b = new TVar(100) + # + # Concurrent::atomically do + # a.value -= 10 + # b.value += 10 + # end + def atomically + raise ArgumentError.new('no block given') unless block_given? + + # Get the current transaction + + transaction = Transaction::current + + # Are we not already in a transaction (not nested)? + + if transaction.nil? + # New transaction + + begin + # Retry loop + + loop do + + # Create a new transaction + + transaction = Transaction.new + Transaction::current = transaction + + # Run the block, aborting on exceptions + + begin + result = yield + rescue Transaction::AbortError => e + transaction.abort + result = Transaction::ABORTED + rescue Transaction::LeaveError => e + transaction.abort + break result + rescue => e + transaction.abort + raise e + end + # If we can commit, break out of the loop + + if result != Transaction::ABORTED + if transaction.commit + break result + end + end + end + ensure + # Clear the current transaction + + Transaction::current = nil + end + else + # Nested transaction - flatten it and just run the block + + yield + end + end + + # Abort a currently running transaction - see `Concurrent::atomically`. + def abort_transaction + raise Transaction::AbortError.new + end + + # Leave a transaction without committing or aborting - see `Concurrent::atomically`. + def leave_transaction + raise Transaction::LeaveError.new + end + + module_function :atomically, :abort_transaction, :leave_transaction + + private + + # @!visibility private + class Transaction + + ABORTED = ::Object.new + + OpenEntry = Struct.new(:value, :modified) + + AbortError = Class.new(StandardError) + LeaveError = Class.new(StandardError) + + def initialize + @open_tvars = {} + end + + def read(tvar) + entry = open(tvar) + entry.value + end + + def write(tvar, value) + entry = open(tvar) + entry.modified = true + entry.value = value + end + + def open(tvar) + entry = @open_tvars[tvar] + + unless entry + unless tvar.unsafe_lock.try_lock + Concurrent::abort_transaction + end + + entry = OpenEntry.new(tvar.unsafe_value, false) + @open_tvars[tvar] = entry + end + + entry + end + + def abort + unlock + end + + def commit + @open_tvars.each do |tvar, entry| + if entry.modified + tvar.unsafe_value = entry.value + end + end + + unlock + end + + def unlock + @open_tvars.each_key do |tvar| + tvar.unsafe_lock.unlock + end + end + + def self.current + Thread.current[:current_tvar_transaction] + end + + def self.current=(transaction) + Thread.current[:current_tvar_transaction] = transaction + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/engine.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/engine.rb new file mode 100644 index 0000000..0c574b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/engine.rb @@ -0,0 +1,45 @@ +module Concurrent + # @!visibility private + module Utility + + # @!visibility private + module EngineDetector + def on_cruby? + RUBY_ENGINE == 'ruby' + end + + def on_jruby? + RUBY_ENGINE == 'jruby' + end + + def on_truffleruby? + RUBY_ENGINE == 'truffleruby' + end + + def on_windows? + !(RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/).nil? + end + + def on_osx? + !(RbConfig::CONFIG['host_os'] =~ /darwin|mac os/).nil? + end + + def on_linux? + !(RbConfig::CONFIG['host_os'] =~ /linux/).nil? + end + + def ruby_version(version = RUBY_VERSION, comparison, major, minor, patch) + result = (version.split('.').map(&:to_i) <=> [major, minor, patch]) + comparisons = { :== => [0], + :>= => [1, 0], + :<= => [-1, 0], + :> => [1], + :< => [-1] } + comparisons.fetch(comparison).include? result + end + end + end + + # @!visibility private + extend Utility::EngineDetector +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb new file mode 100644 index 0000000..1c987d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb @@ -0,0 +1,19 @@ +module Concurrent + + # @!macro monotonic_get_time + # + # Returns the current time as tracked by the application monotonic clock. + # + # @param [Symbol] unit the time unit to be returned, can be either + # :float_second, :float_millisecond, :float_microsecond, :second, + # :millisecond, :microsecond, or :nanosecond default to :float_second. + # + # @return [Float] The current monotonic time since some unspecified + # starting point + # + # @!macro monotonic_clock_warning + def monotonic_time(unit = :float_second) + Process.clock_gettime(Process::CLOCK_MONOTONIC, unit) + end + module_function :monotonic_time +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb new file mode 100644 index 0000000..bf7bab3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb @@ -0,0 +1,77 @@ +require 'concurrent/utility/engine' +# Synchronization::AbstractObject must be defined before loading the extension +require 'concurrent/synchronization/abstract_object' + +module Concurrent + # @!visibility private + module Utility + # @!visibility private + module NativeExtensionLoader + + def allow_c_extensions? + Concurrent.on_cruby? + end + + def c_extensions_loaded? + defined?(@c_extensions_loaded) && @c_extensions_loaded + end + + def load_native_extensions + if Concurrent.on_cruby? && !c_extensions_loaded? + ['concurrent/concurrent_ruby_ext', + "concurrent/#{RUBY_VERSION[0..2]}/concurrent_ruby_ext" + ].each { |p| try_load_c_extension p } + end + + if Concurrent.on_jruby? && !java_extensions_loaded? + begin + require 'concurrent/concurrent_ruby.jar' + set_java_extensions_loaded + rescue LoadError => e + raise e, "Java extensions are required for JRuby.\n" + e.message, e.backtrace + end + end + end + + private + + def load_error_path(error) + if error.respond_to? :path + error.path + else + error.message.split(' -- ').last + end + end + + def set_c_extensions_loaded + @c_extensions_loaded = true + end + + def java_extensions_loaded? + defined?(@java_extensions_loaded) && @java_extensions_loaded + end + + def set_java_extensions_loaded + @java_extensions_loaded = true + end + + def try_load_c_extension(path) + require path + set_c_extensions_loaded + rescue LoadError => e + if load_error_path(e) == path + # move on with pure-Ruby implementations + # TODO (pitr-ch 12-Jul-2018): warning on verbose? + else + raise e + end + end + + end + end + + # @!visibility private + extend Utility::NativeExtensionLoader +end + +Concurrent.load_native_extensions diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_integer.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_integer.rb new file mode 100644 index 0000000..de1cdc3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/native_integer.rb @@ -0,0 +1,54 @@ +module Concurrent + # @!visibility private + module Utility + # @private + module NativeInteger + # http://stackoverflow.com/questions/535721/ruby-max-integer + MIN_VALUE = -(2**(0.size * 8 - 2)) + MAX_VALUE = (2**(0.size * 8 - 2) - 1) + + def ensure_upper_bound(value) + if value > MAX_VALUE + raise RangeError.new("#{value} is greater than the maximum value of #{MAX_VALUE}") + end + value + end + + def ensure_lower_bound(value) + if value < MIN_VALUE + raise RangeError.new("#{value} is less than the maximum value of #{MIN_VALUE}") + end + value + end + + def ensure_integer(value) + unless value.is_a?(Integer) + raise ArgumentError.new("#{value} is not an Integer") + end + value + end + + def ensure_integer_and_bounds(value) + ensure_integer value + ensure_upper_bound value + ensure_lower_bound value + end + + def ensure_positive(value) + if value < 0 + raise ArgumentError.new("#{value} cannot be negative") + end + value + end + + def ensure_positive_and_no_zero(value) + if value < 1 + raise ArgumentError.new("#{value} cannot be negative or zero") + end + value + end + + extend self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/processor_counter.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/processor_counter.rb new file mode 100644 index 0000000..2489cbd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/utility/processor_counter.rb @@ -0,0 +1,220 @@ +require 'etc' +require 'rbconfig' +require 'concurrent/delay' + +module Concurrent + # @!visibility private + module Utility + + # @!visibility private + class ProcessorCounter + def initialize + @processor_count = Delay.new { compute_processor_count } + @physical_processor_count = Delay.new { compute_physical_processor_count } + @cpu_quota = Delay.new { compute_cpu_quota } + @cpu_shares = Delay.new { compute_cpu_shares } + end + + def processor_count + @processor_count.value + end + + def physical_processor_count + @physical_processor_count.value + end + + def available_processor_count + cpu_count = processor_count.to_f + quota = cpu_quota + + return cpu_count if quota.nil? + + # cgroup cpus quotas have no limits, so they can be set to higher than the + # real count of cores. + if quota > cpu_count + cpu_count + else + quota + end + end + + def cpu_quota + @cpu_quota.value + end + + def cpu_shares + @cpu_shares.value + end + + private + + def compute_processor_count + if Concurrent.on_jruby? + java.lang.Runtime.getRuntime.availableProcessors + else + Etc.nprocessors + end + end + + def compute_physical_processor_count + ppc = case RbConfig::CONFIG["target_os"] + when /darwin\d\d/ + IO.popen("/usr/sbin/sysctl -n hw.physicalcpu", &:read).to_i + when /linux/ + cores = {} # unique physical ID / core ID combinations + phy = 0 + IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln| + if ln.start_with?("physical") + phy = ln[/\d+/] + elsif ln.start_with?("core") + cid = phy + ":" + ln[/\d+/] + cores[cid] = true if not cores[cid] + end + end + cores.count + when /mswin|mingw/ + # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0 + result = run('powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores | Select-Object -Property NumberOfCores"') + if !result || $?.exitstatus != 0 + # fallback to deprecated wmic for older systems + result = run("wmic cpu get NumberOfCores") + end + if !result || $?.exitstatus != 0 + # Bail out if both commands returned something unexpected + processor_count + else + # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n" + # wmic: "NumberOfCores \n\n4 \n\n\n\n" + result.scan(/\d+/).map(&:to_i).reduce(:+) + end + else + processor_count + end + # fall back to logical count if physical info is invalid + ppc > 0 ? ppc : processor_count + rescue + return 1 + end + + def run(command) + IO.popen(command, &:read) + rescue Errno::ENOENT + end + + def compute_cpu_quota + if RbConfig::CONFIG["target_os"].include?("linux") + if File.exist?("/sys/fs/cgroup/cpu.max") + # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files + cpu_max = File.read("/sys/fs/cgroup/cpu.max") + return nil if cpu_max.start_with?("max ") # no limit + max, period = cpu_max.split.map(&:to_f) + max / period + elsif File.exist?("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us") + # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt + max = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us").to_i + # If the cpu.cfs_quota_us is -1, cgroup does not adhere to any CPU time restrictions + # https://docs.kernel.org/scheduler/sched-bwc.html#management + return nil if max <= 0 + period = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us").to_f + max / period + end + end + end + + def compute_cpu_shares + if RbConfig::CONFIG["target_os"].include?("linux") + if File.exist?("/sys/fs/cgroup/cpu.weight") + # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files + # Ref: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2254-cgroup-v2#phase-1-convert-from-cgroups-v1-settings-to-v2 + weight = File.read("/sys/fs/cgroup/cpu.weight").to_f + ((((weight - 1) * 262142) / 9999) + 2) / 1024 + elsif File.exist?("/sys/fs/cgroup/cpu/cpu.shares") + # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt + File.read("/sys/fs/cgroup/cpu/cpu.shares").to_f / 1024 + end + end + end + end + end + + # create the default ProcessorCounter on load + @processor_counter = Utility::ProcessorCounter.new + singleton_class.send :attr_reader, :processor_counter + + # Number of processors seen by the OS and used for process scheduling. For + # performance reasons the calculated value will be memoized on the first + # call. + # + # When running under JRuby the Java runtime call + # `java.lang.Runtime.getRuntime.availableProcessors` will be used. According + # to the Java documentation this "value may change during a particular + # invocation of the virtual machine... [applications] should therefore + # occasionally poll this property." We still memoize this value once under + # JRuby. + # + # Otherwise Ruby's Etc.nprocessors will be used. + # + # @return [Integer] number of processors seen by the OS or Java runtime + # + # @see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors() + def self.processor_count + processor_counter.processor_count + end + + # Number of physical processor cores on the current system. For performance + # reasons the calculated value will be memoized on the first call. + # + # On Windows the Win32 API will be queried for the `NumberOfCores from + # Win32_Processor`. This will return the total number "of cores for the + # current instance of the processor." On Unix-like operating systems either + # the `hwprefs` or `sysctl` utility will be called in a subshell and the + # returned value will be used. In the rare case where none of these methods + # work or an exception is raised the function will simply return 1. + # + # @return [Integer] number physical processor cores on the current system + # + # @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb + # + # @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx + # @see http://www.unix.com/man-page/osx/1/HWPREFS/ + # @see http://linux.die.net/man/8/sysctl + def self.physical_processor_count + processor_counter.physical_processor_count + end + + # Number of processors cores available for process scheduling. + # This method takes in account the CPU quota if the process is inside a cgroup with a + # dedicated CPU quota (typically Docker). + # Otherwise it returns the same value as #processor_count but as a Float. + # + # For performance reasons the calculated value will be memoized on the first + # call. + # + # @return [Float] number of available processors + def self.available_processor_count + processor_counter.available_processor_count + end + + # The maximum number of processors cores available for process scheduling. + # Returns `nil` if there is no enforced limit, or a `Float` if the + # process is inside a cgroup with a dedicated CPU quota (typically Docker). + # + # Note that nothing prevents setting a CPU quota higher than the actual number of + # cores on the system. + # + # For performance reasons the calculated value will be memoized on the first + # call. + # + # @return [nil, Float] Maximum number of available processors as set by a cgroup CPU quota, or nil if none set + def self.cpu_quota + processor_counter.cpu_quota + end + + # The CPU shares requested by the process. For performance reasons the calculated + # value will be memoized on the first call. + # + # @return [Float, nil] CPU shares requested by the process, or nil if not set + def self.cpu_shares + processor_counter.cpu_shares + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/version.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/version.rb new file mode 100644 index 0000000..a4cd88a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.8/lib/concurrent-ruby/concurrent/version.rb @@ -0,0 +1,3 @@ +module Concurrent + VERSION = '1.3.8' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/CHANGELOG.md new file mode 100644 index 0000000..95e32c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/CHANGELOG.md @@ -0,0 +1,507 @@ +1.17.4 / 2026-03-26 +------------------- + +Fixed: +* Fix union by-value ABI mismatch with float and double types on ARM64 and X86_64. + See #1177 and #1178 for details. +* Exclude libffi files, which are unnecessary. #1176 + + +1.17.3 / 2025-12-29 +------------------- + +Fixed: +* Opt-in for MFA requirement explicitly. #1159 +* Fix type signature for FFI::AutoPointer#initialize, FFI::StructByReference#native_type and FFI::Struct#auto_ptr . #1158 +* Fix function signature of function_call in FFI trampoline. #1154 + It failed on `aarch64-mingw-ucrt`. +* Add workaround for segmentation faults on `aarch64-mingw-ucrt`. #1154 +* Call super in `Library#freeze` . #1154 +* Deny duplication of AutoPointer per #dup and #clone . #1173 + They led to double free before. + +Added: +* Add binary gems for Ruby-4.0, now providing binary gems for Ruby-3.0 to 4.0. +* Add msys2_mingw_dependencies for Windows Mingw for automatic installation of libffi. #1143 +* Mark callback dispatcher thread as fork safe for Puma. #1156 +* Add missing FFI::Platform module and LastError signatures. #1169 + +Removed: +* Drop fat binary gems for Ruby < 3.0 +* Remove `FFI::TypesGenerator` from distributed gems. #1164 +* Remove libffi build dir after install, safing some install space. #1157 + + +1.17.2 / 2025-04-15 +------------------- + +Fixed: +* #1144, #1145 Update libffi to 3.4.8 to fix installation issues on latest Macos on ARM64 +* Various adjustments to run the specs cleanly on Ruby-3.5 master branch. + + +1.17.1 / 2024-12-30 +------------------- + +Fixed: +* #1117 Restart async callback dispatcher thread after fork. +* #1133 Add ruby-3.4 native gem. +* #1134 Fix FFI::DataConverter non-generic usage in RBS files. + + +1.17.0 / 2024-06-02 +------------------- + +Fixed: +* Add FFI::AbstractMemory#read_array_of_string . It was defined but not exposed to Ruby nor tested. #1070 + + +1.17.0.rc2 / 2024-04-22 +------------------- + +Fixed: +* Add missing write barriers to StructLayout#initialize causing a segfault with GC.stress. #1079 + + +1.17.0.rc1 / 2024-04-08 +------------------- + +Fixed: +* Fix type definitions on `aarch64-linux`. #1067, #1066 +* Use RB_TEST for `Pointer.autorelease=` . #1065 + So that `false` and `nil` are treated as falsey and anything else as truthy. +* Replace Fixnum by Integer. #1064 + Fixnum is no longer present in the ruby language. +* Update `FFI::NativeType` doc. #1061 +* Store FFI::Type::Mapped of FFI::StrPtrConverter in global instead of custom type map +* Various documentation fixes. #1042 +* Update `FFI::Pointer#==` to return `false` if a pointer is compared to a non-pointer object, which is the expected behavior. #1083 +* Avoid warning about undefined wariable `@ffi_functions` #1085 +* Fix a very unlikely GC bug when using a callback block. # 1089 + +Added: +* Provide binary gems for many platforms. #990 +* Add Windows fat binary gem for Ruby-3.3 +* Add RBS type definitions for many user facing parts of the FFI API. #1042 +* Improve fallback search path logic. #1088 + Respect LD_LIBRARY_PATH and DYLD_LIBRARY_PATH on Macos. +* Update libffi to current git master branch. + +Removed: +* Remove `enum CHAR_ARRAY` which is no longer used. #1063 + + +1.16.3 / 2023-10-04 +------------------- + +Fixed: +* Fix gcc error when building on CentOS 7. #1052 +* Avoid trying to store new DataConverter type in frozen TypeDefs hash. #1057 + + +1.16.2 / 2023-09-25 +------------------- + +Fixed: +* Handle null pointer crash after fork. #1051 + + +1.16.1 / 2023-09-24 +------------------- + +Fixed: +* Fix compiling the builtin libffi. #1049 + + +1.16.0 / 2023-09-23 +------------------- + +Fixed: +* Fix an issue with signed bitmasks when using flags on the most significant bit. #949 +* Fix FFI::Pointer#initialize using NUM2LL instead of NUM2ULL. +* Fix FFI::Type#inspect to properly display the constant name. #1002 +* Use libffi closure allocations on hppa-Linux. #1017 + Previously they would segfault. +* Fix class name of Symbol#inspect. +* Fix MSVC support of libtest. #1028 +* Fix attach_function of functions ending in ? or ! #971 + +Added: +* Convert all C-based classes to TypedData and use write barriers. #994, #995, #996, #997, #998, #999, #1000, #1001, #1003, #1004, #1005, #1006, #1007, #1008, #1009, #1010, #1011, #1012 + This results in less pressure on the garbage collector, since the objects can be promoted to the old generation, which means they only get marked on major GC. +* Implement `ObjectSpace.memsize_of()` of all C-based classes. +* Make FFI Ractor compatible. #1023 + Modules extended per `extend FFI::Library` need to be frozen in order to be used by non-main Ractors. + This can be done by calling `freeze` below of all C interface definitions. + * In a Ractor it's possible to: + * load DLLs and call its functions, access its global variables + * use builtin typedefs + * use and modify ractor local typedefs + * define callbacks + * receive async callbacks from non-ruby threads + * use frozen FFI::Library based modules with all attributes (enums, structs, typedefs, functions, callbacks) + * invoke frozen functions and callbacks defined in the main Ractor + * use FFI::Struct definitions from the main Ractor + * In a Ractor it's impossible to: + * create new FFI::Library based modules + * create new FFI::Struct definitions + * use custom global typedefs + * use non-frozen FFI::Library based modules +* Allow type retrieval of attached functions+variables. #1023 +* Make FFI classes `GC.compact` friendly. #1021 +* Update libffi and disable custom trampoline when using libffi closure allocation. #1020 + This is because libffi changed the way how closures are allocated to static trampolines. +* Add types.conf for loongarch64-linux. #943 +* Add types.conf for sw_64-linux (Shen Wei 64-bit, based on Alpha). #1018 +* Add support for aarch64-windows. #1035 +* Windows: Update LoadLibrary error message to include error code. #1026 +* Allow private release method for FFI::ManagedStruct and FFI::AutoPointer. #1029 +* Add support for passing ABI version to FFI.map_library_name. #963 + This adds the new class FFI::LibraryPath . +* Add support for ruby-3.2 to windows binary gem. #1047 +* Enable debug symbols for `rake compile` builds to ease debugging. #1048 + +Removed: +* Remove allocator of AbstractMemory. #1013 + This disables AbstractMemory.new, which has no practical use. +* Remove unused FFI::SizeTypes. #1022 + + +1.15.5 / 2022-01-10 +------------------- + +Fixed: +* Fix long double argument or return values on 32bit i686. #849 +* FFI::ConstGenerator: avoid usage of the same binary file simultaneously. #929 + +Added: +* Add Windows fat binary gem for Ruby-3.1 + +Removed: +* Remove Windows fat binary gem for Ruby < 2.4 + + +1.15.4 / 2021-09-01 +------------------- + +Fixed: +* Fix build for uClibc. #913 +* Correct module lookup when including `ffi-module` gem. #912 + +Changed: +* Use ruby code of the ffi gem in JRuby-9.2.20+. #915 + + +1.15.3 / 2021-06-16 +------------------- + +Fixed: +* Fix temporary packaging issue with libffi. #904 + + +1.15.2 / 2021-06-16 +------------------- + +Added: +* Add support for Windows MINGW-UCRT build. #903 +* Add `/opt/homebrew/lib/` to fallback search paths to improve homebrew support. #880 #882 + +Changed: +* Regenerate `types.conf` for FreeBSD12 aarch64. #902 + + +1.15.1 / 2021-05-22 +------------------- + +Fixed: +* Append -pthread to linker options. #893 +* Use arm or aarch64 to identify Apple ARM CPU arch. #899 +* Allow overriding `gcc` with the `CC` env var in `const_generator.rb` and `struct_generator.rb`. #897 + + +1.15.0 / 2021-03-05 +------------------- + +Fixed: +* Fix MSVC build +* Fix async callbacks in conjunction with fork(). #884 + +Added: +* Allow to pass callbacks in varargs. #885 +* Name the threads for FFI callback dispatcher and async thread calls for easier debugging. #883 + The name can be retrieved by Thread.name and is shown by Thread.list.inspect etc. + Even gdb shows the thread name on supported operating systems. +* Add types.conf for powerpc64le-linux +* Add types.conf for riscv64-linux +* More release automation of ffi gems + +Changed: +* Switch from rubygems-tasks to bundler/gem_helper + +Removed: +* Remove unused VariadicInvoker#init + + +1.14.2 / 2020-12-21 +------------------- + +Fixed: +* Fix builtin libffi on newer Ubuntu caused by an outdated Makefile.in . #863 + + +1.14.1 / 2020-12-19 +------------------- + +Changed: +* Revert changes to FFI::Pointer#write_string made in ffi-1.14.0. + It breaks compatibilty in a way that can cause hard to find errors. #857 + + +1.14.0 / 2020-12-18 +------------------- + +Added: +* Add types.conf for x86_64-msys, x86_64-haiku, aarch64-openbsd and aarch64-darwin (alias arm64-darwin) +* Add method AbstractMemory#size_limit? . #829 +* Add new extconf option --enable-libffi-alloc which is enabled per default on Apple M1 (arm64-darwin). + +Changed: +* Do NULL pointer check only when array length > 0 . #305 +* Raise an error on an unknown order argument. #830 +* Change FFI::Pointer#write_string to terminate with a NUL byte like other string methods. #805 +* Update bundled libffi to latest master. + +Removed: +* Remove win32/stdint.h and stdbool.h because of copyright issue. #693 + +Fixed: +* Fix possible UTF-8 load error in loader script interpretation. #792 +* Fix segfault on non-array argument to #write_array_of_* +* Fix memory leak in MethodHandle . #815 +* Fix possible segfault in combination with fiddle or other libffi using gems . #835 +* Fix possibility to use ffi ruby gem with JRuby-9.3 . #763 +* Fix a GC issue, when a callback Proc is used on more than 2 callback signatures. #820 + + +1.13.1 / 2020-06-09 +------------------- + +Changed: +* Revert use of `ucrtbase.dll` as default C library on Windows-MINGW. + `ucrtbase.dll` is still used on MSWIN target. #790 +* Test for `ffi_prep_closure_loc()` to make sure we can use this function. + This fixes incorrect use of system libffi on MacOS Mojave (10.14). #787 +* Update types.conf on x86_64-dragonflybsd + + +1.13.0 / 2020-06-01 +------------------- + +Added: +* Add TruffleRuby support. Almost all specs are running on TruffleRuby and succeed. #768 +* Add ruby source files to the java gem. This allows to ship the Ruby library code per platform java gem and add it as a default gem to JRuby. #763 +* Add FFI::Platform::LONG_DOUBLE_SIZE +* Add bounds checks for writing to an inline char[] . #756 +* Add long double as callback return value. #771 +* Update type definitions and add types from stdint.h and stddef.h on i386-windows, x86_64-windows, x86_64-darwin, x86_64-linux, arm-linux, powerpc-linux. #749 +* Add new type definitions for powerpc-openbsd and sparcv9-openbsd. #775, #778 + +Changed: +* Raise required ruby version to >= 2.3. +* Lots of cleanups and improvements in library, specs and benchmarks. +* Fix a lot of compiler warnings at the C-extension +* Fix several install issues on MacOS: + * Look for libffi in SDK paths, since recent versions of macOS removed it from `/usr/include` . #757 + * Fix error `ld: library not found for -lgcc_s.10.4` + * Don't built for i386 architecture as it is deprecated +* Several fixes for MSVC build on Windows. #779 +* Use `ucrtbase.dll` as default C library on Windows instead of old `msvcrt.dll`. #779 +* Update builtin libffi to fix a Powerpc issue with parameters of type long +* Allow unmodified sourcing of (the ruby code of) this gem in JRuby and TruffleRuby as a default gem. #747 +* Improve check to detect if a module has a #find_type method suitable for FFI. This fixes compatibility with stdlib `mkmf` . #776 + +Removed: +* Reject callback with `:string` return type at definition, because it didn't work so far and is not save to use. #751, #782 + + +1.12.2 / 2020-02-01 +------------------- + +* Fix possible segfault at FFI::Struct#[] and []= after GC.compact . #742 + + +1.12.1 / 2020-01-14 +------------------- + +Added: +* Add binary gem support for ruby-2.7 on Windows + + +1.12.0 / 2020-01-14 +------------------- + +Added: +* FFI::VERSION is defined as part of `require 'ffi'` now. + It is no longer necessary to `require 'ffi/version'` . + +Changed: +* Update libffi to latest master. + +Deprecated: +* Overwriting struct layouts is now warned and will be disallowed in ffi-2.0. #734, #735 + + +1.11.3 / 2019-11-25 +------------------- + +Removed: +* Remove support for tainted objects which cause deprecation warnings in ruby-2.7. #730 + + +1.11.2 / 2019-11-11 +------------------- + +Added: +* Add DragonFlyBSD as a platform. #724 + +Changed: +* Sort all types.conf files, so that files and changes are easier to compare. +* Regenerated type conf for freebsd12 and x86_64-linux targets. #722 +* Remove MACOSX_DEPLOYMENT_TARGET that was targeting very old version 10.4. #647 +* Fix library name mangling for non glibc Linux/UNIX. #727 +* Fix compiler warnings raised by ruby-2.7 +* Update libffi to latest master. + + +1.11.1 / 2019-05-20 +------------------- + +Changed: +* Raise required ruby version to >=2.0. #699, #700 +* Fix a possible linker error on ruby < 2.3 on Linux. + + +1.11.0 / 2019-05-17 +------------------- +This version was yanked on 2019-05-20 to fix an install issue on ruby-1.9.3. #700 + +Added: +* Add ability to disable or force use of system libffi. #669 + Use like `gem inst ffi -- --enable-system-libffi` . +* Add ability to call FFI callbacks from outside of FFI call frame. #584 +* Add proper documentation to FFI::Generator and ::Task +* Add gemspec metadata. #696, #698 + +Changed: +* Fix stdcall on Win32. #649, #669 +* Fix load paths for FFI::Generator::Task +* Fix FFI::Pointer#read_string(0) to return a binary String. #692 +* Fix benchmark suite so that it runs on ruby-2.x +* Move FFI::Platform::CPU from C to Ruby. #663 +* Move FFI::StructByReference to Ruby. #681 +* Move FFI::DataConverter to Ruby (#661) +* Various cleanups and improvements of specs and benchmarks + +Removed: +* Remove ruby-1.8 and 1.9 compatibility code. #683 +* Remove unused spec files. #684 + + +1.10.0 / 2019-01-06 +------------------- + +Added: +* Add /opt/local/lib/ to ffi's fallback library search path. #638 +* Add binary gem support for ruby-2.6 on Windows +* Add FreeBSD on AArch64 and ARM support. #644 +* Add FFI::LastError.winapi_error on Windows native or Cygwin. #633 + +Changed: +* Update to rake-compiler-dock-0.7.0 +* Use 64-bit inodes on FreeBSD >= 12. #644 +* Switch time_t and suseconds_t types to long on FreeBSD. #627 +* Make register_t long_long on 64-bit FreeBSD. #644 +* Fix Pointer#write_array_of_type #637 + +Removed: +* Drop binary gem support for ruby-2.0 and 2.1 on Windows + + +1.9.25 / 2018-06-03 +------------------- + +Changed: +* Revert closures via libffi. + This re-adds ClosurePool and fixes compat with SELinux enabled systems. #621 + + +1.9.24 / 2018-06-02 +------------------- + +Security Note: + +This update addresses vulnerability CVE-2018-1000201: DLL loading issue which can be hijacked on Windows OS, when a Symbol is used as DLL name instead of a String. Found by Matthew Bush. + +Added: +* Added a CHANGELOG file +* Add mips64(eb) support, and mips r6 support. (#601) + +Changed: +* Update libffi to latest changes on master. +* Don't search in hardcoded /usr paths on Windows. +* Don't treat Symbol args different to Strings in ffi_lib. +* Make sure size_t is defined in Thread.c. Fixes #609 + + +1.9.23 / 2018-02-25 +------------------- + +Changed: +* Fix unnecessary rebuild of configure in darwin multi arch. Fixes #605 + + +1.9.22 / 2018-02-22 +------------------- + +Changed: +* Update libffi to latest changes on master. +* Update detection of system libffi to match new requirements. Fixes #617 +* Prefer bundled libffi over system libffi on Mac OS. +* Do closures via libffi. This removes ClosurePool and fixes compat with PaX. #540 +* Use a more deterministic gem packaging. +* Fix unnecessary update of autoconf files at gem install. + + +1.9.21 / 2018-02-06 +------------------- + +Added: +* Ruby-2.5 support by Windows binary gems. Fixes #598 +* Add missing win64 types. +* Added support for Bitmask. (#573) +* Add support for MSYS2 (#572) and Sparc64 Linux. (#574) + +Changed: +* Fix read_string to not throw an error on length 0. +* Don't use absolute paths for sh and env. Fixes usage on Adroid #528 +* Use Ruby implementation for `which` for better compat with Windows. Fixes #315 +* Fix compatibility with PPC64LE platform. (#577) +* Normalize sparc64 to sparcv9. (#575) + +Removed: +* Drop Ruby 1.8.7 support (#480) + + +1.9.18 / 2017-03-03 +------------------- + +Added: +* Add compatibility with Ruby-2.4. + +Changed: +* Add missing shlwapi.h include to fix Windows build. +* Avoid undefined behaviour of LoadLibrary() on Windows. #553 + + +1.9.17 / 2017-01-13 +------------------- diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/COPYING b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/COPYING new file mode 100644 index 0000000..7622318 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/COPYING @@ -0,0 +1,49 @@ +Copyright (c) 2008-2013, Ruby FFI project contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Ruby FFI project nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +libffi, used by this project, is licensed under the MIT license: + +libffi - Copyright (c) 1996-2011 Anthony Green, Red Hat, Inc and others. +See source files for details. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +``Software''), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Gemfile b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Gemfile new file mode 100644 index 0000000..637f1a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Gemfile @@ -0,0 +1,26 @@ +source 'https://rubygems.org' + +gemspec + +group :development do + gem 'benchmark' # necessary on ruby-3.5+ + gem 'bigdecimal' # necessary on ruby-3.3+ + gem 'bundler', '>= 1.16', '< 5.dev' + gem 'fiddle' # necessary on ruby-4.0+ + gem 'rake', '~> 13.0' + gem 'rake-compiler', '~> 1.1' + gem 'rake-compiler-dock', '~> 1.11.0' + gem 'rspec', '~> 3.0' +end + +group :doc do + gem 'kramdown' + gem 'yard', '~> 0.9' +end + +group :type_check do + if RUBY_VERSION >= "3.0" && %w[ ruby truffleruby ].include?(RUBY_ENGINE) + gem 'rbs', '~> 3.0' + gem 'steep', '~> 1.6' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE new file mode 100644 index 0000000..20185fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2008-2016, Ruby FFI project contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Ruby FFI project nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE.SPECS b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE.SPECS new file mode 100644 index 0000000..5c9ffce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/LICENSE.SPECS @@ -0,0 +1,22 @@ +Copyright (c) 2008-2012 Ruby-FFI contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/README.md b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/README.md new file mode 100644 index 0000000..7f7304b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/README.md @@ -0,0 +1,138 @@ +# Ruby-FFI https://github.com/ffi/ffi/wiki + +## Description + +Ruby-FFI is a gem for programmatically loading dynamically-linked native +libraries, binding functions within them, and calling those functions +from Ruby code. Moreover, a Ruby-FFI extension works without changes +on CRuby (MRI), JRuby, Rubinius and TruffleRuby. [Discover why you should write your next extension +using Ruby-FFI](https://github.com/ffi/ffi/wiki/why-use-ffi). + +## Features + +* Intuitive DSL +* Supports all C native types +* C structs (also nested), enums and global variables +* Callbacks from C to Ruby +* Automatic garbage collection of native memory +* Usable in Ractor: [How-to-use-FFI-in-Ruby-Ractors](https://github.com/ffi/ffi/wiki/Ractors) + +## Synopsis + +```ruby +require 'ffi' + +module MyLib + extend FFI::Library + ffi_lib 'c' + attach_function :puts, [ :string ], :int +end + +MyLib.puts 'Hello, World using libc!' +``` + +For less minimalistic and more examples you may look at: + +* The [documentation](https://www.rubydoc.info/gems/ffi) +* the `samples/` folder +* the examples on the [wiki](https://github.com/ffi/ffi/wiki) +* the projects using FFI listed on the wiki: https://github.com/ffi/ffi/wiki/projects-using-ffi + +## Requirements + +When installing the gem on CRuby (MRI), you will need: +* A C compiler (e.g., Xcode on macOS, `gcc` or `clang` on everything else) +Optionally (speeds up installation): +* The `libffi` library and development headers - this is commonly in the `libffi-dev` or `libffi-devel` packages + +The ffi gem comes with a builtin libffi version, which is used, when the system libffi library is not available or too old. +Use of the system libffi can be enforced by: +``` +gem install ffi -- --enable-system-libffi # to install the gem manually +bundle config build.ffi --enable-system-libffi # for bundle install +``` +or prevented by `--disable-system-libffi`. + +On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.), FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found. + +On FreeBSD systems pkgconf must be installed for the gem to be able to compile using clang. Install either via packages `pkg install pkgconf` or from ports via `devel/pkgconf`. + +On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and `require 'ffi'` works even without installing the gem (i.e., the gem is preinstalled on these implementations). + +## Installation + +From rubygems: + + [sudo] gem install ffi + +From a Gemfile using git or GitHub + + gem 'ffi', github: 'ffi/ffi', submodules: true + +or from the git repository on github: + + git clone git://github.com/ffi/ffi.git + cd ffi + git submodule update --init --recursive + bundle install + rake install + +### Install options: + +* `--enable-system-libffi` : Force usage of system libffi +* `--disable-system-libffi` : Force usage of builtin libffi +* `--enable-libffi-alloc` : Force closure allocation by libffi +* `--disable-libffi-alloc` : Force closure allocation by builtin method + +## License + +The ffi library is covered by the BSD license, also see the LICENSE file. +The specs are covered by the same license as [ruby/spec](https://github.com/ruby/spec), the MIT license. + +## Credits + +The following people have submitted code, bug reports, or otherwise contributed to the success of this project: + +* Alban Peignier +* Aman Gupta +* Andrea Fazzi +* Andreas Niederl +* Andrew Cholakian +* Antonio Terceiro +* Benoit Daloze +* Brian Candler +* Brian D. Burns +* Bryan Kearney +* Charlie Savage +* Chikanaga Tomoyuki +* Hongli Lai +* Ian MacLeod +* Jake Douglas +* Jean-Dominique Morani +* Jeremy Hinegardner +* Jesús García Sáez +* Joe Khoobyar +* Jurij Smakov +* KISHIMOTO, Makoto +* Kim Burgestrand +* Lars Kanis +* Luc Heinrich +* Luis Lavena +* Matijs van Zuijlen +* Matthew King +* Mike Dalessio +* NARUSE, Yui +* Park Heesob +* Shin Yee +* Stephen Bannasch +* Suraj N. Kurapati +* Sylvain Daubert +* Victor Costan +* beoran@gmail.com +* ctide +* emboss +* hobophobe +* meh +* postmodern +* wycats@gmail.com +* Wayne Meissner diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Rakefile b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Rakefile new file mode 100644 index 0000000..3422b74 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Rakefile @@ -0,0 +1,209 @@ +require 'rbconfig' +require 'date' +require 'fileutils' +require 'yaml' +require 'rspec/core/rake_task' +require 'rubygems/package_task' +require 'rake/extensiontask' +require_relative "lib/ffi/version" +require_relative "rakelib/ffi_gem_helper" + +BUILD_DIR = "build" +BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION) + +gem_spec = Bundler.load_gemspec('ffi.gemspec') + +RSpec::Core::RakeTask.new(:spec) do |config| + config.rspec_opts = YAML.load_file 'spec/spec.opts' +end + +desc "Build all packages" +task :package => %w[ gem:java gem:native ] + +CLOBBER.include 'lib/ffi/types.conf' +CLOBBER.include 'pkg' +CLOBBER.include 'log' + +CLEAN.include 'build' +CLEAN.include 'conftest.dSYM' +CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}' +CLEAN.include 'spec/ffi/fixtures/*.o' +CLEAN.include 'spec/ffi/embed-test/ext/*.{o,def}' +CLEAN.include 'spec/ffi/embed-test/ext/Makefile' +CLEAN.include "pkg/ffi-*-*/" +CLEAN.include 'lib/{2,3}.*' + +# clean all shipped files, that are not in git +CLEAN.include( + gem_spec.files - + `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0").map { |f| File.join("ext/ffi_c/libffi", f) } - + `git ls-files -z`.split("\x0") +) + +task :distclean => :clobber + +desc "Test the extension" +task :test => [ :spec ] + + +namespace :bench do + ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000 + bench_files = Dir["bench/bench_*.rb"].sort.reject { |f| f == "bench/bench_helper.rb" } + bench_files.each do |bench| + task File.basename(bench, ".rb")[6..-1] => :compile do + sh %{#{Gem.ruby} #{bench} #{ITER}} + end + end + task :all => :compile do + bench_files.each do |bench| + sh %{#{Gem.ruby} #{bench}} + end + end +end + +task 'spec:run' => :compile +task 'spec:specdoc' => :compile + +task :default => :spec + +namespace 'java' do + + java_gem_spec = gem_spec.dup.tap do |s| + s.files.reject! { |f| File.fnmatch?("ext/*", f) } + s.extensions = [] + s.platform = 'java' + end + + Gem::PackageTask.new(java_gem_spec) do |pkg| + pkg.need_zip = true + pkg.need_tar = true + pkg.package_dir = 'pkg' + end +end + +task 'gem:java' => 'java:gem' + +FfiGemHelper.install_tasks +# Register binary gems to be pushed to rubygems.org +Bundler::GemHelper.instance.cross_platforms = %w[ + x86-mingw32 + x64-mingw-ucrt + x64-mingw32 + x86-linux-gnu + x86-linux-musl + x86_64-linux-gnu + x86_64-linux-musl + arm-linux-gnu + arm-linux-musl + aarch64-linux-gnu + aarch64-linux-musl + aarch64-mingw-ucrt + x86_64-darwin + arm64-darwin +] + +if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx' + require 'rake/extensiontask' + Rake::ExtensionTask.new('ffi_c', gem_spec) do |ext| + ext.name = 'ffi_c' # indicate the name of the extension. + # ext.lib_dir = BUILD_DIR # put binaries into this folder. + ext.tmp_dir = BUILD_DIR # temporary folder used during compilation. + ext.cross_compile = true # enable cross compilation (requires cross compile toolchain) + ext.cross_platform = Bundler::GemHelper.instance.cross_platforms + ext.cross_compiling do |spec| + spec.files.reject! { |path| File.fnmatch?('ext/*', path) } + # Binary gems don't need libffi header+lib files + spec.metadata.delete("msys2_mingw_dependencies") + end + # Enable debug info for 'rake compile' but not for 'gem install' + ext.config_options << "--enable-debug" + + end +else + task :compile do + STDERR.puts "Nothing to compile on #{RUBY_ENGINE}" + end +end + + +namespace "gem" do + task 'prepare' do + require 'rake_compiler_dock' + sh "bundle package" + end + + Bundler::GemHelper.instance.cross_platforms.each do |plat| + desc "Build all native binary gems in parallel" + multitask 'native' => plat + + desc "Build the native gem for #{plat}" + task plat => ['prepare', 'build'] do + RakeCompilerDock.sh <<-EOT, platform: plat + sudo apt-get update && sudo apt-get install -y libltdl-dev && + bundle install --local && + rake native:#{plat} pkg/#{gem_spec.full_name}-#{plat}.gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=#{RakeCompilerDock.ruby_cc_version("~>4.0", "~>3.0")} + EOT + end + end +end + +directory "ext/ffi_c/libffi" +file "ext/ffi_c/libffi/autogen.sh" => "ext/ffi_c/libffi" do + warn "Downloading libffi ..." + sh "git submodule update --init --recursive" +end +task :libffi => "ext/ffi_c/libffi/autogen.sh" + +LIBFFI_GIT_FILES = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0") + +# Generate files which are in the gemspec but not in libffi's git repo by running autogen.sh +gem_spec.files.select do |f| + f =~ /ext\/ffi_c\/libffi\/(.*)/ && !LIBFFI_GIT_FILES.include?($1) +end.each do |f| + file f => "ext/ffi_c/libffi/autogen.sh" do + chdir "ext/ffi_c/libffi" do + sh "sh ./autogen.sh" + end + touch f + if gem_spec.files != Gem::Specification.load('./ffi.gemspec').files + warn "gemspec files have changed -> Please restart rake!" + exit 1 + end + end +end + +# Make sure we have all gemspec files before packaging +task :build => gem_spec.files +task :gem => :build + + +require_relative "lib/ffi/platform" +types_conf = File.expand_path(File.join(FFI::Platform::CONF_DIR, 'types.conf')) +logfile = File.join(File.dirname(__FILE__), 'types_log') + +task types_conf do |task| + require 'fileutils' + require_relative "rakelib/types_generator" + options = {} + FileUtils.mkdir_p(File.dirname(task.name), mode: 0755 ) + File.open(task.name, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f| + f.puts FFI::TypesGenerator.generate(options) + end + File.open(logfile, 'w') do |log| + log.puts(types_conf) + end +end + +desc "Create or update type information for platform #{FFI::Platform::NAME}" +task :types_conf => types_conf + +begin + require 'yard' + + namespace :doc do + YARD::Rake::YardocTask.new do |yard| + end + end +rescue LoadError + warn "[warn] YARD unavailable" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Steepfile b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Steepfile new file mode 100644 index 0000000..d35d735 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/Steepfile @@ -0,0 +1,8 @@ +target :lib do + signature "sig" + + check "lib" + + # ignore whole of lib, to just validate RBS in sig + ignore "lib" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/ffi.gemspec b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/ffi.gemspec new file mode 100644 index 0000000..6fdf2f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/ffi.gemspec @@ -0,0 +1,43 @@ +require File.expand_path("../lib/#{File.basename(__FILE__, '.gemspec')}/version", __FILE__) + +Gem::Specification.new do |s| + s.name = 'ffi' + s.version = FFI::VERSION + s.author = 'Wayne Meissner' + s.email = 'wmeissner@gmail.com' + s.homepage = 'https://github.com/ffi/ffi/wiki' + s.summary = 'Ruby FFI' + s.description = 'Ruby FFI library' + if s.respond_to?(:metadata) + s.metadata['bug_tracker_uri'] = 'https://github.com/ffi/ffi/issues' + s.metadata['changelog_uri'] = 'https://github.com/ffi/ffi/blob/master/CHANGELOG.md' + s.metadata['documentation_uri'] = 'https://github.com/ffi/ffi/wiki' + s.metadata['wiki_uri'] = 'https://github.com/ffi/ffi/wiki' + s.metadata['source_code_uri'] = 'https://github.com/ffi/ffi/' + s.metadata['mailing_list_uri'] = 'http://groups.google.com/group/ruby-ffi' + s.metadata['rubygems_mfa_required'] = 'true' + end + s.files = `git ls-files -z`.split("\x0").reject do |f| + f =~ /^(\.|bench|gen|libtest|nbproject|spec|rakelib)/ + end + + # Add libffi git files + lfs = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0").reject do |f| + f =~ /^(\.|testsuite)/ + end + # Add autoconf generated files of libffi + lfs += %w[ compile configure config.guess config.sub install-sh ltmain.sh missing fficonfig.h.in ] + # Add automake generated files of libffi + lfs += `git --git-dir ext/ffi_c/libffi/.git ls-files -z *.am */*.am`.gsub(".am\0", ".in\0").split("\x0") + s.files += lfs.map do |f| + File.join("ext/ffi_c/libffi", f) + end + + s.extensions << 'ext/ffi_c/extconf.rb' + s.rdoc_options = %w[--exclude=ext/ffi_c/.*\.o$ --exclude=ffi_c\.(bundle|so)$] + s.license = 'BSD-3-Clause' + s.require_paths << 'ext/ffi_c' + s.required_ruby_version = '>= 2.5' + + s.metadata['msys2_mingw_dependencies'] = 'libffi' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.0/ffi_c.bundle b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.0/ffi_c.bundle new file mode 100755 index 0000000..918356b Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.0/ffi_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.1/ffi_c.bundle b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.1/ffi_c.bundle new file mode 100755 index 0000000..564fcc9 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.1/ffi_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.2/ffi_c.bundle b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.2/ffi_c.bundle new file mode 100755 index 0000000..d2b2bbd Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.2/ffi_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.3/ffi_c.bundle b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.3/ffi_c.bundle new file mode 100755 index 0000000..73e4ee0 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.3/ffi_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.4/ffi_c.bundle b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.4/ffi_c.bundle new file mode 100755 index 0000000..4e7efc3 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/3.4/ffi_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/4.0/ffi_c.bundle b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/4.0/ffi_c.bundle new file mode 100755 index 0000000..de98252 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/4.0/ffi_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi.rb new file mode 100644 index 0000000..3fb20a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi.rb @@ -0,0 +1,27 @@ +if RUBY_ENGINE == 'ruby' + begin + require RUBY_VERSION.split('.')[0, 2].join('.') + '/ffi_c' + rescue Exception + require 'ffi_c' + end + + require 'ffi/ffi' + +elsif RUBY_ENGINE == 'jruby' && (RUBY_ENGINE_VERSION.split('.').map(&:to_i) <=> [9, 2, 20]) >= 0 + JRuby::Util.load_ext("org.jruby.ext.ffi.FFIService") + require 'ffi/ffi' + +elsif RUBY_ENGINE == 'truffleruby' && (RUBY_ENGINE_VERSION.split('.').map(&:to_i) <=> [20, 1, 0]) >= 0 + require 'truffleruby/ffi_backend' + require 'ffi/ffi' + +else + # Remove the ffi gem dir from the load path, then reload the internal ffi implementation + $LOAD_PATH.delete(File.dirname(__FILE__)) + $LOAD_PATH.delete(File.join(File.dirname(__FILE__), 'ffi')) + unless $LOADED_FEATURES.nil? + $LOADED_FEATURES.delete(__FILE__) + $LOADED_FEATURES.delete('ffi.rb') + end + require 'ffi.rb' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/abstract_memory.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/abstract_memory.rb new file mode 100644 index 0000000..e0aa221 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/abstract_memory.rb @@ -0,0 +1,44 @@ +# +# Copyright (C) 2020 Lars Kanis +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + + +module FFI + class AbstractMemory + LONG_MAX = FFI::Pointer.new(1).size + private_constant :LONG_MAX + + # Return +true+ if +self+ has a size limit. + # + # @return [Boolean] + def size_limit? + size != LONG_MAX + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/autopointer.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/autopointer.rb new file mode 100644 index 0000000..4dd6113 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/autopointer.rb @@ -0,0 +1,186 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# Copyright (C) 2008 Mike Dalessio +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +module FFI + class AutoPointer < Pointer + extend DataConverter + + # @overload initialize(pointer, method) + # @param pointer [Pointer] + # @param method [Method] + # @return [self] + # The passed Method will be invoked at GC time. + # @overload initialize(pointer, proc) + # @param pointer [Pointer] + # @return [self] + # The passed Proc will be invoked at GC time (SEE WARNING BELOW!) + # @note WARNING: passing a proc _may_ cause your pointer to never be + # GC'd, unless you're careful to avoid trapping a reference to the + # pointer in the proc. See the test specs for examples. + # @overload initialize(pointer) + # @param pointer [Pointer] + # @return [self] + # The pointer's release() class method will be invoked at GC time. + # + # @note The safest, and therefore preferred, calling + # idiom is to pass a Method as the second parameter. Example usage: + # + # class PointerHelper + # def self.release(pointer) + # ... + # end + # end + # + # p = AutoPointer.new(other_pointer, PointerHelper.method(:release)) + # + # The above code will cause PointerHelper#release to be invoked at GC time. + # + # @note + # The last calling idiom (only one parameter) is generally only + # going to be useful if you subclass {AutoPointer}, and override + # #release, which by default does nothing. + def initialize(ptr, proc=nil) + raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) || + ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer) + super(ptr.type_size, ptr) + + @releaser = if proc + if not proc.respond_to?(:call) + raise RuntimeError.new("proc must be callable") + end + Releaser.new(ptr, proc) + + else + if not self.class.respond_to?(:release, true) + raise RuntimeError.new("no release method defined") + end + Releaser.new(ptr, self.class.method(:release)) + end + + ObjectSpace.define_finalizer(self, @releaser) + self + end + + def dup + raise RuntimeError, "cannot duplicate FFI::AutoPointer" + end + + alias clone dup + + # @return [nil] + # Free the pointer. + def free + @releaser.free + end + + # @param [Boolean] autorelease + # @return [Boolean] +autorelease+ + # Set +autorelease+ property. See {Pointer Autorelease section at Pointer}. + def autorelease=(autorelease) + raise FrozenError.new("can't modify frozen #{self.class}") if frozen? + @releaser.autorelease=(autorelease) + end + + # @return [Boolean] +autorelease+ + # Get +autorelease+ property. See {Pointer Autorelease section at Pointer}. + def autorelease? + @releaser.autorelease + end + + # @abstract Base class for {AutoPointer}'s releasers. + # + # All subclasses of Releaser should define a +#release(ptr)+ method. + # A releaser is an object in charge of release an {AutoPointer}. + class Releaser + attr_accessor :autorelease + + # @param [Pointer] ptr + # @param [#call] proc + # @return [nil] + # A new instance of Releaser. + def initialize(ptr, proc) + @ptr = ptr + @proc = proc + @autorelease = true + end + + # @return [nil] + # Free pointer. + def free + if @ptr + release(@ptr) + @autorelease = false + @ptr = nil + @proc = nil + end + end + + # @param args + # Release pointer if +autorelease+ is set. + def call(*args) + release(@ptr) if @autorelease && @ptr + end + + # Release +ptr+ by using Proc or Method defined at +ptr+ + # {AutoPointer#initialize initialization}. + # + # @param [Pointer] ptr + # @return [nil] + def release(ptr) + @proc.call(ptr) + end + end + + # Return native type of AutoPointer. + # + # Override {DataConverter#native_type}. + # @return [Type::POINTER] + # @raise {RuntimeError} if class does not implement a +#release+ method + def self.native_type + if not self.respond_to?(:release, true) + raise RuntimeError.new("no release method defined for #{self.inspect}") + end + Type::POINTER + end + + # Create a new AutoPointer. + # + # Override {DataConverter#from_native}. + # @overload self.from_native(ptr, ctx) + # @param [Pointer] ptr + # @param ctx not used. Please set +nil+. + # @return [AutoPointer] + def self.from_native(val, ctx) + self.new(val) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/buffer.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/buffer.rb new file mode 100644 index 0000000..449e45b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/buffer.rb @@ -0,0 +1,4 @@ +# +# All the code from this file is now implemented in C. This file remains +# to satisfy any leftover require 'ffi/buffer' in user code +# diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/callback.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/callback.rb new file mode 100644 index 0000000..32d52f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/callback.rb @@ -0,0 +1,4 @@ +# +# All the code from this file is now implemented in C. This file remains +# to satisfy any leftover require 'ffi/callback' in user code +# diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/compat.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/compat.rb new file mode 100644 index 0000000..051724f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/compat.rb @@ -0,0 +1,54 @@ +# +# Copyright (C) 2023-2023 Lars Kanis +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +module FFI + if defined?(Ractor.make_shareable) + # This is for FFI internal use only. + def self.make_shareable(obj) + Ractor.make_shareable(obj) + end + else + def self.make_shareable(obj) + obj.freeze + end + end + + if defined?(Ractor.shareable_proc) + # This is for FFI internal use only. + def self.shareable_proc(**kwargs, &block) + Ractor.shareable_proc(**kwargs, &block) + end + else + def self.shareable_proc(**_kwargs, &block) + block + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/data_converter.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/data_converter.rb new file mode 100644 index 0000000..7852e7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/data_converter.rb @@ -0,0 +1,67 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +module FFI + # This module is used to extend somes classes and give then a common API. + # + # Most of methods defined here must be overridden. + module DataConverter + # Get native type. + # + # @overload native_type(type) + # @param [String, Symbol, Type] type + # @return [Type] + # Get native type from +type+. + # + # @overload native_type + # @raise {NotImplementedError} This method must be overridden. + def native_type(type = nil) + if type + @native_type = FFI.find_type(type) + else + native_type = @native_type + unless native_type + raise NotImplementedError, 'native_type method not overridden and no native_type set' + end + native_type + end + end + + # Convert to a native type. + def to_native(value, ctx) + value + end + + # Convert from a native type. + def from_native(value, ctx) + value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/dynamic_library.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/dynamic_library.rb new file mode 100644 index 0000000..468ce04 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/dynamic_library.rb @@ -0,0 +1,118 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +module FFI + class DynamicLibrary + SEARCH_PATH = [] + + # The following search paths are tried, if the library could not be loaded in the first attempt. + # They are only executed on Macos in the following order: + if FFI::Platform.mac? + + # 1. Try library paths possibly defined in LD_LIBRARY_PATH DYLD_LIBRARY_PATH first. + # This is because dlopen doesn't respect LD_LIBRARY_PATH and DYLD_LIBRARY_PATH is deleted by SIP-protected binaries. + # See here for details: https://github.com/ffi/ffi/issues/923#issuecomment-1872565313 + %w[LD_LIBRARY_PATH DYLD_LIBRARY_PATH].each do |custom_path| + SEARCH_PATH.concat ENV.fetch(custom_path,"").split(File::PATH_SEPARATOR) + end + + # 2. Then on macos/arm64 try /opt/homebrew/lib, since this is a typical standard directory. + # FFI is often used together with homebrew, so that we hardcode the path for arm64 here. + if FFI::Platform::ARCH == 'aarch64' + SEARCH_PATH << '/opt/homebrew/lib' + end + + # 3. Then try typical system directories starting with the /local/ directory first. + # + # /usr/local/lib is used by homebrow on x86_64. + # /opt/local/lib is used by MacPorts and Fink. + # /usr/lib is there, because it was always there. + SEARCH_PATH.concat %w[/opt/local/lib /usr/local/lib /usr/lib] + end + + # On Linux the library lookup paths are usually defined through /etc/ld.so.conf, which can be changed at will with root permissions. + # Also LD_LIBRARY_PATH is respected by the dynamic loader, so that there's usually no need and no advantage to do a fallback handling. + # + # Windows has it's own library lookup logic, very different to what we do here. + # See: https://github.com/oneclick/rubyinstaller2/wiki/For-gem-developers#user-content-dll-loading + + FFI.make_shareable(SEARCH_PATH) + SEARCH_PATH_MESSAGE = "Searched in #{ SEARCH_PATH.map{|a| ', ' + a}.join }".freeze + + def self.load_library(name, flags) + if name == FFI::CURRENT_PROCESS + FFI::DynamicLibrary.open(nil, RTLD_LAZY | RTLD_LOCAL) + else + flags ||= RTLD_LAZY | RTLD_LOCAL + + libnames = (name.is_a?(::Array) ? name : [name]) + libnames = libnames.map(&:to_s).map { |n| [n, FFI.map_library_name(n)].uniq }.flatten.compact + errors = [] + + libnames.each do |libname| + lib = try_load(libname, flags, errors) + return lib if lib + + unless libname.start_with?("/") + SEARCH_PATH.each do |prefix| + path = "#{prefix}/#{libname}" + if File.exist?(path) + lib = try_load(path, flags, errors) + return lib if lib + end + end + end + end + + raise LoadError, [*errors, SEARCH_PATH_MESSAGE].join(".\n") + end + end + private_class_method :load_library + + def self.try_load(libname, flags, errors) + begin + lib = FFI::DynamicLibrary.open(libname, flags) + return lib if lib + + # LoadError for C ext & JRuby, RuntimeError for TruffleRuby + rescue LoadError, RuntimeError => ex + if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/ + if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/ + return try_load($1, flags, errors) + end + end + + errors << ex + nil + end + end + private_class_method :try_load + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/enum.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/enum.rb new file mode 100644 index 0000000..af78331 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/enum.rb @@ -0,0 +1,302 @@ +# +# Copyright (C) 2009, 2010 Wayne Meissner +# Copyright (C) 2009 Luc Heinrich +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +module FFI + + # An instance of this class permits to manage {Enum}s. In fact, Enums is a collection of {Enum}s. + class Enums + + def initialize + @all_enums = Array.new + @tagged_enums = Hash.new + @symbol_map = Hash.new + end + + # @param [Enum] enum + # Add an {Enum} to the collection. + def <<(enum) + @all_enums << enum + @tagged_enums[enum.tag] = enum unless enum.tag.nil? + @symbol_map.merge!(enum.symbol_map) + end + + # @param query enum tag or part of an enum name + # @return [Enum] + # Find a {Enum} in collection. + def find(query) + if @tagged_enums.has_key?(query) + @tagged_enums[query] + else + @all_enums.detect { |enum| enum.symbols.include?(query) } + end + end + + # @param symbol a symbol to find in merge symbol maps of all enums. + # @return a symbol + def __map_symbol(symbol) + @symbol_map[symbol] + end + + end + + # Represents a C enum. + # + # For a C enum: + # enum fruits { + # apple, + # banana, + # orange, + # pineapple + # }; + # are defined this vocabulary: + # * a _symbol_ is a word from the enumeration (ie. _apple_, by example); + # * a _value_ is the value of a symbol in the enumeration (by example, apple has value _0_ and banana _1_). + class Enum + include DataConverter + + attr_reader :tag + attr_reader :native_type + + # @overload initialize(info, tag=nil) + # @param [nil, Enumerable] info + # @param [nil, Symbol] tag enum tag + # @overload initialize(native_type, info, tag=nil) + # @param [FFI::Type] native_type Native type for new Enum + # @param [nil, Enumerable] info symbols and values for new Enum + # @param [nil, Symbol] tag name of new Enum + def initialize(*args) + @native_type = args.first.kind_of?(FFI::Type) ? args.shift : Type::INT + info, @tag = *args + @kv_map = Hash.new + unless info.nil? + last_cst = nil + value = 0 + info.each do |i| + case i + when Symbol + raise ArgumentError, "duplicate enum key" if @kv_map.has_key?(i) + @kv_map[i] = value + last_cst = i + value += 1 + when Integer + @kv_map[last_cst] = i + value = i+1 + end + end + end + @vk_map = @kv_map.invert + end + + # @return [Array] enum symbol names + def symbols + @kv_map.keys + end + + # Get a symbol or a value from the enum. + # @overload [](query) + # Get enum value from symbol. + # @param [Symbol] query + # @return [Integer] + # @overload [](query) + # Get enum symbol from value. + # @param [Integer] query + # @return [Symbol] + def [](query) + case query + when Symbol + @kv_map[query] + when Integer + @vk_map[query] + end + end + alias find [] + + # Get the symbol map. + # @return [Hash] + def symbol_map + @kv_map + end + + alias to_h symbol_map + alias to_hash symbol_map + + # @param [Symbol, Integer, #to_int] val + # @param ctx unused + # @return [Integer] value of a enum symbol + def to_native(val, ctx) + @kv_map[val] || if val.is_a?(Integer) + val + elsif val.respond_to?(:to_int) + val.to_int + else + raise ArgumentError, "invalid enum value, #{val.inspect}" + end + end + + # @param val + # @return symbol name if it exists for +val+. + def from_native(val, ctx) + @vk_map[val] || val + end + end + + # Represents a C enum whose values are power of 2 + # + # @example + # enum { + # red = (1<<0), + # green = (1<<1), + # blue = (1<<2) + # } + # + # Contrary to classical enums, bitmask values are usually combined + # when used. + class Bitmask < Enum + + # @overload initialize(info, tag=nil) + # @param [nil, Enumerable] info symbols and bit rank for new Bitmask + # @param [nil, Symbol] tag name of new Bitmask + # @overload initialize(native_type, info, tag=nil) + # @param [FFI::Type] native_type Native type for new Bitmask + # @param [nil, Enumerable] info symbols and bit rank for new Bitmask + # @param [nil, Symbol] tag name of new Bitmask + def initialize(*args) + @native_type = args.first.kind_of?(FFI::Type) ? args.shift : Type::INT + @signed = [Type::INT8, Type::INT16, Type::INT32, Type::INT64].include?(@native_type) + info, @tag = *args + @kv_map = Hash.new + unless info.nil? + last_cst = nil + value = 0 + info.each do |i| + case i + when Symbol + raise ArgumentError, "duplicate bitmask key" if @kv_map.has_key?(i) + @kv_map[i] = 1 << value + last_cst = i + value += 1 + when Integer + raise ArgumentError, "bitmask index should be positive" if i<0 + @kv_map[last_cst] = 1 << i + value = i+1 + end + end + end + @vk_map = @kv_map.invert + end + + # Get a symbol list or a value from the bitmask + # @overload [](*query) + # Get bitmask value from symbol list + # @param [Symbol] query + # @return [Integer] + # @overload [](query) + # Get bitmask value from symbol array + # @param [Array] query + # @return [Integer] + # @overload [](*query) + # Get a list of bitmask symbols corresponding to + # the or reduction of a list of integer + # @param [Integer] query + # @return [Array] + # @overload [](query) + # Get a list of bitmask symbols corresponding to + # the or reduction of a list of integer + # @param [Array] query + # @return [Array] + def [](*query) + flat_query = query.flatten + raise ArgumentError, "query should be homogeneous, #{query.inspect}" unless flat_query.all? { |o| o.is_a?(Symbol) } || flat_query.all? { |o| o.is_a?(Integer) || o.respond_to?(:to_int) } + case flat_query[0] + when Symbol + flat_query.inject(0) do |val, o| + v = @kv_map[o] + if v then val | v else val end + end + when Integer, ->(o) { o.respond_to?(:to_int) } + val = flat_query.inject(0) { |mask, o| mask |= o.to_int } + @kv_map.select { |_, v| v & val != 0 }.keys + end + end + + # Get the native value of a bitmask + # @overload to_native(query, ctx) + # @param [Symbol, Integer, #to_int] query + # @param ctx unused + # @return [Integer] value of a bitmask + # @overload to_native(query, ctx) + # @param [Array] query + # @param ctx unused + # @return [Integer] value of a bitmask + def to_native(query, ctx) + return 0 if query.nil? + flat_query = [query].flatten + res = flat_query.inject(0) do |val, o| + case o + when Symbol + v = @kv_map[o] + raise ArgumentError, "invalid bitmask value, #{o.inspect}" unless v + val | v + when Integer + val | o + when ->(obj) { obj.respond_to?(:to_int) } + val | o.to_int + else + raise ArgumentError, "invalid bitmask value, #{o.inspect}" + end + end + # Take two's complement of positive values bigger than the max value + # for the type when native type is signed. + if @signed && res >= (1 << (@native_type.size * 8 - 1)) + res = -(-res & ((1 << (@native_type.size * 8)) - 1)) + end + res + end + + # @param [Integer] val + # @param ctx unused + # @return [Array] list of symbol names corresponding to val, plus an optional remainder if some bits don't match any constant + def from_native(val, ctx) + flags = @kv_map.select { |_, v| v & val != 0 } + list = flags.keys + # force an unsigned value of the correct size + val &= (1 << (@native_type.size * 8)) - 1 if @signed + # If there are unmatch flags, + # return them in an integer, + # else information can be lost. + # Similar to Enum behavior. + remainder = val ^ flags.values.reduce(0, :|) + list.push remainder unless remainder == 0 + return list + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/errno.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/errno.rb new file mode 100644 index 0000000..de82d89 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/errno.rb @@ -0,0 +1,43 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +module FFI + # @return (see FFI::LastError.error) + # @see FFI::LastError.error + def self.errno + FFI::LastError.error + end + # @param error (see FFI::LastError.error=) + # @return (see FFI::LastError.error=) + # @see FFI::LastError.error= + def self.errno=(error) + FFI::LastError.error = error + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/ffi.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/ffi.rb new file mode 100644 index 0000000..4782270 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/ffi.rb @@ -0,0 +1,109 @@ +# +# Copyright (C) 2008-2010 JRuby project +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +require 'ffi/compat' +require 'ffi/platform' +require 'ffi/data_converter' +require 'ffi/types' +require 'ffi/library_path' +require 'ffi/library' +require 'ffi/errno' +require 'ffi/abstract_memory' +require 'ffi/pointer' +require 'ffi/memorypointer' +require 'ffi/struct' +require 'ffi/union' +require 'ffi/managedstruct' +require 'ffi/callback' +require 'ffi/io' +require 'ffi/autopointer' +require 'ffi/variadic' +require 'ffi/enum' +require 'ffi/version' +require 'ffi/function' + +module FFI + module ModernForkTracking + def _fork + pid = super + if pid == 0 + FFI._async_cb_dispatcher_atfork_child + end + pid + end + end + + module LegacyForkTracking + module KernelExt + def fork + if block_given? + super do + FFI._async_cb_dispatcher_atfork_child + yield + end + else + pid = super + FFI._async_cb_dispatcher_atfork_child if pid.nil? + pid + end + end + end + + module KernelExtPrivate + include KernelExt + private :fork + end + + module IOExt + def popen(*args) + return super unless args[0] == '-' + + super(*args) do |pipe| + FFI._async_cb_dispatcher_atfork_child if pipe.nil? + yield pipe + end + end + ruby2_keywords :popen if respond_to?(:ruby2_keywords) + end + end + + if Process.respond_to?(:_fork) + # The nice Ruby 3.1+ way of doing things + ::Process.singleton_class.prepend(ModernForkTracking) + elsif Process.respond_to?(:fork) + # Barf. Old CRuby. + # Most of the inspiration for how to do this was stolen from ActiveSupport. + ::Object.prepend(LegacyForkTracking::KernelExtPrivate) + ::Object.singleton_class.prepend(LegacyForkTracking::KernelExt) + ::Kernel.prepend(LegacyForkTracking::KernelExtPrivate) + ::Kernel.singleton_class.prepend(LegacyForkTracking::KernelExt) + ::IO.singleton_class.prepend(LegacyForkTracking::IOExt) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/function.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/function.rb new file mode 100644 index 0000000..d8d4765 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/function.rb @@ -0,0 +1,94 @@ +# +# Copyright (C) 2008-2010 JRuby project +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +module FFI + class Function + # Only MRI allows function type queries + if private_method_defined?(:type) + # Retrieve the return type of the function + # + # This method returns FFI type returned by the function. + # + # @return [FFI::Type] + def return_type + type.return_type + end + + # Retrieve Array of parameter types + # + # This method returns an Array of FFI types accepted as function parameters. + # + # @return [Array] + def param_types + type.param_types + end + end + + if RUBY_PLATFORM == 'aarch64-mingw-ucrt' + # Use a workaround for https://github.com/libffi/libffi/issues/905 + def attach(mod, name) + this = self + body = proc do |*args, &block| + this.call(*args, &block) + end + + mod.define_method(name, body) + mod.define_singleton_method(name, body) + + # Store function Proc's for re-definition as Ractor-shareable in Library#freeze + funcs = mod.instance_variable_get("@ffi_function_procs") + unless funcs + funcs = {} + mod.instance_variable_set("@ffi_function_procs", funcs) + end + funcs[name] = self + + self + end + end + + # Stash the Function in a module variable so it can be inspected by attached_functions. + # On CRuby it also ensures that it does not get garbage collected. + module RegisterAttach + def attach(mod, name) + funcs = mod.instance_variable_defined?("@ffi_functions") && mod.instance_variable_get("@ffi_functions") + unless funcs + funcs = {} + mod.instance_variable_set("@ffi_functions", funcs) + end + funcs[name.to_sym] = self + # Jump to the native attach method of CRuby, JRuby or Tuffleruby + super + end + end + private_constant :RegisterAttach + prepend RegisterAttach + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/io.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/io.rb new file mode 100644 index 0000000..7fb2857 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/io.rb @@ -0,0 +1,62 @@ +# +# Copyright (C) 2008, 2009 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +module FFI + + # This module implements a couple of class methods to play with IO. + module IO + # @param [Integer] fd file decriptor + # @param [String] mode mode string + # @return [::IO] + # Synonym for IO::for_fd. + def self.for_fd(fd, mode = "r") + ::IO.for_fd(fd, mode) + end + + # @param [#read] io io to read from + # @param [AbstractMemory] buf destination for data read from +io+ + # @param [nil, Integer] len maximul number of bytes to read from +io+. If +nil+, + # read until end of file. + # @return [Integer] length really read, in bytes + # + # A version of IO#read that reads data from an IO and put then into a native buffer. + # + # This will be optimized at some future time to eliminate the double copy. + # + def self.native_read(io, buf, len) + tmp = io.read(len) + return -1 unless tmp + buf.put_bytes(0, tmp) + tmp.length + end + + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library.rb new file mode 100644 index 0000000..e497b64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library.rb @@ -0,0 +1,592 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +require 'ffi/dynamic_library' + +module FFI + CURRENT_PROCESS = USE_THIS_PROCESS_AS_LIBRARY = FFI.make_shareable(Object.new) + + # @param [String, FFI::LibraryPath] lib library name or LibraryPath object + # @return [String] library name formatted for current platform + # Transform a generic library name to a platform library name + # @example + # # Linux + # FFI.map_library_name 'c' # -> "libc.so.6" + # FFI.map_library_name 'jpeg' # -> "libjpeg.so" + # # Windows + # FFI.map_library_name 'c' # -> "msvcrt.dll" + # FFI.map_library_name 'jpeg' # -> "jpeg.dll" + def self.map_library_name(lib) + # Mangle the library name to reflect the native library naming conventions + LibraryPath.wrap(lib).to_s + end + + # Exception raised when a function is not found in libraries + class NotFoundError < LoadError + def initialize(function, *libraries) + super("Function '#{function}' not found in [#{libraries[0].nil? ? 'current process' : libraries.join(", ")}]") + end + end + + # This module is the base to use native functions. + # + # A basic usage may be: + # require 'ffi' + # + # module Hello + # extend FFI::Library + # ffi_lib FFI::Library::LIBC + # attach_function 'puts', [ :string ], :int + # end + # + # Hello.puts("Hello, World") + # + # + module Library + CURRENT_PROCESS = FFI::CURRENT_PROCESS + LIBC = FFI::Platform::LIBC + + # @param mod extended object + # @return [nil] + # @raise {RuntimeError} if +mod+ is not a Module + # Test if extended object is a Module. If not, raise RuntimeError. + def self.extended(mod) + raise RuntimeError.new("must only be extended by module") unless mod.kind_of?(::Module) + end + + + # @param [Array] names names of libraries to load + # @return [Array] + # @raise {LoadError} if a library cannot be opened + # Load native libraries. + def ffi_lib(*names) + raise LoadError.new("library names list must not be empty") if names.empty? + + lib_flags = defined?(@ffi_lib_flags) && @ffi_lib_flags + + @ffi_libs = names.map do |name| + FFI::DynamicLibrary.send(:load_library, name, lib_flags) + end + end + + # Set the calling convention for {#attach_function} and {#callback} + # + # @see http://en.wikipedia.org/wiki/Stdcall#stdcall + # @note +:stdcall+ is typically used for attaching Windows API functions + # + # @param [Symbol] convention one of +:default+, +:stdcall+ + # @return [Symbol] the new calling convention + def ffi_convention(convention = nil) + @ffi_convention ||= :default + @ffi_convention = convention if convention + @ffi_convention + end + + # @see #ffi_lib + # @return [Array] array of currently loaded FFI libraries + # @raise [LoadError] if no libraries have been loaded (using {#ffi_lib}) + # Get FFI libraries loaded using {#ffi_lib}. + def ffi_libraries + raise LoadError.new("no library specified") if !defined?(@ffi_libs) || @ffi_libs.empty? + @ffi_libs + end + + # Flags used in {#ffi_lib}. + # + # This map allows you to supply symbols to {#ffi_lib_flags} instead of + # the actual constants. + FlagsMap = { + :global => DynamicLibrary::RTLD_GLOBAL, + :local => DynamicLibrary::RTLD_LOCAL, + :lazy => DynamicLibrary::RTLD_LAZY, + :now => DynamicLibrary::RTLD_NOW + } + + # Sets library flags for {#ffi_lib}. + # + # @example + # ffi_lib_flags(:lazy, :local) # => 5 + # + # @param [Symbol, …] flags (see {FlagsMap}) + # @return [Integer] the new value + def ffi_lib_flags(*flags) + @ffi_lib_flags = flags.inject(0) { |result, f| result | FlagsMap[f] } + end + + + ## + # @overload attach_function(func, args, returns, options = {}) + # @example attach function without an explicit name + # module Foo + # extend FFI::Library + # ffi_lib FFI::Library::LIBC + # attach_function :malloc, [:size_t], :pointer + # end + # # now callable via Foo.malloc + # @overload attach_function(name, func, args, returns, options = {}) + # @example attach function with an explicit name + # module Bar + # extend FFI::Library + # ffi_lib FFI::Library::LIBC + # attach_function :c_malloc, :malloc, [:size_t], :pointer + # end + # # now callable via Bar.c_malloc + # + # Attach C function +func+ to this module. + # + # + # @param [#to_s] name name of ruby method to attach as + # @param [#to_s] func name of C function to attach + # @param [Array] args an array of types + # @param [Symbol] returns type of return value + # @option options [Boolean] :blocking (@blocking) set to true if the C function is a blocking call + # @option options [Symbol] :convention (:default) calling convention (see {#ffi_convention}) + # @option options [FFI::Enums] :enums + # @option options [Hash] :type_map + # + # @return [FFI::VariadicInvoker] + # + # @raise [FFI::NotFoundError] if +func+ cannot be found in the attached libraries (see {#ffi_lib}) + def attach_function(name, func, args, returns = nil, options = nil) + mname, a2, a3, a4, a5 = name, func, args, returns, options + cname, arg_types, ret_type, opts = (a4 && (a2.is_a?(String) || a2.is_a?(Symbol))) ? [ a2, a3, a4, a5 ] : [ mname.to_s, a2, a3, a4 ] + + # Convert :foo to the native type + arg_types = arg_types.map { |e| find_type(e) } + options = { + :convention => ffi_convention, + :type_map => defined?(@ffi_typedefs) ? @ffi_typedefs : nil, + :blocking => defined?(@blocking) && @blocking, + :enums => defined?(@ffi_enums) ? @ffi_enums : nil, + } + + @blocking = false + options.merge!(opts) if opts && opts.is_a?(Hash) + + # Try to locate the function in any of the libraries + invokers = [] + ffi_libraries.each do |lib| + if invokers.empty? + begin + function = nil + function_names(cname, arg_types).find do |fname| + function = lib.find_function(fname) + end + raise LoadError unless function + + invokers << if arg_types[-1] == FFI::NativeType::VARARGS + VariadicInvoker.new(function, arg_types, find_type(ret_type), options) + + else + Function.new(find_type(ret_type), arg_types, function, options) + end + + rescue LoadError + end + end + end + invoker = invokers.compact.shift + raise FFI::NotFoundError.new(cname.to_s, ffi_libraries.map { |lib| lib.name }) unless invoker + + invoker.attach(self, mname.to_s) + invoker + end + + # @param [#to_s] name function name + # @param [Array] arg_types function's argument types + # @return [Array] + # This function returns a list of possible names to lookup. + # @note Function names on windows may be decorated if they are using stdcall. See + # * http://en.wikipedia.org/wiki/Name_mangling#C_name_decoration_in_Microsoft_Windows + # * http://msdn.microsoft.com/en-us/library/zxk0tw93%28v=VS.100%29.aspx + # * http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions#STDCALL + # Note that decorated names can be overridden via def files. Also note that the + # windows api, although using, doesn't have decorated names. + def function_names(name, arg_types) + result = [name.to_s] + if ffi_convention == :stdcall + # Get the size of each parameter + size = arg_types.inject(0) do |mem, arg| + size = arg.size + # The size must be a multiple of 4 + size += (4 - size) % 4 + mem + size + end + + result << "_#{name.to_s}@#{size}" # win32 + result << "#{name.to_s}@#{size}" # win64 + end + result + end + + # @overload attach_variable(mname, cname, type) + # @param [#to_s] mname name of ruby method to attach as + # @param [#to_s] cname name of C variable to attach + # @param [DataConverter, Struct, Symbol, Type] type C variable's type + # @example + # module Bar + # extend FFI::Library + # ffi_lib 'my_lib' + # attach_variable :c_myvar, :myvar, :long + # end + # # now callable via Bar.c_myvar + # @overload attach_variable(cname, type) + # @param [#to_s] mname name of ruby method to attach as + # @param [DataConverter, Struct, Symbol, Type] type C variable's type + # @example + # module Bar + # extend FFI::Library + # ffi_lib 'my_lib' + # attach_variable :myvar, :long + # end + # # now callable via Bar.myvar + # @return [DynamicLibrary::Symbol] + # @raise {FFI::NotFoundError} if +cname+ cannot be found in libraries + # + # Attach C variable +cname+ to this module. + def attach_variable(mname, a1, a2 = nil) + cname, type = a2 ? [ a1, a2 ] : [ mname.to_s, a1 ] + mname = mname.to_sym + address = nil + ffi_libraries.each do |lib| + begin + address = lib.find_variable(cname.to_s) + break unless address.nil? + rescue LoadError + end + end + + raise FFI::NotFoundError.new(cname, ffi_libraries) if address.nil? || address.null? + if type.is_a?(Class) && type < FFI::Struct + # If it is a global struct, just attach directly to the pointer + s = s = type.new(address) # Assigning twice to suppress unused variable warning + self.module_eval(<<-code, __FILE__, __LINE__) + @ffi_gsvars = {} unless defined?(@ffi_gsvars) + @ffi_gsvars[#{mname.inspect}] = s + def self.#{mname} + @ffi_gsvars[#{mname.inspect}] + end + code + + else + sc = Class.new(FFI::Struct) + sc.layout :gvar, find_type(type) + s = sc.new(address) + # + # Attach to this module as mname/mname= + # + self.module_eval(<<-code, __FILE__, __LINE__) + @ffi_gvars = {} unless defined?(@ffi_gvars) + @ffi_gvars[#{mname.inspect}] = s + def self.#{mname} + @ffi_gvars[#{mname.inspect}][:gvar] + end + def self.#{mname}=(value) + @ffi_gvars[#{mname.inspect}][:gvar] = value + end + code + + end + + address + end + + + # @overload callback(name, params, ret) + # @param name callback name to add to type map + # @param [Array] params array of parameters' types + # @param [DataConverter, Struct, Symbol, Type] ret callback return type + # @overload callback(params, ret) + # @param [Array] params array of parameters' types + # @param [DataConverter, Struct, Symbol, Type] ret callback return type + # @return [FFI::CallbackInfo] + def callback(*args) + raise ArgumentError, "wrong number of arguments" if args.length < 2 || args.length > 3 + name, params, ret = if args.length == 3 + args + else + [ nil, args[0], args[1] ] + end + + native_params = params.map { |e| find_type(e) } + raise ArgumentError, "callbacks cannot have variadic parameters" if native_params.include?(FFI::Type::VARARGS) + options = Hash.new + options[:convention] = ffi_convention + options[:enums] = @ffi_enums if defined?(@ffi_enums) + ret_type = find_type(ret) + if ret_type == Type::STRING + raise TypeError, ":string is not allowed as return type of callbacks" + end + cb = FFI::CallbackInfo.new(ret_type, native_params, options) + + # Add to the symbol -> type map (unless there was no name) + unless name.nil? + typedef cb, name + end + + cb + end + + # Register or get an already registered type definition. + # + # To register a new type definition, +old+ should be a {FFI::Type}. +add+ + # is in this case the type definition. + # + # If +old+ is a {DataConverter}, a {Type::Mapped} is returned. + # + # If +old+ is +:enum+ + # * and +add+ is an +Array+, a call to {#enum} is made with +add+ as single parameter; + # * in others cases, +info+ is used to create a named enum. + # + # If +old+ is a key for type map, #typedef get +old+ type definition. + # + # @param [DataConverter, Symbol, Type] old + # @param [Symbol] add + # @param [Symbol] info + # @return [FFI::Enum, FFI::Type] + def typedef(old, add, info=nil) + @ffi_typedefs = Hash.new unless defined?(@ffi_typedefs) + + @ffi_typedefs[add] = if old.kind_of?(FFI::Type) + old + + elsif @ffi_typedefs.has_key?(old) + @ffi_typedefs[old] + + elsif old.is_a?(DataConverter) + FFI::Type::Mapped.new(old) + + elsif old == :enum + if add.kind_of?(Array) + self.enum(add) + else + self.enum(info, add) + end + + else + FFI.find_type(old) + end + end + + # @param [DataConverter, Type, Struct, Symbol] t type to find + # @return [Type] + # Find a type definition. + def find_type(t) + if t.kind_of?(Type) + t + + elsif defined?(@ffi_typedefs) && @ffi_typedefs.has_key?(t) + @ffi_typedefs[t] + + elsif t.is_a?(Class) && t < Struct + Type::POINTER + + elsif t.is_a?(DataConverter) + # Add a typedef so next time the converter is used, it hits the cache + typedef Type::Mapped.new(t), t + + end || FFI.find_type(t) + end + + private + # Generic enum builder + # @param [Class] klass can be one of FFI::Enum or FFI::Bitmask + # @param args (see #enum or #bitmask) + def generic_enum(klass, *args) + native_type = args.first.kind_of?(FFI::Type) ? args.shift : nil + name, values = if args[0].kind_of?(Symbol) && args[1].kind_of?(Array) + [ args[0], args[1] ] + elsif args[0].kind_of?(Array) + [ nil, args[0] ] + else + [ nil, args ] + end + @ffi_enums = FFI::Enums.new unless defined?(@ffi_enums) + @ffi_enums << (e = native_type ? klass.new(native_type, values, name) : klass.new(values, name)) + + # If called with a name, add a typedef alias + typedef(e, name) if name + e + end + + public + # @overload enum(name, values) + # Create a named enum. + # @example + # enum :foo, [:zero, :one, :two] # named enum + # @param [Symbol] name name for new enum + # @param [Array] values values for enum + # @overload enum(*args) + # Create an unnamed enum. + # @example + # enum :zero, :one, :two # unnamed enum + # @param args values for enum + # @overload enum(values) + # Create an unnamed enum. + # @example + # enum [:zero, :one, :two] # unnamed enum, equivalent to above example + # @param [Array] values values for enum + # @overload enum(native_type, name, values) + # Create a named enum and specify the native type. + # @example + # enum FFI::Type::UINT64, :foo, [:zero, :one, :two] # named enum + # @param [FFI::Type] native_type native type for new enum + # @param [Symbol] name name for new enum + # @param [Array] values values for enum + # @overload enum(native_type, *args) + # Create an unnamed enum and specify the native type. + # @example + # enum FFI::Type::UINT64, :zero, :one, :two # unnamed enum + # @param [FFI::Type] native_type native type for new enum + # @param args values for enum + # @overload enum(native_type, values) + # Create an unnamed enum and specify the native type. + # @example + # enum Type::UINT64, [:zero, :one, :two] # unnamed enum, equivalent to above example + # @param [FFI::Type] native_type native type for new enum + # @param [Array] values values for enum + # @return [FFI::Enum] + # Create a new {FFI::Enum}. + def enum(*args) + generic_enum(FFI::Enum, *args) + end + + # @overload bitmask(name, values) + # Create a named bitmask + # @example + # bitmask :foo, [:red, :green, :blue] # bits 0,1,2 are used + # bitmask :foo, [:red, :green, 5, :blue] # bits 0,5,6 are used + # @param [Symbol] name for new bitmask + # @param [Array] values for new bitmask + # @overload bitmask(*args) + # Create an unamed bitmask + # @example + # bm = bitmask :red, :green, :blue # bits 0,1,2 are used + # bm = bitmask :red, :green, 5, blue # bits 0,5,6 are used + # @param [Symbol, Integer] args values for new bitmask + # @overload bitmask(values) + # Create an unamed bitmask + # @example + # bm = bitmask [:red, :green, :blue] # bits 0,1,2 are used + # bm = bitmask [:red, :green, 5, blue] # bits 0,5,6 are used + # @param [Array] values for new bitmask + # @overload bitmask(native_type, name, values) + # Create a named enum and specify the native type. + # @example + # bitmask FFI::Type::UINT64, :foo, [:red, :green, :blue] + # @param [FFI::Type] native_type native type for new bitmask + # @param [Symbol] name for new bitmask + # @param [Array] values for new bitmask + # @overload bitmask(native_type, *args) + # @example + # bitmask FFI::Type::UINT64, :red, :green, :blue + # @param [FFI::Type] native_type native type for new bitmask + # @param [Symbol, Integer] args values for new bitmask + # @overload bitmask(native_type, values) + # Create a named enum and specify the native type. + # @example + # bitmask FFI::Type::UINT64, [:red, :green, :blue] + # @param [FFI::Type] native_type native type for new bitmask + # @param [Array] values for new bitmask + # @return [FFI::Bitmask] + # Create a new FFI::Bitmask + def bitmask(*args) + generic_enum(FFI::Bitmask, *args) + end + + # @param name + # @return [FFI::Enum] + # Find an enum by name. + def enum_type(name) + @ffi_enums.find(name) if defined?(@ffi_enums) + end + + # @param symbol + # @return [FFI::Enum] + # Find an enum by a symbol it contains. + def enum_value(symbol) + @ffi_enums.__map_symbol(symbol) + end + + # Retrieve all attached functions and their function signature + # + # This method returns a Hash of method names of attached functions connected by #attach_function and the corresponding function type. + # The function type responds to #return_type and #param_types which return the FFI types of the function signature. + # + # @return [Hash< Symbol => [FFI::Function, FFI::VariadicInvoker] >] + def attached_functions + @ffi_functions || {} + end + + # Retrieve all attached variables and their type + # + # This method returns a Hash of variable names and the corresponding type or variables connected by #attach_variable . + # + # @return [Hash< Symbol => ffi_type >] + def attached_variables + ( + (defined?(@ffi_gsvars) ? @ffi_gsvars : {}).map do |name, gvar| + [name, gvar.class] + end + + (defined?(@ffi_gvars) ? @ffi_gvars : {}).map do |name, gvar| + [name, gvar.layout[:gvar].type] + end + ).to_h + end + + # Freeze all definitions of the module + # + # This freezes the module's definitions, so that it can be used in a Ractor. + # No further functions or variables can be attached and no further enums or typedefs can be created in this module afterwards. + def freeze + # @ffi_function_procs is only used on aarch64-mingw-ucrt + instance_variable_get("@ffi_function_procs")&.each do |name, func| + # Redefine attached functions as Ractor-shareable. + # The function Proc can't be shareable from the beginning, since it references enums and typedefs. + this = FFI.make_shareable(func) + body = FFI.shareable_proc(self: nil) do |*args, &block| + this.call(*args, &block) + end + undef_method(name) + singleton_class.undef_method(name) + + define_method(name, body) + define_singleton_method(name, body) + end + + instance_variables.each do |name| + var = instance_variable_get(name) + FFI.make_shareable(var) + end + super + nil + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library_path.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library_path.rb new file mode 100644 index 0000000..5575a5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/library_path.rb @@ -0,0 +1,109 @@ +# +# Copyright (C) 2023 Lars Kanis +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +module FFI + # Transform a generic library name and ABI number to a platform library name + # + # Example: + # module LibVips + # extend FFI::Library + # ffi_lib LibraryPath.new("vips", abi_number: 42) + # end + # + # This translates to the following library file names: + # libvips-42.dll on Windows + # libvips.so.42 on Linux + # libvips.42.dylib on Macos + # + # See https://packaging.ubuntu.com/html/libraries.html for more information about library naming. + class LibraryPath + attr_reader :name + attr_reader :abi_number + attr_reader :root + + # Build a new library path + # + # * name : The name of the library without file prefix or suffix. + # * abi_number : The ABI number of the library. + # * root : An optional base path prepended to the library name. + def initialize(name, abi_number: nil, root: nil) + @name = name + @abi_number = abi_number + @root = root + end + + def self.wrap(value) + # We allow instances of LibraryPath to pass through transparently: + return value if value.is_a?(self) + + # We special case a library named 'c' to be the standard C library: + return Library::LIBC if value == 'c' + + # If provided a relative file name we convert it into a library path: + if value && File.basename(value) == value + return self.new(value) + end + + # Otherwise, we assume it's a full path to a library: + return value + end + + def full_name + # If the abi_number is given, we format it specifically according to platform rules: + if abi_number + if Platform.windows? + "#{Platform::LIBPREFIX}#{name}-#{abi_number}.#{Platform::LIBSUFFIX}" + elsif Platform.mac? + "#{Platform::LIBPREFIX}#{name}.#{abi_number}.#{Platform::LIBSUFFIX}" + else # Linux? BSD? etc. + "#{Platform::LIBPREFIX}#{name}.#{Platform::LIBSUFFIX}.#{abi_number}" + end + else + # Otherwise we just add prefix and suffix: + lib = name + # Add library prefix if missing + lib = Platform::LIBPREFIX + lib unless lib =~ /^#{Platform::LIBPREFIX}/ + # Add library extension if missing + r = Platform.windows? || Platform.mac? ? "\\.#{Platform::LIBSUFFIX}$" : "\\.so($|\\.[1234567890]+)" + lib += ".#{Platform::LIBSUFFIX}" unless lib =~ /#{r}/ + lib + end + end + + def to_s + if root + # If the root path is given, we generate the full path: + File.join(root, full_name) + else + full_name + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/managedstruct.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/managedstruct.rb new file mode 100644 index 0000000..5d243e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/managedstruct.rb @@ -0,0 +1,84 @@ +# Copyright (C) 2008 Mike Dalessio +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +module FFI + # + # FFI::ManagedStruct allows custom garbage-collection of your FFI::Structs. + # + # The typical use case would be when interacting with a library + # that has a nontrivial memory management design, such as a linked + # list or a binary tree. + # + # When the {Struct} instance is garbage collected, FFI::ManagedStruct will + # invoke the class's release() method during object finalization. + # + # @example Example usage: + # module MyLibrary + # ffi_lib "libmylibrary" + # attach_function :new_dlist, [], :pointer + # attach_function :destroy_dlist, [:pointer], :void + # end + # + # class DoublyLinkedList < FFI::ManagedStruct + # @@@ + # struct do |s| + # s.name 'struct dlist' + # s.include 'dlist.h' + # s.field :head, :pointer + # s.field :tail, :pointer + # end + # @@@ + # + # def self.release ptr + # MyLibrary.destroy_dlist(ptr) + # end + # end + # + # begin + # ptr = DoublyLinkedList.new(MyLibrary.new_dlist) + # # do something with the list + # end + # # struct is out of scope, and will be GC'd using DoublyLinkedList#release + # + # + class ManagedStruct < FFI::Struct + + # @overload initialize(pointer) + # @param [Pointer] pointer + # Create a new ManagedStruct which will invoke the class method #release on + # @overload initialize + # A new instance of FFI::ManagedStruct. + def initialize(pointer=nil) + raise NoMethodError, "release() not implemented for class #{self}" unless self.class.respond_to?(:release, true) + raise ArgumentError, "Must supply a pointer to memory for the Struct" unless pointer + super AutoPointer.new(pointer, self.class.method(:release)) + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/memorypointer.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/memorypointer.rb new file mode 100644 index 0000000..9f07bc6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/memorypointer.rb @@ -0,0 +1 @@ +# This class is now implemented in C diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform.rb new file mode 100644 index 0000000..5ac4dd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform.rb @@ -0,0 +1,187 @@ +# +# Copyright (C) 2008, 2009 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +require 'rbconfig' +require_relative 'compat' + +module FFI + class PlatformError < LoadError; end + + # This module defines different constants and class methods to play with + # various platforms. + module Platform + OS = FFI.make_shareable(case RbConfig::CONFIG['host_os'].downcase + when /linux/ + "linux" + when /darwin/ + "darwin" + when /freebsd/ + "freebsd" + when /netbsd/ + "netbsd" + when /openbsd/ + "openbsd" + when /dragonfly/ + "dragonflybsd" + when /sunos|solaris/ + "solaris" + when /mingw|mswin/ + "windows" + else + RbConfig::CONFIG['host_os'].downcase + end) + + OSVERSION = RbConfig::CONFIG['host_os'].gsub(/[^\d]/, '').to_i + + CPU = FFI.make_shareable(RbConfig::CONFIG['host_cpu']) + + ARCH = FFI.make_shareable(case CPU.downcase + when /amd64|x86_64|x64/ + "x86_64" + when /i\d86|x86|i86pc/ + "i386" + when /ppc64|powerpc64/ + "powerpc64" + when /ppc|powerpc/ + "powerpc" + when /sparcv9|sparc64/ + "sparcv9" + when /arm64|aarch64/ # MacOS calls it "arm64", other operating systems "aarch64" + "aarch64" + when /^arm/ + if OS == "darwin" # Ruby before 3.0 reports "arm" instead of "arm64" as host_cpu on darwin + "aarch64" + else + "arm" + end + else + RbConfig::CONFIG['host_cpu'] + end) + + private + # @param [String) os + # @return [Boolean] + # Test if current OS is +os+. + def self.is_os(os) + OS == os + end + + IS_GNU = defined?(GNU_LIBC) + IS_LINUX = is_os("linux") + IS_MAC = is_os("darwin") + IS_FREEBSD = is_os("freebsd") + IS_NETBSD = is_os("netbsd") + IS_OPENBSD = is_os("openbsd") + IS_DRAGONFLYBSD = is_os("dragonfly") + IS_SOLARIS = is_os("solaris") + IS_WINDOWS = is_os("windows") + IS_BSD = IS_MAC || IS_FREEBSD || IS_NETBSD || IS_OPENBSD || IS_DRAGONFLYBSD + + # Add the version for known ABI breaks + name_version = "12" if IS_FREEBSD && OSVERSION >= 12 # 64-bit inodes + + NAME = FFI.make_shareable("#{ARCH}-#{OS}#{name_version}") + CONF_DIR = FFI.make_shareable(File.join(File.dirname(__FILE__), 'platform', NAME)) + + public + + LIBPREFIX = FFI.make_shareable(case OS + when /windows|msys/ + '' + when /cygwin/ + 'cyg' + else + 'lib' + end) + + LIBSUFFIX = FFI.make_shareable(case OS + when /darwin/ + 'dylib' + when /linux|bsd|solaris/ + 'so' + when /windows|cygwin|msys/ + 'dll' + else + # Punt and just assume a sane unix (i.e. anything but AIX) + 'so' + end) + + LIBC = FFI.make_shareable(if IS_WINDOWS + crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase' + "#{crtname}.dll" + elsif IS_GNU + GNU_LIBC + elsif OS == 'cygwin' + "cygwin1.dll" + elsif OS == 'msys' + # Not sure how msys 1.0 behaves, tested on MSYS2. + "msys-2.0.dll" + else + "#{LIBPREFIX}c.#{LIBSUFFIX}" + end) + + LITTLE_ENDIAN = 1234 unless defined?(LITTLE_ENDIAN) + BIG_ENDIAN = 4321 unless defined?(BIG_ENDIAN) + unless defined?(BYTE_ORDER) + BYTE_ORDER = [0x12345678].pack("I") == [0x12345678].pack("N") ? BIG_ENDIAN : LITTLE_ENDIAN + end + + # Test if current OS is a *BSD (include MAC) + # @return [Boolean] + def self.bsd? + IS_BSD + end + + # Test if current OS is Windows + # @return [Boolean] + def self.windows? + IS_WINDOWS + end + + # Test if current OS is Mac OS + # @return [Boolean] + def self.mac? + IS_MAC + end + + # Test if current OS is Solaris (Sun OS) + # @return [Boolean] + def self.solaris? + IS_SOLARIS + end + + # Test if current OS is a unix OS + # @return [Boolean] + def self.unix? + !IS_WINDOWS + end + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-darwin/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-darwin/types.conf new file mode 100644 index 0000000..68841bb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-darwin/types.conf @@ -0,0 +1,130 @@ +rbx.platform.typedef.__darwin_blkcnt_t = long_long +rbx.platform.typedef.__darwin_blksize_t = int +rbx.platform.typedef.__darwin_clock_t = ulong +rbx.platform.typedef.__darwin_ct_rune_t = int +rbx.platform.typedef.__darwin_dev_t = int +rbx.platform.typedef.__darwin_fsblkcnt_t = uint +rbx.platform.typedef.__darwin_fsfilcnt_t = uint +rbx.platform.typedef.__darwin_gid_t = uint +rbx.platform.typedef.__darwin_id_t = uint +rbx.platform.typedef.__darwin_ino64_t = ulong_long +rbx.platform.typedef.__darwin_ino_t = ulong_long +rbx.platform.typedef.__darwin_intptr_t = long +rbx.platform.typedef.__darwin_mach_port_name_t = uint +rbx.platform.typedef.__darwin_mach_port_t = uint +rbx.platform.typedef.__darwin_mode_t = ushort +rbx.platform.typedef.__darwin_natural_t = uint +rbx.platform.typedef.__darwin_off_t = long_long +rbx.platform.typedef.__darwin_pid_t = int +rbx.platform.typedef.__darwin_pthread_key_t = ulong +rbx.platform.typedef.__darwin_ptrdiff_t = long +rbx.platform.typedef.__darwin_rune_t = int +rbx.platform.typedef.__darwin_sigset_t = uint +rbx.platform.typedef.__darwin_size_t = ulong +rbx.platform.typedef.__darwin_socklen_t = uint +rbx.platform.typedef.__darwin_ssize_t = long +rbx.platform.typedef.__darwin_suseconds_t = int +rbx.platform.typedef.__darwin_time_t = long +rbx.platform.typedef.__darwin_uid_t = uint +rbx.platform.typedef.__darwin_useconds_t = uint +rbx.platform.typedef.__darwin_uuid_string_t[37] = char +rbx.platform.typedef.__darwin_uuid_t[16] = uchar +rbx.platform.typedef.__darwin_wchar_t = int +rbx.platform.typedef.__darwin_wint_t = int +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.errno_t = int +rbx.platform.typedef.fd_mask = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = uint +rbx.platform.typedef.fsfilcnt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = short +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ushort +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long_long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.rsize_t = ulong +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.sae_associd_t = uint +rbx.platform.typedef.sae_connid_t = uint +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.syscall_arg_t = ulong_long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ushort +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.user_addr_t = ulong_long +rbx.platform.typedef.user_long_t = long_long +rbx.platform.typedef.user_off_t = long_long +rbx.platform.typedef.user_size_t = ulong_long +rbx.platform.typedef.user_ssize_t = long_long +rbx.platform.typedef.user_time_t = long_long +rbx.platform.typedef.user_ulong_t = ulong_long +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd/types.conf new file mode 100644 index 0000000..8d111e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd/types.conf @@ -0,0 +1,128 @@ +rbx.platform.typedef.__clock_t = int +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = int +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = uint +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long_long +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr64_t = long_long +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long_long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = int +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd12/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd12/types.conf new file mode 100644 index 0000000..3ccb8f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-freebsd12/types.conf @@ -0,0 +1,181 @@ +rbx.platform.typedef.*) = pointer +rbx.platform.typedef.___wchar_t = uint +rbx.platform.typedef.__accmode_t = int +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__char16_t = ushort +rbx.platform.typedef.__char32_t = uint +rbx.platform.typedef.__clock_t = int +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpulevel_t = int +rbx.platform.typedef.__cpusetid_t = int +rbx.platform.typedef.__cpuwhich_t = int +rbx.platform.typedef.__critical_t = long +rbx.platform.typedef.__ct_rune_t = int +rbx.platform.typedef.__daddr_t = long +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = ulong +rbx.platform.typedef.__fflags_t = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intfptr_t = long +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__lwpid_t = int +rbx.platform.typedef.__mode_t = ushort +rbx.platform.typedef.__nl_item = int +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long +rbx.platform.typedef.__rlim_t = long +rbx.platform.typedef.__rman_res_t = ulong +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = long +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__u_register_t = ulong +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintfptr_t = ulong +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vm_offset_t = ulong +rbx.platform.typedef.__vm_paddr_t = ulong +rbx.platform.typedef.__vm_size_t = ulong +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.accmode_t = int +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.c_caddr_t = pointer +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.cap_ioctl_t = ulong +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpulevel_t = int +rbx.platform.typedef.cpusetid_t = int +rbx.platform.typedef.cpuwhich_t = int +rbx.platform.typedef.critical_t = long +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = ulong +rbx.platform.typedef.fflags_t = uint +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = int +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.kpaddr_t = ulong +rbx.platform.typedef.ksize_t = ulong +rbx.platform.typedef.kssize_t = long +rbx.platform.typedef.kvaddr_t = ulong +rbx.platform.typedef.lwpid_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off64_t = long +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = long +rbx.platform.typedef.rman_res_t = ulong +rbx.platform.typedef.rsize_t = ulong +rbx.platform.typedef.rune_t = int +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.sbintime_t = long +rbx.platform.typedef.segsz_t = long +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_register_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uint +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vm_offset_t = ulong +rbx.platform.typedef.vm_ooffset_t = ulong +rbx.platform.typedef.vm_paddr_t = ulong +rbx.platform.typedef.vm_pindex_t = ulong +rbx.platform.typedef.vm_size_t = ulong +rbx.platform.typedef.wchar_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-linux/types.conf new file mode 100644 index 0000000..c56206e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-linux/types.conf @@ -0,0 +1,175 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__kernel_caddr_t = string +rbx.platform.typedef.__kernel_clock_t = long +rbx.platform.typedef.__kernel_clockid_t = int +rbx.platform.typedef.__kernel_daddr_t = int +rbx.platform.typedef.__kernel_gid16_t = ushort +rbx.platform.typedef.__kernel_gid32_t = uint +rbx.platform.typedef.__kernel_gid_t = uint +rbx.platform.typedef.__kernel_ino_t = ulong +rbx.platform.typedef.__kernel_ipc_pid_t = int +rbx.platform.typedef.__kernel_key_t = int +rbx.platform.typedef.__kernel_loff_t = long_long +rbx.platform.typedef.__kernel_long_t = long +rbx.platform.typedef.__kernel_mode_t = uint +rbx.platform.typedef.__kernel_mqd_t = int +rbx.platform.typedef.__kernel_off_t = long +rbx.platform.typedef.__kernel_old_dev_t = uint +rbx.platform.typedef.__kernel_old_gid_t = ushort +rbx.platform.typedef.__kernel_old_time_t = long +rbx.platform.typedef.__kernel_old_uid_t = ushort +rbx.platform.typedef.__kernel_pid_t = int +rbx.platform.typedef.__kernel_ptrdiff_t = long +rbx.platform.typedef.__kernel_size_t = ulong +rbx.platform.typedef.__kernel_ssize_t = long +rbx.platform.typedef.__kernel_suseconds_t = long +rbx.platform.typedef.__kernel_time64_t = long_long +rbx.platform.typedef.__kernel_time_t = long +rbx.platform.typedef.__kernel_timer_t = int +rbx.platform.typedef.__kernel_uid16_t = ushort +rbx.platform.typedef.__kernel_uid32_t = uint +rbx.platform.typedef.__kernel_uid_t = uint +rbx.platform.typedef.__kernel_ulong_t = ulong +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds64_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__thrd_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__tss_t = uint +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = long +rbx.platform.typedef.int_fast32_t = long +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ulong +rbx.platform.typedef.uint_fast32_t = ulong +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-openbsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-openbsd/types.conf new file mode 100644 index 0000000..6abc9c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-openbsd/types.conf @@ -0,0 +1,134 @@ +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long_long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = ulong_long +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = long_long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = long_long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.sigset_t = uint +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = long_long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-windows/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-windows/types.conf new file mode 100644 index 0000000..5bdbbde --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/aarch64-windows/types.conf @@ -0,0 +1,52 @@ +rbx.platform.typedef.__time32_t = long +rbx.platform.typedef.__time64_t = long_long +rbx.platform.typedef._dev_t = uint +rbx.platform.typedef._ino_t = ushort +rbx.platform.typedef._mode_t = ushort +rbx.platform.typedef._off64_t = long_long +rbx.platform.typedef._off_t = long +rbx.platform.typedef._pid_t = long_long +rbx.platform.typedef._sigset_t = ulong_long +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.errno_t = int +rbx.platform.typedef.ino_t = ushort +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = short +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = long_long +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.off32_t = long +rbx.platform.typedef.off64_t = long_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = long_long +rbx.platform.typedef.ptrdiff_t = long_long +rbx.platform.typedef.rsize_t = ulong_long +rbx.platform.typedef.size_t = ulong_long +rbx.platform.typedef.ssize_t = long_long +rbx.platform.typedef.time_t = long_long +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ushort +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = ulong_long +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.wchar_t = ushort +rbx.platform.typedef.wctype_t = ushort +rbx.platform.typedef.wint_t = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd/types.conf new file mode 100644 index 0000000..cfbb90f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd/types.conf @@ -0,0 +1,152 @@ + +rbx.platform.typedef.*) = pointer +rbx.platform.typedef.__accmode_t = int +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = uint +rbx.platform.typedef.__clock_t = ulong +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpulevel_t = int +rbx.platform.typedef.__cpumask_t = uint +rbx.platform.typedef.__cpusetid_t = int +rbx.platform.typedef.__cpuwhich_t = int +rbx.platform.typedef.__critical_t = int +rbx.platform.typedef.__ct_rune_t = int +rbx.platform.typedef.__dev_t = uint +rbx.platform.typedef.__fd_mask = ulong +rbx.platform.typedef.__fflags_t = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = long_long +rbx.platform.typedef.__ino_t = uint +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intfptr_t = int +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__lwpid_t = int +rbx.platform.typedef.__mode_t = ushort +rbx.platform.typedef.__nl_item = int +rbx.platform.typedef.__nlink_t = ushort +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__ptrdiff_t = int +rbx.platform.typedef.__register_t = int +rbx.platform.typedef.__rlim_t = long_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = uint +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = int +rbx.platform.typedef.__u_register_t = uint +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintfptr_t = uint +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = uint +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vm_offset_t = uint +rbx.platform.typedef.__vm_ooffset_t = long_long +rbx.platform.typedef.__vm_paddr_t = uint +rbx.platform.typedef.__vm_pindex_t = ulong_long +rbx.platform.typedef.__vm_size_t = uint +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.accmode_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = uint +rbx.platform.typedef.c_caddr_t = pointer +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpulevel_t = int +rbx.platform.typedef.cpumask_t = uint +rbx.platform.typedef.cpusetid_t = int +rbx.platform.typedef.cpuwhich_t = int +rbx.platform.typedef.critical_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.fd_mask = ulong +rbx.platform.typedef.fflags_t = uint +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = long_long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = long +rbx.platform.typedef.lwpid_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ushort +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = long_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_register_t = uint +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vm_offset_t = uint +rbx.platform.typedef.vm_ooffset_t = long_long +rbx.platform.typedef.vm_paddr_t = uint +rbx.platform.typedef.vm_pindex_t = ulong_long +rbx.platform.typedef.vm_size_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd12/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd12/types.conf new file mode 100644 index 0000000..523370d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-freebsd12/types.conf @@ -0,0 +1,152 @@ + +rbx.platform.typedef.*) = pointer +rbx.platform.typedef.__accmode_t = int +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = uint +rbx.platform.typedef.__clock_t = ulong +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpulevel_t = int +rbx.platform.typedef.__cpumask_t = uint +rbx.platform.typedef.__cpusetid_t = int +rbx.platform.typedef.__cpuwhich_t = int +rbx.platform.typedef.__critical_t = int +rbx.platform.typedef.__ct_rune_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = ulong +rbx.platform.typedef.__fflags_t = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = long_long +rbx.platform.typedef.__ino_t = ulong_long +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intfptr_t = int +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__lwpid_t = int +rbx.platform.typedef.__mode_t = ushort +rbx.platform.typedef.__nl_item = int +rbx.platform.typedef.__nlink_t = ulong_long +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__ptrdiff_t = int +rbx.platform.typedef.__register_t = int +rbx.platform.typedef.__rlim_t = long_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = uint +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = int +rbx.platform.typedef.__u_register_t = uint +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintfptr_t = uint +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = uint +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vm_offset_t = uint +rbx.platform.typedef.__vm_ooffset_t = long_long +rbx.platform.typedef.__vm_paddr_t = uint +rbx.platform.typedef.__vm_pindex_t = ulong_long +rbx.platform.typedef.__vm_size_t = uint +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.accmode_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = uint +rbx.platform.typedef.c_caddr_t = pointer +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpulevel_t = int +rbx.platform.typedef.cpumask_t = uint +rbx.platform.typedef.cpusetid_t = int +rbx.platform.typedef.cpuwhich_t = int +rbx.platform.typedef.critical_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = ulong +rbx.platform.typedef.fflags_t = uint +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = long_long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = long +rbx.platform.typedef.lwpid_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ulong_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = long_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_register_t = uint +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vm_offset_t = uint +rbx.platform.typedef.vm_ooffset_t = long_long +rbx.platform.typedef.vm_paddr_t = uint +rbx.platform.typedef.vm_pindex_t = ulong_long +rbx.platform.typedef.vm_size_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-linux/types.conf new file mode 100644 index 0000000..a070d39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/arm-linux/types.conf @@ -0,0 +1,132 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = int +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa1.1-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa1.1-linux/types.conf new file mode 100644 index 0000000..c8a8141 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa1.1-linux/types.conf @@ -0,0 +1,178 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = int +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__kernel_caddr_t = string +rbx.platform.typedef.__kernel_clock_t = long +rbx.platform.typedef.__kernel_clockid_t = int +rbx.platform.typedef.__kernel_daddr_t = int +rbx.platform.typedef.__kernel_gid16_t = ushort +rbx.platform.typedef.__kernel_gid32_t = uint +rbx.platform.typedef.__kernel_gid_t = uint +rbx.platform.typedef.__kernel_ino64_t = ulong_long +rbx.platform.typedef.__kernel_ino_t = ulong +rbx.platform.typedef.__kernel_ipc_pid_t = ushort +rbx.platform.typedef.__kernel_key_t = int +rbx.platform.typedef.__kernel_loff_t = long_long +rbx.platform.typedef.__kernel_long_t = long +rbx.platform.typedef.__kernel_mode_t = ushort +rbx.platform.typedef.__kernel_mqd_t = int +rbx.platform.typedef.__kernel_off64_t = long_long +rbx.platform.typedef.__kernel_off_t = long +rbx.platform.typedef.__kernel_old_dev_t = uint +rbx.platform.typedef.__kernel_old_gid_t = uint +rbx.platform.typedef.__kernel_old_time_t = long +rbx.platform.typedef.__kernel_old_uid_t = uint +rbx.platform.typedef.__kernel_pid_t = int +rbx.platform.typedef.__kernel_ptrdiff_t = int +rbx.platform.typedef.__kernel_size_t = uint +rbx.platform.typedef.__kernel_ssize_t = int +rbx.platform.typedef.__kernel_suseconds_t = long +rbx.platform.typedef.__kernel_time64_t = long_long +rbx.platform.typedef.__kernel_time_t = long +rbx.platform.typedef.__kernel_timer_t = int +rbx.platform.typedef.__kernel_uid16_t = ushort +rbx.platform.typedef.__kernel_uid32_t = uint +rbx.platform.typedef.__kernel_uid_t = uint +rbx.platform.typedef.__kernel_ulong_t = ulong +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds64_t = long_long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__thrd_t = ulong +rbx.platform.typedef.__time64_t = long_long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__tss_t = uint +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = long diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa2.0-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa2.0-linux/types.conf new file mode 100644 index 0000000..c8a8141 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/hppa2.0-linux/types.conf @@ -0,0 +1,178 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = int +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__kernel_caddr_t = string +rbx.platform.typedef.__kernel_clock_t = long +rbx.platform.typedef.__kernel_clockid_t = int +rbx.platform.typedef.__kernel_daddr_t = int +rbx.platform.typedef.__kernel_gid16_t = ushort +rbx.platform.typedef.__kernel_gid32_t = uint +rbx.platform.typedef.__kernel_gid_t = uint +rbx.platform.typedef.__kernel_ino64_t = ulong_long +rbx.platform.typedef.__kernel_ino_t = ulong +rbx.platform.typedef.__kernel_ipc_pid_t = ushort +rbx.platform.typedef.__kernel_key_t = int +rbx.platform.typedef.__kernel_loff_t = long_long +rbx.platform.typedef.__kernel_long_t = long +rbx.platform.typedef.__kernel_mode_t = ushort +rbx.platform.typedef.__kernel_mqd_t = int +rbx.platform.typedef.__kernel_off64_t = long_long +rbx.platform.typedef.__kernel_off_t = long +rbx.platform.typedef.__kernel_old_dev_t = uint +rbx.platform.typedef.__kernel_old_gid_t = uint +rbx.platform.typedef.__kernel_old_time_t = long +rbx.platform.typedef.__kernel_old_uid_t = uint +rbx.platform.typedef.__kernel_pid_t = int +rbx.platform.typedef.__kernel_ptrdiff_t = int +rbx.platform.typedef.__kernel_size_t = uint +rbx.platform.typedef.__kernel_ssize_t = int +rbx.platform.typedef.__kernel_suseconds_t = long +rbx.platform.typedef.__kernel_time64_t = long_long +rbx.platform.typedef.__kernel_time_t = long +rbx.platform.typedef.__kernel_timer_t = int +rbx.platform.typedef.__kernel_uid16_t = ushort +rbx.platform.typedef.__kernel_uid32_t = uint +rbx.platform.typedef.__kernel_uid_t = uint +rbx.platform.typedef.__kernel_ulong_t = ulong +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds64_t = long_long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__thrd_t = ulong +rbx.platform.typedef.__time64_t = long_long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__tss_t = uint +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = long diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-cygwin/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-cygwin/types.conf new file mode 100644 index 0000000..93f6b86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-cygwin/types.conf @@ -0,0 +1,3 @@ +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.ssize_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-darwin/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-darwin/types.conf new file mode 100644 index 0000000..ae100f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-darwin/types.conf @@ -0,0 +1,100 @@ +rbx.platform.typedef.__darwin_blkcnt_t = long_long +rbx.platform.typedef.__darwin_blksize_t = int +rbx.platform.typedef.__darwin_clock_t = ulong +rbx.platform.typedef.__darwin_ct_rune_t = int +rbx.platform.typedef.__darwin_dev_t = int +rbx.platform.typedef.__darwin_fsblkcnt_t = uint +rbx.platform.typedef.__darwin_fsfilcnt_t = uint +rbx.platform.typedef.__darwin_gid_t = uint +rbx.platform.typedef.__darwin_id_t = uint +rbx.platform.typedef.__darwin_ino64_t = ulong_long +rbx.platform.typedef.__darwin_ino_t = ulong_long +rbx.platform.typedef.__darwin_intptr_t = long +rbx.platform.typedef.__darwin_mach_port_name_t = uint +rbx.platform.typedef.__darwin_mach_port_t = uint +rbx.platform.typedef.__darwin_mode_t = ushort +rbx.platform.typedef.__darwin_natural_t = uint +rbx.platform.typedef.__darwin_off_t = long_long +rbx.platform.typedef.__darwin_pid_t = int +rbx.platform.typedef.__darwin_pthread_key_t = ulong +rbx.platform.typedef.__darwin_ptrdiff_t = int +rbx.platform.typedef.__darwin_rune_t = int +rbx.platform.typedef.__darwin_sigset_t = uint +rbx.platform.typedef.__darwin_size_t = ulong +rbx.platform.typedef.__darwin_socklen_t = uint +rbx.platform.typedef.__darwin_ssize_t = long +rbx.platform.typedef.__darwin_suseconds_t = int +rbx.platform.typedef.__darwin_time_t = long +rbx.platform.typedef.__darwin_uid_t = uint +rbx.platform.typedef.__darwin_useconds_t = uint +rbx.platform.typedef.__darwin_uuid_t[16] = uchar +rbx.platform.typedef.__darwin_wchar_t = int +rbx.platform.typedef.__darwin_wint_t = int +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fd_mask = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = uint +rbx.platform.typedef.fsfilcnt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ushort +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.syscall_arg_t = ulong_long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.user_addr_t = ulong_long +rbx.platform.typedef.user_long_t = long_long +rbx.platform.typedef.user_size_t = ulong_long +rbx.platform.typedef.user_ssize_t = long_long +rbx.platform.typedef.user_time_t = long_long +rbx.platform.typedef.user_ulong_t = ulong_long +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd/types.conf new file mode 100644 index 0000000..6c882d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd/types.conf @@ -0,0 +1,152 @@ + +rbx.platform.typedef.*) = pointer +rbx.platform.typedef.__accmode_t = int +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = uint +rbx.platform.typedef.__clock_t = ulong +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpulevel_t = int +rbx.platform.typedef.__cpumask_t = uint +rbx.platform.typedef.__cpusetid_t = int +rbx.platform.typedef.__cpuwhich_t = int +rbx.platform.typedef.__critical_t = int +rbx.platform.typedef.__ct_rune_t = int +rbx.platform.typedef.__dev_t = uint +rbx.platform.typedef.__fd_mask = ulong +rbx.platform.typedef.__fflags_t = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = long_long +rbx.platform.typedef.__ino_t = uint +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intfptr_t = int +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__lwpid_t = int +rbx.platform.typedef.__mode_t = ushort +rbx.platform.typedef.__nl_item = int +rbx.platform.typedef.__nlink_t = ushort +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__ptrdiff_t = int +rbx.platform.typedef.__register_t = int +rbx.platform.typedef.__rlim_t = long_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = uint +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__u_register_t = uint +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintfptr_t = uint +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = uint +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vm_offset_t = uint +rbx.platform.typedef.__vm_ooffset_t = long_long +rbx.platform.typedef.__vm_paddr_t = uint +rbx.platform.typedef.__vm_pindex_t = ulong_long +rbx.platform.typedef.__vm_size_t = uint +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.accmode_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = uint +rbx.platform.typedef.c_caddr_t = pointer +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpulevel_t = int +rbx.platform.typedef.cpumask_t = uint +rbx.platform.typedef.cpusetid_t = int +rbx.platform.typedef.cpuwhich_t = int +rbx.platform.typedef.critical_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.fd_mask = ulong +rbx.platform.typedef.fflags_t = uint +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = long_long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = long +rbx.platform.typedef.lwpid_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ushort +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = long_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_register_t = uint +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vm_offset_t = uint +rbx.platform.typedef.vm_ooffset_t = long_long +rbx.platform.typedef.vm_paddr_t = uint +rbx.platform.typedef.vm_pindex_t = ulong_long +rbx.platform.typedef.vm_size_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd12/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd12/types.conf new file mode 100644 index 0000000..523370d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-freebsd12/types.conf @@ -0,0 +1,152 @@ + +rbx.platform.typedef.*) = pointer +rbx.platform.typedef.__accmode_t = int +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = uint +rbx.platform.typedef.__clock_t = ulong +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpulevel_t = int +rbx.platform.typedef.__cpumask_t = uint +rbx.platform.typedef.__cpusetid_t = int +rbx.platform.typedef.__cpuwhich_t = int +rbx.platform.typedef.__critical_t = int +rbx.platform.typedef.__ct_rune_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = ulong +rbx.platform.typedef.__fflags_t = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = long_long +rbx.platform.typedef.__ino_t = ulong_long +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intfptr_t = int +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__lwpid_t = int +rbx.platform.typedef.__mode_t = ushort +rbx.platform.typedef.__nl_item = int +rbx.platform.typedef.__nlink_t = ulong_long +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__ptrdiff_t = int +rbx.platform.typedef.__register_t = int +rbx.platform.typedef.__rlim_t = long_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = uint +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = int +rbx.platform.typedef.__u_register_t = uint +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintfptr_t = uint +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = uint +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vm_offset_t = uint +rbx.platform.typedef.__vm_ooffset_t = long_long +rbx.platform.typedef.__vm_paddr_t = uint +rbx.platform.typedef.__vm_pindex_t = ulong_long +rbx.platform.typedef.__vm_size_t = uint +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.accmode_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = uint +rbx.platform.typedef.c_caddr_t = pointer +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpulevel_t = int +rbx.platform.typedef.cpumask_t = uint +rbx.platform.typedef.cpusetid_t = int +rbx.platform.typedef.cpuwhich_t = int +rbx.platform.typedef.critical_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = ulong +rbx.platform.typedef.fflags_t = uint +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = long_long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = long +rbx.platform.typedef.lwpid_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ulong_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = long_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_register_t = uint +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vm_offset_t = uint +rbx.platform.typedef.vm_ooffset_t = long_long +rbx.platform.typedef.vm_paddr_t = uint +rbx.platform.typedef.vm_pindex_t = ulong_long +rbx.platform.typedef.vm_size_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-gnu/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-gnu/types.conf new file mode 100644 index 0000000..fa2fa8c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-gnu/types.conf @@ -0,0 +1,107 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = uint +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsid_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__pthread_key = int +rbx.platform.typedef.__pthread_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__sigset_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.fsid_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.pthread_t = int +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.sigset_t = ulong +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-linux/types.conf new file mode 100644 index 0000000..feb6bc4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-linux/types.conf @@ -0,0 +1,103 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-netbsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-netbsd/types.conf new file mode 100644 index 0000000..a5aba89 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-netbsd/types.conf @@ -0,0 +1,126 @@ +rbx.platform.typedef.__clock_t = int +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = int +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = uint +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = int +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = int +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = int +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr64_t = long_long +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = int +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-openbsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-openbsd/types.conf new file mode 100644 index 0000000..15a0d61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-openbsd/types.conf @@ -0,0 +1,128 @@ +rbx.platform.typedef.__clock_t = int +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = int +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = uint +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = int +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = int +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = int +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr64_t = long_long +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = int +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-solaris/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-solaris/types.conf new file mode 100644 index 0000000..22a2414 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-solaris/types.conf @@ -0,0 +1,122 @@ +rbx.platform.typedef.*caddr_t = char +rbx.platform.typedef.blkcnt64_t = long_long +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cnt_t = short +rbx.platform.typedef.cpu_flag_t = ushort +rbx.platform.typedef.ctid_t = long +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.datalink_id_t = uint +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.diskaddr_t = ulong_long +rbx.platform.typedef.disp_lock_t = uchar +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fds_mask = long +rbx.platform.typedef.fsblkcnt64_t = ulong_long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt64_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.hrtime_t = long_long +rbx.platform.typedef.id_t = long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.index_t = short +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.ipaddr_t = uint +rbx.platform.typedef.k_fltset_t = uint +rbx.platform.typedef.key_t = int +rbx.platform.typedef.len_t = ulong_long +rbx.platform.typedef.lgrp_id_t = long +rbx.platform.typedef.lock_t = uchar +rbx.platform.typedef.longlong_t = long_long +rbx.platform.typedef.major_t = ulong +rbx.platform.typedef.minor_t = ulong +rbx.platform.typedef.mode_t = ulong +rbx.platform.typedef.model_t = uint +rbx.platform.typedef.nfds_t = ulong +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.o_dev_t = short +rbx.platform.typedef.o_gid_t = ushort +rbx.platform.typedef.o_ino_t = ushort +rbx.platform.typedef.o_mode_t = ushort +rbx.platform.typedef.o_nlink_t = short +rbx.platform.typedef.o_pid_t = short +rbx.platform.typedef.o_uid_t = ushort +rbx.platform.typedef.off64_t = long_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.offset_t = long_long +rbx.platform.typedef.pad64_t = long_long +rbx.platform.typedef.pfn_t = ulong +rbx.platform.typedef.pgcnt_t = ulong +rbx.platform.typedef.pid_t = long +rbx.platform.typedef.poolid_t = long +rbx.platform.typedef.pri_t = short +rbx.platform.typedef.projid_t = long +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_t = uint +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.rlim64_t = ulong_long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.spgcnt_t = long +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.sysid_t = short +rbx.platform.typedef.t_scalar_t = long +rbx.platform.typedef.t_uscalar_t = ulong +rbx.platform.typedef.taskid_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_longlong_t = ulong_long +rbx.platform.typedef.u_offset_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uchar_t = uchar +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uint_t = uint +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ulong_t = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.upad64_t = ulong_long +rbx.platform.typedef.use_t = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.ushort_t = ushort +rbx.platform.typedef.zoneid_t = long diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-windows/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-windows/types.conf new file mode 100644 index 0000000..a5d0b05 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/i386-windows/types.conf @@ -0,0 +1,52 @@ +rbx.platform.typedef.__time32_t = long +rbx.platform.typedef.__time64_t = long_long +rbx.platform.typedef._dev_t = uint +rbx.platform.typedef._ino_t = ushort +rbx.platform.typedef._mode_t = ushort +rbx.platform.typedef._off64_t = long_long +rbx.platform.typedef._off_t = long +rbx.platform.typedef._pid_t = int +rbx.platform.typedef._sigset_t = ulong +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.errno_t = int +rbx.platform.typedef.ino_t = ushort +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = short +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.off32_t = long +rbx.platform.typedef.off64_t = long_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.rsize_t = uint +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.time_t = long +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ushort +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.wchar_t = ushort +rbx.platform.typedef.wctype_t = ushort +rbx.platform.typedef.wint_t = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/ia64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/ia64-linux/types.conf new file mode 100644 index 0000000..e0eeecc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/ia64-linux/types.conf @@ -0,0 +1,104 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/loongarch64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/loongarch64-linux/types.conf new file mode 100644 index 0000000..aa8716d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/loongarch64-linux/types.conf @@ -0,0 +1,141 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = long +rbx.platform.typedef.int_fast32_t = long +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ulong +rbx.platform.typedef.uint_fast32_t = ulong +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips-linux/types.conf new file mode 100644 index 0000000..24e8202 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64-linux/types.conf new file mode 100644 index 0000000..b61f4f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64-linux/types.conf @@ -0,0 +1,104 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64el-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64el-linux/types.conf new file mode 100644 index 0000000..b61f4f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mips64el-linux/types.conf @@ -0,0 +1,104 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsel-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsel-linux/types.conf new file mode 100644 index 0000000..24e8202 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsel-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6-linux/types.conf new file mode 100644 index 0000000..24e8202 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6el-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6el-linux/types.conf new file mode 100644 index 0000000..24e8202 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa32r6el-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6-linux/types.conf new file mode 100644 index 0000000..b61f4f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6-linux/types.conf @@ -0,0 +1,104 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6el-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6el-linux/types.conf new file mode 100644 index 0000000..b61f4f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/mipsisa64r6el-linux/types.conf @@ -0,0 +1,104 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-aix/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-aix/types.conf new file mode 100644 index 0000000..cbd20e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-aix/types.conf @@ -0,0 +1,180 @@ +rbx.platform.typedef.UTF32Char = uint +rbx.platform.typedef.UniChar = ushort +rbx.platform.typedef.__cptr32 = string +rbx.platform.typedef.__cptr64 = ulong_long +rbx.platform.typedef.__long32_t = long +rbx.platform.typedef.__long64_t = int +rbx.platform.typedef.__ptr32 = pointer +rbx.platform.typedef.__ptr64 = ulong_long +rbx.platform.typedef.__ulong32_t = ulong +rbx.platform.typedef.__ulong64_t = uint +rbx.platform.typedef.aptx_t = ushort +rbx.platform.typedef.blkcnt32_t = int +rbx.platform.typedef.blkcnt64_t = ulong_long +rbx.platform.typedef.blkcnt_t = int +rbx.platform.typedef.blksize32_t = int +rbx.platform.typedef.blksize64_t = ulong_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.boolean_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.chan_t = int +rbx.platform.typedef.class_id_t = uint +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = long_long +rbx.platform.typedef.cnt64_t = long_long +rbx.platform.typedef.cnt_t = short +rbx.platform.typedef.crid_t = int +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr64_t = long_long +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev32_t = uint +rbx.platform.typedef.dev64_t = ulong_long +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.esid_t = uint +rbx.platform.typedef.ext_t = int +rbx.platform.typedef.fpos64_t = long_long +rbx.platform.typedef.fpos_t = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino32_t = uint +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16 = short +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32 = int +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int32long64_t = int +rbx.platform.typedef.int64 = long_long +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8 = char +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = short +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intfast_t = int +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.krpn_t = int +rbx.platform.typedef.kvmhandle_t = ulong +rbx.platform.typedef.kvmid_t = long +rbx.platform.typedef.kvpn_t = int +rbx.platform.typedef.level_t = int +rbx.platform.typedef.liobn_t = uint +rbx.platform.typedef.long32int64_t = long +rbx.platform.typedef.longlong_t = long_long +rbx.platform.typedef.mid_t = pointer +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.mtyp_t = long +rbx.platform.typedef.nlink_t = short +rbx.platform.typedef.off64_t = long_long +rbx.platform.typedef.off_t = long +rbx.platform.typedef.offset_t = long_long +rbx.platform.typedef.paddr_t = long +rbx.platform.typedef.pdtx_t = int +rbx.platform.typedef.pid32_t = int +rbx.platform.typedef.pid64_t = ulong_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pshift_t = ushort +rbx.platform.typedef.psize_t = long_long +rbx.platform.typedef.psx_t = short +rbx.platform.typedef.ptex_t = ulong +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_t = uint +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.rlim64_t = ulong_long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.rpn64_t = long_long +rbx.platform.typedef.rpn_t = int +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.signal_t = int +rbx.platform.typedef.size64_t = ulong_long +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.slab_t[12] = char +rbx.platform.typedef.snidx_t = int +rbx.platform.typedef.socklen_t = ulong +rbx.platform.typedef.soff_t = int +rbx.platform.typedef.sshift_t = ushort +rbx.platform.typedef.ssize64_t = long_long +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.swhatx_t = ulong +rbx.platform.typedef.tid32_t = int +rbx.platform.typedef.tid64_t = ulong_long +rbx.platform.typedef.tid_t = int +rbx.platform.typedef.time32_t = int +rbx.platform.typedef.time64_t = long_long +rbx.platform.typedef.time_t = int +rbx.platform.typedef.timer32_t = int +rbx.platform.typedef.timer64_t = long_long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16 = ushort +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32 = uint +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64 = ulong_long +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8 = uchar +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_longlong_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uchar = uchar +rbx.platform.typedef.uchar_t = uchar +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint32long64_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ushort +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uint_t = uint +rbx.platform.typedef.uintfast_t = uint +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ulong32int64_t = ulong +rbx.platform.typedef.ulong_t = ulong +rbx.platform.typedef.unidx_t = int +rbx.platform.typedef.unit_addr_t = ulong_long +rbx.platform.typedef.ureg_t = ulong +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.ushort_t = ushort +rbx.platform.typedef.va_list = string +rbx.platform.typedef.vmfkey_t = uint +rbx.platform.typedef.vmhandle32_t = uint +rbx.platform.typedef.vmhandle_t = ulong +rbx.platform.typedef.vmhwkey_t = int +rbx.platform.typedef.vmid32_t = int +rbx.platform.typedef.vmid64_t = long_long +rbx.platform.typedef.vmid_t = long +rbx.platform.typedef.vmidx_t = int +rbx.platform.typedef.vmkey_t = int +rbx.platform.typedef.vmlpghandle_t = ulong +rbx.platform.typedef.vmm_lock_t = int +rbx.platform.typedef.vmnodeidx_t = int +rbx.platform.typedef.vmprkey_t = uint +rbx.platform.typedef.vmsize_t = int +rbx.platform.typedef.vpn_t = int +rbx.platform.typedef.wchar_t = ushort +rbx.platform.typedef.wctype_t = uint +rbx.platform.typedef.wint_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-darwin/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-darwin/types.conf new file mode 100644 index 0000000..ae100f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-darwin/types.conf @@ -0,0 +1,100 @@ +rbx.platform.typedef.__darwin_blkcnt_t = long_long +rbx.platform.typedef.__darwin_blksize_t = int +rbx.platform.typedef.__darwin_clock_t = ulong +rbx.platform.typedef.__darwin_ct_rune_t = int +rbx.platform.typedef.__darwin_dev_t = int +rbx.platform.typedef.__darwin_fsblkcnt_t = uint +rbx.platform.typedef.__darwin_fsfilcnt_t = uint +rbx.platform.typedef.__darwin_gid_t = uint +rbx.platform.typedef.__darwin_id_t = uint +rbx.platform.typedef.__darwin_ino64_t = ulong_long +rbx.platform.typedef.__darwin_ino_t = ulong_long +rbx.platform.typedef.__darwin_intptr_t = long +rbx.platform.typedef.__darwin_mach_port_name_t = uint +rbx.platform.typedef.__darwin_mach_port_t = uint +rbx.platform.typedef.__darwin_mode_t = ushort +rbx.platform.typedef.__darwin_natural_t = uint +rbx.platform.typedef.__darwin_off_t = long_long +rbx.platform.typedef.__darwin_pid_t = int +rbx.platform.typedef.__darwin_pthread_key_t = ulong +rbx.platform.typedef.__darwin_ptrdiff_t = int +rbx.platform.typedef.__darwin_rune_t = int +rbx.platform.typedef.__darwin_sigset_t = uint +rbx.platform.typedef.__darwin_size_t = ulong +rbx.platform.typedef.__darwin_socklen_t = uint +rbx.platform.typedef.__darwin_ssize_t = long +rbx.platform.typedef.__darwin_suseconds_t = int +rbx.platform.typedef.__darwin_time_t = long +rbx.platform.typedef.__darwin_uid_t = uint +rbx.platform.typedef.__darwin_useconds_t = uint +rbx.platform.typedef.__darwin_uuid_t[16] = uchar +rbx.platform.typedef.__darwin_wchar_t = int +rbx.platform.typedef.__darwin_wint_t = int +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fd_mask = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = uint +rbx.platform.typedef.fsfilcnt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ushort +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.syscall_arg_t = ulong_long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.user_addr_t = ulong_long +rbx.platform.typedef.user_long_t = long_long +rbx.platform.typedef.user_size_t = ulong_long +rbx.platform.typedef.user_ssize_t = long_long +rbx.platform.typedef.user_time_t = long_long +rbx.platform.typedef.user_ulong_t = ulong_long +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-linux/types.conf new file mode 100644 index 0000000..42eec13 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-linux/types.conf @@ -0,0 +1,130 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = int +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = long diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-openbsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-openbsd/types.conf new file mode 100644 index 0000000..aea7955 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc-openbsd/types.conf @@ -0,0 +1,156 @@ +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long_long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = ulong_long +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = long_long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = long_long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = int +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.sigset_t = uint +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = long_long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uint +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong +rbx.platform.typedef.wchar_t = int +rbx.platform.typedef.wint_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64-linux/types.conf new file mode 100644 index 0000000..b61f4f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64-linux/types.conf @@ -0,0 +1,104 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64le-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64le-linux/types.conf new file mode 100644 index 0000000..9ac9c2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/powerpc64le-linux/types.conf @@ -0,0 +1,100 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/riscv64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/riscv64-linux/types.conf new file mode 100644 index 0000000..ede0f98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/riscv64-linux/types.conf @@ -0,0 +1,104 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390-linux/types.conf new file mode 100644 index 0000000..291b032 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390x-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390x-linux/types.conf new file mode 100644 index 0000000..32a7feb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/s390x-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-linux/types.conf new file mode 100644 index 0000000..aea09d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long_long +rbx.platform.typedef.__blkcnt64_t = long_long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong_long +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong_long +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong_long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = int +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long_long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long_long +rbx.platform.typedef.__rlim64_t = ulong_long +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = int +rbx.platform.typedef.__suseconds_t = int +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong_long +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong_long +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-solaris/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-solaris/types.conf new file mode 100644 index 0000000..a1548e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparc-solaris/types.conf @@ -0,0 +1,128 @@ +rbx.platform.typedef.() = pointer +rbx.platform.typedef.*caddr_t = char +rbx.platform.typedef.Psocklen_t = pointer +rbx.platform.typedef.avl_index_t = uint +rbx.platform.typedef.blkcnt64_t = long_long +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cnt_t = short +rbx.platform.typedef.cpu_flag_t = ushort +rbx.platform.typedef.ctid_t = long +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.diskaddr_t = ulong_long +rbx.platform.typedef.disp_lock_t = uchar +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fds_mask = long +rbx.platform.typedef.fsblkcnt64_t = ulong_long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt64_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = long +rbx.platform.typedef.hrtime_t = long_long +rbx.platform.typedef.id_t = long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.index_t = short +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int) = pointer +rbx.platform.typedef.int) = pointer +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.ipaddr_t = uint +rbx.platform.typedef.k_fltset_t = uint +rbx.platform.typedef.key_t = int +rbx.platform.typedef.kid_t = int +rbx.platform.typedef.len_t = ulong_long +rbx.platform.typedef.lock_t = uchar +rbx.platform.typedef.longlong_t = long_long +rbx.platform.typedef.major_t = ulong +rbx.platform.typedef.minor_t = ulong +rbx.platform.typedef.mode_t = ulong +rbx.platform.typedef.model_t = uint +rbx.platform.typedef.nfds_t = ulong +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.o_dev_t = short +rbx.platform.typedef.o_gid_t = ushort +rbx.platform.typedef.o_ino_t = ushort +rbx.platform.typedef.o_mode_t = ushort +rbx.platform.typedef.o_nlink_t = short +rbx.platform.typedef.o_pid_t = short +rbx.platform.typedef.o_uid_t = ushort +rbx.platform.typedef.off64_t = long_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.offset_t = long_long +rbx.platform.typedef.pad64_t = long_long +rbx.platform.typedef.pfn_t = ulong +rbx.platform.typedef.pgcnt_t = ulong +rbx.platform.typedef.pid_t = long +rbx.platform.typedef.poolid_t = long +rbx.platform.typedef.pri_t = short +rbx.platform.typedef.projid_t = long +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_t = uint +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.rlim64_t = ulong_long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.size_t) = pointer +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.spgcnt_t = long +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.sysid_t = short +rbx.platform.typedef.t_scalar_t = long +rbx.platform.typedef.t_uscalar_t = ulong +rbx.platform.typedef.taskid_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.ts_t = long_long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_longlong_t = ulong_long +rbx.platform.typedef.u_offset_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uchar_t = uchar +rbx.platform.typedef.uid_t = long +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uint_t = uint +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ulong_t = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.upad64_t = ulong_long +rbx.platform.typedef.use_t = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.ushort_t = ushort +rbx.platform.typedef.zoneid_t = long diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-linux/types.conf new file mode 100644 index 0000000..7626bfc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-linux/types.conf @@ -0,0 +1,102 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.*__qaddr_t = long +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = int +rbx.platform.typedef.__swblk_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-openbsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-openbsd/types.conf new file mode 100644 index 0000000..aea7955 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-openbsd/types.conf @@ -0,0 +1,156 @@ +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long_long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = ulong_long +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = long_long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = long_long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = int +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.sigset_t = uint +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = long_long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uint +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong +rbx.platform.typedef.wchar_t = int +rbx.platform.typedef.wint_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-solaris/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-solaris/types.conf new file mode 100644 index 0000000..a1548e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sparcv9-solaris/types.conf @@ -0,0 +1,128 @@ +rbx.platform.typedef.() = pointer +rbx.platform.typedef.*caddr_t = char +rbx.platform.typedef.Psocklen_t = pointer +rbx.platform.typedef.avl_index_t = uint +rbx.platform.typedef.blkcnt64_t = long_long +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cnt_t = short +rbx.platform.typedef.cpu_flag_t = ushort +rbx.platform.typedef.ctid_t = long +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.diskaddr_t = ulong_long +rbx.platform.typedef.disp_lock_t = uchar +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fds_mask = long +rbx.platform.typedef.fsblkcnt64_t = ulong_long +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt64_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = long +rbx.platform.typedef.hrtime_t = long_long +rbx.platform.typedef.id_t = long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.index_t = short +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int) = pointer +rbx.platform.typedef.int) = pointer +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = int +rbx.platform.typedef.ipaddr_t = uint +rbx.platform.typedef.k_fltset_t = uint +rbx.platform.typedef.key_t = int +rbx.platform.typedef.kid_t = int +rbx.platform.typedef.len_t = ulong_long +rbx.platform.typedef.lock_t = uchar +rbx.platform.typedef.longlong_t = long_long +rbx.platform.typedef.major_t = ulong +rbx.platform.typedef.minor_t = ulong +rbx.platform.typedef.mode_t = ulong +rbx.platform.typedef.model_t = uint +rbx.platform.typedef.nfds_t = ulong +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.o_dev_t = short +rbx.platform.typedef.o_gid_t = ushort +rbx.platform.typedef.o_ino_t = ushort +rbx.platform.typedef.o_mode_t = ushort +rbx.platform.typedef.o_nlink_t = short +rbx.platform.typedef.o_pid_t = short +rbx.platform.typedef.o_uid_t = ushort +rbx.platform.typedef.off64_t = long_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.offset_t = long_long +rbx.platform.typedef.pad64_t = long_long +rbx.platform.typedef.pfn_t = ulong +rbx.platform.typedef.pgcnt_t = ulong +rbx.platform.typedef.pid_t = long +rbx.platform.typedef.poolid_t = long +rbx.platform.typedef.pri_t = short +rbx.platform.typedef.projid_t = long +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_t = uint +rbx.platform.typedef.ptrdiff_t = int +rbx.platform.typedef.rlim64_t = ulong_long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = uint +rbx.platform.typedef.size_t) = pointer +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.spgcnt_t = long +rbx.platform.typedef.ssize_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.sysid_t = short +rbx.platform.typedef.t_scalar_t = long +rbx.platform.typedef.t_uscalar_t = ulong +rbx.platform.typedef.taskid_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.ts_t = long_long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_longlong_t = ulong_long +rbx.platform.typedef.u_offset_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uchar_t = uchar +rbx.platform.typedef.uid_t = long +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uint_t = uint +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = uint +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ulong_t = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.upad64_t = ulong_long +rbx.platform.typedef.use_t = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.ushort_t = ushort +rbx.platform.typedef.zoneid_t = long diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sw_64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sw_64-linux/types.conf new file mode 100644 index 0000000..aa8716d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/sw_64-linux/types.conf @@ -0,0 +1,141 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = long +rbx.platform.typedef.int_fast32_t = long +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ulong +rbx.platform.typedef.uint_fast32_t = ulong +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-cygwin/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-cygwin/types.conf new file mode 100644 index 0000000..5bef6d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-cygwin/types.conf @@ -0,0 +1,3 @@ +rbx.platform.typedef.ptrdiff_t = int64 +rbx.platform.typedef.size_t = uint64 +rbx.platform.typedef.ssize_t = int64 diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-darwin/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-darwin/types.conf new file mode 100644 index 0000000..68841bb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-darwin/types.conf @@ -0,0 +1,130 @@ +rbx.platform.typedef.__darwin_blkcnt_t = long_long +rbx.platform.typedef.__darwin_blksize_t = int +rbx.platform.typedef.__darwin_clock_t = ulong +rbx.platform.typedef.__darwin_ct_rune_t = int +rbx.platform.typedef.__darwin_dev_t = int +rbx.platform.typedef.__darwin_fsblkcnt_t = uint +rbx.platform.typedef.__darwin_fsfilcnt_t = uint +rbx.platform.typedef.__darwin_gid_t = uint +rbx.platform.typedef.__darwin_id_t = uint +rbx.platform.typedef.__darwin_ino64_t = ulong_long +rbx.platform.typedef.__darwin_ino_t = ulong_long +rbx.platform.typedef.__darwin_intptr_t = long +rbx.platform.typedef.__darwin_mach_port_name_t = uint +rbx.platform.typedef.__darwin_mach_port_t = uint +rbx.platform.typedef.__darwin_mode_t = ushort +rbx.platform.typedef.__darwin_natural_t = uint +rbx.platform.typedef.__darwin_off_t = long_long +rbx.platform.typedef.__darwin_pid_t = int +rbx.platform.typedef.__darwin_pthread_key_t = ulong +rbx.platform.typedef.__darwin_ptrdiff_t = long +rbx.platform.typedef.__darwin_rune_t = int +rbx.platform.typedef.__darwin_sigset_t = uint +rbx.platform.typedef.__darwin_size_t = ulong +rbx.platform.typedef.__darwin_socklen_t = uint +rbx.platform.typedef.__darwin_ssize_t = long +rbx.platform.typedef.__darwin_suseconds_t = int +rbx.platform.typedef.__darwin_time_t = long +rbx.platform.typedef.__darwin_uid_t = uint +rbx.platform.typedef.__darwin_useconds_t = uint +rbx.platform.typedef.__darwin_uuid_string_t[37] = char +rbx.platform.typedef.__darwin_uuid_t[16] = uchar +rbx.platform.typedef.__darwin_wchar_t = int +rbx.platform.typedef.__darwin_wint_t = int +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.errno_t = int +rbx.platform.typedef.fd_mask = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = uint +rbx.platform.typedef.fsfilcnt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino64_t = ulong_long +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = short +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ushort +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long_long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.rsize_t = ulong +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.sae_associd_t = uint +rbx.platform.typedef.sae_connid_t = uint +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.syscall_arg_t = ulong_long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ushort +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.user_addr_t = ulong_long +rbx.platform.typedef.user_long_t = long_long +rbx.platform.typedef.user_off_t = long_long +rbx.platform.typedef.user_size_t = ulong_long +rbx.platform.typedef.user_ssize_t = long_long +rbx.platform.typedef.user_time_t = long_long +rbx.platform.typedef.user_ulong_t = ulong_long +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-dragonflybsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-dragonflybsd/types.conf new file mode 100644 index 0000000..889f6a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-dragonflybsd/types.conf @@ -0,0 +1,130 @@ +rbx.platform.typedef.*) = pointer +rbx.platform.typedef.___wchar_t = int +rbx.platform.typedef.__clock_t = ulong +rbx.platform.typedef.__clockid_t = ulong +rbx.platform.typedef.__fd_mask = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intlp_t = long +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long +rbx.platform.typedef.__rlim_t = long +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintlp_t = ulong +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.c_caddr_t = pointer +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.clockid_t = ulong +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = int +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.lwpid_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = long +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_daddr_t = uint +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uint +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.v_caddr_t = pointer +rbx.platform.typedef.wchar_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd/types.conf new file mode 100644 index 0000000..8dbe370 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd/types.conf @@ -0,0 +1,128 @@ +rbx.platform.typedef.__clock_t = int +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = int +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = uint +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long_long +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr64_t = long_long +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long_long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd12/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd12/types.conf new file mode 100644 index 0000000..31b1073 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-freebsd12/types.conf @@ -0,0 +1,158 @@ +rbx.platform.typedef.*) = pointer +rbx.platform.typedef.___wchar_t = int +rbx.platform.typedef.__accmode_t = int +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__char16_t = ushort +rbx.platform.typedef.__char32_t = uint +rbx.platform.typedef.__clock_t = int +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpulevel_t = int +rbx.platform.typedef.__cpusetid_t = int +rbx.platform.typedef.__cpuwhich_t = int +rbx.platform.typedef.__critical_t = long +rbx.platform.typedef.__ct_rune_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = ulong +rbx.platform.typedef.__fflags_t = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = long +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intfptr_t = long +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__lwpid_t = int +rbx.platform.typedef.__mode_t = ushort +rbx.platform.typedef.__nl_item = int +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long +rbx.platform.typedef.__rlim_t = long +rbx.platform.typedef.__rman_res_t = ulong +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = long +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__u_register_t = ulong +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintfptr_t = ulong +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vm_offset_t = ulong +rbx.platform.typedef.__vm_paddr_t = ulong +rbx.platform.typedef.__vm_size_t = ulong +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.accmode_t = int +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.c_caddr_t = pointer +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.cap_ioctl_t = ulong +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpulevel_t = int +rbx.platform.typedef.cpusetid_t = int +rbx.platform.typedef.cpuwhich_t = int +rbx.platform.typedef.critical_t = long +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = ulong +rbx.platform.typedef.fflags_t = uint +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = long +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.ksize_t = ulong +rbx.platform.typedef.kvaddr_t = ulong +rbx.platform.typedef.lwpid_t = int +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off64_t = long +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = long +rbx.platform.typedef.rman_res_t = ulong +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.sbintime_t = long +rbx.platform.typedef.segsz_t = long +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_register_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vm_offset_t = ulong +rbx.platform.typedef.vm_ooffset_t = long +rbx.platform.typedef.vm_paddr_t = ulong +rbx.platform.typedef.vm_pindex_t = ulong +rbx.platform.typedef.vm_size_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-haiku/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-haiku/types.conf new file mode 100644 index 0000000..d5ddfa7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-haiku/types.conf @@ -0,0 +1,117 @@ +rbx.platform.typedef.__haiku_addr_t = ulong +rbx.platform.typedef.__haiku_generic_addr_t = ulong +rbx.platform.typedef.__haiku_int16 = short +rbx.platform.typedef.__haiku_int32 = int +rbx.platform.typedef.__haiku_int64 = long +rbx.platform.typedef.__haiku_int8 = char +rbx.platform.typedef.__haiku_phys_addr_t = ulong +rbx.platform.typedef.__haiku_phys_saddr_t = long +rbx.platform.typedef.__haiku_saddr_t = long +rbx.platform.typedef.__haiku_std_int16 = short +rbx.platform.typedef.__haiku_std_int32 = int +rbx.platform.typedef.__haiku_std_int64 = long +rbx.platform.typedef.__haiku_std_int8 = char +rbx.platform.typedef.__haiku_std_uint16 = ushort +rbx.platform.typedef.__haiku_std_uint32 = uint +rbx.platform.typedef.__haiku_std_uint64 = ulong +rbx.platform.typedef.__haiku_std_uint8 = uchar +rbx.platform.typedef.__haiku_uint16 = ushort +rbx.platform.typedef.__haiku_uint32 = uint +rbx.platform.typedef.__haiku_uint64 = ulong +rbx.platform.typedef.__haiku_uint8 = uchar +rbx.platform.typedef.addr_t = ulong +rbx.platform.typedef.bigtime_t = long +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = pointer +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cnt_t = int +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fd_mask = uint +rbx.platform.typedef.fsblkcnt_t = long +rbx.platform.typedef.fsfilcnt_t = long +rbx.platform.typedef.generic_addr_t = ulong +rbx.platform.typedef.generic_size_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = int +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = long +rbx.platform.typedef.int16 = short +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32 = int +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64 = long +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8 = char +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = int +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nanotime_t = long +rbx.platform.typedef.nlink_t = int +rbx.platform.typedef.off_t = long +rbx.platform.typedef.perform_code = uint +rbx.platform.typedef.phys_addr_t = ulong +rbx.platform.typedef.phys_size_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = int +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.sig_atomic_t = int +rbx.platform.typedef.sigset_t = ulong +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.status_t = int +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.time_t = long +rbx.platform.typedef.type_code = uint +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uchar = uchar +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16 = ushort +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32 = uint +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64 = ulong +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8 = uchar +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uint +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.umode_t = uint +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.unichar = ushort +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.void*) = pointer +rbx.platform.typedef.wchar_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-linux/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-linux/types.conf new file mode 100644 index 0000000..060f161 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-linux/types.conf @@ -0,0 +1,132 @@ +rbx.platform.typedef.*__caddr_t = char +rbx.platform.typedef.__blkcnt64_t = long +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = long +rbx.platform.typedef.__clock_t = long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__daddr_t = int +rbx.platform.typedef.__dev_t = ulong +rbx.platform.typedef.__fd_mask = long +rbx.platform.typedef.__fsblkcnt64_t = ulong +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt64_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__fsword_t = long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino64_t = ulong +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = int +rbx.platform.typedef.__loff_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = ulong +rbx.platform.typedef.__off64_t = long +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__priority_which_t = int +rbx.platform.typedef.__quad_t = long +rbx.platform.typedef.__rlim64_t = ulong +rbx.platform.typedef.__rlim_t = ulong +rbx.platform.typedef.__rlimit_resource_t = int +rbx.platform.typedef.__rusage_who_t = int +rbx.platform.typedef.__sig_atomic_t = int +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__syscall_slong_t = long +rbx.platform.typedef.__syscall_ulong_t = ulong +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = pointer +rbx.platform.typedef.__u_char = uchar +rbx.platform.typedef.__u_int = uint +rbx.platform.typedef.__u_long = ulong +rbx.platform.typedef.__u_quad_t = ulong +rbx.platform.typedef.__u_short = ushort +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = long +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = long +rbx.platform.typedef.int_fast32_t = long +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = int +rbx.platform.typedef.loff_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ulong +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_once_t = int +rbx.platform.typedef.pthread_t = ulong +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.quad_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = pointer +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ulong +rbx.platform.typedef.uint_fast32_t = ulong +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.wchar_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-msys/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-msys/types.conf new file mode 100644 index 0000000..aa827c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-msys/types.conf @@ -0,0 +1,119 @@ +rbx.platform.typedef.*addr_t = char +rbx.platform.typedef.__ULong = uint +rbx.platform.typedef.__blkcnt_t = long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = ulong +rbx.platform.typedef.__clockid_t = ulong +rbx.platform.typedef.__cpu_mask = ulong +rbx.platform.typedef.__dev_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong +rbx.platform.typedef.__fsfilcnt_t = ulong +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__ino_t = ulong +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long_long +rbx.platform.typedef.__loff_t = long_long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nl_item = int +rbx.platform.typedef.__nlink_t = ushort +rbx.platform.typedef.__off_t = long +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__sigset_t = ulong +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = int +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__time_t = long +rbx.platform.typedef.__timer_t = ulong +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = ulong +rbx.platform.typedef._fpos64_t = long_long +rbx.platform.typedef._fpos_t = long +rbx.platform.typedef._off64_t = long_long +rbx.platform.typedef._off_t = long +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = ulong +rbx.platform.typedef.clockid_t = ulong +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.fd_mask = ulong +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = long +rbx.platform.typedef.int_fast32_t = long +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long_long +rbx.platform.typedef.loff_t = long_long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = ushort +rbx.platform.typedef.off_t = long +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sbintime_t = long +rbx.platform.typedef.sig_atomic_t = int +rbx.platform.typedef.sigset_t = ulong +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = int +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = ulong +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_register_t = ulong +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ulong +rbx.platform.typedef.uint_fast32_t = ulong +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.useconds_t = ulong +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vm_offset_t = ulong +rbx.platform.typedef.vm_size_t = ulong +rbx.platform.typedef.wint_t = uint diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-netbsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-netbsd/types.conf new file mode 100644 index 0000000..15a0d61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-netbsd/types.conf @@ -0,0 +1,128 @@ +rbx.platform.typedef.__clock_t = int +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = int +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = uint +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = int +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = int +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = int +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = int +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr64_t = long_long +rbx.platform.typedef.daddr_t = int +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = uint +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = int +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = int +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = int +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-openbsd/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-openbsd/types.conf new file mode 100644 index 0000000..6abc9c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-openbsd/types.conf @@ -0,0 +1,134 @@ +rbx.platform.typedef.__blkcnt_t = long_long +rbx.platform.typedef.__blksize_t = int +rbx.platform.typedef.__clock_t = long_long +rbx.platform.typedef.__clockid_t = int +rbx.platform.typedef.__cpuid_t = ulong +rbx.platform.typedef.__dev_t = int +rbx.platform.typedef.__fd_mask = uint +rbx.platform.typedef.__fixpt_t = uint +rbx.platform.typedef.__fsblkcnt_t = ulong_long +rbx.platform.typedef.__fsfilcnt_t = ulong_long +rbx.platform.typedef.__gid_t = uint +rbx.platform.typedef.__id_t = uint +rbx.platform.typedef.__in_addr_t = uint +rbx.platform.typedef.__in_port_t = ushort +rbx.platform.typedef.__ino_t = ulong_long +rbx.platform.typedef.__int16_t = short +rbx.platform.typedef.__int32_t = int +rbx.platform.typedef.__int64_t = long_long +rbx.platform.typedef.__int8_t = char +rbx.platform.typedef.__int_fast16_t = int +rbx.platform.typedef.__int_fast32_t = int +rbx.platform.typedef.__int_fast64_t = long_long +rbx.platform.typedef.__int_fast8_t = int +rbx.platform.typedef.__int_least16_t = short +rbx.platform.typedef.__int_least32_t = int +rbx.platform.typedef.__int_least64_t = long_long +rbx.platform.typedef.__int_least8_t = char +rbx.platform.typedef.__intmax_t = long_long +rbx.platform.typedef.__intptr_t = long +rbx.platform.typedef.__key_t = long +rbx.platform.typedef.__mode_t = uint +rbx.platform.typedef.__nlink_t = uint +rbx.platform.typedef.__off_t = long_long +rbx.platform.typedef.__paddr_t = ulong +rbx.platform.typedef.__pid_t = int +rbx.platform.typedef.__psize_t = ulong +rbx.platform.typedef.__ptrdiff_t = long +rbx.platform.typedef.__register_t = long +rbx.platform.typedef.__rlim_t = ulong_long +rbx.platform.typedef.__rune_t = int +rbx.platform.typedef.__sa_family_t = uchar +rbx.platform.typedef.__segsz_t = int +rbx.platform.typedef.__size_t = ulong +rbx.platform.typedef.__socklen_t = uint +rbx.platform.typedef.__ssize_t = long +rbx.platform.typedef.__suseconds_t = long +rbx.platform.typedef.__swblk_t = int +rbx.platform.typedef.__time_t = long_long +rbx.platform.typedef.__timer_t = int +rbx.platform.typedef.__uid_t = uint +rbx.platform.typedef.__uint16_t = ushort +rbx.platform.typedef.__uint32_t = uint +rbx.platform.typedef.__uint64_t = ulong_long +rbx.platform.typedef.__uint8_t = uchar +rbx.platform.typedef.__uint_fast16_t = uint +rbx.platform.typedef.__uint_fast32_t = uint +rbx.platform.typedef.__uint_fast64_t = ulong_long +rbx.platform.typedef.__uint_fast8_t = uint +rbx.platform.typedef.__uint_least16_t = ushort +rbx.platform.typedef.__uint_least32_t = uint +rbx.platform.typedef.__uint_least64_t = ulong_long +rbx.platform.typedef.__uint_least8_t = uchar +rbx.platform.typedef.__uintmax_t = ulong_long +rbx.platform.typedef.__uintptr_t = ulong +rbx.platform.typedef.__useconds_t = uint +rbx.platform.typedef.__vaddr_t = ulong +rbx.platform.typedef.__vsize_t = ulong +rbx.platform.typedef.__wchar_t = int +rbx.platform.typedef.__wctrans_t = pointer +rbx.platform.typedef.__wctype_t = pointer +rbx.platform.typedef.__wint_t = int +rbx.platform.typedef.blkcnt_t = long_long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.caddr_t = string +rbx.platform.typedef.clock_t = long_long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cpuid_t = ulong +rbx.platform.typedef.daddr32_t = int +rbx.platform.typedef.daddr_t = long_long +rbx.platform.typedef.dev_t = int +rbx.platform.typedef.fixpt_t = uint +rbx.platform.typedef.fsblkcnt_t = ulong_long +rbx.platform.typedef.fsfilcnt_t = ulong_long +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.id_t = uint +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.ino_t = ulong_long +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.key_t = long +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.paddr_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.psize_t = ulong +rbx.platform.typedef.qaddr_t = pointer +rbx.platform.typedef.quad_t = long_long +rbx.platform.typedef.register_t = long +rbx.platform.typedef.rlim_t = ulong_long +rbx.platform.typedef.sa_family_t = uchar +rbx.platform.typedef.segsz_t = int +rbx.platform.typedef.sigset_t = uint +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.swblk_t = int +rbx.platform.typedef.time_t = long_long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_int16_t = ushort +rbx.platform.typedef.u_int32_t = uint +rbx.platform.typedef.u_int64_t = ulong_long +rbx.platform.typedef.u_int8_t = uchar +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_quad_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.vaddr_t = ulong +rbx.platform.typedef.vsize_t = ulong diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-solaris/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-solaris/types.conf new file mode 100644 index 0000000..a7890d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-solaris/types.conf @@ -0,0 +1,122 @@ +rbx.platform.typedef.*caddr_t = char +rbx.platform.typedef.blkcnt64_t = long +rbx.platform.typedef.blkcnt_t = long +rbx.platform.typedef.blksize_t = int +rbx.platform.typedef.clock_t = long +rbx.platform.typedef.clockid_t = int +rbx.platform.typedef.cnt_t = short +rbx.platform.typedef.cpu_flag_t = ushort +rbx.platform.typedef.ctid_t = int +rbx.platform.typedef.daddr_t = long +rbx.platform.typedef.datalink_id_t = uint +rbx.platform.typedef.dev_t = ulong +rbx.platform.typedef.diskaddr_t = ulong_long +rbx.platform.typedef.disp_lock_t = uchar +rbx.platform.typedef.fd_mask = long +rbx.platform.typedef.fds_mask = long +rbx.platform.typedef.fsblkcnt64_t = ulong +rbx.platform.typedef.fsblkcnt_t = ulong +rbx.platform.typedef.fsfilcnt64_t = ulong +rbx.platform.typedef.fsfilcnt_t = ulong +rbx.platform.typedef.gid_t = uint +rbx.platform.typedef.hrtime_t = long_long +rbx.platform.typedef.id_t = int +rbx.platform.typedef.in_addr_t = uint +rbx.platform.typedef.in_port_t = ushort +rbx.platform.typedef.index_t = short +rbx.platform.typedef.ino64_t = ulong +rbx.platform.typedef.ino_t = ulong +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = int +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long +rbx.platform.typedef.intptr_t = long +rbx.platform.typedef.ipaddr_t = uint +rbx.platform.typedef.k_fltset_t = uint +rbx.platform.typedef.key_t = int +rbx.platform.typedef.len_t = ulong_long +rbx.platform.typedef.lgrp_id_t = int +rbx.platform.typedef.lock_t = uchar +rbx.platform.typedef.longlong_t = long_long +rbx.platform.typedef.major_t = uint +rbx.platform.typedef.minor_t = uint +rbx.platform.typedef.mode_t = uint +rbx.platform.typedef.model_t = uint +rbx.platform.typedef.nfds_t = ulong +rbx.platform.typedef.nlink_t = uint +rbx.platform.typedef.o_dev_t = short +rbx.platform.typedef.o_gid_t = ushort +rbx.platform.typedef.o_ino_t = ushort +rbx.platform.typedef.o_mode_t = ushort +rbx.platform.typedef.o_nlink_t = short +rbx.platform.typedef.o_pid_t = short +rbx.platform.typedef.o_uid_t = ushort +rbx.platform.typedef.off64_t = long +rbx.platform.typedef.off_t = long +rbx.platform.typedef.offset_t = long_long +rbx.platform.typedef.pad64_t = long +rbx.platform.typedef.pfn_t = ulong +rbx.platform.typedef.pgcnt_t = ulong +rbx.platform.typedef.pid_t = int +rbx.platform.typedef.poolid_t = int +rbx.platform.typedef.pri_t = short +rbx.platform.typedef.projid_t = int +rbx.platform.typedef.pthread_key_t = uint +rbx.platform.typedef.pthread_t = uint +rbx.platform.typedef.ptrdiff_t = long +rbx.platform.typedef.rlim64_t = ulong_long +rbx.platform.typedef.rlim_t = ulong +rbx.platform.typedef.sa_family_t = ushort +rbx.platform.typedef.size_t = ulong +rbx.platform.typedef.socklen_t = uint +rbx.platform.typedef.spgcnt_t = long +rbx.platform.typedef.ssize_t = long +rbx.platform.typedef.suseconds_t = long +rbx.platform.typedef.sysid_t = short +rbx.platform.typedef.t_scalar_t = int +rbx.platform.typedef.t_uscalar_t = uint +rbx.platform.typedef.taskid_t = int +rbx.platform.typedef.time_t = long +rbx.platform.typedef.timer_t = int +rbx.platform.typedef.u_char = uchar +rbx.platform.typedef.u_int = uint +rbx.platform.typedef.u_long = ulong +rbx.platform.typedef.u_longlong_t = ulong_long +rbx.platform.typedef.u_offset_t = ulong_long +rbx.platform.typedef.u_short = ushort +rbx.platform.typedef.uchar_t = uchar +rbx.platform.typedef.uid_t = uint +rbx.platform.typedef.uint = uint +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint32_t = uint +rbx.platform.typedef.uint64_t = ulong +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = uint +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least32_t = uint +rbx.platform.typedef.uint_least64_t = ulong +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uint_t = uint +rbx.platform.typedef.uintmax_t = ulong +rbx.platform.typedef.uintptr_t = ulong +rbx.platform.typedef.ulong = ulong +rbx.platform.typedef.ulong_t = ulong +rbx.platform.typedef.unchar = uchar +rbx.platform.typedef.upad64_t = ulong +rbx.platform.typedef.use_t = uchar +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.ushort = ushort +rbx.platform.typedef.ushort_t = ushort +rbx.platform.typedef.zoneid_t = int diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-windows/types.conf b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-windows/types.conf new file mode 100644 index 0000000..5bdbbde --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/platform/x86_64-windows/types.conf @@ -0,0 +1,52 @@ +rbx.platform.typedef.__time32_t = long +rbx.platform.typedef.__time64_t = long_long +rbx.platform.typedef._dev_t = uint +rbx.platform.typedef._ino_t = ushort +rbx.platform.typedef._mode_t = ushort +rbx.platform.typedef._off64_t = long_long +rbx.platform.typedef._off_t = long +rbx.platform.typedef._pid_t = long_long +rbx.platform.typedef._sigset_t = ulong_long +rbx.platform.typedef.dev_t = uint +rbx.platform.typedef.errno_t = int +rbx.platform.typedef.ino_t = ushort +rbx.platform.typedef.int16_t = short +rbx.platform.typedef.int32_t = int +rbx.platform.typedef.int64_t = long_long +rbx.platform.typedef.int8_t = char +rbx.platform.typedef.int_fast16_t = short +rbx.platform.typedef.int_fast32_t = int +rbx.platform.typedef.int_fast64_t = long_long +rbx.platform.typedef.int_fast8_t = char +rbx.platform.typedef.int_least16_t = short +rbx.platform.typedef.int_least32_t = int +rbx.platform.typedef.int_least64_t = long_long +rbx.platform.typedef.int_least8_t = char +rbx.platform.typedef.intmax_t = long_long +rbx.platform.typedef.intptr_t = long_long +rbx.platform.typedef.mode_t = ushort +rbx.platform.typedef.off32_t = long +rbx.platform.typedef.off64_t = long_long +rbx.platform.typedef.off_t = long_long +rbx.platform.typedef.pid_t = long_long +rbx.platform.typedef.ptrdiff_t = long_long +rbx.platform.typedef.rsize_t = ulong_long +rbx.platform.typedef.size_t = ulong_long +rbx.platform.typedef.ssize_t = long_long +rbx.platform.typedef.time_t = long_long +rbx.platform.typedef.uint16_t = ushort +rbx.platform.typedef.uint64_t = ulong_long +rbx.platform.typedef.uint8_t = uchar +rbx.platform.typedef.uint_fast16_t = ushort +rbx.platform.typedef.uint_fast32_t = uint +rbx.platform.typedef.uint_fast64_t = ulong_long +rbx.platform.typedef.uint_fast8_t = uchar +rbx.platform.typedef.uint_least16_t = ushort +rbx.platform.typedef.uint_least64_t = ulong_long +rbx.platform.typedef.uint_least8_t = uchar +rbx.platform.typedef.uintmax_t = ulong_long +rbx.platform.typedef.uintptr_t = ulong_long +rbx.platform.typedef.useconds_t = uint +rbx.platform.typedef.wchar_t = ushort +rbx.platform.typedef.wctype_t = ushort +rbx.platform.typedef.wint_t = ushort diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/pointer.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/pointer.rb new file mode 100644 index 0000000..e65835f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/pointer.rb @@ -0,0 +1,167 @@ +# +# Copyright (C) 2008, 2009 Wayne Meissner +# Copyright (c) 2007, 2008 Evan Phoenix +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +require 'ffi/platform' + +# NOTE: all method definitions in this file are conditional on +# whether they are not already defined. This is needed because +# some Ruby implementations (e.g., TruffleRuby) might already +# provide these methods due to using FFI internally, and we +# should not override them to avoid warnings. + +module FFI + class Pointer + + # Pointer size + SIZE = Platform::ADDRESS_SIZE / 8 unless const_defined?(:SIZE) + + # Return the size of a pointer on the current platform, in bytes + # @return [Integer] + def self.size + SIZE + end unless respond_to?(:size) + + # @param [nil,Integer] len length of string to return + # @return [String] + # Read pointer's contents as a string, or the first +len+ bytes of the + # equivalent string if +len+ is not +nil+. + def read_string(len=nil) + if len + return ''.b if len == 0 + get_bytes(0, len) + else + get_string(0) + end + end unless method_defined?(:read_string) + + # @param [Integer] len length of string to return + # @return [String] + # Read the first +len+ bytes of pointer's contents as a string. + # + # Same as: + # ptr.read_string(len) # with len not nil + def read_string_length(len) + get_bytes(0, len) + end unless method_defined?(:read_string_length) + + # @return [String] + # Read pointer's contents as a string. + # + # Same as: + # ptr.read_string # with no len + def read_string_to_null + get_string(0) + end unless method_defined?(:read_string_to_null) + + # @param [String] str string to write + # @param [Integer] len length of string to return + # @return [self] + # Write +len+ first bytes of +str+ in pointer's contents. + # + # Same as: + # ptr.write_string(str, len) # with len not nil + def write_string_length(str, len) + put_bytes(0, str, 0, len) + end unless method_defined?(:write_string_length) + + # @param [String] str string to write + # @param [Integer] len length of string to return + # @return [self] + # Write +str+ in pointer's contents, or first +len+ bytes if + # +len+ is not +nil+. + def write_string(str, len=nil) + len = str.bytesize unless len + # Write the string data without NUL termination + put_bytes(0, str, 0, len) + end unless method_defined?(:write_string) + + # @param [Type] type type of data to read from pointer's contents + # @param [Symbol] reader method to send to +self+ to read +type+ + # @param [Integer] length + # @return [Array] + # Read an array of +type+ of length +length+. + # @example + # ptr.read_array_of_type(TYPE_UINT8, :read_uint8, 4) # -> [1, 2, 3, 4] + def read_array_of_type(type, reader, length) + ary = [] + size = FFI.type_size(type) + tmp = self + length.times { |j| + ary << tmp.send(reader) + tmp += size unless j == length-1 # avoid OOB + } + ary + end unless method_defined?(:read_array_of_type) + + # @param [Type] type type of data to write to pointer's contents + # @param [Symbol] writer method to send to +self+ to write +type+ + # @param [Array] ary + # @return [self] + # Write +ary+ in pointer's contents as +type+. + # @example + # ptr.write_array_of_type(TYPE_UINT8, :put_uint8, [1, 2, 3 ,4]) + def write_array_of_type(type, writer, ary) + size = FFI.type_size(type) + ary.each_with_index { |val, i| + break unless i < self.size + self.send(writer, i * size, val) + } + self + end unless method_defined?(:write_array_of_type) + + # @return [self] + def to_ptr + self + end unless method_defined?(:to_ptr) + + # @param [Symbol,Type] type of data to read + # @return [Object] + # Read pointer's contents as +type+ + # + # Same as: + # ptr.get(type, 0) + def read(type) + get(type, 0) + end unless method_defined?(:read) + + # @param [Symbol,Type] type of data to read + # @param [Object] value to write + # @return [nil] + # Write +value+ of type +type+ to pointer's content + # + # Same as: + # ptr.put(type, 0) + def write(type, value) + put(type, 0, value) + end unless method_defined?(:write) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct.rb new file mode 100644 index 0000000..bf6228a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct.rb @@ -0,0 +1,317 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# Copyright (C) 2008, 2009 Andrea Fazzi +# Copyright (C) 2008, 2009 Luc Heinrich +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +require 'ffi/platform' +require 'ffi/struct_layout' +require 'ffi/struct_layout_builder' +require 'ffi/struct_by_reference' + +module FFI + + class Struct + + # Get struct size + # @return [Integer] + def size + self.class.size + end + + # @return [Integer] Struct alignment + def alignment + self.class.alignment + end + alias_method :align, :alignment + + # (see FFI::StructLayout#offset_of) + def offset_of(name) + self.class.offset_of(name) + end + + # (see FFI::StructLayout#members) + def members + self.class.members + end + + # @return [Array] + # Get array of values from Struct fields. + def values + members.map { |m| self[m] } + end + + # (see FFI::StructLayout#offsets) + def offsets + self.class.offsets + end + + # Clear the struct content. + # @return [self] + def clear + pointer.clear + self + end + + # Get {Pointer} to struct content. + # @return [AbstractMemory] + def to_ptr + pointer + end + + # Get struct size + # @return [Integer] + def self.size + defined?(@layout) ? @layout.size : defined?(@size) ? @size : 0 + end + + # set struct size + # @param [Integer] size + # @return [size] + def self.size=(size) + raise ArgumentError, "Size already set" if defined?(@size) || defined?(@layout) + @size = size + end + + # @return (see Struct#alignment) + def self.alignment + @layout.alignment + end + + # (see FFI::Type#members) + def self.members + @layout.members + end + + # (see FFI::StructLayout#offsets) + def self.offsets + @layout.offsets + end + + # (see FFI::StructLayout#offset_of) + def self.offset_of(name) + @layout.offset_of(name) + end + + def self.in + ptr(:in) + end + + def self.out + ptr(:out) + end + + def self.ptr(flags = :inout) + @ref_data_type ||= Type::Mapped.new(StructByReference.new(self)) + end + + def self.val + @val_data_type ||= StructByValue.new(self) + end + + def self.by_value + self.val + end + + def self.by_ref(flags = :inout) + self.ptr(flags) + end + + class ManagedStructConverter < StructByReference + + # @param [Struct] struct_class + def initialize(struct_class) + super(struct_class) + + raise NoMethodError, "release() not implemented for class #{struct_class}" unless struct_class.respond_to? :release + @method = struct_class.method(:release) + end + + # @param [Pointer] ptr + # @param [nil] ctx + # @return [Struct] + def from_native(ptr, ctx) + struct_class.new(AutoPointer.new(ptr, @method)) + end + end + + def self.auto_ptr + @managed_type ||= Type::Mapped.new(ManagedStructConverter.new(self)) + end + + + class << self + public + + # @return [StructLayout] + # @overload layout + # @return [StructLayout] + # Get struct layout. + # @overload layout(*spec) + # @param [Array,Array(Hash)] spec + # @return [StructLayout] + # Create struct layout from +spec+. + # @example Creating a layout from an array +spec+ + # class MyStruct < Struct + # layout :field1, :int, + # :field2, :pointer, + # :field3, :string + # end + # @example Creating a layout from an array +spec+ with offset + # class MyStructWithOffset < Struct + # layout :field1, :int, + # :field2, :pointer, 6, # set offset to 6 for this field + # :field3, :string + # end + # @example Creating a layout from a hash +spec+ + # class MyStructFromHash < Struct + # layout :field1 => :int, + # :field2 => :pointer, + # :field3 => :string + # end + # @example Creating a layout with pointers to functions + # class MyFunctionTable < Struct + # layout :function1, callback([:int, :int], :int), + # :function2, callback([:pointer], :void), + # :field3, :string + # end + def layout(*spec) + return @layout if spec.size == 0 + + warn "[DEPRECATION] Struct layout is already defined for class #{self.inspect}. Redefinition as in #{caller[0]} will be disallowed in ffi-2.0." if defined?(@layout) + + builder = StructLayoutBuilder.new + builder.union = self < Union + builder.packed = @packed if defined?(@packed) + builder.alignment = @min_alignment if defined?(@min_alignment) + + if spec[0].kind_of?(Hash) + hash_layout(builder, spec) + else + array_layout(builder, spec) + end + builder.size = @size if defined?(@size) && @size > builder.size + cspec = builder.build + @layout = cspec unless self == Struct + @size = cspec.size + return cspec + end + + + protected + + def callback(params, ret) + mod = enclosing_module + ret_type = find_type(ret, mod) + if ret_type == Type::STRING + raise TypeError, ":string is not allowed as return type of callbacks" + end + FFI::CallbackInfo.new(ret_type, params.map { |e| find_type(e, mod) }) + end + + def packed(packed = 1) + @packed = packed + end + alias :pack :packed + + def aligned(alignment = 1) + @min_alignment = alignment + end + alias :align :aligned + + def enclosing_module + begin + mod = self.name.split("::")[0..-2].inject(Object) { |obj, c| obj.const_get(c) } + if mod.respond_to?(:find_type) && (mod.is_a?(FFI::Library) || mod < FFI::Struct) + mod + end + rescue Exception + nil + end + end + + + def find_field_type(type, mod = enclosing_module) + if type.kind_of?(Class) && type < Struct + FFI::Type::Struct.new(type) + + elsif type.kind_of?(Class) && type < FFI::StructLayout::Field + type + + elsif type.kind_of?(::Array) + FFI::Type::Array.new(find_field_type(type[0]), type[1]) + + else + find_type(type, mod) + end + end + + def find_type(type, mod = enclosing_module) + if mod + mod.find_type(type) + end || FFI.find_type(type) + end + + private + + # @param [StructLayoutBuilder] builder + # @param [Hash] spec + # @return [builder] + # Add hash +spec+ to +builder+. + def hash_layout(builder, spec) + spec[0].each do |name, type| + builder.add name, find_field_type(type), nil + end + end + + # @param [StructLayoutBuilder] builder + # @param [Array] spec + # @return [builder] + # Add array +spec+ to +builder+. + def array_layout(builder, spec) + i = 0 + while i < spec.size + name, type = spec[i, 2] + i += 2 + + # If the next param is a Integer, it specifies the offset + if spec[i].kind_of?(Integer) + offset = spec[i] + i += 1 + else + offset = nil + end + + builder.add name, find_field_type(type), offset + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_by_reference.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_by_reference.rb new file mode 100644 index 0000000..9ed1f71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_by_reference.rb @@ -0,0 +1,72 @@ +# +# Copyright (C) 2010 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.# + +module FFI + # This class includes the {FFI::DataConverter} module. + class StructByReference + include DataConverter + + attr_reader :struct_class + + # @param [Struct] struct_class + def initialize(struct_class) + unless Class === struct_class and struct_class < FFI::Struct + raise TypeError, 'wrong type (expected subclass of FFI::Struct)' + end + @struct_class = struct_class + end + + # Always get {FFI::Type}::POINTER. + def native_type(_type = nil) + FFI::Type::POINTER + end + + # @param [nil, Struct] value + # @param [nil] ctx + # @return [AbstractMemory] Pointer on +value+. + def to_native(value, ctx) + return Pointer::NULL if value.nil? + + unless @struct_class === value + raise TypeError, "wrong argument type #{value.class} (expected #{@struct_class})" + end + + value.pointer + end + + # @param [AbstractMemory] value + # @param [nil] ctx + # @return [Struct] + # Create a struct from content of memory +value+. + def from_native(value, ctx) + @struct_class.new(value) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout.rb new file mode 100644 index 0000000..fb84202 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout.rb @@ -0,0 +1,96 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# Copyright (C) 2008, 2009 Andrea Fazzi +# Copyright (C) 2008, 2009 Luc Heinrich +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +module FFI + + class StructLayout + + # @return [Array + # Get an array of tuples (field name, offset of the field). + def offsets + members.map { |m| [ m, self[m].offset ] } + end + + # @return [Integer] + # Get the offset of a field. + def offset_of(field_name) + self[field_name].offset + end + + # An enum {Field} in a {StructLayout}. + class Enum < Field + + # @param [AbstractMemory] ptr pointer on a {Struct} + # @return [Object] + # Get an object of type {#type} from memory pointed by +ptr+. + def get(ptr) + type.find(ptr.get_int(offset)) + end + + # @param [AbstractMemory] ptr pointer on a {Struct} + # @param value + # @return [nil] + # Set +value+ into memory pointed by +ptr+. + def put(ptr, value) + ptr.put_int(offset, type.find(value)) + end + + end + + class InnerStruct < Field + def get(ptr) + type.struct_class.new(ptr.slice(self.offset, self.size)) + end + + def put(ptr, value) + raise TypeError, "wrong value type (expected #{type.struct_class})" unless value.is_a?(type.struct_class) + ptr.slice(self.offset, self.size).__copy_from__(value.pointer, self.size) + end + end + + class Mapped < Field + def initialize(name, offset, type, orig_field) + @orig_field = orig_field + super(name, offset, type) + end + + def get(ptr) + type.from_native(@orig_field.get(ptr), nil) + end + + def put(ptr, value) + @orig_field.put(ptr, type.to_native(value, nil)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout_builder.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout_builder.rb new file mode 100644 index 0000000..2221a60 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/struct_layout_builder.rb @@ -0,0 +1,227 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +module FFI + + # Build a {StructLayout struct layout}. + class StructLayoutBuilder + attr_reader :size + attr_reader :alignment + + def initialize + @size = 0 + @alignment = 1 + @min_alignment = 1 + @packed = false + @union = false + @fields = Array.new + end + + # Set size attribute with +size+ only if +size+ is greater than attribute value. + # @param [Integer] size + def size=(size) + @size = size if size > @size + end + + # Set alignment attribute with +align+ only if it is greater than attribute value. + # @param [Integer] align + def alignment=(align) + @alignment = align if align > @alignment + @min_alignment = align + end + + # Set union attribute. + # Set to +true+ to build a {Union} instead of a {Struct}. + # @param [Boolean] is_union + # @return [is_union] + def union=(is_union) + @union = is_union + end + + # Building a {Union} or a {Struct} ? + # + # @return [Boolean] + # + def union? + @union + end + + # Set packed attribute + # @overload packed=(packed) Set alignment and packed attributes to + # +packed+. + # + # @param [Integer] packed + # + # @return [packed] + # @overload packed=(packed) Set packed attribute. + # @param packed + # + # @return [0,1] + # + def packed=(packed) + if packed.is_a?(0.class) + @alignment = packed + @packed = packed + else + @packed = packed ? 1 : 0 + end + end + + + # List of number types + NUMBER_TYPES = [ + Type::INT8, + Type::UINT8, + Type::INT16, + Type::UINT16, + Type::INT32, + Type::UINT32, + Type::LONG, + Type::ULONG, + Type::INT64, + Type::UINT64, + Type::FLOAT32, + Type::FLOAT64, + Type::LONGDOUBLE, + Type::BOOL, + ].freeze + + # @param [String, Symbol] name name of the field + # @param [Array, DataConverter, Struct, StructLayout::Field, Symbol, Type] type type of the field + # @param [Integer, nil] offset + # @return [self] + # Add a field to the builder. + # @note Setting +offset+ to +nil+ or +-1+ is equivalent to +0+. + def add(name, type, offset = nil) + + if offset.nil? || offset == -1 + offset = @union ? 0 : align(@size, @packed ? [ @packed, type.alignment ].min : [ @min_alignment, type.alignment ].max) + end + + # + # If a FFI::Type type was passed in as the field arg, try and convert to a StructLayout::Field instance + # + field = type.is_a?(StructLayout::Field) ? type : field_for_type(name, offset, type) + @fields << field + @alignment = [ @alignment, field.alignment ].max unless @packed + @size = [ @size, field.size + (@union ? 0 : field.offset) ].max + + return self + end + + # @param (see #add) + # @return (see #add) + # Same as {#add}. + # @see #add + def add_field(name, type, offset = nil) + add(name, type, offset) + end + + # @param (see #add) + # @return (see #add) + # Add a struct as a field to the builder. + def add_struct(name, type, offset = nil) + add(name, Type::Struct.new(type), offset) + end + + # @param name (see #add) + # @param type (see #add) + # @param [Integer] count array length + # @param offset (see #add) + # @return (see #add) + # Add an array as a field to the builder. + def add_array(name, type, count, offset = nil) + add(name, Type::Array.new(type, count), offset) + end + + # @return [StructLayout] + # Build and return the struct layout. + def build + # Add tail padding if the struct is not packed + size = @packed ? @size : align(@size, @alignment) + + layout = StructLayout.new(@fields, size, @alignment) + layout.__union! if @union + layout + end + + private + + # @param [Integer] offset + # @param [Integer] align + # @return [Integer] + def align(offset, align) + align + ((offset - 1) & ~(align - 1)); + end + + # @param (see #add) + # @return [StructLayout::Field] + def field_for_type(name, offset, type) + field_class = case + when type.is_a?(Type::Function) + StructLayout::Function + + when type.is_a?(Type::Struct) + StructLayout::InnerStruct + + when type.is_a?(Type::Array) + StructLayout::Array + + when type.is_a?(FFI::Enum) + StructLayout::Enum + + when NUMBER_TYPES.include?(type) + StructLayout::Number + + when type == Type::POINTER + StructLayout::Pointer + + when type == Type::STRING + StructLayout::String + + when type.is_a?(Class) && type < StructLayout::Field + type + + when type.is_a?(DataConverter) + return StructLayout::Mapped.new(name, offset, Type::Mapped.new(type), field_for_type(name, offset, type.native_type)) + + when type.is_a?(Type::Mapped) + return StructLayout::Mapped.new(name, offset, type, field_for_type(name, offset, type.native_type)) + + else + raise TypeError, "invalid struct field type #{type.inspect}" + end + + field_class.new(name, offset, type) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb new file mode 100644 index 0000000..70ba9c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/const_generator.rb @@ -0,0 +1,232 @@ +require 'tempfile' +require 'open3' + +module FFI + + # ConstGenerator turns C constants into ruby values. + # + # @example a simple example for stdio + # require 'ffi/tools/const_generator' + # cg = FFI::ConstGenerator.new('stdio') do |gen| + # gen.const(:SEEK_SET) + # gen.const('SEEK_CUR') + # gen.const('seek_end') # this constant does not exist + # end # #calculate called automatically at the end of the block + # + # cg['SEEK_SET'] # => 0 + # cg['SEEK_CUR'] # => 1 + # cg['seek_end'] # => nil + # cg.to_ruby # => "SEEK_SET = 0\nSEEK_CUR = 1\n# seek_end not available" + class ConstGenerator + @options = {} + attr_reader :constants + + # Creates a new constant generator that uses +prefix+ as a name, and an + # options hash. + # + # The only option is +:required+, which if set to +true+ raises an error if a + # constant you have requested was not found. + # + # @param [#to_s] prefix + # @param [Hash] options + # @return + # @option options [Boolean] :required + # @overload initialize(prefix, options) + # @overload initialize(prefix, options) { |gen| ... } + # @yieldparam [ConstGenerator] gen new generator is passed to the block + # When passed a block, {#calculate} is automatically called at the end of + # the block, otherwise you must call it yourself. + def initialize(prefix = nil, options = {}) + @includes = ['stdio.h', 'stddef.h'] + @constants = {} + @prefix = prefix + + @required = options[:required] + @options = options + + if block_given? then + yield self + calculate self.class.options.merge(options) + end + end + # Set class options + # These options are merged with {#initialize} options when it is called with a block. + # @param [Hash] options + # @return [Hash] class options + def self.options=(options) + @options = options + end + # Get class options. + # @return [Hash] class options + def self.options + @options + end + # @param [String] name + # @return constant value (converted if a +converter+ was defined). + # Access a constant by name. + def [](name) + @constants[name].converted_value + end + + # Request the value for C constant +name+. + # + # @param [#to_s] name C constant name + # @param [String] format a printf format string to print the value out + # @param [String] cast a C cast for the value + # @param ruby_name alternate ruby name for {#to_ruby} + # + # @overload const(name, format=nil, cast='', ruby_name=nil, converter=nil) + # +converter+ is a Method or a Proc. + # @param [#call] converter convert the value from a string to the appropriate + # type for {#to_ruby}. + # @overload const(name, format=nil, cast='', ruby_name=nil) { |value| ... } + # Use a converter block. This block convert the value from a string to the + # appropriate type for {#to_ruby}. + # @yieldparam value constant value + def const(name, format = nil, cast = '', ruby_name = nil, converter = nil, + &converter_proc) + format ||= '%d' + cast ||= '' + + if converter_proc and converter then + raise ArgumentError, "Supply only converter or converter block" + end + + converter = converter_proc if converter.nil? + + const = Constant.new name, format, cast, ruby_name, converter + @constants[name.to_s] = const + return const + end + + # Calculate constants values. + # @param [Hash] options + # @option options [String] :cppflags flags for C compiler + # @return [nil] + # @raise if a constant is missing and +:required+ was set to +true+ (see {#initialize}) + def calculate(options = {}) + binary_path = nil + + Tempfile.open("#{@prefix}.const_generator") do |f| + binary_path = f.path + ".bin" + @includes.each do |inc| + f.puts "#include <#{inc}>" + end + f.puts "\nint main(int argc, char **argv)\n{" + + @constants.each_value do |const| + f.puts <<-EOF + #ifdef #{const.name} + printf("#{const.name} #{const.format}\\n", #{const.cast}#{const.name}); + #endif + EOF + end + + f.puts "\n\treturn 0;\n}" + f.flush + + cc = ENV['CC'] || 'gcc' + output = `#{cc} #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary_path} 2>&1` + + unless $?.success? then + output = output.split("\n").map { |l| "\t#{l}" }.join "\n" + raise "Compilation error generating constants #{@prefix}:\n#{output}" + end + end + + output = `#{binary_path}` + File.unlink(binary_path + (FFI::Platform.windows? ? ".exe" : "")) + output.each_line do |line| + line =~ /^(\S+)\s(.*)$/ + const = @constants[$1] + const.value = $2 + end + + missing_constants = @constants.select do |name, constant| + constant.value.nil? + end.map { |name,| name } + + if @required and not missing_constants.empty? then + raise "Missing required constants for #{@prefix}: #{missing_constants.join ', '}" + end + end + + # Dump constants to +io+. + # @param [#puts] io + # @return [nil] + def dump_constants(io) + @constants.each do |name, constant| + name = [@prefix, name].join '.' if @prefix + io.puts "#{name} = #{constant.converted_value}" + end + end + + # Outputs values for discovered constants. If the constant's value was + # not discovered it is not omitted. + # @return [String] + def to_ruby + @constants.sort_by { |name,| name }.map do |name, constant| + if constant.value.nil? then + "# #{name} not available" + else + constant.to_ruby + end + end.join "\n" + end + + # Add additional C include file(s) to calculate constants from. + # @note +stdio.h+ and +stddef.h+ automatically included + # @param [List, Array] i include file(s) + # @return [Array] array of include files + def include(*i) + @includes |= i.flatten + end + + end + + # This class hold constants for {ConstGenerator} + class ConstGenerator::Constant + + attr_reader :name, :format, :cast + attr_accessor :value + + # @param [#to_s] name + # @param [String] format a printf format string to print the value out + # @param [String] cast a C cast for the value + # @param ruby_name alternate ruby name for {#to_ruby} + # @param [#call] converter convert the value from a string to the appropriate + # type for {#to_ruby}. + def initialize(name, format, cast, ruby_name = nil, converter=nil) + @name = name + @format = format + @cast = cast + @ruby_name = ruby_name + @converter = converter + @value = nil + end + + # Return constant value (converted if a +converter+ was defined). + # @return constant value. + def converted_value + if @converter + @converter.call(@value) + else + @value + end + end + + # get constant ruby name + # @return [String] + def ruby_name + @ruby_name || @name + end + + # Get an evaluable string from constant. + # @return [String] + def to_ruby + "#{ruby_name} = #{converted_value}" + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb new file mode 100644 index 0000000..5552ea5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator.rb @@ -0,0 +1,105 @@ +require 'ffi/tools/struct_generator' +require 'ffi/tools/const_generator' + +module FFI + + ## + # Generate files with C structs for FFI::Struct and C constants. + # + # == A simple example + # + # In file +zlib.rb.ffi+: + # module Zlib + # @@@ + # constants do |c| + # c.include "zlib.h" + # c.const :ZLIB_VERNUM + # end + # @@@ + # + # class ZStream < FFI::Struct + # + # struct do |s| + # s.name "struct z_stream_s" + # s.include "zlib.h" + # + # s.field :next_in, :pointer + # s.field :avail_in, :uint + # s.field :total_in, :ulong + # end + # @@@ + # end + # end + # + # Translate the file: + # require "ffi/tools/generator" + # FFI::Generator.new "zlib.rb.ffi", "zlib.rb" + # + # Generates the file +zlib.rb+ with constant values and offsets: + # module Zlib + # ZLIB_VERNUM = 4784 + # + # class ZStream < FFI::Struct + # layout :next_in, :pointer, 0, + # :avail_in, :uint, 8, + # :total_in, :ulong, 16 + # end + # + # @see FFI::Generator::Task for easy integration in a Rakefile + class Generator + + def initialize(ffi_name, rb_name, options = {}) + @ffi_name = ffi_name + @rb_name = rb_name + @options = options + @name = File.basename rb_name, '.rb' + + file = File.read @ffi_name + + new_file = file.gsub(/^( *)@@@(.*?)@@@/m) do + @constants = [] + @structs = [] + + indent = $1 + original_lines = $2.count "\n" + + instance_eval $2, @ffi_name, $`.count("\n") + + new_lines = [] + @constants.each { |c| new_lines << c.to_ruby } + @structs.each { |s| new_lines << s.generate_layout } + + new_lines = new_lines.join("\n").split "\n" # expand multiline blocks + new_lines = new_lines.map { |line| indent + line } + + padding = original_lines - new_lines.length + new_lines += [nil] * padding if padding >= 0 + + new_lines.join "\n" + end + + open @rb_name, 'w' do |f| + f.puts "# This file is generated from `#{@ffi_name}'. Do not edit." + f.puts + f.puts new_file + end + end + + def constants(options = {}, &block) + @constants << FFI::ConstGenerator.new(@name, @options.merge(options), &block) + end + + def struct(options = {}, &block) + @structs << FFI::StructGenerator.new(@name, @options.merge(options), &block) + end + + ## + # Utility converter for constants + + def to_s + proc { |obj| obj.to_s.inspect } + end + + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb new file mode 100644 index 0000000..da72968 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/generator_task.rb @@ -0,0 +1,32 @@ +require 'ffi/tools/generator' +require 'rake' +require 'rake/tasklib' + +## +# Add Rake tasks that generate files with C structs for FFI::Struct and C constants. +# +# @example a simple example for your Rakefile +# require "ffi/tools/generator_task" +# # Add a task to generate my_object.rb out of my_object.rb.ffi +# FFI::Generator::Task.new ["my_object.rb"], cflags: "-I/usr/local/mylibrary" +# +# The generated files are also added to the 'clear' task. +# +# @see FFI::Generator for a description of the file content +class FFI::Generator::Task < Rake::TaskLib + + def initialize(rb_names, options={}) + task :clean do rm_f rb_names end + + rb_names.each do |rb_name| + ffi_name = "#{rb_name}.ffi" + + file rb_name => ffi_name do |t| + puts "Generating #{rb_name}..." if Rake.application.options.trace + + FFI::Generator.new ffi_name, rb_name, options + end + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb new file mode 100644 index 0000000..3a951c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/tools/struct_generator.rb @@ -0,0 +1,195 @@ +require 'tempfile' + +module FFI + + ## + # Generates an FFI Struct layout. + # + # Given the @@@ portion in: + # + # class Zlib::ZStream < FFI::Struct + # @@@ + # name "struct z_stream_s" + # include "zlib.h" + # + # field :next_in, :pointer + # field :avail_in, :uint + # field :total_in, :ulong + # + # # ... + # @@@ + # end + # + # StructGenerator will create the layout: + # + # layout :next_in, :pointer, 0, + # :avail_in, :uint, 4, + # :total_in, :ulong, 8, + # # ... + # + # StructGenerator does its best to pad the layout it produces to preserve + # line numbers. Place the struct definition as close to the top of the file + # for best results. + + class StructGenerator + @options = {} + attr_accessor :size + attr_reader :fields + + def initialize(name, options = {}) + @name = name + @struct_name = nil + @includes = [] + @fields = [] + @found = false + @size = nil + + if block_given? then + yield self + calculate self.class.options.merge(options) + end + end + def self.options=(options) + @options = options + end + def self.options + @options + end + def calculate(options = {}) + binary = File.join Dir.tmpdir, "rb_struct_gen_bin_#{Process.pid}" + + raise "struct name not set" if @struct_name.nil? + + Tempfile.open("#{@name}.struct_generator") do |f| + f.puts "#include " + + @includes.each do |inc| + f.puts "#include <#{inc}>" + end + + f.puts "#include \n\n" + f.puts "int main(int argc, char **argv)\n{" + f.puts " #{@struct_name} s;" + f.puts %[ printf("sizeof(#{@struct_name}) %u\\n", (unsigned int) sizeof(#{@struct_name}));] + + @fields.each do |field| + f.puts <<-EOF + printf("#{field.name} %u %u\\n", (unsigned int) offsetof(#{@struct_name}, #{field.name}), + (unsigned int) sizeof(s.#{field.name})); + EOF + end + + f.puts "\n return 0;\n}" + f.flush + + cc = ENV['CC'] || 'gcc' + output = `#{cc} #{options[:cppflags]} #{options[:cflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary} 2>&1` + + unless $?.success? then + @found = false + output = output.split("\n").map { |l| "\t#{l}" }.join "\n" + raise "Compilation error generating struct #{@name} (#{@struct_name}):\n#{output}" + end + end + + output = `#{binary}`.split "\n" + File.unlink(binary + (FFI::Platform.windows? ? ".exe" : "")) + sizeof = output.shift + unless @size + m = /\s*sizeof\([^)]+\) (\d+)/.match sizeof + @size = m[1] + end + + line_no = 0 + output.each do |line| + md = line.match(/.+ (\d+) (\d+)/) + @fields[line_no].offset = md[1].to_i + @fields[line_no].size = md[2].to_i + + line_no += 1 + end + + @found = true + end + + def field(name, type=nil) + field = Field.new(name, type) + @fields << field + return field + end + + def found? + @found + end + + def dump_config(io) + io.puts "rbx.platform.#{@name}.sizeof = #{@size}" + + @fields.each { |field| io.puts field.to_config(@name) } + end + + def generate_layout + buf = "" + + @fields.each_with_index do |field, i| + if buf.empty? + buf << "layout :#{field.name}, :#{field.type}, #{field.offset}" + else + buf << " :#{field.name}, :#{field.type}, #{field.offset}" + end + + if i < @fields.length - 1 + buf << ",\n" + end + end + + buf + end + + def get_field(name) + @fields.find { |f| name == f.name } + end + + def include(i) + @includes << i + end + + def name(n) + @struct_name = n + end + + end + + ## + # A field in a Struct. + + class StructGenerator::Field + + attr_reader :name + attr_reader :type + attr_reader :offset + attr_accessor :size + + def initialize(name, type) + @name = name + @type = type + @offset = nil + @size = nil + end + + def offset=(o) + @offset = o + end + + def to_config(name) + buf = [] + buf << "rbx.platform.#{name}.#{@name}.offset = #{@offset}" + buf << "rbx.platform.#{name}.#{@name}.size = #{@size}" + buf << "rbx.platform.#{name}.#{@name}.type = #{@type}" if @type + buf + end + + end + +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/types.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/types.rb new file mode 100644 index 0000000..6f3ee4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/types.rb @@ -0,0 +1,222 @@ +# +# Copyright (C) 2008-2010 Wayne Meissner +# Copyright (c) 2007, 2008 Evan Phoenix +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# see {file:README} +module FFI + + # Unless custom_typedefs already defined in the C-ext? + unless defined?(custom_typedefs) + # Truffleruby and JRuby don't support Ractor so far. + # So they don't need separation between builtin and custom types. + def self.custom_typedefs + TypeDefs + end + writable_typemap = true + end + + class << self + + private :custom_typedefs + + # @param [Type, DataConverter, Symbol] old type definition used by {FFI.find_type} + # @param [Symbol] add new type definition's name to add + # @return [Type] + # Add a definition type to type definitions. + # + # The type definition is local per Ractor. + def typedef(old, add) + tm = custom_typedefs + tm[add] = find_type(old) + end + + # (see FFI.typedef) + def add_typedef(old, add) + typedef old, add + end + + private def __typedef(old, add) + TypeDefs[add] = find_type(old, TypeDefs) + end + + # @param [Type, DataConverter, Symbol] name + # @param [Hash] type_map if nil, {FFI::TypeDefs} is used + # @return [Type] + # Find a type in +type_map+ ({FFI::TypeDefs}, by default) from + # a type objet, a type name (symbol). If +name+ is a {DataConverter}, + # a new {Type::Mapped} is created. + def find_type(name, type_map = nil) + if name.is_a?(Type) + name + + elsif type_map&.has_key?(name) + type_map[name] + + elsif (tm=custom_typedefs).has_key?(name) + tm[name] + + elsif TypeDefs.has_key?(name) + TypeDefs[name] + + elsif name.is_a?(DataConverter) + # Add a typedef so next time the converter is used, it hits the cache + tm = (type_map || custom_typedefs) + tm[name] = Type::Mapped.new(name) + else + raise TypeError, "unable to resolve type '#{name}'" + end + end + + # @param type +type+ is an instance of class accepted by {FFI.find_type} + # @return [Integer] + # Get +type+ size, in bytes. + def type_size(type) + find_type(type).size + end + end + + # List of type definitions + TypeDefs.merge!({ + # The C void type; only useful for function return types + :void => Type::VOID, + + # C boolean type + :bool => Type::BOOL, + + # C nul-terminated string + :string => Type::STRING, + + # C signed char + :char => Type::CHAR, + # C unsigned char + :uchar => Type::UCHAR, + + # C signed short + :short => Type::SHORT, + # C unsigned short + :ushort => Type::USHORT, + + # C signed int + :int => Type::INT, + # C unsigned int + :uint => Type::UINT, + + # C signed long + :long => Type::LONG, + + # C unsigned long + :ulong => Type::ULONG, + + # C signed long long integer + :long_long => Type::LONG_LONG, + + # C unsigned long long integer + :ulong_long => Type::ULONG_LONG, + + # C single precision float + :float => Type::FLOAT, + + # C double precision float + :double => Type::DOUBLE, + + # C long double + :long_double => Type::LONGDOUBLE, + + # Native memory address + :pointer => Type::POINTER, + + # 8 bit signed integer + :int8 => Type::INT8, + # 8 bit unsigned integer + :uint8 => Type::UINT8, + + # 16 bit signed integer + :int16 => Type::INT16, + # 16 bit unsigned integer + :uint16 => Type::UINT16, + + # 32 bit signed integer + :int32 => Type::INT32, + # 32 bit unsigned integer + :uint32 => Type::UINT32, + + # 64 bit signed integer + :int64 => Type::INT64, + # 64 bit unsigned integer + :uint64 => Type::UINT64, + + :buffer_in => Type::BUFFER_IN, + :buffer_out => Type::BUFFER_OUT, + :buffer_inout => Type::BUFFER_INOUT, + + # Used in function prototypes to indicate the arguments are variadic + :varargs => Type::VARARGS, + }) + + # This will convert a pointer to a Ruby string (just like `:string`), but + # also allow to work with the pointer itself. This is useful when you want + # a Ruby string already containing a copy of the data, but also the pointer + # to the data for you to do something with it, like freeing it, in case the + # library handed the memory off to the caller (Ruby-FFI). + # + # It's {typedef}'d as +:strptr+. + class StrPtrConverter + extend DataConverter + native_type Type::POINTER + + # @param [Pointer] val + # @param ctx not used + # @return [Array(String, Pointer)] + # Returns a [ String, Pointer ] tuple so the C memory for the string can be freed + def self.from_native(val, ctx) + [ val.null? ? nil : val.get_string(0), val ] + end + end + + __typedef(StrPtrConverter, :strptr) + + # Load all the platform dependent types + begin + File.open(File.join(Platform::CONF_DIR, 'types.conf'), "r") do |f| + prefix = "rbx.platform.typedef." + f.each_line { |line| + if line.index(prefix) == 0 + new_type, orig_type = line.chomp.slice(prefix.length..-1).split(/\s*=\s*/) + __typedef(orig_type.to_sym, new_type.to_sym) + end + } + end + __typedef :pointer, :caddr_t + rescue Errno::ENOENT + end + + FFI.make_shareable(TypeDefs) unless writable_typemap +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/union.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/union.rb new file mode 100644 index 0000000..38414ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/union.rb @@ -0,0 +1,43 @@ +# +# Copyright (C) 2009 Andrea Fazzi +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +require 'ffi/struct' + +module FFI + + class Union < FFI::Struct + def self.builder + b = StructLayoutBuilder.new + b.union = true + b + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/variadic.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/variadic.rb new file mode 100644 index 0000000..ee33409 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/variadic.rb @@ -0,0 +1,80 @@ +# +# Copyright (C) 2008, 2009 Wayne Meissner +# Copyright (C) 2009 Luc Heinrich +# +# This file is part of ruby-ffi. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Ruby FFI project nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +module FFI + class VariadicInvoker + def call(*args, &block) + param_types = Array.new(@fixed) + param_values = Array.new + @fixed.each_with_index do |t, i| + param_values << args[i] + end + i = @fixed.length + while i < args.length + param_types << FFI.find_type(args[i], @type_map) + param_values << args[i + 1] + i += 2 + end + invoke(param_types, param_values, &block) + end + + # + # Attach the invoker to module +mod+ as +mname+ + # + def attach(mod, mname) + invoker = self + params = "*args" + call = "call" + mname = mname.to_sym + mod.module_eval <<-code, __FILE__, __LINE__ + @ffi_functions = {} unless defined?(@ffi_functions) + @ffi_functions[#{mname.inspect}] = invoker + + def self.#{mname}(#{params}) + @ffi_functions[#{mname.inspect}].#{call}(#{params}) + end + + define_method(#{mname.inspect}, &method(#{mname.inspect})) + code + invoker + end + + # Retrieve Array of parameter types + # + # This method returns an Array of FFI types accepted as function parameters. + # + # @return [Array] + def param_types + [*@fixed, Type::Builtin::VARARGS] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/version.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/version.rb new file mode 100644 index 0000000..59c95df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/lib/ffi/version.rb @@ -0,0 +1,3 @@ +module FFI + VERSION = '1.17.4' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getlogin.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getlogin.rb new file mode 100644 index 0000000..6713021 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getlogin.rb @@ -0,0 +1,8 @@ +require 'ffi' + +module Foo + extend FFI::Library + ffi_lib FFI::Library::LIBC + attach_function :getlogin, [ ], :string +end +puts "getlogin=#{Foo.getlogin}" diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getpid.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getpid.rb new file mode 100644 index 0000000..1720635 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/getpid.rb @@ -0,0 +1,8 @@ +require 'ffi' + +module Foo + extend FFI::Library + ffi_lib FFI::Library::LIBC + attach_function :getpid, [ ], :int +end +puts "My pid=#{Foo.getpid}" diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/gettimeofday.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/gettimeofday.rb new file mode 100644 index 0000000..864bbb6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/gettimeofday.rb @@ -0,0 +1,18 @@ +require 'ffi' +require 'rbconfig' + +class Timeval < FFI::Struct + layout tv_sec: :ulong, tv_usec: :ulong +end +module LibC + extend FFI::Library + if FFI::Platform.windows? + ffi_lib RbConfig::CONFIG["LIBRUBY_SO"] + else + ffi_lib FFI::Library::LIBC + end + attach_function :gettimeofday, [ :pointer, :pointer ], :int +end +t = Timeval.new +LibC.gettimeofday(t.pointer, nil) +puts "t.tv_sec=#{t[:tv_sec]} t.tv_usec=#{t[:tv_usec]}" diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello.rb new file mode 100644 index 0000000..f2ccf37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello.rb @@ -0,0 +1,8 @@ +require 'ffi' + +module Foo + extend FFI::Library + ffi_lib FFI::Library::LIBC + attach_function("cputs", "puts", [ :string ], :int) +end +Foo.cputs("Hello, World via libc puts using FFI on MRI ruby") diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello_ractor.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello_ractor.rb new file mode 100644 index 0000000..9a01704 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/hello_ractor.rb @@ -0,0 +1,19 @@ +# See the ffi wiki for how to use FFI with Ractors: +# https://github.com/ffi/ffi/wiki/Ractors + +require 'ffi' + +class Ractor + # compat with Ruby-3.4 and older + alias value take unless method_defined? :value +end + +module Foo + extend FFI::Library + ffi_lib FFI::Library::LIBC + attach_function("cputs", "puts", [ :string ], :int) + freeze +end +Ractor.new do + Foo.cputs("Hello, World via libc puts using FFI in a Ractor") +end.value diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/inotify.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/inotify.rb new file mode 100644 index 0000000..018d78c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/inotify.rb @@ -0,0 +1,60 @@ +require 'ffi' + +module Inotify + extend FFI::Library + ffi_lib FFI::Library::LIBC + class Event < FFI::Struct + layout \ + :wd, :int, + :mask, :uint, + :cookie, :uint, + :len, :uint + end + attach_function :init, :inotify_init, [ ], :int + attach_function :add_watch, :inotify_add_watch, [ :int, :string, :uint ], :int + attach_function :rm_watch, :inotify_rm_watch, [ :int, :uint ], :int + attach_function :read, [ :int, :buffer_out, :uint ], :int + IN_ACCESS=0x00000001 + IN_MODIFY=0x00000002 + IN_ATTRIB=0x00000004 + IN_CLOSE_WRITE=0x00000008 + IN_CLOSE_NOWRITE=0x00000010 + IN_CLOSE=(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) + IN_OPEN=0x00000020 + IN_MOVED_FROM=0x00000040 + IN_MOVED_TO=0x00000080 + IN_MOVE= (IN_MOVED_FROM | IN_MOVED_TO) + IN_CREATE=0x00000100 + IN_DELETE=0x00000200 + IN_DELETE_SELF=0x00000400 + IN_MOVE_SELF=0x00000800 + # Events sent by the kernel. + IN_UNMOUNT=0x00002000 + IN_Q_OVERFLOW=0x00004000 + IN_IGNORED=0x00008000 + IN_ONLYDIR=0x01000000 + IN_DONT_FOLLOW=0x02000000 + IN_MASK_ADD=0x20000000 + IN_ISDIR=0x40000000 + IN_ONESHOT=0x80000000 + IN_ALL_EVENTS=(IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \ + | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM \ + | IN_MOVED_TO | IN_CREATE | IN_DELETE \ + | IN_DELETE_SELF | IN_MOVE_SELF) + +end +if $0 == __FILE__ + fd = Inotify.init + puts "fd=#{fd}" + wd = Inotify.add_watch(fd, "/tmp/", Inotify::IN_ALL_EVENTS) + fp = FFI::IO.for_fd(fd) + puts "wfp=#{fp}" + while true + buf = FFI::Buffer.alloc_out(Inotify::Event.size + 4096, 1, false) + ev = Inotify::Event.new buf + ready = IO.select([ fp ], nil, nil, nil) + n = Inotify.read(fd, buf, buf.total) + puts "Read #{n} bytes from inotify fd" + puts "event.wd=#{ev[:wd]} mask=#{ev[:mask]} len=#{ev[:len]} name=#{ev[:len] > 0 ? buf.get_string(16) : 'unknown'}" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/pty.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/pty.rb new file mode 100644 index 0000000..8b6b885 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/pty.rb @@ -0,0 +1,75 @@ +require 'ffi' + +module PTY + private + module LibC + extend FFI::Library + ffi_lib FFI::Library::LIBC + attach_function :forkpty, [ :buffer_out, :buffer_out, :buffer_in, :buffer_in ], :int + attach_function :openpty, [ :buffer_out, :buffer_out, :buffer_out, :buffer_in, :buffer_in ], :int + attach_function :login_tty, [ :int ], :int + attach_function :close, [ :int ], :int + attach_function :strerror, [ :int ], :string + attach_function :fork, [], :int + attach_function :execv, [ :string, :buffer_in ], :int + attach_function :execvp, [ :string, :buffer_in ], :int + attach_function :dup2, [ :int, :int ], :int + attach_function :dup, [ :int ], :int + end + Buffer = FFI::Buffer + def self.build_args(args) + cmd = args.shift + cmd_args = args.map do |arg| + MemoryPointer.from_string(arg) + end + exec_args = MemoryPointer.new(:pointer, 1 + cmd_args.length + 1) + exec_cmd = MemoryPointer.from_string(cmd) + exec_args[0].put_pointer(0, exec_cmd) + cmd_args.each_with_index do |arg, i| + exec_args[i + 1].put_pointer(0, arg) + end + [ cmd, exec_args ] + end + public + def self.getpty(*args) + mfdp = Buffer.new :int + name = Buffer.new 1024 + # + # All the execv setup is done in the parent, since doing anything other than + # execv in the child after fork is really flakey + # + exec_cmd, exec_args = build_args(args) + pid = LibC.forkpty(mfdp, name, nil, nil) + raise "forkpty failed: #{LibC.strerror(FFI.errno)}" if pid < 0 + if pid == 0 + LibC.execvp(exec_cmd, exec_args) + exit 1 + end + masterfd = mfdp.get_int(0) + rfp = FFI::IO.for_fd(masterfd, "r") + wfp = FFI::IO.for_fd(LibC.dup(masterfd), "w") + if block_given? + yield rfp, wfp, pid + rfp.close unless rfp.closed? + wfp.close unless wfp.closed? + else + [ rfp, wfp, pid ] + end + end + def self.spawn(*args, &block) + self.getpty("/bin/sh", "-c", args[0], &block) + end +end +module LibC + extend FFI::Library + attach_function :close, [ :int ], :int + attach_function :write, [ :int, :buffer_in, :ulong ], :long + attach_function :read, [ :int, :buffer_out, :ulong ], :long +end +PTY.getpty("/bin/ls", "-alR", "/") { |rfd, wfd, pid| +#PTY.spawn("ls -laR /") { |rfd, wfd, pid| + puts "child pid=#{pid}" + while !rfd.eof? && (buf = rfd.gets) + puts "child: '#{buf.strip}'" + end +} diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort.rb new file mode 100644 index 0000000..58622c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort.rb @@ -0,0 +1,20 @@ +require 'ffi' + +module LibC + extend FFI::Library + ffi_lib FFI::Library::LIBC + callback :qsort_cmp, [ :pointer, :pointer ], :int + attach_function :qsort, [ :pointer, :ulong, :ulong, :qsort_cmp ], :int +end + +p = FFI::MemoryPointer.new(:int, 2) +p.put_array_of_int32(0, [ 2, 1 ]) +puts "ptr=#{p.inspect}" +puts "Before qsort #{p.get_array_of_int32(0, 2).join(', ')}" +LibC.qsort(p, 2, 4) do |p1, p2| + i1 = p1.get_int32(0) + i2 = p2.get_int32(0) + puts "In block: comparing #{i1} and #{i2}" + i1 < i2 ? -1 : i1 > i2 ? 1 : 0 +end +puts "After qsort #{p.get_array_of_int32(0, 2).join(', ')}" diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort_ractor.rb b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort_ractor.rb new file mode 100644 index 0000000..7fe9afa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/samples/qsort_ractor.rb @@ -0,0 +1,36 @@ +# See the ffi wiki for how to use FFI with Ractors: +# https://github.com/ffi/ffi/wiki/Ractors + +require 'ffi' + +class Ractor + # compat with Ruby-3.4 and older + alias value take unless method_defined? :value +end + +module LibC + extend FFI::Library + ffi_lib FFI::Library::LIBC + callback :qsort_cmp, [ :pointer, :pointer ], :int + attach_function :qsort, [ :pointer, :ulong, :ulong, :qsort_cmp ], :int + + freeze # Freeze the module variables, so that it can be shared across ractors. +end + +p = FFI::MemoryPointer.new(:int, 3) +p.put_array_of_int32(0, [ 2, 3, 1 ]) # Write some unsorted data into the memory +# Ractor.make_shareable(p) # freeze the pointer to be shared between ractors instead of copied +puts "main -ptr=#{p.inspect}" +res = Ractor.new(p) do |p| + puts "ractor-ptr=#{p.inspect}" + puts "Before qsort #{p.get_array_of_int32(0, 3).join(', ')}" + LibC.qsort(p, 3, 4) do |p1, p2| + i1 = p1.get_int32(0) + i2 = p2.get_int32(0) + puts "In block: comparing #{i1} and #{i2}" + i1 < i2 ? -1 : i1 > i2 ? 1 : 0 + end + puts "After qsort #{p.get_array_of_int32(0, 3).join(', ')}" +end.value + +puts "After ractor termination #{p.get_array_of_int32(0, 3).join(', ')}" diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi.rbs new file mode 100644 index 0000000..6cba15f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi.rbs @@ -0,0 +1,29 @@ +module FFI + type ffi_type = Type | Symbol + type ffi_auto_type = ffi_type | DataConverter[untyped, untyped, untyped] + type type_map = Hash[Symbol | DataConverter[untyped, untyped, untyped], Type] + + class CallbackInfo = FunctionType + class FunctionInfo = FunctionType + class NativeLibrary = DynamicLibrary + + VERSION: String + TypeDefs: type_map + + type current_process = Object + CURRENT_PROCESS: current_process + USE_THIS_PROCESS_AS_LIBRARY: current_process + + class NotFoundError < LoadError + end + + private def self.custom_typedefs: () -> type_map + def self.errno: () -> Integer + def self.errno=: (Integer) -> Integer + def self.find_type: (ffi_auto_type name, ?type_map? type_map) -> Type + def self.make_shareable: [T] (T obj) -> T + def self.map_library_name: (_ToS lib) -> String + def self.type_size: (ffi_auto_type type) -> Integer + def self.typedef: (ffi_auto_type old, Symbol add) -> Type + alias self.add_typedef self.typedef +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/abstract_memory.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/abstract_memory.rbs new file mode 100644 index 0000000..9678ad0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/abstract_memory.rbs @@ -0,0 +1,165 @@ +module FFI + class AbstractMemory + interface _Size + def size: () -> Integer + end + include _Size + type type_size = Integer | _Size | Symbol + + type order_out = :big | :little + type order_in = order_out | :network + + def []: (Integer idx) -> instance + def clear: () -> self + def freeze: ... + def get: (ffi_type type, Integer offset) -> top + def put: (ffi_type type, Integer offset, top value) -> nil + def size_limit?: () -> bool + def type_size: () -> Integer + alias total size + + def get_int8: (Integer offset) -> Integer + def get_int16: (Integer offset) -> Integer + def get_int32: (Integer offset) -> Integer + def get_int64: (Integer offset) -> Integer + def get_uint8: (Integer offset) -> Integer + def get_uint16: (Integer offset) -> Integer + def get_uint32: (Integer offset) -> Integer + def get_uint64: (Integer offset) -> Integer + def get_char: (Integer offset) -> Integer + def get_short: (Integer offset) -> Integer + def get_int: (Integer offset) -> Integer + def get_long_long: (Integer offset) -> Integer + def get_float32: (Integer offset) -> Float + def get_float64: (Integer offset) -> Float + def get_pointer: (Integer offset) -> Pointer + def get_bytes: (Integer offset, Integer length) -> String + def get_string: (Integer offset, ?Integer? length) -> String + alias get_float get_float32 + alias get_double get_float64 + + def put_int8: (Integer offset, int value) -> self + def put_int16: (Integer offset, int value) -> self + def put_int32: (Integer offset, int value) -> self + def put_int64: (Integer offset, int value) -> self + def put_uint8: (Integer offset, int value) -> self + def put_uint16: (Integer offset, int value) -> self + def put_uint32: (Integer offset, int value) -> self + def put_uint64: (Integer offset, int value) -> self + def put_char: (Integer offset, int value) -> self + def put_short: (Integer offset, int value) -> self + def put_int: (Integer offset, int value) -> self + def put_long_long: (Integer offset, int value) -> self + def put_float32: (Integer offset, Numeric value) -> self + def put_float64: (Integer offset, Numeric value) -> self + def put_pointer: (Integer offset, pointer value) -> self + def put_bytes: (Integer offset, String str, ?Integer index, ?Integer? length) -> self + def put_string: (Integer offset, String value) -> self + alias put_float put_float32 + alias put_double put_float64 + + def read_int8: () -> Integer + def read_int16: () -> Integer + def read_int32: () -> Integer + def read_int64: () -> Integer + def read_uint8: () -> Integer + def read_uint16: () -> Integer + def read_uint32: () -> Integer + def read_uint64: () -> Integer + def read_char: () -> Integer + def read_short: () -> Integer + def read_int: () -> Integer + def read_long_long: () -> Integer + def read_float: () -> Float + def read_double: () -> Float + def read_pointer: () -> Pointer + def read_bytes: (Integer length) -> String + + def write_int8: (int value) -> self + def write_int16: (int value) -> self + def write_int32: (int value) -> self + def write_int64: (int value) -> self + def write_uint8: (int value) -> self + def write_uint16: (int value) -> self + def write_uint32: (int value) -> self + def write_uint64: (int value) -> self + def write_char: (int value) -> self + def write_short: (int value) -> self + def write_int: (int value) -> self + def write_long_long: (int value) -> self + def write_float: (Numeric value) -> self + def write_double: (Numeric value) -> self + def write_pointer: (pointer value) -> self + def write_bytes: (String str, ?Integer index, ?Integer? length) -> self + + def get_array_of_int8: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_int16: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_int32: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_int64: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_uint8: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_uint16: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_uint32: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_uint64: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_char: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_short: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_int: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_long_long: (Integer offset, Integer length) -> Array[Integer] + def get_array_of_float32: (Integer offset, Integer length) -> Array[Float] + def get_array_of_float64: (Integer offset, Integer length) -> Array[Float] + def get_array_of_pointer: (Integer offset, Integer length) -> Array[Pointer] + def get_array_of_string: (Integer offset, ?Integer? count) -> Array[String?] + alias get_array_of_float get_array_of_float32 + alias get_array_of_double get_array_of_float64 + + def put_array_of_int8: (Integer offset, Array[int] ary) -> self + def put_array_of_int16: (Integer offset, Array[int] ary) -> self + def put_array_of_int32: (Integer offset, Array[int] ary) -> self + def put_array_of_int64: (Integer offset, Array[int] ary) -> self + def put_array_of_uint8: (Integer offset, Array[int] ary) -> self + def put_array_of_uint16: (Integer offset, Array[int] ary) -> self + def put_array_of_uint32: (Integer offset, Array[int] ary) -> self + def put_array_of_uint64: (Integer offset, Array[int] ary) -> self + def put_array_of_char: (Integer offset, Array[int] ary) -> self + def put_array_of_short: (Integer offset, Array[int] ary) -> self + def put_array_of_int: (Integer offset, Array[int] ary) -> self + def put_array_of_long_long: (Integer offset, Array[int] ary) -> self + def put_array_of_float32: (Integer offset, Array[Numeric] ary) -> self + def put_array_of_float64: (Integer offset, Array[Numeric] ary) -> self + def put_array_of_pointer: (Integer offset, Array[pointer] ary) -> self + alias put_array_of_float put_array_of_float32 + alias put_array_of_double put_array_of_float64 + + def read_array_of_int8: (Integer length) -> Array[Integer] + def read_array_of_int16: (Integer length) -> Array[Integer] + def read_array_of_int32: (Integer length) -> Array[Integer] + def read_array_of_int64: (Integer length) -> Array[Integer] + def read_array_of_uint8: (Integer length) -> Array[Integer] + def read_array_of_uint16: (Integer length) -> Array[Integer] + def read_array_of_uint32: (Integer length) -> Array[Integer] + def read_array_of_uint64: (Integer length) -> Array[Integer] + def read_array_of_char: (Integer length) -> Array[Integer] + def read_array_of_short: (Integer length) -> Array[Integer] + def read_array_of_int: (Integer length) -> Array[Integer] + def read_array_of_long_long: (Integer length) -> Array[Integer] + def read_array_of_float: (Integer length) -> Array[Float] + def read_array_of_double: (Integer length) -> Array[Float] + def read_array_of_pointer: (Integer length) -> Array[Pointer] + def read_array_of_string: (?Integer? count) -> Array[String?] + + def write_array_of_int8: (Array[int] ary) -> self + def write_array_of_int16: (Array[int] ary) -> self + def write_array_of_int32: (Array[int] ary) -> self + def write_array_of_int64: (Array[int] ary) -> self + def write_array_of_uint8: (Array[int] ary) -> self + def write_array_of_uint16: (Array[int] ary) -> self + def write_array_of_uint32: (Array[int] ary) -> self + def write_array_of_uint64: (Array[int] ary) -> self + def write_array_of_char: (Array[int] ary) -> self + def write_array_of_short: (Array[int] ary) -> self + def write_array_of_int: (Array[int] ary) -> self + def write_array_of_long_long: (Array[int] ary) -> self + def write_array_of_float: (Array[Numeric] ary) -> self + def write_array_of_double: (Array[Numeric] ary) -> self + def write_array_of_pointer: (Array[pointer] ary) -> self + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/auto_pointer.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/auto_pointer.rbs new file mode 100644 index 0000000..21c7d04 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/auto_pointer.rbs @@ -0,0 +1,26 @@ +module FFI + class AutoPointer < Pointer + class Releaser + attr_accessor autorelease: boolish + interface _Proc[P < Pointer] + def call: (P) -> void + end + def initialize: [P < Pointer] (P ptr, _Proc[P] proc) -> void + + def call: (*untyped) -> void + def free: () -> nil + def release: (Pointer ptr) -> void + end + + def initialize: (Pointer pointer, Method | ^(instance) -> void | Releaser::_Proc[instance] callable) -> self + | (Pointer pointer) -> self # where class < `def self.release: (instance pointer) -> void` + + extend DataConverter[Pointer, instance, nil] + def self.from_native: ... + def self.native_type: () -> Type::Builtin + + def autorelease?: ... + def autorelease=: ... + def free: () -> nil + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/buffer.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/buffer.rbs new file mode 100644 index 0000000..68cde6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/buffer.rbs @@ -0,0 +1,18 @@ +module FFI + class Buffer < AbstractMemory + def initialize: (AbstractMemory::type_size, ?Integer count, boolish clear) -> self + alias self.alloc_inout self.new + alias self.new_inout self.alloc_inout + alias self.alloc_in self.alloc_inout + alias self.new_in self.alloc_in + alias self.alloc_out self.alloc_inout + alias self.new_out self.alloc_out + + def +: (Integer) -> Buffer + def inspect: ... + def order: () -> AbstractMemory::order_out + | (AbstractMemory::order_in order) -> Buffer + | (untyped order) -> (self | Buffer) + def slice: (Integer offset, Integer length) -> Buffer + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/data_converter.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/data_converter.rbs new file mode 100644 index 0000000..a0e2e39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/data_converter.rbs @@ -0,0 +1,10 @@ +module FFI + interface _DataConverter[N, R, in C] + def from_native: (N value, C ctx) -> R + def native_type: (?ffi_auto_type? type) -> Type + def to_native: (R value, C ctx) -> N + end + module DataConverter[N, R, in C] + include _DataConverter[N, R, C] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/dynamic_library.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/dynamic_library.rbs new file mode 100644 index 0000000..48031bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/dynamic_library.rbs @@ -0,0 +1,9 @@ +module FFI + class DynamicLibrary + # TODO + + class Symbol < Pointer + # TODO + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/enum.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/enum.rbs new file mode 100644 index 0000000..3cae0b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/enum.rbs @@ -0,0 +1,38 @@ +module FFI + class Enums + def initialize: () -> void + + def <<: (Enum enum) -> void + def __map_symbol: (Symbol symbol) -> Integer? + def find: (Symbol query) -> Enum + end + + class Enum + include DataConverter[Integer, Symbol | Integer, untyped] + + attr_reader native_type: Type + attr_reader tag: Symbol? + def initialize: (Enumerable[Symbol | Integer], ?Symbol? tag, *untyped) -> void + | (Type native_type, Enumerable[Symbol | Integer], ?Symbol? tag, *untyped) -> void + + def []: (Symbol query) -> Integer? + | (Integer query) -> Symbol? + def symbol_map: () -> Hash[Symbol, Integer] + alias to_h symbol_map + alias to_hash symbol_map + def symbols: () -> Array[Symbol] + def to_native: (Symbol | int value, untyped ctx) -> Integer + end + + class Bitmask < Enum + def initialize: ... + + def []: (*Symbol query) -> Integer + | (Array[Symbol] query) -> Integer + | (*Integer query) -> Array[Symbol] + | (Array[Integer] query) -> Array[Symbol] + def from_native: (Integer, untyped ctx) -> Array[Symbol | Integer] + def to_native: (Array[Symbol | int] value, untyped ctx) -> Integer + | ... + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/errno.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/errno.rbs new file mode 100644 index 0000000..2877cd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/errno.rbs @@ -0,0 +1,8 @@ +module FFI + module LastError + def self?.error: () -> Integer + def self?.error=: (Integer) -> Integer + def self?.winapi_error: () -> Integer? + def self?.winapi_error=: (Integer? error) -> void + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/function.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/function.rbs new file mode 100644 index 0000000..94a23c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/function.rbs @@ -0,0 +1,39 @@ +module FFI + interface _Function + # TODO: leads to a endless recursion when used with -rrbs/test/setup + # def attach: (Module mod, String name) -> self + def call: (*untyped args) -> untyped + def param_types: () -> Array[Type] + def return_type: () -> Type + end + + class Function < Pointer + include _Function + # ?blocking: boolish?, ?convention: Library::convention?, ?enums: Enums? + def initialize: + ( + ffi_type return_type, Array[ffi_type] param_types, + ?Hash[Symbol, untyped] options + ) { (*untyped) -> untyped } -> self + | ( + ffi_type return_type, Array[ffi_type] param_types, Proc | Pointer proc, + ?Hash[Symbol, untyped] options + ) -> self + + def autorelease?: ... + alias autorelease autorelease? + def autorelease=: ... + def free: () -> self + end + + class VariadicInvoker + include _Function + def initialize: + ( + Pointer function, Array[ffi_type] parameter_types, ffi_type return_type, + Hash[Symbol, untyped] options #TODO + ) -> void + + def invoke: (Array[Type] parameter_types, Array[untyped] parameter_values) -> untyped + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/library.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/library.rbs new file mode 100644 index 0000000..e823b6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/library.rbs @@ -0,0 +1,42 @@ +module FFI + module Library + type convention = :default | :stdcall + type ffi_lib_flag = :global | :local | :lazy | :now + type ffi_lib_type = ffi_auto_type | singleton(Struct) + + CURRENT_PROCESS: current_process + LIBC: String + FlagsMap: Hash[ffi_lib_flag, Integer] + + def self.extended: ... + + def attach_function: ( _ToS func, Array[ffi_lib_type] args, ffi_lib_type? returns, ?blocking: boolish, ?convention: convention, ?enums: Enums, ?type_map: type_map) -> (Function | VariadicInvoker) + | (_ToS name, _ToS func, Array[ffi_lib_type] args, ?ffi_lib_type? returns, ?blocking: boolish, ?convention: convention, ?enums: Enums, ?type_map: type_map) -> (Function | VariadicInvoker) + def attach_variable: (?_ToS mname, _ToS cname, ffi_lib_type type) -> DynamicLibrary::Symbol + def attached_functions: () -> Hash[Symbol, Function | VariadicInvoker] + def attached_variables: () -> Hash[Symbol, Type | singleton(Struct)] + + def bitmask: (?Type native_type, Symbol name, Array[Symbol | Integer] values) -> Bitmask + | (?Type native_type, *Symbol | Integer args) -> Bitmask + | (?Type native_type, Array[Symbol | Integer] values) -> Bitmask + def enum: (?Type native_type, Symbol name, Array[Symbol | Integer] values) -> Enum + | (?Type native_type, *Symbol | Integer args) -> Enum + | (?Type native_type, Array[Symbol | Integer] values) -> Enum + def enum_type: (Symbol name) -> Enum? + def enum_for: (Symbol name) -> Integer? + + def callback: (?Symbol name, Array[ffi_lib_type] params, ffi_lib_type ret) -> CallbackInfo + def ffi_convention: (?convention? convention) -> convention + def ffi_lib: (*_ToS names) -> Array[DynamicLibrary] + def ffi_lib_flags: (*ffi_lib_flag flags) -> Integer + def ffi_libraries: () -> Array[DynamicLibrary] + def find_type: (ffi_lib_type t) -> Type + def freeze: () -> void + def function_names: (_ToS name, Array[Type | singleton(Struct)] arg_types) -> Array[String] + def typedef: [T < Type, N, R, C] (T old, Symbol | DataConverter[N, R, C] add, ?untyped) -> T + | (Symbol old, Symbol add, ?untyped) -> (Type | Enum) + | [X < DataConverter[N, R, C], N, R, C] (X old, Symbol add, ?untyped) -> Type::Mapped[X, N, R, C] + | (:enum old, Array[Symbol | Integer] add, ?untyped) -> Enum + | (:enum old, Symbol | Type add, Array[Symbol | Integer] info) -> Enum + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/native_type.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/native_type.rbs new file mode 100644 index 0000000..c9617a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/native_type.rbs @@ -0,0 +1,86 @@ +module FFI + class Type + INT8: Builtin + SCHAR: Builtin + CHAR: Builtin + UINT8: Builtin + UCHAR: Builtin + INT16: Builtin + SHORT: Builtin + SSHORT: Builtin + UINT16: Builtin + USHORT: Builtin + INT32: Builtin + INT: Builtin + SINT: Builtin + UINT32: Builtin + UINT: Builtin + INT64: Builtin + LONG_LONG: Builtin + SLONG_LONG: Builtin + UINT64: Builtin + ULONG_LONG: Builtin + LONG: Builtin + SLONG: Builtin + ULONG: Builtin + FLOAT32: Builtin + FLOAT: Builtin + FLOAT64: Builtin + DOUBLE: Builtin + LONGDOUBLE: Builtin + POINTER: Builtin + BOOL: Builtin + STRING: Builtin + BUFFER_IN: Builtin + BUFFER_OUT: Builtin + BUFFER_INOUT: Builtin + VARARGS: Builtin + VOID: Builtin + end + + module NativeType + INT8: Type::Builtin + UINT8: Type::Builtin + INT16: Type::Builtin + UINT16: Type::Builtin + INT32: Type::Builtin + UINT32: Type::Builtin + INT64: Type::Builtin + UINT64: Type::Builtin + LONG: Type::Builtin + ULONG: Type::Builtin + FLOAT32: Type::Builtin + FLOAT64: Type::Builtin + LONGDOUBLE: Type::Builtin + POINTER: Type::Builtin + BOOL: Type::Builtin + STRING: Type::Builtin + BUFFER_IN: Type::Builtin + BUFFER_OUT: Type::Builtin + BUFFER_INOUT: Type::Builtin + VARARGS: Type::Builtin + VOID: Type::Builtin + end + + TYPE_INT8: Type::Builtin + TYPE_UINT8: Type::Builtin + TYPE_INT16: Type::Builtin + TYPE_UINT16: Type::Builtin + TYPE_INT32: Type::Builtin + TYPE_UINT32: Type::Builtin + TYPE_INT64: Type::Builtin + TYPE_UINT64: Type::Builtin + TYPE_LONG: Type::Builtin + TYPE_ULONG: Type::Builtin + TYPE_FLOAT32: Type::Builtin + TYPE_FLOAT64: Type::Builtin + TYPE_LONGDOUBLE: Type::Builtin + TYPE_POINTER: Type::Builtin + TYPE_BOOL: Type::Builtin + TYPE_STRING: Type::Builtin + TYPE_BUFFER_IN: Type::Builtin + TYPE_BUFFER_OUT: Type::Builtin + TYPE_BUFFER_INOUT: Type::Builtin + TYPE_VARARGS: Type::Builtin + TYPE_VOID: Type::Builtin +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/platform.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/platform.rbs new file mode 100644 index 0000000..b51188a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/platform.rbs @@ -0,0 +1,49 @@ +module FFI + class PlatformError < LoadError + end + + module Platform + OS: String + + OSVERSION: Integer + + CPU: String + + ARCH: String + + IS_GNU: bool + IS_LINUX: bool + IS_MAC: bool + IS_FREEBSD: bool + IS_NETBSD: bool + IS_OPENBSD: bool + IS_DRAGONFLYBSD: bool + IS_SOLARIS: bool + IS_WINDOWS: bool + IS_BSD: bool + + NAME: String + + CONF_DIR: String + + LIBPREFIX: String + + LIBSUFFIX: String + + LIBC: String + + LITTLE_ENDIAN: Integer + + BIG_ENDIAN: Integer + + def self.bsd?: () -> bool + def self.windows?: () -> bool + def self.mac?: () -> bool + def self.solaris?: () -> bool + def self.unix?: () -> bool + + private + + def self.is_os: (String os) -> bool + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/pointer.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/pointer.rbs new file mode 100644 index 0000000..fd4e9b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/pointer.rbs @@ -0,0 +1,42 @@ +module FFI + type pointer = Pointer::_ToPtr? | Integer + class Pointer < AbstractMemory + interface _ToPtr + def to_ptr: () -> Pointer + end + include _ToPtr + + SIZE: Integer + NULL: Pointer + def self.size: () -> Integer + + def initialize: (?AbstractMemory::type_size type, (Pointer | Integer) address) -> void + def +: (Integer offset) -> Pointer + def ==: (Pointer? other) -> bool + def address: () -> Integer + alias to_i address + def autorelease?: () -> bool + def autorelease=: (boolish autorelease) -> boolish + def free: () -> self + def inspect: ... + def null?: () -> bool + def order: () -> AbstractMemory::order_out + | (AbstractMemory::order_in) -> Pointer + def read: (ffi_type type) -> top + def read_array_of_type: (ffi_auto_type type, Symbol reader, Integer length) -> Array[top] + def read_string: (?Integer? len) -> String + def read_string_length: (Integer len) -> String + def read_string_to_null: () -> String + def slice: (Integer offset, Integer length) -> Pointer + def type_size: () -> Integer + def write: (ffi_type type, top value) -> nil + def write_array_of_type: (ffi_auto_type type, Symbol writer, Array[top]) -> self + def write_string: (String str, ?Integer? len) -> self + def write_string_length: (String str, Integer len) -> self + end + + class MemoryPointer < Pointer + def initialize: (AbstractMemory::type_size size, ?Integer count, ?boolish clear) -> self + def self.from_string: (String s) -> instance + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct.rbs new file mode 100644 index 0000000..27b4d5a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct.rbs @@ -0,0 +1,76 @@ +module FFI + class Struct[out P < AbstractMemory, unchecked out E] + type layout = Library::ffi_lib_type | singleton(StructLayout::Field) | [layout, Integer] + + type ptr = Type::Mapped[ + StructByReference[Struct[AbstractMemory, untyped], AbstractMemory], + AbstractMemory, Struct[AbstractMemory, untyped], untyped + ] + def self.ptr: (?untyped flags) -> ptr # https://github.com/ffi/ffi/issues/1073 + alias self.by_ref self.ptr + def self.in: () -> ptr + def self.out: () -> ptr + def self.val: () -> StructByValue[singleton(Struct)] + alias self.by_value self.val + + alias self.alloc_inout self.new + alias self.alloc_in self.new + alias self.alloc_out self.new + alias self.new_inout self.new + alias self.new_in self.new + alias self.new_out self.new + + def self.auto_ptr: () -> Type::Mapped[ + ManagedStructConverter[ManagedStruct[AutoPointer, untyped], AutoPointer], + Pointer, ManagedStruct[AutoPointer, untyped], untyped + ] + def self.layout: (*layout | Integer) -> StructLayout + | (Hash[Symbol, layout]) -> StructLayout + def self.size=: (Integer size) -> Integer + + def self?.alignment: () -> Integer + def self?.members: () -> Array[Symbol] + def self?.offset_of: (Symbol name) -> Integer + def self?.offsets: () -> Array[[Symbol, Integer]] + def self?.size: -> Integer + + def initialize: (?P pointer, *layout args) -> void + def []: (Symbol field_name) -> E + def []=: (Symbol field_name, E value) -> E + alias align alignment + def clear: () -> self + def layout: () -> StructLayout + def null?: () -> bool + def order: (AbstractMemory::order_in order) -> Struct[P, E] + | () -> AbstractMemory::order_out + def pointer: () -> P + alias to_ptr pointer + def values: () -> Array[E] + + class InlineArray[out P < AbstractMemory, unchecked out E] + include Enumerable[E] + include AbstractMemory::_Size + + def initialize: (P memory, StructLayout::Field field) -> self + def []: (Integer index) -> E + def []=: (Integer index, E value) -> E + def each: () { (E) -> void } -> self + def to_a: () -> Array[E] + def to_ptr: () -> P + end + + class ManagedStructConverter[S < ManagedStruct[P, untyped], P < AutoPointer] < StructByReference[S, P] + def initialize: ... + def from_native: (Pointer ptr, untyped ctx) -> S + end + end + + class ManagedStruct[out P < AutoPointer, unchecked out E] < Struct[P, E] + def self.release: (AbstractMemory ptr) -> void + def initialize: (Pointer pointer) -> self + end + + class Union[out P < AbstractMemory, unchecked out E] < Struct[P, E] + def self.builder: () -> StructLayoutBuilder + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_reference.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_reference.rbs new file mode 100644 index 0000000..20ea2f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_reference.rbs @@ -0,0 +1,11 @@ +module FFI + class StructByReference[S < Struct[P, untyped], P < AbstractMemory] + include DataConverter[P, S, untyped] + attr_reader struct_class: Struct[P, untyped] + + def initialize: (S struct_class) -> void + def from_native: (P value, untyped ctx) -> S + def native_type: (?ffi_auto_type? type) -> Type + def to_native: (S? value, untyped ctx) -> P + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_value.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_value.rbs new file mode 100644 index 0000000..902bcc6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_by_value.rbs @@ -0,0 +1,7 @@ +module FFI + class StructByValue[C < singleton(Struct)] < Type + def initialize: (C) -> self + def layout: () -> StructLayout + def struct_class: () -> C + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout.rbs new file mode 100644 index 0000000..12b05ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout.rbs @@ -0,0 +1,9 @@ +module FFI + class StructLayout + #TODO + + class Field + #TODO + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout_builder.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout_builder.rbs new file mode 100644 index 0000000..291a669 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/struct_layout_builder.rbs @@ -0,0 +1,5 @@ +module FFI + class StructLayoutBuilder + #TODO + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/type.rbs b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/type.rbs new file mode 100644 index 0000000..66186d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ffi-1.17.4-arm64-darwin/sig/ffi/type.rbs @@ -0,0 +1,39 @@ +module FFI + class Type + class Array = ArrayType + class Function = FunctionType + class Struct = StructByValue + + include AbstractMemory::_Size + def initialize: (Integer | Type value) -> self + def alignment: () -> Integer + def inspect: ... + + class Builtin < Type + def inspect: ... + end + + class Mapped[X < _DataConverter[N, R, C], N, R, C] + include _DataConverter[N, R, C] + + def initialize: (X converter) -> self + def converter: () -> X + end + end + + class ArrayType + def initialize: (Type component_type, Integer length) -> self + def element_type: -> Type + def length: -> Integer + end + + class FunctionType < Type + def initialize: + ( + ffi_type return_type, Array[ffi_type] param_types, + ?blocking: boolish, ?convention: Library::convention, ?enums: Enums + ) -> self + def param_types: () -> Array[Type] + def return_type: () -> Type + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/Rakefile b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/Rakefile new file mode 100755 index 0000000..0d4f84e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/Rakefile @@ -0,0 +1,3 @@ +import '../../../lib/google/tasks/ffi.rake' + +task default: ['ffi-protobuf:default'] \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.c new file mode 100755 index 0000000..d2b7094 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.c @@ -0,0 +1,335 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby <-> upb data conversion functions. +// +// This file Also contains a few other assorted algorithms on upb_MessageValue. +// +// None of the algorithms in this file require any access to the internal +// representation of Ruby or upb objects. +// ----------------------------------------------------------------------------- + +#include "convert.h" + +#include "message.h" +#include "protobuf.h" +#include "shared_convert.h" + +static upb_StringView Convert_StringData(VALUE str, upb_Arena* arena) { + upb_StringView ret; + if (arena) { + char* ptr = upb_Arena_Malloc(arena, RSTRING_LEN(str)); + memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str)); + ret.data = ptr; + } else { + // Data is only needed temporarily (within map lookup). + ret.data = RSTRING_PTR(str); + } + ret.size = RSTRING_LEN(str); + return ret; +} + +static bool is_ruby_num(VALUE value) { + return (TYPE(value) == T_FLOAT || TYPE(value) == T_FIXNUM || + TYPE(value) == T_BIGNUM); +} + +static void Convert_CheckInt(const char* name, upb_CType type, VALUE val) { + if (!is_ruby_num(val)) { + rb_raise(cTypeError, + "Expected number type for integral field '%s' (given %s).", name, + rb_class2name(CLASS_OF(val))); + } + + // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper + // bound; we just need to do precision checks (i.e., disallow rounding) and + // check for < 0 on unsigned types. + if (TYPE(val) == T_FLOAT) { + double dbl_val = NUM2DBL(val); + if (floor(dbl_val) != dbl_val) { + rb_raise(rb_eRangeError, + "Non-integral floating point value assigned to integer field " + "'%s' (given %s).", + name, rb_class2name(CLASS_OF(val))); + } + } + if (type == kUpb_CType_UInt32 || type == kUpb_CType_UInt64) { + if (NUM2DBL(val) < 0) { + rb_raise( + rb_eRangeError, + "Assigning negative value to unsigned integer field '%s' (given %s).", + name, rb_class2name(CLASS_OF(val))); + } + } +} + +static int32_t Convert_ToEnum(VALUE value, const char* name, + const upb_EnumDef* e) { + int32_t val; + + switch (TYPE(value)) { + case T_FLOAT: + case T_FIXNUM: + case T_BIGNUM: + Convert_CheckInt(name, kUpb_CType_Int32, value); + val = NUM2INT(value); + break; + case T_STRING: { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize( + e, RSTRING_PTR(value), RSTRING_LEN(value)); + if (!ev) goto unknownval; + val = upb_EnumValueDef_Number(ev); + break; + } + case T_SYMBOL: { + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByName(e, rb_id2name(SYM2ID(value))); + if (!ev) goto unknownval; + val = upb_EnumValueDef_Number(ev); + break; + } + default: + rb_raise(cTypeError, + "Expected number or symbol type for enum field '%s'.", name); + } + + return val; + +unknownval: + rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name); +} + +VALUE Convert_CheckStringUtf8(VALUE str) { + VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding()); + + if (rb_obj_encoding(str) == utf8) { + // Note: Just because a string is marked as having UTF-8 encoding does + // not mean that it is *valid* UTF-8. We have to check separately + // whether it is valid. + if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) { + VALUE exc = rb_const_get_at( + rb_cEncoding, rb_intern("InvalidByteSequenceError")); + rb_raise(exc, "String is invalid UTF-8"); + } + } else { + // Note: this will not duplicate underlying string data unless + // necessary. + // + // This will throw an exception if the conversion cannot be performed: + // - Encoding::UndefinedConversionError if certain characters cannot be + // converted to UTF-8. + // - Encoding::InvalidByteSequenceError if certain characters were invalid + // in the source encoding. + str = rb_str_encode(str, utf8, 0, Qnil); + PBRUBY_ASSERT(rb_enc_str_coderange(str) != ENC_CODERANGE_BROKEN); + } + + return str; +} + +upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name, + TypeInfo type_info, upb_Arena* arena) { + upb_MessageValue ret; + + switch (type_info.type) { + case kUpb_CType_Float: + if (!is_ruby_num(value)) { + rb_raise(cTypeError, + "Expected number type for float field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + ret.float_val = NUM2DBL(value); + break; + case kUpb_CType_Double: + if (!is_ruby_num(value)) { + rb_raise(cTypeError, + "Expected number type for double field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + ret.double_val = NUM2DBL(value); + break; + case kUpb_CType_Bool: { + if (value == Qtrue) { + ret.bool_val = 1; + } else if (value == Qfalse) { + ret.bool_val = 0; + } else { + rb_raise(cTypeError, + "Invalid argument for boolean field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + break; + } + case kUpb_CType_String: + if (rb_obj_class(value) == rb_cSymbol) { + value = rb_funcall(value, rb_intern("to_s"), 0); + } else if (!rb_obj_is_kind_of(value, rb_cString)) { + rb_raise(cTypeError, + "Invalid argument for string field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + + value = Convert_CheckStringUtf8(value); + ret.str_val = Convert_StringData(value, arena); + break; + case kUpb_CType_Bytes: { + VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding()); + if (rb_obj_class(value) != rb_cString) { + rb_raise(cTypeError, + "Invalid argument for bytes field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + + if (rb_obj_encoding(value) != bytes) { + // Note: this will not duplicate underlying string data unless + // necessary. + // TODO: is this really necessary to get raw bytes? + value = rb_str_encode(value, bytes, 0, Qnil); + } + + ret.str_val = Convert_StringData(value, arena); + break; + } + case kUpb_CType_Message: + ret.msg_val = + Message_GetUpbMessage(value, type_info.def.msgdef, name, arena); + break; + case kUpb_CType_Enum: + ret.int32_val = Convert_ToEnum(value, name, type_info.def.enumdef); + break; + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + Convert_CheckInt(name, type_info.type, value); + switch (type_info.type) { + case kUpb_CType_Int32: + ret.int32_val = NUM2INT(value); + break; + case kUpb_CType_Int64: + ret.int64_val = NUM2LL(value); + break; + case kUpb_CType_UInt32: + ret.uint32_val = NUM2UINT(value); + break; + case kUpb_CType_UInt64: + ret.uint64_val = NUM2ULL(value); + break; + default: + rb_raise(cTypeError, "Convert_RubyToUpb(): Unexpected type %d", + (int)type_info.type); + } + break; + default: + rb_raise(cTypeError, + "Convert_RubyToUpb(): Unexpected type %d", (int)type_info.type); + } + + return ret; +} + +VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info, + VALUE arena) { + switch (type_info.type) { + case kUpb_CType_Float: + return DBL2NUM(upb_val.float_val); + case kUpb_CType_Double: + return DBL2NUM(upb_val.double_val); + case kUpb_CType_Bool: + return upb_val.bool_val ? Qtrue : Qfalse; + case kUpb_CType_Int32: + return INT2NUM(upb_val.int32_val); + case kUpb_CType_Int64: + return LL2NUM(upb_val.int64_val); + case kUpb_CType_UInt32: + return UINT2NUM(upb_val.uint32_val); + case kUpb_CType_UInt64: + return ULL2NUM(upb_val.int64_val); + case kUpb_CType_Enum: { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber( + type_info.def.enumdef, upb_val.int32_val); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + } else { + return INT2NUM(upb_val.int32_val); + } + } + case kUpb_CType_String: { + VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); + rb_enc_associate(str_rb, rb_utf8_encoding()); + rb_obj_freeze(str_rb); + return str_rb; + } + case kUpb_CType_Bytes: { + VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); + rb_enc_associate(str_rb, rb_ascii8bit_encoding()); + rb_obj_freeze(str_rb); + return str_rb; + } + case kUpb_CType_Message: + return Message_GetRubyWrapper((upb_Message*)upb_val.msg_val, + type_info.def.msgdef, arena); + default: + rb_raise(rb_eRuntimeError, "Convert_UpbToRuby(): Unexpected type %d", + (int)type_info.type); + } +} + +upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info, + upb_Arena* arena) { + upb_MessageValue new_msgval; + + switch (type_info.type) { + default: + memcpy(&new_msgval, &msgval, sizeof(msgval)); + break; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + size_t n = msgval.str_val.size; + char* mem = upb_Arena_Malloc(arena, n); + new_msgval.str_val.data = mem; + new_msgval.str_val.size = n; + memcpy(mem, msgval.str_val.data, n); + break; + } + case kUpb_CType_Message: + new_msgval.msg_val = + Message_deep_copy(msgval.msg_val, type_info.def.msgdef, arena); + break; + } + + return new_msgval; +} + +bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + TypeInfo type_info) { + upb_Status status; + upb_Status_Clear(&status); + bool return_value = shared_Msgval_IsEqual(val1, val2, type_info.type, + type_info.def.msgdef, &status); + if (upb_Status_IsOk(&status)) { + return return_value; + } else { + rb_raise(rb_eRuntimeError, "Msgval_IsEqual(): %s", + upb_Status_ErrorMessage(&status)); + } +} + +uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info, + uint64_t seed) { + upb_Status status; + upb_Status_Clear(&status); + uint64_t return_value = shared_Msgval_GetHash( + val, type_info.type, type_info.def.msgdef, seed, &status); + if (upb_Status_IsOk(&status)) { + return return_value; + } else { + rb_raise(rb_eRuntimeError, "Msgval_GetHash(): %s", + upb_Status_ErrorMessage(&status)); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.h new file mode 100755 index 0000000..ac3eaab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.h @@ -0,0 +1,50 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_CONVERT_H_ +#define RUBY_PROTOBUF_CONVERT_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Converts |ruby_val| to a upb_MessageValue according to |type_info|. +// +// The |arena| parameter indicates the lifetime of the container where this +// value will be assigned. It is used as follows: +// - If type is string or bytes, the string data will be copied into |arena|. +// - If type is message, and we need to auto-construct a message due to implicit +// conversions (eg. Time -> Google::Protobuf::Timestamp), the new message +// will be created in |arena|. +// - If type is message and the Ruby value is a message instance, we will fuse +// the message's arena into |arena|, to ensure that this message outlives the +// container. +upb_MessageValue Convert_RubyToUpb(VALUE ruby_val, const char *name, + TypeInfo type_info, upb_Arena *arena); + +// Converts |upb_val| to a Ruby VALUE according to |type_info|. This may involve +// creating a Ruby wrapper object. +// +// The |arena| parameter indicates the arena that owns the lifetime of +// |upb_val|. Any Ruby wrapper object that is created will reference |arena| +// and ensure it outlives the wrapper. +VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info, + VALUE arena); + +// Creates a deep copy of |msgval| in |arena|. +upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info, + upb_Arena *arena); + +// Returns true if |val1| and |val2| are equal. Their type is given by +// |type_info|. +bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + TypeInfo type_info); + +// Returns a hash value for the given upb_MessageValue. +uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info, + uint64_t seed); + +#endif // RUBY_PROTOBUF_CONVERT_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.c new file mode 100755 index 0000000..5bc405f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.c @@ -0,0 +1,2084 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include +#include + +#include "convert.h" +#include "message.h" +#include "protobuf.h" + +// ----------------------------------------------------------------------------- +// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor +// instances. +// ----------------------------------------------------------------------------- + +static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def); +static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def); +static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def); +static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def); +static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def); +static VALUE get_servicedef_obj(VALUE descriptor_pool, + const upb_ServiceDef* def); +static VALUE get_methoddef_obj(VALUE descriptor_pool, const upb_MethodDef* def); + +// A distinct object that is not accessible from Ruby. We use this as a +// constructor argument to enforce that certain objects cannot be created from +// Ruby. +VALUE c_only_cookie = Qnil; + +// ----------------------------------------------------------------------------- +// Common utilities. +// ----------------------------------------------------------------------------- + +static const char* get_str(VALUE str) { + Check_Type(str, T_STRING); + return RSTRING_PTR(str); +} + +static VALUE rb_str_maybe_null(const char* s) { + if (s == NULL) { + s = ""; + } + return rb_str_new2(s); +} +static ID options_instancevar_interned; +// ----------------------------------------------------------------------------- +// DescriptorPool. +// ----------------------------------------------------------------------------- + +typedef struct { + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor. + upb_DefPool* symtab; +} DescriptorPool; + +VALUE cDescriptorPool = Qnil; + +// Global singleton DescriptorPool. The user is free to create others, but this +// is used by generated code. +VALUE generated_pool = Qnil; + +static void DescriptorPool_mark(void* _self) { + DescriptorPool* self = _self; + rb_gc_mark(self->def_to_descriptor); +} + +static void DescriptorPool_free(void* _self) { + DescriptorPool* self = _self; + upb_DefPool_Free(self->symtab); + xfree(self); +} + +static const rb_data_type_t DescriptorPool_type = { + "Google::Protobuf::DescriptorPool", + {DescriptorPool_mark, DescriptorPool_free, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static DescriptorPool* ruby_to_DescriptorPool(VALUE val) { + DescriptorPool* ret; + TypedData_Get_Struct(val, DescriptorPool, &DescriptorPool_type, ret); + return ret; +} + +// Exposed to other modules in defs.h. +const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb) { + DescriptorPool* pool = ruby_to_DescriptorPool(desc_pool_rb); + return pool->symtab; +} + +/** + * ruby-doc: DescriptorPool + * + * A DescriptorPool is the registry of all known Protobuf descriptor objects. + * + */ + +/* + * ruby-doc: DescriptorPool.new + * + * Creates a new, empty, descriptor pool. + */ +static VALUE DescriptorPool_alloc(VALUE klass) { + DescriptorPool* self = ALLOC(DescriptorPool); + VALUE ret; + + self->def_to_descriptor = Qnil; + ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self); + + RB_OBJ_WRITE(ret, &self->def_to_descriptor, rb_hash_new()); + self->symtab = upb_DefPool_New(); + + // Ruby treats all enums as open. + upb_DefPool_DisableClosedEnumChecking(self->symtab); + + return ObjectCache_TryAdd(self->symtab, ret); +} + +/* + * ruby-doc: DescriptorPool#add_serialized_file + * + * Adds the given serialized + * {https://protobuf.com/docs/descriptors#file-descriptors FileDescriptorProto} + * to the pool. + * + * @param serialized_file_proto [String] + * @return [FileDescriptor] + */ +VALUE DescriptorPool_add_serialized_file(VALUE _self, + VALUE serialized_file_proto) { + DescriptorPool* self = ruby_to_DescriptorPool(_self); + Check_Type(serialized_file_proto, T_STRING); + VALUE arena_rb = Arena_new(); + upb_Arena* arena = Arena_get(arena_rb); + google_protobuf_FileDescriptorProto* file_proto = + google_protobuf_FileDescriptorProto_parse( + RSTRING_PTR(serialized_file_proto), + RSTRING_LEN(serialized_file_proto), arena); + if (!file_proto) { + rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto"); + } + upb_Status status; + upb_Status_Clear(&status); + const upb_FileDef* filedef = + upb_DefPool_AddFile(self->symtab, file_proto, &status); + if (!filedef) { + rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s", + upb_Status_ErrorMessage(&status)); + } + RB_GC_GUARD(arena_rb); + return get_filedef_obj(_self, filedef); +} + +/* + * ruby-doc: DescriptorPool#lookup + * + * Finds a {Descriptor}, {EnumDescriptor}, + * {FieldDescriptor} or {ServiceDescriptor} by + * name and returns it, or nil if none exists with the given name. + * + * @param name [String] + * @return [Descriptor,EnumDescriptor,FieldDescriptor,ServiceDescriptor] + */ +static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) { + DescriptorPool* self = ruby_to_DescriptorPool(_self); + const char* name_str = get_str(name); + const upb_MessageDef* msgdef; + const upb_EnumDef* enumdef; + const upb_FieldDef* fielddef; + const upb_ServiceDef* servicedef; + const upb_FileDef* filedef; + + msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str); + if (msgdef) { + return get_msgdef_obj(_self, msgdef); + } + + fielddef = upb_DefPool_FindExtensionByName(self->symtab, name_str); + if (fielddef) { + return get_fielddef_obj(_self, fielddef); + } + + enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str); + if (enumdef) { + return get_enumdef_obj(_self, enumdef); + } + + servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str); + if (servicedef) { + return get_servicedef_obj(_self, servicedef); + } + + filedef = upb_DefPool_FindFileByName(self->symtab, name_str); + if (filedef) { + return get_filedef_obj(_self, filedef); + } + + return Qnil; +} + +/* + * ruby-doc: DescriptorPool.generated_pool + * + * Class method that returns the global {DescriptorPool}. This is a singleton + * into which generated-code message and enum types are registered. The user may + * also register types in this pool for convenience so that they do not have to + * hold a reference to a private pool instance. + * + * @return [DescriptorPool] + */ +static VALUE DescriptorPool_generated_pool(VALUE _self) { + return generated_pool; +} + +static void DescriptorPool_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "DescriptorPool", rb_cObject); + rb_define_alloc_func(klass, DescriptorPool_alloc); + rb_define_method(klass, "add_serialized_file", + DescriptorPool_add_serialized_file, 1); + rb_define_method(klass, "lookup", DescriptorPool_lookup, 1); + rb_define_singleton_method(klass, "generated_pool", + DescriptorPool_generated_pool, 0); + rb_gc_register_address(&cDescriptorPool); + cDescriptorPool = klass; + + rb_gc_register_address(&generated_pool); + generated_pool = rb_class_new_instance(0, NULL, klass); + options_instancevar_interned = rb_intern("options"); +} + +// ----------------------------------------------------------------------------- +// Descriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_MessageDef* msgdef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE klass; + VALUE descriptor_pool; +} Descriptor; + +VALUE cDescriptor = Qnil; + +static void Descriptor_mark(void* _self) { + Descriptor* self = _self; + rb_gc_mark(self->klass); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t Descriptor_type = { + "Google::Protobuf::Descriptor", + {Descriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static Descriptor* ruby_to_Descriptor(VALUE val) { + Descriptor* ret; + TypedData_Get_Struct(val, Descriptor, &Descriptor_type, ret); + return ret; +} + +// Decode and return a frozen instance of a Descriptor Option for the given pool +static VALUE decode_options(VALUE self, const char* option_type, int size, + const char* bytes, VALUE descriptor_pool) { + VALUE options_rb = rb_ivar_get(self, options_instancevar_interned); + if (options_rb != Qnil) { + return options_rb; + } + + static const char* prefix = "google.protobuf."; + char fullname + [/*strlen(prefix)*/ 16 + + /*strln(longest option type supported e.g. "MessageOptions")*/ 14 + + /*null terminator*/ 1]; + + snprintf(fullname, sizeof(fullname), "%s%s", prefix, option_type); + const upb_MessageDef* msgdef = upb_DefPool_FindMessageByName( + ruby_to_DescriptorPool(descriptor_pool)->symtab, fullname); + if (!msgdef) { + rb_raise(rb_eRuntimeError, "Cannot find %s in DescriptorPool", option_type); + } + + VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef); + const Descriptor* desc = ruby_to_Descriptor(desc_rb); + + options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, false); + + // Strip features from the options proto to keep it internal. + const upb_MessageDef* decoded_desc = NULL; + upb_Message* options = Message_GetMutable(options_rb, &decoded_desc); + PBRUBY_ASSERT(options != NULL); + PBRUBY_ASSERT(decoded_desc == msgdef); + const upb_FieldDef* field = + upb_MessageDef_FindFieldByName(decoded_desc, "features"); + PBRUBY_ASSERT(field != NULL); + upb_Message_ClearFieldByDef(options, field); + + Message_freeze(options_rb); + + rb_ivar_set(self, options_instancevar_interned, options_rb); + return options_rb; +} + +/* + * ruby-doc: Descriptor + * + * A Descriptor provides information about a given Protobuf definition. + */ + +/* + * ruby-doc: Descriptor.initialize + * + * Creates a new, empty, message type descriptor. At a minimum, its name must be + * set before it is added to a pool. It cannot be used to create messages until + * it is added to a pool, after which it becomes immutable (as part of a + * finalization process). + */ +static VALUE Descriptor_alloc(VALUE klass) { + Descriptor* self = ALLOC(Descriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &Descriptor_type, self); + self->msgdef = NULL; + self->klass = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +/* + * call-seq: + * Descriptor.new(c_only_cookie, ptr) => Descriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE Descriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + Descriptor* self = ruby_to_Descriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->msgdef = (const upb_MessageDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: Descriptor#file_descriptor + * + * Returns the {FileDescriptor} object this message belongs to. + * + * @return [FileDescriptor] + */ +static VALUE Descriptor_file_descriptor(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + return get_filedef_obj(self->descriptor_pool, + upb_MessageDef_File(self->msgdef)); +} + +/* + * ruby-doc: Descriptor#name + * + * Returns the name of this message type as a fully-qualified string (e.g., + * My.Package.MessageType). + * + * @return [String] + */ +static VALUE Descriptor_name(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + return rb_str_maybe_null(upb_MessageDef_FullName(self->msgdef)); +} + +/* + * ruby-doc: Descriptor#each + * + * Iterates over fields in this message type, yielding to the block on each one. + * + * @yield [FieldDescriptor] + * @return [nil] + */ +static VALUE Descriptor_each(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + + int n = upb_MessageDef_FieldCount(self->msgdef); + for (int i = 0; i < n; i++) { + const upb_FieldDef* field = upb_MessageDef_Field(self->msgdef, i); + VALUE obj = get_fielddef_obj(self->descriptor_pool, field); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: Descriptor#lookup + * + * Returns the field descriptor for the field with the given name, if present, + * or nil if none. + * + * @param name [String] + * @return [FieldDescriptor] + */ +static VALUE Descriptor_lookup(VALUE _self, VALUE name) { + Descriptor* self = ruby_to_Descriptor(_self); + const char* s = get_str(name); + const upb_FieldDef* field = upb_MessageDef_FindFieldByName(self->msgdef, s); + if (field == NULL) { + return Qnil; + } + return get_fielddef_obj(self->descriptor_pool, field); +} + +/* + * ruby-doc: Descriptor#each_oneof + * + * Invokes the given block for each oneof in this message type, passing the + * corresponding {OneofDescriptor}. + * + * @yield [OneofDescriptor] + * @return [nil] + */ +static VALUE Descriptor_each_oneof(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + + int n = upb_MessageDef_OneofCount(self->msgdef); + for (int i = 0; i < n; i++) { + const upb_OneofDef* oneof = upb_MessageDef_Oneof(self->msgdef, i); + VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: Descriptor#lookup_oneof + * + * Returns the oneof descriptor for the oneof with the given name, if present, + * or nil if none. + * + * @param name [String] + * @return [OneofDescriptor] + */ +static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) { + Descriptor* self = ruby_to_Descriptor(_self); + const char* s = get_str(name); + const upb_OneofDef* oneof = upb_MessageDef_FindOneofByName(self->msgdef, s); + if (oneof == NULL) { + return Qnil; + } + return get_oneofdef_obj(self->descriptor_pool, oneof); +} + +/* + * ruby-doc: Descriptor#msgclass + * + * Returns the Ruby class created for this message type. + * + * @return [Class] + */ +static VALUE Descriptor_msgclass(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + if (self->klass == Qnil) { + RB_OBJ_WRITE(_self, &self->klass, build_class_from_descriptor(_self)); + } + return self->klass; +} + +/* + * ruby-doc: Descriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L571 + * MessageOptions} for this {Descriptor}. + * + * @return [MessageOptions] + */ +static VALUE Descriptor_options(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + const google_protobuf_MessageOptions* opts = + upb_MessageDef_Options(self->msgdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = + google_protobuf_MessageOptions_serialize(opts, arena, &size); + VALUE message_options = decode_options(_self, "MessageOptions", size, + serialized, self->descriptor_pool); + upb_Arena_Free(arena); + return message_options; +} + +/* + * ruby-doc: Descriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L147 + * DescriptorProto} of this {Descriptor}. + * + * @return [DescriptorProto] + */ +static VALUE Descriptor_to_proto(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_DescriptorProto* proto = + upb_MessageDef_ToProto(self->msgdef, arena); + size_t size; + const char* serialized = + google_protobuf_DescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::DescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void Descriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject); + rb_define_alloc_func(klass, Descriptor_alloc); + rb_define_method(klass, "initialize", Descriptor_initialize, 3); + rb_define_method(klass, "each", Descriptor_each, 0); + rb_define_method(klass, "lookup", Descriptor_lookup, 1); + rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0); + rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1); + rb_define_method(klass, "msgclass", Descriptor_msgclass, 0); + rb_define_method(klass, "name", Descriptor_name, 0); + rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0); + rb_define_method(klass, "options", Descriptor_options, 0); + rb_define_method(klass, "to_proto", Descriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cDescriptor); + cDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// FileDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_FileDef* filedef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE descriptor_pool; // Owns the upb_FileDef. +} FileDescriptor; + +static VALUE cFileDescriptor = Qnil; + +static void FileDescriptor_mark(void* _self) { + FileDescriptor* self = _self; + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t FileDescriptor_type = { + "Google::Protobuf::FileDescriptor", + {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static FileDescriptor* ruby_to_FileDescriptor(VALUE val) { + FileDescriptor* ret; + TypedData_Get_Struct(val, FileDescriptor, &FileDescriptor_type, ret); + return ret; +} + +static VALUE FileDescriptor_alloc(VALUE klass) { + FileDescriptor* self = ALLOC(FileDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &FileDescriptor_type, self); + self->descriptor_pool = Qnil; + self->filedef = NULL; + return ret; +} + +/** + * ruby-doc: FileDescriptor + * + * A FileDescriptor provides information about all Protobuf definitions in a + * particular file. + */ + +/* + * ruby-doc: FileDescriptor#initialize + * + * Returns a new file descriptor. May + * to a builder. + */ +static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->filedef = (const upb_FileDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: FileDescriptor#name + * + * Returns the name of the file. + * + * @return [String] + */ +static VALUE FileDescriptor_name(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + const char* name = upb_FileDef_Name(self->filedef); + return name == NULL ? Qnil : rb_str_new2(name); +} + +/* + * ruby-doc: FileDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L442 + * FileOptions} for this {FileDescriptor}. + * + * @return [FileOptions] + */ +static VALUE FileDescriptor_options(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + const google_protobuf_FileOptions* opts = upb_FileDef_Options(self->filedef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size); + VALUE file_options = decode_options(_self, "FileOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return file_options; +} + +/* + * ruby-doc: FileDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L104 + * FileDescriptorProto} of this {FileDescriptor}. + * + * @return [FileDescriptorProto] + */ +static VALUE FileDescriptor_to_proto(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_FileDescriptorProto* file_proto = + upb_FileDef_ToProto(self->filedef, arena); + + size_t size; + const char* serialized = + google_protobuf_FileDescriptorProto_serialize(file_proto, arena, &size); + + VALUE file_proto_class = + rb_path2class("Google::Protobuf::FileDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, file_proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void FileDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject); + rb_define_alloc_func(klass, FileDescriptor_alloc); + rb_define_method(klass, "initialize", FileDescriptor_initialize, 3); + rb_define_method(klass, "name", FileDescriptor_name, 0); + rb_define_method(klass, "options", FileDescriptor_options, 0); + rb_define_method(klass, "to_proto", FileDescriptor_to_proto, 0); + rb_gc_register_address(&cFileDescriptor); + cFileDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// FieldDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_FieldDef* fielddef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE descriptor_pool; // Owns the upb_FieldDef. +} FieldDescriptor; + +static VALUE cFieldDescriptor = Qnil; + +static void FieldDescriptor_mark(void* _self) { + FieldDescriptor* self = _self; + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t FieldDescriptor_type = { + "Google::Protobuf::FieldDescriptor", + {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) { + FieldDescriptor* ret; + TypedData_Get_Struct(val, FieldDescriptor, &FieldDescriptor_type, ret); + return ret; +} + +/** + * ruby-doc: FieldDescriptor + * + * A FieldDescriptor provides information about the Protobuf definition of a + * field inside a {Descriptor}. + */ + +/* + * ruby-doc: FieldDescriptor#initialize + * + * Returns a new field descriptor. Its name, type, etc. must be set before it is + * added to a message type. + */ +static VALUE FieldDescriptor_alloc(VALUE klass) { + FieldDescriptor* self = ALLOC(FieldDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &FieldDescriptor_type, self); + self->fielddef = NULL; + return ret; +} + +/* + * call-seq: + * FieldDescriptor.new(c_only_cookie, pool, ptr) => FieldDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->fielddef = (const upb_FieldDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#name + * + * Returns the name of this field. + * + * @return [String] + */ +static VALUE FieldDescriptor_name(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return rb_str_maybe_null(upb_FieldDef_Name(self->fielddef)); +} + +// Non-static, exposed to other .c files. +upb_CType ruby_to_fieldtype(VALUE type) { + if (TYPE(type) != T_SYMBOL) { + rb_raise(rb_eArgError, "Expected symbol for field type."); + } + +#define CONVERT(upb, ruby) \ + if (SYM2ID(type) == rb_intern(#ruby)) { \ + return kUpb_CType_##upb; \ + } + + CONVERT(Float, float); + CONVERT(Double, double); + CONVERT(Bool, bool); + CONVERT(String, string); + CONVERT(Bytes, bytes); + CONVERT(Message, message); + CONVERT(Enum, enum); + CONVERT(Int32, int32); + CONVERT(Int64, int64); + CONVERT(UInt32, uint32); + CONVERT(UInt64, uint64); + +#undef CONVERT + + rb_raise(rb_eArgError, "Unknown field type."); + return 0; +} + +static VALUE descriptortype_to_ruby(upb_FieldType type) { + switch (type) { +#define CONVERT(upb, ruby) \ + case kUpb_FieldType_##upb: \ + return ID2SYM(rb_intern(#ruby)); + CONVERT(Float, float); + CONVERT(Double, double); + CONVERT(Bool, bool); + CONVERT(String, string); + CONVERT(Bytes, bytes); + CONVERT(Message, message); + CONVERT(Group, group); + CONVERT(Enum, enum); + CONVERT(Int32, int32); + CONVERT(Int64, int64); + CONVERT(UInt32, uint32); + CONVERT(UInt64, uint64); + CONVERT(SInt32, sint32); + CONVERT(SInt64, sint64); + CONVERT(Fixed32, fixed32); + CONVERT(Fixed64, fixed64); + CONVERT(SFixed32, sfixed32); + CONVERT(SFixed64, sfixed64); +#undef CONVERT + } + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#type + * + * Returns this field's type, as a Ruby symbol, or nil if not yet set. + * + * Valid field types are: + * :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string, + * :bytes, :message. + * + * @return [Symbol] + */ +static VALUE FieldDescriptor__type(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return descriptortype_to_ruby(upb_FieldDef_Type(self->fielddef)); +} + +/* + * ruby-doc: FieldDescriptor#default + * + * Returns this field's default, as a Ruby object, or nil if not yet set. + * + * @return [Object,nil] + */ +static VALUE FieldDescriptor_default(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_FieldDef* f = self->fielddef; + upb_MessageValue default_val = upb_MessageValue_Zero(); + if (upb_FieldDef_IsSubMessage(f)) { + return Qnil; + } else if (!upb_FieldDef_IsRepeated(f)) { + default_val = upb_FieldDef_Default(f); + } + return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil); +} + +/* + * ruby-doc: FieldDescriptor.has_presence? + * + * Returns whether this field tracks presence. + * + * @return [Boolean] + */ +static VALUE FieldDescriptor_has_presence(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_HasPresence(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#required? + * + * Returns whether this is a required field. + * + * @return [Boolean] + */ +static VALUE FieldDescriptor_is_required(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_IsRequired(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#repeated? + * + * Returns whether this is a repeated field. + * @return [Boolean] + */ +static VALUE FieldDescriptor_is_repeated(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_IsRepeated(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#is_packed? + * + * Returns whether this is a repeated field that uses packed encoding. + * @return [Boolean] + */ +static VALUE FieldDescriptor_is_packed(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_IsPacked(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#json_name + * + * Returns this field's json_name, as a Ruby string, or nil if not yet set. + * + * @return [String,nil] + */ +static VALUE FieldDescriptor_json_name(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_FieldDef* f = self->fielddef; + const char* json_name = upb_FieldDef_JsonName(f); + return rb_str_new2(json_name); +} + +/* + * ruby-doc: FieldDescriptor#label + * + * Returns this field's label (i.e., plurality), as a Ruby symbol. + * Valid field labels are: + * :optional, :repeated + * + * @return [Symbol] + * @deprecated Use {#repeated?} or {#required?} instead. + */ +static VALUE FieldDescriptor_label(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + switch (upb_FieldDef_Label(self->fielddef)) { +#define CONVERT(upb, ruby) \ + case kUpb_Label_##upb: \ + return ID2SYM(rb_intern(#ruby)); + + CONVERT(Optional, optional); + CONVERT(Required, required); + CONVERT(Repeated, repeated); + +#undef CONVERT + } + + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#number + * + * Returns the tag number for this field. + * + * @return [Integer] + */ +static VALUE FieldDescriptor_number(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return INT2NUM(upb_FieldDef_Number(self->fielddef)); +} + +/* + * ruby-doc: FieldDescriptor#submsg_name + * + * Returns the name of the message or enum type corresponding to this field, if + * it is a message or enum field (respectively), or nil otherwise. This type + * name will be resolved within the context of the pool to which the containing + * message type is added. + * + * @return [String,nil] + */ +static VALUE FieldDescriptor_submsg_name(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + switch (upb_FieldDef_CType(self->fielddef)) { + case kUpb_CType_Enum: + return rb_str_new2( + upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(self->fielddef))); + case kUpb_CType_Message: + return rb_str_new2( + upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(self->fielddef))); + default: + return Qnil; + } +} + +/* + * ruby-doc: FieldDescriptor#subtype + * + * Returns the message or enum descriptor corresponding to this field's type if + * it is a message or enum field, respectively, or nil otherwise. Cannot be + * called *until* the containing message type is added to a pool (and thus + * resolved). + * + * @return [Descriptor,EnumDescriptor,nil] + */ +static VALUE FieldDescriptor_subtype(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + switch (upb_FieldDef_CType(self->fielddef)) { + case kUpb_CType_Enum: + return get_enumdef_obj(self->descriptor_pool, + upb_FieldDef_EnumSubDef(self->fielddef)); + case kUpb_CType_Message: + return get_msgdef_obj(self->descriptor_pool, + upb_FieldDef_MessageSubDef(self->fielddef)); + default: + return Qnil; + } +} + +/* + * ruby-doc: FieldDescriptor#get + * + * Returns the value set for this field on the given message. Raises an + * exception if message is of the wrong type. + * + * @param message [AbstractMessage] + * @return [Object] + */ +static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + + Message_Get(msg_rb, &m); + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "get method called on wrong message type"); + } + + return Message_getfield(msg_rb, self->fielddef); +} + +/* + * ruby-doc: FieldDescriptor.has? + * + * Returns whether the value is set on the given message. Raises an + * exception when calling for fields that do not have presence. + * + * @param message [AbstractMessage] + * @return [Boolean] + */ +static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + const upb_Message* msg = Message_Get(msg_rb, &m); + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "has method called on wrong message type"); + } else if (!upb_FieldDef_HasPresence(self->fielddef)) { + rb_raise(rb_eArgError, "does not track presence"); + } + + return upb_Message_HasFieldByDef(msg, self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#clear + * + * Clears the field from the message if it's set. + * + * @param message [AbstractMessage] + * @return [nil] + */ +static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + upb_Message* msg = Message_GetMutable(msg_rb, &m); + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "has method called on wrong message type"); + } + + upb_Message_ClearFieldByDef(msg, self->fielddef); + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#set + * + * Sets the value corresponding to this field to the given value on the given + * message. Raises an exception if message is of the wrong type. Performs the + * ordinary type-checks for field setting. + * + * @param message [AbstractMessage] + * @param value [Object] + */ +static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + upb_Message* msg = Message_GetMutable(msg_rb, &m); + upb_Arena* arena = Arena_get(Message_GetArena(msg_rb)); + upb_MessageValue msgval; + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "set method called on wrong message type"); + } + + msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef), + TypeInfo_get(self->fielddef), arena); + upb_Message_SetFieldByDef(msg, self->fielddef, msgval, arena); + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L656 + * FieldOptions} for this {FieldDescriptor}. + * + * @return [FieldOptions] + */ +static VALUE FieldDescriptor_options(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const google_protobuf_FieldOptions* opts = + upb_FieldDef_Options(self->fielddef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size); + VALUE field_options = decode_options(_self, "FieldOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return field_options; +} + +/* + * ruby-doc: FieldDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L236 + * FieldDescriptorProto} of this {FieldDescriptor}. + * + * @return [FieldDescriptorProto] + */ +static VALUE FieldDescriptor_to_proto(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_FieldDescriptorProto* proto = + upb_FieldDef_ToProto(self->fielddef, arena); + size_t size; + const char* serialized = + google_protobuf_FieldDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::FieldDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void FieldDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject); + rb_define_alloc_func(klass, FieldDescriptor_alloc); + rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3); + rb_define_method(klass, "name", FieldDescriptor_name, 0); + rb_define_method(klass, "type", FieldDescriptor__type, 0); + rb_define_method(klass, "default", FieldDescriptor_default, 0); + rb_define_method(klass, "has_presence?", FieldDescriptor_has_presence, 0); + rb_define_method(klass, "required?", FieldDescriptor_is_required, 0); + rb_define_method(klass, "repeated?", FieldDescriptor_is_repeated, 0); + rb_define_method(klass, "is_packed?", FieldDescriptor_is_packed, 0); + rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0); + rb_define_method(klass, "label", FieldDescriptor_label, 0); + rb_define_method(klass, "number", FieldDescriptor_number, 0); + rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0); + rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0); + rb_define_method(klass, "has?", FieldDescriptor_has, 1); + rb_define_method(klass, "clear", FieldDescriptor_clear, 1); + rb_define_method(klass, "get", FieldDescriptor_get, 1); + rb_define_method(klass, "set", FieldDescriptor_set, 2); + rb_define_method(klass, "options", FieldDescriptor_options, 0); + rb_define_method(klass, "to_proto", FieldDescriptor_to_proto, 0); + rb_gc_register_address(&cFieldDescriptor); + cFieldDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// OneofDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_OneofDef* oneofdef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE descriptor_pool; // Owns the upb_OneofDef. +} OneofDescriptor; + +static VALUE cOneofDescriptor = Qnil; + +static void OneofDescriptor_mark(void* _self) { + OneofDescriptor* self = _self; + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t OneofDescriptor_type = { + "Google::Protobuf::OneofDescriptor", + {OneofDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static OneofDescriptor* ruby_to_OneofDescriptor(VALUE val) { + OneofDescriptor* ret; + TypedData_Get_Struct(val, OneofDescriptor, &OneofDescriptor_type, ret); + return ret; +} + +/** + * ruby-doc: OneofDescriptor + * + * A OneofDescriptor provides information about the Protobuf definition of a + * oneof inside a {Descriptor}. + */ + +/* + * ruby-doc: OneofDescriptor#initialize + * + * Creates a new, empty, oneof descriptor. The oneof may only be modified prior + * to being added to a message descriptor which is subsequently added to a pool. + */ +static VALUE OneofDescriptor_alloc(VALUE klass) { + OneofDescriptor* self = ALLOC(OneofDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &OneofDescriptor_type, self); + self->oneofdef = NULL; + self->descriptor_pool = Qnil; + return ret; +} + +/* + * call-seq: + * OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->oneofdef = (const upb_OneofDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: OneofDescriptor#name + * + * Returns the name of this oneof. + * + * @return [String] + */ +static VALUE OneofDescriptor_name(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + return rb_str_maybe_null(upb_OneofDef_Name(self->oneofdef)); +} + +/* + * ruby-doc: OneofDescriptor#each + * + * Iterates through fields in this oneof, yielding to the block on each one. + * + * @yield [FieldDescriptor] + * @return [nil] + */ +static VALUE OneofDescriptor_each(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + + int n = upb_OneofDef_FieldCount(self->oneofdef); + for (int i = 0; i < n; i++) { + const upb_FieldDef* f = upb_OneofDef_Field(self->oneofdef, i); + VALUE obj = get_fielddef_obj(self->descriptor_pool, f); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: OneofDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L824 + * OneofOptions} for this {OneofDescriptor}. + * + * @return [OneofOptions] + */ +static VALUE OneOfDescriptor_options(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + const google_protobuf_OneofOptions* opts = + upb_OneofDef_Options(self->oneofdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size); + VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return oneof_options; +} + +/* + * ruby-doc: OneofDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L343 + * OneofDescriptorProto} of this {OneofDescriptor}. + * + * @return [OneofDescriptorProto] + */ +static VALUE OneOfDescriptor_to_proto(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_OneofDescriptorProto* proto = + upb_OneofDef_ToProto(self->oneofdef, arena); + size_t size; + const char* serialized = + google_protobuf_OneofDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::OneofDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void OneofDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject); + rb_define_alloc_func(klass, OneofDescriptor_alloc); + rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3); + rb_define_method(klass, "name", OneofDescriptor_name, 0); + rb_define_method(klass, "each", OneofDescriptor_each, 0); + rb_define_method(klass, "options", OneOfDescriptor_options, 0); + rb_define_method(klass, "to_proto", OneOfDescriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cOneofDescriptor); + cOneofDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// EnumDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_EnumDef* enumdef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE module; // begins as nil + VALUE descriptor_pool; // Owns the upb_EnumDef. +} EnumDescriptor; + +static VALUE cEnumDescriptor = Qnil; + +static void EnumDescriptor_mark(void* _self) { + EnumDescriptor* self = _self; + rb_gc_mark(self->module); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t EnumDescriptor_type = { + "Google::Protobuf::EnumDescriptor", + {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) { + EnumDescriptor* ret; + TypedData_Get_Struct(val, EnumDescriptor, &EnumDescriptor_type, ret); + return ret; +} + +static VALUE EnumDescriptor_alloc(VALUE klass) { + EnumDescriptor* self = ALLOC(EnumDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &EnumDescriptor_type, self); + self->enumdef = NULL; + self->module = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +// Exposed to other modules in defs.h. +const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) { + EnumDescriptor* desc = ruby_to_EnumDescriptor(enum_desc_rb); + return desc->enumdef; +} + +/** + * ruby-doc: EnumDescriptor + * + * An EnumDescriptor provides information about the Protobuf definition of an + * enum inside a {Descriptor}. + */ + +/* + * call-seq: + * EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->enumdef = (const upb_EnumDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: EnumDescriptor#file_descriptor + * + * Returns the {FileDescriptor} object this enum belongs to. + * + * @return [FileDescriptor] + */ +static VALUE EnumDescriptor_file_descriptor(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + return get_filedef_obj(self->descriptor_pool, + upb_EnumDef_File(self->enumdef)); +} + +/* + * ruby-doc: EnumDescriptor#is_closed? + * + * Returns whether this enum is open or closed. + * + * @return [Boolean] + */ +static VALUE EnumDescriptor_is_closed(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + return upb_EnumDef_IsClosed(self->enumdef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: EnumDescriptor#name + * + * Returns the name of this enum type. + * + * @return [String] + */ +static VALUE EnumDescriptor_name(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + return rb_str_maybe_null(upb_EnumDef_FullName(self->enumdef)); +} + +/* + * ruby-doc: EnumDescriptor#lookup_name + * + * Returns the numeric value corresponding to the given key name (as a Ruby + * symbol), or nil if none. + * + * @param name [Symbol] + * @return [Integer,nil] + */ +static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + const char* name_str = rb_id2name(SYM2ID(name)); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByName(self->enumdef, name_str); + if (ev) { + return INT2NUM(upb_EnumValueDef_Number(ev)); + } else { + return Qnil; + } +} + +/* + * ruby-doc: EnumDescriptor#lookup_value + * + * Returns the key name (as a Ruby symbol) corresponding to the integer value, + * or nil if none. + * + * @param name [Integer] + * @return [Symbol,nil] + */ +static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + int32_t val = NUM2INT(number); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(self->enumdef, val); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + } else { + return Qnil; + } +} + +/* + * ruby-doc: EnumDescriptor#each + * + * Iterates over key => value mappings in this enum's definition, yielding to + * the block with (key, value) arguments for each one. + * + * @yield [Symbol, Integer] + * @return [nil] + */ +static VALUE EnumDescriptor_each(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + + int n = upb_EnumDef_ValueCount(self->enumdef); + for (int i = 0; i < n; i++) { + const upb_EnumValueDef* ev = upb_EnumDef_Value(self->enumdef, i); + VALUE key = ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + VALUE number = INT2NUM(upb_EnumValueDef_Number(ev)); + rb_yield_values(2, key, number); + } + + return Qnil; +} + +/* + * ruby-doc: EnumDescriptor#enummodule + * + * Returns the Ruby module corresponding to this enum type. + * + * @return [Module] + */ +static VALUE EnumDescriptor_enummodule(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + if (self->module == Qnil) { + RB_OBJ_WRITE(_self, &self->module, build_module_from_enumdesc(_self)); + } + return self->module; +} + +/* + * ruby-doc: EnumDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L838 + * EnumOptions} for this {EnumDescriptor}. + * + * @return [EnumOptions] + */ +static VALUE EnumDescriptor_options(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(self->enumdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size); + VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return enum_options; +} + +/* + * ruby-doc: EnumDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L349 + * EnumDescriptorProto} of this {EnumDescriptor}. + * @return [EnumDescriptorProto] + */ +static VALUE EnumDescriptor_to_proto(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_EnumDescriptorProto* proto = + upb_EnumDef_ToProto(self->enumdef, arena); + + size_t size; + const char* serialized = + google_protobuf_EnumDescriptorProto_serialize(proto, arena, &size); + + VALUE proto_class = rb_path2class("Google::Protobuf::EnumDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void EnumDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject); + rb_define_alloc_func(klass, EnumDescriptor_alloc); + rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3); + rb_define_method(klass, "name", EnumDescriptor_name, 0); + rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1); + rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1); + rb_define_method(klass, "each", EnumDescriptor_each, 0); + rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0); + rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0); + rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0); + rb_define_method(klass, "options", EnumDescriptor_options, 0); + rb_define_method(klass, "to_proto", EnumDescriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cEnumDescriptor); + cEnumDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// ServiceDescriptor +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_ServiceDef* servicedef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE module; // begins as nil + VALUE descriptor_pool; // Owns the upb_ServiceDef. +} ServiceDescriptor; + +static VALUE cServiceDescriptor = Qnil; + +static void ServiceDescriptor_mark(void* _self) { + ServiceDescriptor* self = _self; + rb_gc_mark(self->module); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t ServiceDescriptor_type = { + "Google::Protobuf::ServicDescriptor", + {ServiceDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static ServiceDescriptor* ruby_to_ServiceDescriptor(VALUE val) { + ServiceDescriptor* ret; + TypedData_Get_Struct(val, ServiceDescriptor, &ServiceDescriptor_type, ret); + return ret; +} + +static VALUE ServiceDescriptor_alloc(VALUE klass) { + ServiceDescriptor* self = ALLOC(ServiceDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &ServiceDescriptor_type, self); + self->servicedef = NULL; + self->module = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +/** + * ruby-doc: ServiceDescriptor + * + * A ServiceDescriptor provides information about the Protobuf definition of an + * RPC service. + */ + +/* + * call-seq: + * ServiceDescriptor.new(c_only_cookie, ptr) => ServiceDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE ServiceDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->servicedef = (const upb_ServiceDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: ServiceDescriptor#name + * + * Returns the name of this service. + * + * @return [String] + */ +static VALUE ServiceDescriptor_name(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + return rb_str_maybe_null(upb_ServiceDef_FullName(self->servicedef)); +} + +/* + * ruby-doc: ServiceDescriptor#file_descriptor + * + * Returns the {FileDescriptor} object this service belongs to. + * @return [FileDescriptor] + */ +static VALUE ServiceDescriptor_file_descriptor(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + return get_filedef_obj(self->descriptor_pool, + upb_ServiceDef_File(self->servicedef)); +} + +/* + * ruby-doc: ServiceDescriptor#each + * + * Iterates over methods in this service, yielding to the block on each one. + * + * @yield [MethodDescriptor] + * @return [nil] + */ +static VALUE ServiceDescriptor_each(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + + int n = upb_ServiceDef_MethodCount(self->servicedef); + for (int i = 0; i < n; i++) { + const upb_MethodDef* method = upb_ServiceDef_Method(self->servicedef, i); + VALUE obj = get_methoddef_obj(self->descriptor_pool, method); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: ServiceDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L901 + * ServiceOptions} for this {ServiceDescriptor}. + * + * @return [ServiceOptions] + */ +static VALUE ServiceDescriptor_options(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + const google_protobuf_ServiceOptions* opts = + upb_ServiceDef_Options(self->servicedef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = + google_protobuf_ServiceOptions_serialize(opts, arena, &size); + VALUE service_options = decode_options(_self, "ServiceOptions", size, + serialized, self->descriptor_pool); + upb_Arena_Free(arena); + return service_options; +} + +/* + * ruby-doc: ServiceDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L386 + * ServiceDescriptorProto} of this {ServiceDescriptor}. + * + * @return [ServiceDescriptorProto] + */ +static VALUE ServiceDescriptor_to_proto(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_ServiceDescriptorProto* proto = + upb_ServiceDef_ToProto(self->servicedef, arena); + size_t size; + const char* serialized = + google_protobuf_ServiceDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::ServiceDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void ServiceDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject); + rb_define_alloc_func(klass, ServiceDescriptor_alloc); + rb_define_method(klass, "initialize", ServiceDescriptor_initialize, 3); + rb_define_method(klass, "name", ServiceDescriptor_name, 0); + rb_define_method(klass, "each", ServiceDescriptor_each, 0); + rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor, + 0); + rb_define_method(klass, "options", ServiceDescriptor_options, 0); + rb_define_method(klass, "to_proto", ServiceDescriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cServiceDescriptor); + cServiceDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// MethodDescriptor +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_MethodDef* methoddef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE module; // begins as nil + VALUE descriptor_pool; // Owns the upb_MethodDef. +} MethodDescriptor; + +static VALUE cMethodDescriptor = Qnil; + +static void MethodDescriptor_mark(void* _self) { + MethodDescriptor* self = _self; + rb_gc_mark(self->module); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t MethodDescriptor_type = { + "Google::Protobuf::MethodDescriptor", + {MethodDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static MethodDescriptor* ruby_to_MethodDescriptor(VALUE val) { + MethodDescriptor* ret; + TypedData_Get_Struct(val, MethodDescriptor, &MethodDescriptor_type, ret); + return ret; +} + +static VALUE MethodDescriptor_alloc(VALUE klass) { + MethodDescriptor* self = ALLOC(MethodDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &MethodDescriptor_type, self); + self->methoddef = NULL; + self->module = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +/** + * ruby-doc: MethodDescriptor + * + * A MethodDescriptor provides information about the Protobuf definition of a + * method inside an RPC service. + */ + +/* + * call-seq: + * MethodDescriptor.new(c_only_cookie, ptr) => MethodDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE MethodDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->methoddef = (const upb_MethodDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: MethodDescriptor#name + * + * Returns the name of this method + * + * @return [String] + */ +static VALUE MethodDescriptor_name(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + return rb_str_maybe_null(upb_MethodDef_Name(self->methoddef)); +} + +/* + * ruby-doc: MethodDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L927 + * MethodOptions} for this {MethodDescriptor}. + * + * @return [MethodOptions] + */ +static VALUE MethodDescriptor_options(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + const google_protobuf_MethodOptions* opts = + upb_MethodDef_Options(self->methoddef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = + google_protobuf_MethodOptions_serialize(opts, arena, &size); + VALUE method_options = decode_options(_self, "MethodOptions", size, + serialized, self->descriptor_pool); + upb_Arena_Free(arena); + return method_options; +} + +/* + * ruby-doc: MethodDescriptor#input_type + * + * Returns the {Descriptor} for the request message type of this method + * + * @return [Descriptor] + */ +static VALUE MethodDescriptor_input_type(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + const upb_MessageDef* type = upb_MethodDef_InputType(self->methoddef); + return get_msgdef_obj(self->descriptor_pool, type); +} + +/* + * ruby-doc: MethodDescriptor#output_type + * + * Returns the {Descriptor} for the response message type of this method + * + * @return [Descriptor] + */ +static VALUE MethodDescriptor_output_type(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + const upb_MessageDef* type = upb_MethodDef_OutputType(self->methoddef); + return get_msgdef_obj(self->descriptor_pool, type); +} + +/* + * ruby-doc: MethodDescriptor#client_streaming + * + * Returns whether or not this is a streaming request method + * + * @return [Boolean] + */ +static VALUE MethodDescriptor_client_streaming(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: MethodDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L394 + * MethodDescriptorProto} of this {MethodDescriptor}. + * + * @return [MethodDescriptorProto] + */ +static VALUE MethodDescriptor_to_proto(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_MethodDescriptorProto* proto = + upb_MethodDef_ToProto(self->methoddef, arena); + size_t size; + const char* serialized = + google_protobuf_MethodDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::MethodDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +/* + * ruby-doc: MethodDescriptor#server_streaming + * + * Returns whether or not this is a streaming response method + * + * @return [Boolean] + */ +static VALUE MethodDescriptor_server_streaming(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + return upb_MethodDef_ServerStreaming(self->methoddef) ? Qtrue : Qfalse; +} + +static void MethodDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "MethodDescriptor", rb_cObject); + rb_define_alloc_func(klass, MethodDescriptor_alloc); + rb_define_method(klass, "initialize", MethodDescriptor_initialize, 3); + rb_define_method(klass, "name", MethodDescriptor_name, 0); + rb_define_method(klass, "options", MethodDescriptor_options, 0); + rb_define_method(klass, "input_type", MethodDescriptor_input_type, 0); + rb_define_method(klass, "output_type", MethodDescriptor_output_type, 0); + rb_define_method(klass, "client_streaming", MethodDescriptor_client_streaming, + 0); + rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming, + 0); + rb_define_method(klass, "to_proto", MethodDescriptor_to_proto, 0); + rb_gc_register_address(&cMethodDescriptor); + cMethodDescriptor = klass; +} + +static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) { + DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool); + VALUE key = ULL2NUM((intptr_t)ptr); + VALUE def; + + def = rb_hash_aref(descriptor_pool->def_to_descriptor, key); + + if (ptr == NULL) { + return Qnil; + } + + if (def == Qnil) { + // Lazily create wrapper object. + VALUE args[3] = {c_only_cookie, _descriptor_pool, key}; + def = rb_class_new_instance(3, args, klass); + rb_hash_aset(descriptor_pool->def_to_descriptor, key, def); + } + + return def; +} + +static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def) { + return get_def_obj(descriptor_pool, def, cDescriptor); +} + +static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def) { + return get_def_obj(descriptor_pool, def, cEnumDescriptor); +} + +static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def) { + return get_def_obj(descriptor_pool, def, cFieldDescriptor); +} + +static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def) { + return get_def_obj(descriptor_pool, def, cFileDescriptor); +} + +static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) { + return get_def_obj(descriptor_pool, def, cOneofDescriptor); +} + +static VALUE get_servicedef_obj(VALUE descriptor_pool, + const upb_ServiceDef* def) { + return get_def_obj(descriptor_pool, def, cServiceDescriptor); +} + +static VALUE get_methoddef_obj(VALUE descriptor_pool, + const upb_MethodDef* def) { + return get_def_obj(descriptor_pool, def, cMethodDescriptor); +} + +// ----------------------------------------------------------------------------- +// Shared functions +// ----------------------------------------------------------------------------- + +// Functions exposed to other modules in defs.h. + +VALUE Descriptor_DefToClass(const upb_MessageDef* m) { + const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m)); + VALUE pool = ObjectCache_Get(symtab); + PBRUBY_ASSERT(pool != Qnil); + VALUE desc_rb = get_msgdef_obj(pool, m); + const Descriptor* desc = ruby_to_Descriptor(desc_rb); + return desc->klass; +} + +const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb) { + const Descriptor* desc = ruby_to_Descriptor(desc_rb); + return desc->msgdef; +} + +VALUE TypeInfo_InitArg(int argc, VALUE* argv, int skip_arg) { + if (argc > skip_arg) { + if (argc > 1 + skip_arg) { + rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", + skip_arg + 1); + } + return argv[skip_arg]; + } else { + return Qnil; + } +} + +TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, + VALUE* type_class, VALUE* init_arg) { + TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])}; + + if (ret.type == kUpb_CType_Message || ret.type == kUpb_CType_Enum) { + *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2); + + if (argc < 2 + skip_arg) { + rb_raise(rb_eArgError, "Expected at least %d arguments for message/enum.", + 2 + skip_arg); + } + + VALUE klass = argv[1 + skip_arg]; + VALUE desc = MessageOrEnum_GetDescriptor(klass); + *type_class = klass; + + if (desc == Qnil) { + rb_raise(rb_eArgError, + "Type class has no descriptor. Please pass a " + "class or enum as returned by the DescriptorPool."); + } + + if (ret.type == kUpb_CType_Message) { + ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef; + Message_CheckClass(klass); + } else { + PBRUBY_ASSERT(ret.type == kUpb_CType_Enum); + ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef; + } + } else { + *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 1); + } + + return ret; +} + +void Defs_register(VALUE module) { + DescriptorPool_register(module); + Descriptor_register(module); + FileDescriptor_register(module); + FieldDescriptor_register(module); + OneofDescriptor_register(module); + EnumDescriptor_register(module); + ServiceDescriptor_register(module); + MethodDescriptor_register(module); + + rb_gc_register_address(&c_only_cookie); + c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.h new file mode 100755 index 0000000..931dd6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.h @@ -0,0 +1,82 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_DEFS_H_ +#define RUBY_PROTOBUF_DEFS_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// ----------------------------------------------------------------------------- +// TypeInfo +// ----------------------------------------------------------------------------- + +// This bundles a upb_CType and msgdef/enumdef when appropriate. This is +// convenient for functions that need type information but cannot necessarily +// assume a upb_FieldDef will be available. +// +// For example, Google::Protobuf::Map and Google::Protobuf::RepeatedField can +// be constructed with type information alone: +// +// # RepeatedField will internally store the type information in a TypeInfo. +// Google::Protobuf::RepeatedField.new(:message, FooMessage) + +typedef struct { + upb_CType type; + union { + const upb_MessageDef* msgdef; // When type == kUpb_CType_Message + const upb_EnumDef* enumdef; // When type == kUpb_CType_Enum + } def; +} TypeInfo; + +static inline TypeInfo TypeInfo_get(const upb_FieldDef* f) { + TypeInfo ret = {upb_FieldDef_CType(f), {NULL}}; + switch (ret.type) { + case kUpb_CType_Message: + ret.def.msgdef = upb_FieldDef_MessageSubDef(f); + break; + case kUpb_CType_Enum: + ret.def.enumdef = upb_FieldDef_EnumSubDef(f); + break; + default: + break; + } + return ret; +} + +TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, + VALUE* type_class, VALUE* init_arg); + +static inline TypeInfo TypeInfo_from_type(upb_CType type) { + TypeInfo ret = {type}; + assert(type != kUpb_CType_Message && type != kUpb_CType_Enum); + return ret; +} + +// ----------------------------------------------------------------------------- +// Other utilities +// ----------------------------------------------------------------------------- + +VALUE Descriptor_DefToClass(const upb_MessageDef* m); + +// Returns the underlying msgdef, enumdef, or symtab (respectively) for the +// given Descriptor, EnumDescriptor, or DescriptorPool Ruby object. +const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb); +const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb); +const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb); + +// Returns a upb field type for the given Ruby symbol +// (eg. :float => kUpb_CType_Float). +upb_CType ruby_to_fieldtype(VALUE type); + +// The singleton generated pool (a DescriptorPool object). +extern VALUE generated_pool; + +// Call at startup to register all types in this module. +void Defs_register(VALUE module); + +#endif // RUBY_PROTOBUF_DEFS_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/extconf.rb new file mode 100755 index 0000000..f97b9b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/extconf.rb @@ -0,0 +1,38 @@ +#!/usr/bin/ruby + +require 'mkmf' + +ext_name = "google/protobuf_c" + +dir_config(ext_name) + +if ENV["CC"] + RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] +end + +if ENV["CXX"] + RbConfig::CONFIG["CXX"] = RbConfig::MAKEFILE_CONFIG["CXX"] = ENV["CXX"] +end + +if ENV["LD"] + RbConfig::CONFIG["LD"] = RbConfig::MAKEFILE_CONFIG["LD"] = ENV["LD"] +end + +debug_enabled = ENV["PROTOBUF_CONFIG"] == "dbg" + +additional_c_flags = debug_enabled ? "-O0 -fno-omit-frame-pointer -fvisibility=default -g" : "-O3 -DNDEBUG -fvisibility=hidden" + +if RUBY_PLATFORM =~ /darwin/ || RUBY_PLATFORM =~ /linux/ || RUBY_PLATFORM =~ /freebsd/ + $CFLAGS += " -std=gnu99 -Wall -Wsign-compare -Wno-declaration-after-statement #{additional_c_flags}" +else + $CFLAGS += " -std=gnu99 #{additional_c_flags}" +end + +$VPATH << "$(srcdir)/third_party/utf8_range" +$INCFLAGS += " -I$(srcdir)/third_party/utf8_range" + +$srcs = ["protobuf.c", "convert.c", "defs.c", "message.c", "repeated_field.c", + "map.c", "ruby-upb.c", "utf8_range.c", "shared_convert.c", + "shared_message.c"] + +create_makefile(ext_name) diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/glue.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/glue.c new file mode 100755 index 0000000..46e9146 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/glue.c @@ -0,0 +1,135 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Exposing inlined UPB functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#include "ruby-upb.h" + +upb_Arena* Arena_create() { return upb_Arena_Init(NULL, 0, &upb_alloc_global); } + +google_protobuf_FileDescriptorProto* FileDescriptorProto_parse( + const char* serialized_file_proto, size_t length, upb_Arena* arena) { + return google_protobuf_FileDescriptorProto_parse(serialized_file_proto, + length, arena); +} + +char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(enumdef); + char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, size); + return serialized; +} + +char* EnumDescriptor_serialized_to_proto(const upb_EnumDef* enumdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_EnumDescriptorProto* file_proto = + upb_EnumDef_ToProto(enumdef, arena); + char* serialized = + google_protobuf_EnumDescriptorProto_serialize(file_proto, arena, size); + return serialized; +} + +char* FileDescriptor_serialized_options(const upb_FileDef* filedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef); + char* serialized = google_protobuf_FileOptions_serialize(opts, arena, size); + return serialized; +} + +char* FileDescriptor_serialized_to_proto(const upb_FileDef* filedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FileDescriptorProto* file_proto = + upb_FileDef_ToProto(filedef, arena); + char* serialized = + google_protobuf_FileDescriptorProto_serialize(file_proto, arena, size); + return serialized; +} + +char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size, + upb_Arena* arena) { + const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef); + char* serialized = + google_protobuf_MessageOptions_serialize(opts, arena, size); + return serialized; +} + +char* Descriptor_serialized_to_proto(const upb_MessageDef* msgdef, size_t* size, + upb_Arena* arena) { + const google_protobuf_DescriptorProto* proto = + upb_MessageDef_ToProto(msgdef, arena); + char* serialized = + google_protobuf_DescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef); + char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, size); + return serialized; +} + +char* OneOfDescriptor_serialized_to_proto(const upb_OneofDef* oneofdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_OneofDescriptorProto* proto = + upb_OneofDef_ToProto(oneofdef, arena); + char* serialized = + google_protobuf_OneofDescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef); + char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size); + return serialized; +} + +char* FieldDescriptor_serialized_to_proto(const upb_FieldDef* fieldef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FieldDescriptorProto* proto = + upb_FieldDef_ToProto(fieldef, arena); + char* serialized = + google_protobuf_FieldDescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_ServiceOptions* opts = + upb_ServiceDef_Options(servicedef); + char* serialized = + google_protobuf_ServiceOptions_serialize(opts, arena, size); + return serialized; +} + +char* ServiceDescriptor_serialized_to_proto(const upb_ServiceDef* servicedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_ServiceDescriptorProto* proto = + upb_ServiceDef_ToProto(servicedef, arena); + char* serialized = + google_protobuf_ServiceDescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* MethodDescriptor_serialized_options(const upb_MethodDef* methoddef, + size_t* size, upb_Arena* arena) { + const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(methoddef); + char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, size); + return serialized; +} + +char* MethodDescriptor_serialized_to_proto(const upb_MethodDef* methodef, + size_t* size, upb_Arena* arena) { + const google_protobuf_MethodDescriptorProto* proto = + upb_MethodDef_ToProto(methodef, arena); + char* serialized = + google_protobuf_MethodDescriptorProto_serialize(proto, arena, size); + return serialized; +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.c new file mode 100755 index 0000000..4ad3995 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.c @@ -0,0 +1,768 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "convert.h" +#include "defs.h" +#include "message.h" +#include "protobuf.h" + +// ----------------------------------------------------------------------------- +// Basic map operations on top of upb_Map. +// +// Note that we roll our own `Map` container here because, as for +// `RepeatedField`, we want a strongly-typed container. This is so that any user +// errors due to incorrect map key or value types are raised as close as +// possible to the error site, rather than at some deferred point (e.g., +// serialization). +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// Map container type. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_Map* map; // Can convert to mutable when non-frozen. + upb_CType key_type; + TypeInfo value_type_info; + VALUE value_type_class; + VALUE arena; +} Map; + +static void Map_mark(void* _self) { + Map* self = _self; + rb_gc_mark(self->value_type_class); + rb_gc_mark(self->arena); +} + +static size_t Map_memsize(const void* _self) { return sizeof(Map); } + +const rb_data_type_t Map_type = { + "Google::Protobuf::Map", + {Map_mark, RUBY_DEFAULT_FREE, Map_memsize}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, +}; + +VALUE cMap; + +static Map* ruby_to_Map(VALUE _self) { + Map* self; + TypedData_Get_Struct(_self, Map, &Map_type, self); + return self; +} + +static VALUE Map_alloc(VALUE klass) { + Map* self = ALLOC(Map); + self->map = NULL; + self->value_type_class = Qnil; + self->value_type_info.def.msgdef = NULL; + self->arena = Qnil; + return TypedData_Wrap_Struct(klass, &Map_type, self); +} + +VALUE Map_GetRubyWrapper(const upb_Map* map, upb_CType key_type, + TypeInfo value_type, VALUE arena) { + PBRUBY_ASSERT(map); + PBRUBY_ASSERT(arena != Qnil); + + VALUE val = ObjectCache_Get(map); + + if (val == Qnil) { + val = Map_alloc(cMap); + Map* self; + TypedData_Get_Struct(val, Map, &Map_type, self); + self->map = map; + self->arena = arena; + self->key_type = key_type; + self->value_type_info = value_type; + if (self->value_type_info.type == kUpb_CType_Message) { + const upb_MessageDef* val_m = self->value_type_info.def.msgdef; + self->value_type_class = Descriptor_DefToClass(val_m); + } + return ObjectCache_TryAdd(map, val); + } + return val; +} + +static VALUE Map_new_this_type(Map* from) { + VALUE arena_rb = Arena_new(); + upb_Map* map = upb_Map_New(Arena_get(arena_rb), from->key_type, + from->value_type_info.type); + VALUE ret = + Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb); + PBRUBY_ASSERT(ruby_to_Map(ret)->value_type_class == from->value_type_class); + return ret; +} + +static TypeInfo Map_keyinfo(Map* self) { + TypeInfo ret; + ret.type = self->key_type; + ret.def.msgdef = NULL; + return ret; +} + +static upb_Map* Map_GetMutable(VALUE _self) { + const upb_Map* map = ruby_to_Map(_self)->map; + Protobuf_CheckNotFrozen(_self, upb_Map_IsFrozen(map)); + return (upb_Map*)map; +} + +VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type, + TypeInfo val_info) { + VALUE hash = rb_hash_new(); + TypeInfo key_info = TypeInfo_from_type(key_type); + + if (!map) return hash; + + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(map, &key, &val, &iter)) { + VALUE key_val = Convert_UpbToRuby(key, key_info, Qnil); + VALUE val_val = Scalar_CreateHash(val, val_info); + rb_hash_aset(hash, key_val, val_val); + } + + return hash; +} + +VALUE Map_deep_copy(VALUE obj) { + Map* self = ruby_to_Map(obj); + VALUE new_arena_rb = Arena_new(); + upb_Arena* arena = Arena_get(new_arena_rb); + upb_Map* new_map = + upb_Map_New(arena, self->key_type, self->value_type_info.type); + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + upb_MessageValue val_copy = + Msgval_DeepCopy(val, self->value_type_info, arena); + upb_Map_Set(new_map, key, val_copy, arena); + } + + return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info, + new_arena_rb); +} + +const upb_Map* Map_GetUpbMap(VALUE val, const upb_FieldDef* field, + upb_Arena* arena) { + const upb_FieldDef* key_field = map_field_key(field); + const upb_FieldDef* value_field = map_field_value(field); + TypeInfo value_type_info = TypeInfo_get(value_field); + Map* self; + + if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || + RTYPEDDATA_TYPE(val) != &Map_type) { + rb_raise(cTypeError, "Expected Map instance"); + } + + self = ruby_to_Map(val); + if (self->key_type != upb_FieldDef_CType(key_field)) { + rb_raise(cTypeError, "Map key type does not match field's key type"); + } + if (self->value_type_info.type != value_type_info.type) { + rb_raise(cTypeError, "Map value type does not match field's value type"); + } + if (self->value_type_info.def.msgdef != value_type_info.def.msgdef) { + rb_raise(cTypeError, "Map value type has wrong message/enum class"); + } + + Arena_fuse(self->arena, arena); + return self->map; +} + +void Map_Inspect(StringBuilder* b, const upb_Map* map, upb_CType key_type, + TypeInfo val_type) { + bool first = true; + TypeInfo key_type_info = {key_type}; + StringBuilder_Printf(b, "{"); + if (map) { + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(map, &key, &val, &iter)) { + if (first) { + first = false; + } else { + StringBuilder_Printf(b, ", "); + } + StringBuilder_PrintMsgval(b, key, key_type_info); + StringBuilder_Printf(b, "=>"); + StringBuilder_PrintMsgval(b, val, val_type); + } + } + StringBuilder_Printf(b, "}"); +} + +static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) { + Map* self = ruby_to_Map(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue key_val = + Convert_RubyToUpb(key, "", Map_keyinfo(self), arena); + upb_MessageValue val_val = + Convert_RubyToUpb(val, "", self->value_type_info, arena); + upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena); + return ST_CONTINUE; +} + +// Used only internally -- shared by #merge and #initialize. +static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) { + if (TYPE(hashmap) == T_HASH) { + rb_hash_foreach(hashmap, merge_into_self_callback, _self); + } else if (RB_TYPE_P(hashmap, T_DATA) && RTYPEDDATA_P(hashmap) && + RTYPEDDATA_TYPE(hashmap) == &Map_type) { + Map* self = ruby_to_Map(_self); + Map* other = ruby_to_Map(hashmap); + upb_Arena* arena = Arena_get(self->arena); + upb_Map* self_map = Map_GetMutable(_self); + + Arena_fuse(other->arena, arena); + + if (self->key_type != other->key_type || + self->value_type_info.type != other->value_type_info.type || + self->value_type_class != other->value_type_class) { + rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types"); + } + + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(other->map, &key, &val, &iter)) { + upb_Map_Set(self_map, key, val, arena); + } + } else { + rb_raise(rb_eArgError, "Unknown type merging into Map"); + } + return _self; +} + +/** + * ruby-doc: Map + * + * This class represents a Protobuf Map. It is largely automatically transformed + * to and from a Ruby hash. + */ + +/* + * ruby-doc: Map#initialize + * + * Allocates a new Map container. This constructor may be called with 2, 3, or 4 + * arguments. The first two arguments are always present and are symbols (taking + * on the same values as field-type symbols in message descriptors) that + * indicate the type of the map key and value fields. + * + * The supported key types are: :int32, :int64, :uint32, :uint64, :bool, + * :string, :bytes. + * + * The supported value types are: :int32, :int64, :uint32, :uint64, :bool, + * :string, :bytes, :enum, :message. + * + * The third argument, value_typeclass, must be present if value_type is :enum + * or :message. As in RepeatedField#new, this argument must be a message class + * (for :message) or enum module (for :enum). + * + * The last argument, if present, provides initial content for map. Note that + * this may be an ordinary Ruby hashmap or another Map instance with identical + * key and value types. Also note that this argument may be present whether or + * not value_typeclass is present (and it is unambiguously separate from + * value_typeclass because value_typeclass's presence is strictly determined by + * value_type). The contents of this initial hashmap or Map instance are + * shallow-copied into the new Map: the original map is unmodified, but + * references to underlying objects will be shared if the value type is a + * message type. + * + * @param key_type [Symbol] + * @param value_type [Symbol] + * @param value_typeclass [Class,Module] + * @paramdefault value_typeclass nil + * @param init_hashmap [Hash,Map] + * @paramdefault init_hashmap {} + */ +static VALUE Map_init(int argc, VALUE* argv, VALUE _self) { + Map* self = ruby_to_Map(_self); + VALUE init_arg; + + // We take either two args (:key_type, :value_type), three args (:key_type, + // :value_type, "ValueMessageType"), or four args (the above plus an initial + // hashmap). + if (argc < 2 || argc > 4) { + rb_raise(rb_eArgError, "Map constructor expects 2, 3 or 4 arguments."); + } + + self->key_type = ruby_to_fieldtype(argv[0]); + self->value_type_info = + TypeInfo_FromClass(argc, argv, 1, &self->value_type_class, &init_arg); + self->arena = Arena_new(); + + // Check that the key type is an allowed type. + switch (self->key_type) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + case kUpb_CType_Bool: + case kUpb_CType_String: + case kUpb_CType_Bytes: + // These are OK. + break; + default: + rb_raise(rb_eArgError, "Invalid key type for map."); + } + + self->map = upb_Map_New(Arena_get(self->arena), self->key_type, + self->value_type_info.type); + VALUE stored = ObjectCache_TryAdd(self->map, _self); + (void)stored; + PBRUBY_ASSERT(stored == _self); + + if (init_arg != Qnil) { + Map_merge_into_self(_self, init_arg); + } + + return Qnil; +} + +/* + * ruby-doc: Map#each + * + * Invokes &block on each |key, value| pair in the map, in unspecified order. + * Note that Map also includes Enumerable; map thus acts like a normal Ruby + * sequence. + * + * @yield [Object, Object] + * @return [nil] + */ +static VALUE Map_each(VALUE _self) { + Map* self = ruby_to_Map(_self); + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + + while (upb_Map_Next(self->map, &key, &val, &iter)) { + VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); + VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); + rb_yield_values(2, key_val, val_val); + } + + return Qnil; +} + +/* + * ruby-doc: Map#keys + * + * Returns the list of keys contained in the map, in unspecified order. + * + * @return [Array] + */ +static VALUE Map_keys(VALUE _self) { + Map* self = ruby_to_Map(_self); + size_t iter = kUpb_Map_Begin; + VALUE ret = rb_ary_new(); + upb_MessageValue key, val; + + while (upb_Map_Next(self->map, &key, &val, &iter)) { + VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); + rb_ary_push(ret, key_val); + } + + return ret; +} + +/* + * ruby-doc: Map#values + * + * Returns the list of values contained in the map, in unspecified order. + * + * @return [Array] + */ +static VALUE Map_values(VALUE _self) { + Map* self = ruby_to_Map(_self); + size_t iter = kUpb_Map_Begin; + VALUE ret = rb_ary_new(); + upb_MessageValue key, val; + + while (upb_Map_Next(self->map, &key, &val, &iter)) { + VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); + rb_ary_push(ret, val_val); + } + + return ret; +} + +/* + * ruby-doc: Map#[] + * + * Accesses the element at the given key. Throws an exception if the key type is + * incorrect. Returns nil when the key is not present in the map. + * + * @param key [Object] + * @return [Object] + */ +static VALUE Map_index(VALUE _self, VALUE key) { + Map* self = ruby_to_Map(_self); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val; + + if (upb_Map_Get(self->map, key_upb, &val)) { + return Convert_UpbToRuby(val, self->value_type_info, self->arena); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Map#[]= + * + * Inserts or overwrites the value at the given key with the given new value. + * Throws an exception if the key type is incorrect. Returns the new value that + * was just inserted. + * + * @param key [Object] + * @param value [Object] + * @return [Object] + */ +static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) { + Map* self = ruby_to_Map(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val_upb = + Convert_RubyToUpb(val, "", self->value_type_info, arena); + + upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena); + + return val; +} + +/* + * ruby-doc: Map#has_key? + * + * Returns true if the given key is present in the map. Throws an exception if + * the key has the wrong type. + * + * @param key [Object] + * @return [Boolean] + */ +static VALUE Map_has_key(VALUE _self, VALUE key) { + Map* self = ruby_to_Map(_self); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + + if (upb_Map_Get(self->map, key_upb, NULL)) { + return Qtrue; + } else { + return Qfalse; + } +} + +/* + * ruby-doc: Map#delete + * + * Deletes the value at the given key, if any, returning either the old value or + * nil if none was present. Throws an exception if the key is of the wrong type. + * + * @param key [Object] + * @return [Object] + */ +static VALUE Map_delete(VALUE _self, VALUE key) { + upb_Map* map = Map_GetMutable(_self); + Map* self = ruby_to_Map(_self); + + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val_upb; + + if (upb_Map_Delete(map, key_upb, &val_upb)) { + return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Map#clear + * + * Removes all entries from the map. + * + * @return [nil] + */ +static VALUE Map_clear(VALUE _self) { + upb_Map_Clear(Map_GetMutable(_self)); + return Qnil; +} + +/* + * ruby-doc: Map#length + * + * Returns the number of entries (key-value pairs) in the map. + * + * @return [Integer] + */ +static VALUE Map_length(VALUE _self) { + Map* self = ruby_to_Map(_self); + return ULL2NUM(upb_Map_Size(self->map)); +} + +/* + * ruby-doc: Map#dup + * + * Duplicates this map with a shallow copy. References to all non-primitive + * element objects (e.g., submessages) are shared. + * + * @return [Map] + */ +static VALUE Map_dup(VALUE _self) { + Map* self = ruby_to_Map(_self); + VALUE new_map_rb = Map_new_this_type(self); + Map* new_self = ruby_to_Map(new_map_rb); + size_t iter = kUpb_Map_Begin; + upb_Arena* arena = Arena_get(new_self->arena); + upb_Map* new_map = Map_GetMutable(new_map_rb); + + Arena_fuse(self->arena, arena); + + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + upb_Map_Set(new_map, key, val, arena); + } + + return new_map_rb; +} + +/* + * ruby-doc: Map#== + * + * Compares this map to another. Maps are equal if they have identical key sets, + * and for each key, the values in both maps compare equal. Elements are + * compared as per normal Ruby semantics, by calling their :== methods (or + * performing a more efficient comparison for primitive types). + * + * Maps with dissimilar key types or value types/typeclasses are never equal, + * even if value comparison (for example, between integers and floats) would + * have otherwise indicated that every element has equal value. + * + * @param other [Map] + * @return [Boolean] + */ +VALUE Map_eq(VALUE _self, VALUE _other) { + Map* self = ruby_to_Map(_self); + Map* other; + + // Allow comparisons to Ruby hashmaps by converting to a temporary Map + // instance. Slow, but workable. + if (TYPE(_other) == T_HASH) { + VALUE other_map = Map_new_this_type(self); + Map_merge_into_self(other_map, _other); + _other = other_map; + } + + other = ruby_to_Map(_other); + + if (self == other) { + return Qtrue; + } + if (self->key_type != other->key_type || + self->value_type_info.type != other->value_type_info.type || + self->value_type_class != other->value_type_class) { + return Qfalse; + } + if (upb_Map_Size(self->map) != upb_Map_Size(other->map)) { + return Qfalse; + } + + // For each member of self, check that an equal member exists at the same key + // in other. + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + upb_MessageValue other_val; + if (!upb_Map_Get(other->map, key, &other_val)) { + // Not present in other map. + return Qfalse; + } + if (!Msgval_IsEqual(val, other_val, self->value_type_info)) { + // Present but different value. + return Qfalse; + } + } + + return Qtrue; +} + +/* + * ruby-doc: Map#frozen? + * + * Returns true if the map is frozen in either Ruby or the underlying + * representation. Freezes the Ruby map object if it is not already frozen in + * Ruby but it is frozen in the underlying representation. + * + * @return [Boolean] + */ +VALUE Map_frozen(VALUE _self) { + Map* self = ruby_to_Map(_self); + if (!upb_Map_IsFrozen(self->map)) { + PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self)); + return Qfalse; + } + + // Lazily freeze the Ruby wrapper. + if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self); + return Qtrue; +} + +/* + * ruby-doc: Map#freeze + * + * Freezes the map object. We have to intercept this so we can freeze the + * underlying representation, not just the Ruby wrapper. + * + * @return [self] + */ +VALUE Map_freeze(VALUE _self) { + Map* self = ruby_to_Map(_self); + if (RB_OBJ_FROZEN(_self)) { + PBRUBY_ASSERT(upb_Map_IsFrozen(self->map)); + return _self; + } + + if (!upb_Map_IsFrozen(self->map)) { + if (self->value_type_info.type == kUpb_CType_Message) { + upb_Map_Freeze( + Map_GetMutable(_self), + upb_MessageDef_MiniTable(self->value_type_info.def.msgdef)); + } else { + upb_Map_Freeze(Map_GetMutable(_self), NULL); + } + } + + RB_OBJ_FREEZE(_self); + + return _self; +} + +VALUE Map_EmptyFrozen(const upb_FieldDef* f) { + PBRUBY_ASSERT(upb_FieldDef_IsMap(f)); + VALUE val = ObjectCache_Get(f); + + if (val == Qnil) { + const upb_FieldDef* key_f = map_field_key(f); + const upb_FieldDef* val_f = map_field_value(f); + upb_CType key_type = upb_FieldDef_CType(key_f); + TypeInfo value_type_info = TypeInfo_get(val_f); + val = Map_alloc(cMap); + Map* self; + TypedData_Get_Struct(val, Map, &Map_type, self); + self->arena = Arena_new(); + self->map = + upb_Map_New(Arena_get(self->arena), key_type, value_type_info.type); + self->key_type = key_type; + self->value_type_info = value_type_info; + if (self->value_type_info.type == kUpb_CType_Message) { + const upb_MessageDef* val_m = value_type_info.def.msgdef; + self->value_type_class = Descriptor_DefToClass(val_m); + } + return ObjectCache_TryAdd(f, Map_freeze(val)); + } + PBRUBY_ASSERT(RB_OBJ_FROZEN(val)); + PBRUBY_ASSERT(upb_Map_IsFrozen(ruby_to_Map(val)->map)); + return val; +} + +/* + * ruby-doc: Map#hash + * + * Returns a hash value based on this map's contents. + * + * @return [Integer] + */ +VALUE Map_hash(VALUE _self) { + Map* self = ruby_to_Map(_self); + uint64_t hash = 0; + + size_t iter = kUpb_Map_Begin; + TypeInfo key_info = {self->key_type}; + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + hash += Msgval_GetHash(key, key_info, 0); + hash += Msgval_GetHash(val, self->value_type_info, 0); + } + + return LL2NUM(hash); +} + +/* + * ruby-doc: Map#to_h + * + * Returns a Ruby Hash object containing all the values within the map + * + * @return [Hash] + */ +VALUE Map_to_h(VALUE _self) { + Map* self = ruby_to_Map(_self); + return Map_CreateHash(self->map, self->key_type, self->value_type_info); +} + +/* + * ruby-doc: Map#inspect + * + * Returns a string representing this map's elements. It will be formatted as + * "{key => value, key => value, ...}", with each key and value string + * representation computed by its own #inspect method. + * + * @return [String] + */ +VALUE Map_inspect(VALUE _self) { + Map* self = ruby_to_Map(_self); + + StringBuilder* builder = StringBuilder_New(); + Map_Inspect(builder, self->map, self->key_type, self->value_type_info); + VALUE ret = StringBuilder_ToRubyString(builder); + StringBuilder_Free(builder); + return ret; +} + +/* + * ruby-doc: Map#merge + * + * Copies key/value pairs from other_map into a copy of this map. If a key is + * set in other_map and this map, the value from other_map overwrites the value + * in the new copy of this map. Returns the new copy of this map with merged + * contents. + * + * @param other_map [Map] + * @return [Map] + */ +static VALUE Map_merge(VALUE _self, VALUE hashmap) { + VALUE dupped = Map_dup(_self); + return Map_merge_into_self(dupped, hashmap); +} + +void Map_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "Map", rb_cObject); + rb_define_alloc_func(klass, Map_alloc); + rb_gc_register_address(&cMap); + cMap = klass; + + rb_define_method(klass, "initialize", Map_init, -1); + rb_define_method(klass, "each", Map_each, 0); + rb_define_method(klass, "keys", Map_keys, 0); + rb_define_method(klass, "values", Map_values, 0); + rb_define_method(klass, "[]", Map_index, 1); + rb_define_method(klass, "[]=", Map_index_set, 2); + rb_define_method(klass, "has_key?", Map_has_key, 1); + rb_define_method(klass, "delete", Map_delete, 1); + rb_define_method(klass, "clear", Map_clear, 0); + rb_define_method(klass, "length", Map_length, 0); + rb_define_method(klass, "size", Map_length, 0); + rb_define_method(klass, "dup", Map_dup, 0); + // Also define #clone so that we don't inherit Object#clone. + rb_define_method(klass, "clone", Map_dup, 0); + rb_define_method(klass, "==", Map_eq, 1); + rb_define_method(klass, "freeze", Map_freeze, 0); + rb_define_method(klass, "frozen?", Map_frozen, 0); + rb_define_method(klass, "hash", Map_hash, 0); + rb_define_method(klass, "to_h", Map_to_h, 0); + rb_define_method(klass, "inspect", Map_inspect, 0); + rb_define_method(klass, "merge", Map_merge, 1); + rb_include_module(klass, rb_mEnumerable); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.h new file mode 100755 index 0000000..58e8c25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.h @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_MAP_H_ +#define RUBY_PROTOBUF_MAP_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Returns a frozen sentinel Ruby wrapper object for an empty upb_Map with the +// key and value types specified by the field. Creates one if it doesn't exist. +VALUE Map_EmptyFrozen(const upb_FieldDef* f); + +// Returns a Ruby wrapper object for the given map, which will be created if +// one does not exist already. +VALUE Map_GetRubyWrapper(const upb_Map *map, upb_CType key_type, + TypeInfo value_type, VALUE arena); + +// Gets the underlying upb_Map for this Ruby map object, which must have +// key/value type that match |field|. If this is not a map or the type doesn't +// match, raises an exception. +const upb_Map *Map_GetUpbMap(VALUE val, const upb_FieldDef *field, + upb_Arena *arena); + +// Implements #inspect for this map by appending its contents to |b|. +void Map_Inspect(StringBuilder *b, const upb_Map *map, upb_CType key_type, + TypeInfo val_type); + +// Returns a new Hash object containing the contents of this Map. +VALUE Map_CreateHash(const upb_Map *map, upb_CType key_type, TypeInfo val_info); + +// Returns a deep copy of this Map object. +VALUE Map_deep_copy(VALUE obj); + +// Ruby class of Google::Protobuf::Map. +extern VALUE cMap; + +// Call at startup to register all types in this module. +void Map_register(VALUE module); + +// Recursively freeze map +VALUE Map_freeze(VALUE _self); + +#endif // RUBY_PROTOBUF_MAP_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.c new file mode 100755 index 0000000..93b9c7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.c @@ -0,0 +1,1462 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "message.h" + +#include "convert.h" +#include "defs.h" +#include "map.h" +#include "protobuf.h" +#include "repeated_field.h" +#include "shared_message.h" + +static VALUE cParseError = Qnil; +static VALUE cAbstractMessage = Qnil; +static ID descriptor_instancevar_interned; + +static VALUE initialize_rb_class_with_no_args(VALUE klass) { + return rb_funcall(klass, rb_intern("new"), 0); +} + +VALUE MessageOrEnum_GetDescriptor(VALUE klass) { + return rb_ivar_get(klass, descriptor_instancevar_interned); +} + +// ----------------------------------------------------------------------------- +// Class/module creation from msgdefs and enumdefs, respectively. +// ----------------------------------------------------------------------------- + +typedef struct { + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE arena; + const upb_Message* msg; // Can get as mutable when non-frozen. + const upb_MessageDef* + msgdef; // kept alive by self.class.descriptor reference. +} Message; + +static void Message_mark(void* _self) { + Message* self = (Message*)_self; + rb_gc_mark(self->arena); +} + +static size_t Message_memsize(const void* _self) { return sizeof(Message); } + +static rb_data_type_t Message_type = { + "Google::Protobuf::Message", + {Message_mark, RUBY_DEFAULT_FREE, Message_memsize}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static Message* ruby_to_Message(VALUE msg_rb) { + Message* msg; + TypedData_Get_Struct(msg_rb, Message, &Message_type, msg); + return msg; +} + +static VALUE Message_alloc(VALUE klass) { + VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned); + Message* msg = ALLOC(Message); + VALUE ret; + + msg->msgdef = Descriptor_GetMsgDef(descriptor); + msg->arena = Qnil; + msg->msg = NULL; + + ret = TypedData_Wrap_Struct(klass, &Message_type, msg); + rb_ivar_set(ret, descriptor_instancevar_interned, descriptor); + + return ret; +} + +const upb_Message* Message_Get(VALUE msg_rb, const upb_MessageDef** m) { + Message* msg = ruby_to_Message(msg_rb); + if (m) *m = msg->msgdef; + return msg->msg; +} + +upb_Message* Message_GetMutable(VALUE msg_rb, const upb_MessageDef** m) { + const upb_Message* upb_msg = Message_Get(msg_rb, m); + Protobuf_CheckNotFrozen(msg_rb, upb_Message_IsFrozen(upb_msg)); + return (upb_Message*)upb_msg; +} + +void Message_InitPtr(VALUE self_, const upb_Message* msg, VALUE arena) { + PBRUBY_ASSERT(arena != Qnil); + Message* self = ruby_to_Message(self_); + self->msg = msg; + RB_OBJ_WRITE(self_, &self->arena, arena); + VALUE stored = ObjectCache_TryAdd(msg, self_); + (void)stored; + PBRUBY_ASSERT(stored == self_); +} + +VALUE Message_GetArena(VALUE msg_rb) { + Message* msg = ruby_to_Message(msg_rb); + return msg->arena; +} + +void Message_CheckClass(VALUE klass) { + if (rb_get_alloc_func(klass) != &Message_alloc) { + rb_raise(rb_eArgError, + "Message class was not returned by the DescriptorPool."); + } +} + +VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m, + VALUE arena) { + if (msg == NULL) return Qnil; + + VALUE val = ObjectCache_Get(msg); + + if (val == Qnil) { + VALUE klass = Descriptor_DefToClass(m); + val = Message_alloc(klass); + Message_InitPtr(val, msg, arena); + } + return val; +} + +void Message_PrintMessage(StringBuilder* b, const upb_Message* msg, + const upb_MessageDef* m) { + bool first = true; + int n = upb_MessageDef_FieldCount(m); + VALUE klass = Descriptor_DefToClass(m); + StringBuilder_Printf(b, "<%s: ", rb_class2name(klass)); + + for (int i = 0; i < n; i++) { + const upb_FieldDef* field = upb_MessageDef_Field(m, i); + + if (upb_FieldDef_HasPresence(field) && + !upb_Message_HasFieldByDef(msg, field)) { + continue; + } + + if (!first) { + StringBuilder_Printf(b, ", "); + } else { + first = false; + } + + upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, field); + + StringBuilder_Printf(b, "%s: ", upb_FieldDef_Name(field)); + + if (upb_FieldDef_IsMap(field)) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + TypeInfo val_info = TypeInfo_get(val_f); + Map_Inspect(b, msgval.map_val, upb_FieldDef_CType(key_f), val_info); + } else if (upb_FieldDef_IsRepeated(field)) { + RepeatedField_Inspect(b, msgval.array_val, TypeInfo_get(field)); + } else { + StringBuilder_PrintMsgval(b, msgval, TypeInfo_get(field)); + } + } + + StringBuilder_Printf(b, ">"); +} + +// Helper functions for #method_missing //////////////////////////////////////// + +enum { + METHOD_UNKNOWN = 0, + METHOD_GETTER = 1, + METHOD_SETTER = 2, + METHOD_CLEAR = 3, + METHOD_PRESENCE = 4, + METHOD_ENUM_GETTER = 5, + METHOD_WRAPPER_GETTER = 6, + METHOD_WRAPPER_SETTER = 7 +}; + +// Check if the field is a well known wrapper type +static bool IsWrapper(const upb_MessageDef* m) { + if (!m) return false; + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: + return true; + default: + return false; + } +} + +static bool IsFieldWrapper(const upb_FieldDef* f) { + return IsWrapper(upb_FieldDef_MessageSubDef(f)); +} + +static bool Match(const upb_MessageDef* m, const char* name, + const upb_FieldDef** f, const upb_OneofDef** o, + const char* prefix, const char* suffix) { + size_t sp = strlen(prefix); + size_t ss = strlen(suffix); + size_t sn = strlen(name); + + if (sn <= sp + ss) return false; + + if (memcmp(name, prefix, sp) != 0 || + memcmp(name + sn - ss, suffix, ss) != 0) { + return false; + } + + return upb_MessageDef_FindByNameWithSize(m, name + sp, sn - sp - ss, f, o); +} + +static int extract_method_call(VALUE method_name, Message* self, + const upb_FieldDef** f, const upb_OneofDef** o) { + const upb_MessageDef* m = self->msgdef; + const char* name; + + Check_Type(method_name, T_SYMBOL); + name = rb_id2name(SYM2ID(method_name)); + + if (Match(m, name, f, o, "", "")) return METHOD_GETTER; + if (Match(m, name, f, o, "", "=")) return METHOD_SETTER; + if (Match(m, name, f, o, "clear_", "")) return METHOD_CLEAR; + if (Match(m, name, f, o, "has_", "?") && + (*o || (*f && upb_FieldDef_HasPresence(*f)))) { + return METHOD_PRESENCE; + } + if (Match(m, name, f, o, "", "_as_value") && *f && + !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) { + return METHOD_WRAPPER_GETTER; + } + if (Match(m, name, f, o, "", "_as_value=") && *f && + !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) { + return METHOD_WRAPPER_SETTER; + } + if (Match(m, name, f, o, "", "_const") && *f && + upb_FieldDef_CType(*f) == kUpb_CType_Enum) { + return METHOD_ENUM_GETTER; + } + + return METHOD_UNKNOWN; +} + +static VALUE Message_oneof_accessor(VALUE _self, const upb_OneofDef* o, + int accessor_type) { + Message* self = ruby_to_Message(_self); + const upb_FieldDef* oneof_field = upb_Message_WhichOneofByDef(self->msg, o); + + switch (accessor_type) { + case METHOD_PRESENCE: + return oneof_field == NULL ? Qfalse : Qtrue; + case METHOD_CLEAR: + if (oneof_field != NULL) { + upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL), + oneof_field); + } + return Qnil; + case METHOD_GETTER: + return oneof_field == NULL + ? Qnil + : ID2SYM(rb_intern(upb_FieldDef_Name(oneof_field))); + case METHOD_SETTER: + rb_raise(rb_eRuntimeError, "Oneof accessors are read-only."); + } + rb_raise(rb_eRuntimeError, "Invalid access of oneof field."); +} + +static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val, + upb_Arena* arena) { + upb_MessageValue msgval; + if (upb_FieldDef_IsMap(f)) { + msgval.map_val = Map_GetUpbMap(val, f, arena); + } else if (upb_FieldDef_IsRepeated(f)) { + msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); + } else { + if (val == Qnil && + (upb_FieldDef_IsSubMessage(f) || upb_FieldDef_RealContainingOneof(f))) { + upb_Message_ClearFieldByDef(msg, f); + return; + } + msgval = + Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + } + upb_Message_SetFieldByDef(msg, f, msgval, arena); +} + +VALUE Message_getfield_frozen(const upb_Message* msg, const upb_FieldDef* f, + VALUE arena) { + upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f); + if (upb_FieldDef_IsMap(f)) { + if (msgval.map_val == NULL) { + return Map_EmptyFrozen(f); + } + const upb_FieldDef* key_f = map_field_key(f); + const upb_FieldDef* val_f = map_field_value(f); + upb_CType key_type = upb_FieldDef_CType(key_f); + TypeInfo value_type_info = TypeInfo_get(val_f); + return Map_GetRubyWrapper(msgval.map_val, key_type, value_type_info, arena); + } + if (upb_FieldDef_IsRepeated(f)) { + if (msgval.array_val == NULL) { + return RepeatedField_EmptyFrozen(f); + } + return RepeatedField_GetRubyWrapper(msgval.array_val, TypeInfo_get(f), + arena); + } + VALUE ret; + if (upb_FieldDef_IsSubMessage(f)) { + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + ret = Message_GetRubyWrapper(msgval.msg_val, m, arena); + } else { + ret = Convert_UpbToRuby(msgval, TypeInfo_get(f), Qnil); + } + return ret; +} + +VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) { + Message* self = ruby_to_Message(_self); + if (upb_Message_IsFrozen(self->msg)) { + return Message_getfield_frozen(self->msg, f, self->arena); + } + upb_Message* msg = Message_GetMutable(_self, NULL); + upb_Arena* arena = Arena_get(self->arena); + if (upb_FieldDef_IsMap(f)) { + upb_Map* map = upb_Message_Mutable(msg, f, arena).map; + const upb_FieldDef* key_f = map_field_key(f); + const upb_FieldDef* val_f = map_field_value(f); + upb_CType key_type = upb_FieldDef_CType(key_f); + TypeInfo value_type_info = TypeInfo_get(val_f); + return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena); + } else if (upb_FieldDef_IsRepeated(f)) { + upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; + return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena); + } else if (upb_FieldDef_IsSubMessage(f)) { + if (!upb_Message_HasFieldByDef(msg, f)) return Qnil; + upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + return Message_GetRubyWrapper(submsg, m, self->arena); + } else { + upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f); + return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena); + } +} + +static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f, + int accessor_type, int argc, VALUE* argv) { + upb_Arena* arena = Arena_get(Message_GetArena(_self)); + + switch (accessor_type) { + case METHOD_SETTER: + Message_setfield(Message_GetMutable(_self, NULL), f, argv[1], arena); + return Qnil; + case METHOD_CLEAR: + upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL), f); + return Qnil; + case METHOD_PRESENCE: + if (!upb_FieldDef_HasPresence(f)) { + rb_raise(rb_eRuntimeError, "Field does not have presence."); + } + return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f) ? Qtrue + : Qfalse; + case METHOD_WRAPPER_GETTER: { + Message* self = ruby_to_Message(_self); + if (upb_Message_HasFieldByDef(self->msg, f)) { + PBRUBY_ASSERT(upb_FieldDef_IsSubMessage(f) && + !upb_FieldDef_IsRepeated(f)); + upb_MessageValue wrapper = upb_Message_GetFieldByDef(self->msg, f); + const upb_MessageDef* wrapper_m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* value_f = + upb_MessageDef_FindFieldByNumber(wrapper_m, 1); + upb_MessageValue value = + upb_Message_GetFieldByDef(wrapper.msg_val, value_f); + return Convert_UpbToRuby(value, TypeInfo_get(value_f), self->arena); + } else { + return Qnil; + } + } + case METHOD_WRAPPER_SETTER: { + upb_Message* msg = Message_GetMutable(_self, NULL); + if (argv[1] == Qnil) { + upb_Message_ClearFieldByDef(msg, f); + } else { + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumber(upb_FieldDef_MessageSubDef(f), 1); + upb_MessageValue msgval = Convert_RubyToUpb( + argv[1], upb_FieldDef_Name(f), TypeInfo_get(val_f), arena); + upb_Message* wrapper = upb_Message_Mutable(msg, f, arena).msg; + upb_Message_SetFieldByDef(wrapper, val_f, msgval, arena); + } + return Qnil; + } + case METHOD_ENUM_GETTER: { + upb_MessageValue msgval = + upb_Message_GetFieldByDef(Message_Get(_self, NULL), f); + + if (upb_FieldDef_IsRepeated(f)) { + // Map repeated fields to a new type with ints + VALUE arr = rb_ary_new(); + size_t i, n = upb_Array_Size(msgval.array_val); + for (i = 0; i < n; i++) { + upb_MessageValue elem = upb_Array_Get(msgval.array_val, i); + rb_ary_push(arr, INT2NUM(elem.int32_val)); + } + return arr; + } else { + return INT2NUM(msgval.int32_val); + } + } + case METHOD_GETTER: + return Message_getfield(_self, f); + default: + rb_raise(rb_eRuntimeError, "Internal error, no such accessor: %d", + accessor_type); + } +} + +/* + * ruby-doc: AbstractMessage + * + * The {AbstractMessage} class is the parent class for all Protobuf messages, + * and is generated from C code. + * + * For any field whose name does not conflict with a built-in method, an + * accessor is provided with the same name as the field, and a setter is + * provided with the name of the field plus the '=' suffix. Thus, given a + * message instance 'msg' with field 'foo', the following code is valid: + * + * msg.foo = 42 + * puts msg.foo + * + * This method also provides read-only accessors for oneofs. If a oneof exists + * with name 'my_oneof', then msg.my_oneof will return a Ruby symbol equal to + * the name of the field in that oneof that is currently set, or nil if none. + * + * It also provides methods of the form 'clear_fieldname' to clear the value + * of the field 'fieldname'. For basic data types, this will set the default + * value of the field. + * + * Additionally, it provides methods of the form 'has_fieldname?', which returns + * true if the field 'fieldname' is set in the message object, else false. For + * 'proto3' syntax, calling this for a basic type field will result in an error. + */ +static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { + Message* self = ruby_to_Message(_self); + const upb_OneofDef* o; + const upb_FieldDef* f; + int accessor_type; + + if (argc < 1) { + rb_raise(rb_eArgError, "Expected method name as first argument."); + } + + accessor_type = extract_method_call(argv[0], self, &f, &o); + + if (accessor_type == METHOD_UNKNOWN) return rb_call_super(argc, argv); + + // Validate argument count. + switch (accessor_type) { + case METHOD_SETTER: + case METHOD_WRAPPER_SETTER: + if (argc != 2) { + rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc); + } + break; + default: + if (argc != 1) { + rb_raise(rb_eArgError, "Expected 1 argument, received %d", argc); + } + break; + } + + // Dispatch accessor. + if (o != NULL) { + return Message_oneof_accessor(_self, o, accessor_type); + } else { + return Message_field_accessor(_self, f, accessor_type, argc, argv); + } +} + +static VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) { + Message* self = ruby_to_Message(_self); + const upb_OneofDef* o; + const upb_FieldDef* f; + int accessor_type; + + if (argc < 1) { + rb_raise(rb_eArgError, "Expected method name as first argument."); + } + + accessor_type = extract_method_call(argv[0], self, &f, &o); + + if (accessor_type == METHOD_UNKNOWN) { + return rb_call_super(argc, argv); + } else if (o != NULL) { + return accessor_type == METHOD_SETTER ? Qfalse : Qtrue; + } else { + return Qtrue; + } +} + +void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val, + upb_Arena* arena); + +typedef struct { + upb_Map* map; + TypeInfo key_type; + TypeInfo val_type; + upb_Arena* arena; +} MapInit; + +static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { + MapInit* map_init = (MapInit*)_self; + upb_MessageValue k, v; + k = Convert_RubyToUpb(key, "", map_init->key_type, NULL); + + if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) { + const upb_MiniTable* t = + upb_MessageDef_MiniTable(map_init->val_type.def.msgdef); + upb_Message* msg = upb_Message_New(t, map_init->arena); + Message_InitFromValue(msg, map_init->val_type.def.msgdef, val, + map_init->arena); + v.msg_val = msg; + } else { + v = Convert_RubyToUpb(val, "", map_init->val_type, map_init->arena); + } + upb_Map_Set(map_init->map, k, v, map_init->arena); + return ST_CONTINUE; +} + +static void Map_InitFromValue(upb_Map* map, const upb_FieldDef* f, VALUE val, + upb_Arena* arena) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + if (TYPE(val) != T_HASH) { + rb_raise(rb_eArgError, + "Expected Hash object as initializer value for map field '%s' " + "(given %s).", + upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val))); + } + MapInit map_init = {map, TypeInfo_get(key_f), TypeInfo_get(val_f), arena}; + rb_hash_foreach(val, Map_initialize_kwarg, (VALUE)&map_init); +} + +static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info, + upb_Arena* arena) { + if (info.type == kUpb_CType_Message) { + upb_MessageValue msgval; + const upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef); + upb_Message* msg = upb_Message_New(t, arena); + Message_InitFromValue(msg, info.def.msgdef, val, arena); + msgval.msg_val = msg; + return msgval; + } else { + return Convert_RubyToUpb(val, "", info, arena); + } +} + +static void RepeatedField_InitFromValue(upb_Array* arr, const upb_FieldDef* f, + VALUE val, upb_Arena* arena) { + TypeInfo type_info = TypeInfo_get(f); + + if (TYPE(val) != T_ARRAY) { + rb_raise(rb_eArgError, + "Expected array as initializer value for repeated field '%s' " + "(given %s).", + upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val))); + } + + for (int i = 0; i < RARRAY_LEN(val); i++) { + VALUE entry = rb_ary_entry(val, i); + upb_MessageValue msgval; + if (upb_FieldDef_IsSubMessage(f) && TYPE(entry) == T_HASH) { + msgval = MessageValue_FromValue(entry, type_info, arena); + } else { + msgval = Convert_RubyToUpb(entry, upb_FieldDef_Name(f), type_info, arena); + } + upb_Array_Append(arr, msgval, arena); + } +} + +static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f, + VALUE val, upb_Arena* arena) { + if (TYPE(val) == T_NIL) return; + + if (upb_FieldDef_IsMap(f)) { + upb_Map* map = upb_Message_Mutable(msg, f, arena).map; + Map_InitFromValue(map, f, val, arena); + } else if (upb_FieldDef_IsRepeated(f)) { + upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; + RepeatedField_InitFromValue(arr, f, val, arena); + } else if (upb_FieldDef_IsSubMessage(f)) { + if (TYPE(val) == T_HASH) { + upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + Message_InitFromValue(submsg, upb_FieldDef_MessageSubDef(f), val, arena); + } else { + Message_setfield(msg, f, val, arena); + } + } else { + upb_MessageValue msgval = + Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + upb_Message_SetFieldByDef(msg, f, msgval, arena); + } +} + +typedef struct { + upb_Message* msg; + const upb_MessageDef* msgdef; + upb_Arena* arena; +} MsgInit; + +static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { + MsgInit* msg_init = (MsgInit*)_self; + const char* name; + + if (TYPE(key) == T_STRING) { + name = RSTRING_PTR(key); + } else if (TYPE(key) == T_SYMBOL) { + name = RSTRING_PTR(rb_id2str(SYM2ID(key))); + } else { + rb_raise(rb_eArgError, + "Expected string or symbols as hash keys when initializing proto " + "from hash."); + } + + const upb_FieldDef* f = + upb_MessageDef_FindFieldByName(msg_init->msgdef, name); + + if (f == NULL) { + rb_raise(rb_eArgError, + "Unknown field name '%s' in initialization map entry.", name); + } + + Message_InitFieldFromValue(msg_init->msg, f, val, msg_init->arena); + return ST_CONTINUE; +} + +void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val, + upb_Arena* arena) { + MsgInit msg_init = {msg, m, arena}; + if (TYPE(val) == T_HASH) { + rb_hash_foreach(val, Message_initialize_kwarg, (VALUE)&msg_init); + } else { + rb_raise(rb_eArgError, "Expected hash arguments or message, not %s", + rb_class2name(CLASS_OF(val))); + } +} + +/* + * ruby-doc: AbstractMessage#initialize + * + * Creates a new instance of the given message class. Keyword arguments may be + * provided with keywords corresponding to field names. + * + * @param kwargs the list of field keys and values. + */ +static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) { + Message* self = ruby_to_Message(_self); + VALUE arena_rb = Arena_new(); + upb_Arena* arena = Arena_get(arena_rb); + const upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef); + upb_Message* msg = upb_Message_New(t, arena); + + Message_InitPtr(_self, msg, arena_rb); + + if (argc == 0) { + return Qnil; + } + if (argc != 1) { + rb_raise(rb_eArgError, "Expected 0 or 1 arguments."); + } + Message_InitFromValue((upb_Message*)self->msg, self->msgdef, argv[0], arena); + return Qnil; +} + +/* + * ruby-doc: AbstractMessage#dup + * + * Performs a shallow copy of this message and returns the new copy. + * + * @return [AbstractMessage] + */ +static VALUE Message_dup(VALUE _self) { + Message* self = ruby_to_Message(_self); + VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self)); + Message* new_msg_self = ruby_to_Message(new_msg); + const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef); + upb_Message_ShallowCopy((upb_Message*)new_msg_self->msg, self->msg, m); + Arena_fuse(self->arena, Arena_get(new_msg_self->arena)); + return new_msg; +} + +/* + * ruby-doc: AbstractMessage#== + * + * Performs a deep comparison of this message with another. Messages are equal + * if they have the same type and if each field is equal according to the :== + * method's semantics (a more efficient comparison may actually be done if the + * field is of a primitive type). + * + * @param other [AbstractMessage] + * @return [Boolean] + */ +static VALUE Message_eq(VALUE _self, VALUE _other) { + if (CLASS_OF(_self) != CLASS_OF(_other)) return Qfalse; + + Message* self = ruby_to_Message(_self); + Message* other = ruby_to_Message(_other); + assert(self->msgdef == other->msgdef); + + const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef); + const int options = 0; + return upb_Message_IsEqual(self->msg, other->msg, m, options) ? Qtrue + : Qfalse; +} + +uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed) { + upb_Status status; + upb_Status_Clear(&status); + uint64_t return_value = shared_Message_Hash(msg, m, seed, &status); + if (upb_Status_IsOk(&status)) { + return return_value; + } else { + rb_raise(cParseError, "Message_Hash(): %s", + upb_Status_ErrorMessage(&status)); + } +} + +/* + * ruby-doc: AbstractMessage#hash + * + * Returns a hash value that represents this message's field values. + * + * @return [Integer] + */ +static VALUE Message_hash(VALUE _self) { + Message* self = ruby_to_Message(_self); + uint64_t hash_value = Message_Hash(self->msg, self->msgdef, 0); + // RUBY_FIXNUM_MAX should be one less than a power of 2. + assert((RUBY_FIXNUM_MAX & (RUBY_FIXNUM_MAX + 1)) == 0); + return INT2FIX(hash_value & RUBY_FIXNUM_MAX); +} + +/* + * ruby-doc: AbstractMessage#inspect + * + * Returns a human-readable string representing this message. It will be + * formatted as "". Each + * field's value is represented according to its own #inspect method. + * + * @return [String] + */ +static VALUE Message_inspect(VALUE _self) { + Message* self = ruby_to_Message(_self); + + StringBuilder* builder = StringBuilder_New(); + Message_PrintMessage(builder, self->msg, self->msgdef); + VALUE ret = StringBuilder_ToRubyString(builder); + StringBuilder_Free(builder); + return ret; +} + +// Support functions for Message_to_h ////////////////////////////////////////// + +static VALUE RepeatedField_CreateArray(const upb_Array* arr, + TypeInfo type_info) { + int size = arr ? upb_Array_Size(arr) : 0; + VALUE ary = rb_ary_new2(size); + + for (int i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(arr, i); + VALUE val = Scalar_CreateHash(msgval, type_info); + rb_ary_push(ary, val); + } + + return ary; +} + +static VALUE Message_CreateHash(const upb_Message* msg, + const upb_MessageDef* m) { + if (!msg) return Qnil; + + VALUE hash = rb_hash_new(); + size_t iter = kUpb_Message_Begin; + const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(m)); + const upb_FieldDef* field; + upb_MessageValue val; + + while (upb_Message_Next(msg, m, pool, &field, &val, &iter)) { + if (upb_FieldDef_IsExtension(field)) { + // TODO: allow extensions once we have decided what naming scheme the + // symbol should use. eg. :"[pkg.ext]" + continue; + } + + TypeInfo type_info = TypeInfo_get(field); + VALUE msg_value; + + if (upb_FieldDef_IsMap(field)) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + upb_CType key_type = upb_FieldDef_CType(key_f); + msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f)); + } else if (upb_FieldDef_IsRepeated(field)) { + msg_value = RepeatedField_CreateArray(val.array_val, type_info); + } else { + msg_value = Scalar_CreateHash(val, type_info); + } + + VALUE msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field))); + rb_hash_aset(hash, msg_key, msg_value); + } + + return hash; +} + +VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) { + if (type_info.type == kUpb_CType_Message) { + return Message_CreateHash(msgval.msg_val, type_info.def.msgdef); + } else { + return Convert_UpbToRuby(msgval, type_info, Qnil); + } +} + +/* + * ruby-doc: AbstractMessage#to_h + * + * Returns the message as a Ruby Hash object, with keys as symbols. + * + * @return [Hash] + */ +static VALUE Message_to_h(VALUE _self) { + Message* self = ruby_to_Message(_self); + return Message_CreateHash(self->msg, self->msgdef); +} + +/* + * ruby-doc: AbstractMessage#frozen? + * + * Returns true if the message is frozen in either Ruby or the underlying + * representation. Freezes the Ruby message object if it is not already frozen + * in Ruby but it is frozen in the underlying representation. + * + * @return [Boolean] + */ +VALUE Message_frozen(VALUE _self) { + Message* self = ruby_to_Message(_self); + if (!upb_Message_IsFrozen(self->msg)) { + PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self)); + return Qfalse; + } + + // Lazily freeze the Ruby wrapper. + if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self); + return Qtrue; +} + +/* + * ruby-doc: AbstractMessage#freeze + * + * Freezes the message object. We have to intercept this so we can freeze the + * underlying representation, not just the Ruby wrapper. + * + * @return [self] + */ +VALUE Message_freeze(VALUE _self) { + Message* self = ruby_to_Message(_self); + if (RB_OBJ_FROZEN(_self)) { + PBRUBY_ASSERT(upb_Message_IsFrozen(self->msg)); + return _self; + } + if (!upb_Message_IsFrozen(self->msg)) { + upb_Message_Freeze(Message_GetMutable(_self, NULL), + upb_MessageDef_MiniTable(self->msgdef)); + } + RB_OBJ_FREEZE(_self); + return _self; +} + +/* + * ruby-doc: AbstractMessage#[] + * + * Accesses a field's value by field name. The provided field name should be a + * string. + * + * @param index [Integer] + * @return [Object] + */ +static VALUE Message_index(VALUE _self, VALUE field_name) { + Message* self = ruby_to_Message(_self); + const upb_FieldDef* field; + + Check_Type(field_name, T_STRING); + field = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name)); + + if (field == NULL) { + return Qnil; + } + + return Message_getfield(_self, field); +} + +/* + * ruby-doc: AbstractMessage#[]= + * + * Sets a field's value by field name. The provided field name should be a + * string. + * + * @param index [Integer] + * @param value [Object] + * @return [nil] + */ +static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) { + Message* self = ruby_to_Message(_self); + const upb_FieldDef* f; + upb_MessageValue val; + upb_Arena* arena = Arena_get(self->arena); + + Check_Type(field_name, T_STRING); + f = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name)); + + if (f == NULL) { + rb_raise(rb_eArgError, "Unknown field: %s", RSTRING_PTR(field_name)); + } + + val = Convert_RubyToUpb(value, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val, arena); + + return Qnil; +} + +/* + * ruby-doc: AbstractMessage.decode + * + * Decodes the given data (as a string containing bytes in protocol buffers wire + * format) under the interpretation given by this message class's definition + * and returns a message object with the corresponding field values. + * @param data [String] + * @param options [Hash] + * @option recursion_limit [Integer] set to maximum decoding depth for message + * (default is 64) + * @return [AbstractMessage] + */ +static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) { + VALUE data = argv[0]; + int options = 0; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + + VALUE depth = + rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit"))); + + if (depth != Qnil && TYPE(depth) == T_FIXNUM) { + options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth)); + } + } + + if (TYPE(data) != T_STRING) { + rb_raise(rb_eArgError, "Expected string for binary protobuf data."); + } + + return Message_decode_bytes(RSTRING_LEN(data), RSTRING_PTR(data), options, + klass, /*freeze*/ false); +} + +VALUE Message_decode_bytes(size_t size, const char* bytes, int options, + VALUE klass, bool freeze) { + VALUE msg_rb = initialize_rb_class_with_no_args(klass); + Message* msg = ruby_to_Message(msg_rb); + + const upb_FileDef* file = upb_MessageDef_File(msg->msgdef); + const upb_ExtensionRegistry* extreg = + upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file)); + upb_DecodeStatus status = upb_Decode(bytes, size, (upb_Message*)msg->msg, + upb_MessageDef_MiniTable(msg->msgdef), + extreg, options, Arena_get(msg->arena)); + if (status != kUpb_DecodeStatus_Ok) { + rb_raise(cParseError, "Error occurred during parsing"); + } + if (freeze) { + Message_freeze(msg_rb); + } + return msg_rb; +} + +/* + * ruby-doc: AbstractMessage.decode_json + * + * Decodes the given data (as a string containing bytes in protocol buffers wire + * format) under the interpretration given by this message class's definition + * and returns a message object with the corresponding field values. + * + * @param data [String] + * @param options [Hash] + * @option ignore_unknown_fields [Boolean] set true to ignore unknown fields + * (default is to raise an error) + * @return [AbstractMessage] + */ +static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { + VALUE data = argv[0]; + int options = 0; + upb_Status status; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + + if (RTEST(rb_hash_lookup2( + hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse))) { + options |= upb_JsonDecode_IgnoreUnknown; + } + } + + if (TYPE(data) != T_STRING) { + rb_raise(rb_eArgError, "Expected string for JSON data."); + } + + // TODO: Check and respect string encoding. If not UTF-8, we need to + // convert, because string handlers pass data directly to message string + // fields. + + VALUE msg_rb = initialize_rb_class_with_no_args(klass); + Message* msg = ruby_to_Message(msg_rb); + + // We don't allow users to decode a wrapper type directly. + if (IsWrapper(msg->msgdef)) { + rb_raise(rb_eRuntimeError, "Cannot parse a wrapper directly."); + } + + upb_Status_Clear(&status); + const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef)); + + int result = upb_JsonDecodeDetectingNonconformance( + RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg, + msg->msgdef, pool, options, Arena_get(msg->arena), &status); + + switch (result) { + case kUpb_JsonDecodeResult_Ok: + break; + case kUpb_JsonDecodeResult_Error: + rb_raise(cParseError, "Error occurred during parsing: %s", + upb_Status_ErrorMessage(&status)); + break; + } + + return msg_rb; +} + +/* + * ruby-doc: AbstractMessage.encode + * + * Encodes the given message object to its serialized form in protocol buffers + * wire format. + * + * @param msg [AbstractMessage] + * @param options [Hash] + * @option recursion_limit [Integer] set to maximum encoding depth for message + * (default is 64) + * @return [String] + */ +static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) { + Message* msg = ruby_to_Message(argv[0]); + int options = 0; + char* data; + size_t size; + + if (CLASS_OF(argv[0]) != klass) { + rb_raise(rb_eArgError, "Message of wrong type."); + } + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + VALUE depth = + rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit"))); + + if (depth != Qnil && TYPE(depth) == T_FIXNUM) { + options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth)); + } + } + + upb_Arena* arena = upb_Arena_New(); + + upb_EncodeStatus status = + upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), options, + arena, &data, &size); + + if (status == kUpb_EncodeStatus_Ok) { + VALUE ret = rb_str_new(data, size); + rb_enc_associate(ret, rb_ascii8bit_encoding()); + upb_Arena_Free(arena); + return ret; + } else { + upb_Arena_Free(arena); + rb_raise(rb_eRuntimeError, "Exceeded maximum depth (possibly cycle)"); + } +} + +/* + * ruby-doc: AbstractMessage.encode_json + * + * Encodes the given message object into its serialized JSON representation. + * + * @param msg [AbstractMessage] + * @param options [Hash] + * @option preserve_proto_fieldnames [Boolean] set true to use original + * fieldnames (default is to camelCase) + * @option emit_defaults [Boolean] set true to emit 0/false values (default is + * to omit them) + * @return [String] + */ +static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) { + Message* msg = ruby_to_Message(argv[0]); + int options = 0; + char buf[1024]; + size_t size; + upb_Status status; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + if (RTEST(rb_funcall(hash_args, rb_intern("respond_to?"), 1, + rb_str_new2("to_h")))) { + hash_args = rb_funcall(hash_args, rb_intern("to_h"), 0); + } else { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + } + + if (RTEST(rb_hash_lookup2(hash_args, + ID2SYM(rb_intern("preserve_proto_fieldnames")), + Qfalse))) { + options |= upb_JsonEncode_UseProtoNames; + } + + if (RTEST(rb_hash_lookup2(hash_args, ID2SYM(rb_intern("emit_defaults")), + Qfalse))) { + options |= upb_JsonEncode_EmitDefaults; + } + + if (RTEST(rb_hash_lookup2(hash_args, + ID2SYM(rb_intern("format_enums_as_integers")), + Qfalse))) { + options |= upb_JsonEncode_FormatEnumsAsIntegers; + } + } + + upb_Status_Clear(&status); + const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef)); + size = upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf, sizeof(buf), + &status); + + if (!upb_Status_IsOk(&status)) { + rb_raise(cParseError, "Error occurred during encoding: %s", + upb_Status_ErrorMessage(&status)); + } + + VALUE ret; + if (size >= sizeof(buf)) { + char* buf2 = malloc(size + 1); + upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf2, size + 1, + &status); + ret = rb_str_new(buf2, size); + free(buf2); + } else { + ret = rb_str_new(buf, size); + } + + rb_enc_associate(ret, rb_utf8_encoding()); + return ret; +} + +/* + * ruby-doc: AbstractMessage.descriptor + * + * Class method that returns the Descriptor instance corresponding to this + * message class's type. + * + * @return [Descriptor] + */ +static VALUE Message_descriptor(VALUE klass) { + return rb_ivar_get(klass, descriptor_instancevar_interned); +} + +VALUE build_class_from_descriptor(VALUE descriptor) { + const char* name; + VALUE klass; + + name = upb_MessageDef_FullName(Descriptor_GetMsgDef(descriptor)); + if (name == NULL) { + rb_raise(rb_eRuntimeError, "Descriptor does not have assigned name."); + } + + klass = rb_define_class_id( + // Docs say this parameter is ignored. User will assign return value to + // their own toplevel constant class name. + rb_intern("Message"), cAbstractMessage); + rb_ivar_set(klass, descriptor_instancevar_interned, descriptor); + return klass; +} + +/* ruby-doc: Enum + * + * There isn't really a concrete `Enum` module generated by Protobuf. Instead, + * you can use this documentation as an indicator of methods that are defined on + * each `Enum` module that is generated. E.g. if you have: + * + * enum my_enum_type + * + * in your Proto file and generate Ruby code, a module + * called `MyEnumType` will be generated with the following methods available. + */ + +/* + * ruby-doc: Enum.lookup + * + * This module method, provided on each generated enum module, looks up an enum + * value by number and returns its name as a Ruby symbol, or nil if not found. + * + * @param number [Integer] + * @return [String] + */ +static VALUE enum_lookup(VALUE self, VALUE number) { + int32_t num = NUM2INT(number); + VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned); + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e, num); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Enum.resolve + * + * This module method, provided on each generated enum module, looks up an enum + * value by name (as a Ruby symbol) and returns its name, or nil if not found. + * + * @param name [String] + * @return [Integer] + */ +static VALUE enum_resolve(VALUE self, VALUE sym) { + const char* name = rb_id2name(SYM2ID(sym)); + VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned); + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByName(e, name); + if (ev) { + return INT2NUM(upb_EnumValueDef_Number(ev)); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Enum.descriptor + * + * This module method, provided on each generated enum module, returns the + * {EnumDescriptor} corresponding to this enum type. + * + * @return [EnumDescriptor] + * + */ +static VALUE enum_descriptor(VALUE self) { + return rb_ivar_get(self, descriptor_instancevar_interned); +} + +VALUE build_module_from_enumdesc(VALUE _enumdesc) { + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(_enumdesc); + VALUE mod = rb_define_module_id(rb_intern(upb_EnumDef_FullName(e))); + + int n = upb_EnumDef_ValueCount(e); + for (int i = 0; i < n; i++) { + const upb_EnumValueDef* ev = upb_EnumDef_Value(e, i); + upb_Arena* arena = upb_Arena_New(); + const char* src_name = upb_EnumValueDef_Name(ev); + char* name = upb_strdup2(src_name, strlen(src_name), arena); + int32_t value = upb_EnumValueDef_Number(ev); + if (name[0] < 'A' || name[0] > 'Z') { + if (name[0] >= 'a' && name[0] <= 'z') { + name[0] -= 32; // auto capitalize + } else { + rb_warn( + "Enum value '%s' does not start with an uppercase letter " + "as is required for Ruby constants.", + name); + } + } + rb_define_const(mod, name, INT2NUM(value)); + upb_Arena_Free(arena); + } + + rb_define_singleton_method(mod, "lookup", enum_lookup, 1); + rb_define_singleton_method(mod, "resolve", enum_resolve, 1); + rb_define_singleton_method(mod, "descriptor", enum_descriptor, 0); + rb_ivar_set(mod, descriptor_instancevar_interned, _enumdesc); + + return mod; +} + +// Internal to the library; used by Google::Protobuf.deep_copy. +upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, + upb_Arena* arena) { + // Serialize and parse. + upb_Arena* tmp_arena = upb_Arena_New(); + const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); + size_t size; + + upb_Message* new_msg = upb_Message_New(layout, arena); + char* data; + + const upb_FileDef* file = upb_MessageDef_File(m); + const upb_ExtensionRegistry* extreg = + upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file)); + if (upb_Encode(msg, layout, 0, tmp_arena, &data, &size) != + kUpb_EncodeStatus_Ok || + upb_Decode(data, size, new_msg, layout, extreg, 0, arena) != + kUpb_DecodeStatus_Ok) { + upb_Arena_Free(tmp_arena); + rb_raise(cParseError, "Error occurred copying proto"); + } + + upb_Arena_Free(tmp_arena); + return new_msg; +} + +const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, + const char* name, upb_Arena* arena) { + if (value == Qnil) { + rb_raise(cTypeError, "nil message not allowed here."); + } + + VALUE klass = CLASS_OF(value); + VALUE desc_rb = rb_ivar_get(klass, descriptor_instancevar_interned); + const upb_MessageDef* val_m = + desc_rb == Qnil ? NULL : Descriptor_GetMsgDef(desc_rb); + + if (val_m != m) { + // Check for possible implicit conversions + // TODO: hash conversion? + + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Timestamp: { + // Time -> Google::Protobuf::Timestamp + const upb_MiniTable* t = upb_MessageDef_MiniTable(m); + upb_Message* msg = upb_Message_New(t, arena); + upb_MessageValue sec, nsec; + struct timespec time; + const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(m, 2); + + if (!rb_obj_is_kind_of(value, rb_cTime)) goto badtype; + + time = rb_time_timespec(value); + sec.int64_val = time.tv_sec; + nsec.int32_val = time.tv_nsec; + upb_Message_SetFieldByDef(msg, sec_f, sec, arena); + upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena); + return msg; + } + case kUpb_WellKnown_Duration: { + // Numeric -> Google::Protobuf::Duration + const upb_MiniTable* t = upb_MessageDef_MiniTable(m); + upb_Message* msg = upb_Message_New(t, arena); + upb_MessageValue sec, nsec; + const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(m, 2); + + if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype; + + sec.int64_val = NUM2LL(value); + nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000); + upb_Message_SetFieldByDef(msg, sec_f, sec, arena); + upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena); + return msg; + } + default: + badtype: + rb_raise(cTypeError, + "Invalid type %s to assign to submessage field '%s'.", + rb_class2name(CLASS_OF(value)), name); + } + } + + Message* self = ruby_to_Message(value); + Arena_fuse(self->arena, arena); + + return self->msg; +} + +static void Message_define_class(VALUE klass) { + rb_define_alloc_func(klass, Message_alloc); + + rb_require("google/protobuf/message_exts"); + rb_define_method(klass, "method_missing", Message_method_missing, -1); + rb_define_method(klass, "respond_to_missing?", Message_respond_to_missing, + -1); + rb_define_method(klass, "initialize", Message_initialize, -1); + rb_define_method(klass, "dup", Message_dup, 0); + // Also define #clone so that we don't inherit Object#clone. + rb_define_method(klass, "clone", Message_dup, 0); + rb_define_method(klass, "==", Message_eq, 1); + rb_define_method(klass, "eql?", Message_eq, 1); + rb_define_method(klass, "freeze", Message_freeze, 0); + rb_define_method(klass, "frozen?", Message_frozen, 0); + rb_define_method(klass, "hash", Message_hash, 0); + rb_define_method(klass, "to_h", Message_to_h, 0); + rb_define_method(klass, "inspect", Message_inspect, 0); + rb_define_method(klass, "to_s", Message_inspect, 0); + rb_define_method(klass, "[]", Message_index, 1); + rb_define_method(klass, "[]=", Message_index_set, 2); + rb_define_singleton_method(klass, "decode", Message_decode, -1); + rb_define_singleton_method(klass, "encode", Message_encode, -1); + rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1); + rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1); + rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0); +} + +void Message_register(VALUE protobuf) { + cParseError = rb_const_get(protobuf, rb_intern("ParseError")); + cAbstractMessage = + rb_define_class_under(protobuf, "AbstractMessage", rb_cObject); + Message_define_class(cAbstractMessage); + rb_gc_register_address(&cAbstractMessage); + + // Ruby-interned string: "descriptor". We use this identifier to store an + // instance variable on message classes we create in order to link them back + // to their descriptors. + descriptor_instancevar_interned = rb_intern("@descriptor"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.h new file mode 100755 index 0000000..1b37db5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.h @@ -0,0 +1,82 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_MESSAGE_H_ +#define RUBY_PROTOBUF_MESSAGE_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Gets the underlying upb_Message* and upb_MessageDef for the given Ruby +// message wrapper. Requires that |value| is indeed a message object. +const upb_Message* Message_Get(VALUE value, const upb_MessageDef** m); + +// Like Message_Get(), but checks that the object is not frozen and returns a +// mutable pointer. +upb_Message* Message_GetMutable(VALUE value, const upb_MessageDef** m); + +// Returns the Arena object for this message. +VALUE Message_GetArena(VALUE value); + +// Converts |value| into a upb_Message value of the expected upb_MessageDef +// type, raising an error if this is not possible. Used when assigning |value| +// to a field of another message, which means the message must be of a +// particular type. +// +// This will perform automatic conversions in some cases (for example, Time -> +// Google::Protobuf::Timestamp). If any new message is created, it will be +// created on |arena|, and any existing message will have its arena fused with +// |arena|. +const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, + const char* name, upb_Arena* arena); + +// Gets or constructs a Ruby wrapper object for the given message. The wrapper +// object will reference |arena| and ensure that it outlives this object. +VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m, + VALUE arena); + +// Gets the given field from this message. +VALUE Message_getfield(VALUE _self, const upb_FieldDef* f); + +// Implements #inspect for this message, printing the text to |b|. +void Message_PrintMessage(StringBuilder* b, const upb_Message* msg, + const upb_MessageDef* m); + +// Returns a hash value for the given message. +uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed); + +// Returns a deep copy of the given message. +upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, + upb_Arena* arena); + +// Checks that this Ruby object is a message, and raises an exception if not. +void Message_CheckClass(VALUE klass); + +// Returns a new Hash object containing the contents of this message. +VALUE Scalar_CreateHash(upb_MessageValue val, TypeInfo type_info); + +// Creates a message class or enum module for this descriptor, respectively. +VALUE build_class_from_descriptor(VALUE descriptor); +VALUE build_module_from_enumdesc(VALUE _enumdesc); + +// Returns the Descriptor/EnumDescriptor for the given message class or enum +// module, respectively. Returns nil if this is not a message class or enum +// module. +VALUE MessageOrEnum_GetDescriptor(VALUE klass); + +// Decodes a Message from a byte sequence. +VALUE Message_decode_bytes(size_t size, const char* bytes, int options, + VALUE klass, bool freeze); + +// Recursively freeze message +VALUE Message_freeze(VALUE _self); + +// Call at startup to register all types in this module. +void Message_register(VALUE protobuf); + +#endif // RUBY_PROTOBUF_MESSAGE_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.c new file mode 100755 index 0000000..6eea18c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.c @@ -0,0 +1,357 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "protobuf.h" + +#include "defs.h" +#include "map.h" +#include "message.h" +#include "repeated_field.h" + +VALUE cParseError; +VALUE cTypeError; + +const upb_FieldDef *map_field_key(const upb_FieldDef *field) { + const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field); + return upb_MessageDef_FindFieldByNumber(entry, 1); +} + +const upb_FieldDef *map_field_value(const upb_FieldDef *field) { + const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field); + return upb_MessageDef_FindFieldByNumber(entry, 2); +} + +// ----------------------------------------------------------------------------- +// StringBuilder, for inspect +// ----------------------------------------------------------------------------- + +struct StringBuilder { + size_t size; + size_t cap; + char *data; +}; + +typedef struct StringBuilder StringBuilder; + +static size_t StringBuilder_SizeOf(size_t cap) { + return sizeof(StringBuilder) + cap; +} + +StringBuilder *StringBuilder_New() { + const size_t cap = 128; + StringBuilder *builder = malloc(sizeof(*builder)); + builder->size = 0; + builder->cap = cap; + builder->data = malloc(builder->cap); + return builder; +} + +void StringBuilder_Free(StringBuilder *b) { + free(b->data); + free(b); +} + +void StringBuilder_Printf(StringBuilder *b, const char *fmt, ...) { + size_t have = b->cap - b->size; + size_t n; + va_list args; + + va_start(args, fmt); + n = vsnprintf(&b->data[b->size], have, fmt, args); + va_end(args); + + if (have <= n) { + while (have <= n) { + b->cap *= 2; + have = b->cap - b->size; + } + b->data = realloc(b->data, StringBuilder_SizeOf(b->cap)); + va_start(args, fmt); + n = vsnprintf(&b->data[b->size], have, fmt, args); + va_end(args); + PBRUBY_ASSERT(n < have); + } + + b->size += n; +} + +VALUE StringBuilder_ToRubyString(StringBuilder *b) { + VALUE ret = rb_str_new(b->data, b->size); + rb_enc_associate(ret, rb_utf8_encoding()); + return ret; +} + +static void StringBuilder_PrintEnum(StringBuilder *b, int32_t val, + const upb_EnumDef *e) { + const upb_EnumValueDef *ev = upb_EnumDef_FindValueByNumber(e, val); + if (ev) { + StringBuilder_Printf(b, ":%s", upb_EnumValueDef_Name(ev)); + } else { + StringBuilder_Printf(b, "%" PRId32, val); + } +} + +void StringBuilder_PrintMsgval(StringBuilder *b, upb_MessageValue val, + TypeInfo info) { + switch (info.type) { + case kUpb_CType_Bool: + StringBuilder_Printf(b, "%s", val.bool_val ? "true" : "false"); + break; + case kUpb_CType_Float: { + VALUE str = rb_inspect(DBL2NUM(val.float_val)); + StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); + break; + } + case kUpb_CType_Double: { + VALUE str = rb_inspect(DBL2NUM(val.double_val)); + StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); + break; + } + case kUpb_CType_Int32: + StringBuilder_Printf(b, "%" PRId32, val.int32_val); + break; + case kUpb_CType_UInt32: + StringBuilder_Printf(b, "%" PRIu32, val.uint32_val); + break; + case kUpb_CType_Int64: + StringBuilder_Printf(b, "%" PRId64, val.int64_val); + break; + case kUpb_CType_UInt64: + StringBuilder_Printf(b, "%" PRIu64, val.uint64_val); + break; + case kUpb_CType_String: + StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, + val.str_val.data); + break; + case kUpb_CType_Bytes: + StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, + val.str_val.data); + break; + case kUpb_CType_Enum: + StringBuilder_PrintEnum(b, val.int32_val, info.def.enumdef); + break; + case kUpb_CType_Message: + Message_PrintMessage(b, val.msg_val, info.def.msgdef); + break; + } +} + +// ----------------------------------------------------------------------------- +// Arena +// ----------------------------------------------------------------------------- + +typedef struct { + upb_Arena *arena; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE pinned_objs; +} Arena; + +static void Arena_mark(void *data) { + Arena *arena = data; + rb_gc_mark(arena->pinned_objs); +} + +static void Arena_free(void *data) { + Arena *arena = data; + upb_Arena_Free(arena->arena); + xfree(arena); +} + +static size_t Arena_memsize(const void *data) { + const Arena *arena = data; + size_t fused_count; + size_t memsize = upb_Arena_SpaceAllocated(arena->arena, &fused_count); + if (fused_count > 1) { + // If other arena were fused we attribute an equal + // share of memory usage to each one. + memsize /= fused_count; + } + return memsize + sizeof(Arena); +} + +static VALUE cArena; + +const rb_data_type_t Arena_type = { + "Google::Protobuf::Internal::Arena", + {Arena_mark, Arena_free, Arena_memsize}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static void *ruby_upb_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, + size_t size, size_t *actual_size) { + if (size == 0) { + xfree(ptr); + return NULL; + } else { + return xrealloc(ptr, size); + } +} + +upb_alloc ruby_upb_alloc = {&ruby_upb_allocfunc}; + +static VALUE Arena_alloc(VALUE klass) { + Arena *arena = ALLOC(Arena); + arena->arena = upb_Arena_Init(NULL, 0, &ruby_upb_alloc); + arena->pinned_objs = Qnil; + return TypedData_Wrap_Struct(klass, &Arena_type, arena); +} + +upb_Arena *Arena_get(VALUE _arena) { + Arena *arena; + TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); + return arena->arena; +} + +void Arena_fuse(VALUE _arena, upb_Arena *other) { + Arena *arena; + TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); + if (!upb_Arena_Fuse(arena->arena, other)) { + rb_raise(rb_eRuntimeError, + "Unable to fuse arenas. This should never happen since Ruby does " + "not use initial blocks"); + } +} + +VALUE Arena_new() { return Arena_alloc(cArena); } + +void Arena_register(VALUE module) { + VALUE internal = rb_define_module_under(module, "Internal"); + VALUE klass = rb_define_class_under(internal, "Arena", rb_cObject); + rb_define_alloc_func(klass, Arena_alloc); + rb_gc_register_address(&cArena); + cArena = klass; +} + +// ----------------------------------------------------------------------------- +// Object Cache +// ----------------------------------------------------------------------------- + +// Public ObjectCache API. + +VALUE weak_obj_cache = Qnil; +ID item_get; +ID item_try_add; + +static void ObjectCache_Init(VALUE protobuf) { + item_get = rb_intern("get"); + item_try_add = rb_intern("try_add"); + + rb_gc_register_address(&weak_obj_cache); + VALUE internal = rb_const_get(protobuf, rb_intern("Internal")); +#if SIZEOF_LONG >= SIZEOF_VALUE + VALUE cache_class = rb_const_get(internal, rb_intern("ObjectCache")); +#else + VALUE cache_class = rb_const_get(internal, rb_intern("LegacyObjectCache")); +#endif + + weak_obj_cache = rb_class_new_instance(0, NULL, cache_class); + rb_const_set(internal, rb_intern("OBJECT_CACHE"), weak_obj_cache); + rb_const_set(internal, rb_intern("SIZEOF_LONG"), INT2NUM(SIZEOF_LONG)); + rb_const_set(internal, rb_intern("SIZEOF_VALUE"), INT2NUM(SIZEOF_VALUE)); +} + +static VALUE ObjectCache_GetKey(const void *key) { + VALUE key_val = (VALUE)key; + PBRUBY_ASSERT((key_val & 3) == 0); + // Ensure the key can be stored as a Fixnum since 1 bit is needed for + // FIXNUM_FLAG and 1 bit is needed for the sign bit. + VALUE new_key = LL2NUM(key_val >> 2); + PBRUBY_ASSERT(FIXNUM_P(new_key)); + return new_key; +} + +VALUE ObjectCache_TryAdd(const void *key, VALUE val) { + VALUE key_val = ObjectCache_GetKey(key); + return rb_funcall(weak_obj_cache, item_try_add, 2, key_val, val); +} + +// Returns the cached object for this key, if any. Otherwise returns Qnil. +VALUE ObjectCache_Get(const void *key) { + VALUE key_val = ObjectCache_GetKey(key); + return rb_funcall(weak_obj_cache, item_get, 1, key_val); +} + +/* + * call-seq: + * Google::Protobuf.discard_unknown(msg) + * + * Discard unknown fields in the given message object and recursively discard + * unknown fields in submessages. + */ +static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) { + const upb_MessageDef *m; + upb_Message *msg = Message_GetMutable(msg_rb, &m); + const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(m)); + if (!upb_Message_DiscardUnknown(msg, m, ext_pool, 128)) { + rb_raise(rb_eRuntimeError, "Messages nested too deeply."); + } + + return Qnil; +} + +/* + * call-seq: + * Google::Protobuf.deep_copy(obj) => copy_of_obj + * + * Performs a deep copy of a RepeatedField instance, a Map instance, or a + * message object, recursively copying its members. + */ +VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) { + VALUE klass = CLASS_OF(obj); + if (klass == cRepeatedField) { + return RepeatedField_deep_copy(obj); + } else if (klass == cMap) { + return Map_deep_copy(obj); + } else { + VALUE new_arena_rb = Arena_new(); + upb_Arena *new_arena = Arena_get(new_arena_rb); + const upb_MessageDef *m; + const upb_Message *msg = Message_Get(obj, &m); + upb_Message *new_msg = Message_deep_copy(msg, m, new_arena); + return Message_GetRubyWrapper(new_msg, m, new_arena_rb); + } +} + +// ----------------------------------------------------------------------------- +// Initialization/entry point. +// ----------------------------------------------------------------------------- + +// This must be named "Init_protobuf_c" because the Ruby module is named +// "protobuf_c" -- the VM looks for this symbol in our .so. +__attribute__((visibility("default"))) void Init_protobuf_c() { + VALUE google = rb_define_module("Google"); + VALUE protobuf = rb_define_module_under(google, "Protobuf"); + + ObjectCache_Init(protobuf); + Arena_register(protobuf); + Defs_register(protobuf); + RepeatedField_register(protobuf); + Map_register(protobuf); + Message_register(protobuf); + + cParseError = rb_const_get(protobuf, rb_intern("ParseError")); + rb_gc_register_mark_object(cParseError); + cTypeError = rb_const_get(protobuf, rb_intern("TypeError")); + rb_gc_register_mark_object(cTypeError); + + rb_define_singleton_method(protobuf, "discard_unknown", + Google_Protobuf_discard_unknown, 1); + rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy, + 1); +} + +// ----------------------------------------------------------------------------- +// Utilities +// ----------------------------------------------------------------------------- + +// Raises a Ruby error if val is frozen in Ruby or UPB. +void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen) { + if (RB_UNLIKELY(rb_obj_frozen_p(val)||upb_frozen)) { + rb_error_frozen_object(val); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.h new file mode 100755 index 0000000..abb7c89 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.h @@ -0,0 +1,100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ +#define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ + +// Ruby 3+ defines NDEBUG itself, see: https://bugs.ruby-lang.org/issues/18777 +#ifdef NDEBUG +#include +#else +#include +#undef NDEBUG +#endif + +#include // Must be included after the NDEBUG logic above. +#include +#include + +#include "defs.h" +#include "ruby-upb.h" + +// These operate on a map field (i.e., a repeated field of submessages whose +// submessage type is a map-entry msgdef). +const upb_FieldDef* map_field_key(const upb_FieldDef* field); +const upb_FieldDef* map_field_value(const upb_FieldDef* field); + +// ----------------------------------------------------------------------------- +// Arena +// ----------------------------------------------------------------------------- + +// A Ruby object that wraps an underlying upb_Arena. Any objects that are +// allocated from this arena should reference the Arena in rb_gc_mark(), to +// ensure that the object's underlying memory outlives any Ruby object that can +// reach it. + +VALUE Arena_new(); +upb_Arena* Arena_get(VALUE arena); + +// Fuses this arena to another, throwing a Ruby exception if this is not +// possible. +void Arena_fuse(VALUE arena, upb_Arena* other); + +// ----------------------------------------------------------------------------- +// ObjectCache +// ----------------------------------------------------------------------------- + +// Global object cache from upb array/map/message/symtab to wrapper object. +// +// This is a conceptually "weak" cache, in that it does not prevent "val" from +// being collected (though in Ruby <2.7 is it effectively strong, due to +// implementation limitations). + +// Tries to add a new entry to the cache, returning the newly installed value or +// the pre-existing entry. +VALUE ObjectCache_TryAdd(const void* key, VALUE val); + +// Returns the cached object for this key, if any. Otherwise returns Qnil. +VALUE ObjectCache_Get(const void* key); + +// ----------------------------------------------------------------------------- +// StringBuilder, for inspect +// ----------------------------------------------------------------------------- + +struct StringBuilder; +typedef struct StringBuilder StringBuilder; + +StringBuilder* StringBuilder_New(); +void StringBuilder_Free(StringBuilder* b); +void StringBuilder_Printf(StringBuilder* b, const char* fmt, ...); +VALUE StringBuilder_ToRubyString(StringBuilder* b); + +void StringBuilder_PrintMsgval(StringBuilder* b, upb_MessageValue val, + TypeInfo info); + +// ----------------------------------------------------------------------------- +// Utilities. +// ----------------------------------------------------------------------------- + +extern VALUE cTypeError; + +#ifdef NDEBUG +#define PBRUBY_ASSERT(expr) \ + do { \ + } while (false && (expr)) +#else +#define PBRUBY_ASSERT(expr) \ + if (!(expr)) \ + rb_bug("Assertion failed at %s:%d, expr: %s", __FILE__, __LINE__, #expr) +#endif + +// Raises a Ruby error if val is frozen in Ruby or upb_frozen is true. +void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen); + +#define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.c new file mode 100755 index 0000000..ed19346 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.c @@ -0,0 +1,728 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "repeated_field.h" + +#include "convert.h" +#include "defs.h" +#include "message.h" +#include "protobuf.h" + +// ----------------------------------------------------------------------------- +// Repeated field container type. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_Array* array; // Can get as mutable when non-frozen. + TypeInfo type_info; + VALUE type_class; // To GC-root the msgdef/enumdef in type_info. + VALUE arena; // To GC-root the upb_Array. +} RepeatedField; + +VALUE cRepeatedField; + +static void RepeatedField_mark(void* _self) { + RepeatedField* self = (RepeatedField*)_self; + rb_gc_mark(self->type_class); + rb_gc_mark(self->arena); +} + +const rb_data_type_t RepeatedField_type = { + "Google::Protobuf::RepeatedField", + {RepeatedField_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static RepeatedField* ruby_to_RepeatedField(VALUE _self) { + RepeatedField* self; + TypedData_Get_Struct(_self, RepeatedField, &RepeatedField_type, self); + return self; +} + +static upb_Array* RepeatedField_GetMutable(VALUE _self) { + const upb_Array* array = ruby_to_RepeatedField(_self)->array; + Protobuf_CheckNotFrozen(_self, upb_Array_IsFrozen(array)); + return (upb_Array*)array; +} + +VALUE RepeatedField_alloc(VALUE klass) { + RepeatedField* self = ALLOC(RepeatedField); + self->arena = Qnil; + self->type_class = Qnil; + self->array = NULL; + return TypedData_Wrap_Struct(klass, &RepeatedField_type, self); +} + +VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f) { + PBRUBY_ASSERT(upb_FieldDef_IsRepeated(f)); + VALUE val = ObjectCache_Get(f); + + if (val == Qnil) { + val = RepeatedField_alloc(cRepeatedField); + RepeatedField* self; + TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self); + self->arena = Arena_new(); + TypeInfo type_info = TypeInfo_get(f); + self->array = upb_Array_New(Arena_get(self->arena), type_info.type); + self->type_info = type_info; + if (self->type_info.type == kUpb_CType_Message) { + self->type_class = Descriptor_DefToClass(type_info.def.msgdef); + } + val = ObjectCache_TryAdd(f, RepeatedField_freeze(val)); + } + PBRUBY_ASSERT(RB_OBJ_FROZEN(val)); + PBRUBY_ASSERT(upb_Array_IsFrozen(ruby_to_RepeatedField(val)->array)); + return val; +} + +VALUE RepeatedField_GetRubyWrapper(const upb_Array* array, TypeInfo type_info, + VALUE arena) { + PBRUBY_ASSERT(array); + PBRUBY_ASSERT(arena != Qnil); + VALUE val = ObjectCache_Get(array); + + if (val == Qnil) { + val = RepeatedField_alloc(cRepeatedField); + RepeatedField* self; + TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self); + self->array = array; + self->arena = arena; + self->type_info = type_info; + if (self->type_info.type == kUpb_CType_Message) { + self->type_class = Descriptor_DefToClass(type_info.def.msgdef); + } + val = ObjectCache_TryAdd(array, val); + } + + PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type); + PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef == + type_info.def.msgdef); + PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array); + return val; +} + +static VALUE RepeatedField_new_this_type(RepeatedField* from) { + VALUE arena_rb = Arena_new(); + upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type); + VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb); + PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class); + return ret; +} + +void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array, + TypeInfo info) { + bool first = true; + StringBuilder_Printf(b, "["); + size_t n = array ? upb_Array_Size(array) : 0; + for (size_t i = 0; i < n; i++) { + if (first) { + first = false; + } else { + StringBuilder_Printf(b, ", "); + } + StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info); + } + StringBuilder_Printf(b, "]"); +} + +VALUE RepeatedField_deep_copy(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + VALUE new_rptfield = RepeatedField_new_this_type(self); + RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield); + VALUE arena_rb = new_self->arena; + upb_Array* new_array = RepeatedField_GetMutable(new_rptfield); + upb_Arena* arena = Arena_get(arena_rb); + size_t elements = upb_Array_Size(self->array); + + upb_Array_Resize(new_array, elements, arena); + + size_t size = upb_Array_Size(self->array); + for (size_t i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena); + upb_Array_Set(new_array, i, copy); + } + + return new_rptfield; +} + +const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field, + upb_Arena* arena) { + RepeatedField* self; + TypeInfo type_info = TypeInfo_get(field); + + if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || + RTYPEDDATA_TYPE(val) != &RepeatedField_type) { + rb_raise(cTypeError, "Expected repeated field array"); + } + + self = ruby_to_RepeatedField(val); + if (self->type_info.type != type_info.type) { + rb_raise(cTypeError, "Repeated field array has wrong element type"); + } + + if (self->type_info.def.msgdef != type_info.def.msgdef) { + rb_raise(cTypeError, "Repeated field array has wrong message/enum class"); + } + + Arena_fuse(self->arena, arena); + return self->array; +} + +static int index_position(VALUE _index, RepeatedField* repeated_field) { + int index = NUM2INT(_index); + if (index < 0) index += upb_Array_Size(repeated_field->array); + return index; +} + +static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) { + size_t size = upb_Array_Size(self->array); + VALUE ary = rb_ary_new2(size); + long i; + + for (i = beg; i < beg + len; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena); + rb_ary_push(ary, elem); + } + return ary; +} + +/** + * ruby-doc: RepeatedField + * + */ + +/* + * ruby-doc: RepeatedField#each + * + * Invokes the block once for each element of the repeated field. RepeatedField + * also includes Enumerable; combined with this method, the repeated field thus + * acts like an ordinary Ruby sequence. + * + * @yield [Object] + * @return [self] + */ +static VALUE RepeatedField_each(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + int size = upb_Array_Size(self->array); + int i; + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); + rb_yield(val); + } + return _self; +} + +/* + * ruby-doc: RepeatedField#[] + * + * Accesses the element at the given index. Returns nil on out-of-bounds + * + * @param index [Integer] + * @return [Object,nil] + */ +static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + long size = upb_Array_Size(self->array); + + VALUE arg = argv[0]; + long beg, len; + + if (argc == 1) { + if (FIXNUM_P(arg)) { + /* standard case */ + upb_MessageValue msgval; + int index = index_position(argv[0], self); + if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) { + return Qnil; + } + msgval = upb_Array_Get(self->array, index); + return Convert_UpbToRuby(msgval, self->type_info, self->arena); + } else { + /* check if idx is Range */ + switch (rb_range_beg_len(arg, &beg, &len, size, 0)) { + case Qfalse: + break; + case Qnil: + return Qnil; + default: + return RepeatedField_subarray(self, beg, len); + } + } + } + + /* assume 2 arguments */ + beg = NUM2LONG(argv[0]); + len = NUM2LONG(argv[1]); + if (beg < 0) { + beg += size; + } + if (beg >= size) { + return Qnil; + } + return RepeatedField_subarray(self, beg, len); +} + +/* + * ruby-doc: RepeatedField#[]= + * + * Sets the element at the given index. On out-of-bounds assignments, extends + * the array and fills the hole (if any) with default values. + * + * @param index [Integer] + * @param value [Object + * @return [nil] + */ +static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { + RepeatedField* self = ruby_to_RepeatedField(_self); + int size = upb_Array_Size(self->array); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena); + + int index = index_position(_index, self); + if (index < 0 || index >= (INT_MAX - 1)) { + return Qnil; + } + + if (index >= size) { + upb_Array_Resize(array, index + 1, arena); + upb_MessageValue fill; + memset(&fill, 0, sizeof(fill)); + for (int i = size; i < index; i++) { + // Fill default values. + // TODO: should this happen at the upb level? + upb_Array_Set(array, i, fill); + } + } + + upb_Array_Set(array, index, msgval); + return Qnil; +} + +/* + * ruby-doc: RepeatedField#push + * + * Adds a new element to the repeated field. + * + * @param value [Object] + * @return [self] + */ +static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_Array* array = RepeatedField_GetMutable(_self); + int i; + + for (i = 0; i < argc; i++) { + upb_MessageValue msgval = + Convert_RubyToUpb(argv[i], "", self->type_info, arena); + upb_Array_Append(array, msgval, arena); + } + + return _self; +} + +/* + * ruby-doc: RepeatedField#<< + * + * Adds a new element to the repeated field. + * + * @param value [Object] + * @return [self] + */ +static VALUE RepeatedField_push(VALUE _self, VALUE val) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_Array* array = RepeatedField_GetMutable(_self); + + upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena); + upb_Array_Append(array, msgval, arena); + + return _self; +} + +/* + * Private ruby method, used by RepeatedField.pop + */ +static VALUE RepeatedField_pop_one(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + size_t size = upb_Array_Size(self->array); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_MessageValue last; + VALUE ret; + + if (size == 0) { + return Qnil; + } + + last = upb_Array_Get(self->array, size - 1); + ret = Convert_UpbToRuby(last, self->type_info, self->arena); + + upb_Array_Resize(array, size - 1, Arena_get(self->arena)); + return ret; +} + +/* + * ruby-doc: RepeatedField#replace + * + * Replaces the contents of the repeated field with the given list of elements. + * + * @param list [Array] + * @return [Array] + */ +static VALUE RepeatedField_replace(VALUE _self, VALUE list) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Array* array = RepeatedField_GetMutable(_self); + int i; + + Check_Type(list, T_ARRAY); + upb_Array_Resize(array, 0, Arena_get(self->arena)); + + for (i = 0; i < RARRAY_LEN(list); i++) { + RepeatedField_push(_self, rb_ary_entry(list, i)); + } + + return list; +} + +/* + * ruby-doc: RepeatedField#clear + * + * Clears (removes all elements from) this repeated field. + * + * @return [self] + */ +static VALUE RepeatedField_clear(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_Array_Resize(array, 0, Arena_get(self->arena)); + return _self; +} + +/* + * ruby-doc: RepeatedField#length + * + * Returns the length of this repeated field. + * + * @return [Integer] + */ +static VALUE RepeatedField_length(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + return INT2NUM(upb_Array_Size(self->array)); +} + +/* + * ruby-doc: RepeatedField#dup + * + * Duplicates this repeated field with a shallow copy. References to all + * non-primitive element objects (e.g., submessages) are shared. + * + * @return [RepeatedField] + */ +static VALUE RepeatedField_dup(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + VALUE new_rptfield = RepeatedField_new_this_type(self); + RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield); + upb_Array* new_array = RepeatedField_GetMutable(new_rptfield); + upb_Arena* arena = Arena_get(new_rptfield_self->arena); + int size = upb_Array_Size(self->array); + int i; + + Arena_fuse(self->arena, arena); + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + upb_Array_Append(new_array, msgval, arena); + } + + return new_rptfield; +} + +/* + * ruby-doc: RepeatedField#to_ary + * + * Used when converted implicitly into array, e.g. compared to an Array. + * Also called as a fallback of Object#to_a + * + * @return [Array] + */ +VALUE RepeatedField_to_ary(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + int size = upb_Array_Size(self->array); + VALUE ary = rb_ary_new2(size); + int i; + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); + rb_ary_push(ary, val); + } + + return ary; +} + +/* + * ruby-doc: RepeatedField#== + * + * Compares this repeated field to another. Repeated fields are equal if their + * element types are equal, their lengths are equal, and each element is equal. + * Elements are compared as per normal Ruby semantics, by calling their :== + * methods (or performing a more efficient comparison for primitive types). + * + * Repeated fields with dissimilar element types are never equal, even if value + * comparison (for example, between integers and floats) would have otherwise + * indicated that every element has equal value. + * + * @param other [RepeatedField] + * @return [Boolean] + */ +VALUE RepeatedField_eq(VALUE _self, VALUE _other) { + RepeatedField* self; + RepeatedField* other; + + if (_self == _other) { + return Qtrue; + } + + if (TYPE(_other) == T_ARRAY) { + VALUE self_ary = RepeatedField_to_ary(_self); + return rb_equal(self_ary, _other); + } + + self = ruby_to_RepeatedField(_self); + other = ruby_to_RepeatedField(_other); + size_t n = upb_Array_Size(self->array); + + if (self->type_info.type != other->type_info.type || + self->type_class != other->type_class || + upb_Array_Size(other->array) != n) { + return Qfalse; + } + + for (size_t i = 0; i < n; i++) { + upb_MessageValue val1 = upb_Array_Get(self->array, i); + upb_MessageValue val2 = upb_Array_Get(other->array, i); + if (!Msgval_IsEqual(val1, val2, self->type_info)) { + return Qfalse; + } + } + + return Qtrue; +} + +/* + * ruby-doc: RepeatedField#frozen? + * + * Returns true if the repeated field is frozen in either Ruby or the underlying + * representation. Freezes the Ruby repeated field object if it is not already + * frozen in Ruby but it is frozen in the underlying representation. + * + * @return [Boolean] + */ +VALUE RepeatedField_frozen(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + if (!upb_Array_IsFrozen(self->array)) { + PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self)); + return Qfalse; + } + + // Lazily freeze the Ruby wrapper. + if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self); + return Qtrue; +} + +/* + * ruby-doc: RepeatedField#freeze + * + * Freezes the repeated field object. We have to intercept this so we can freeze + * the underlying representation, not just the Ruby wrapper. + * + * @return [self] + */ +VALUE RepeatedField_freeze(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + if (RB_OBJ_FROZEN(_self)) { + PBRUBY_ASSERT(upb_Array_IsFrozen(self->array)); + return _self; + } + + if (!upb_Array_IsFrozen(self->array)) { + if (self->type_info.type == kUpb_CType_Message) { + upb_Array_Freeze(RepeatedField_GetMutable(_self), + upb_MessageDef_MiniTable(self->type_info.def.msgdef)); + } else { + upb_Array_Freeze(RepeatedField_GetMutable(_self), NULL); + } + } + RB_OBJ_FREEZE(_self); + return _self; +} + +/* + * ruby-doc: RepeatedField#hash + * + * Returns a hash value computed from this repeated field's elements. + * + * @return [Integer] + */ +VALUE RepeatedField_hash(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + uint64_t hash = 0; + size_t n = upb_Array_Size(self->array); + + for (size_t i = 0; i < n; i++) { + upb_MessageValue val = upb_Array_Get(self->array, i); + hash = Msgval_GetHash(val, self->type_info, hash); + } + + return LL2NUM(hash); +} + +/* + * ruby-doc: RepeatedField#+ + * + * Returns a new repeated field that contains the concatenated list of this + * repeated field's elements and other's elements. The other (second) list may + * be either another repeated field or a Ruby array. + * + * @param other [Array,RepeatedField] + * @return [RepeatedField] + */ +VALUE RepeatedField_plus(VALUE _self, VALUE list) { + VALUE dupped_ = RepeatedField_dup(_self); + + if (TYPE(list) == T_ARRAY) { + int i; + for (i = 0; i < RARRAY_LEN(list); i++) { + VALUE elem = rb_ary_entry(list, i); + RepeatedField_push(dupped_, elem); + } + } else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) && + RTYPEDDATA_TYPE(list) == &RepeatedField_type) { + RepeatedField* self = ruby_to_RepeatedField(_self); + RepeatedField* list_rptfield = ruby_to_RepeatedField(list); + RepeatedField* dupped = ruby_to_RepeatedField(dupped_); + upb_Array* dupped_array = RepeatedField_GetMutable(dupped_); + upb_Arena* arena = Arena_get(dupped->arena); + Arena_fuse(list_rptfield->arena, arena); + int size = upb_Array_Size(list_rptfield->array); + int i; + + if (self->type_info.type != list_rptfield->type_info.type || + self->type_class != list_rptfield->type_class) { + rb_raise(rb_eArgError, + "Attempt to append RepeatedField with different element type."); + } + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i); + upb_Array_Append(dupped_array, msgval, arena); + } + } else { + rb_raise(rb_eArgError, "Unknown type appending to RepeatedField"); + } + + return dupped_; +} + +/* + * ruby-doc: RepeatedField#concat + * + * concats the passed in array to self. Returns a Ruby array. + * + * @param other [RepeatedField] + * @return [Array] + */ +VALUE RepeatedField_concat(VALUE _self, VALUE list) { + int i; + + Check_Type(list, T_ARRAY); + for (i = 0; i < RARRAY_LEN(list); i++) { + RepeatedField_push(_self, rb_ary_entry(list, i)); + } + return _self; +} + +/* + * ruby-doc: RepeatedField#initialize + * + * Creates a new repeated field. The provided type must be a Ruby symbol, and + * can take on the same values as those accepted by {FieldDescriptor#type=}. If + * the type is :message or :enum, type_class must be non-nil, and must be the + * Ruby class or module returned by {Descriptor#msgclass} or + * {EnumDescriptor#enummodule}, respectively. An initial list of elements may + * also be provided. + * + * @param type [Symbol] + * @param type_class [Class, Module] + * @paramdefault type_class nil + * @param initial_elems [Array] + * @paramdefault initial_elems [] + * @return [RepeatedField] + */ +VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Arena* arena; + VALUE ary = Qnil; + + self->arena = Arena_new(); + arena = Arena_get(self->arena); + + if (argc < 1) { + rb_raise(rb_eArgError, "Expected at least 1 argument."); + } + + self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary); + self->array = upb_Array_New(arena, self->type_info.type); + VALUE stored_val = ObjectCache_TryAdd(self->array, _self); + PBRUBY_ASSERT(stored_val == _self); + + if (ary != Qnil) { + if (!RB_TYPE_P(ary, T_ARRAY)) { + rb_raise(rb_eArgError, "Expected array as initialize argument"); + } + for (int i = 0; i < RARRAY_LEN(ary); i++) { + RepeatedField_push(_self, rb_ary_entry(ary, i)); + } + } + return Qnil; +} + +void RepeatedField_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject); + rb_define_alloc_func(klass, RepeatedField_alloc); + rb_gc_register_address(&cRepeatedField); + cRepeatedField = klass; + + rb_define_method(klass, "initialize", RepeatedField_init, -1); + rb_define_method(klass, "each", RepeatedField_each, 0); + rb_define_method(klass, "[]", RepeatedField_index, -1); + rb_define_method(klass, "at", RepeatedField_index, -1); + rb_define_method(klass, "[]=", RepeatedField_index_set, 2); + rb_define_method(klass, "push", RepeatedField_push_vararg, -1); + rb_define_method(klass, "<<", RepeatedField_push, 1); + rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0); + rb_define_method(klass, "replace", RepeatedField_replace, 1); + rb_define_method(klass, "clear", RepeatedField_clear, 0); + rb_define_method(klass, "length", RepeatedField_length, 0); + rb_define_method(klass, "size", RepeatedField_length, 0); + rb_define_method(klass, "dup", RepeatedField_dup, 0); + // Also define #clone so that we don't inherit Object#clone. + rb_define_method(klass, "clone", RepeatedField_dup, 0); + rb_define_method(klass, "==", RepeatedField_eq, 1); + rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0); + rb_define_method(klass, "freeze", RepeatedField_freeze, 0); + rb_define_method(klass, "frozen?", RepeatedField_frozen, 0); + rb_define_method(klass, "hash", RepeatedField_hash, 0); + rb_define_method(klass, "+", RepeatedField_plus, 1); + rb_define_method(klass, "concat", RepeatedField_concat, 1); + rb_include_module(klass, rb_mEnumerable); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.h new file mode 100755 index 0000000..1ae31cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.h @@ -0,0 +1,45 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_REPEATED_FIELD_H_ +#define RUBY_PROTOBUF_REPEATED_FIELD_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Returns a frozen sentinel Ruby wrapper object for an empty upb_Array of the +// type specified by the field. Creates one if it doesn't exist. +VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f); + +// Returns a Ruby wrapper object for the given upb_Array, which will be created +// if one does not exist already. +VALUE RepeatedField_GetRubyWrapper(const upb_Array* msg, TypeInfo type_info, + VALUE arena); + +// Gets the underlying upb_Array for this Ruby RepeatedField object, which must +// have a type that matches |f|. If this is not a repeated field or the type +// doesn't match, raises an exception. +const upb_Array* RepeatedField_GetUpbArray(VALUE value, const upb_FieldDef* f, + upb_Arena* arena); + +// Implements #inspect for this repeated field by appending its contents to |b|. +void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array, + TypeInfo info); + +// Returns a deep copy of this RepeatedField object. +VALUE RepeatedField_deep_copy(VALUE obj); + +// Ruby class of Google::Protobuf::RepeatedField. +extern VALUE cRepeatedField; + +// Call at startup to register all types in this module. +void RepeatedField_register(VALUE module); + +// Recursively freeze RepeatedField. +VALUE RepeatedField_freeze(VALUE _self); + +#endif // RUBY_PROTOBUF_REPEATED_FIELD_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.c new file mode 100755 index 0000000..841c0f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.c @@ -0,0 +1,18154 @@ +/* Amalgamated source file */ +#include "ruby-upb.h" + +/* + * This is where we define internal portability macros used across upb. + * + * All of these macros are undef'd in undef.inc to avoid leaking them to users. + * + * The correct usage is: + * + * #include "upb/foobar.h" + * #include "upb/baz.h" + * + * // MUST be last included header. + * #include "upb/port/def.inc" + * + * // Code for this file. + * // <...> + * + * // Can be omitted for .c files, required for .h. + * #include "upb/port/undef.inc" + * + * This file is private and must not be included by users! + */ + +#if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(_MSC_VER) && _MSC_VER >= 1900)) +#error upb requires C99 or C++17 or MSVC >= 2015. +#endif + +// Portable check for GCC minimum version: +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +#define UPB_GNUC_MIN(x, y) \ + (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +#else +#define UPB_GNUC_MIN(x, y) 0 +#endif + +// Macros for checking for compiler attributes, defined here to avoid the +// problem described in +// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. +#ifdef __has_attribute +#define UPB_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define UPB_HAS_ATTRIBUTE(x) 0 +#endif + +#if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define UPB_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define UPB_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +// Once in a while we want to use this macro in a C++-only portion of an +// otherwise C-compatible header, so we copy and paste this from ABSL. +#if UPB_HAS_CPP_ATTRIBUTE(deprecated) && UPB_HAS_CPP_ATTRIBUTE(clang::annotate) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated, clang::annotate("inline-me")]] +#elif UPB_HAS_CPP_ATTRIBUTE(deprecated) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated]] +#else +#define UPB_DEPRECATE_AND_INLINE() +#endif + +#ifdef __has_builtin +#define UPB_HAS_BUILTIN(x) __has_builtin(x) +#else +#define UPB_HAS_BUILTIN(x) 0 +#endif + +#ifdef __has_extension +#define UPB_HAS_EXTENSION(x) __has_extension(x) +#else +#define UPB_HAS_EXTENSION(x) 0 +#endif + +#ifdef __has_feature +#define UPB_HAS_FEATURE(x) __has_feature(x) +#else +#define UPB_HAS_FEATURE(x) 0 +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef UINTPTR_MAX +Error, UINTPTR_MAX is undefined +#endif + +#if UINTPTR_MAX == 0xffffffff +#define UPB_SIZE(size32, size64) size32 +#else +#define UPB_SIZE(size32, size64) size64 +#endif + +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) + +// A flexible array member may have lower alignment requirements than the struct +// overall - in that case, it can overlap with the trailing padding of the rest +// of the struct, and a naive sizeof(base) + sizeof(flex) * count calculation +// will not take into account that overlap, and allocate more than is required. +#define UPB_SIZEOF_FLEX(type, member, count) \ + UPB_MAX(sizeof(type), offsetof(type, member[count])) + +#define UPB_SIZEOF_FLEX_WOULD_OVERFLOW(type, member, count) \ + (((SIZE_MAX - offsetof(type, member[0])) / \ + (offsetof(type, member[1]) - offsetof(type, member[0]))) < (size_t)count) + +#define UPB_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +#define UPB_MAPTYPE_STRING 0 + +// UPB_EXPORT: always generate a public symbol. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_EXPORT __attribute__((visibility("default"))) __attribute__((used)) +#else +#define UPB_EXPORT +#endif + +// UPB_INLINE: inline if possible, emit standalone code if required. +#ifdef __cplusplus +#define UPB_INLINE inline +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_INLINE static __inline__ +#else +#define UPB_INLINE static +#endif + +// UPB_INLINE_IF_NOT_GCC: because gcc can be very noisy at times. +#if defined(__GNUC__) && !defined(__clang__) +#define UPB_INLINE_IF_NOT_GCC static +#else +#define UPB_INLINE_IF_NOT_GCC UPB_INLINE +#endif + +#ifdef UPB_BUILD_API +#define UPB_API UPB_EXPORT +#define UPB_API_INLINE UPB_EXPORT +#else +#define UPB_API +#define UPB_API_INLINE UPB_INLINE +#endif + +#ifdef EXPORT_UPBC +#define UPBC_API UPB_EXPORT +#else +#define UPBC_API +#endif + +#if UPB_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#else +#define UPB_ASAN 0 +#endif + +#if UPB_HAS_FEATURE(hwaddress_sanitizer) +#define UPB_HWASAN 1 +#define UPB_HWASAN_POISON_TAG 17 +#define UPB_MALLOC_ALIGN 16 +#else +#define UPB_HWASAN 0 +#define UPB_MALLOC_ALIGN 8 +#endif + +#if UPB_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) +#define UPB_TSAN 1 +#else +#define UPB_TSAN 0 +#endif + +#if UPB_HAS_FEATURE(memory_sanitizer) +#define UPB_MSAN 1 +#else +#define UPB_MSAN 0 +#endif + +// An unfortunate concession to C++17 and MSVC, which don't support zero-sized +// structs. +#if UPB_ASAN || UPB_HWASAN || UPB_TSAN +#define UPB_XSAN_MEMBER upb_Xsan xsan; +#define UPB_XSAN(st) (&(st)->xsan) +#define UPB_XSAN_STRUCT_SIZE 1 +#else +#define UPB_XSAN_MEMBER +#define UPB_XSAN(st) (NULL) +#define UPB_XSAN_STRUCT_SIZE 0 +#endif + +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, UPB_MALLOC_ALIGN) + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_alignof) || \ + defined(__cplusplus) +#define UPB_ALIGN_OF(type) alignof(type) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_alignof) +#define UPB_ALIGN_OF(type) _Alignof(type) +#elif UPB_GNUC_MIN(2, 95) +#define UPB_ALIGN_OF(type) __alignof__(type) +#elif defined(_MSC_VER) +#define UPB_ALIGN_OF(type) __alignof(type) +#else +#define UPB_ALIGN_OF(type) \ + offsetof( \ + struct { \ + char c; \ + type member; \ + }, \ + member) +#endif + +#ifdef _MSC_VER +// Some versions of our Windows compiler don't support the C11 syntax. +#define UPB_ALIGN_AS(x) __declspec(align(x)) +#elif defined(__GNUC__) +#define UPB_ALIGN_AS(x) __attribute__((aligned(x))) +#else +#define UPB_ALIGN_AS(x) _Alignas(x) +#endif + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_static_assert) || \ + defined(__cplusplus) +#define UPB_STATIC_ASSERT(val, msg) static_assert((val), msg) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_static_assert) || \ + UPB_GNUC_MIN(4, 6) +#define UPB_STATIC_ASSERT(val, msg) _Static_assert((val), msg) +#else +// Unfortunately this hack doesn't work inside struct declarations, but it works +// everywhere else +#define UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) s1##s2 +#define UPB_STATIC_ASSERT_CONCAT(s1, s2) UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) +#ifdef __COUNTER__ +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __COUNTER__)[(condition) ? 1 : -1] +#else +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __LINE__)[(condition) ? 1 : -1] +#endif +#endif + +// Hints to the compiler about likely/unlikely branches. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_LIKELY(x) __builtin_expect((bool)(x), 1) +#define UPB_UNLIKELY(x) __builtin_expect((bool)(x), 0) +#else +#define UPB_LIKELY(x) (x) +#define UPB_UNLIKELY(x) (x) +#endif + +#if UPB_HAS_BUILTIN(__builtin_expect_with_probability) +#define UPB_UNPREDICTABLE(x) \ + __builtin_expect_with_probability((bool)(x), 1, 0.5) +#else +#define UPB_UNPREDICTABLE(x) (x) +#endif + +// Macros for function attributes on compilers that support them. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) static +#define UPB_NOINLINE __attribute__((noinline)) +#define UPB_NORETURN __attribute__((__noreturn__)) +#define UPB_PRINTF(str, first_vararg) \ + __attribute__((format(printf, str, first_vararg))) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE static +#define UPB_NORETURN __declspec(noreturn) +#define UPB_PRINTF(str, first_vararg) +#else /* !defined(__GNUC__) */ +#define UPB_FORCEINLINE static +#define UPB_NOINLINE +#define UPB_NORETURN +#define UPB_PRINTF(str, first_vararg) +#endif + +#if defined(__clang__) +#define UPB_NODEREF __attribute__((noderef)) +#else +#define UPB_NODEREF +#endif + +#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define UPB_UNUSED(var) (void)(var) + +// UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) \ + if (!(expr)) __builtin_unreachable() +#elif defined _MSC_VER +#define UPB_ASSUME(expr) \ + if (!(expr)) __assume(0) +#else +#define UPB_ASSUME(expr) \ + do { \ + } while (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + +#if UPB_HAS_BUILTIN(__builtin_constant_p) && UPB_HAS_ATTRIBUTE(const) +#define UPB_MAYBE_ASSUME(pred, x) \ + if (__builtin_constant_p(pred) && pred) UPB_ASSUME(x) +#define UPB_ATTR_CONST __attribute__((const)) +#else +#define UPB_MAYBE_ASSUME(pred, x) +#define UPB_ATTR_CONST +#endif + +/* UPB_ASSERT(): in release mode, we use the expression without letting it be + * evaluated. This prevents "unused variable" warnings. */ +#ifdef NDEBUG +#define UPB_ASSERT(expr) \ + do { \ + } while (false && (expr)) +#else +#define UPB_ASSERT(expr) assert(expr) +#endif + +#if !defined(NDEBUG) && !defined(UPB_TSAN) +#define UPB_ENABLE_REF_CYCLE_CHECKS 1 +#else +#define UPB_ENABLE_REF_CYCLE_CHECKS 0 +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __builtin_unreachable(); \ + } while (0) +#elif defined(_MSC_VER) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __assume(0); \ + } while (0) +#else +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + } while (0) +#endif + +#ifdef __ANDROID__ +#define UPB_DEFAULT_MAX_BLOCK_SIZE 8192 +#else +#define UPB_DEFAULT_MAX_BLOCK_SIZE 32768 +#endif + +/* UPB_SETJMP() / UPB_LONGJMP() */ +// Android uses a custom libc that does not implement all of posix, but it has +// had sigsetjmp/siglongjmp forever on arm and since API 12 on x86. Apple has +// sigsetjmp, but does not define the posix feature test macro. +#if defined(__APPLE__) || defined(_POSIX_C_SOURCE) || defined(__ANDROID__) +// avoid setting/restoring signal mask, which involves costly syscalls +#define UPB_SETJMP(buf) sigsetjmp(buf, 0) +#define UPB_LONGJMP(buf, val) siglongjmp(buf, val) +#elif defined(WASM_WAMR) +#define UPB_SETJMP(buf) 0 +#define UPB_LONGJMP(buf, val) abort() +#else +#define UPB_SETJMP(buf) setjmp(buf) +#define UPB_LONGJMP(buf, val) longjmp(buf, val) +#endif + +#if ((__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)) || \ + UPB_HAS_EXTENSION(c_atomic) || \ + defined(__GNUC__) // GCC supported atomics as an extension before it + // supported __has_extension +#define UPB_USE_C11_ATOMICS +#elif defined(_MSC_VER) +#define UPB_USE_MSC_ATOMICS +#endif + +#if defined(UPB_USE_C11_ATOMICS) +#define UPB_ATOMIC(T) _Atomic(T) +#elif defined(UPB_USE_MSC_ATOMICS) +#define UPB_ATOMIC(T) volatile T +#else +#define UPB_ATOMIC(T) T +#endif + +/* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */ +#define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr)) + +#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only + +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + +/* Configure whether fasttable is switched on or not. *************************/ + +#if UPB_HAS_ATTRIBUTE(musttail) +#define UPB_MUSTTAIL __attribute__((musttail)) +#else +#define UPB_MUSTTAIL +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_most) && !defined(__i386__) +#define UPB_PRESERVE_MOST __attribute__((preserve_most)) +#else +#define UPB_PRESERVE_MOST +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_none) +#define UPB_PRESERVE_NONE __attribute__((preserve_none)) +#else +#define UPB_PRESERVE_NONE +#endif + +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +#define UPB_ARM64_ASM 1 +#else +#define UPB_ARM64_ASM 0 +#endif + +/* When compiling with branch protection, we need to ensure that all branch + * targets in assembly use the appropriate landing pad instruction. These + * instructions are backwards compatible with processors that don't have + * FEAT_BTI and are treated as nops. + */ +#if UPB_ARM64_ASM && defined(__ARM_FEATURE_BTI_DEFAULT) +#if __ARM_FEATURE_BTI_DEFAULT == 1 +#define UPB_ARM64_BTI_DEFAULT 1 +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif + +/* This check is not fully robust: it does not require that we have "musttail" + * support available. We need tail calls to avoid consuming arbitrary amounts + * of stack space. + * + * GCC/Clang can mostly be trusted to generate tail calls as long as + * optimization is enabled, but, debug builds will not generate tail calls + * unless "musttail" is available. + * + * We should probably either: + * 1. require that the compiler supports musttail. + * 2. add some fallback code for when musttail isn't available (ie. return + * instead of tail calling). This is safe and portable, but this comes at + * a CPU cost. + */ +#if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__) +#define UPB_FASTTABLE_SUPPORTED 1 +#else +#define UPB_FASTTABLE_SUPPORTED 0 +#endif + +/* define UPB_ENABLE_FASTTABLE to force fast table support. + * This is useful when we want to ensure we are really getting fasttable, + * for example for testing or benchmarking. */ +#if defined(UPB_ENABLE_FASTTABLE) +#if !UPB_FASTTABLE_SUPPORTED +#error fasttable is x86-64/ARM64 only and requires GCC or Clang. +#endif +#define UPB_FASTTABLE 1 +/* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible. + * This is useful for releasing code that might be used on multiple platforms, + * for example the PHP or Ruby C extensions. */ +#elif defined(UPB_TRY_ENABLE_FASTTABLE) +#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#else +#define UPB_FASTTABLE 0 +#endif + +/* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully + * degrade to non-fasttable if the runtime or platform do not support it. */ +#if !UPB_FASTTABLE +#define UPB_FASTTABLE_INIT(...) +#define UPB_FASTTABLE_MASK(mask) -1 +#else +#define UPB_FASTTABLE_INIT(...) __VA_ARGS__ +#define UPB_FASTTABLE_MASK(mask) mask +#endif + +#undef UPB_FASTTABLE_SUPPORTED + +#if defined(__cplusplus) +#if defined(__clang__) || UPB_GNUC_MIN(6, 0) +// https://gcc.gnu.org/gcc-6/changes.html +#define UPB_DEPRECATED [[deprecated]] +#else +#define UPB_DEPRECATED +#endif +#else +#define UPB_DEPRECATED +#endif + +#if defined(UPB_IS_GOOGLE3) && \ + (!defined(UPB_BOOTSTRAP_STAGE) || UPB_BOOTSTRAP_STAGE != 0) +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_IS_GOOGLE3) && defined(UPB_BOOTSTRAP_STAGE) && \ + UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) proto2__##sym##_msg_init() +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() +#else +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init +#endif + +#undef UPB_IS_GOOGLE3 + +#ifdef __clang__ +#define UPB_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address"))) +#else +#define UPB_NO_SANITIZE_ADDRESS +#endif + +#if defined(__GNUC__) && (defined(__clang__) || UPB_GNUC_MIN(11, 0)) +#define UPB_RETAIN __attribute__((retain)) +#else +#define UPB_RETAIN +#endif + +// Linker arrays combine elements from multiple translation units into a single +// array that can be iterated over at runtime. +// +// It is an alternative to pre-main "registration" functions. +// +// Usage: +// +// // In N translation units. +// UPB_LINKARR_APPEND(foo_array) static int elems[3] = {1, 2, 3}; +// +// // At runtime: +// UPB_LINKARR_DECLARE(foo_array, int); +// +// void f() { +// const int* start = UPB_LINKARR_START(foo_array); +// const int* stop = UPB_LINKARR_STOP(foo_array); +// for (const int* p = start; p < stop; p++) { +// // Windows can introduce zero padding, so we have to skip zeroes. +// if (*p != 0) { +// vec.push_back(*p); +// } +// } +// } + +#if defined(__GNUC__) && !defined(__clang__) +// GCC can't handle mismatched retain attributes in the same section: +// https://github.com/protocolbuffers/protobuf/issues/26385 +// To work around this, we retain all linker array elements, even though this +// effectively disables tree-shaking of unused extensions when using GCC. +#define UPB_LINKARR_ATTR UPB_RETAIN +#else +#define UPB_LINKARR_ATTR +#endif + +#define UPB_LINKARR_SENTINEL UPB_RETAIN __attribute__((weak, used)) + +#if defined(__ELF__) || defined(__wasm__) + +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(__MACH__) + +/* As described in: https://stackoverflow.com/a/22366882 */ +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(_MSC_VER) + +/* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ +#define UPB_STRINGIFY_INTERNAL(x) #x +#define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) +#define UPB_CONCAT(a, b, c) a##b##c +#define UPB_LINKARR_NAME(name, index) \ + UPB_STRINGIFY(UPB_CONCAT(la_, name, index)) +#define UPB_LINKARR_APPEND(name) \ + __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $j))) +// clang-format off +#define UPB_LINKARR_DECLARE(name, type) \ + __pragma(message(UPB_LINKARR_NAME(name, $j))) \ + __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ + __pragma(section(UPB_LINKARR_NAME(name, $z), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $a)), selectany) \ + type __start_linkarr_##name; \ + __declspec(allocate(UPB_LINKARR_NAME(name, $z)), selectany) \ + type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} +// clang-format on +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#else + +// Linker arrays are not supported on this platform. Make macros no-ops. +#define UPB_LINKARR_APPEND(name) +#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_START(name) (NULL) +#define UPB_LINKARR_STOP(name) (NULL) + +#endif + +// Workaround for https://github.com/llvm/llvm-project/issues/167577 until it's +// fixed. Some function must exist for the constructor to work properly. +// TODO Remove this or gate it on a future version of clang. +#if defined(__clang__) && defined(__arm__) +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((used, visibility("hidden"))) void UPB_PRIVATE(unique_name)( \ + void) {} +#else +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) +#endif + +#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) +#define UPB_CONSTRUCTOR(name, unique_name) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ + name)(void) +#elif defined(_MSC_VER) +/* + * See: https://stackoverflow.com/questions/1113409 + * + * The /include pragma suggested in the link above doesn't work in our case + * because it requires globally unique names. We need a different solution + * to prevent optimizers from removing the constructor. Our solution is to + * create a dummy exported weak symbol that prevent this stripping. + */ +#pragma section(".CRT$XCT", read) +#define UPB_CONSTRUCTOR(name, unique_name) \ + static void __cdecl UPB_PRIVATE(name)(void); \ + __declspec(allocate(".CRT$XCT"), selectany) void( \ + __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ + __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ + &UPB_PRIVATE(name##_); \ + static void __cdecl UPB_PRIVATE(name)(void) + +#else +// No constructor support, nothing we can do except not break builds. +#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#endif + +// +// Weak alias platform support. Theoretically this should be possible to do with +// only C using attributes like __attribute__((weak, alias("foo"))), but +// Clang doesn't support this properly on macOS. So we have to use assembly. +#if defined(__APPLE__) + +// TODO: once https://github.com/llvm/llvm-project/issues/167262 is fixed +// in the LLVM linker, we should have all weak variables point to a single +// "default" empty MiniTable instead of having each leaf define its own, like +// we do with ELF below. This will reduce binary size if many messages are tree +// shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) \ + __attribute__((weak)) const upb_MiniTable name = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to; \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); \ + __asm__(".weak_definition _" #to); +#define UPB_STRONG_ALIAS(type, from, to) \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); + +#elif defined(__ELF__) + +// On ELF, weak aliases work properly, so we can have all weak MiniTables point +// to the same empty singleton MiniTable. This reduces code size if many +// MiniTables are tree shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ + __attribute__((weak)) \ + const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to \ + __attribute__((weak, alias("kUpb_WeakSingletonPlaceholderMiniTable"))); +#define UPB_STRONG_ALIAS(type, from, to) \ + extern type to __attribute__((alias(#from))); + +#else +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) weak_alias_not_supported_on_this_platform +#define UPB_STRONG_ALIAS(type, from, to) \ + strong_alias_not_supported_on_this_platform +#endif + +// Future versions of upb will include breaking changes to some APIs. +// This macro can be set to enable these API changes ahead of time, so that +// user code can be updated before upgrading versions of protobuf. +#ifdef UPB_FUTURE_BREAKING_CHANGES + +#endif + +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#include + +// Must be last. + +extern const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* UPB_PRIVATE(upb_generated_extension_list); +typedef struct { + upb_MiniTableField fields[1]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__FileDescriptorSet_msg_init_Fields; + +static const google__protobuf__FileDescriptorSet_msg_init_Fields google_protobuf_FileDescriptorSet__fields = {{ + {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FileDescriptorProto_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FileDescriptorSet_msg_init = { + &google_protobuf_FileDescriptorSet__fields.fields[0], + 16, 1, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FileDescriptorSet", +#endif +}; + +typedef struct { + upb_MiniTableField fields[14]; + upb_MiniTableSubInternal subs[7]; +} google__protobuf__FileDescriptorProto_msg_init_Fields; + +static const google__protobuf__FileDescriptorProto_msg_init_Fields google_protobuf_FileDescriptorProto__fields = {{ + {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FileOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FileDescriptorProto_msg_init = { + &google_protobuf_FileDescriptorProto__fields.fields[0], + UPB_SIZE(80, 144), 14, kUpb_ExtMode_NonExtendable, 12, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FileDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0020000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x004000003f00001a, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x007800003f000050, &upb_DecodeFast_Varint32_Repeated_Tag1Byte}, + {0x008000003f000058, &upb_DecodeFast_Varint32_Repeated_Tag1Byte}, + {0x0030000004000062, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x008800003f00007a, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[11]; + upb_MiniTableSubInternal subs[9]; +} google__protobuf__DescriptorProto_msg_init_Fields; + +static const google__protobuf__DescriptorProto_msg_init_Fields google_protobuf_DescriptorProto__fields = {{ + {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ExtensionRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MessageOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ReservedRange_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__SymbolVisibility_enum_init}, +}}; + +const upb_MiniTable google__protobuf__DescriptorProto_msg_init = { + &google_protobuf_DescriptorProto__fields.fields[0], + UPB_SIZE(64, 104), 11, kUpb_ExtMode_NonExtendable, 11, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.DescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x006000003f000052, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__DescriptorProto__ExtensionRange_msg_init_Fields; + +static const google__protobuf__DescriptorProto__ExtensionRange_msg_init_Fields google_protobuf_DescriptorProto_ExtensionRange__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__DescriptorProto__ExtensionRange_msg_init = { + &google_protobuf_DescriptorProto_ExtensionRange__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.DescriptorProto.ExtensionRange", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; +} google__protobuf__DescriptorProto__ReservedRange_msg_init_Fields; + +static const google__protobuf__DescriptorProto__ReservedRange_msg_init_Fields google_protobuf_DescriptorProto_ReservedRange__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__DescriptorProto__ReservedRange_msg_init = { + &google_protobuf_DescriptorProto_ReservedRange__fields.fields[0], + 24, 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.DescriptorProto.ReservedRange", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[4]; + upb_MiniTableSubInternal subs[4]; +} google__protobuf__ExtensionRangeOptions_msg_init_Fields; + +static const google__protobuf__ExtensionRangeOptions_msg_init_Fields google_protobuf_ExtensionRangeOptions__fields = {{ + {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions__Declaration_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__ExtensionRangeOptions__VerificationState_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__ExtensionRangeOptions_msg_init = { + &google_protobuf_ExtensionRangeOptions__fields.fields[0], + UPB_SIZE(32, 40), 4, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ExtensionRangeOptions", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; +} google__protobuf__ExtensionRangeOptions__Declaration_msg_init_Fields; + +static const google__protobuf__ExtensionRangeOptions__Declaration_msg_init_Fields google_protobuf_ExtensionRangeOptions_Declaration__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__ExtensionRangeOptions__Declaration_msg_init = { + &google_protobuf_ExtensionRangeOptions_Declaration__fields.fields[0], + UPB_SIZE(32, 48), 5, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ExtensionRangeOptions.Declaration", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x002000000200001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000003000028, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000004000030, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[11]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FieldDescriptorProto_msg_init_Fields; + +static const google__protobuf__FieldDescriptorProto_msg_init_Fields google_protobuf_FieldDescriptorProto__fields = {{ + {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldDescriptorProto__Label_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldDescriptorProto__Type_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FieldDescriptorProto_msg_init = { + &google_protobuf_FieldDescriptorProto__fields.fields[0], + UPB_SIZE(72, 120), 11, kUpb_ExtMode_NonExtendable, 10, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0030000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x000c000002000018, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0040000005000032, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x005000000600003a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0018000008000048, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0060000009000052, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000a00000a000188, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__OneofDescriptorProto_msg_init_Fields; + +static const google__protobuf__OneofDescriptorProto_msg_init_Fields google_protobuf_OneofDescriptorProto__fields = {{ + {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__OneofDescriptorProto_msg_init = { + &google_protobuf_OneofDescriptorProto__fields.fields[0], + UPB_SIZE(24, 40), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.OneofDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[6]; + upb_MiniTableSubInternal subs[4]; +} google__protobuf__EnumDescriptorProto_msg_init_Fields; + +static const google__protobuf__EnumDescriptorProto_msg_init_Fields google_protobuf_EnumDescriptorProto__fields = {{ + {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__SymbolVisibility_enum_init}, +}}; + +const upb_MiniTable google__protobuf__EnumDescriptorProto_msg_init = { + &google_protobuf_EnumDescriptorProto__fields.fields[0], + UPB_SIZE(40, 64), 6, kUpb_ExtMode_NonExtendable, 6, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x003800003f00002a, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; +} google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init_Fields; + +static const google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init_Fields google_protobuf_EnumDescriptorProto_EnumReservedRange__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init = { + &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields.fields[0], + 24, 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumDescriptorProto.EnumReservedRange", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__EnumValueDescriptorProto_msg_init_Fields; + +static const google__protobuf__EnumValueDescriptorProto_msg_init_Fields google_protobuf_EnumValueDescriptorProto__fields = {{ + {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__EnumValueDescriptorProto_msg_init = { + &google_protobuf_EnumValueDescriptorProto__fields.fields[0], + UPB_SIZE(32, 40), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumValueDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x000c000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__ServiceDescriptorProto_msg_init_Fields; + +static const google__protobuf__ServiceDescriptorProto_msg_init_Fields google_protobuf_ServiceDescriptorProto__fields = {{ + {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__ServiceDescriptorProto_msg_init = { + &google_protobuf_ServiceDescriptorProto__fields.fields[0], + UPB_SIZE(32, 48), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ServiceDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[6]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__MethodDescriptorProto_msg_init_Fields; + +static const google__protobuf__MethodDescriptorProto_msg_init_Fields google_protobuf_MethodDescriptorProto__fields = {{ + {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__MethodDescriptorProto_msg_init = { + &google_protobuf_MethodDescriptorProto__fields.fields[0], + UPB_SIZE(40, 72), 6, kUpb_ExtMode_NonExtendable, 6, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.MethodDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0020000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x003000000200001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000004000028, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000005000030, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[21]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FileOptions_msg_init_Fields; + +static const google__protobuf__FileOptions_msg_init_Fields google_protobuf_FileOptions__fields = {{ + {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FileOptions__OptimizeMode_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FileOptions_msg_init = { + &google_protobuf_FileOptions__fields.fields[0], + UPB_SIZE(112, 200), 21, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FileOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001800000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0028000001000042, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000b000003000050, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x003800000400005a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000005000180, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x000d000006000188, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x000e000007000190, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000f0000080001a0, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x005800000d0002aa, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x00100000090001b8, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x007800000f0002c2, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x00880000100002ca, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001100000a0001d8, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x00980000110002e2, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x00a80000120002ea, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001200000b0001f8, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[7]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__MessageOptions_msg_init_Fields; + +static const google__protobuf__MessageOptions_msg_init_Fields google_protobuf_MessageOptions__fields = {{ + {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__MessageOptions_msg_init = { + &google_protobuf_MessageOptions__fields.fields[0], + UPB_SIZE(24, 32), 7, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.MessageOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000008, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000001000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000b000002000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000003000038, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000d000004000058, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[14]; + upb_MiniTableSubInternal subs[8]; +} google__protobuf__FieldOptions_msg_init_Fields; + +static const google__protobuf__FieldOptions_msg_init_Fields google_protobuf_FieldOptions__fields = {{ + {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__CType_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__JSType_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__OptionRetention_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__OptionTargetType_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__EditionDefault_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__FeatureSupport_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FieldOptions_msg_init = { + &google_protobuf_FieldOptions__fields.fields[0], + UPB_SIZE(48, 72), 14, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000a000001000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000b000002000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000003000028, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000d000005000050, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000e000006000078, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000f000007000180, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__FieldOptions__EditionDefault_msg_init_Fields; + +static const google__protobuf__FieldOptions__EditionDefault_msg_init_Fields google_protobuf_FieldOptions_EditionDefault__fields = {{ + {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FieldOptions__EditionDefault_msg_init = { + &google_protobuf_FieldOptions_EditionDefault__fields.fields[0], + UPB_SIZE(24, 32), 2, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldOptions.EditionDefault", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0010000000000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FieldOptions__FeatureSupport_msg_init_Fields; + +static const google__protobuf__FieldOptions__FeatureSupport_msg_init_Fields google_protobuf_FieldOptions_FeatureSupport__fields = {{ + {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FieldOptions__FeatureSupport_msg_init = { + &google_protobuf_FieldOptions_FeatureSupport__fields.fields[0], + UPB_SIZE(40, 56), 5, kUpb_ExtMode_NonExtendable, 5, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldOptions.FeatureSupport", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001800000200001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002800000400002a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__OneofOptions_msg_init_Fields; + +static const google__protobuf__OneofOptions_msg_init_Fields google_protobuf_OneofOptions__fields = {{ + {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__OneofOptions_msg_init = { + &google_protobuf_OneofOptions__fields.fields[0], + UPB_SIZE(24, 32), 2, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.OneofOptions", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__EnumOptions_msg_init_Fields; + +static const google__protobuf__EnumOptions_msg_init_Fields google_protobuf_EnumOptions__fields = {{ + {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__EnumOptions_msg_init = { + &google_protobuf_EnumOptions__fields.fields[0], + UPB_SIZE(24, 32), 5, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000001000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000b000002000030, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__EnumValueOptions_msg_init_Fields; + +static const google__protobuf__EnumValueOptions_msg_init_Fields google_protobuf_EnumValueOptions__fields = {{ + {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__FeatureSupport_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__EnumValueOptions_msg_init = { + &google_protobuf_EnumValueOptions__fields.fields[0], + UPB_SIZE(24, 40), 5, kUpb_ExtMode_Extendable, 4, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumValueOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000008, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000a000002000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__ServiceOptions_msg_init_Fields; + +static const google__protobuf__ServiceOptions_msg_init_Fields google_protobuf_ServiceOptions__fields = {{ + {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__ServiceOptions_msg_init = { + &google_protobuf_ServiceOptions__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ServiceOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000288, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[4]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__MethodOptions_msg_init_Fields; + +static const google__protobuf__MethodOptions_msg_init_Fields google_protobuf_MethodOptions__fields = {{ + {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__MethodOptions__IdempotencyLevel_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__MethodOptions_msg_init = { + &google_protobuf_MethodOptions__fields.fields[0], + UPB_SIZE(24, 32), 4, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.MethodOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000288, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[7]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__UninterpretedOption_msg_init_Fields; + +static const google__protobuf__UninterpretedOption_msg_init_Fields google_protobuf_UninterpretedOption__fields = {{ + {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption__NamePart_msg_init}, +}}; + +const upb_MiniTable google__protobuf__UninterpretedOption_msg_init = { + &google_protobuf_UninterpretedOption__fields.fields[0], + UPB_SIZE(64, 96), 7, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.UninterpretedOption", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0048000001000020, &upb_DecodeFast_Varint64_Scalar_Tag1Byte}, + {0x0050000002000028, &upb_DecodeFast_Varint64_Scalar_Tag1Byte}, + {0x0058000003000031, &upb_DecodeFast_Fixed64_Scalar_Tag1Byte}, + {0x002000000400003a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0030000005000042, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; +} google__protobuf__UninterpretedOption__NamePart_msg_init_Fields; + +static const google__protobuf__UninterpretedOption__NamePart_msg_init_Fields google_protobuf_UninterpretedOption_NamePart__fields = {{ + {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__UninterpretedOption__NamePart_msg_init = { + &google_protobuf_UninterpretedOption_NamePart__fields.fields[0], + UPB_SIZE(24, 32), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 2, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.UninterpretedOption.NamePart", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0009000001000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[8]; + upb_MiniTableSubInternal subs[8]; +} google__protobuf__FeatureSet_msg_init_Fields; + +static const google__protobuf__FeatureSet_msg_init_Fields google_protobuf_FeatureSet__fields = {{ + {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__FieldPresence_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__EnumType_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__Utf8Validation_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__MessageEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__JsonFormat_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__EnforceNamingStyle_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FeatureSet_msg_init = { + &google_protobuf_FeatureSet__fields.fields[0], + 48, 8, kUpb_ExtMode_Extendable, 8, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSet", +#endif +}; + +const upb_MiniTable google__protobuf__FeatureSet__VisibilityFeature_msg_init = { + NULL, + 8, 0, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSet.VisibilityFeature", +#endif +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FeatureSetDefaults_msg_init_Fields; + +static const google__protobuf__FeatureSetDefaults_msg_init_Fields google_protobuf_FeatureSetDefaults__fields = {{ + {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FeatureSetDefaults_msg_init = { + &google_protobuf_FeatureSetDefaults__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSetDefaults", +#endif +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init_Fields; + +static const google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init_Fields google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__fields = {{ + {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init = { + &google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault", +#endif +}; + +typedef struct { + upb_MiniTableField fields[1]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__SourceCodeInfo_msg_init_Fields; + +static const google__protobuf__SourceCodeInfo_msg_init_Fields google_protobuf_SourceCodeInfo__fields = {{ + {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo__Location_msg_init}, +}}; + +const upb_MiniTable google__protobuf__SourceCodeInfo_msg_init = { + &google_protobuf_SourceCodeInfo__fields.fields[0], + 16, 1, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.SourceCodeInfo", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; +} google__protobuf__SourceCodeInfo__Location_msg_init_Fields; + +static const google__protobuf__SourceCodeInfo__Location_msg_init_Fields google_protobuf_SourceCodeInfo_Location__fields = {{ + {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__SourceCodeInfo__Location_msg_init = { + &google_protobuf_SourceCodeInfo_Location__fields.fields[0], + UPB_SIZE(40, 72), 5, kUpb_ExtMode_NonExtendable, 4, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.SourceCodeInfo.Location", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x003000003f00000a, &upb_DecodeFast_Varint32_Packed_Tag1Byte}, + {0x003800003f000012, &upb_DecodeFast_Varint32_Packed_Tag1Byte}, + {0x001000000000001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0020000001000022, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x004000003f000032, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[1]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__GeneratedCodeInfo_msg_init_Fields; + +static const google__protobuf__GeneratedCodeInfo_msg_init_Fields google_protobuf_GeneratedCodeInfo__fields = {{ + {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__GeneratedCodeInfo__Annotation_msg_init}, +}}; + +const upb_MiniTable google__protobuf__GeneratedCodeInfo_msg_init = { + &google_protobuf_GeneratedCodeInfo__fields.fields[0], + 16, 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.GeneratedCodeInfo", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__GeneratedCodeInfo__Annotation_msg_init_Fields; + +static const google__protobuf__GeneratedCodeInfo__Annotation_msg_init_Fields google_protobuf_GeneratedCodeInfo_Annotation__fields = {{ + {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init}, +}}; + +const upb_MiniTable google__protobuf__GeneratedCodeInfo__Annotation_msg_init = { + &google_protobuf_GeneratedCodeInfo_Annotation__fields.fields[0], + UPB_SIZE(40, 48), 5, kUpb_ExtMode_NonExtendable, 5, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.GeneratedCodeInfo.Annotation", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002800003f00000a, &upb_DecodeFast_Varint32_Packed_Tag1Byte}, + {0x0018000000000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x000c000001000018, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000002000020, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTableEnum google__protobuf__Edition_enum_init = { + 64, + 11, + { + 0x7, + 0x0, + 0x384, + 0x3e6, + 0x3e7, + 0x3e8, + 0x3e9, + 0x3ea, + 0x270f, + 0x1869d, + 0x1869e, + 0x1869f, + 0x7fffffff, + }, +}; + +const upb_MiniTableEnum google__protobuf__ExtensionRangeOptions__VerificationState_enum_init = { + 64, + 0, + { + 0x3, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__EnforceNamingStyle_enum_init = { + 64, + 0, + { + 0xf, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__EnumType_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__FieldPresence_enum_init = { + 64, + 0, + { + 0xf, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__JsonFormat_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__MessageEncoding_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__Utf8Validation_enum_init = { + 64, + 0, + { + 0xd, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init = { + 64, + 0, + { + 0x1f, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Label_enum_init = { + 64, + 0, + { + 0xe, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Type_enum_init = { + 64, + 0, + { + 0x7fffe, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__CType_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__JSType_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__OptionRetention_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__OptionTargetType_enum_init = { + 64, + 0, + { + 0x3ff, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FileOptions__OptimizeMode_enum_init = { + 64, + 0, + { + 0xe, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__MethodOptions__IdempotencyLevel_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +static const upb_MiniTable *messages_layout[34] = { + &google__protobuf__FileDescriptorSet_msg_init, + &google__protobuf__FileDescriptorProto_msg_init, + &google__protobuf__DescriptorProto_msg_init, + &google__protobuf__DescriptorProto__ExtensionRange_msg_init, + &google__protobuf__DescriptorProto__ReservedRange_msg_init, + &google__protobuf__ExtensionRangeOptions_msg_init, + &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, + &google__protobuf__FieldDescriptorProto_msg_init, + &google__protobuf__OneofDescriptorProto_msg_init, + &google__protobuf__EnumDescriptorProto_msg_init, + &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, + &google__protobuf__EnumValueDescriptorProto_msg_init, + &google__protobuf__ServiceDescriptorProto_msg_init, + &google__protobuf__MethodDescriptorProto_msg_init, + &google__protobuf__FileOptions_msg_init, + &google__protobuf__MessageOptions_msg_init, + &google__protobuf__FieldOptions_msg_init, + &google__protobuf__FieldOptions__EditionDefault_msg_init, + &google__protobuf__FieldOptions__FeatureSupport_msg_init, + &google__protobuf__OneofOptions_msg_init, + &google__protobuf__EnumOptions_msg_init, + &google__protobuf__EnumValueOptions_msg_init, + &google__protobuf__ServiceOptions_msg_init, + &google__protobuf__MethodOptions_msg_init, + &google__protobuf__UninterpretedOption_msg_init, + &google__protobuf__UninterpretedOption__NamePart_msg_init, + &google__protobuf__FeatureSet_msg_init, + &google__protobuf__FeatureSet__VisibilityFeature_msg_init, + &google__protobuf__FeatureSetDefaults_msg_init, + &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, + &google__protobuf__SourceCodeInfo_msg_init, + &google__protobuf__SourceCodeInfo__Location_msg_init, + &google__protobuf__GeneratedCodeInfo_msg_init, + &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, +}; + +static const upb_MiniTableEnum *enums_layout[20] = { + &google__protobuf__Edition_enum_init, + &google__protobuf__ExtensionRangeOptions__VerificationState_enum_init, + &google__protobuf__FeatureSet__EnforceNamingStyle_enum_init, + &google__protobuf__FeatureSet__EnumType_enum_init, + &google__protobuf__FeatureSet__FieldPresence_enum_init, + &google__protobuf__FeatureSet__JsonFormat_enum_init, + &google__protobuf__FeatureSet__MessageEncoding_enum_init, + &google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init, + &google__protobuf__FeatureSet__Utf8Validation_enum_init, + &google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init, + &google__protobuf__FieldDescriptorProto__Label_enum_init, + &google__protobuf__FieldDescriptorProto__Type_enum_init, + &google__protobuf__FieldOptions__CType_enum_init, + &google__protobuf__FieldOptions__JSType_enum_init, + &google__protobuf__FieldOptions__OptionRetention_enum_init, + &google__protobuf__FieldOptions__OptionTargetType_enum_init, + &google__protobuf__FileOptions__OptimizeMode_enum_init, + &google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init, + &google__protobuf__MethodOptions__IdempotencyLevel_enum_init, + &google__protobuf__SymbolVisibility_enum_init, +}; + +const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = { + messages_layout, + enums_layout, + NULL, + 34, + 20, + 0, +}; + + + + +#include +#include +#include +#include +#include + +// Must be last. + +void upb_Status_Clear(upb_Status* status) { + if (!status) return; + status->ok = true; + status->msg[0] = '\0'; +} + +bool upb_Status_IsOk(const upb_Status* status) { return status->ok; } + +const char* upb_Status_ErrorMessage(const upb_Status* status) { + return status->msg; +} + +void upb_Status_SetErrorMessage(upb_Status* status, const char* msg) { + if (!status) return; + status->ok = false; + strncpy(status->msg, msg, _kUpb_Status_MaxMessage - 1); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; +} + +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + upb_Status_VSetErrorFormat(status, fmt, args); + va_end(args); +} + +void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt, + va_list args) { + if (!status) return; + status->ok = false; + vsnprintf(status->msg, sizeof(status->msg), fmt, args); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; +} + +void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, + va_list args) { + size_t len; + if (!status) return; + status->ok = false; + len = strlen(status->msg); + vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; +} + +/* + * upb_table Implementation + * + * Implementation is heavily inspired by Lua's ltable.c. + */ + + +#include +#include + + +// Must be last. + +#define UPB_MAXARRSIZE 16 // 2**16 = 64k. + +// From Chromium. +#define ARRAY_SIZE(x) \ + ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x]))))) + +/* The minimum utilization of the array part of a mixed hash/array table. This + * is a speed/memory-usage tradeoff (though it's not straightforward because of + * cache effects). The lower this is, the more memory we'll use. */ +static const double MIN_DENSITY = 0.1; + +#if defined(__has_builtin) +#if __has_builtin(__builtin_popcount) +#define UPB_FAST_POPCOUNT32(i) __builtin_popcount(i) +#endif +#elif defined(__GNUC__) +#define UPB_FAST_POPCOUNT32(i) __builtin_popcount(i) +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) +// Only use __popcnt on x86/x64 architectures for MSVC +#define UPB_FAST_POPCOUNT32(i) __popcnt(i) +#endif + +UPB_INLINE int _upb_popcnt32(uint32_t i) { +#ifdef UPB_FAST_POPCOUNT32 + return UPB_FAST_POPCOUNT32(i); +#else + int count = 0; + while (i != 0) { + count += i & 1; + i >>= 1; + } + return count; +#endif +} + +#undef UPB_FAST_POPCOUNT32 + +UPB_INLINE uint8_t _upb_log2_table_size(upb_table* t) { + return _upb_popcnt32(t->mask); +} + +static bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; } + +static int log2ceil(uint64_t v) { + int ret = 0; + bool pow2 = is_pow2(v); + while (v >>= 1) ret++; + ret = pow2 ? ret : ret + 1; // Ceiling. + return UPB_MIN(UPB_MAXARRSIZE, ret); +} + +/* A type to represent the lookup key of either a strtable, inttable or + * exttable. */ +typedef union { + uintptr_t num; + upb_StringView str; + struct { + const void* ptr; + uint32_t ext_num; + } ext; +} lookupkey_t; + +static lookupkey_t strkey2(const char* str, size_t len) { + return (lookupkey_t){.str = upb_StringView_FromDataAndSize(str, len)}; +} + +static lookupkey_t intkey(uintptr_t key) { return (lookupkey_t){.num = key}; } + +static lookupkey_t extkey(const void* ptr, uint32_t ext_num) { + return (lookupkey_t){.ext = {ptr, ext_num}}; +} + +// Conceptually the hash and equal functions should only take the key, not the +// value, but the extension table stores part of its logical key in the value +// slot. This is a sign that we have outgrown the original architecture. +typedef uint32_t hashfunc_t(upb_key key, upb_value val); +typedef bool eqlfunc_t(upb_key k1, upb_value v1, lookupkey_t k2); + +/* Base table (shared code) ***************************************************/ + +static uint32_t upb_inthash(uintptr_t key) { + UPB_STATIC_ASSERT(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8, + "Pointers don't fit"); + if (sizeof(uintptr_t) == 8) { + return (uint32_t)key ^ (uint32_t)(key >> 32); + } else { + return (uint32_t)key; + } +} + +static const upb_tabent* upb_getentry(const upb_table* t, uint32_t hash) { + return t->entries + (hash & t->mask); +} + +static bool isfull(upb_table* t) { + uint32_t size = upb_table_size(t); + // 0.875 load factor + return t->count == (size - (size >> 3)); +} + +static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) { + if (size_lg2 >= 32) { + return false; + } + t->count = 0; + uint32_t size = 1 << size_lg2; + t->mask = size - 1; // 0 mask if size_lg2 is 0 + if (upb_table_size(t) > (SIZE_MAX / sizeof(upb_tabent))) { + return false; + } + size_t bytes = upb_table_size(t) * sizeof(upb_tabent); + if (bytes > 0) { + t->entries = upb_Arena_Malloc(a, bytes); + if (!t->entries) return false; + memset(t->entries, 0, bytes); + } else { + t->entries = NULL; + } + return true; +} + +static upb_tabent* emptyent(upb_table* t, upb_tabent* e) { + upb_tabent* begin = t->entries; + upb_tabent* end = begin + upb_table_size(t); + for (e = e + 1; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + for (e = begin; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + UPB_ASSERT(false); + return NULL; +} + +static upb_tabent* getentry_mutable(upb_table* t, uint32_t hash) { + return (upb_tabent*)upb_getentry(t, hash); +} + +static const upb_tabent* findentry(const upb_table* t, lookupkey_t key, + uint32_t hash, eqlfunc_t* eql) { + const upb_tabent* e; + + if (t->count == 0) return NULL; + e = upb_getentry(t, hash); + if (upb_tabent_isempty(e)) return NULL; + while (1) { + if (eql(e->key, e->val, key)) return e; + if ((e = e->next) == NULL) return NULL; + } +} + +static upb_tabent* findentry_mutable(upb_table* t, lookupkey_t key, + uint32_t hash, eqlfunc_t* eql) { + return (upb_tabent*)findentry(t, key, hash, eql); +} + +static bool lookup(const upb_table* t, lookupkey_t key, upb_value* v, + uint32_t hash, eqlfunc_t* eql) { + const upb_tabent* e = findentry(t, key, hash, eql); + if (e) { + if (v) *v = e->val; + return true; + } else { + return false; + } +} + +/* The given key must not already exist in the table. */ +static void insert(upb_table* t, lookupkey_t key, upb_key tabkey, upb_value val, + uint32_t hash, hashfunc_t* hashfunc, eqlfunc_t* eql) { + upb_tabent* mainpos_e; + upb_tabent* our_e; + + UPB_ASSERT(findentry(t, key, hash, eql) == NULL); + + t->count++; + mainpos_e = getentry_mutable(t, hash); + our_e = mainpos_e; + + if (upb_tabent_isempty(mainpos_e)) { + /* Our main position is empty; use it. */ + our_e->next = NULL; + } else { + /* Collision. */ + upb_tabent* new_e = emptyent(t, mainpos_e); + /* Head of collider's chain. */ + upb_tabent* chain = + getentry_mutable(t, hashfunc(mainpos_e->key, mainpos_e->val)); + if (chain == mainpos_e) { + /* Existing ent is in its main position (it has the same hash as us, and + * is the head of our chain). Insert to new ent and append to this chain. + */ + new_e->next = mainpos_e->next; + mainpos_e->next = new_e; + our_e = new_e; + } else { + /* Existing ent is not in its main position (it is a node in some other + * chain). This implies that no existing ent in the table has our hash. + * Evict it (updating its chain) and use its ent for head of our chain. */ + *new_e = *mainpos_e; /* copies next. */ + while (chain->next != mainpos_e) { + chain = (upb_tabent*)chain->next; + UPB_ASSERT(chain); + } + chain->next = new_e; + our_e = mainpos_e; + our_e->next = NULL; + } + } + our_e->key = tabkey; + our_e->val = val; + UPB_ASSERT(findentry(t, key, hash, eql) == our_e); +} + +static bool rm(upb_table* t, lookupkey_t key, upb_value* val, uint32_t hash, + eqlfunc_t* eql) { + upb_tabent* chain = getentry_mutable(t, hash); + if (upb_tabent_isempty(chain)) return false; + if (eql(chain->key, chain->val, key)) { + /* Element to remove is at the head of its chain. */ + t->count--; + if (val) *val = chain->val; + if (chain->next) { + upb_tabent* move = (upb_tabent*)chain->next; + *chain = *move; + move->key = upb_key_empty(); + } else { + chain->key = upb_key_empty(); + } + return true; + } else { + /* Element to remove is either in a non-head position or not in the + * table. */ + while (chain->next && !eql(chain->next->key, chain->next->val, key)) { + chain = (upb_tabent*)chain->next; + } + if (chain->next) { + /* Found element to remove. */ + upb_tabent* rm = (upb_tabent*)chain->next; + t->count--; + if (val) *val = chain->next->val; + rm->key = upb_key_empty(); + chain->next = rm->next; + return true; + } else { + /* Element to remove is not in the table. */ + return false; + } + } +} + +static size_t next(const upb_table* t, size_t i) { + do { + if (++i >= upb_table_size(t)) return SIZE_MAX - 1; /* Distinct from -1. */ + } while (upb_tabent_isempty(&t->entries[i])); + + return i; +} + +static size_t begin(const upb_table* t) { return next(t, -1); } + +/* upb_strtable ***************************************************************/ + +// A simple "subclass" of upb_table that only adds a hash function for strings. + +static upb_SizePrefixString* upb_SizePrefixString_Copy(upb_StringView s, + upb_Arena* a) { + // A 2GB string will fail at serialization time, but we accept up to 4GB in + // memory here. + if (s.size > UINT32_MAX) return NULL; + upb_SizePrefixString* str = + upb_Arena_Malloc(a, sizeof(uint32_t) + s.size + 1); + if (str == NULL) return NULL; + str->size = s.size; + char* data = (char*)str->data; + if (s.size) memcpy(data, s.data, s.size); + data[s.size] = '\0'; + return str; +} + +/* Adapted from ABSL's wyhash. */ + +static uint64_t UnalignedLoad64(const void* p) { + uint64_t val; + memcpy(&val, p, 8); + return val; +} + +static uint32_t UnalignedLoad32(const void* p) { + uint32_t val; + memcpy(&val, p, 4); + return val; +} + +#if defined(_MSC_VER) && defined(_M_X64) +#include +#endif + +/* Computes a * b, returning the low 64 bits of the result and storing the high + * 64 bits in |*high|. */ +static uint64_t upb_umul128(uint64_t v0, uint64_t v1, uint64_t* out_high) { +#ifdef __SIZEOF_INT128__ + __uint128_t p = v0; + p *= v1; + *out_high = (uint64_t)(p >> 64); + return (uint64_t)p; +#elif defined(_MSC_VER) && defined(_M_X64) + return _umul128(v0, v1, out_high); +#else + uint64_t a32 = v0 >> 32; + uint64_t a00 = v0 & 0xffffffff; + uint64_t b32 = v1 >> 32; + uint64_t b00 = v1 & 0xffffffff; + uint64_t high = a32 * b32; + uint64_t low = a00 * b00; + uint64_t mid1 = a32 * b00; + uint64_t mid2 = a00 * b32; + low += (mid1 << 32) + (mid2 << 32); + // Omit carry bit, for mixing we do not care about exact numerical precision. + high += (mid1 >> 32) + (mid2 >> 32); + *out_high = high; + return low; +#endif +} + +static uint64_t WyhashMix(uint64_t v0, uint64_t v1) { + uint64_t high; + uint64_t low = upb_umul128(v0, v1, &high); + return low ^ high; +} + +static uint64_t Wyhash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[]) { + const uint8_t* ptr = (const uint8_t*)data; + uint64_t starting_length = (uint64_t)len; + uint64_t current_state = seed ^ salt[0]; + + if (len > 64) { + // If we have more than 64 bytes, we're going to handle chunks of 64 + // bytes at a time. We're going to build up two separate hash states + // which we will then hash together. + uint64_t duplicated_state = current_state; + + do { + uint64_t a = UnalignedLoad64(ptr); + uint64_t b = UnalignedLoad64(ptr + 8); + uint64_t c = UnalignedLoad64(ptr + 16); + uint64_t d = UnalignedLoad64(ptr + 24); + uint64_t e = UnalignedLoad64(ptr + 32); + uint64_t f = UnalignedLoad64(ptr + 40); + uint64_t g = UnalignedLoad64(ptr + 48); + uint64_t h = UnalignedLoad64(ptr + 56); + + uint64_t cs0 = WyhashMix(a ^ salt[1], b ^ current_state); + uint64_t cs1 = WyhashMix(c ^ salt[2], d ^ current_state); + current_state = (cs0 ^ cs1); + + uint64_t ds0 = WyhashMix(e ^ salt[3], f ^ duplicated_state); + uint64_t ds1 = WyhashMix(g ^ salt[4], h ^ duplicated_state); + duplicated_state = (ds0 ^ ds1); + + ptr += 64; + len -= 64; + } while (len > 64); + + current_state = current_state ^ duplicated_state; + } + + // We now have a data `ptr` with at most 64 bytes and the current state + // of the hashing state machine stored in current_state. + while (len > 16) { + uint64_t a = UnalignedLoad64(ptr); + uint64_t b = UnalignedLoad64(ptr + 8); + + current_state = WyhashMix(a ^ salt[1], b ^ current_state); + + ptr += 16; + len -= 16; + } + + // We now have a data `ptr` with at most 16 bytes. + uint64_t a = 0; + uint64_t b = 0; + if (len > 8) { + // When we have at least 9 and at most 16 bytes, set A to the first 64 + // bits of the input and B to the last 64 bits of the input. Yes, they will + // overlap in the middle if we are working with less than the full 16 + // bytes. + a = UnalignedLoad64(ptr); + b = UnalignedLoad64(ptr + len - 8); + } else if (len > 3) { + // If we have at least 4 and at most 8 bytes, set A to the first 32 + // bits and B to the last 32 bits. + a = UnalignedLoad32(ptr); + b = UnalignedLoad32(ptr + len - 4); + } else if (len > 0) { + // If we have at least 1 and at most 3 bytes, read all of the provided + // bits into A, with some adjustments. + a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]); + b = 0; + } else { + a = 0; + b = 0; + } + + uint64_t w = WyhashMix(a ^ salt[1], b ^ current_state); + uint64_t z = salt[1] ^ starting_length; + return WyhashMix(w, z); +} + +const uint64_t kWyhashSalt[5] = { + 0x243F6A8885A308D3ULL, 0x13198A2E03707344ULL, 0xA4093822299F31D0ULL, + 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL, +}; + +uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed) { + return Wyhash(p, n, seed, kWyhashSalt); +} + +static const void* const _upb_seed; + +// Returns a random seed for upb's hash function. This does not provide +// high-quality randomness, but it should be enough to prevent unit tests from +// relying on a deterministic map ordering. By returning the address of a +// variable, we are able to get some randomness for free provided that ASLR is +// enabled. +static uint64_t _upb_Seed(void) { return (uint64_t)&_upb_seed; } + +static uint32_t _upb_Hash_NoSeed(const char* p, size_t n) { + return _upb_Hash(p, n, _upb_Seed()); +} + +static uint32_t strhash(upb_key key, upb_value val) { + UPB_UNUSED(val); + return _upb_Hash_NoSeed(key.str->data, key.str->size); +} + +static bool streql(upb_key k1, upb_value v1, lookupkey_t k2) { + UPB_UNUSED(v1); + const upb_SizePrefixString* k1s = k1.str; + const upb_StringView k2s = k2.str; + return k1s->size == k2s.size && + (k1s->size == 0 || memcmp(k1s->data, k2s.data, k1s->size) == 0); +} + +/** Calculates the number of entries required to hold an expected number of + * values, within the table's load factor. */ +static size_t _upb_entries_needed_for(size_t expected_size) { + size_t need_entries = expected_size + 1 + expected_size / 7; + UPB_ASSERT(need_entries - (need_entries >> 3) >= expected_size); + return need_entries; +} + +bool upb_strtable_init(upb_strtable* t, size_t expected_size, upb_Arena* a) { + int size_lg2 = upb_Log2Ceiling(_upb_entries_needed_for(expected_size)); + return init(&t->t, size_lg2, a); +} + +void upb_strtable_clear(upb_strtable* t) { + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); +} + +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a) { + upb_strtable new_table; + if (!init(&new_table.t, size_lg2, a)) return false; + + intptr_t iter = UPB_STRTABLE_BEGIN; + upb_StringView sv; + upb_value val; + while (upb_strtable_next2(t, &sv, &val, &iter)) { + // Unlike normal insert, does not copy string data or possibly reallocate + // the table + // The data pointer used in the table is guaranteed to point at a + // upb_SizePrefixString, we just need to back up by the size of the uint32_t + // length prefix. + const upb_SizePrefixString* keystr = + (const upb_SizePrefixString*)(sv.data - sizeof(uint32_t)); + UPB_ASSERT(keystr->data == sv.data); + UPB_ASSERT(keystr->size == sv.size); + + lookupkey_t lookupkey = {.str = sv}; + upb_key tabkey = {.str = keystr}; + uint32_t hash = _upb_Hash_NoSeed(sv.data, sv.size); + insert(&new_table.t, lookupkey, tabkey, val, hash, &strhash, &streql); + } + *t = new_table; + return true; +} + +bool upb_strtable_insert(upb_strtable* t, const char* k, size_t len, + upb_value v, upb_Arena* a) { + if (isfull(&t->t)) { + /* Need to resize. New table of double the size, add old elements to it. */ + if (!upb_strtable_resize(t, _upb_log2_table_size(&t->t) + 1, a)) { + return false; + } + } + + upb_StringView sv = upb_StringView_FromDataAndSize(k, len); + upb_SizePrefixString* size_prefix_string = upb_SizePrefixString_Copy(sv, a); + if (!size_prefix_string) return false; + + lookupkey_t lookupkey = {.str = sv}; + upb_key key = {.str = size_prefix_string}; + uint32_t hash = _upb_Hash_NoSeed(k, len); + insert(&t->t, lookupkey, key, v, hash, &strhash, &streql); + return true; +} + +bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, + upb_value* v) { + uint32_t hash = _upb_Hash_NoSeed(key, len); + return lookup(&t->t, strkey2(key, len), v, hash, &streql); +} + +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val) { + uint32_t hash = _upb_Hash_NoSeed(key, len); + return rm(&t->t, strkey2(key, len), val, hash, &streql); +} + +/* Iteration */ + +void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t) { + i->t = t; + i->index = begin(&t->t); +} + +void upb_strtable_next(upb_strtable_iter* i) { + i->index = next(&i->t->t, i->index); +} + +bool upb_strtable_done(const upb_strtable_iter* i) { + if (!i->t) return true; + return i->index >= upb_table_size(&i->t->t) || + upb_tabent_isempty(str_tabent(i)); +} + +upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i) { + UPB_ASSERT(!upb_strtable_done(i)); + return upb_key_strview(str_tabent(i)->key); +} + +upb_value upb_strtable_iter_value(const upb_strtable_iter* i) { + UPB_ASSERT(!upb_strtable_done(i)); + return str_tabent(i)->val; +} + +void upb_strtable_iter_setdone(upb_strtable_iter* i) { + i->t = NULL; + i->index = SIZE_MAX; +} + +bool upb_strtable_iter_isequal(const upb_strtable_iter* i1, + const upb_strtable_iter* i2) { + if (upb_strtable_done(i1) && upb_strtable_done(i2)) return true; + return i1->t == i2->t && i1->index == i2->index; +} + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter) { + size_t tab_idx = next(&t->t, *iter); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + *key = upb_key_strview(ent->key); + *val = ent->val; + *iter = tab_idx; + return true; + } + + return false; +} + +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter) { + intptr_t i = *iter; + upb_tabent* ent = &t->t.entries[i]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = upb_key_empty(); + ent->next = NULL; +} + +void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v) { + t->t.entries[iter].val = v; +} + +/* upb_exttable ***************************************************************/ + +static uint32_t _upb_exttable_hash(const void* ptr, uint32_t ext_num) { + uint64_t a = (uintptr_t)ptr; + uint64_t b = ext_num; + return (uint32_t)WyhashMix(a ^ kWyhashSalt[1], b ^ _upb_Seed()); +} + +static uint32_t exthash(upb_key key, upb_value val) { + const void* ptr = (const void*)key.num; + uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(val); + return _upb_exttable_hash(ptr, ext_num); +} + +static bool exteql(upb_key k1, upb_value v1, lookupkey_t k2) { + if ((const void*)k1.num == k2.ext.ptr) { + uint32_t ext_num1 = *(const uint32_t*)upb_value_getconstptr(v1); + return ext_num1 == k2.ext.ext_num; + } + return false; +} + +bool upb_exttable_init(upb_exttable* t, size_t expected_size, upb_Arena* a) { + int size_lg2 = upb_Log2Ceiling(_upb_entries_needed_for(expected_size)); + return init(&t->t, size_lg2, a); +} + +void upb_exttable_clear(upb_exttable* t) { + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); +} + +bool upb_exttable_resize(upb_exttable* t, size_t size_lg2, upb_Arena* a) { + upb_exttable new_table; + if (!init(&new_table.t, size_lg2, a)) return false; + + size_t i; + for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { + const upb_tabent* e = &t->t.entries[i]; + uint32_t hash = exthash(e->key, e->val); + uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(e->val); + lookupkey_t lookupkey = extkey((const void*)e->key.num, ext_num); + insert(&new_table.t, lookupkey, e->key, e->val, hash, &exthash, &exteql); + } + + *t = new_table; + return true; +} + +bool upb_exttable_insert(upb_exttable* t, const void* k, const uint32_t* v, + upb_Arena* a) { + UPB_ASSERT(k != NULL); + UPB_ASSERT(v != NULL); + UPB_ASSERT(*v != 0); + + if (isfull(&t->t)) { + if (!upb_exttable_resize(t, _upb_log2_table_size(&t->t) + 1, a)) { + return false; + } + } + + lookupkey_t lookupkey = extkey(k, *v); + upb_key key = {.num = (uintptr_t)k}; + upb_value val = upb_value_constptr(v); + uint32_t hash = _upb_exttable_hash(k, *v); + insert(&t->t, lookupkey, key, val, hash, &exthash, &exteql); + return true; +} + +const uint32_t* upb_exttable_lookup(const upb_exttable* t, const void* k, + uint32_t ext_number) { + uint32_t hash = _upb_exttable_hash(k, ext_number); + upb_value val; + if (lookup(&t->t, extkey(k, ext_number), &val, hash, &exteql)) { + return (const uint32_t*)upb_value_getconstptr(val); + } + return NULL; +} + +const uint32_t* upb_exttable_remove(upb_exttable* t, const void* k, + uint32_t ext_number) { + uint32_t hash = _upb_exttable_hash(k, ext_number); + upb_value val; + if (rm(&t->t, extkey(k, ext_number), &val, hash, &exteql)) { + return (const uint32_t*)upb_value_getconstptr(val); + } + return NULL; +} + +size_t upb_exttable_size(const upb_exttable* t) { return t->t.count; } + +/* upb_inttable ***************************************************************/ + +/* For inttables we use a hybrid structure where small keys are kept in an + * array and large keys are put in the hash table. */ + +// The sentinel value used in the dense array part. Note that callers must +// ensure that inttable is never used with a value of this sentinel type +// (pointers and u32 values will never be; i32 needs to be handled carefully +// to avoid sign-extending into this value). +static const upb_value kInttableSentinel = {.val = UINT64_MAX}; +static uint32_t presence_mask_arr_size(uint32_t array_size) { + return (array_size + 7) / 8; // sizeof(uint8_t) is always 1. +} + +static uint32_t inthash(upb_key key, upb_value val) { + UPB_UNUSED(val); + return upb_inthash(key.num); +} + +static bool inteql(upb_key k1, upb_value v1, lookupkey_t k2) { + UPB_UNUSED(v1); + return k1.num == k2.num; +} + +static upb_value* mutable_array(upb_inttable* t) { + return (upb_value*)t->array; +} + +static const upb_value* inttable_array_get(const upb_inttable* t, + uintptr_t key) { + UPB_ASSERT(key < t->array_size); + const upb_value* val = &t->array[key]; + return upb_inttable_arrhas(t, key) ? val : NULL; +} + +static upb_value* inttable_val(upb_inttable* t, uintptr_t key) { + if (key < t->array_size) { + return (upb_value*)inttable_array_get(t, key); + } else { + upb_tabent* e = + findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql); + return e ? &e->val : NULL; + } +} + +static const upb_value* inttable_val_const(const upb_inttable* t, + uintptr_t key) { + return inttable_val((upb_inttable*)t, key); +} + +size_t upb_inttable_count(const upb_inttable* t) { + return t->t.count + t->array_count; +} + +static void check(upb_inttable* t) { + UPB_UNUSED(t); +#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG) + { + // This check is very expensive (makes inserts/deletes O(N)). + size_t count = 0; + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + while (upb_inttable_next(t, &key, &val, &iter)) { + UPB_ASSERT(upb_inttable_lookup(t, key, NULL)); + } + UPB_ASSERT(count == upb_inttable_count(t)); + } +#endif +} + +bool upb_inttable_sizedinit(upb_inttable* t, uint32_t asize, int hsize_lg2, + upb_Arena* a) { + if (!init(&t->t, hsize_lg2, a)) return false; + /* Always make the array part at least 1 long, so that we know key 0 + * won't be in the hash part, which simplifies things. */ + t->array_size = UPB_MAX(1, asize); + t->array_count = 0; +#if UINT32_MAX >= SIZE_MAX + if (UPB_UNLIKELY(SIZE_MAX / sizeof(upb_value) < t->array_size)) { + return false; + } +#endif + + // Allocate the array part and the presence mask array in one allocation. + size_t array_bytes = t->array_size * sizeof(upb_value); + uint32_t presence_bytes = presence_mask_arr_size(t->array_size); + uintptr_t total_bytes = array_bytes + presence_bytes; + if (UPB_UNLIKELY(total_bytes > SIZE_MAX)) { + return false; + } + void* alloc = upb_Arena_Malloc(a, total_bytes); + if (!alloc) { + return false; + } + t->array = alloc; + memset(mutable_array(t), 0xff, array_bytes); + t->presence_mask = (uint8_t*)alloc + array_bytes; + memset((uint8_t*)t->presence_mask, 0, presence_bytes); + + check(t); + return true; +} + +bool upb_inttable_init(upb_inttable* t, upb_Arena* a) { + // The init size of the table part to match that of strtable. + return upb_inttable_sizedinit(t, 0, 3, a); +} + +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a) { + if (key < t->array_size) { + UPB_ASSERT(!upb_inttable_arrhas(t, key)); + t->array_count++; + mutable_array(t)[key] = val; + ((uint8_t*)t->presence_mask)[key / 8] |= (1 << (key % 8)); + } else { + if (isfull(&t->t)) { + /* Need to resize the hash part, but we re-use the array part. */ + size_t i; + upb_table new_table; + + if (!init(&new_table, _upb_log2_table_size(&t->t) + 1, a)) { + return false; + } + + for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { + const upb_tabent* e = &t->t.entries[i]; + insert(&new_table, intkey(e->key.num), e->key, e->val, + inthash(e->key, e->val), &inthash, &inteql); + } + + UPB_ASSERT(t->t.count == new_table.count); + + t->t = new_table; + } + upb_key tabkey = {.num = key}; + insert(&t->t, intkey(key), tabkey, val, upb_inthash(key), &inthash, + &inteql); + } + check(t); + return true; +} + +bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v) { + const upb_value* table_v = inttable_val_const(t, key); + if (!table_v) return false; + if (v) *v = *table_v; + return true; +} + +bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val) { + upb_value* table_v = inttable_val(t, key); + if (!table_v) return false; + *table_v = val; + return true; +} + +bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val) { + bool success; + if (key < t->array_size) { + if (upb_inttable_arrhas(t, key)) { + t->array_count--; + if (val) { + *val = t->array[key]; + } + mutable_array(t)[key] = kInttableSentinel; + ((uint8_t*)t->presence_mask)[key / 8] &= ~(1 << (key % 8)); + success = true; + } else { + success = false; + } + } else { + success = rm(&t->t, intkey(key), val, upb_inthash(key), &inteql); + } + check(t); + return success; +} + +bool upb_inttable_compact(upb_inttable* t, upb_Arena* a) { + /* A power-of-two histogram of the table keys. */ + uint32_t counts[UPB_MAXARRSIZE + 1] = {0}; + + /* The max key in each bucket. */ + uintptr_t max[UPB_MAXARRSIZE + 1] = {0}; + + { + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + while (upb_inttable_next(t, &key, &val, &iter)) { + int bucket = log2ceil(key); + max[bucket] = UPB_MAX(max[bucket], key); + counts[bucket]++; + } + } + + /* Find the largest power of two that satisfies the MIN_DENSITY + * definition (while actually having some keys). */ + uint32_t arr_count = upb_inttable_count(t); + + // Scan all buckets except capped bucket + int size_lg2 = ARRAY_SIZE(counts) - 1; + for (; size_lg2 > 0; size_lg2--) { + if (counts[size_lg2] == 0) { + /* We can halve again without losing any entries. */ + continue; + } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) { + break; + } + + arr_count -= counts[size_lg2]; + } + + UPB_ASSERT(arr_count <= upb_inttable_count(t)); + + upb_inttable new_t; + { + /* Insert all elements into new, perfectly-sized table. */ + uintptr_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */ + uint32_t hash_count = upb_inttable_count(t) - arr_count; + size_t hash_size = hash_count ? _upb_entries_needed_for(hash_count) : 0; + int hashsize_lg2 = log2ceil(hash_size); + + if (!upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a)) { + return false; + } + + { + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + while (upb_inttable_next(t, &key, &val, &iter)) { + upb_inttable_insert(&new_t, key, val, a); + } + } + + UPB_ASSERT(new_t.array_size == arr_size); + } + *t = new_t; + return true; +} + +void upb_inttable_clear(upb_inttable* t) { + // Clear the array part. + size_t array_bytes = t->array_size * sizeof(upb_value); + t->array_count = 0; + // Clear the array by setting all bits to 1, as UINT64_MAX is the sentinel + // value for an empty array. + memset(mutable_array(t), 0xff, array_bytes); + // Clear the presence mask array. + memset((uint8_t*)t->presence_mask, 0, presence_mask_arr_size(t->array_size)); + // Clear the table part. + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); +} + +// Iteration. + +bool upb_inttable_next(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter) { + intptr_t i = *iter; + if ((size_t)(i + 1) <= t->array_size) { + while ((size_t)++i < t->array_size) { + const upb_value* ent = inttable_array_get(t, i); + if (ent) { + *key = i; + *val = *ent; + *iter = i; + return true; + } + } + i--; // Back up to exactly one position before the start of the table. + } + + size_t tab_idx = next(&t->t, i - t->array_size); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + *key = ent->key.num; + *val = ent->val; + *iter = tab_idx + t->array_size; + return true; + } else { + // We should set the iterator any way. When we are done, the iterator value + // is invalidated. `upb_inttable_done` will check on the iterator value to + // determine if the iteration is done. + *iter = INTPTR_MAX - 1; // To disambiguate from UPB_INTTABLE_BEGIN, to + // match the behavior of `upb_strtable_iter`. + return false; + } +} + +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter) { + intptr_t i = *iter; + if ((size_t)i < t->array_size) { + t->array_count--; + mutable_array(t)[i].val = -1; + } else { + upb_tabent* ent = &t->t.entries[i - t->array_size]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = upb_key_empty(); + ent->next = NULL; + } +} + +void upb_inttable_setentryvalue(upb_inttable* t, intptr_t iter, upb_value v) { + if ((size_t)iter < t->array_size) { + mutable_array(t)[iter] = v; + } else { + upb_tabent* ent = &t->t.entries[iter - t->array_size]; + ent->val = v; + } +} + +bool upb_inttable_done(const upb_inttable* t, intptr_t iter) { + if ((uintptr_t)iter >= t->array_size + upb_table_size(&t->t)) { + return true; + } else if ((size_t)iter < t->array_size) { + return !upb_inttable_arrhas(t, iter); + } else { + return upb_tabent_isempty(&t->t.entries[iter - t->array_size]); + } +} + +uintptr_t upb_inttable_iter_key(const upb_inttable* t, intptr_t iter) { + UPB_ASSERT(!upb_inttable_done(t, iter)); + return (size_t)iter < t->array_size + ? iter + : t->t.entries[iter - t->array_size].key.num; +} + +upb_value upb_inttable_iter_value(const upb_inttable* t, intptr_t iter) { + UPB_ASSERT(!upb_inttable_done(t, iter)); + if ((size_t)iter < t->array_size) { + return t->array[iter]; + } else { + return t->t.entries[iter - t->array_size].val; + } +} + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// Must be last. + +typedef struct { + const char *ptr, *end; + upb_Arena* arena; /* TODO: should we have a tmp arena for tmp data? */ + const upb_DefPool* symtab; + int depth; + int result; + upb_Status* status; + jmp_buf err; + int line; + const char* line_begin; + bool is_first; + int options; + const upb_FieldDef* debug_field; +} jsondec; + +typedef struct { + upb_MessageValue value; + bool ignore; +} upb_JsonMessageValue; + +enum { JD_OBJECT, JD_ARRAY, JD_STRING, JD_NUMBER, JD_TRUE, JD_FALSE, JD_NULL }; + +/* Forward declarations of mutually-recursive functions. */ +static void jsondec_wellknown(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); +static upb_JsonMessageValue jsondec_value(jsondec* d, const upb_FieldDef* f); +static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); +static void jsondec_object(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); + +static bool jsondec_streql(upb_StringView str, const char* lit) { + return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0; +} + +static bool jsondec_isnullvalue(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Enum && + strcmp(upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(f)), + "google.protobuf.NullValue") == 0; +} + +static bool jsondec_isvalue(const upb_FieldDef* f) { + return (upb_FieldDef_CType(f) == kUpb_CType_Message && + upb_MessageDef_WellKnownType(upb_FieldDef_MessageSubDef(f)) == + kUpb_WellKnown_Value) || + jsondec_isnullvalue(f); +} + +static void jsondec_seterrmsg(jsondec* d, const char* msg) { + upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: %s", d->line, + (int)(d->ptr - d->line_begin), msg); +} + +UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) { + jsondec_seterrmsg(d, msg); + UPB_LONGJMP(d->err, 1); +} + +UPB_PRINTF(2, 3) +UPB_NORETURN static void jsondec_errf(jsondec* d, const char* fmt, ...) { + va_list argp; + upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: ", d->line, + (int)(d->ptr - d->line_begin)); + va_start(argp, fmt); + upb_Status_VAppendErrorFormat(d->status, fmt, argp); + va_end(argp); + UPB_LONGJMP(d->err, 1); +} + +// Advances d->ptr until the next non-whitespace character or to the end of +// the buffer. +static void jsondec_consumews(jsondec* d) { + while (d->ptr != d->end) { + switch (*d->ptr) { + case '\n': + d->line++; + d->line_begin = d->ptr; + /* Fallthrough. */ + case '\r': + case '\t': + case ' ': + d->ptr++; + break; + default: + return; + } + } +} + +// Advances d->ptr until the next non-whitespace character. Postcondition that +// d->ptr is pointing at a valid non-whitespace character (will err if end of +// buffer is reached). +static void jsondec_skipws(jsondec* d) { + jsondec_consumews(d); + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } +} + +static bool jsondec_tryparsech(jsondec* d, char ch) { + if (d->ptr == d->end || *d->ptr != ch) return false; + d->ptr++; + return true; +} + +static void jsondec_parselit(jsondec* d, const char* lit) { + size_t avail = d->end - d->ptr; + size_t len = strlen(lit); + if (avail < len || memcmp(d->ptr, lit, len) != 0) { + jsondec_errf(d, "Expected: '%s'", lit); + } + d->ptr += len; +} + +static void jsondec_wsch(jsondec* d, char ch) { + jsondec_skipws(d); + if (!jsondec_tryparsech(d, ch)) { + jsondec_errf(d, "Expected: '%c'", ch); + } +} + +static void jsondec_true(jsondec* d) { jsondec_parselit(d, "true"); } +static void jsondec_false(jsondec* d) { jsondec_parselit(d, "false"); } +static void jsondec_null(jsondec* d) { jsondec_parselit(d, "null"); } + +static void jsondec_entrysep(jsondec* d) { + jsondec_skipws(d); + jsondec_parselit(d, ":"); +} + +static int jsondec_rawpeek(jsondec* d) { + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } + + switch (*d->ptr) { + case '{': + return JD_OBJECT; + case '[': + return JD_ARRAY; + case '"': + return JD_STRING; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return JD_NUMBER; + case 't': + return JD_TRUE; + case 'f': + return JD_FALSE; + case 'n': + return JD_NULL; + default: + jsondec_errf(d, "Unexpected character: '%c'", *d->ptr); + } +} + +/* JSON object/array **********************************************************/ + +/* These are used like so: + * + * jsondec_objstart(d); + * while (jsondec_objnext(d)) { + * ... + * } + * jsondec_objend(d) */ + +static int jsondec_peek(jsondec* d) { + jsondec_skipws(d); + return jsondec_rawpeek(d); +} + +static void jsondec_push(jsondec* d) { + if (--d->depth < 0) { + jsondec_err(d, "Recursion limit exceeded"); + } + d->is_first = true; +} + +static bool jsondec_seqnext(jsondec* d, char end_ch) { + bool is_first = d->is_first; + d->is_first = false; + jsondec_skipws(d); + if (*d->ptr == end_ch) return false; + if (!is_first) jsondec_parselit(d, ","); + return true; +} + +static void jsondec_arrstart(jsondec* d) { + jsondec_push(d); + jsondec_wsch(d, '['); +} + +static void jsondec_arrend(jsondec* d) { + d->depth++; + jsondec_wsch(d, ']'); +} + +static bool jsondec_arrnext(jsondec* d) { return jsondec_seqnext(d, ']'); } + +static void jsondec_objstart(jsondec* d) { + jsondec_push(d); + jsondec_wsch(d, '{'); +} + +static void jsondec_objend(jsondec* d) { + d->depth++; + jsondec_wsch(d, '}'); +} + +static bool jsondec_objnext(jsondec* d) { + if (!jsondec_seqnext(d, '}')) return false; + if (jsondec_peek(d) != JD_STRING) { + jsondec_err(d, "Object must start with string"); + } + return true; +} + +/* JSON number ****************************************************************/ + +static bool jsondec_tryskipdigits(jsondec* d) { + const char* start = d->ptr; + + while (d->ptr < d->end) { + if (*d->ptr < '0' || *d->ptr > '9') { + break; + } + d->ptr++; + } + + return d->ptr != start; +} + +static void jsondec_skipdigits(jsondec* d) { + if (!jsondec_tryskipdigits(d)) { + jsondec_err(d, "Expected one or more digits"); + } +} + +static double jsondec_number(jsondec* d) { + const char* start = d->ptr; + + UPB_ASSERT(jsondec_rawpeek(d) == JD_NUMBER); + + /* Skip over the syntax of a number, as specified by JSON. */ + if (*d->ptr == '-') d->ptr++; + + if (jsondec_tryparsech(d, '0')) { + if (jsondec_tryskipdigits(d)) { + jsondec_err(d, "number cannot have leading zero"); + } + } else { + jsondec_skipdigits(d); + } + + if (d->ptr == d->end) goto parse; + if (jsondec_tryparsech(d, '.')) { + jsondec_skipdigits(d); + } + if (d->ptr == d->end) goto parse; + + if (*d->ptr == 'e' || *d->ptr == 'E') { + d->ptr++; + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF in number"); + } + if (*d->ptr == '+' || *d->ptr == '-') { + d->ptr++; + } + jsondec_skipdigits(d); + } + +parse: + /* Having verified the syntax of a JSON number, use strtod() to parse + * (strtod() accepts a superset of JSON syntax). */ + errno = 0; + { + // Copy the number into a null-terminated scratch buffer since strtod + // expects a null-terminated string. + char nullz[64]; + ptrdiff_t len = d->ptr - start; + if (len > (ptrdiff_t)(sizeof(nullz) - 1)) { + jsondec_err(d, "excessively long number"); + } + memcpy(nullz, start, len); + nullz[len] = '\0'; + + char* end; + double val = strtod(nullz, &end); + UPB_ASSERT(end - nullz == len); + + /* Currently the min/max-val conformance tests fail if we check this. Does + * this mean the conformance tests are wrong or strtod() is wrong, or + * something else? Investigate further. */ + /* + if (errno == ERANGE) { + jsondec_err(d, "Number out of range"); + } + */ + + if (val > DBL_MAX || val < -DBL_MAX) { + jsondec_err(d, "Number out of range"); + } + + return val; + } +} + +/* JSON string ****************************************************************/ + +static char jsondec_escape(jsondec* d) { + switch (*d->ptr++) { + case '"': + return '\"'; + case '\\': + return '\\'; + case '/': + return '/'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + default: + jsondec_err(d, "Invalid escape char"); + } +} + +static uint32_t jsondec_codepoint(jsondec* d) { + uint32_t cp = 0; + const char* end; + + if (d->end - d->ptr < 4) { + jsondec_err(d, "EOF inside string"); + } + + end = d->ptr + 4; + while (d->ptr < end) { + char ch = *d->ptr++; + if (ch >= '0' && ch <= '9') { + ch -= '0'; + } else if (ch >= 'a' && ch <= 'f') { + ch = ch - 'a' + 10; + } else if (ch >= 'A' && ch <= 'F') { + ch = ch - 'A' + 10; + } else { + jsondec_err(d, "Invalid hex digit"); + } + cp = (cp << 4) | ch; + } + + return cp; +} + +/* Parses a \uXXXX unicode escape (possibly a surrogate pair). */ +static size_t jsondec_unicode(jsondec* d, char* out) { + uint32_t cp = jsondec_codepoint(d); + if (upb_Unicode_IsHigh(cp)) { + /* Surrogate pair: two 16-bit codepoints become a 32-bit codepoint. */ + jsondec_parselit(d, "\\u"); + uint32_t low = jsondec_codepoint(d); + if (!upb_Unicode_IsLow(low)) jsondec_err(d, "Invalid low surrogate"); + cp = upb_Unicode_FromPair(cp, low); + } else if (upb_Unicode_IsLow(cp)) { + jsondec_err(d, "Unpaired low surrogate"); + } + + /* Write to UTF-8 */ + int bytes = upb_Unicode_ToUTF8(cp, out); + if (bytes == 0) jsondec_err(d, "Invalid codepoint"); + return bytes; +} + +static void jsondec_resize(jsondec* d, char** buf, char** end, char** buf_end) { + size_t oldsize = *buf_end - *buf; + size_t len = *end - *buf; + size_t size = UPB_MAX(8, 2 * oldsize); + + *buf = upb_Arena_Realloc(d->arena, *buf, len, size); + if (!*buf) jsondec_err(d, "Out of memory"); + + *end = *buf + len; + *buf_end = *buf + size; +} + +static upb_StringView jsondec_string(jsondec* d) { + char* buf = NULL; + char* end = NULL; + char* buf_end = NULL; + + jsondec_skipws(d); + + if (*d->ptr++ != '"') { + jsondec_err(d, "Expected string"); + } + + while (d->ptr < d->end) { + char ch = *d->ptr++; + + if (end == buf_end) { + jsondec_resize(d, &buf, &end, &buf_end); + } + + switch (ch) { + case '"': { + upb_StringView ret; + ret.data = buf; + ret.size = end - buf; + *end = '\0'; /* Needed for possible strtod(). */ + return ret; + } + case '\\': + if (d->ptr == d->end) goto eof; + if (*d->ptr == 'u') { + d->ptr++; + if (buf_end - end < 4) { + /* Allow space for maximum-sized codepoint (4 bytes). */ + jsondec_resize(d, &buf, &end, &buf_end); + } + end += jsondec_unicode(d, end); + } else { + *end++ = jsondec_escape(d); + } + break; + default: + if ((unsigned char)ch < 0x20) { + jsondec_err(d, "Invalid char in JSON string"); + } + *end++ = ch; + break; + } + } + +eof: + jsondec_err(d, "EOF inside string"); +} + +static void jsondec_skipval(jsondec* d) { + switch (jsondec_peek(d)) { + case JD_OBJECT: + jsondec_objstart(d); + while (jsondec_objnext(d)) { + jsondec_string(d); + jsondec_entrysep(d); + jsondec_skipval(d); + } + jsondec_objend(d); + break; + case JD_ARRAY: + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + jsondec_skipval(d); + } + jsondec_arrend(d); + break; + case JD_TRUE: + jsondec_true(d); + break; + case JD_FALSE: + jsondec_false(d); + break; + case JD_NULL: + jsondec_null(d); + break; + case JD_STRING: + jsondec_string(d); + break; + case JD_NUMBER: + jsondec_number(d); + break; + } +} + +/* Base64 decoding for bytes fields. ******************************************/ + +static unsigned int jsondec_base64_tablelookup(const char ch) { + /* Table includes the normal base64 chars plus the URL-safe variant. */ + const signed char table[256] = { + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, 62 /*+*/, -1, 62 /*-*/, -1, 63 /*/ */, 52 /*0*/, + 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/, + 60 /*8*/, 61 /*9*/, -1, -1, -1, -1, -1, + -1, -1, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/, + 5 /*F*/, 6 /*G*/, 07 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/, + 12 /*M*/, 13 /*N*/, 14 /*O*/, 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/, + 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, 23 /*X*/, 24 /*Y*/, 25 /*Z*/, + -1, -1, -1, -1, 63 /*_*/, -1, 26 /*a*/, + 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, 33 /*h*/, + 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/, + 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/, + 48 /*w*/, 49 /*x*/, 50 /*y*/, 51 /*z*/, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1}; + + /* Sign-extend return value so high bit will be set on any unexpected char. */ + return table[(unsigned)ch]; +} + +static char* jsondec_partialbase64(jsondec* d, const char* ptr, const char* end, + char* out) { + int32_t val = -1; + + switch (end - ptr) { + case 2: + val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12; + out[0] = val >> 16; + out += 1; + break; + case 3: + val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12 | + jsondec_base64_tablelookup(ptr[2]) << 6; + out[0] = val >> 16; + out[1] = (val >> 8) & 0xff; + out += 2; + break; + } + + if (val < 0) { + jsondec_err(d, "Corrupt base64"); + } + + return out; +} + +static size_t jsondec_base64(jsondec* d, upb_StringView str) { + /* We decode in place. This is safe because this is a new buffer (not + * aliasing the input) and because base64 decoding shrinks 4 bytes into 3. */ + char* out = (char*)str.data; + const char* ptr = str.data; + const char* end = ptr + str.size; + const char* end4 = ptr + (str.size & -4); /* Round down to multiple of 4. */ + + for (; ptr < end4; ptr += 4, out += 3) { + int val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12 | + jsondec_base64_tablelookup(ptr[2]) << 6 | + jsondec_base64_tablelookup(ptr[3]) << 0; + + if (val < 0) { + /* Junk chars or padding. Remove trailing padding, if any. */ + if (end - ptr == 4 && ptr[3] == '=') { + if (ptr[2] == '=') { + end -= 2; + } else { + end -= 1; + } + } + break; + } + + out[0] = val >> 16; + out[1] = (val >> 8) & 0xff; + out[2] = val & 0xff; + } + + if (ptr < end) { + /* Process remaining chars. We do not require padding. */ + out = jsondec_partialbase64(d, ptr, end, out); + } + + return out - str.data; +} + +/* Low-level integer parsing **************************************************/ + +static const char* jsondec_buftouint64(jsondec* d, const char* ptr, + const char* end, uint64_t* val) { + const char* out = upb_BufToUint64(ptr, end, val); + if (!out) jsondec_err(d, "Integer overflow"); + return out; +} + +static const char* jsondec_buftoint64(jsondec* d, const char* ptr, + const char* end, int64_t* val, + bool* is_neg) { + const char* out = upb_BufToInt64(ptr, end, val, is_neg); + if (!out) jsondec_err(d, "Integer overflow"); + return out; +} + +static uint64_t jsondec_strtouint64(jsondec* d, upb_StringView str) { + const char* end = str.data + str.size; + uint64_t ret; + if (jsondec_buftouint64(d, str.data, end, &ret) != end) { + jsondec_err(d, "Non-number characters in quoted integer"); + } + return ret; +} + +static int64_t jsondec_strtoint64(jsondec* d, upb_StringView str) { + const char* end = str.data + str.size; + int64_t ret; + if (jsondec_buftoint64(d, str.data, end, &ret, NULL) != end) { + jsondec_err(d, "Non-number characters in quoted integer"); + } + return ret; +} + +static void jsondec_checkempty(jsondec* d, upb_StringView str, + const upb_FieldDef* f) { + if (str.size != 0) return; + d->result = kUpb_JsonDecodeResult_Error; + upb_Status_SetErrorFormat(d->status, + "Empty string is not a valid number (field: %s). " + "This will be an error in a future version.", + upb_FieldDef_FullName(f)); +} + +/* Primitive value types ******************************************************/ + +/* Parse INT32 or INT64 value. */ +static upb_MessageValue jsondec_int(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: { + double dbl = jsondec_number(d); + if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) { + jsondec_err(d, "JSON number is out of range."); + } + val.int64_val = dbl; /* must be guarded, overflow here is UB */ + if (val.int64_val != dbl) { + jsondec_errf(d, "JSON number was not integral (%f != %" PRId64 ")", dbl, + val.int64_val); + } + break; + } + case JD_STRING: { + upb_StringView str = jsondec_string(d); + jsondec_checkempty(d, str, f); + val.int64_val = jsondec_strtoint64(d, str); + break; + } + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_FieldDef_CType(f) == kUpb_CType_Int32 || + upb_FieldDef_CType(f) == kUpb_CType_Enum) { + if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) { + jsondec_err(d, "Integer out of range."); + } + val.int32_val = (int32_t)val.int64_val; + } + + return val; +} + +/* Parse UINT32 or UINT64 value. */ +static upb_MessageValue jsondec_uint(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: { + double dbl = jsondec_number(d); + if (dbl > 18446744073709549568.0 || dbl < 0) { + jsondec_err(d, "JSON number is out of range."); + } + val.uint64_val = dbl; /* must be guarded, overflow here is UB */ + if (val.uint64_val != dbl) { + jsondec_errf(d, "JSON number was not integral (%f != %" PRIu64 ")", dbl, + val.uint64_val); + } + break; + } + case JD_STRING: { + upb_StringView str = jsondec_string(d); + jsondec_checkempty(d, str, f); + val.uint64_val = jsondec_strtouint64(d, str); + break; + } + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_FieldDef_CType(f) == kUpb_CType_UInt32) { + if (val.uint64_val > UINT32_MAX) { + jsondec_err(d, "Integer out of range."); + } + val.uint32_val = (uint32_t)val.uint64_val; + } + + return val; +} + +/* Parse DOUBLE or FLOAT value. */ +static upb_MessageValue jsondec_double(jsondec* d, const upb_FieldDef* f) { + upb_StringView str; + upb_MessageValue val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: + val.double_val = jsondec_number(d); + break; + case JD_STRING: + str = jsondec_string(d); + if (str.size == 0) { + jsondec_checkempty(d, str, f); + val.double_val = 0.0; + } else if (jsondec_streql(str, "NaN")) { + val.double_val = NAN; + } else if (jsondec_streql(str, "Infinity")) { + val.double_val = INFINITY; + } else if (jsondec_streql(str, "-Infinity")) { + val.double_val = -INFINITY; + } else { + char* end; + val.double_val = strtod(str.data, &end); + if (end != str.data + str.size) { + d->result = kUpb_JsonDecodeResult_Error; + upb_Status_SetErrorFormat( + d->status, + "Non-number characters in quoted number (field: %s). " + "This will be an error in a future version.", + upb_FieldDef_FullName(f)); + } + } + break; + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_FieldDef_CType(f) == kUpb_CType_Float) { + float f = val.double_val; + if (val.double_val != INFINITY && val.double_val != -INFINITY) { + if (f == INFINITY || f == -INFINITY) jsondec_err(d, "Float out of range"); + } + val.float_val = f; + } + + return val; +} + +/* Parse STRING or BYTES value. */ +static upb_MessageValue jsondec_strfield(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; + val.str_val = jsondec_string(d); + if (upb_FieldDef_CType(f) == kUpb_CType_Bytes) { + val.str_val.size = jsondec_base64(d, val.str_val); + } + return val; +} + +static upb_JsonMessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) { + switch (jsondec_peek(d)) { + case JD_STRING: { + upb_StringView str = jsondec_string(d); + const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size); + upb_JsonMessageValue val = {.ignore = false}; + if (ev) { + val.value.int32_val = upb_EnumValueDef_Number(ev); + } else { + if (d->options & upb_JsonDecode_IgnoreUnknown) { + val.ignore = true; + } else { + jsondec_errf(d, "Unknown enumerator: '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(str)); + } + } + return val; + } + case JD_NULL: { + if (jsondec_isnullvalue(f)) { + upb_JsonMessageValue val = {.ignore = false}; + jsondec_null(d); + val.value.int32_val = 0; + return val; + } + } + /* Fallthrough. */ + default: + return (upb_JsonMessageValue){.value = jsondec_int(d, f), + .ignore = false}; + } +} + +static upb_MessageValue jsondec_bool(jsondec* d, const upb_FieldDef* f) { + bool is_map_key = upb_FieldDef_Number(f) == 1 && + upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f)); + upb_MessageValue val; + + if (is_map_key) { + upb_StringView str = jsondec_string(d); + if (jsondec_streql(str, "true")) { + val.bool_val = true; + } else if (jsondec_streql(str, "false")) { + val.bool_val = false; + } else { + jsondec_err(d, "Invalid boolean map key"); + } + } else { + switch (jsondec_peek(d)) { + case JD_TRUE: + val.bool_val = true; + jsondec_true(d); + break; + case JD_FALSE: + val.bool_val = false; + jsondec_false(d); + break; + default: + jsondec_err(d, "Expected true or false"); + } + } + + return val; +} + +/* Composite types (array/message/map) ****************************************/ + +static void jsondec_array(jsondec* d, upb_Message* msg, const upb_FieldDef* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Array* arr = upb_Message_Mutable(msg, f, d->arena).array; + + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + upb_JsonMessageValue elem = jsondec_value(d, f); + if (!elem.ignore) { + upb_Array_Append(arr, elem.value, d->arena); + } + } + jsondec_arrend(d); +} + +static void jsondec_map(jsondec* d, upb_Message* msg, const upb_FieldDef* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Map* map = upb_Message_Mutable(msg, f, d->arena).map; + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry, 2); + + jsondec_objstart(d); + while (jsondec_objnext(d)) { + upb_JsonMessageValue key, val; + key = jsondec_value(d, key_f); + UPB_ASSUME(!key.ignore); // Map key cannot be enum. + jsondec_entrysep(d); + val = jsondec_value(d, val_f); + if (!val.ignore) { + upb_Map_Set(map, key.value, val.value, d->arena); + } + } + jsondec_objend(d); +} + +static void jsondec_tomsg(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (upb_MessageDef_WellKnownType(m) == kUpb_WellKnown_Unspecified) { + jsondec_object(d, msg, m); + } else { + jsondec_wellknown(d, msg, m); + } +} + +static upb_MessageValue jsondec_msg(jsondec* d, const upb_FieldDef* f) { + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); + upb_Message* msg = upb_Message_New(layout, d->arena); + upb_MessageValue val; + + jsondec_tomsg(d, msg, m); + val.msg_val = msg; + return val; +} + +static void jsondec_field(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_StringView name; + const upb_FieldDef* f; + const upb_FieldDef* preserved; + + name = jsondec_string(d); + jsondec_entrysep(d); + + if (name.size >= 2 && name.data[0] == '[' && + name.data[name.size - 1] == ']') { + f = upb_DefPool_FindExtensionByNameWithSize(d->symtab, name.data + 1, + name.size - 2); + if (f && upb_FieldDef_ContainingType(f) != m) { + jsondec_errf( + d, "Extension %s extends message %s, but was seen in message %s", + upb_FieldDef_FullName(f), + upb_MessageDef_FullName(upb_FieldDef_ContainingType(f)), + upb_MessageDef_FullName(m)); + } + } else { + f = upb_MessageDef_FindByJsonNameWithSize(m, name.data, name.size); + } + + if (!f) { + if ((d->options & upb_JsonDecode_IgnoreUnknown) == 0) { + jsondec_errf(d, "No such field: " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(name)); + } + jsondec_skipval(d); + return; + } + + if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) { + /* JSON "null" indicates a default value, so no need to set anything. */ + jsondec_null(d); + return; + } + + if (upb_FieldDef_RealContainingOneof(f) && + upb_Message_WhichOneofByDef(msg, upb_FieldDef_ContainingOneof(f))) { + jsondec_err(d, "More than one field for this oneof."); + } + + preserved = d->debug_field; + d->debug_field = f; + + if (upb_FieldDef_IsMap(f)) { + jsondec_map(d, msg, f); + } else if (upb_FieldDef_IsRepeated(f)) { + jsondec_array(d, msg, f); + } else if (upb_FieldDef_IsSubMessage(f)) { + upb_Message* submsg = upb_Message_Mutable(msg, f, d->arena).msg; + const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f); + jsondec_tomsg(d, submsg, subm); + } else { + upb_JsonMessageValue val = jsondec_value(d, f); + if (!val.ignore) { + upb_Message_SetFieldByDef(msg, f, val.value, d->arena); + } + } + + d->debug_field = preserved; +} + +static void jsondec_object(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + jsondec_objstart(d); + while (jsondec_objnext(d)) { + jsondec_field(d, msg, m); + } + jsondec_objend(d); +} + +static upb_MessageValue jsondec_nonenum(jsondec* d, const upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return jsondec_bool(d, f); + case kUpb_CType_Float: + case kUpb_CType_Double: + return jsondec_double(d, f); + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + return jsondec_uint(d, f); + case kUpb_CType_Int32: + case kUpb_CType_Int64: + return jsondec_int(d, f); + case kUpb_CType_String: + case kUpb_CType_Bytes: + return jsondec_strfield(d, f); + case kUpb_CType_Message: + return jsondec_msg(d, f); + case kUpb_CType_Enum: + default: + UPB_UNREACHABLE(); + } +} + +static upb_JsonMessageValue jsondec_value(jsondec* d, const upb_FieldDef* f) { + if (upb_FieldDef_CType(f) == kUpb_CType_Enum) { + return jsondec_enum(d, f); + } else { + return (upb_JsonMessageValue){.value = jsondec_nonenum(d, f), + .ignore = false}; + } +} + +/* Well-known types ***********************************************************/ + +static int jsondec_tsdigits(jsondec* d, const char** ptr, size_t digits, + const char* after) { + uint64_t val; + const char* p = *ptr; + const char* end = p + digits; + size_t after_len = after ? strlen(after) : 0; + + UPB_ASSERT(digits <= 9); /* int can't overflow. */ + + if (jsondec_buftouint64(d, p, end, &val) != end || + (after_len && memcmp(end, after, after_len) != 0)) { + jsondec_err(d, "Malformed timestamp"); + } + + UPB_ASSERT(val < INT_MAX); + + *ptr = end + after_len; + return (int)val; +} + +static int jsondec_nanos(jsondec* d, const char** ptr, const char* end) { + uint64_t nanos = 0; + const char* p = *ptr; + + if (p != end && *p == '.') { + const char* nano_end = jsondec_buftouint64(d, p + 1, end, &nanos); + int digits = (int)(nano_end - p - 1); + int exp_lg10 = 9 - digits; + if (digits > 9) { + jsondec_err(d, "Too many digits for partial seconds"); + } + while (exp_lg10--) nanos *= 10; + *ptr = nano_end; + } + + UPB_ASSERT(nanos < INT_MAX); + + return (int)nanos; +} + +/* jsondec_epochdays(1970, 1, 1) == 1970-01-01 == 0. */ +int jsondec_epochdays(int y, int m, int d) { + const uint32_t year_base = 4800; /* Before min year, multiple of 400. */ + const uint32_t m_adj = m - 3; /* March-based month. */ + const uint32_t carry = m_adj > (uint32_t)m ? 1 : 0; + const uint32_t adjust = carry ? 12 : 0; + const uint32_t y_adj = y + year_base - carry; + const uint32_t month_days = ((m_adj + adjust) * 62719 + 769) / 2048; + const uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400; + return y_adj * 365 + leap_days + month_days + (d - 1) - 2472632; +} + +static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s) { + return (int64_t)jsondec_epochdays(y, m, d) * 86400 + h * 3600 + min * 60 + s; +} + +static void jsondec_timestamp(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_MessageValue seconds; + upb_MessageValue nanos; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; + + if (str.size < 20) goto malformed; + + { + /* 1972-01-01T01:00:00 */ + int year = jsondec_tsdigits(d, &ptr, 4, "-"); + int mon = jsondec_tsdigits(d, &ptr, 2, "-"); + int day = jsondec_tsdigits(d, &ptr, 2, "T"); + int hour = jsondec_tsdigits(d, &ptr, 2, ":"); + int min = jsondec_tsdigits(d, &ptr, 2, ":"); + int sec = jsondec_tsdigits(d, &ptr, 2, NULL); + + seconds.int64_val = jsondec_unixtime(year, mon, day, hour, min, sec); + } + + nanos.int32_val = jsondec_nanos(d, &ptr, end); + + { + /* [+-]08:00 or Z */ + int ofs_hour = 0; + int ofs_min = 0; + bool neg = false; + + if (ptr == end) goto malformed; + + switch (*ptr++) { + case '-': + neg = true; + /* fallthrough */ + case '+': + if ((end - ptr) != 5) goto malformed; + ofs_hour = jsondec_tsdigits(d, &ptr, 2, ":"); + ofs_min = jsondec_tsdigits(d, &ptr, 2, NULL); + ofs_min = ((ofs_hour * 60) + ofs_min) * 60; + seconds.int64_val += (neg ? ofs_min : -ofs_min); + break; + case 'Z': + if (ptr != end) goto malformed; + break; + default: + goto malformed; + } + } + + if (seconds.int64_val < -62135596800) { + jsondec_err(d, "Timestamp out of range"); + } + + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 1), + seconds, d->arena); + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 2), nanos, + d->arena); + return; + +malformed: + jsondec_err(d, "Malformed timestamp"); +} + +static void jsondec_duration(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_MessageValue seconds; + upb_MessageValue nanos; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; + const int64_t max = (uint64_t)3652500 * 86400; + bool neg = false; + + /* "3.000000001s", "3s", etc. */ + ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val, &neg); + nanos.int32_val = jsondec_nanos(d, &ptr, end); + + if (end - ptr != 1 || *ptr != 's') { + jsondec_err(d, "Malformed duration"); + } + + if (seconds.int64_val < -max || seconds.int64_val > max) { + jsondec_err(d, "Duration out of range"); + } + + if (neg) { + nanos.int32_val = -nanos.int32_val; + } + + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 1), + seconds, d->arena); + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 2), nanos, + d->arena); +} + +static void jsondec_listvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(values_f); + const upb_MiniTable* value_layout = upb_MessageDef_MiniTable(value_m); + upb_Array* values = upb_Message_Mutable(msg, values_f, d->arena).array; + + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + upb_Message* value_msg = upb_Message_New(value_layout, d->arena); + upb_MessageValue value; + value.msg_val = value_msg; + upb_Array_Append(values, value, d->arena); + jsondec_wellknownvalue(d, value_msg, value_m); + } + jsondec_arrend(d); +} + +static void jsondec_struct(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(value_f); + const upb_MiniTable* value_layout = upb_MessageDef_MiniTable(value_m); + upb_Map* fields = upb_Message_Mutable(msg, fields_f, d->arena).map; + + jsondec_objstart(d); + while (jsondec_objnext(d)) { + upb_MessageValue key, value; + upb_Message* value_msg = upb_Message_New(value_layout, d->arena); + key.str_val = jsondec_string(d); + value.msg_val = value_msg; + upb_Map_Set(fields, key, value, d->arena); + jsondec_entrysep(d); + jsondec_wellknownvalue(d, value_msg, value_m); + } + jsondec_objend(d); +} + +static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_MessageValue val; + const upb_FieldDef* f; + upb_Message* submsg; + + switch (jsondec_peek(d)) { + case JD_NUMBER: + /* double number_value = 2; */ + f = upb_MessageDef_FindFieldByNumber(m, 2); + val.double_val = jsondec_number(d); + break; + case JD_STRING: + /* string string_value = 3; */ + f = upb_MessageDef_FindFieldByNumber(m, 3); + val.str_val = jsondec_string(d); + break; + case JD_FALSE: + /* bool bool_value = 4; */ + f = upb_MessageDef_FindFieldByNumber(m, 4); + val.bool_val = false; + jsondec_false(d); + break; + case JD_TRUE: + /* bool bool_value = 4; */ + f = upb_MessageDef_FindFieldByNumber(m, 4); + val.bool_val = true; + jsondec_true(d); + break; + case JD_NULL: + /* NullValue null_value = 1; */ + f = upb_MessageDef_FindFieldByNumber(m, 1); + val.int32_val = 0; + jsondec_null(d); + break; + /* Note: these cases return, because upb_Message_Mutable() is enough. */ + case JD_OBJECT: + /* Struct struct_value = 5; */ + f = upb_MessageDef_FindFieldByNumber(m, 5); + submsg = upb_Message_Mutable(msg, f, d->arena).msg; + jsondec_struct(d, submsg, upb_FieldDef_MessageSubDef(f)); + return; + case JD_ARRAY: + /* ListValue list_value = 6; */ + f = upb_MessageDef_FindFieldByNumber(m, 6); + submsg = upb_Message_Mutable(msg, f, d->arena).msg; + jsondec_listvalue(d, submsg, upb_FieldDef_MessageSubDef(f)); + return; + default: + UPB_UNREACHABLE(); + } + + upb_Message_SetFieldByDef(msg, f, val, d->arena); +} + +static upb_StringView jsondec_mask(jsondec* d, const char* buf, + const char* end) { + /* FieldMask fields grow due to inserted '_' characters, so we can't do the + * transform in place. */ + const char* ptr = buf; + upb_StringView ret; + char* out; + + ret.size = end - ptr; + while (ptr < end) { + ret.size += (*ptr >= 'A' && *ptr <= 'Z'); + ptr++; + } + + out = upb_Arena_Malloc(d->arena, ret.size); + ptr = buf; + ret.data = out; + + while (ptr < end) { + char ch = *ptr++; + if (ch >= 'A' && ch <= 'Z') { + *out++ = '_'; + *out++ = ch + 32; + } else if (ch == '_') { + jsondec_err(d, "field mask may not contain '_'"); + } else { + *out++ = ch; + } + } + + return ret; +} + +static void jsondec_fieldmask(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + /* repeated string paths = 1; */ + const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_Array* arr = upb_Message_Mutable(msg, paths_f, d->arena).array; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; + upb_MessageValue val; + + while (ptr < end) { + const char* elem_end = memchr(ptr, ',', end - ptr); + if (elem_end) { + val.str_val = jsondec_mask(d, ptr, elem_end); + ptr = elem_end + 1; + } else { + val.str_val = jsondec_mask(d, ptr, end); + ptr = end; + } + upb_Array_Append(arr, val, d->arena); + } +} + +static void jsondec_anyfield(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (upb_MessageDef_WellKnownType(m) == kUpb_WellKnown_Unspecified) { + /* For regular types: {"@type": "[user type]", "f1": , "f2": } + * where f1, f2, etc. are the normal fields of this type. */ + jsondec_field(d, msg, m); + } else { + /* For well-known types: {"@type": "[well-known type]", "value": } + * where is whatever encoding the WKT normally uses. */ + upb_StringView str = jsondec_string(d); + jsondec_entrysep(d); + if (!jsondec_streql(str, "value")) { + jsondec_err(d, "Key for well-known type must be 'value'"); + } + jsondec_wellknown(d, msg, m); + } +} + +static const upb_MessageDef* jsondec_typeurl(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* type_url_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* type_m; + upb_StringView type_url = jsondec_string(d); + const char* end = type_url.data + type_url.size; + const char* ptr = end; + upb_MessageValue val; + + val.str_val = type_url; + upb_Message_SetFieldByDef(msg, type_url_f, val, d->arena); + + /* Find message name after the last '/' */ + while (ptr > type_url.data && *--ptr != '/') { + } + + if (ptr == type_url.data || ptr == end) { + jsondec_err(d, "Type url must have at least one '/' and non-empty host"); + } + + ptr++; + type_m = upb_DefPool_FindMessageByNameWithSize(d->symtab, ptr, end - ptr); + + if (!type_m) { + jsondec_err(d, "Type was not found"); + } + + return type_m; +} + +static void jsondec_any(jsondec* d, upb_Message* msg, const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + /* string type_url = 1; + * bytes value = 2; */ + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 2); + upb_Message* any_msg; + const upb_MessageDef* any_m = NULL; + const char* pre_type_data = NULL; + const char* pre_type_end = NULL; + upb_MessageValue encoded; + + jsondec_objstart(d); + + /* Scan looking for "@type", which is not necessarily first. */ + while (!any_m && jsondec_objnext(d)) { + const char* start = d->ptr; + upb_StringView name = jsondec_string(d); + jsondec_entrysep(d); + if (jsondec_streql(name, "@type")) { + any_m = jsondec_typeurl(d, msg, m); + if (pre_type_data) { + pre_type_end = start; + while (*pre_type_end != ',') pre_type_end--; + } + } else { + if (!pre_type_data) pre_type_data = start; + jsondec_skipval(d); + } + } + + if (!any_m) { + jsondec_err(d, "Any object didn't contain a '@type' field"); + } + + const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m); + any_msg = upb_Message_New(any_layout, d->arena); + + if (pre_type_data) { + size_t len = pre_type_end - pre_type_data + 1; + char* tmp = upb_Arena_Malloc(d->arena, len); + const char* saved_ptr = d->ptr; + const char* saved_end = d->end; + memcpy(tmp, pre_type_data, len - 1); + tmp[len - 1] = '}'; + d->ptr = tmp; + d->end = tmp + len; + d->is_first = true; + while (jsondec_objnext(d)) { + jsondec_anyfield(d, any_msg, any_m); + } + d->ptr = saved_ptr; + d->end = saved_end; + } + + while (jsondec_objnext(d)) { + jsondec_anyfield(d, any_msg, any_m); + } + + jsondec_objend(d); + + upb_EncodeStatus status = + upb_Encode(any_msg, upb_MessageDef_MiniTable(any_m), 0, d->arena, + (char**)&encoded.str_val.data, &encoded.str_val.size); + // TODO: We should fail gracefully here on a bad return status. + UPB_ASSERT(status == kUpb_EncodeStatus_Ok); + upb_Message_SetFieldByDef(msg, value_f, encoded, d->arena); +} + +static void jsondec_wrapper(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_JsonMessageValue val = jsondec_value(d, value_f); + UPB_ASSUME(val.ignore == false); // Wrapper cannot be an enum. + upb_Message_SetFieldByDef(msg, value_f, val.value, d->arena); +} + +static void jsondec_wellknown(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Any: + jsondec_any(d, msg, m); + break; + case kUpb_WellKnown_FieldMask: + jsondec_fieldmask(d, msg, m); + break; + case kUpb_WellKnown_Duration: + jsondec_duration(d, msg, m); + break; + case kUpb_WellKnown_Timestamp: + jsondec_timestamp(d, msg, m); + break; + case kUpb_WellKnown_Value: + jsondec_wellknownvalue(d, msg, m); + break; + case kUpb_WellKnown_ListValue: + jsondec_listvalue(d, msg, m); + break; + case kUpb_WellKnown_Struct: + jsondec_struct(d, msg, m); + break; + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: + jsondec_wrapper(d, msg, m); + break; + default: + UPB_UNREACHABLE(); + } +} + +static int upb_JsonDecoder_Decode(jsondec* const d, upb_Message* const msg, + const upb_MessageDef* const m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (UPB_SETJMP(d->err)) return kUpb_JsonDecodeResult_Error; + + jsondec_tomsg(d, msg, m); + + // Consume any trailing whitespace before checking if we read the entire + // input. + jsondec_consumews(d); + + if (d->ptr == d->end) { + return d->result; + } else { + jsondec_seterrmsg(d, "unexpected trailing characters"); + return kUpb_JsonDecodeResult_Error; + } +} + +int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size, + upb_Message* msg, + const upb_MessageDef* m, + const upb_DefPool* symtab, + int options, upb_Arena* arena, + upb_Status* status) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + jsondec d; + + if (size == 0) return true; + + d.ptr = buf; + d.end = buf + size; + d.arena = arena; + d.symtab = symtab; + d.status = status; + d.options = options; + d.depth = 64; + d.result = kUpb_JsonDecodeResult_Ok; + d.line = 1; + d.line_begin = d.ptr; + d.debug_field = NULL; + d.is_first = false; + + return upb_JsonDecoder_Decode(&d, msg, m); +} + + +#include +#include +#include +#include +#include +#include + + +// Must be last. + +typedef struct { + char *buf, *ptr, *end; + size_t overflow; + int indent_depth; + int options; + const upb_DefPool* ext_pool; + jmp_buf err; + upb_Status* status; + upb_Arena* arena; +} jsonenc; + +static void jsonenc_msg(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); +static void jsonenc_scalar(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f); +static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); +static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m, bool first); +static void jsonenc_value(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); + +UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) { + upb_Status_SetErrorMessage(e->status, msg); + UPB_LONGJMP(e->err, 1); +} + +UPB_PRINTF(2, 3) +UPB_NORETURN static void jsonenc_errf(jsonenc* e, const char* fmt, ...) { + va_list argp; + va_start(argp, fmt); + upb_Status_VSetErrorFormat(e->status, fmt, argp); + va_end(argp); + UPB_LONGJMP(e->err, 1); +} + +static upb_Arena* jsonenc_arena(jsonenc* e) { + /* Create lazily, since it's only needed for Any */ + if (!e->arena) { + e->arena = upb_Arena_New(); + } + return e->arena; +} + +static void jsonenc_putbytes(jsonenc* e, const void* data, size_t len) { + size_t have = e->end - e->ptr; + if (UPB_LIKELY(have >= len)) { + memcpy(e->ptr, data, len); + e->ptr += len; + } else { + if (have) { + memcpy(e->ptr, data, have); + e->ptr += have; + } + e->overflow += (len - have); + } +} + +static void jsonenc_putstr(jsonenc* e, const char* str) { + jsonenc_putbytes(e, str, strlen(str)); +} + +UPB_PRINTF(2, 3) +static void jsonenc_printf(jsonenc* e, const char* fmt, ...) { + size_t n; + size_t have = e->end - e->ptr; + va_list args; + + va_start(args, fmt); + n = _upb_vsnprintf(e->ptr, have, fmt, args); + va_end(args); + + if (UPB_LIKELY(have > n)) { + e->ptr += n; + } else { + e->ptr = UPB_PTRADD(e->ptr, have); + e->overflow += (n - have); + } +} + +static void jsonenc_nanos(jsonenc* e, int32_t nanos) { + int digits = 9; + + if (nanos == 0) return; + if (nanos < 0 || nanos >= 1000000000) { + jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos"); + } + + while (nanos % 1000 == 0) { + nanos /= 1000; + digits -= 3; + } + + jsonenc_printf(e, ".%.*" PRId32, digits, nanos); +} + +static void jsonenc_timestamp(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2); + int64_t seconds = upb_Message_GetFieldByDef(msg, seconds_f).int64_val; + int32_t nanos = upb_Message_GetFieldByDef(msg, nanos_f).int32_val; + int L, N, I, J, K, hour, min, sec; + + if (seconds < -62135596800) { + jsonenc_err(e, + "error formatting timestamp as JSON: minimum acceptable value " + "is 0001-01-01T00:00:00Z"); + } else if (seconds > 253402300799) { + jsonenc_err(e, + "error formatting timestamp as JSON: maximum acceptable value " + "is 9999-12-31T23:59:59Z"); + } + + /* Julian Day -> Y/M/D, Algorithm from: + * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for + * Processing Calendar Dates," Communications of the Association of + * Computing Machines, vol. 11 (1968), p. 657. */ + seconds += 62135596800; // Ensure seconds is positive. + L = (int)(seconds / 86400) - 719162 + 68569 + 2440588; + N = 4 * L / 146097; + L = L - (146097 * N + 3) / 4; + I = 4000 * (L + 1) / 1461001; + L = L - 1461 * I / 4 + 31; + J = 80 * L / 2447; + K = L - 2447 * J / 80; + L = J / 11; + J = J + 2 - 12 * L; + I = 100 * (N - 49) + I + L; + + sec = seconds % 60; + min = (seconds / 60) % 60; + hour = (seconds / 3600) % 24; + + jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec); + jsonenc_nanos(e, nanos); + jsonenc_putstr(e, "Z\""); +} + +static void jsonenc_duration(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2); + int64_t seconds = upb_Message_GetFieldByDef(msg, seconds_f).int64_val; + int32_t nanos = upb_Message_GetFieldByDef(msg, nanos_f).int32_val; + bool negative = false; + + if (seconds > 315576000000 || seconds < -315576000000 || + (seconds != 0 && nanos != 0 && (seconds < 0) != (nanos < 0))) { + jsonenc_err(e, "bad duration"); + } + + if (seconds < 0) { + negative = true; + seconds = -seconds; + } + if (nanos < 0) { + negative = true; + nanos = -nanos; + } + + jsonenc_putstr(e, "\""); + if (negative) { + jsonenc_putstr(e, "-"); + } + jsonenc_printf(e, "%" PRId64, seconds); + jsonenc_nanos(e, nanos); + jsonenc_putstr(e, "s\""); +} + +static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) { + const upb_EnumDef* e_def = upb_FieldDef_EnumSubDef(f); + + if (strcmp(upb_EnumDef_FullName(e_def), "google.protobuf.NullValue") == 0) { + jsonenc_putstr(e, "null"); + } else { + const upb_EnumValueDef* ev = + (e->options & upb_JsonEncode_FormatEnumsAsIntegers) + ? NULL + : upb_EnumDef_FindValueByNumber(e_def, val); + + if (ev) { + jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev)); + } else { + jsonenc_printf(e, "%" PRId32, val); + } + } +} + +static void jsonenc_bytes(jsonenc* e, upb_StringView str) { + /* This is the regular base64, not the "web-safe" version. */ + static const char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + const unsigned char* ptr = (unsigned char*)str.data; + const unsigned char* end = UPB_PTRADD(ptr, str.size); + char buf[4]; + + jsonenc_putstr(e, "\""); + + while (end - ptr >= 3) { + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)]; + buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)]; + buf[3] = base64[ptr[2] & 0x3f]; + jsonenc_putbytes(e, buf, 4); + ptr += 3; + } + + switch (end - ptr) { + case 2: + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)]; + buf[2] = base64[(ptr[1] & 0xf) << 2]; + buf[3] = '='; + jsonenc_putbytes(e, buf, 4); + break; + case 1: + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4)]; + buf[2] = '='; + buf[3] = '='; + jsonenc_putbytes(e, buf, 4); + break; + } + + jsonenc_putstr(e, "\""); +} + +static void jsonenc_stringbody(jsonenc* e, upb_StringView str) { + const char* ptr = str.data; + const char* end = UPB_PTRADD(ptr, str.size); + + while (ptr < end) { + switch (*ptr) { + case '\n': + jsonenc_putstr(e, "\\n"); + break; + case '\r': + jsonenc_putstr(e, "\\r"); + break; + case '\t': + jsonenc_putstr(e, "\\t"); + break; + case '\"': + jsonenc_putstr(e, "\\\""); + break; + case '\f': + jsonenc_putstr(e, "\\f"); + break; + case '\b': + jsonenc_putstr(e, "\\b"); + break; + case '\\': + jsonenc_putstr(e, "\\\\"); + break; + default: + if ((uint8_t)*ptr < 0x20) { + jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr); + } else { + /* This could be a non-ASCII byte. We rely on the string being valid + * UTF-8. */ + jsonenc_putbytes(e, ptr, 1); + } + break; + } + ptr++; + } +} + +static void jsonenc_string(jsonenc* e, upb_StringView str) { + jsonenc_putstr(e, "\""); + jsonenc_stringbody(e, str); + jsonenc_putstr(e, "\""); +} + +static bool upb_JsonEncode_HandleSpecialDoubles(jsonenc* e, double val) { + if (val == INFINITY) { + jsonenc_putstr(e, "\"Infinity\""); + } else if (val == -INFINITY) { + jsonenc_putstr(e, "\"-Infinity\""); + } else if (val != val) { + jsonenc_putstr(e, "\"NaN\""); + } else { + return false; + } + return true; +} + +static void upb_JsonEncode_Double(jsonenc* e, double val) { + if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return; + char buf[32]; + _upb_EncodeRoundTripDouble(val, buf, sizeof(buf)); + jsonenc_putstr(e, buf); +} + +static void upb_JsonEncode_Float(jsonenc* e, float val) { + if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return; + char buf[32]; + _upb_EncodeRoundTripFloat(val, buf, sizeof(buf)); + jsonenc_putstr(e, buf); +} + +static void jsonenc_wrapper(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_MessageValue val = upb_Message_GetFieldByDef(msg, val_f); + jsonenc_scalar(e, val, val_f); +} + +static const upb_MessageDef* jsonenc_getanymsg(jsonenc* e, + upb_StringView type_url) { + /* Find last '/', if any. */ + const char* end = type_url.data + type_url.size; + const char* ptr = end; + const upb_MessageDef* ret; + + if (!e->ext_pool) { + jsonenc_err(e, "Tried to encode Any, but no symtab was provided"); + } + + if (type_url.size == 0) goto badurl; + + while (true) { + if (--ptr == type_url.data) { + /* Type URL must contain at least one '/', with host before. */ + goto badurl; + } + if (*ptr == '/') { + ptr++; + break; + } + } + + ret = upb_DefPool_FindMessageByNameWithSize(e->ext_pool, ptr, end - ptr); + + if (!ret) { + jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr); + } + + return ret; + +badurl: + jsonenc_errf(e, "Bad type URL: " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(type_url)); +} + +static void jsonenc_any(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* type_url_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 2); + upb_StringView type_url = upb_Message_GetFieldByDef(msg, type_url_f).str_val; + upb_StringView value = upb_Message_GetFieldByDef(msg, value_f).str_val; + const upb_MessageDef* any_m = jsonenc_getanymsg(e, type_url); + const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m); + upb_Arena* arena = jsonenc_arena(e); + upb_Message* any = upb_Message_New(any_layout, arena); + + if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + jsonenc_err(e, "Error decoding message in Any"); + } + + jsonenc_putstr(e, "{\"@type\":"); + jsonenc_string(e, type_url); + + if (upb_MessageDef_WellKnownType(any_m) == kUpb_WellKnown_Unspecified) { + /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */ + jsonenc_msgfields(e, any, any_m, false); + } else { + /* Well-known type: {"@type": "...","value": } */ + jsonenc_putstr(e, ",\"value\":"); + jsonenc_msgfield(e, any, any_m); + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_putsep(jsonenc* e, const char* str, bool* first) { + if (*first) { + *first = false; + } else { + jsonenc_putstr(e, str); + } +} + +static void jsonenc_fieldpath(jsonenc* e, upb_StringView path) { + const char* ptr = path.data; + const char* end = ptr + path.size; + + while (ptr < end) { + char ch = *ptr; + + if (ch >= 'A' && ch <= 'Z') { + jsonenc_err(e, "Field mask element may not have upper-case letter."); + } else if (ch == '_') { + if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') { + jsonenc_err(e, "Underscore must be followed by a lowercase letter."); + } + ch = *++ptr - 32; + } + + jsonenc_putbytes(e, &ch, 1); + ptr++; + } +} + +static void jsonenc_fieldmask(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_Array* paths = upb_Message_GetFieldByDef(msg, paths_f).array_val; + bool first = true; + size_t i, n = 0; + + if (paths) n = upb_Array_Size(paths); + + jsonenc_putstr(e, "\""); + + for (i = 0; i < n; i++) { + jsonenc_putsep(e, ",", &first); + jsonenc_fieldpath(e, upb_Array_Get(paths, i).str_val); + } + + jsonenc_putstr(e, "\""); +} + +static void jsonenc_struct(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + jsonenc_putstr(e, "{"); + + const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_Map* fields = upb_Message_GetFieldByDef(msg, fields_f).map_val; + + if (fields) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + + size_t iter = kUpb_Map_Begin; + bool first = true; + + upb_MessageValue key, val; + while (upb_Map_Next(fields, &key, &val, &iter)) { + jsonenc_putsep(e, ",", &first); + jsonenc_string(e, key.str_val); + jsonenc_putstr(e, ":"); + jsonenc_value(e, val.msg_val, upb_FieldDef_MessageSubDef(value_f)); + } + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_listvalue(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* values_m = upb_FieldDef_MessageSubDef(values_f); + const upb_Array* values = upb_Message_GetFieldByDef(msg, values_f).array_val; + size_t i; + bool first = true; + + jsonenc_putstr(e, "["); + + if (values) { + const size_t size = upb_Array_Size(values); + for (i = 0; i < size; i++) { + upb_MessageValue elem = upb_Array_Get(values, i); + + jsonenc_putsep(e, ",", &first); + jsonenc_value(e, elem.msg_val, values_m); + } + } + + jsonenc_putstr(e, "]"); +} + +static void jsonenc_value(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + /* TODO: do we want a reflection method to get oneof case? */ + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; + + if (!upb_Message_Next(msg, m, NULL, &f, &val, &iter)) { + jsonenc_err(e, "No value set in Value proto"); + } + + switch (upb_FieldDef_Number(f)) { + case 1: + jsonenc_putstr(e, "null"); + break; + case 2: + if (upb_JsonEncode_HandleSpecialDoubles(e, val.double_val)) { + jsonenc_err( + e, + "google.protobuf.Value cannot encode double values for " + "infinity or nan, because they would be parsed as a string"); + } + upb_JsonEncode_Double(e, val.double_val); + break; + case 3: + jsonenc_string(e, val.str_val); + break; + case 4: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case 5: + jsonenc_struct(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); + break; + case 6: + jsonenc_listvalue(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); + break; + } +} + +static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Unspecified: + jsonenc_msg(e, msg, m); + break; + case kUpb_WellKnown_Any: + jsonenc_any(e, msg, m); + break; + case kUpb_WellKnown_FieldMask: + jsonenc_fieldmask(e, msg, m); + break; + case kUpb_WellKnown_Duration: + jsonenc_duration(e, msg, m); + break; + case kUpb_WellKnown_Timestamp: + jsonenc_timestamp(e, msg, m); + break; + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: + jsonenc_wrapper(e, msg, m); + break; + case kUpb_WellKnown_Value: + jsonenc_value(e, msg, m); + break; + case kUpb_WellKnown_ListValue: + jsonenc_listvalue(e, msg, m); + break; + case kUpb_WellKnown_Struct: + jsonenc_struct(e, msg, m); + break; + } +} + +static void jsonenc_scalar(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case kUpb_CType_Float: + upb_JsonEncode_Float(e, val.float_val); + break; + case kUpb_CType_Double: + upb_JsonEncode_Double(e, val.double_val); + break; + case kUpb_CType_Int32: + jsonenc_printf(e, "%" PRId32, val.int32_val); + break; + case kUpb_CType_UInt32: + jsonenc_printf(e, "%" PRIu32, val.uint32_val); + break; + case kUpb_CType_Int64: + jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val); + break; + case kUpb_CType_UInt64: + jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val); + break; + case kUpb_CType_String: + jsonenc_string(e, val.str_val); + break; + case kUpb_CType_Bytes: + jsonenc_bytes(e, val.str_val); + break; + case kUpb_CType_Enum: + jsonenc_enum(val.int32_val, f, e); + break; + case kUpb_CType_Message: + jsonenc_msgfield(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); + break; + } +} + +static void jsonenc_mapkey(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f) { + jsonenc_putstr(e, "\""); + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case kUpb_CType_Int32: + jsonenc_printf(e, "%" PRId32, val.int32_val); + break; + case kUpb_CType_UInt32: + jsonenc_printf(e, "%" PRIu32, val.uint32_val); + break; + case kUpb_CType_Int64: + jsonenc_printf(e, "%" PRId64, val.int64_val); + break; + case kUpb_CType_UInt64: + jsonenc_printf(e, "%" PRIu64, val.uint64_val); + break; + case kUpb_CType_String: + jsonenc_stringbody(e, val.str_val); + break; + default: + UPB_UNREACHABLE(); + } + + jsonenc_putstr(e, "\":"); +} + +static void jsonenc_array(jsonenc* e, const upb_Array* arr, + const upb_FieldDef* f) { + size_t i; + size_t size = arr ? upb_Array_Size(arr) : 0; + bool first = true; + + jsonenc_putstr(e, "["); + + for (i = 0; i < size; i++) { + jsonenc_putsep(e, ",", &first); + jsonenc_scalar(e, upb_Array_Get(arr, i), f); + } + + jsonenc_putstr(e, "]"); +} + +static void jsonenc_map(jsonenc* e, const upb_Map* map, const upb_FieldDef* f) { + jsonenc_putstr(e, "{"); + + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry, 2); + + if (map) { + size_t iter = kUpb_Map_Begin; + bool first = true; + + upb_MessageValue key, val; + while (upb_Map_Next(map, &key, &val, &iter)) { + jsonenc_putsep(e, ",", &first); + jsonenc_mapkey(e, key, key_f); + jsonenc_scalar(e, val, val_f); + } + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_fieldval(jsonenc* e, const upb_FieldDef* f, + upb_MessageValue val, bool* first) { + const char* name; + + jsonenc_putsep(e, ",", first); + + if (upb_FieldDef_IsExtension(f)) { + // TODO: For MessageSet, I would have expected this to print the message + // name here, but Python doesn't appear to do this. We should do more + // research here about what various implementations do. + jsonenc_printf(e, "\"[%s]\":", upb_FieldDef_FullName(f)); + } else { + if (e->options & upb_JsonEncode_UseProtoNames) { + name = upb_FieldDef_Name(f); + } else { + name = upb_FieldDef_JsonName(f); + } + jsonenc_printf(e, "\"%s\":", name); + } + + if (upb_FieldDef_IsMap(f)) { + jsonenc_map(e, val.map_val, f); + } else if (upb_FieldDef_IsRepeated(f)) { + jsonenc_array(e, val.array_val, f); + } else { + jsonenc_scalar(e, val, f); + } +} + +static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m, bool first) { + upb_MessageValue val; + const upb_FieldDef* f; + + if (e->options & upb_JsonEncode_EmitDefaults) { + /* Iterate over all fields. */ + int i = 0; + int n = upb_MessageDef_FieldCount(m); + for (i = 0; i < n; i++) { + f = upb_MessageDef_Field(m, i); + if (!upb_FieldDef_HasPresence(f) || upb_Message_HasFieldByDef(msg, f)) { + jsonenc_fieldval(e, f, upb_Message_GetFieldByDef(msg, f), &first); + } + } + } else { + /* Iterate over non-empty fields. */ + size_t iter = kUpb_Message_Begin; + while (upb_Message_Next(msg, m, e->ext_pool, &f, &val, &iter)) { + jsonenc_fieldval(e, f, val, &first); + } + } +} + +static void jsonenc_msg(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + jsonenc_putstr(e, "{"); + jsonenc_msgfields(e, msg, m, true); + jsonenc_putstr(e, "}"); +} + +static size_t jsonenc_nullz(jsonenc* e, size_t size) { + size_t ret = e->ptr - e->buf + e->overflow; + + if (size > 0) { + if (e->ptr == e->end) e->ptr--; + *e->ptr = '\0'; + } + + return ret; +} + +static size_t upb_JsonEncoder_Encode(jsonenc* const e, + const upb_Message* const msg, + const upb_MessageDef* const m, + const size_t size) { + if (UPB_SETJMP(e->err) != 0) return -1; + + jsonenc_msgfield(e, msg, m); + if (e->arena) upb_Arena_Free(e->arena); + return jsonenc_nullz(e, size); +} + +size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, char* buf, + size_t size, upb_Status* status) { + jsonenc e; + + e.buf = buf; + e.ptr = buf; + e.end = UPB_PTRADD(buf, size); + e.overflow = 0; + e.options = options; + e.ext_pool = ext_pool; + e.status = status; + e.arena = NULL; + + return upb_JsonEncoder_Encode(&e, msg, m, size); +} + + +// Must be last. + +const char* upb_BufToUint64(const char* ptr, const char* end, uint64_t* val) { + uint64_t u64 = 0; + while (ptr < end) { + unsigned ch = *ptr - '0'; + if (ch >= 10) break; + if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) { + return NULL; // integer overflow + } + u64 *= 10; + u64 += ch; + ptr++; + } + + *val = u64; + return ptr; +} + +const char* upb_BufToInt64(const char* ptr, const char* end, int64_t* val, + bool* is_neg) { + bool neg = false; + uint64_t u64; + + if (ptr != end && *ptr == '-') { + ptr++; + neg = true; + } + + ptr = upb_BufToUint64(ptr, end, &u64); + if (!ptr || u64 > (uint64_t)INT64_MAX + neg) { + return NULL; // integer overflow + } + + *val = neg ? -u64 : u64; + if (is_neg) *is_neg = neg; + return ptr; +} + + +#include +#include +#include +#include + +// Must be last. + +/* Miscellaneous utilities ****************************************************/ + +static void upb_FixLocale(char* p) { + /* printf() is dependent on locales; sadly there is no easy and portable way + * to avoid this. This little post-processing step will translate 1,2 -> 1.2 + * since JSON needs the latter. Arguably a hack, but it is simple and the + * alternatives are far more complicated, platform-dependent, and/or larger + * in code size. */ + for (; *p; p++) { + if (*p == ',') *p = '.'; + } +} + +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + if (isnan(val)) { + snprintf(buf, size, "%s", "nan"); + return; + } + snprintf(buf, size, "%.*g", DBL_DIG, val); + if (strtod(buf, NULL) != val) { + snprintf(buf, size, "%.*g", DBL_DIG + 2, val); + assert(strtod(buf, NULL) == val); + } + upb_FixLocale(buf); +} + +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + if (isnan(val)) { + snprintf(buf, size, "%s", "nan"); + return; + } + snprintf(buf, size, "%.*g", FLT_DIG, val); + if (strtof(buf, NULL) != val) { + snprintf(buf, size, "%.*g", FLT_DIG + 3, val); + assert(strtof(buf, NULL) == val); + } + upb_FixLocale(buf); +} + + +#include +#include + +// Must be last. + +// Determine the locale-specific radix character by calling sprintf() to print +// the number 1.5, then stripping off the digits. As far as I can tell, this +// is the only portable, thread-safe way to get the C library to divulge the +// locale's radix character. No, localeconv() is NOT thread-safe. + +static int GetLocaleRadix(char *data, size_t capacity) { + char temp[16]; + const int size = snprintf(temp, sizeof(temp), "%.1f", 1.5); + UPB_ASSERT(temp[0] == '1'); + UPB_ASSERT(temp[size - 1] == '5'); + if (size < capacity) { + return 0; + } + temp[size - 1] = '\0'; + strncpy(data, temp + 1, size); + return size - 2; +} + +// Populates a string identical to *input except that the character pointed to +// by pos (which should be '.') is replaced with the locale-specific radix. + +static void LocalizeRadix(const char *input, const char *pos, char *output, + int output_size) { + const int len1 = pos - input; + + char radix[8]; + const int len2 = GetLocaleRadix(radix, sizeof(radix)); + + const int n = output_size - len1 - len2 - 1; + if (n < 0) { + return; + } + + memcpy(output, input, len1); + memcpy(output + len1, radix, len2); + strncpy(output + len1 + len2, input + len1 + 1, n); + output[output_size - 1] = '\0'; +} + +double _upb_NoLocaleStrtod(const char *str, char **endptr) { + // We cannot simply set the locale to "C" temporarily with setlocale() + // as this is not thread-safe. Instead, we try to parse in the current + // locale first. If parsing stops at a '.' character, then this is a + // pretty good hint that we're actually in some other locale in which + // '.' is not the radix character. + + char *temp_endptr; + double result = strtod(str, &temp_endptr); + if (endptr != NULL) *endptr = temp_endptr; + if (*temp_endptr != '.') return result; + + // Parsing halted on a '.'. Perhaps we're in a different locale? Let's + // try to replace the '.' with a locale-specific radix character and + // try again. + + char localized[80]; + LocalizeRadix(str, temp_endptr, localized, sizeof localized); + char *localized_endptr; + result = strtod(localized, &localized_endptr); + if ((localized_endptr - &localized[0]) > (temp_endptr - str)) { + // This attempt got further, so replacing the decimal must have helped. + // Update endptr to point at the right location. + if (endptr != NULL) { + // size_diff is non-zero if the localized radix has multiple bytes. + int size_diff = strlen(localized) - strlen(str); + *endptr = (char *)str + (localized_endptr - &localized[0] - size_diff); + } + } + + return result; +} + + +// Must be last. + +int upb_Unicode_ToUTF8(uint32_t cp, char* out) { + if (cp <= 0x7f) { + out[0] = cp; + return 1; + } + if (cp <= 0x07ff) { + out[0] = (cp >> 6) | 0xc0; + out[1] = (cp & 0x3f) | 0x80; + return 2; + } + if (cp <= 0xffff) { + out[0] = (cp >> 12) | 0xe0; + out[1] = ((cp >> 6) & 0x3f) | 0x80; + out[2] = (cp & 0x3f) | 0x80; + return 3; + } + if (cp <= 0x10ffff) { + out[0] = (cp >> 18) | 0xf0; + out[1] = ((cp >> 12) & 0x3f) | 0x80; + out[2] = ((cp >> 6) & 0x3f) | 0x80; + out[3] = (cp & 0x3f) | 0x80; + return 4; + } + return 0; +} + + +#include + +// Must be last. + +static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, + size_t size, size_t* actual_size) { + UPB_UNUSED(alloc); + UPB_UNUSED(oldsize); + UPB_UNUSED(actual_size); + if (size == 0) { + free(ptr); + return NULL; + } else { + return realloc(ptr, size); + } +} + +upb_alloc upb_alloc_global = {&upb_global_allocfunc}; + + +#include + + +#ifdef UPB_TRACING_ENABLED +#include +#endif + +#include +#include + + +// Must be last. + +static UPB_ATOMIC(size_t) g_max_block_size = UPB_DEFAULT_MAX_BLOCK_SIZE; + +void upb_Arena_SetMaxBlockSize(size_t max) { + UPB_ASSERT(max <= UINT32_MAX); + upb_Atomic_Store(&g_max_block_size, max, memory_order_relaxed); +} + +typedef struct upb_MemBlock { + struct upb_MemBlock* next; + // Size of the actual allocation. + // Size of 0 means this is a upb_ArenaRef. + size_t size; + // Data follows. +} upb_MemBlock; + +// A special block type that indicates a reference to another arena. +// When this arena is freed, a ref is released on the referenced arena. +// size must be 0. +typedef struct upb_ArenaRef { + upb_MemBlock prefix; // size is always zero + const upb_Arena* arena; +#ifndef NDEBUG + const struct upb_ArenaRef* next_ref; +#endif +} upb_ArenaRef; + +typedef struct upb_ArenaInternal { + // upb_alloc* together with a low bit which signals if there is an initial + // block. + uintptr_t block_alloc; + + // Linked list of blocks to free/cleanup. + upb_MemBlock* blocks; + +#ifndef NDEBUG + // Stack of pointers to other arenas that this arena owns. + // Used for debug-only ref cycle checks. + UPB_ATOMIC(const upb_ArenaRef*) refs; +#endif + + // Size of the last block we allocated in the normal exponential scheme. + uint32_t last_block_size; + + // A hint that grows whenever we perform a "one-off" allocation into a a + // dedicated block. This helps us determine if these outlier blocks are + // actually common enough that we should switch back to the normal exponential + // scheme at the larger size. + uint32_t size_hint; + + // All non atomic members used during allocation must be above this point, and + // are used by _SwapIn/_SwapOut + + // Total space allocated in blocks, atomic only for SpaceAllocated + UPB_ATOMIC(uintptr_t) space_allocated; + + // The cleanup for the allocator. This is called after all the blocks are + // freed in an arena. + upb_AllocCleanupFunc* upb_alloc_cleanup; + + // When multiple arenas are fused together, each arena points to a parent + // arena (root points to itself). The root tracks how many live arenas + // reference it. + + // The low bit is tagged: + // 0: pointer to parent + // 1: count, left shifted by one + UPB_ATOMIC(uintptr_t) parent_or_count; + + // All nodes that are fused together are in a singly-linked list. + // == NULL at end of list. + UPB_ATOMIC(struct upb_ArenaInternal*) next; + + // - If the low bit is set, is a pointer to the tail of the list (populated + // for roots, set to self for roots with no fused arenas). This is best + // effort, and it may not always reflect the true tail, but it will always + // be a valid node in the list. This is useful for finding the list tail + // without having to walk the entire list. + // - If the low bit is not set, is a pointer to the previous node in the list, + // such that a->previous_or_tail->next == a. + UPB_ATOMIC(uintptr_t) previous_or_tail; + + // We use a different UPB_XSAN_MEMBER than the one in upb_Arena because the + // two are distinct synchronization domains. The upb_Arena.ptr member is + // not published in the allocation path, so it is not synchronized with + // respect to operations performed in this file such as Fuse, Free, + // SpaceAllocated, etc. This means that it is not safe to read or write + // the upb_Arena.ptr member in those functions. + UPB_XSAN_MEMBER +} upb_ArenaInternal; + +// All public + private state for an arena. +typedef struct { + upb_Arena head; + upb_ArenaInternal body; +} upb_ArenaState; + +typedef struct { + upb_ArenaInternal* root; + uintptr_t tagged_count; +} upb_ArenaRoot; + +static const size_t kUpb_MemblockReserve = + UPB_ALIGN_MALLOC(sizeof(upb_MemBlock)); + +static const size_t kUpb_ArenaRefReserve = + UPB_ALIGN_MALLOC(sizeof(upb_ArenaRef)); + +// Extracts the (upb_ArenaInternal*) from a (upb_Arena*) +static upb_ArenaInternal* upb_Arena_Internal(const upb_Arena* a) { + return &((upb_ArenaState*)a)->body; +} + +static bool _upb_Arena_IsTaggedRefcount(uintptr_t parent_or_count) { + return (parent_or_count & 1) == 1; +} + +static bool _upb_Arena_IsTaggedPointer(uintptr_t parent_or_count) { + return (parent_or_count & 1) == 0; +} + +static uintptr_t _upb_Arena_RefCountFromTagged(uintptr_t parent_or_count) { + UPB_ASSERT(_upb_Arena_IsTaggedRefcount(parent_or_count)); + return parent_or_count >> 1; +} + +static uintptr_t _upb_Arena_TaggedFromRefcount(uintptr_t refcount) { + uintptr_t parent_or_count = (refcount << 1) | 1; + UPB_ASSERT(_upb_Arena_IsTaggedRefcount(parent_or_count)); + return parent_or_count; +} + +static upb_ArenaInternal* _upb_Arena_PointerFromTagged( + uintptr_t parent_or_count) { + UPB_ASSERT(_upb_Arena_IsTaggedPointer(parent_or_count)); + return (upb_ArenaInternal*)parent_or_count; +} + +static uintptr_t _upb_Arena_TaggedFromPointer(upb_ArenaInternal* ai) { + uintptr_t parent_or_count = (uintptr_t)ai; + UPB_ASSERT(_upb_Arena_IsTaggedPointer(parent_or_count)); + return parent_or_count; +} + +static bool _upb_Arena_IsTaggedTail(uintptr_t previous_or_tail) { + return (previous_or_tail & 1) == 1; +} + +static bool _upb_Arena_IsTaggedPrevious(uintptr_t previous_or_tail) { + return (previous_or_tail & 1) == 0; +} + +static upb_ArenaInternal* _upb_Arena_TailFromTagged( + uintptr_t previous_or_tail) { + UPB_ASSERT(_upb_Arena_IsTaggedTail(previous_or_tail)); + return (upb_ArenaInternal*)(previous_or_tail ^ 1); +} + +static uintptr_t _upb_Arena_TaggedFromTail(upb_ArenaInternal* tail) { + uintptr_t previous_or_tail = (uintptr_t)tail | 1; + UPB_ASSERT(_upb_Arena_IsTaggedTail(previous_or_tail)); + return previous_or_tail; +} + +static upb_ArenaInternal* _upb_Arena_PreviousFromTagged( + uintptr_t previous_or_tail) { + UPB_ASSERT(_upb_Arena_IsTaggedPrevious(previous_or_tail)); + return (upb_ArenaInternal*)previous_or_tail; +} + +static uintptr_t _upb_Arena_TaggedFromPrevious(upb_ArenaInternal* ai) { + uintptr_t previous = (uintptr_t)ai; + UPB_ASSERT(_upb_Arena_IsTaggedPrevious(previous)); + return previous; +} + +static upb_alloc* _upb_ArenaInternal_BlockAlloc(upb_ArenaInternal* ai) { + return (upb_alloc*)(ai->block_alloc & ~0x1); +} + +static uintptr_t _upb_Arena_MakeBlockAlloc(upb_alloc* alloc, bool has_initial) { + uintptr_t alloc_uint = (uintptr_t)alloc; + UPB_ASSERT((alloc_uint & 1) == 0); + return alloc_uint | (has_initial ? 1 : 0); +} + +static bool _upb_ArenaInternal_HasInitialBlock(upb_ArenaInternal* ai) { + return ai->block_alloc & 0x1; +} + +#ifdef UPB_TRACING_ENABLED +static void (*_init_arena_trace_handler)(const upb_Arena*, size_t size) = NULL; +static void (*_fuse_arena_trace_handler)(const upb_Arena*, + const upb_Arena*) = NULL; +static void (*_free_arena_trace_handler)(const upb_Arena*) = NULL; + +void upb_Arena_SetTraceHandler( + void (*initArenaTraceHandler)(const upb_Arena*, size_t size), + void (*fuseArenaTraceHandler)(const upb_Arena*, const upb_Arena*), + void (*freeArenaTraceHandler)(const upb_Arena*)) { + _init_arena_trace_handler = initArenaTraceHandler; + _fuse_arena_trace_handler = fuseArenaTraceHandler; + _free_arena_trace_handler = freeArenaTraceHandler; +} + +void upb_Arena_LogInit(const upb_Arena* arena, size_t size) { + if (_init_arena_trace_handler) { + _init_arena_trace_handler(arena, size); + } +} +void upb_Arena_LogFuse(const upb_Arena* arena1, const upb_Arena* arena2) { + if (_fuse_arena_trace_handler) { + _fuse_arena_trace_handler(arena1, arena2); + } +} +void upb_Arena_LogFree(const upb_Arena* arena) { + if (_free_arena_trace_handler) { + _free_arena_trace_handler(arena); + } +} +#endif // UPB_TRACING_ENABLED + +// If the param a is already the root, provides no memory order of refcount. +// If it has a parent, then acquire memory order is provided for both the root +// and the refcount. Thread safe. +static upb_ArenaRoot _upb_Arena_FindRoot(upb_ArenaInternal* ai) { + uintptr_t poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_relaxed); + if (_upb_Arena_IsTaggedRefcount(poc)) { + // Fast, relaxed path - arenas that have never been fused to a parent only + // need relaxed memory order, since they're returning themselves and the + // refcount. + return (upb_ArenaRoot){.root = ai, .tagged_count = poc}; + } + // Slow path needs acquire order; reloading is cheaper than a fence on ARM + // (LDA vs DMB ISH). Even though this is a reread, we know it must be a tagged + // pointer because if this Arena isn't a root, it can't ever become one. + poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_acquire); + do { + upb_ArenaInternal* next = _upb_Arena_PointerFromTagged(poc); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(next)); + UPB_ASSERT(ai != next); + poc = upb_Atomic_Load(&next->parent_or_count, memory_order_acquire); + + if (_upb_Arena_IsTaggedPointer(poc)) { + // To keep complexity down, we lazily collapse levels of the tree. This + // keeps it flat in the final case, but doesn't cost much incrementally. + // + // Path splitting keeps time complexity down, see: + // https://en.wikipedia.org/wiki/Disjoint-set_data_structure + UPB_ASSERT(ai != _upb_Arena_PointerFromTagged(poc)); + upb_Atomic_Store(&ai->parent_or_count, poc, memory_order_release); + } + ai = next; + } while (_upb_Arena_IsTaggedPointer(poc)); + return (upb_ArenaRoot){.root = ai, .tagged_count = poc}; +} + +uintptr_t upb_Arena_SpaceAllocated(const upb_Arena* arena, + size_t* fused_count) { + upb_ArenaInternal* ai = upb_Arena_Internal(arena); + uintptr_t memsize = 0; + size_t local_fused_count = 0; + // Our root would get updated by any racing fuses before our target arena + // became reachable from the root via the linked list; in order to preserve + // monotonic output (any arena counted by a previous invocation is counted by + // this one), we instead iterate forwards and backwards so that we only see + // the results of completed fuses. + uintptr_t previous_or_tail = + upb_Atomic_Load(&ai->previous_or_tail, memory_order_acquire); + while (_upb_Arena_IsTaggedPrevious(previous_or_tail)) { + upb_ArenaInternal* previous = + _upb_Arena_PreviousFromTagged(previous_or_tail); + UPB_ASSERT(previous != ai); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(previous)); + // Unfortunate macro behavior; prior to C11 when using nonstandard atomics + // this returns a void* and can't be used with += without an intermediate + // conversion to an integer. + // Relaxed is safe - no subsequent reads depend this one + uintptr_t allocated = + upb_Atomic_Load(&previous->space_allocated, memory_order_relaxed); + memsize += allocated; + previous_or_tail = + upb_Atomic_Load(&previous->previous_or_tail, memory_order_acquire); + local_fused_count++; + } + while (ai != NULL) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(ai)); + // Unfortunate macro behavior; prior to C11 when using nonstandard atomics + // this returns a void* and can't be used with += without an intermediate + // conversion to an integer. + // Relaxed is safe - no subsequent reads depend this one + uintptr_t allocated = + upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed); + memsize += allocated; + ai = upb_Atomic_Load(&ai->next, memory_order_acquire); + local_fused_count++; + } + + if (fused_count) *fused_count = local_fused_count; + return memsize; +} + +uint32_t upb_Arena_DebugRefCount(const upb_Arena* a) { + uintptr_t tagged = _upb_Arena_FindRoot(upb_Arena_Internal(a)).tagged_count; + return (uint32_t)_upb_Arena_RefCountFromTagged(tagged); +} + +#if UPB_ENABLE_REF_CYCLE_CHECKS + +bool upb_Arena_HasRefChain(const upb_Arena* from, const upb_Arena* to) { + upb_ArenaInternal* ai = upb_Arena_Internal(from); + upb_ArenaInternal* current; + + if (upb_Arena_IsFused(from, to)) return true; + + // 1. Traverse backward to the start of a consistent segment. + uintptr_t previous_or_tail = + upb_Atomic_Load(&ai->previous_or_tail, memory_order_acquire); + while (_upb_Arena_IsTaggedPrevious(previous_or_tail)) { + ai = _upb_Arena_PreviousFromTagged(previous_or_tail); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(ai)); + previous_or_tail = + upb_Atomic_Load(&ai->previous_or_tail, memory_order_acquire); + } + + // 2. Traverse forward through all arenas in the fuse group. + current = ai; + while (current != NULL) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(current)); + const upb_ArenaRef* ref = + upb_Atomic_Load(¤t->refs, memory_order_acquire); + while (ref != NULL) { + if (ref->arena == to || upb_Arena_HasRefChain(ref->arena, to)) { + return true; + } + ref = ref->next_ref; + } + current = upb_Atomic_Load(¤t->next, memory_order_acquire); + } + return false; +} + +#endif + +static upb_MemBlock* _upb_Arena_AllocBlockInternal(upb_alloc* alloc, + size_t size) { + UPB_ASSERT(size >= kUpb_MemblockReserve); + upb_SizedPtr alloc_result = upb_SizeReturningMalloc(alloc, size); + if (!alloc_result.p) return NULL; + upb_MemBlock* block = alloc_result.p; + block->size = alloc_result.n; + return block; +} + +static upb_MemBlock* _upb_Arena_AllocBlock(upb_Arena* a, size_t size) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + return _upb_Arena_AllocBlockInternal(_upb_ArenaInternal_BlockAlloc(ai), size); +} + +static void _upb_Arena_AddBlock(upb_Arena* a, upb_MemBlock* block) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + + // Atomic add not required here, as threads won't race allocating blocks, plus + // atomic fetch-add is slower than load/add/store on arm devices compiled + // targeting pre-v8.1. Relaxed order is safe as nothing depends on order of + // size allocated. + uintptr_t old_space_allocated = + upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed); + upb_Atomic_Store(&ai->space_allocated, old_space_allocated + block->size, + memory_order_relaxed); + + block->next = ai->blocks; + ai->blocks = block; +} + +static void _upb_Arena_UseBlockInternal(upb_Arena* a, upb_MemBlock* block, + size_t offset) { + size_t block_size = block->size; + char* start = UPB_PTR_AT(block, kUpb_MemblockReserve + offset, char); + a->UPB_PRIVATE(ptr) = start; + a->UPB_PRIVATE(end) = UPB_PTR_AT(block, block_size, char); + UPB_PRIVATE(upb_Xsan_PoisonRegion)(start, a->UPB_PRIVATE(end) - start); + UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(a)); + UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= + block_size - kUpb_MemblockReserve - offset); +} + +static void _upb_Arena_UseBlock(upb_Arena* a, upb_MemBlock* block) { + _upb_Arena_UseBlockInternal(a, block, 0); +} + +static bool _upb_Arena_WouldReduceFreeSpace(upb_Arena* a, size_t size, + size_t block_size) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + size_t current_free = + ai->blocks ? a->UPB_PRIVATE(end) - a->UPB_PRIVATE(ptr) : 0; + size_t future_free = block_size - kUpb_MemblockReserve - size; + return current_free >= future_free; +} + +// Fulfills the allocation request by allocating a new block. Returns NULL on +// allocation failure. +void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(upb_Arena* a, size_t size) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + if (!ai->block_alloc) return NULL; + + // Whether to satisfy the allocation from a one-off block which is right-sized + // for the current allocation. We do this if we suspect that the current + // allocation is an outlier that does not represent the typical size of + // allocations from this arena, or if we would reduce free space by + // using exponential growth. + bool one_off = false; + + // Relaxed order is safe here as we don't need any ordering with the setter. + size_t max_block_size = + upb_Atomic_Load(&g_max_block_size, memory_order_relaxed); + size_t block_size = UPB_MIN(ai->last_block_size * 2, max_block_size); + + if (size + kUpb_MemblockReserve > block_size) { + // A regular doubling would not yield a large enough block. Does size_hint + // indicate that we have consistently needed large blocks? + block_size = UPB_MIN(ai->size_hint * 2, max_block_size); + if (size + kUpb_MemblockReserve > block_size) { + // Even size_hint is not large enough, we will have to do a one-off. + one_off = true; + } + } + + // If switching to a block of this size would *reduce* available free space, + // we might as well make a one-off block instead. + one_off = one_off || _upb_Arena_WouldReduceFreeSpace(a, size, block_size); + + if (one_off) { + // Note: this may exceed the max block size, but that's okay. + block_size = size + kUpb_MemblockReserve; + } + + upb_MemBlock* block = _upb_Arena_AllocBlock(a, block_size); + if (!block) return NULL; + + _upb_Arena_AddBlock(a, block); + + // Recheck size, in case the allocator gave us a much larger block than we + // requested and we want to make it the new allocating region. + if (UPB_UNLIKELY(one_off) && + _upb_Arena_WouldReduceFreeSpace(a, size, block->size)) { + // Increase size_hint, so that a series of one-off allocations will + // eventually convince us to switch to exponential growth at the larger + // size. + ai->size_hint = UPB_MIN(ai->size_hint + (size >> 1), max_block_size >> 1); + char* allocated = UPB_PTR_AT(block, kUpb_MemblockReserve, char); + char* poison_start = allocated + size - UPB_PRIVATE(kUpb_Asan_GuardSize); + UPB_PRIVATE(upb_Xsan_PoisonRegion)( + poison_start, UPB_PTR_AT(block, block->size, char) - poison_start); + return allocated; + } else { + ai->last_block_size = UPB_MIN(block->size, UINT32_MAX); + ai->size_hint = ai->last_block_size; + _upb_Arena_UseBlock(a, block); + UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= size); + return upb_Arena_Malloc(a, size - UPB_PRIVATE(kUpb_Asan_GuardSize)); + } +} + +static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) { + const size_t first_block_overhead = + UPB_ALIGN_MALLOC(kUpb_MemblockReserve + sizeof(upb_ArenaState)); + upb_ArenaState* a; + + if (!alloc) return NULL; + + // We need to malloc the initial block. + size_t block_size = + first_block_overhead + UPB_MAX(256, UPB_ALIGN_MALLOC(first_size) + + UPB_PRIVATE(kUpb_Asan_GuardSize)); + upb_MemBlock* block = _upb_Arena_AllocBlockInternal(alloc, block_size); + if (!block) return NULL; + + // Initialize the arena state in the first block. We "borrow" the memory from + // the block, because we can't yet call upb_Arena_Malloc. + a = UPB_PTR_AT(block, kUpb_MemblockReserve, upb_ArenaState); + a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 0); + a->body.last_block_size = UPB_MIN(block->size, UINT32_MAX); + a->body.size_hint = UPB_MIN(block->size, UINT32_MAX); + upb_Atomic_Init(&a->body.parent_or_count, _upb_Arena_TaggedFromRefcount(1)); + upb_Atomic_Init(&a->body.next, NULL); + upb_Atomic_Init(&a->body.previous_or_tail, + _upb_Arena_TaggedFromTail(&a->body)); + upb_Atomic_Init(&a->body.space_allocated, 0); + a->body.blocks = NULL; +#ifndef NDEBUG + a->body.refs = NULL; +#endif + a->body.upb_alloc_cleanup = NULL; + UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body)); + + _upb_Arena_AddBlock(&a->head, block); + _upb_Arena_UseBlockInternal(&a->head, block, + UPB_ALIGN_MALLOC(sizeof(upb_ArenaState))); + + return &a->head; +} + +upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) { + UPB_STATIC_ASSERT(UPB_ARENA_SIZE_HACK >= sizeof(upb_ArenaState), + "Need to update UPB_ARENA_SIZE_HACK"); + upb_ArenaState* a; + + if (mem) { + /* Align initial pointer up so that we return properly-aligned pointers. */ + void* aligned = (void*)UPB_ALIGN_MALLOC((uintptr_t)mem); + size_t delta = (uintptr_t)aligned - (uintptr_t)mem; + n = delta <= n ? n - delta : 0; + mem = aligned; + } + if (UPB_UNLIKELY(n < sizeof(upb_ArenaState) || !mem)) { + upb_Arena* ret = _upb_Arena_InitSlow(alloc, mem ? 0 : n); +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogInit(ret, n); +#endif + return ret; + } + + a = mem; + + upb_Atomic_Init(&a->body.parent_or_count, _upb_Arena_TaggedFromRefcount(1)); + upb_Atomic_Init(&a->body.next, NULL); + upb_Atomic_Init(&a->body.previous_or_tail, + _upb_Arena_TaggedFromTail(&a->body)); + upb_Atomic_Init(&a->body.space_allocated, 0); + a->body.blocks = NULL; +#ifndef NDEBUG + a->body.refs = NULL; +#endif + a->body.size_hint = 128; + a->body.last_block_size = 128; + a->body.upb_alloc_cleanup = NULL; + a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 1); + a->head.UPB_PRIVATE(ptr) = (void*)UPB_ALIGN_MALLOC((uintptr_t)(a + 1)); + a->head.UPB_PRIVATE(end) = UPB_PTR_AT(mem, n, char); + UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body)); +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogInit(&a->head, n); +#endif + return &a->head; +} + +static void _upb_Arena_DoFree(upb_ArenaInternal* ai) { + UPB_ASSERT(_upb_Arena_RefCountFromTagged(ai->parent_or_count) == 1); + while (ai != NULL) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(ai)); + // Load first since arena itself is likely from one of its blocks. Relaxed + // order is safe because fused arena ordering is provided by the reference + // count, and fuse is not permitted to race with the final decrement. + upb_ArenaInternal* next_arena = + (upb_ArenaInternal*)upb_Atomic_Load(&ai->next, memory_order_relaxed); + // Freeing may have memory barriers that confuse tsan, so assert immediately + // after load here + if (next_arena) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(next_arena)); + } + upb_alloc* block_alloc = _upb_ArenaInternal_BlockAlloc(ai); + upb_MemBlock* block = ai->blocks; + upb_AllocCleanupFunc* alloc_cleanup = *ai->upb_alloc_cleanup; + while (block != NULL) { + // Load first since we are deleting block. + upb_MemBlock* next_block = block->next; + if (block->size == 0) { + // If the block is an arena ref, then we need to release our ref on the + // referenced arena. + upb_ArenaRef* ref = (upb_ArenaRef*)block; + upb_Arena_DecRefFor((upb_Arena*)ref->arena, ai); + } else { + upb_free_sized(block_alloc, block, block->size); + } + block = next_block; + } + if (alloc_cleanup != NULL) { + alloc_cleanup(block_alloc); + } + ai = next_arena; + } +} + +void upb_Arena_Free(upb_Arena* a) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + // Cannot be replaced with _upb_Arena_FindRoot, as that provides only a + // relaxed read of the refcount if ai is already the root. + uintptr_t poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_acquire); +retry: + while (_upb_Arena_IsTaggedPointer(poc)) { + ai = _upb_Arena_PointerFromTagged(poc); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(ai)); + poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_acquire); + } + + // compare_exchange or fetch_sub are RMW operations, which are more + // expensive then direct loads. As an optimization, we only do RMW ops + // when we need to update things for other threads to see. + if (poc == _upb_Arena_TaggedFromRefcount(1)) { +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogFree(a); +#endif + _upb_Arena_DoFree(ai); + return; + } + + if (upb_Atomic_CompareExchangeWeak( + &ai->parent_or_count, &poc, + _upb_Arena_TaggedFromRefcount(_upb_Arena_RefCountFromTagged(poc) - 1), + memory_order_release, memory_order_acquire)) { + // We were >1 and we decremented it successfully, so we are done. + return; + } + + // We failed our update, so someone has done something, retry the whole + // process, but the failed exchange reloaded `poc` for us. + goto retry; +} + +// Logically performs the following operation, in a way that is safe against +// racing fuses: +// ret = TAIL(parent) +// ret->next = child +// return ret +// +// The caller is therefore guaranteed that ret->next == child. +static upb_ArenaInternal* _upb_Arena_LinkForward( + upb_ArenaInternal* const parent, upb_ArenaInternal* child) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(parent)); + uintptr_t parent_previous_or_tail = + upb_Atomic_Load(&parent->previous_or_tail, memory_order_acquire); + + // Optimization: use parent->previous_or_tail to skip to TAIL(parent) in O(1) + // time when possible. This is the common case because we just fused into + // parent, suggesting that it should be a root with a cached tail. + // + // However, if there was a racing fuse, parent may no longer be a root, in + // which case we need to walk the entire list to find the tail. The tail + // pointer is also not guaranteed to be the true tail, so even when the + // optimization is taken, we still need to walk list nodes to find the true + // tail. + upb_ArenaInternal* parent_tail = + _upb_Arena_IsTaggedTail(parent_previous_or_tail) + ? _upb_Arena_TailFromTagged(parent_previous_or_tail) + : parent; + + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(parent_tail)); + upb_ArenaInternal* parent_tail_next = + upb_Atomic_Load(&parent_tail->next, memory_order_acquire); + + do { + // Walk the list to find the true tail (a node with next == NULL). + while (parent_tail_next != NULL) { + parent_tail = parent_tail_next; + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(parent_tail)); + parent_tail_next = + upb_Atomic_Load(&parent_tail->next, memory_order_acquire); + } + } while (!upb_Atomic_CompareExchangeWeak( // Replace a NULL next with child. + &parent_tail->next, &parent_tail_next, child, memory_order_release, + memory_order_acquire)); + + return parent_tail; +} + +// Updates parent->previous_or_tail = child->previous_or_tail in hopes that the +// latter represents the true tail of the newly-combined list. +// +// This is a best-effort operation that may set the tail to a stale value, and +// may fail to update the tail at all. +void _upb_Arena_UpdateParentTail(upb_ArenaInternal* parent, + upb_ArenaInternal* child) { + // We are guaranteed that child->previous_or_tail is tagged, because we have + // just transitioned child from root -> non-root, which is an exclusive + // operation that can only happen once. So we are the exclusive updater of + // child->previous_or_tail that can transition it from tagged to untagged. + // + // However, we are not guaranteed that child->previous_or_tail is the true + // tail. A racing fuse may have appended to child's list but not yet updated + // child->previous_or_tail. + uintptr_t child_previous_or_tail = + upb_Atomic_Load(&child->previous_or_tail, memory_order_acquire); + upb_ArenaInternal* new_parent_tail = + _upb_Arena_TailFromTagged(child_previous_or_tail); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(new_parent_tail)); + + // If another thread fused with parent, such that it is no longer a root, + // don't overwrite their previous pointer with our tail. Relaxed order is fine + // here as we only inspect the tag bit. + uintptr_t parent_previous_or_tail = + upb_Atomic_Load(&parent->previous_or_tail, memory_order_relaxed); + if (_upb_Arena_IsTaggedTail(parent_previous_or_tail)) { + upb_Atomic_CompareExchangeStrong( + &parent->previous_or_tail, &parent_previous_or_tail, + _upb_Arena_TaggedFromTail(new_parent_tail), memory_order_release, + memory_order_relaxed); + } +} + +static void _upb_Arena_LinkBackward(upb_ArenaInternal* child, + upb_ArenaInternal* old_parent_tail) { + // Link child to parent going backwards, for SpaceAllocated. This transitions + // child->previous_or_tail from tail (tagged) to previous (untagged), after + // which its value is immutable. + // + // - We are guaranteed that no other threads are also attempting to perform + // this transition (tail -> previous), because we just updated + // old_parent_tail->next from NULL to non-NULL, an exclusive operation that + // can only happen once. + // + // - _upb_Arena_UpdateParentTail() uses CAS to ensure that it + // does not perform the reverse transition (previous -> tail). + // + // - We are guaranteed that old_parent_tail is the correct "previous" pointer, + // even in the presence of racing fuses that are adding more nodes to the + // list, because _upb_Arena_LinkForward() guarantees that: + // old_parent_tail->next == child. + upb_Atomic_Store(&child->previous_or_tail, + _upb_Arena_TaggedFromPrevious(old_parent_tail), + memory_order_release); +} + +static void _upb_Arena_DoFuseArenaLists(upb_ArenaInternal* const parent, + upb_ArenaInternal* child) { + upb_ArenaInternal* old_parent_tail = _upb_Arena_LinkForward(parent, child); + _upb_Arena_UpdateParentTail(parent, child); + _upb_Arena_LinkBackward(child, old_parent_tail); +} + +void upb_Arena_SetAllocCleanup(upb_Arena* a, upb_AllocCleanupFunc* func) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + upb_ArenaInternal* ai = upb_Arena_Internal(a); + UPB_ASSERT(ai->upb_alloc_cleanup == NULL); + ai->upb_alloc_cleanup = func; +} + +// Thread safe. +static upb_ArenaInternal* _upb_Arena_DoFuse(upb_ArenaInternal** ai1, + upb_ArenaInternal** ai2, + uintptr_t* ref_delta) { + // `parent_or_count` has two distinct modes + // - parent pointer mode + // - refcount mode + // + // In parent pointer mode, it may change what pointer it refers to in the + // tree, but it will always approach a root. Any operation that walks the + // tree to the root may collapse levels of the tree concurrently. + upb_ArenaRoot r1 = _upb_Arena_FindRoot(*ai1); + upb_ArenaRoot r2 = _upb_Arena_FindRoot(*ai2); + + if (r1.root == r2.root) return r1.root; // Already fused. + + *ai1 = r1.root; + *ai2 = r2.root; + + // Avoid cycles by always fusing into the root with the lower address. + if ((uintptr_t)r1.root > (uintptr_t)r2.root) { + upb_ArenaRoot tmp = r1; + r1 = r2; + r2 = tmp; + } + + // The moment we install `r1` as the parent for `r2` all racing frees may + // immediately begin decrementing `r1`'s refcount (including pending + // increments to that refcount and their frees!). We need to add `r2`'s refs + // now, so that `r1` can withstand any unrefs that come from r2. + // + // Note that while it is possible for `r2`'s refcount to increase + // asynchronously, we will not actually do the reparenting operation below + // unless `r2`'s refcount is unchanged from when we read it. + // + // Note that we may have done this previously, either to this node or a + // different node, during a previous and failed DoFuse() attempt. But we will + // not lose track of these refs because we always add them to our overall + // delta. + uintptr_t r2_untagged_count = r2.tagged_count & ~1; + uintptr_t with_r2_refs = r1.tagged_count + r2_untagged_count; + if (!upb_Atomic_CompareExchangeStrong( + &r1.root->parent_or_count, &r1.tagged_count, with_r2_refs, + memory_order_release, memory_order_acquire)) { + return NULL; + } + + // Perform the actual fuse by removing the refs from `r2` and swapping in the + // parent pointer. + if (!upb_Atomic_CompareExchangeStrong( + &r2.root->parent_or_count, &r2.tagged_count, + _upb_Arena_TaggedFromPointer(r1.root), memory_order_release, + memory_order_acquire)) { + // We'll need to remove the excess refs we added to r1 previously. + *ref_delta += r2_untagged_count; + return NULL; + } + + // Now that the fuse has been performed (and can no longer fail) we need to + // append `r2` to `r1`'s linked list. + _upb_Arena_DoFuseArenaLists(r1.root, r2.root); + return r1.root; +} + +// Thread safe. +static bool _upb_Arena_FixupRefs(upb_ArenaInternal* new_root, + uintptr_t ref_delta) { + if (ref_delta == 0) return true; // No fixup required. + // Relaxed order is safe here as if the value is a pointer, we don't deref it + // or publish it anywhere else. The refcount does provide memory order + // between allocations on arenas and the eventual free and thus normally + // requires acquire/release; but in this case any edges provided by the refs + // we are cleaning up were already provided by the fuse operation itself. It's + // not valid for a decrement that could cause the overall fused arena to reach + // a zero refcount to race with this function, as that could result in a + // use-after-free anyway. + uintptr_t poc = + upb_Atomic_Load(&new_root->parent_or_count, memory_order_relaxed); + if (_upb_Arena_IsTaggedPointer(poc)) return false; + uintptr_t with_refs = poc - ref_delta; + UPB_ASSERT(!_upb_Arena_IsTaggedPointer(with_refs)); + // Relaxed order on success is safe here, for the same reasons as the relaxed + // read above. Relaxed order is safe on failure because the updated value is + // stored in a local variable which goes immediately out of scope; the retry + // loop will reread what it needs with proper memory order. + return upb_Atomic_CompareExchangeStrong(&new_root->parent_or_count, &poc, + with_refs, memory_order_relaxed, + memory_order_relaxed); +} + +bool upb_Arena_Fuse(const upb_Arena* a1, const upb_Arena* a2) { + if (a1 == a2) return true; // trivial fuse + +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogFuse(a1, a2); +#endif + + upb_ArenaInternal* ai1 = upb_Arena_Internal(a1); + upb_ArenaInternal* ai2 = upb_Arena_Internal(a2); + + // Do not fuse initial blocks since we cannot lifetime extend them. + // Any other fuse scenario is allowed. + if (_upb_ArenaInternal_HasInitialBlock(ai1) || + _upb_ArenaInternal_HasInitialBlock(ai2)) { + return false; + } + + // The number of refs we ultimately need to transfer to the new root. + uintptr_t ref_delta = 0; + while (true) { + upb_ArenaInternal* new_root = _upb_Arena_DoFuse(&ai1, &ai2, &ref_delta); + if (new_root != NULL && _upb_Arena_FixupRefs(new_root, ref_delta)) { +#if UPB_ENABLE_REF_CYCLE_CHECKS + UPB_ASSERT(!upb_Arena_HasRefChain(a1, a2)); +#endif + return true; + } + } +} + +bool upb_Arena_IsFused(const upb_Arena* a, const upb_Arena* b) { + if (a == b) return true; // trivial fuse + upb_ArenaInternal* ra = _upb_Arena_FindRoot(upb_Arena_Internal(a)).root; + upb_ArenaInternal* rb = upb_Arena_Internal(b); + while (true) { + rb = _upb_Arena_FindRoot(rb).root; + if (ra == rb) return true; + upb_ArenaInternal* tmp = _upb_Arena_FindRoot(ra).root; + if (ra == tmp) return false; + // a's root changed since we last checked. Retry. + ra = tmp; + } +} + +bool upb_Arena_IncRefFor(const upb_Arena* a, const void* owner) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + if (_upb_ArenaInternal_HasInitialBlock(ai)) return false; + upb_ArenaRoot r; + r.root = ai; + +retry: + r = _upb_Arena_FindRoot(r.root); + if (upb_Atomic_CompareExchangeWeak( + &r.root->parent_or_count, &r.tagged_count, + _upb_Arena_TaggedFromRefcount( + _upb_Arena_RefCountFromTagged(r.tagged_count) + 1), + // Relaxed order is safe on success, incrementing the refcount + // need not perform any synchronization with the eventual free of the + // arena - that's provided by decrements. + memory_order_relaxed, + // Relaxed order is safe on failure as r.tagged_count is immediately + // overwritten by retrying the find root operation. + memory_order_relaxed)) { + // We incremented it successfully, so we are done. + return true; + } + // We failed update due to parent switching on the arena. + goto retry; +} + +void upb_Arena_DecRefFor(const upb_Arena* a, const void* owner) { + upb_Arena_Free((upb_Arena*)a); +} + +bool upb_Arena_RefArena(upb_Arena* from, const upb_Arena* to) { + UPB_ASSERT(!upb_Arena_IsFused(from, to)); + if (_upb_ArenaInternal_HasInitialBlock(upb_Arena_Internal(to))) { + // We can't increment a ref to `to`, so return early. + return false; + } + + upb_ArenaInternal* ai = upb_Arena_Internal(from); + upb_ArenaRef* ref = upb_Arena_Malloc(from, kUpb_ArenaRefReserve); + + if (!ref) { + return false; + } + + // When 'from' is freed, a ref on 'to' will be released. + // Intentionally ignore return value, since we already check up above if this + // call will succeed. + bool result = upb_Arena_IncRefFor(to, from); + UPB_ASSERT(result); + + // When we add a reference from `from` to `to`, we need to keep track of the + // ref in the `from` arena's linked list of refs. This allows us to + // walk all refs for `from` when `from` is freed, and thus allows us to + // decrement the refcount on `to` when `from` is freed. + ref->prefix.next = ai->blocks; + ref->prefix.size = 0; + ref->arena = to; + ai->blocks = (upb_MemBlock*)ref; + +#ifndef NDEBUG + // Add to the dedicated list of refs. + // This function is not thread-safe from `from`, so a simple load/store is + // sufficient. + ref->next_ref = upb_Atomic_Load(&ai->refs, memory_order_relaxed); + upb_Atomic_Store(&ai->refs, ref, memory_order_release); +#endif + +#if UPB_ENABLE_REF_CYCLE_CHECKS + UPB_ASSERT(!upb_Arena_HasRefChain(to, from)); // Forbid cycles. +#endif + + return true; +} + +#ifndef NDEBUG +bool upb_Arena_HasRef(const upb_Arena* from, const upb_Arena* to) { + const upb_ArenaInternal* ai = upb_Arena_Internal(from); + const upb_ArenaRef* ref = upb_Atomic_Load(&ai->refs, memory_order_acquire); + while (ref != NULL) { + if (upb_Arena_IsFused(ref->arena, to)) { + return true; + } + ref = ref->next_ref; + } + return false; +} +#endif + +upb_alloc* upb_Arena_GetUpbAlloc(upb_Arena* a) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(a)); + upb_ArenaInternal* ai = upb_Arena_Internal(a); + return _upb_ArenaInternal_BlockAlloc(ai); +} + +void UPB_PRIVATE(_upb_Arena_SwapIn)(upb_Arena* des, const upb_Arena* src) { + memcpy(des, src, offsetof(upb_ArenaState, body.space_allocated)); + upb_ArenaInternal* desi = upb_Arena_Internal(des); + upb_ArenaInternal* srci = upb_Arena_Internal(src); + uintptr_t new_space_allocated = + upb_Atomic_Load(&srci->space_allocated, memory_order_relaxed); + upb_Atomic_Store(&desi->space_allocated, new_space_allocated, + memory_order_relaxed); +} + +void UPB_PRIVATE(_upb_Arena_SwapOut)(upb_Arena* des, const upb_Arena* src) { + UPB_PRIVATE(_upb_Arena_SwapIn)(des, src); +} + +bool _upb_Arena_WasLastAlloc(struct upb_Arena* a, void* ptr, size_t oldsize) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + upb_MemBlock* block = ai->blocks; + // Skip any arena refs. + while (block != NULL && block->size == 0) { + block = block->next; + } + if (block == NULL) return false; + char* start = UPB_PTR_AT(block, kUpb_MemblockReserve, char); + return UPB_PRIVATE(upb_Xsan_PtrEq)(ptr, start) && + UPB_PRIVATE(_upb_Arena_AllocSpan)(oldsize) == + block->size - kUpb_MemblockReserve; +} + + + +// Must be last. + +bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* f, + upb_Message* map_entry_message, upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(map_entry_message)); + const upb_MiniTable* map_entry_mini_table = + upb_MiniTable_MapEntrySubMessage(f); + UPB_ASSERT(map_entry_mini_table); + const upb_MiniTableField* map_entry_key_field = + upb_MiniTable_MapKey(map_entry_mini_table); + const upb_MiniTableField* map_entry_value_field = + upb_MiniTable_MapValue(map_entry_mini_table); + // Map key/value cannot have explicit defaults, + // hence assuming a zero default is valid. + upb_MessageValue default_val = upb_MessageValue_Zero(); + upb_MessageValue map_entry_key = + upb_Message_GetField(map_entry_message, map_entry_key_field, default_val); + upb_MessageValue map_entry_value = upb_Message_GetField( + map_entry_message, map_entry_value_field, default_val); + return upb_Map_Set(map, map_entry_key, map_entry_value, arena); +} + + +#include +#include + + +// Must be last. + +upb_Array* upb_Array_New(upb_Arena* a, upb_CType type) { + const int lg2 = UPB_PRIVATE(_upb_CType_SizeLg2)(type); + return UPB_PRIVATE(_upb_Array_New)(a, 4, lg2); +} + +upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { + UPB_ASSERT(i < upb_Array_Size(arr)); + upb_MessageValue ret; + const char* data = upb_Array_DataPtr(arr); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + memcpy(&ret, data + (i << lg2), 1 << lg2); + return ret; +} + +upb_Message* upb_Array_GetMutable(upb_Array* arr, size_t i) { + UPB_ASSERT(i < upb_Array_Size(arr)); + size_t elem_size = sizeof(upb_Message*); + UPB_ASSERT(elem_size == (1 << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr))); + char* data = upb_Array_MutableDataPtr(arr); + upb_Message* ret; + memcpy(&ret, data + (i * elem_size), elem_size); + UPB_ASSERT(!upb_Message_IsFrozen(ret)); + return ret; +} + +void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + UPB_ASSERT(i < upb_Array_Size(arr)); + char* data = upb_Array_MutableDataPtr(arr); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + memcpy(data + (i << lg2), &val, 1 << lg2); +} + +bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + UPB_ASSERT(arena); + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + upb_Array_Set(arr, arr->UPB_PRIVATE(size) - 1, val); + return true; +} + +bool upb_Array_Copy(upb_Array* dst, const upb_Array* src, upb_Arena* arena) { + UPB_ASSERT(dst); + UPB_ASSERT(src); + UPB_ASSERT(!upb_Array_IsFrozen(dst)); + if (dst == src) return true; + size_t len = upb_Array_Size(src); + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) { + return false; + } + if (len == 0) return true; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst); + const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src); + UPB_ASSERT(lg2 == src_lg2); + char* dst_data = upb_Array_MutableDataPtr(dst); + const char* src_data = upb_Array_DataPtr(src); + memcpy(dst_data, src_data, len << lg2); + return true; +} + +bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src, + upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(dst)); + UPB_ASSERT(src); + size_t src_len = upb_Array_Size(src); + if (src_len == 0) return true; + size_t dst_len = upb_Array_Size(dst); + size_t len = dst_len + src_len; + if (UPB_UNLIKELY(len < dst_len)) return false; + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) { + return false; + } + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst); + const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src); + UPB_ASSERT(lg2 == src_lg2); + char* dst_data = upb_Array_MutableDataPtr(dst); + const char* src_data = upb_Array_DataPtr(src); + memcpy(dst_data + (dst_len << lg2), src_data, src_len << lg2); + return true; +} + +void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx, + size_t count) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + char* data = upb_Array_MutableDataPtr(arr); + memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2); +} + +bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, + upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + UPB_ASSERT(arena); + UPB_ASSERT(i <= arr->UPB_PRIVATE(size)); + UPB_ASSERT(count + arr->UPB_PRIVATE(size) >= count); + const size_t oldsize = arr->UPB_PRIVATE(size); + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + count, arena)) { + return false; + } + upb_Array_Move(arr, i + count, i, oldsize - i); + return true; +} + +/* + * i end arr->size + * |------------|XXXXXXXX|--------| + */ +void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + const size_t end = i + count; + UPB_ASSERT(i <= end); + UPB_ASSERT(end <= arr->UPB_PRIVATE(size)); + upb_Array_Move(arr, i, end, arr->UPB_PRIVATE(size) - end); + arr->UPB_PRIVATE(size) -= count; +} + +bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + const size_t oldsize = arr->UPB_PRIVATE(size); + if (UPB_UNLIKELY( + !UPB_PRIVATE(_upb_Array_ResizeUninitialized)(arr, size, arena))) { + return false; + } + const size_t newsize = arr->UPB_PRIVATE(size); + if (newsize > oldsize) { + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + char* data = upb_Array_MutableDataPtr(arr); + memset(data + (oldsize << lg2), 0, (newsize - oldsize) << lg2); + } + return true; +} + +bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_capacity, + upb_Arena* arena) { + size_t new_capacity = UPB_MAX(array->UPB_PRIVATE(capacity), 4); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); + size_t old_bytes = array->UPB_PRIVATE(capacity) << lg2; + void* ptr = upb_Array_MutableDataPtr(array); + + // Log2 ceiling of size. + while (new_capacity < min_capacity) { + if (upb_ShlOverflow(&new_capacity, 1)) { + new_capacity = SIZE_MAX; + break; + } + } + + size_t new_bytes = new_capacity; + if (upb_ShlOverflow(&new_bytes, lg2)) { + return false; + } + ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes); + if (!ptr) return false; + + UPB_PRIVATE(_upb_Array_SetTaggedPtr)(array, ptr, lg2); + array->UPB_PRIVATE(capacity) = new_capacity; + return true; +} + +void upb_Array_Freeze(upb_Array* arr, const upb_MiniTable* m) { + if (upb_Array_IsFrozen(arr)) return; + UPB_PRIVATE(_upb_Array_ShallowFreeze)(arr); + + if (m) { + const size_t size = upb_Array_Size(arr); + + for (size_t i = 0; i < size; i++) { + upb_MessageValue val = upb_Array_Get(arr, i); + upb_Message_Freeze((upb_Message*)val.msg_val, m); + } + } +} + + +#include +#include + + +// Must be last. + +bool upb_Message_NextExtensionReverse(const upb_Message* msg, + const upb_MiniTableExtension** result, + uintptr_t* iter) { + upb_MessageValue val; + return UPB_PRIVATE(_upb_Message_NextExtensionReverse)(msg, result, &val, + iter); +} + +const upb_MiniTableExtension* upb_Message_FindExtensionByNumber( + const upb_Message* msg, uint32_t field_number) { + uintptr_t iter = kUpb_Message_ExtensionBegin; + const upb_MiniTableExtension* result; + while (upb_Message_NextExtensionReverse(msg, &result, &iter)) { + if (upb_MiniTableExtension_Number(result) == field_number) return result; + } + return NULL; +} + + +#include +#include + + +// Must be last. + +// Strings/bytes are special-cased in maps. +char _upb_Map_CTypeSizeTable[12] = { + [kUpb_CType_Bool] = 1, + [kUpb_CType_Float] = 4, + [kUpb_CType_Int32] = 4, + [kUpb_CType_UInt32] = 4, + [kUpb_CType_Enum] = 4, + [kUpb_CType_Message] = sizeof(void*), + [kUpb_CType_Double] = 8, + [kUpb_CType_Int64] = 8, + [kUpb_CType_UInt64] = 8, + [kUpb_CType_String] = UPB_MAPTYPE_STRING, + [kUpb_CType_Bytes] = UPB_MAPTYPE_STRING, +}; + +upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, upb_CType value_type) { + return _upb_Map_New(a, _upb_Map_CTypeSize(key_type), + _upb_Map_CTypeSize(value_type)); +} + +size_t upb_Map_Size(const upb_Map* map) { return _upb_Map_Size(map); } + +bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* val) { + return _upb_Map_Get(map, &key, map->key_size, val, map->val_size); +} + +struct upb_Message* upb_Map_GetMutable(upb_Map* map, upb_MessageValue key) { + UPB_ASSERT(map->val_size == sizeof(upb_Message*)); + upb_Message* val = NULL; + if (_upb_Map_Get(map, &key, map->key_size, &val, sizeof(upb_Message*))) { + return val; + } else { + return NULL; + } +} + +void upb_Map_Clear(upb_Map* map) { _upb_Map_Clear(map); } + +upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key, + upb_MessageValue val, upb_Arena* arena) { + UPB_ASSERT(arena); + return (upb_MapInsertStatus)_upb_Map_Insert(map, &key, map->key_size, &val, + map->val_size, arena); +} + +bool upb_Map_Delete(upb_Map* map, upb_MessageValue key, upb_MessageValue* val) { + upb_value v; + const bool removed = _upb_Map_Delete(map, &key, map->key_size, &v); + if (val) _upb_map_fromvalue(v, val, map->val_size); + return removed; +} + +bool upb_Map_Next(const upb_Map* map, upb_MessageValue* key, + upb_MessageValue* val, size_t* iter) { + upb_value v; + bool ret; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView strkey; + ret = upb_strtable_next2(&map->t.strtable, &strkey, &v, (intptr_t*)iter); + if (ret) { + _upb_map_fromkey(strkey, key, map->key_size); + } + } else { + uintptr_t intkey; + ret = upb_inttable_next(&map->t.inttable, &intkey, &v, (intptr_t*)iter); + if (ret) { + memcpy(key, &intkey, map->key_size); + } + } + if (ret) { + _upb_map_fromvalue(v, val, map->val_size); + } + return ret; +} + +UPB_API void upb_Map_SetEntryValue(upb_Map* map, size_t iter, + upb_MessageValue val) { + upb_value v; + _upb_map_tovalue(&val, map->val_size, &v, NULL); + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_setentryvalue(&map->t.strtable, iter, v); + } else { + upb_inttable_setentryvalue(&map->t.inttable, iter, v); + } +} + +bool upb_MapIterator_Next(const upb_Map* map, size_t* iter) { + return _upb_map_next(map, iter); +} + +bool upb_MapIterator_Done(const upb_Map* map, size_t iter) { + UPB_ASSERT(iter != kUpb_Map_Begin); + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter i; + i.t = &map->t.strtable; + i.index = iter; + return upb_strtable_done(&i); + } else { + return upb_inttable_done(&map->t.inttable, iter); + } +} + +// Returns the key and value for this entry of the map. +upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) { + upb_MessageValue ret; + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter i; + i.t = &map->t.strtable; + i.index = iter; + _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size); + } else { + uintptr_t intkey = upb_inttable_iter_key(&map->t.inttable, iter); + memcpy(&ret, &intkey, map->key_size); + } + return ret; +} + +upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter) { + upb_value v; + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter i; + i.t = &map->t.strtable; + i.index = iter; + v = upb_strtable_iter_value(&i); + } else { + v = upb_inttable_iter_value(&map->t.inttable, iter); + } + + upb_MessageValue ret; + _upb_map_fromvalue(v, &ret, map->val_size); + return ret; +} + +void upb_Map_Freeze(upb_Map* map, const upb_MiniTable* m) { + if (upb_Map_IsFrozen(map)) return; + UPB_PRIVATE(_upb_Map_ShallowFreeze)(map); + + if (m) { + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + + while (upb_Map_Next(map, &key, &val, &iter)) { + upb_Message_Freeze((upb_Message*)val.msg_val, m); + } + } +} + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { + upb_Map* map = upb_Arena_Malloc(a, sizeof(upb_Map)); + if (!map) return NULL; + + if (key_size <= sizeof(uintptr_t) && key_size != UPB_MAPTYPE_STRING) { + if (!upb_inttable_init(&map->t.inttable, a)) return NULL; + map->UPB_PRIVATE(is_strtable) = false; + } else { + if (!upb_strtable_init(&map->t.strtable, 4, a)) return NULL; + map->UPB_PRIVATE(is_strtable) = true; + } + map->key_size = key_size; + map->val_size = value_size; + map->UPB_PRIVATE(is_frozen) = false; + + return map; +} + + +#include +#include +#include + + +// Must be last. + +static int _upb_mapsorter_intkeys(const void* _a, const void* _b) { + const upb_tabent* const* a = _a; + const upb_tabent* const* b = _b; + uintptr_t a_key = (*a)->key.num; + uintptr_t b_key = (*b)->key.num; + return a_key < b_key ? -1 : a_key > b_key; +} + +static void _upb_mapsorter_getkeys(const void* _a, const void* _b, void* a_key, + void* b_key, size_t size) { + const upb_tabent* const* a = _a; + const upb_tabent* const* b = _b; + upb_StringView a_tabkey = upb_key_strview((*a)->key); + upb_StringView b_tabkey = upb_key_strview((*b)->key); + _upb_map_fromkey(a_tabkey, a_key, size); + _upb_map_fromkey(b_tabkey, b_key, size); +} + +static int _upb_mapsorter_cmpi64(const void* _a, const void* _b) { + int64_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpu64(const void* _a, const void* _b) { + uint64_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpi32(const void* _a, const void* _b) { + int32_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpu32(const void* _a, const void* _b) { + uint32_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpbool(const void* _a, const void* _b) { + bool a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 1); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpstr(const void* _a, const void* _b) { + upb_StringView a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, UPB_MAPTYPE_STRING); + size_t common_size = UPB_MIN(a.size, b.size); + int cmp = memcmp(a.data, b.data, common_size); + if (cmp) return -cmp; + return a.size < b.size ? -1 : a.size > b.size; +} + +static int (*const compar[kUpb_FieldType_SizeOf])(const void*, const void*) = { + [kUpb_FieldType_Int64] = _upb_mapsorter_cmpi64, + [kUpb_FieldType_SFixed64] = _upb_mapsorter_cmpi64, + [kUpb_FieldType_SInt64] = _upb_mapsorter_cmpi64, + + [kUpb_FieldType_UInt64] = _upb_mapsorter_cmpu64, + [kUpb_FieldType_Fixed64] = _upb_mapsorter_cmpu64, + + [kUpb_FieldType_Int32] = _upb_mapsorter_cmpi32, + [kUpb_FieldType_SInt32] = _upb_mapsorter_cmpi32, + [kUpb_FieldType_SFixed32] = _upb_mapsorter_cmpi32, + [kUpb_FieldType_Enum] = _upb_mapsorter_cmpi32, + + [kUpb_FieldType_UInt32] = _upb_mapsorter_cmpu32, + [kUpb_FieldType_Fixed32] = _upb_mapsorter_cmpu32, + + [kUpb_FieldType_Bool] = _upb_mapsorter_cmpbool, + + [kUpb_FieldType_String] = _upb_mapsorter_cmpstr, + [kUpb_FieldType_Bytes] = _upb_mapsorter_cmpstr, +}; + +static bool _upb_mapsorter_resize(_upb_mapsorter* s, _upb_sortedmap* sorted, + int size) { + sorted->start = s->size; + sorted->pos = sorted->start; + sorted->end = sorted->start + size; + + if (sorted->end > s->cap) { + const int oldsize = s->cap * sizeof(*s->entries); + s->cap = upb_RoundUpToPowerOfTwo(sorted->end); + const int newsize = s->cap * sizeof(*s->entries); + s->entries = upb_grealloc(s->entries, oldsize, newsize); + if (!s->entries) return false; + } + + s->size = sorted->end; + return true; +} + +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const upb_Map* map, _upb_sortedmap* sorted) { + int map_size; + if (map->UPB_PRIVATE(is_strtable)) { + map_size = _upb_Map_Size(map); + } else { + // For inttable, only sort the table entries, since the array part is + // already in a sorted order. + map_size = map->t.inttable.t.count; + } + + if (!_upb_mapsorter_resize(s, sorted, map_size)) return false; + + // Copy non-empty entries from the table to s->entries. + const void** dst = &s->entries[sorted->start]; + const upb_tabent* src; + const upb_tabent* end; + if (map->UPB_PRIVATE(is_strtable)) { + src = map->t.strtable.t.entries; + end = src + upb_table_size(&map->t.strtable.t); + } else { + // For inttable, only sort the table entries, since the array part is + // already in a sorted order. + src = map->t.inttable.t.entries; + end = src + upb_table_size(&map->t.inttable.t); + } + for (; src < end; src++) { + if (!upb_tabent_isempty(src)) { + *dst = src; + dst++; + } + } + UPB_ASSERT(dst == &s->entries[sorted->end]); + + // Sort entries according to the key type. + qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), + map->UPB_PRIVATE(is_strtable) ? compar[key_type] + : _upb_mapsorter_intkeys); + return true; +} + +static int _upb_mapsorter_cmpext(const void* _a, const void* _b) { + const upb_Extension* const* a = _a; + const upb_Extension* const* b = _b; + uint32_t a_num = upb_MiniTableExtension_Number((*a)->ext); + uint32_t b_num = upb_MiniTableExtension_Number((*b)->ext); + UPB_ASSERT(a_num != b_num); + return a_num < b_num ? -1 : 1; +} + +bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, + _upb_sortedmap* sorted) { + size_t count = 0; + for (size_t i = 0; i < in->size; i++) { + count += upb_TaggedAuxPtr_IsExtension(in->aux_data[i]); + } + if (!_upb_mapsorter_resize(s, sorted, count)) return false; + if (count == 0) return true; + const upb_Extension** entry = + (const upb_Extension**)&s->entries[sorted->start]; + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + *entry++ = upb_TaggedAuxPtr_Extension(tagged_ptr); + } + } + qsort(&s->entries[sorted->start], count, sizeof(*s->entries), + _upb_mapsorter_cmpext); + return true; +} + + +#include +#include +#include +#include + + +// Must be last. + +upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* a) { + return _upb_Message_New(m, a); +} + +UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg, + const char* data, + size_t len, + upb_Arena* arena, + bool alias) { + { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + // Alias fast path was already checked in the inline function that calls + // this one + if (!alias && in && in->size) { + upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1]; + if (upb_TaggedAuxPtr_IsUnknown(ptr)) { + upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr); + if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) { + // If part of the existing field was deleted at the beginning, we can + // reconstruct it by comparing the address of the end with the address + // of the entry itself; having the non-aliased tag means that the + // string_view and the data it points to are part of the same original + // upb_Arena_Malloc allocation, and the end of the string view + // represents the end of that allocation. + size_t prev_alloc_size = + (existing->data + existing->size) - (char*)existing; + if (SIZE_MAX - prev_alloc_size >= len) { + size_t new_alloc_size = prev_alloc_size + len; + if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, + new_alloc_size)) { + memcpy(UPB_PTR_AT(existing, prev_alloc_size, void), data, len); + existing->size += len; + return true; + } + } + } + } + } + } + // TODO: b/376969853 - Add debug check that the unknown field is an overall + // valid proto field + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) { + return false; + } + upb_StringView* view; + if (alias) { + view = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!view) return false; + view->data = data; + } else { + if (SIZE_MAX - sizeof(upb_StringView) < len) return false; + view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); + if (!view) return false; + char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); + memcpy(copy, data, len); + view->data = copy; + } + view->size = len; + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + in->aux_data[in->size++] = alias + ? upb_TaggedAuxPtr_MakeUnknownDataAliased(view) + : upb_TaggedAuxPtr_MakeUnknownData(view); + return true; +} + +bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, + upb_Arena* arena, + upb_StringView data[], + size_t count) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(count > 0); + size_t total_len = 0; + for (size_t i = 0; i < count; i++) { + if (SIZE_MAX - total_len < data[i].size) { + return false; + } + total_len += data[i].size; + } + + { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (in && in->size) { + upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1]; + if (upb_TaggedAuxPtr_IsUnknown(ptr)) { + upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr); + if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) { + size_t prev_alloc_size = + (existing->data + existing->size) - (char*)existing; + if (SIZE_MAX - prev_alloc_size >= total_len) { + size_t new_alloc_size = prev_alloc_size + total_len; + if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, + new_alloc_size)) { + char* copy = UPB_PTR_AT(existing, prev_alloc_size, char); + for (size_t i = 0; i < count; i++) { + memcpy(copy, data[i].data, data[i].size); + copy += data[i].size; + } + existing->size += total_len; + return true; + } + } + } + } + } + } + + if (SIZE_MAX - sizeof(upb_StringView) < total_len) return false; + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) return false; + + upb_StringView* view = + upb_Arena_Malloc(arena, sizeof(upb_StringView) + total_len); + if (!view) return false; + char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); + view->data = copy; + view->size = total_len; + for (size_t i = 0; i < count; i++) { + memcpy(copy, data[i].data, data[i].size); + copy += data[i].size; + } + // TODO: b/376969853 - Add debug check that the unknown field is an overall + // valid proto field + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view); + return true; +} + +void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return; + uint32_t size = 0; + for (uint32_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + in->aux_data[size++] = tagged_ptr; + } + } + in->size = size; +} + +upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg, + upb_StringView* data, + uintptr_t* iter, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(*iter != kUpb_Message_UnknownBegin); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + UPB_ASSERT(in); + UPB_ASSERT(*iter <= in->size); + upb_TaggedAuxPtr unknown_ptr = in->aux_data[*iter - 1]; + UPB_ASSERT(upb_TaggedAuxPtr_IsUnknown(unknown_ptr)); + upb_StringView* unknown = upb_TaggedAuxPtr_UnknownData(unknown_ptr); + if (unknown->data == data->data && unknown->size == data->size) { + // Remove whole field + in->aux_data[*iter - 1] = upb_TaggedAuxPtr_Null(); + } else if (unknown->data == data->data) { + // Strip prefix + unknown->data += data->size; + unknown->size -= data->size; + *data = *unknown; + return kUpb_DeleteUnknown_IterUpdated; + } else if (unknown->data + unknown->size == data->data + data->size) { + // Truncate existing field + unknown->size -= data->size; + if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) { + in->aux_data[*iter - 1] = + upb_TaggedAuxPtr_MakeUnknownDataAliased(unknown); + } + } else { + UPB_ASSERT(unknown->data < data->data && + unknown->data + unknown->size > data->data + data->size); + // Split in the middle + upb_StringView* prefix = unknown; + upb_StringView* suffix = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!suffix) { + return kUpb_DeleteUnknown_AllocFail; + } + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) { + return kUpb_DeleteUnknown_AllocFail; + } + in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (*iter != in->size) { + // Shift later entries down so that unknown field ordering is preserved + memmove(&in->aux_data[*iter + 1], &in->aux_data[*iter], + sizeof(upb_TaggedAuxPtr) * (in->size - *iter)); + } + in->aux_data[*iter] = upb_TaggedAuxPtr_MakeUnknownDataAliased(suffix); + if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) { + in->aux_data[*iter - 1] = upb_TaggedAuxPtr_MakeUnknownDataAliased(prefix); + } + in->size++; + suffix->data = data->data + data->size; + suffix->size = (prefix->data + prefix->size) - suffix->data; + prefix->size = data->data - prefix->data; + } + return upb_Message_NextUnknown(msg, data, iter) + ? kUpb_DeleteUnknown_IterUpdated + : kUpb_DeleteUnknown_DeletedLast; +} + +size_t upb_Message_ExtensionCount(const upb_Message* msg) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return 0; + const upb_MiniTableExtension* ext; + upb_MessageValue val; + uintptr_t iter = kUpb_Message_ExtensionBegin; + size_t count = 0; + while (upb_Message_NextExtension(msg, &ext, &val, &iter)) { + count++; + } + return count; +} + +void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { + if (upb_Message_IsFrozen(msg)) return; + UPB_PRIVATE(_upb_Message_ShallowFreeze)(msg); + + // Base Fields. + const size_t field_count = upb_MiniTable_FieldCount(m); + + for (size_t i = 0; i < field_count; i++) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + const upb_MiniTable* m2 = upb_MiniTable_SubMessage(f); + + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) { + case kUpb_FieldMode_Array: { + upb_Array* arr = upb_Message_GetMutableArray(msg, f); + if (arr) upb_Array_Freeze(arr, m2); + break; + } + case kUpb_FieldMode_Map: { + upb_Map* map = upb_Message_GetMutableMap(msg, f); + if (map) { + const upb_MiniTableField* f2 = upb_MiniTable_MapValue(m2); + const upb_MiniTable* m3 = upb_MiniTable_SubMessage(f2); + upb_Map_Freeze(map, m3); + } + break; + } + case kUpb_FieldMode_Scalar: { + if (m2) { + upb_Message* msg2 = upb_Message_GetMutableMessage(msg, f); + if (msg2) upb_Message_Freeze(msg2, m2); + } + break; + } + } + } + + // Extensions. + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + // TODO: b/376969853 - use iterator API + uint32_t size = in ? in->size : 0; + for (size_t i = 0; i < size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (!upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + continue; + } + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + const upb_MiniTableExtension* e = ext->ext; + const upb_MiniTableField* f = &e->UPB_PRIVATE(field); + const upb_MiniTable* m2 = upb_MiniTableExtension_GetSubMessage(e); + + upb_MessageValue val; + memcpy(&val, &(ext->data), sizeof(upb_MessageValue)); + + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) { + case kUpb_FieldMode_Array: { + upb_Array* arr = (upb_Array*)val.array_val; + if (arr) upb_Array_Freeze(arr, m2); + break; + } + case kUpb_FieldMode_Map: + UPB_UNREACHABLE(); // Maps cannot be extensions. + break; + case kUpb_FieldMode_Scalar: + if (upb_MiniTableField_IsSubMessage(f)) { + upb_Message* msg2 = (upb_Message*)val.msg_val; + if (msg2) upb_Message_Freeze(msg2, m2); + } + break; + } + } +} + + +#include +#include + + +// Must be last. + + +#ifdef __cplusplus +extern "C" { +#endif + +bool upb_Message_IsEmpty(const upb_Message* msg, const upb_MiniTable* m) { + if (upb_Message_ExtensionCount(msg)) return false; + + const upb_MiniTableField* f; + upb_MessageValue v; + size_t iter = kUpb_BaseField_Begin; + return !UPB_PRIVATE(_upb_Message_NextBaseField)(msg, m, &f, &v, &iter); +} + +static bool _upb_Array_IsEqual(const upb_Array* arr1, const upb_Array* arr2, + upb_CType ctype, const upb_MiniTable* m, + int options) { + // Check for trivial equality. + if (arr1 == arr2) return true; + + // Must have identical element counts. + const size_t size1 = arr1 ? upb_Array_Size(arr1) : 0; + const size_t size2 = arr2 ? upb_Array_Size(arr2) : 0; + if (size1 != size2) return false; + + for (size_t i = 0; i < size1; i++) { + const upb_MessageValue val1 = upb_Array_Get(arr1, i); + const upb_MessageValue val2 = upb_Array_Get(arr2, i); + + if (!upb_MessageValue_IsEqual(val1, val2, ctype, m, options)) return false; + } + + return true; +} + +static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, + const upb_MiniTable* m, int options) { + // Check for trivial equality. + if (map1 == map2) return true; + + // Must have identical element counts. + size_t size1 = map1 ? upb_Map_Size(map1) : 0; + size_t size2 = map2 ? upb_Map_Size(map2) : 0; + if (size1 != size2) return false; + + const upb_MiniTableField* f = upb_MiniTable_MapValue(m); + const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(f); + const upb_CType ctype = upb_MiniTableField_CType(f); + + upb_MessageValue key, val1, val2; + size_t iter = kUpb_Map_Begin; + while (upb_Map_Next(map1, &key, &val1, &iter)) { + if (!upb_Map_Get(map2, key, &val2)) return false; + if (!upb_MessageValue_IsEqual(val1, val2, ctype, m2_value, options)) + return false; + } + + return true; +} + +static bool _upb_Message_BaseFieldsAreEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, + int options) { + // Iterate over all base fields for each message. + // The order will always match if the messages are equal. + size_t iter1 = kUpb_BaseField_Begin; + size_t iter2 = kUpb_BaseField_Begin; + + for (;;) { + const upb_MiniTableField *f1, *f2; + upb_MessageValue val1, val2; + + const bool got1 = + UPB_PRIVATE(_upb_Message_NextBaseField)(msg1, m, &f1, &val1, &iter1); + const bool got2 = + UPB_PRIVATE(_upb_Message_NextBaseField)(msg2, m, &f2, &val2, &iter2); + + if (got1 != got2) return false; // Must have identical field counts. + if (!got1) return true; // Loop termination condition. + if (f1 != f2) return false; // Must have identical fields set. + + const upb_MiniTable* subm = upb_MiniTable_SubMessage(f1); + const upb_CType ctype = upb_MiniTableField_CType(f1); + + bool eq; + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f1)) { + case kUpb_FieldMode_Array: + eq = _upb_Array_IsEqual(val1.array_val, val2.array_val, ctype, subm, + options); + break; + case kUpb_FieldMode_Map: + eq = _upb_Map_IsEqual(val1.map_val, val2.map_val, subm, options); + break; + case kUpb_FieldMode_Scalar: + eq = upb_MessageValue_IsEqual(val1, val2, ctype, subm, options); + break; + } + if (!eq) return false; + } +} + +static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, + int options) { + const upb_MiniTableExtension* e; + upb_MessageValue val1; + + // Iterate over all extensions for msg1, and search msg2 for each extension. + size_t count1 = 0; + size_t iter1 = kUpb_Message_ExtensionBegin; + while (upb_Message_NextExtension(msg1, &e, &val1, &iter1)) { + const upb_Extension* ext2 = UPB_PRIVATE(_upb_Message_Getext)(msg2, e); + if (!ext2) return false; + + count1++; + + const upb_MessageValue val2 = ext2->data; + const upb_MiniTableField* f = &e->UPB_PRIVATE(field); + const upb_MiniTable* subm = upb_MiniTableField_IsSubMessage(f) + ? upb_MiniTableExtension_GetSubMessage(e) + : NULL; + const upb_CType ctype = upb_MiniTableField_CType(f); + + bool eq; + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) { + case kUpb_FieldMode_Array: + eq = _upb_Array_IsEqual(val1.array_val, val2.array_val, ctype, subm, + options); + break; + case kUpb_FieldMode_Map: + UPB_UNREACHABLE(); // Maps cannot be extensions. + break; + case kUpb_FieldMode_Scalar: { + eq = upb_MessageValue_IsEqual(val1, val2, ctype, subm, options); + break; + } + } + if (!eq) return false; + } + + // Must have identical extension counts (this catches the case where msg2 + // has extensions that msg1 doesn't). + if (count1 != upb_Message_ExtensionCount(msg2)) return false; + + return true; +} + +bool upb_Message_IsEqual(const upb_Message* msg1, const upb_Message* msg2, + const upb_MiniTable* m, int options) { + if (UPB_UNLIKELY(msg1 == msg2)) return true; + + if (!_upb_Message_BaseFieldsAreEqual(msg1, msg2, m, options)) return false; + if (!_upb_Message_ExtensionsAreEqual(msg1, msg2, m, options)) return false; + + if (!(options & kUpb_CompareOption_IncludeUnknownFields)) return true; + + // The wire encoder enforces a maximum depth of 100 so we match that here. + return UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)(msg1, msg2, 100) == + kUpb_UnknownCompareResult_Equal; +} + + +#include +#include + + +// Must be last. + +typedef struct upb_UnknownFields upb_UnknownFields; + +typedef struct { + uint32_t tag; + union { + uint64_t varint; + uint64_t uint64; + uint32_t uint32; + upb_StringView delimited; + upb_UnknownFields* group; + } data; +} upb_UnknownField; + +struct upb_UnknownFields { + size_t size; + size_t capacity; + upb_UnknownField* fields; +}; + +typedef struct { + upb_EpsCopyInputStream stream; + upb_Arena* arena; + upb_UnknownField* tmp; + size_t tmp_size; + int depth; + upb_UnknownCompareResult status; + jmp_buf err; +} upb_UnknownField_Context; + +typedef struct { + upb_UnknownField* arr_base; + upb_UnknownField* arr_ptr; + upb_UnknownField* arr_end; + uint32_t last_tag; + bool sorted; +} upb_UnknownFields_Builder; + +UPB_NORETURN static void upb_UnknownFields_OutOfMemory( + upb_UnknownField_Context* ctx) { + ctx->status = kUpb_UnknownCompareResult_OutOfMemory; + UPB_LONGJMP(ctx->err, 1); +} + +static void upb_UnknownFields_Grow(upb_UnknownField_Context* ctx, + upb_UnknownField** base, + upb_UnknownField** ptr, + upb_UnknownField** end) { + size_t old = (*ptr - *base); + size_t new = UPB_MAX(4, old * 2); + + *base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base), + new * sizeof(**base)); + if (!*base) upb_UnknownFields_OutOfMemory(ctx); + + *ptr = *base + old; + *end = *base + new; +} + +// We have to implement our own sort here, since qsort() is not an in-order +// sort. Here we use merge sort, the simplest in-order sort. +static void upb_UnknownFields_Merge(upb_UnknownField* arr, size_t start, + size_t mid, size_t end, + upb_UnknownField* tmp) { + memcpy(tmp, &arr[start], (end - start) * sizeof(*tmp)); + + upb_UnknownField* ptr1 = tmp; + upb_UnknownField* end1 = &tmp[mid - start]; + upb_UnknownField* ptr2 = &tmp[mid - start]; + upb_UnknownField* end2 = &tmp[end - start]; + upb_UnknownField* out = &arr[start]; + + while (ptr1 < end1 && ptr2 < end2) { + if (ptr1->tag <= ptr2->tag) { + *out++ = *ptr1++; + } else { + *out++ = *ptr2++; + } + } + + if (ptr1 < end1) { + memcpy(out, ptr1, (end1 - ptr1) * sizeof(*out)); + } else if (ptr2 < end2) { + memcpy(out, ptr1, (end2 - ptr2) * sizeof(*out)); + } +} + +static void upb_UnknownFields_SortRecursive(upb_UnknownField* arr, size_t start, + size_t end, upb_UnknownField* tmp) { + if (end - start > 1) { + size_t mid = start + ((end - start) / 2); + upb_UnknownFields_SortRecursive(arr, start, mid, tmp); + upb_UnknownFields_SortRecursive(arr, mid, end, tmp); + upb_UnknownFields_Merge(arr, start, mid, end, tmp); + } +} + +static void upb_UnknownFields_Sort(upb_UnknownField_Context* ctx, + upb_UnknownFields* fields) { + if (ctx->tmp_size < fields->size) { + const int oldsize = ctx->tmp_size * sizeof(*ctx->tmp); + ctx->tmp_size = UPB_MAX(8, ctx->tmp_size); + while (ctx->tmp_size < fields->size) ctx->tmp_size *= 2; + const int newsize = ctx->tmp_size * sizeof(*ctx->tmp); + ctx->tmp = upb_grealloc(ctx->tmp, oldsize, newsize); + } + upb_UnknownFields_SortRecursive(fields->fields, 0, fields->size, ctx->tmp); +} + +static upb_UnknownFields* upb_UnknownFields_BuildFromBuffer( + upb_UnknownField_Context* ctx, const char** buf); + +// Combines two unknown fields into one. +static void upb_CombineUnknownFields(upb_UnknownField_Context* ctx, + upb_UnknownFields_Builder* builder, + const char** buf) { + upb_UnknownField* arr_base = builder->arr_base; + upb_UnknownField* arr_ptr = builder->arr_ptr; + upb_UnknownField* arr_end = builder->arr_end; + const char* ptr = *buf; + uint32_t last_tag = builder->last_tag; + bool sorted = builder->sorted; + + // Parse the unknown field data. It is an invariant of the data structure that + // unknown field data is valid, so parse errors here should be impossible. + while (!upb_EpsCopyInputStream_IsDone(&ctx->stream, &ptr)) { + uint32_t tag; + ptr = upb_WireReader_ReadTag(ptr, &tag, &ctx->stream); + UPB_ASSERT(tag <= UINT32_MAX); + int wire_type = upb_WireReader_GetWireType(tag); + if (wire_type == kUpb_WireType_EndGroup) break; + if (tag < last_tag) sorted = false; + last_tag = tag; + + if (arr_ptr == arr_end) { + upb_UnknownFields_Grow(ctx, &arr_base, &arr_ptr, &arr_end); + } + upb_UnknownField* field = arr_ptr; + field->tag = tag; + arr_ptr++; + + switch (wire_type) { + case kUpb_WireType_Varint: + ptr = upb_WireReader_ReadVarint(ptr, &field->data.varint, &ctx->stream); + UPB_ASSERT(ptr); + break; + case kUpb_WireType_64Bit: + ptr = + upb_WireReader_ReadFixed64(ptr, &field->data.uint64, &ctx->stream); + UPB_ASSERT(ptr); + break; + case kUpb_WireType_32Bit: + ptr = + upb_WireReader_ReadFixed32(ptr, &field->data.uint32, &ctx->stream); + UPB_ASSERT(ptr); + break; + case kUpb_WireType_Delimited: { + int size; + upb_StringView sv; + ptr = upb_WireReader_ReadSize(ptr, &size, &ctx->stream); + UPB_ASSERT(ptr); + ptr = upb_EpsCopyInputStream_ReadStringAlwaysAlias(&ctx->stream, ptr, + size, &sv); + UPB_ASSERT(ptr); + field->data.delimited.data = sv.data; + field->data.delimited.size = sv.size; + break; + } + case kUpb_WireType_StartGroup: + if (--ctx->depth < 0) { + ctx->status = kUpb_UnknownCompareResult_MaxDepthExceeded; + UPB_LONGJMP(ctx->err, 1); + } + field->data.group = upb_UnknownFields_BuildFromBuffer(ctx, &ptr); + ctx->depth++; + break; + default: + UPB_UNREACHABLE(); + } + } + *buf = ptr; + builder->arr_base = arr_base; + builder->arr_ptr = arr_ptr; + builder->arr_end = arr_end; + builder->sorted = sorted; + builder->last_tag = last_tag; +} + +static upb_UnknownFields* upb_UnknownFields_DoBuild( + upb_UnknownField_Context* ctx, upb_UnknownFields_Builder* builder) { + upb_UnknownFields* ret = upb_Arena_Malloc(ctx->arena, sizeof(*ret)); + if (!ret) upb_UnknownFields_OutOfMemory(ctx); + ret->fields = builder->arr_base; + ret->size = builder->arr_ptr - builder->arr_base; + ret->capacity = builder->arr_end - builder->arr_base; + if (!builder->sorted) { + upb_UnknownFields_Sort(ctx, ret); + } + return ret; +} + +// Builds a upb_UnknownFields data structure from the binary data in buf. +static upb_UnknownFields* upb_UnknownFields_BuildFromBuffer( + upb_UnknownField_Context* ctx, const char** buf) { + upb_UnknownFields_Builder builder = { + .arr_base = NULL, + .arr_ptr = NULL, + .arr_end = NULL, + .sorted = true, + .last_tag = 0, + }; + const char* ptr = *buf; + upb_CombineUnknownFields(ctx, &builder, &ptr); + upb_UnknownFields* fields = upb_UnknownFields_DoBuild(ctx, &builder); + *buf = ptr; + return fields; +} + +// Builds a upb_UnknownFields data structure from the unknown fields of a +// upb_Message. +static upb_UnknownFields* upb_UnknownFields_Build(upb_UnknownField_Context* ctx, + const upb_Message* msg) { + upb_UnknownFields_Builder builder = { + .arr_base = NULL, + .arr_ptr = NULL, + .arr_end = NULL, + .sorted = true, + .last_tag = 0, + }; + uintptr_t iter = kUpb_Message_UnknownBegin; + upb_StringView view; + while (upb_Message_NextUnknown(msg, &view, &iter)) { + upb_EpsCopyInputStream_Init(&ctx->stream, &view.data, view.size); + upb_CombineUnknownFields(ctx, &builder, &view.data); + UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &view.data) && + !upb_EpsCopyInputStream_IsError(&ctx->stream)); + } + upb_UnknownFields* fields = upb_UnknownFields_DoBuild(ctx, &builder); + return fields; +} + +// Compares two sorted upb_UnknownFields structures for equality. +static bool upb_UnknownFields_IsEqual(const upb_UnknownFields* uf1, + const upb_UnknownFields* uf2) { + if (uf1->size != uf2->size) return false; + for (size_t i = 0, n = uf1->size; i < n; i++) { + upb_UnknownField* f1 = &uf1->fields[i]; + upb_UnknownField* f2 = &uf2->fields[i]; + if (f1->tag != f2->tag) return false; + int wire_type = f1->tag & 7; + switch (wire_type) { + case kUpb_WireType_Varint: + if (f1->data.varint != f2->data.varint) return false; + break; + case kUpb_WireType_64Bit: + if (f1->data.uint64 != f2->data.uint64) return false; + break; + case kUpb_WireType_32Bit: + if (f1->data.uint32 != f2->data.uint32) return false; + break; + case kUpb_WireType_Delimited: + if (!upb_StringView_IsEqual(f1->data.delimited, f2->data.delimited)) { + return false; + } + break; + case kUpb_WireType_StartGroup: + if (!upb_UnknownFields_IsEqual(f1->data.group, f2->data.group)) { + return false; + } + break; + default: + UPB_UNREACHABLE(); + } + } + return true; +} + +static upb_UnknownCompareResult upb_UnknownField_DoCompare( + upb_UnknownField_Context* ctx, const upb_Message* msg1, + const upb_Message* msg2) { + upb_UnknownCompareResult ret; + // First build both unknown fields into a sorted data structure (similar + // to the UnknownFieldSet in C++). + upb_UnknownFields* uf1 = upb_UnknownFields_Build(ctx, msg1); + upb_UnknownFields* uf2 = upb_UnknownFields_Build(ctx, msg2); + + // Now perform the equality check on the sorted structures. + if (upb_UnknownFields_IsEqual(uf1, uf2)) { + ret = kUpb_UnknownCompareResult_Equal; + } else { + ret = kUpb_UnknownCompareResult_NotEqual; + } + return ret; +} + +static upb_UnknownCompareResult upb_UnknownField_Compare( + upb_UnknownField_Context* const ctx, const upb_Message* msg1, + const upb_Message* msg2) { + upb_UnknownCompareResult ret; + if (UPB_SETJMP(ctx->err) == 0) { + ret = upb_UnknownField_DoCompare(ctx, msg1, msg2); + } else { + ret = ctx->status; + UPB_ASSERT(ret != kUpb_UnknownCompareResult_Equal); + } + + upb_Arena_Free(ctx->arena); + upb_gfree(ctx->tmp); + return ret; +} + +upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( + const upb_Message* msg1, const upb_Message* msg2, int max_depth) { + bool msg1_empty = !upb_Message_HasUnknown(msg1); + bool msg2_empty = !upb_Message_HasUnknown(msg2); + if (msg1_empty && msg2_empty) return kUpb_UnknownCompareResult_Equal; + if (msg1_empty || msg2_empty) return kUpb_UnknownCompareResult_NotEqual; + + upb_UnknownField_Context ctx = { + .arena = upb_Arena_New(), + .depth = max_depth, + .tmp = NULL, + .tmp_size = 0, + .status = kUpb_UnknownCompareResult_Equal, + }; + + if (!ctx.arena) return kUpb_UnknownCompareResult_OutOfMemory; + + return upb_UnknownField_Compare(&ctx, msg1, msg2); +} + + +#include +#include +#include + + +// Must be last. + +static upb_StringView upb_Clone_StringView(upb_StringView str, + upb_Arena* arena) { + if (str.size == 0) { + return upb_StringView_FromDataAndSize(NULL, 0); + } + void* cloned_data = upb_Arena_Malloc(arena, str.size); + upb_StringView cloned_str = + upb_StringView_FromDataAndSize(cloned_data, str.size); + memcpy(cloned_data, str.data, str.size); + return cloned_str; +} + +static bool upb_Clone_MessageValue(void* value, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + switch (value_type) { + case kUpb_CType_Bool: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return true; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView source = *(upb_StringView*)value; + size_t size = source.size; + void* cloned_data = upb_Arena_Malloc(arena, size); + if (cloned_data == NULL) { + return false; + } + *(upb_StringView*)value = + upb_StringView_FromDataAndSize(cloned_data, size); + memcpy(cloned_data, source.data, size); + return true; + } break; + case kUpb_CType_Message: { + UPB_ASSERT(sub); + const upb_Message* source = *(upb_Message**)value; + UPB_ASSERT(source); + upb_Message* clone = upb_Message_DeepClone(source, sub, arena); + *(upb_Message**)value = clone; + return clone != NULL; + } break; + } + UPB_UNREACHABLE(); +} + +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena) { + upb_Map* cloned_map = _upb_Map_New(arena, map->key_size, map->val_size); + if (cloned_map == NULL) { + return NULL; + } + upb_MessageValue key, val; + size_t iter = kUpb_Map_Begin; + while (upb_Map_Next(map, &key, &val, &iter)) { + const upb_MiniTableField* value_field = + upb_MiniTable_MapValue(map_entry_table); + const upb_MiniTable* value_sub = + upb_MiniTableField_CType(value_field) == kUpb_CType_Message + ? upb_MiniTable_GetSubMessageTable(value_field) + : NULL; + upb_CType value_field_type = upb_MiniTableField_CType(value_field); + if (!upb_Clone_MessageValue(&val, value_field_type, value_sub, arena)) { + return NULL; + } + if (!upb_Map_Set(cloned_map, key, val, arena)) { + return NULL; + } + } + return cloned_map; +} + +static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, + const upb_MiniTable* mini_table, + const upb_MiniTableField* f, + upb_Message* clone, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(clone)); + const upb_MiniTable* map_entry_table = upb_MiniTable_MapEntrySubMessage(f); + UPB_ASSERT(map_entry_table); + + const upb_MiniTableField* key_field = upb_MiniTable_MapKey(map_entry_table); + const upb_MiniTableField* value_field = + upb_MiniTable_MapValue(map_entry_table); + + upb_Map* cloned_map = upb_Map_DeepClone( + map, upb_MiniTableField_CType(key_field), + upb_MiniTableField_CType(value_field), map_entry_table, arena); + if (!cloned_map) { + return NULL; + } + upb_Message_SetBaseField(clone, f, &cloned_map); + return cloned_map; +} + +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + const size_t size = upb_Array_Size(array); + const int lg2 = UPB_PRIVATE(_upb_CType_SizeLg2)(value_type); + upb_Array* cloned_array = UPB_PRIVATE(_upb_Array_New)(arena, size, lg2); + if (!cloned_array) { + return NULL; + } + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(cloned_array, size, arena)) { + return NULL; + } + for (size_t i = 0; i < size; ++i) { + upb_MessageValue val = upb_Array_Get(array, i); + if (!upb_Clone_MessageValue(&val, value_type, sub, arena)) { + return NULL; + } + upb_Array_Set(cloned_array, i, val); + } + return cloned_array; +} + +static bool upb_Message_Array_DeepClone(const upb_Array* array, + const upb_MiniTable* mini_table, + const upb_MiniTableField* field, + upb_Message* clone, upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(clone)); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); + upb_Array* cloned_array = + upb_Array_DeepClone(array, upb_MiniTableField_CType(field), + upb_MiniTableField_CType(field) == kUpb_CType_Message + ? upb_MiniTable_GetSubMessageTable(field) + : NULL, + arena); + + // Clear out upb_Array* due to parent memcpy. + upb_Message_SetBaseField(clone, field, &cloned_array); + return true; +} + +static bool upb_Clone_ExtensionValue( + const upb_MiniTableExtension* mini_table_ext, const upb_Extension* source, + upb_Extension* dest, upb_Arena* arena) { + dest->data = source->data; + return upb_Clone_MessageValue( + &dest->data, upb_MiniTableExtension_CType(mini_table_ext), + upb_MiniTableExtension_GetSubMessage(mini_table_ext), arena); +} + +upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(dst)); + upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0); + // Only copy message area skipping upb_Message_Internal. + memcpy(dst + 1, src + 1, mini_table->UPB_PRIVATE(size) - sizeof(upb_Message)); + for (int i = 0; i < upb_MiniTable_FieldCount(mini_table); ++i) { + const upb_MiniTableField* field = + upb_MiniTable_GetFieldByIndex(mini_table, i); + if (upb_MiniTableField_IsScalar(field)) { + switch (upb_MiniTableField_CType(field)) { + case kUpb_CType_Message: { + const upb_Message* sub_message = upb_Message_GetMessage(src, field); + if (sub_message != NULL) { + const upb_MiniTable* sub_message_table = + upb_MiniTable_GetSubMessageTable(field); + upb_Message* dst_sub_message = + upb_Message_DeepClone(sub_message, sub_message_table, arena); + if (dst_sub_message == NULL) { + return NULL; + } + upb_Message_SetBaseFieldMessage(dst, field, dst_sub_message); + } + } break; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView str = upb_Message_GetString(src, field, empty_string); + if (str.size != 0) { + if (!upb_Message_SetString( + dst, field, upb_Clone_StringView(str, arena), arena)) { + return NULL; + } + } + } break; + default: + // Scalar, already copied. + break; + } + } else { + if (upb_MiniTableField_IsMap(field)) { + const upb_Map* map = upb_Message_GetMap(src, field); + if (map != NULL) { + if (!upb_Message_Map_DeepClone(map, mini_table, field, dst, arena)) { + return NULL; + } + } + } else { + const upb_Array* array = upb_Message_GetArray(src, field); + if (array != NULL) { + if (!upb_Message_Array_DeepClone(array, mini_table, field, dst, + arena)) { + return NULL; + } + } + } + } + } + // Clone extensions. + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(src); + if (!in) return dst; + + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + // Clone extension + const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + const upb_MiniTableField* field = &msg_ext->ext->UPB_PRIVATE(field); + upb_Extension* dst_ext = UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + dst, msg_ext->ext, arena); + if (!dst_ext) return NULL; + if (upb_MiniTableField_IsScalar(field)) { + if (!upb_Clone_ExtensionValue(msg_ext->ext, msg_ext, dst_ext, arena)) { + return NULL; + } + } else { + upb_Array* msg_array = (upb_Array*)msg_ext->data.array_val; + UPB_ASSERT(msg_array); + upb_Array* cloned_array = upb_Array_DeepClone( + msg_array, upb_MiniTableField_CType(field), + upb_MiniTableExtension_GetSubMessage(msg_ext->ext), arena); + if (!cloned_array) { + return NULL; + } + dst_ext->data.array_val = cloned_array; + } + } else if (upb_TaggedAuxPtr_IsUnknown(tagged_ptr)) { + // Clone unknown + upb_StringView* unknown = upb_TaggedAuxPtr_UnknownData(tagged_ptr); + // Make a copy into destination arena. + if (!UPB_PRIVATE(_upb_Message_AddUnknown)( + dst, unknown->data, unknown->size, arena, kUpb_AddUnknown_Copy)) { + return NULL; + } + } + } + + return dst; +} + +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(dst)); + upb_Message_Clear(dst, mini_table); + return _upb_Message_Copy(dst, src, mini_table, arena) != NULL; +} + +// Deep clones a message using the provided target arena. +// +// Returns NULL on failure. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + return _upb_Message_Copy(clone, msg, m, arena); +} + +// Performs a shallow copy. TODO: Extend to handle unknown fields. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m) { + UPB_ASSERT(!upb_Message_IsFrozen(dst)); + memcpy(dst, src, m->UPB_PRIVATE(size)); +} + +// Performs a shallow clone. Ignores unknown fields. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, + upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + upb_Message_ShallowCopy(clone, msg, m); + return clone; +} + +#include "stddef.h" + +// Must be last. + +bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + upb_Arena* arena) { + char* buf = NULL; + size_t size = 0; + // This tmp arena is used to hold the bytes for `src` serialized. This bends + // the typical "no hidden allocations" design of upb, but under a properly + // optimized implementation this extra allocation would not be necessary and + // so we don't want to unnecessarily have the bad API or bloat the passed-in + // arena with this very-short-term allocation. + upb_Arena* encode_arena = upb_Arena_New(); + upb_EncodeStatus e_status = upb_Encode(src, mt, 0, encode_arena, &buf, &size); + if (e_status != kUpb_EncodeStatus_Ok) { + upb_Arena_Free(encode_arena); + return false; + } + upb_DecodeStatus d_status = upb_Decode(buf, size, dst, mt, extreg, 0, arena); + if (d_status != kUpb_DecodeStatus_Ok) { + upb_Arena_Free(encode_arena); + return false; + } + upb_Arena_Free(encode_arena); + return true; +} + + +#include +#include + + +// Must be last. + +const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)( + const struct upb_Message* msg, const upb_MiniTableExtension* e) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return NULL; + + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + if (ext->ext == e) { + return ext; + } + } + } + + return NULL; +} + +upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Extension* ext = (upb_Extension*)UPB_PRIVATE(_upb_Message_Getext)(msg, e); + if (ext) return ext; + + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, a)) return NULL; + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + ext = upb_Arena_Malloc(a, sizeof(upb_Extension)); + if (!ext) return NULL; + memset(ext, 0, sizeof(upb_Extension)); + ext->ext = e; + in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeExtension(ext); + return ext; +} + + +#include +#include +#include +#include + + +// Must be last. + +// The latest win32 SDKs have an invalid definition of NAN. +// https://developercommunity.visualstudio.com/t/NAN-is-no-longer-compile-time-constant-i/10688907 +// +// Unfortunately, the `0.0 / 0.0` workaround doesn't work in Clang under C23, so +// try __builtin_nan first, if that exists. +#ifdef _WIN32 +#ifdef __has_builtin +#if __has_builtin(__builtin_nan) +#define UPB_NAN __builtin_nan("0") +#endif +#if __has_builtin(__builtin_inf) +#define UPB_INFINITY __builtin_inf() +#endif +#endif +#ifndef UPB_NAN +#define UPB_NAN 0.0 / 0.0 +#endif +#ifndef UPB_INFINITY +#define UPB_INFINITY 1.0 / 0.0 +#endif +#else +// For !_WIN32, assume math.h works. +#define UPB_NAN NAN +#define UPB_INFINITY INFINITY +#endif + +const float kUpb_FltInfinity = UPB_INFINITY; +const double kUpb_Infinity = UPB_INFINITY; +const double kUpb_NaN = UPB_NAN; + +static size_t _upb_Message_SizeOfInternal(uint32_t count) { + return UPB_SIZEOF_FLEX(upb_Message_Internal, aux_data, count); +} + +bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg, + upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) { + // No internal data, allocate from scratch. + uint32_t capacity = 4; + in = upb_Arena_Malloc(a, _upb_Message_SizeOfInternal(capacity)); + if (!in) return false; + in->size = 0; + in->capacity = capacity; + UPB_PRIVATE(_upb_Message_SetInternal)(msg, in); + } else if (in->capacity == in->size) { + if (in->size == UINT32_MAX) return false; + // Internal data is too small, reallocate. + size_t needed_pow2 = upb_RoundUpToPowerOfTwo(in->size + 1); + if (needed_pow2 > UINT32_MAX) return false; + uint32_t new_capacity = needed_pow2; + if (UPB_SIZEOF_FLEX_WOULD_OVERFLOW(upb_Message_Internal, aux_data, + new_capacity)) { + return false; + } + in = upb_Arena_Realloc(a, in, _upb_Message_SizeOfInternal(in->capacity), + _upb_Message_SizeOfInternal(new_capacity)); + if (!in) return false; + in->capacity = new_capacity; + UPB_PRIVATE(_upb_Message_SetInternal)(msg, in); + } + UPB_ASSERT(in->capacity - in->size >= 1); + return true; +} + +#ifdef UPB_TRACING_ENABLED +static void (*_message_trace_handler)(const upb_MiniTable*, const upb_Arena*); + +void upb_Message_LogNewMessage(const upb_MiniTable* m, const upb_Arena* arena) { + if (_message_trace_handler) { + _message_trace_handler(m, arena); + } +} + +void upb_Message_SetNewMessageTraceHandler(void (*handler)(const upb_MiniTable*, + const upb_Arena*)) { + _message_trace_handler = handler; +} +#endif // UPB_TRACING_ENABLED + + +#include + + +// Must be last. + +bool UPB_PRIVATE(_upb_Message_NextBaseField)(const upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField** out_f, + upb_MessageValue* out_v, + size_t* iter) { + const size_t count = upb_MiniTable_FieldCount(m); + size_t i = *iter; + + while (++i < count) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + const void* src = UPB_PRIVATE(_upb_Message_DataPtr)(msg, f); + + upb_MessageValue val; + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, &val, src); + + // Skip field if unset or empty. + if (upb_MiniTableField_HasPresence(f)) { + if (!upb_Message_HasBaseField(msg, f)) continue; + } else { + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(f, src)) continue; + + if (upb_MiniTableField_IsArray(f)) { + if (upb_Array_Size(val.array_val) == 0) continue; + } else if (upb_MiniTableField_IsMap(f)) { + if (upb_Map_Size(val.map_val) == 0) continue; + } + } + + *out_f = f; + *out_v = val; + *iter = i; + return true; + } + + return false; +} + + +#include +#include + + +// Must be last. + +typedef struct { + upb_MdDecoder base; + upb_Arena* arena; + upb_MiniTableEnum* enum_table; + uint32_t enum_value_count; + uint32_t enum_data_count; + uint32_t enum_data_capacity; +} upb_MdEnumDecoder; + +static size_t upb_MiniTableEnum_Size(uint32_t count) { + return UPB_SIZEOF_FLEX(upb_MiniTableEnum, UPB_PRIVATE(data), count); +} + +static upb_MiniTableEnum* _upb_MiniTable_AddEnumDataMember(upb_MdEnumDecoder* d, + uint32_t val) { + if (d->enum_data_count == d->enum_data_capacity) { + size_t old_sz = upb_MiniTableEnum_Size(d->enum_data_capacity); + if (d->enum_data_capacity > UINT32_MAX / 2) { + upb_MdDecoder_ErrorJmp(&d->base, "Out of memory"); + } + uint32_t new_capacity = UPB_MAX(2, d->enum_data_capacity * 2); + if (UPB_SIZEOF_FLEX_WOULD_OVERFLOW(upb_MiniTableEnum, UPB_PRIVATE(data), + new_capacity)) { + upb_MdDecoder_ErrorJmp(&d->base, "Out of memory"); + } + size_t new_sz = upb_MiniTableEnum_Size(new_capacity); + d->enum_table = upb_Arena_Realloc(d->arena, d->enum_table, old_sz, new_sz); + upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); + d->enum_data_capacity = new_capacity; + } + d->enum_table->UPB_PRIVATE(data)[d->enum_data_count++] = val; + return d->enum_table; +} + +static void upb_MiniTableEnum_BuildValue(upb_MdEnumDecoder* d, uint32_t val) { + upb_MiniTableEnum* table = d->enum_table; + d->enum_value_count++; + if (table->UPB_PRIVATE(value_count) || + (val > 512 && d->enum_value_count < val / 32)) { + if (table->UPB_PRIVATE(value_count) == 0) { + UPB_ASSERT(d->enum_data_count == table->UPB_PRIVATE(mask_limit) / 32); + } + table = _upb_MiniTable_AddEnumDataMember(d, val); + table->UPB_PRIVATE(value_count)++; + } else { + uint32_t new_mask_limit = ((val / 32) + 1) * 32; + while (table->UPB_PRIVATE(mask_limit) < new_mask_limit) { + table = _upb_MiniTable_AddEnumDataMember(d, 0); + table->UPB_PRIVATE(mask_limit) += 32; + } + table->UPB_PRIVATE(data)[val / 32] |= 1ULL << (val % 32); + } +} + +static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum( + upb_MdEnumDecoder* d, const char* data, size_t len) { + // If the string is non-empty then it must begin with a version tag. + if (len) { + if (*data != kUpb_EncodedVersion_EnumV1) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid enum version: %c", *data); + } + data++; + len--; + } + + upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); + + // Guarantee at least 64 bits of mask without checking mask size. + d->enum_table->UPB_PRIVATE(mask_limit) = 64; + d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); + d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); + + d->enum_table->UPB_PRIVATE(value_count) = 0; + + const char* ptr = data; + uint32_t base = 0; + + while (ptr < d->base.end) { + char ch = *ptr++; + if (ch <= kUpb_EncodedValue_MaxEnumMask) { + uint32_t mask = _upb_FromBase92(ch); + for (int i = 0; i < 5; i++, base++, mask >>= 1) { + if (mask & 1) upb_MiniTableEnum_BuildValue(d, base); + } + } else if (kUpb_EncodedValue_MinSkip <= ch && + ch <= kUpb_EncodedValue_MaxSkip) { + uint32_t skip; + ptr = upb_MdDecoder_DecodeBase92Varint(&d->base, ptr, ch, + kUpb_EncodedValue_MinSkip, + kUpb_EncodedValue_MaxSkip, &skip); + base += skip; + } else { + upb_MdDecoder_ErrorJmp(&d->base, "Unexpected character: %c", ch); + } + } + + return d->enum_table; +} + +static upb_MiniTableEnum* upb_MtDecoder_BuildMiniTableEnum( + upb_MdEnumDecoder* const decoder, const char* const data, + size_t const len) { + if (UPB_SETJMP(decoder->base.err) != 0) return NULL; + return upb_MtDecoder_DoBuildMiniTableEnum(decoder, data, len); +} + +upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len, + upb_Arena* arena, + upb_Status* status) { + uint32_t initial_capacity = 2; + upb_MdEnumDecoder decoder = { + .base = + { + .end = UPB_PTRADD(data, len), + .status = status, + }, + .arena = arena, + .enum_table = + upb_Arena_Malloc(arena, upb_MiniTableEnum_Size(initial_capacity)), + .enum_value_count = 0, + .enum_data_count = 0, + .enum_data_capacity = initial_capacity, + }; + + return upb_MtDecoder_BuildMiniTableEnum(&decoder, data, len); +} + + +#include +#include +#include +#include +#include + + +// Our awkward dance for including fasttable only when it is enabled. +#if UPB_FASTTABLE +#define UPB_INCLUDE_FAST_DECODE +#endif + +#ifdef UPB_INCLUDE_FAST_DECODE +#endif + +#undef UPB_INCLUDE_FAST_DECODE + +// Must be last. + +// We reserve unused hasbits to make room for upb_Message fields. +#define kUpb_Reserved_Hasbytes sizeof(struct upb_Message) + +// 64 is the first hasbit that we currently use. +#define kUpb_Reserved_Hasbits (kUpb_Reserved_Hasbytes * 8) + +#define kUpb_OneOfLayoutItem_IndexSentinel ((uint16_t)-1) + +// Stores the field number of the present value of the oneof +#define kUpb_OneOf_CaseFieldRep (kUpb_FieldRep_4Byte) + +// The maximum field number that can be encoded on the wire. +// Note that this limit does not apply to MessageSet, which can have field +// numbers up to INT32_MAX. +#define kUpb_MaxFieldNumber ((1 << 29) - 1) + +typedef struct { + // Index of the corresponding field. The field's offset will be the index of + // the next field in a linked list. + uint16_t field_index; + // This enum is stored in bytes to avoid trailing padding while preserving + // two-byte alignment. + uint8_t /* upb_FieldRep*/ rep; +} upb_OneOfLayoutItem; + +typedef struct { + upb_OneOfLayoutItem* data; + size_t size; + size_t buf_capacity_bytes; +} upb_OneOfLayoutItemVector; + +typedef struct { + upb_MdDecoder base; + upb_MiniTableField* fields; + upb_MiniTablePlatform platform; + upb_OneOfLayoutItemVector oneofs; + upb_Arena* arena; + // Initially tracks the count of each field rep type; then, during assignment, + // tracks the base offset for the next processed field of the given rep. + uint16_t rep_counts_offsets[kUpb_FieldRep_Max + 1]; + uint32_t sub_count; + bool is_extension; + + // When building fasttables, we don't know the total size of the table until + // we're done decoding, so we allocate a temporary table on the stack and + // allocate the real thing from the arena later. + upb_MiniTable table; +} upb_MtDecoder; + +// In each field's offset, we temporarily store a presence classifier: +enum PresenceClass { + kNoPresence = 0, + kHasbitPresence = 1, + kRequiredPresence = 2, + kOneofBase = 3, + // Negative values refer to a specific oneof with that number. Positive + // values >= kOneofBase indicate that this field is in a oneof, and specify + // the next field in this oneof's linked list. +}; + +static bool upb_MtDecoder_FieldIsPackable(upb_MiniTableField* field) { + return (field->UPB_PRIVATE(mode) & kUpb_FieldMode_Array) && + upb_FieldType_IsPackable(field->UPB_PRIVATE(descriptortype)); +} + +typedef struct { + uint16_t submsg_count; + uint16_t subenum_count; +} upb_SubCounts; + +static void upb_MiniTable_SetTypeAndSub(upb_MtDecoder* d, + upb_MiniTableField* field, + upb_FieldType type, + uint64_t msg_modifiers, + bool is_proto3_enum) { + if (is_proto3_enum) { + UPB_ASSERT(type == kUpb_FieldType_Enum); + type = kUpb_FieldType_Int32; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; + } else if (type == kUpb_FieldType_String && + !(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) { + type = kUpb_FieldType_Bytes; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; + } + + field->UPB_PRIVATE(descriptortype) = type; + + if (upb_MtDecoder_FieldIsPackable(field) && + (msg_modifiers & kUpb_MessageModifier_DefaultIsPacked)) { + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsPacked; + } + + // We initially set `submsg_ofs` to the index of the sub in the list of subs. + // Later, we'll update it to be a relative byte offset. + if (type == kUpb_FieldType_Message || type == kUpb_FieldType_Group || + type == kUpb_FieldType_Enum) { + field->UPB_PRIVATE(submsg_ofs) = d->sub_count++; + } else { + field->UPB_PRIVATE(submsg_ofs) = kUpb_NoSub; + } +} + +static const char kUpb_EncodedToType[] = { + [kUpb_EncodedType_Double] = kUpb_FieldType_Double, + [kUpb_EncodedType_Float] = kUpb_FieldType_Float, + [kUpb_EncodedType_Int64] = kUpb_FieldType_Int64, + [kUpb_EncodedType_UInt64] = kUpb_FieldType_UInt64, + [kUpb_EncodedType_Int32] = kUpb_FieldType_Int32, + [kUpb_EncodedType_Fixed64] = kUpb_FieldType_Fixed64, + [kUpb_EncodedType_Fixed32] = kUpb_FieldType_Fixed32, + [kUpb_EncodedType_Bool] = kUpb_FieldType_Bool, + [kUpb_EncodedType_String] = kUpb_FieldType_String, + [kUpb_EncodedType_Group] = kUpb_FieldType_Group, + [kUpb_EncodedType_Message] = kUpb_FieldType_Message, + [kUpb_EncodedType_Bytes] = kUpb_FieldType_Bytes, + [kUpb_EncodedType_UInt32] = kUpb_FieldType_UInt32, + [kUpb_EncodedType_OpenEnum] = kUpb_FieldType_Enum, + [kUpb_EncodedType_SFixed32] = kUpb_FieldType_SFixed32, + [kUpb_EncodedType_SFixed64] = kUpb_FieldType_SFixed64, + [kUpb_EncodedType_SInt32] = kUpb_FieldType_SInt32, + [kUpb_EncodedType_SInt64] = kUpb_FieldType_SInt64, + [kUpb_EncodedType_ClosedEnum] = kUpb_FieldType_Enum, +}; + +static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch, + upb_MiniTableField* field, + uint64_t msg_modifiers) { + static const char kUpb_EncodedToFieldRep[] = { + [kUpb_EncodedType_Double] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_Float] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_Int64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_UInt64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_Int32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_Fixed64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_Fixed32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_Bool] = kUpb_FieldRep_1Byte, + [kUpb_EncodedType_String] = kUpb_FieldRep_StringView, + [kUpb_EncodedType_Bytes] = kUpb_FieldRep_StringView, + [kUpb_EncodedType_UInt32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_OpenEnum] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_SFixed32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_SFixed64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_SInt32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_SInt64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_ClosedEnum] = kUpb_FieldRep_4Byte, + }; + + char pointer_rep = d->platform == kUpb_MiniTablePlatform_32Bit + ? kUpb_FieldRep_4Byte + : kUpb_FieldRep_8Byte; + + int8_t type = _upb_FromBase92(ch); + if (ch >= _upb_ToBase92(kUpb_EncodedType_RepeatedBase)) { + type -= kUpb_EncodedType_RepeatedBase; + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Array; + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(offset) = kNoPresence; + } else { + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Scalar; + field->UPB_PRIVATE(offset) = kHasbitPresence; + if (type == kUpb_EncodedType_Group || type == kUpb_EncodedType_Message) { + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; + } else if ((unsigned long)type >= sizeof(kUpb_EncodedToFieldRep)) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid field type: %d", (int)type); + } else { + field->UPB_PRIVATE(mode) |= kUpb_EncodedToFieldRep[type] + << kUpb_FieldRep_Shift; + } + } + if ((unsigned long)type >= sizeof(kUpb_EncodedToType)) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid field type: %d", (int)type); + } + upb_MiniTable_SetTypeAndSub(d, field, kUpb_EncodedToType[type], msg_modifiers, + type == kUpb_EncodedType_OpenEnum); +} + +static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, + uint32_t message_modifiers, + uint32_t field_modifiers, + upb_MiniTableField* field) { + if (field_modifiers & kUpb_EncodedFieldModifier_FlipPacked) { + if (!upb_MtDecoder_FieldIsPackable(field)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Cannot flip packed on unpackable field %" PRIu32, + upb_MiniTableField_Number(field)); + } + field->UPB_PRIVATE(mode) ^= kUpb_LabelFlags_IsPacked; + } + + if (field_modifiers & kUpb_EncodedFieldModifier_FlipValidateUtf8) { + if (field->UPB_PRIVATE(descriptortype) != kUpb_FieldType_Bytes || + !(field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsAlternate)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Cannot flip ValidateUtf8 on field %" PRIu32 + ", type=%d, mode=%d", + upb_MiniTableField_Number(field), + (int)field->UPB_PRIVATE(descriptortype), + (int)field->UPB_PRIVATE(mode)); + } + field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_String; + field->UPB_PRIVATE(mode) &= ~kUpb_LabelFlags_IsAlternate; + } + + bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular; + bool required = field_modifiers & kUpb_EncodedFieldModifier_IsRequired; + + // Validate. + if ((singular || required) && field->UPB_PRIVATE(offset) != kHasbitPresence) { + upb_MdDecoder_ErrorJmp(&d->base, + "Invalid modifier(s) for repeated field %" PRIu32, + upb_MiniTableField_Number(field)); + } + if (singular && required) { + upb_MdDecoder_ErrorJmp( + &d->base, "Field %" PRIu32 " cannot be both singular and required", + upb_MiniTableField_Number(field)); + } + + if (singular && upb_MiniTableField_IsSubMessage(field)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Field %" PRIu32 " cannot be a singular submessage", + upb_MiniTableField_Number(field)); + } + + if (singular) field->UPB_PRIVATE(offset) = kNoPresence; + if (required) { + field->UPB_PRIVATE(offset) = kRequiredPresence; + } +} + +static void upb_MtDecoder_PushOneof(upb_MtDecoder* d, + upb_OneOfLayoutItem item) { + if (item.field_index == kUpb_OneOfLayoutItem_IndexSentinel) { + upb_MdDecoder_ErrorJmp(&d->base, "Empty oneof"); + } + if ((d->oneofs.size + 1) * sizeof(*d->oneofs.data) > + d->oneofs.buf_capacity_bytes) { + size_t new_cap = UPB_MAX(8, d->oneofs.size * 2) * sizeof(*d->oneofs.data); + d->oneofs.data = + upb_grealloc(d->oneofs.data, d->oneofs.buf_capacity_bytes, new_cap); + upb_MdDecoder_CheckOutOfMemory(&d->base, d->oneofs.data); + d->oneofs.buf_capacity_bytes = new_cap; + } + item.field_index -= kOneofBase; + + d->rep_counts_offsets[kUpb_OneOf_CaseFieldRep]++; + d->rep_counts_offsets[item.rep]++; + d->oneofs.data[d->oneofs.size++] = item; +} + +static size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep, + upb_MiniTablePlatform platform) { + enum { string_view_size_32 = 8, string_view_size_64 = 16 }; + UPB_STATIC_ASSERT(sizeof(upb_StringView) == + UPB_SIZE(string_view_size_32, string_view_size_64), + "StringView size mismatch"); + static const uint8_t kRepToSize32[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_size_32, + [kUpb_FieldRep_8Byte] = 8, + }; + static const uint8_t kRepToSize64[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_size_64, + [kUpb_FieldRep_8Byte] = 8, + }; + return platform == kUpb_MiniTablePlatform_32Bit ? kRepToSize32[rep] + : kRepToSize64[rep]; +} + +static size_t upb_MtDecoder_AlignOfRep(upb_FieldRep rep, + upb_MiniTablePlatform platform) { + enum { string_view_align_32 = 4, string_view_align_64 = 8 }; + UPB_STATIC_ASSERT(UPB_ALIGN_OF(upb_StringView) == + UPB_SIZE(string_view_align_32, string_view_align_64), + "StringView size mismatch"); + + static const uint8_t kRepToAlign32[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_align_32, + [kUpb_FieldRep_8Byte] = 8, + }; + static const uint8_t kRepToAlign64[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_align_64, + [kUpb_FieldRep_8Byte] = 8, + }; + return platform == kUpb_MiniTablePlatform_32Bit ? kRepToAlign32[rep] + : kRepToAlign64[rep]; +} + +static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d, + const char* ptr, + char first_ch, + upb_OneOfLayoutItem* item) { + uint32_t field_num; + ptr = upb_MdDecoder_DecodeBase92Varint( + &d->base, ptr, first_ch, kUpb_EncodedValue_MinOneofField, + kUpb_EncodedValue_MaxOneofField, &field_num); + upb_MiniTableField* f = + (void*)upb_MiniTable_FindFieldByNumber(&d->table, field_num); + + if (!f) { + upb_MdDecoder_ErrorJmp(&d->base, + "Couldn't add field number %" PRIu32 + " to oneof, no such field number.", + field_num); + } + if (f->UPB_PRIVATE(offset) != kHasbitPresence) { + upb_MdDecoder_ErrorJmp( + &d->base, + "Cannot add repeated, required, or singular field %" PRIu32 + " to oneof.", + field_num); + } + + // Oneof storage must be large enough to accommodate the largest member. + int rep = f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift; + size_t new_size = upb_MtDecoder_SizeOfRep(rep, d->platform); + size_t new_align = upb_MtDecoder_AlignOfRep(rep, d->platform); + size_t current_size = upb_MtDecoder_SizeOfRep(item->rep, d->platform); + size_t current_align = upb_MtDecoder_AlignOfRep(item->rep, d->platform); + + if (new_size > current_size || + (new_size == current_size && new_align > current_align)) { + UPB_ASSERT(new_align >= current_align); + item->rep = rep; + } else { + UPB_ASSERT(current_align >= new_align); + } + // Prepend this field to the linked list. + f->UPB_PRIVATE(offset) = item->field_index; + item->field_index = (f - d->fields) + kOneofBase; + return ptr; +} + +static const char* upb_MtDecoder_DecodeOneofs(upb_MtDecoder* d, + const char* ptr) { + upb_OneOfLayoutItem item = { + .rep = 0, .field_index = kUpb_OneOfLayoutItem_IndexSentinel}; + while (ptr < d->base.end) { + char ch = *ptr++; + if (ch == kUpb_EncodedValue_FieldSeparator) { + // Field separator, no action needed. + } else if (ch == kUpb_EncodedValue_OneofSeparator) { + // End of oneof. + upb_MtDecoder_PushOneof(d, item); + item.field_index = + kUpb_OneOfLayoutItem_IndexSentinel; // Move to next oneof. + } else { + ptr = upb_MtDecoder_DecodeOneofField(d, ptr, ch, &item); + } + } + + // Push final oneof. + upb_MtDecoder_PushOneof(d, item); + return ptr; +} + +static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d, + const char* ptr, char first_ch, + upb_MiniTableField* last_field, + uint64_t* msg_modifiers) { + uint32_t mod; + ptr = upb_MdDecoder_DecodeBase92Varint(&d->base, ptr, first_ch, + kUpb_EncodedValue_MinModifier, + kUpb_EncodedValue_MaxModifier, &mod); + if (last_field) { + upb_MtDecoder_ModifyField(d, *msg_modifiers, mod, last_field); + } else { + if (d->is_extension) { + upb_MdDecoder_ErrorJmp(&d->base, + "Extensions cannot have message modifiers"); + } + *msg_modifiers = mod; + } + + return ptr; +} + +size_t upb_MtDecoder_PtrSize(upb_MtDecoder* d) { + return d->platform == kUpb_MiniTablePlatform_32Bit ? 4 : 8; +} + +static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, + upb_MiniTableSubInternal* subs) { + // The `ofs` variable tracks byte offset between the current field and the + // current entry in the `subs` array. Whenever we move to the next entry in + // the `fields` array, the offset decreases by the size of the field, but + // whenever we move to the next entry in the `subs` array, the offset + // *increases* by the size of the entry in the `subs` array. + UPB_ASSERT((char*)subs >= (char*)d->fields); + size_t ofs = (char*)subs - (char*)d->fields; + uintptr_t ptr_size = upb_MtDecoder_PtrSize(d); + for (int i = 0; i < d->table.UPB_PRIVATE(field_count); + i++, ofs -= sizeof(upb_MiniTableField)) { + upb_MiniTableField* f = &d->fields[i]; + if (f->UPB_PRIVATE(submsg_ofs) == kUpb_NoSub) continue; + size_t u32_ofs = ofs / kUpb_SubmsgOffsetBytes; + UPB_ASSERT((ofs % 4) == 0); + UPB_ASSERT((i * sizeof(upb_MiniTableField) + ofs) % ptr_size == 0); + if (u32_ofs > UINT16_MAX) { + upb_MdDecoder_ErrorJmp(&d->base, "Submessage offset overflow"); + } + f->UPB_PRIVATE(submsg_ofs) = u32_ofs; + ofs += ptr_size; + } +} + +static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, + size_t len, void* fields, + size_t field_size, + uint16_t* field_count) { + uint64_t msg_modifiers = 0; + uint32_t last_field_number = 0; + upb_MiniTableField* last_field = NULL; + bool need_dense_below = !d->is_extension; + + d->base.end = UPB_PTRADD(ptr, len); + + while (ptr < d->base.end) { + char ch = *ptr++; + if (ch <= kUpb_EncodedValue_MaxField) { + if (d->is_extension && last_field) { + // For extensions, consume only a single field and then return. + return --ptr; + } + upb_MiniTableField* field = fields; + *field_count += 1; + fields = (char*)fields + field_size; + uint32_t number = ++last_field_number; + if (number == 0 || (number > kUpb_MaxFieldNumber && !d->is_extension)) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid field number: %" PRIu32, + number); + } + field->UPB_PRIVATE(number) = number; + last_field = field; + upb_MiniTable_SetField(d, ch, field, msg_modifiers); + } else if (kUpb_EncodedValue_MinModifier <= ch && + ch <= kUpb_EncodedValue_MaxModifier) { + ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers); + if (msg_modifiers & kUpb_MessageModifier_IsExtendable) { + d->table.UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable; + } + } else if (ch == kUpb_EncodedValue_End) { + if (d->is_extension) { + upb_MdDecoder_ErrorJmp(&d->base, "Extensions cannot have oneofs."); + } + ptr = upb_MtDecoder_DecodeOneofs(d, ptr); + } else if (kUpb_EncodedValue_MinSkip <= ch && + ch <= kUpb_EncodedValue_MaxSkip) { + if (need_dense_below) { + d->table.UPB_PRIVATE(dense_below) = d->table.UPB_PRIVATE(field_count); + need_dense_below = false; + } + uint32_t skip; + ptr = upb_MdDecoder_DecodeBase92Varint(&d->base, ptr, ch, + kUpb_EncodedValue_MinSkip, + kUpb_EncodedValue_MaxSkip, &skip); + last_field_number += skip; + last_field_number--; // Next field seen will increment. + } else { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid char: %c", ch); + } + } + + if (need_dense_below) { + d->table.UPB_PRIVATE(dense_below) = d->table.UPB_PRIVATE(field_count); + } + + return ptr; +} + +static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, + size_t len) { + const size_t bytes_per_field = + sizeof(upb_MiniTableField) + sizeof(upb_MiniTableSubInternal); + // Buffer length is an upper bound on the number of fields. We will return + // what we don't use. + if ((SIZE_MAX - 4) / bytes_per_field < len) { + upb_MdDecoder_ErrorJmp(&d->base, "MiniDescriptor is too large"); + } + // Max size used per field is a upb_MiniTableField and a + // upb_MiniTableSubInternal. There could also be up to 4 bytes of padding, + // since sizeof(upb_MiniTableField) == 12 and + // alignof(upb_MiniTableSubInternal) == 8. + UPB_STATIC_ASSERT(UPB_ALIGN_OF(upb_MiniTableSubInternal) - + UPB_ALIGN_OF(upb_MiniTableField) <= + 4, + "alignment difference is too large"); + const size_t initial_bytes = bytes_per_field * len + 4; + d->fields = upb_Arena_Malloc(d->arena, initial_bytes); + upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); + + d->table.UPB_PRIVATE(field_count) = 0; + d->table.UPB_PRIVATE(fields) = d->fields; + upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields), + &d->table.UPB_PRIVATE(field_count)); + size_t field_bytes = + UPB_ALIGN_UP(d->table.UPB_PRIVATE(field_count) * sizeof(*d->fields), + upb_MtDecoder_PtrSize(d)); + upb_MiniTableSubInternal* subs = + UPB_PTR_AT(d->fields, field_bytes, upb_MiniTableSubInternal); + memset(subs, 0, sizeof(upb_MiniTableSubInternal) * d->sub_count); + + // We now know how much space we actually used, so shrink the allocation to + // that size. + size_t final_bytes = + field_bytes + sizeof(upb_MiniTableSubInternal) * d->sub_count; + upb_Arena_ShrinkLast(d->arena, d->fields, initial_bytes, final_bytes); + upb_MtDecoder_AllocateSubs(d, subs); +} + +static void upb_MtDecoder_CalculateAlignments(upb_MtDecoder* d) { + // Add alignment counts for non-oneof fields (oneofs were added already) + int n = d->table.UPB_PRIVATE(field_count); + for (int i = 0; i < n; i++) { + upb_MiniTableField* f = &d->fields[i]; + if (f->UPB_PRIVATE(offset) >= kOneofBase) continue; + d->rep_counts_offsets[f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift]++; + } + + // Reserve properly aligned space for each type of field representation + // present in this message. When we iterate over the fields, they will obtain + // their offset from within the region matching their alignment requirements. + size_t base = d->table.UPB_PRIVATE(size); + // Start with the lowest alignment requirement, going up, because: + // 1. If there are presence bits, we won't be aligned to start, but adding + // some lower-alignment fields may get us closer without wasting space to + // padding. + // 2. The allocator enforces 8 byte alignment, so moving intermediate padding + // to trailing padding doesn't save us anything. + for (upb_FieldRep rep = kUpb_FieldRep_1Byte; rep <= kUpb_FieldRep_Max; + rep++) { + uint16_t count = d->rep_counts_offsets[rep]; + if (count) { + base = UPB_ALIGN_UP(base, upb_MtDecoder_AlignOfRep(rep, d->platform)); + // This entry now tracks the base offset for this field representation + // type, instead of the count + d->rep_counts_offsets[rep] = base; + base += upb_MtDecoder_SizeOfRep(rep, d->platform) * count; + } + } + static const size_t max = UINT16_MAX; + if (base > max) { + upb_MdDecoder_ErrorJmp( + &d->base, "Message size exceeded maximum size of %zu bytes", max); + } + d->table.UPB_PRIVATE(size) = (uint16_t)base; +} + +static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) { + return (n + d - 1) / d; +} + +static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { + int n = d->table.UPB_PRIVATE(field_count); + size_t last_hasbit = kUpb_Reserved_Hasbits - 1; + + // First assign required fields, which must have the lowest hasbits. + for (int i = 0; i < n; i++) { + upb_MiniTableField* field = + (upb_MiniTableField*)&d->table.UPB_PRIVATE(fields)[i]; + if (field->UPB_PRIVATE(offset) == kRequiredPresence) { + field->presence = ++last_hasbit; + } else if (field->UPB_PRIVATE(offset) == kNoPresence) { + field->presence = 0; + } + } + if (last_hasbit >= kUpb_Reserved_Hasbits + 63) { + upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields"); + } + + d->table.UPB_PRIVATE(required_count) = + last_hasbit - (kUpb_Reserved_Hasbits - 1); + UPB_ASSERT(d->table.UPB_PRIVATE(required_count) < 64); + + // Next assign non-required hasbit fields. + for (int i = 0; i < n; i++) { + upb_MiniTableField* field = + (upb_MiniTableField*)&d->table.UPB_PRIVATE(fields)[i]; + if (field->UPB_PRIVATE(offset) == kHasbitPresence) { + field->presence = ++last_hasbit; + } + } + + d->table.UPB_PRIVATE(size) = + last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0; +} + +static size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) { + size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform); + size_t offset = d->rep_counts_offsets[rep]; + d->rep_counts_offsets[rep] += size; + return offset; +} + +static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { + upb_MiniTableField* field_end = + UPB_PTRADD(d->fields, d->table.UPB_PRIVATE(field_count)); + for (upb_MiniTableField* field = d->fields; field < field_end; field++) { + if (field->UPB_PRIVATE(offset) >= kOneofBase) continue; + field->UPB_PRIVATE(offset) = + upb_MtDecoder_Place(d, field->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift); + } + + upb_OneOfLayoutItem* oneof_end = UPB_PTRADD(d->oneofs.data, d->oneofs.size); + + for (upb_OneOfLayoutItem* item = d->oneofs.data; item < oneof_end; item++) { + upb_MiniTableField* f = &d->fields[item->field_index]; + uint16_t case_offset = upb_MtDecoder_Place(d, kUpb_OneOf_CaseFieldRep); + uint16_t data_offset = upb_MtDecoder_Place(d, item->rep); + while (true) { + f->presence = ~case_offset; + uint16_t next_offset = f->UPB_PRIVATE(offset); + f->UPB_PRIVATE(offset) = data_offset; + if (next_offset == kUpb_OneOfLayoutItem_IndexSentinel) break; + UPB_ASSERT(next_offset - kOneofBase < d->table.UPB_PRIVATE(field_count)); + f = &d->fields[next_offset - kOneofBase]; + } + } + + // Since messages are always allocated on arenas, we can save repeatedly + // realigning by doing alignment at minitable construction time. We don't want + // to align to UPB_MALLOC_ALIGN because it can change with sanitizers, and if + // we're generating code we don't want to calculate size differently depending + // on the proto compiler's host or build configuration. + d->table.UPB_PRIVATE(size) = + UPB_ALIGN_UP(d->table.UPB_PRIVATE(size), kUpb_Message_Align); +} + +static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d, + const upb_MiniTableField* f, + uint32_t expected_num) { + const char* name = expected_num == 1 ? "key" : "val"; + const uint32_t f_number = upb_MiniTableField_Number(f); + if (f_number != expected_num) { + upb_MdDecoder_ErrorJmp(&d->base, + "map %s did not have expected number (%d vs %d)", + name, expected_num, f_number); + } + + if (!upb_MiniTableField_IsScalar(f)) { + upb_MdDecoder_ErrorJmp( + &d->base, "map %s cannot be repeated or map, or be in oneof", name); + } + + uint32_t not_ok_types; + if (expected_num == 1) { + not_ok_types = (1 << kUpb_FieldType_Float) | (1 << kUpb_FieldType_Double) | + (1 << kUpb_FieldType_Message) | (1 << kUpb_FieldType_Group) | + (1 << kUpb_FieldType_Bytes) | (1 << kUpb_FieldType_Enum); + } else { + not_ok_types = 1 << kUpb_FieldType_Group; + } + + if ((1 << upb_MiniTableField_Type(f)) & not_ok_types) { + upb_MdDecoder_ErrorJmp(&d->base, "map %s cannot have type %d", name, + (int)f->UPB_PRIVATE(descriptortype)); + } +} + +static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, + size_t len) { + upb_MtDecoder_ParseMessage(d, data, len); + upb_MtDecoder_AssignHasbits(d); + + if (UPB_UNLIKELY(d->table.UPB_PRIVATE(field_count) != 2)) { + upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map", + d->table.UPB_PRIVATE(field_count)); + UPB_UNREACHABLE(); + } + + if (d->oneofs.size != 0) { + upb_MdDecoder_ErrorJmp(&d->base, "Map entry cannot have oneof"); + } + + upb_MtDecoder_ValidateEntryField(d, &d->table.UPB_PRIVATE(fields)[0], 1); + upb_MtDecoder_ValidateEntryField(d, &d->table.UPB_PRIVATE(fields)[1], 2); + + d->fields[0].UPB_PRIVATE(offset) = offsetof(upb_MapEntry, k); + d->fields[1].UPB_PRIVATE(offset) = offsetof(upb_MapEntry, v); + d->table.UPB_PRIVATE(size) = sizeof(upb_MapEntry); + + // Map entries have a special bit set to signal it's a map entry, used in + // upb_MiniTable_SetSubMessage() below. + d->table.UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry; +} + +static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, + size_t len) { + if (len > 0) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid message set encode length: %zu", + len); + } + + upb_MiniTable* ret = &d->table; + ret->UPB_PRIVATE(size) = kUpb_Reserved_Hasbytes; + ret->UPB_PRIVATE(field_count) = 0; + ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet; + ret->UPB_PRIVATE(dense_below) = 0; + ret->UPB_PRIVATE(table_mask) = -1; + ret->UPB_PRIVATE(required_count) = 0; +} + +static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( + upb_MtDecoder* decoder, const char* data, size_t len, void** buf, + size_t* buf_size) { + decoder->table.UPB_PRIVATE(size) = kUpb_Reserved_Hasbytes; + decoder->table.UPB_PRIVATE(field_count) = 0; + decoder->table.UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable; + decoder->table.UPB_PRIVATE(dense_below) = 0; + decoder->table.UPB_PRIVATE(table_mask) = -1; + decoder->table.UPB_PRIVATE(required_count) = 0; +#ifdef UPB_TRACING_ENABLED + // MiniTables built from MiniDescriptors will not be able to vend the message + // name unless it is explicitly set with upb_MiniTable_SetFullName(). + decoder->table.UPB_PRIVATE(full_name) = 0; +#endif + + // Strip off and verify the version tag. + if (!len--) goto done; + const char vers = *data++; + + switch (vers) { + case kUpb_EncodedVersion_MapV1: + upb_MtDecoder_ParseMap(decoder, data, len); + break; + + case kUpb_EncodedVersion_MessageV1: + upb_MtDecoder_ParseMessage(decoder, data, len); + upb_MtDecoder_AssignHasbits(decoder); + upb_MtDecoder_CalculateAlignments(decoder); + upb_MtDecoder_AssignOffsets(decoder); + break; + + case kUpb_EncodedVersion_MessageSetV1: + upb_MtDecoder_ParseMessageSet(decoder, data, len); + break; + + default: + upb_MdDecoder_ErrorJmp(&decoder->base, "Invalid message version: %c", + vers); + } + +done: + *buf = decoder->oneofs.data; + *buf_size = decoder->oneofs.buf_capacity_bytes; + size_t mt_size = sizeof(upb_MiniTable); + +#if UPB_FASTTABLE + upb_DecodeFast_TableEntry fasttable[32]; + int fasttable_size = upb_DecodeFast_BuildTable(&decoder->table, fasttable); + mt_size += fasttable_size * sizeof(fasttable[0]); +#endif + + upb_MiniTable* ret = upb_Arena_Malloc(decoder->arena, mt_size); + memcpy(ret, &decoder->table, sizeof(*ret)); + +#if UPB_FASTTABLE + ret->UPB_PRIVATE(table_mask) = upb_DecodeFast_GetTableMask(fasttable_size); + for (int i = 0; i < fasttable_size; i++) { + ret->UPB_PRIVATE(fasttable)[i].field_data = fasttable[i].function_data; + ret->UPB_PRIVATE(fasttable)[i].field_parser = + upb_DecodeFast_GetFunctionPointer(fasttable[i].function_idx); + } +#endif + UPB_PRIVATE(upb_MiniTable_CheckInvariants)(ret); + return ret; +} + +static upb_MiniTable* upb_MtDecoder_BuildMiniTableWithBuf( + upb_MtDecoder* const decoder, const char* const data, const size_t len, + void** const buf, size_t* const buf_size) { + if (UPB_SETJMP(decoder->base.err) != 0) { + *buf = decoder->oneofs.data; + *buf_size = decoder->oneofs.buf_capacity_bytes; + return NULL; + } + + return upb_MtDecoder_DoBuildMiniTableWithBuf(decoder, data, len, buf, + buf_size); +} + +upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, void** buf, + size_t* buf_size, + upb_Status* status) { + upb_MtDecoder decoder = { + .base = {.status = status}, + .platform = platform, + .sub_count = 0, + .is_extension = false, + .oneofs = + { + .data = *buf, + .buf_capacity_bytes = *buf_size, + .size = 0, + }, + .arena = arena, + }; + + return upb_MtDecoder_BuildMiniTableWithBuf(&decoder, data, len, buf, + buf_size); +} + +static const char* upb_MtDecoder_DoBuildMiniTableExtension( + upb_MtDecoder* decoder, const char* data, size_t len, + upb_MiniTableExtension* ext, const upb_MiniTable* extendee, + upb_MiniTableSub sub) { + if (!(extendee->UPB_PRIVATE(ext) & + (kUpb_ExtMode_Extendable | kUpb_ExtMode_IsMessageSet))) { + upb_MdDecoder_ErrorJmp(&decoder->base, "Extendee is not extendable"); + } + + // If the string is non-empty then it must begin with a version tag. + if (len) { + if (*data != kUpb_EncodedVersion_ExtensionV1) { + upb_MdDecoder_ErrorJmp(&decoder->base, "Invalid ext version: %c", *data); + } + data++; + len--; + } + + uint16_t count = 0; + const char* ret = + upb_MtDecoder_Parse(decoder, data, len, ext, sizeof(*ext), &count); + if (!ret || count != 1) return NULL; + + upb_MiniTableField* f = &ext->UPB_PRIVATE(field); + + f->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsExtension; + f->UPB_PRIVATE(offset) = 0; + f->presence = 0; + + // In upb_MiniTableExtension, the `sub` member is a pointer-sized member that + // directly follows the `field` member. + f->UPB_PRIVATE(submsg_ofs) = + UPB_ALIGN_UP(sizeof(upb_MiniTableField), upb_MtDecoder_PtrSize(decoder)) / + kUpb_SubmsgOffsetBytes; + + if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) { + // Extensions of MessageSet must be messages. + if (!upb_MiniTableField_IsSubMessage(f)) return NULL; + + // Extensions of MessageSet must be non-repeating. + if (upb_MiniTableField_IsArray(f)) return NULL; + } + + ext->UPB_PRIVATE(extendee) = extendee; + ext->UPB_PRIVATE(sub) = sub; + + return ret; +} + +static const char* upb_MtDecoder_BuildMiniTableExtension( + upb_MtDecoder* const decoder, const char* const data, const size_t len, + upb_MiniTableExtension* const ext, const upb_MiniTable* const extendee, + const upb_MiniTableSub sub) { + if (UPB_SETJMP(decoder->base.err) != 0) return NULL; + return upb_MtDecoder_DoBuildMiniTableExtension(decoder, data, len, ext, + extendee, sub); +} + +const char* _upb_MiniTableExtension_Init(const char* data, size_t len, + upb_MiniTableExtension* ext, + const upb_MiniTable* extendee, + upb_MiniTableSub sub, + upb_MiniTablePlatform platform, + upb_Status* status) { + upb_MtDecoder decoder = { + .base = {.status = status}, + .arena = NULL, + .platform = platform, + .sub_count = 0, + .is_extension = true, + }; + + return upb_MtDecoder_BuildMiniTableExtension(&decoder, data, len, ext, + extendee, sub); +} + +upb_MiniTableExtension* _upb_MiniTableExtension_Build( + const char* data, size_t len, const upb_MiniTable* extendee, + upb_MiniTableSub sub, upb_MiniTablePlatform platform, upb_Arena* arena, + upb_Status* status) { + upb_MiniTableExtension* ext = + upb_Arena_Malloc(arena, sizeof(upb_MiniTableExtension)); + if (UPB_UNLIKELY(!ext)) return NULL; + + const char* ptr = _upb_MiniTableExtension_Init(data, len, ext, extendee, sub, + platform, status); + if (UPB_UNLIKELY(!ptr)) return NULL; + + return ext; +} + +upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, upb_Status* status) { + void* buf = NULL; + size_t size = 0; + upb_MiniTable* ret = upb_MiniTable_BuildWithBuf(data, len, platform, arena, + &buf, &size, status); + upb_gfree(buf); + return ret; +} + + +#include +#include +#include + + +// Must be last. + +bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, + upb_MiniTableField* field, + const upb_MiniTable* sub) { + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); + UPB_ASSERT(sub); + + const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; + + switch (field->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Message: + if (sub_is_map) { + const bool table_is_map = + table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; + if (UPB_UNLIKELY(table_is_map)) return false; + + field->UPB_PRIVATE(mode) = + (field->UPB_PRIVATE(mode) & ~kUpb_FieldMode_Mask) | + kUpb_FieldMode_Map; + } + break; + + case kUpb_FieldType_Group: + if (UPB_UNLIKELY(sub_is_map)) return false; + break; + + default: + return false; + } + + upb_MiniTableSubInternal* table_sub = + UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + // TODO: Add this assert back once YouTube is updated to not call + // this function repeatedly. + // UPB_ASSERT(upb_MiniTable_GetSubMessageTable(table, field) == NULL); + table_sub->UPB_PRIVATE(submsg) = sub; + return true; +} + +bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, + const upb_MiniTableEnum* sub) { + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); + UPB_ASSERT(sub); + + if (field->UPB_PRIVATE(descriptortype) != kUpb_FieldType_Enum) { + return false; + } + + if ((table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry) && + !upb_MiniTableEnum_CheckValue(sub, 0)) { + // An enum used in a map must include 0 as a value. This matches a check + // performed in protoc ("Enum value in map must define 0 as the first + // value"). Protoc should ensure that we never get here. + // + // This ends up being important if we receive wire messages where a map + // entry omits the value (and thus defaults to 0). + return false; + } + + upb_MiniTableSubInternal* table_sub = + UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + *table_sub = upb_MiniTableSub_FromEnum(sub); + return true; +} + +uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* m, + const upb_MiniTableField** subs) { + uint32_t msg_count = 0; + uint32_t enum_count = 0; + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { + *subs = f; + ++subs; + msg_count++; + } + } + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_IsClosedEnum(f)) { + *subs = f; + ++subs; + enum_count++; + } + } + + return (msg_count << 16) | enum_count; +} + +// The list of sub_tables and sub_enums must exactly match the number and order +// of sub-message fields and sub-enum fields given by upb_MiniTable_GetSubList() +// above. +bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables, + size_t sub_table_count, + const upb_MiniTableEnum** sub_enums, + size_t sub_enum_count) { + uint32_t msg_count = 0; + uint32_t enum_count = 0; + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + upb_MiniTableField* f = + (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { + const upb_MiniTable* sub = sub_tables[msg_count++]; + if (msg_count > sub_table_count) return false; + if (sub && !upb_MiniTable_SetSubMessage(m, f, sub)) return false; + } + } + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + upb_MiniTableField* f = + (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_IsClosedEnum(f)) { + const upb_MiniTableEnum* sub = sub_enums[enum_count++]; + if (enum_count > sub_enum_count) return false; + if (sub && !upb_MiniTable_SetSubEnum(m, f, sub)) return false; + } + } + + return (msg_count == sub_table_count) && (enum_count == sub_enum_count); +} + + +const char _kUpb_ToBase92[] = { + ' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', + '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '{', '|', '}', '~', +}; + +const int8_t _kUpb_FromBase92[] = { + 0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, -1, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +}; + + +#include +#include +#include + + +// Must be last. + +typedef struct { + uint64_t present_values_mask; + uint32_t last_written_value; +} upb_MtDataEncoderInternal_EnumState; + +typedef struct { + uint64_t msg_modifiers; + uint32_t last_field_num; + enum { + kUpb_OneofState_NotStarted, + kUpb_OneofState_StartedOneof, + kUpb_OneofState_EmittedOneofField, + } oneof_state; +} upb_MtDataEncoderInternal_MsgState; + +typedef struct { + char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize. + union { + upb_MtDataEncoderInternal_EnumState enum_state; + upb_MtDataEncoderInternal_MsgState msg_state; + } state; +} upb_MtDataEncoderInternal; + +static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal( + upb_MtDataEncoder* e, char* buf_start) { + UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal)); + upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal; + ret->buf_start = buf_start; + return ret; +} + +static char* upb_MtDataEncoder_PutRaw(upb_MtDataEncoder* e, char* ptr, + char ch) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize); + if (ptr == e->end) return NULL; + *ptr++ = ch; + return ptr; +} + +static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) { + return upb_MtDataEncoder_PutRaw(e, ptr, _upb_ToBase92(ch)); +} + +static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr, + uint32_t val, int min, int max) { + int shift = upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min) + 1); + UPB_ASSERT(shift <= 6); + uint32_t mask = (1 << shift) - 1; + do { + uint32_t bits = val & mask; + ptr = upb_MtDataEncoder_Put(e, ptr, bits + _upb_FromBase92(min)); + if (!ptr) return NULL; + val >>= shift; + } while (val); + return ptr; +} + +char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr, + uint64_t mod) { + if (mod) { + ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod, + kUpb_EncodedValue_MinModifier, + kUpb_EncodedValue_MaxModifier); + } + return ptr; +} + +char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.msg_state.msg_modifiers = 0; + in->state.msg_state.last_field_num = 0; + in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted; + + ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_ExtensionV1); + if (!ptr) return NULL; + + return upb_MtDataEncoder_PutField(e, ptr, type, field_num, field_mod); +} + +char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr, + upb_FieldType key_type, + upb_FieldType value_type, uint64_t key_mod, + uint64_t value_mod) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.msg_state.msg_modifiers = 0; + in->state.msg_state.last_field_num = 0; + in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted; + + ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MapV1); + if (!ptr) return NULL; + + ptr = upb_MtDataEncoder_PutField(e, ptr, key_type, 1, key_mod); + if (!ptr) return NULL; + + return upb_MtDataEncoder_PutField(e, ptr, value_type, 2, value_mod); +} + +char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr) { + (void)upb_MtDataEncoder_GetInternal(e, ptr); + return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageSetV1); +} + +char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr, + uint64_t msg_mod) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.msg_state.msg_modifiers = msg_mod; + in->state.msg_state.last_field_num = 0; + in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted; + + ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageV1); + if (!ptr) return NULL; + + return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod); +} + +static char* _upb_MtDataEncoder_MaybePutFieldSkip(upb_MtDataEncoder* e, + char* ptr, + uint32_t field_num) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + if (field_num <= in->state.msg_state.last_field_num) return NULL; + if (in->state.msg_state.last_field_num + 1 != field_num) { + // Put skip. + UPB_ASSERT(field_num > in->state.msg_state.last_field_num); + uint32_t skip = field_num - in->state.msg_state.last_field_num; + ptr = upb_MtDataEncoder_PutBase92Varint( + e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip); + if (!ptr) return NULL; + } + in->state.msg_state.last_field_num = field_num; + return ptr; +} + +static char* _upb_MtDataEncoder_PutFieldType(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, + uint64_t field_mod) { + static const char kUpb_TypeToEncoded[] = { + [kUpb_FieldType_Double] = kUpb_EncodedType_Double, + [kUpb_FieldType_Float] = kUpb_EncodedType_Float, + [kUpb_FieldType_Int64] = kUpb_EncodedType_Int64, + [kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64, + [kUpb_FieldType_Int32] = kUpb_EncodedType_Int32, + [kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64, + [kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32, + [kUpb_FieldType_Bool] = kUpb_EncodedType_Bool, + [kUpb_FieldType_String] = kUpb_EncodedType_String, + [kUpb_FieldType_Group] = kUpb_EncodedType_Group, + [kUpb_FieldType_Message] = kUpb_EncodedType_Message, + [kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes, + [kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32, + [kUpb_FieldType_Enum] = kUpb_EncodedType_OpenEnum, + [kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32, + [kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64, + [kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32, + [kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64, + }; + + int encoded_type = kUpb_TypeToEncoded[type]; + + if (field_mod & kUpb_FieldModifier_IsClosedEnum) { + UPB_ASSERT(type == kUpb_FieldType_Enum); + encoded_type = kUpb_EncodedType_ClosedEnum; + } + + if (field_mod & kUpb_FieldModifier_IsRepeated) { + // Repeated fields shift the type number up (unlike other modifiers which + // are bit flags). + encoded_type += kUpb_EncodedType_RepeatedBase; + } + + return upb_MtDataEncoder_Put(e, ptr, encoded_type); +} + +static char* _upb_MtDataEncoder_MaybePutModifiers(upb_MtDataEncoder* e, + char* ptr, upb_FieldType type, + uint64_t field_mod) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + uint32_t encoded_modifiers = 0; + if ((field_mod & kUpb_FieldModifier_IsRepeated) && + upb_FieldType_IsPackable(type)) { + bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked; + bool default_is_packed = in->state.msg_state.msg_modifiers & + kUpb_MessageModifier_DefaultIsPacked; + if (field_is_packed != default_is_packed) { + encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked; + } + } + + if (type == kUpb_FieldType_String) { + bool field_validates_utf8 = field_mod & kUpb_FieldModifier_ValidateUtf8; + bool message_validates_utf8 = + in->state.msg_state.msg_modifiers & kUpb_MessageModifier_ValidateUtf8; + if (field_validates_utf8 != message_validates_utf8) { + // Old binaries do not recognize the field modifier. We need the failure + // mode to be too lax rather than too strict. Our caller should have + // handled this (see _upb_MessageDef_ValidateUtf8()). + assert(!message_validates_utf8); + encoded_modifiers |= kUpb_EncodedFieldModifier_FlipValidateUtf8; + } + } + + if (field_mod & kUpb_FieldModifier_IsProto3Singular) { + encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular; + } + + if (field_mod & kUpb_FieldModifier_IsRequired) { + encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired; + } + + return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers); +} + +char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod) { + upb_MtDataEncoder_GetInternal(e, ptr); + + ptr = _upb_MtDataEncoder_MaybePutFieldSkip(e, ptr, field_num); + if (!ptr) return NULL; + + ptr = _upb_MtDataEncoder_PutFieldType(e, ptr, type, field_mod); + if (!ptr) return NULL; + + return _upb_MtDataEncoder_MaybePutModifiers(e, ptr, type, field_mod); +} + +char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) { + ptr = upb_MtDataEncoder_Put(e, ptr, _upb_FromBase92(kUpb_EncodedValue_End)); + } else { + ptr = upb_MtDataEncoder_Put( + e, ptr, _upb_FromBase92(kUpb_EncodedValue_OneofSeparator)); + } + in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof; + return ptr; +} + +char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr, + uint32_t field_num) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) { + ptr = upb_MtDataEncoder_Put( + e, ptr, _upb_FromBase92(kUpb_EncodedValue_FieldSeparator)); + if (!ptr) return NULL; + } + ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, _upb_ToBase92(0), + _upb_ToBase92(63)); + in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField; + return ptr; +} + +char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.enum_state.present_values_mask = 0; + in->state.enum_state.last_written_value = 0; + + return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_EnumV1); +} + +static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e, + char* ptr) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask); + in->state.enum_state.present_values_mask = 0; + in->state.enum_state.last_written_value += 5; + return ptr; +} + +char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr, + uint32_t val) { + // TODO: optimize this encoding. + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + UPB_ASSERT(val >= in->state.enum_state.last_written_value); + uint32_t delta = val - in->state.enum_state.last_written_value; + if (delta >= 5 && in->state.enum_state.present_values_mask) { + ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr); + if (!ptr) { + return NULL; + } + delta -= 5; + } + + if (delta >= 5) { + ptr = upb_MtDataEncoder_PutBase92Varint( + e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip); + in->state.enum_state.last_written_value += delta; + delta = 0; + } + + UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0); + in->state.enum_state.present_values_mask |= 1ULL << delta; + return ptr; +} + +char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + if (!in->state.enum_state.present_values_mask) return ptr; + return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr); +} + + +#include +#include +#include + + +// Must be last. + +struct upb_ExtensionRegistry { + upb_exttable exts; + upb_Arena* arena; +}; + +upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { + upb_ExtensionRegistry* r = upb_Arena_Malloc(arena, sizeof(*r)); + if (!r) return NULL; + r->arena = arena; + if (!upb_exttable_init(&r->exts, 8, arena)) return NULL; + return r; +} + +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) { + UPB_STATIC_ASSERT( + offsetof(upb_MiniTableExtension, + UPB_PRIVATE(field).UPB_PRIVATE(number)) == 0, + "Extension must be first-member-of-struct convertable with uint32_t"); + uint32_t fieldnum = upb_MiniTableExtension_Number(e); + const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(e); + + const uint32_t kMaxFieldNumber = (1 << 29) - 1; + if (fieldnum == 0 || + (fieldnum > kMaxFieldNumber && !upb_MiniTable_IsMessageSet(extendee))) { + return kUpb_ExtensionRegistryStatus_InvalidExtension; + } + + if (upb_exttable_lookup(&r->exts, extendee, fieldnum) != NULL) { + return kUpb_ExtensionRegistryStatus_DuplicateEntry; + } + + if (!upb_exttable_insert(&r->exts, extendee, (const uint32_t*)e, r->arena)) { + return kUpb_ExtensionRegistryStatus_OutOfMemory; + } + return kUpb_ExtensionRegistryStatus_Ok; +} + +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count) { + const upb_MiniTableExtension** start = e; + const upb_MiniTableExtension** end = UPB_PTRADD(e, count); + upb_ExtensionRegistryStatus status = kUpb_ExtensionRegistryStatus_Ok; + for (; e < end; e++) { + status = upb_ExtensionRegistry_Add(r, *e); + if (status != kUpb_ExtensionRegistryStatus_Ok) goto failure; + } + return kUpb_ExtensionRegistryStatus_Ok; + +failure: + // Back out the entries previously added. + for (end = e, e = start; e < end; e++) { + const upb_MiniTableExtension* ext = *e; + upb_exttable_remove(&r->exts, upb_MiniTableExtension_Extendee(ext), + upb_MiniTableExtension_Number(ext)); + } + UPB_ASSERT(status != kUpb_ExtensionRegistryStatus_Ok); + return status; +} + +const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( + const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) { + const uint32_t* v = upb_exttable_lookup(&r->exts, t, num); + return (const upb_MiniTableExtension*)v; +} + +size_t upb_ExtensionRegistry_Size(const upb_ExtensionRegistry* r) { + return upb_exttable_size(&r->exts); +} + + +#include +#include + + +// Must be last. + +#if UPB_TSAN +#include +#endif // UPB_TSAN + +const UPB_PRIVATE(upb_GeneratedExtensionListEntry) * + UPB_PRIVATE(upb_generated_extension_list) = NULL; + +typedef struct upb_GeneratedRegistry { + UPB_ATOMIC(upb_GeneratedRegistryRef*) ref; + UPB_ATOMIC(int32_t) ref_count; +} upb_GeneratedRegistry; + +static upb_GeneratedRegistry* _upb_generated_registry(void) { + static upb_GeneratedRegistry r = {NULL, 0}; + return &r; +} + +static bool _upb_GeneratedRegistry_AddAllLinkedExtensions( + upb_ExtensionRegistry* r) { + const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* entry = + UPB_PRIVATE(upb_generated_extension_list); + while (entry != NULL) { + const upb_MiniTableExtension** current = entry->start; + for (current = entry->start; current != entry->stop; ++current) { + const upb_MiniTableExtension* ext = *current; + // Sentinels and padding introduced by the linker can result in zeroed + // entries, so simply skip them. + if (*current == NULL) { + // MSVC introduces padding that might not be sized exactly the same as + // the linker array element, but it should be properly aligned, so just + // skipping empty elements should be safe. (If the size and align of + // the array elements was different, we'd have to do something more + // complicated). + continue; + } + + if (upb_ExtensionRegistry_Add(r, ext) != + kUpb_ExtensionRegistryStatus_Ok) { + return false; + } + } + entry = entry->next; + } + return true; +} + +// Constructs a new GeneratedRegistryRef, adding all linked extensions to the +// registry or returning NULL on failure. +static upb_GeneratedRegistryRef* _upb_GeneratedRegistry_New(void) { + upb_Arena* arena = NULL; + upb_ExtensionRegistry* extreg = NULL; + upb_GeneratedRegistryRef* ref = upb_gmalloc(sizeof(upb_GeneratedRegistryRef)); + if (ref == NULL) goto err; + arena = upb_Arena_New(); + if (arena == NULL) goto err; + extreg = upb_ExtensionRegistry_New(arena); + if (extreg == NULL) goto err; + + ref->UPB_PRIVATE(arena) = arena; + ref->UPB_PRIVATE(registry) = extreg; + + if (!_upb_GeneratedRegistry_AddAllLinkedExtensions(extreg)) goto err; + + return ref; + +err: + if (arena != NULL) upb_Arena_Free(arena); + if (ref != NULL) upb_gfree(ref); + return NULL; +} + +const upb_GeneratedRegistryRef* upb_GeneratedRegistry_Load(void) { + upb_GeneratedRegistry* registry = _upb_generated_registry(); + + // Loop until we successfully acquire a reference. This loop should only + // kick in under extremely high contention, and it should be guaranteed to + // succeed. + while (true) { + int32_t count = upb_Atomic_Load(®istry->ref_count, memory_order_acquire); + + // Try to increment the refcount, but only if it's not zero. + while (count > 0) { + if (upb_Atomic_CompareExchangeStrong(®istry->ref_count, &count, + count + 1, memory_order_acquire, + memory_order_relaxed)) { + // Successfully incremented. We can now safely load and return the + // pointer. + const upb_GeneratedRegistryRef* ref = + upb_Atomic_Load(®istry->ref, memory_order_acquire); + UPB_ASSERT(ref != NULL); + return ref; + } + // CAS failed, `count` was updated. Loop will retry. + } + + // If we're here, the count was 0. Time for the slow path. + // Double-check that the pointer is NULL before trying to create. + upb_GeneratedRegistryRef* ref = + upb_Atomic_Load(®istry->ref, memory_order_acquire); + if (ref == NULL) { + // Pointer is NULL, try to create and publish a new registry. + upb_GeneratedRegistryRef* new_ref = _upb_GeneratedRegistry_New(); + if (new_ref == NULL) return NULL; // OOM + + // Try to CAS the pointer from NULL to our new_ref. + if (upb_Atomic_CompareExchangeStrong(®istry->ref, &ref, new_ref, + memory_order_release, + memory_order_acquire)) { + // We won the race. Set the ref count to 1. + upb_Atomic_Store(®istry->ref_count, 1, memory_order_release); + return new_ref; + } else { + // We lost the race. `ref` now holds the pointer from the winning + // thread. Clean up our unused one and loop to try again to get a + // reference. + upb_Arena_Free(new_ref->UPB_PRIVATE(arena)); + upb_gfree(new_ref); + } + } + // If we are here, either we lost the CAS race, or the pointer was already + // non-NULL. In either case, we loop to the top and try to increment the + // refcount of the existing object. + +#if UPB_TSAN + // Yield to give other threads a chance to increment the refcount. This is + // especially an issue for TSAN builds, which are prone to locking up from + // the thread with the upb_Atomic_Store call above getting starved. + sched_yield(); +#endif // UPB_TSAN + } +} + +void upb_GeneratedRegistry_Release(const upb_GeneratedRegistryRef* r) { + if (r == NULL) return; + + upb_GeneratedRegistry* registry = _upb_generated_registry(); + + int ref_count = upb_Atomic_Sub(®istry->ref_count, 1, memory_order_acq_rel); + UPB_ASSERT(registry->ref_count >= 0); + + // A ref_count of 1 means that we decremented the refcount to 0. + if (ref_count == 1) { + upb_GeneratedRegistryRef* ref = + upb_Atomic_Exchange(®istry->ref, NULL, memory_order_acq_rel); + if (ref != NULL) { + // This is the last reference and we won any potential race to store NULL, + // so we need to clean up. + upb_Arena_Free(ref->UPB_PRIVATE(arena)); + upb_gfree(ref); + } + } +} + +const upb_ExtensionRegistry* upb_GeneratedRegistry_Get( + const upb_GeneratedRegistryRef* r) { + if (r == NULL) return NULL; + return r->UPB_PRIVATE(registry); +} + + +#include +#include + + +// Must be last. + +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f) { + if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) { + return NULL; + } + const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + for (; ptr < end; ptr++) { + if (ptr->presence == (*f).presence) { + return ptr; + } + } + return NULL; +} + +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f) { + const upb_MiniTableField* ptr = *f; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + while (++ptr < end) { + if (ptr->presence == (*f)->presence) { + *f = ptr; + return true; + } + } + return false; +} + + +#include + + +// Must be last. + +// A MiniTable for a statically tree shaken message. Messages that use this +// MiniTable are guaranteed to remain unlinked; unlike the empty message, this +// MiniTable is never replaced, which greatly simplifies everything, because the +// type of a sub-message is always known, without consulting a tagged bit. +const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_StaticallyTreeShaken) = { + .UPB_PRIVATE(fields) = NULL, + .UPB_PRIVATE(size) = sizeof(struct upb_Message), + .UPB_PRIVATE(field_count) = 0, + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, + .UPB_PRIVATE(dense_below) = 0, + .UPB_PRIVATE(table_mask) = -1, + .UPB_PRIVATE(required_count) = 0, +}; + + +#include +#include +#include +#include +#include + + +// Must be last. + +struct upb_DefPool { + upb_Arena* arena; + upb_strtable syms; // full_name -> packed def ptr + upb_strtable files; // file_name -> (upb_FileDef*) + upb_inttable exts; // (upb_MiniTableExtension*) -> (upb_FieldDef*) + upb_ExtensionRegistry* extreg; + const upb_GeneratedRegistryRef* generated_extreg; + const google_protobuf_FeatureSetDefaults* feature_set_defaults; + upb_MiniTablePlatform platform; + void* scratch_data; + size_t scratch_size; + size_t bytes_loaded; + bool disable_closed_enum_checking; + bool disable_implicit_field_presence; +}; + +void upb_DefPool_Free(upb_DefPool* s) { + upb_GeneratedRegistry_Release(s->generated_extreg); + upb_Arena_Free(s->arena); + upb_gfree(s->scratch_data); + upb_gfree(s); +} + +static const char serialized_defaults[] = UPB_INTERNAL_UPB_EDITION_DEFAULTS; + +upb_DefPool* upb_DefPool_New(void) { + upb_DefPool* s = upb_gmalloc(sizeof(*s)); + if (!s) return NULL; + + s->arena = upb_Arena_New(); + s->bytes_loaded = 0; + s->disable_closed_enum_checking = false; + s->disable_implicit_field_presence = false; + + s->scratch_size = 240; + s->scratch_data = upb_gmalloc(s->scratch_size); + if (!s->scratch_data) goto err; + + if (!upb_strtable_init(&s->syms, 32, s->arena)) goto err; + if (!upb_strtable_init(&s->files, 4, s->arena)) goto err; + if (!upb_inttable_init(&s->exts, s->arena)) goto err; + + s->extreg = upb_ExtensionRegistry_New(s->arena); + if (!s->extreg) goto err; + + s->generated_extreg = upb_GeneratedRegistry_Load(); + if (!s->generated_extreg) goto err; + + s->platform = kUpb_MiniTablePlatform_Native; + + upb_Status status; + if (!upb_DefPool_SetFeatureSetDefaults( + s, serialized_defaults, sizeof(serialized_defaults) - 1, &status)) { + goto err; + } + + if (!s->feature_set_defaults) goto err; + + return s; + +err: + upb_DefPool_Free(s); + return NULL; +} + +void upb_DefPool_DisableClosedEnumChecking(upb_DefPool* s) { + UPB_ASSERT(upb_strtable_count(&s->files) == 0); + s->disable_closed_enum_checking = true; +} + +bool upb_DefPool_ClosedEnumCheckingDisabled(const upb_DefPool* s) { + return s->disable_closed_enum_checking; +} + +void upb_DefPool_DisableImplicitFieldPresence(upb_DefPool* s) { + UPB_ASSERT(upb_strtable_count(&s->files) == 0); + s->disable_implicit_field_presence = true; +} + +bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s) { + return s->disable_implicit_field_presence; +} + +const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults( + const upb_DefPool* s) { + return s->feature_set_defaults; +} + +bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status) { + const google_protobuf_FeatureSetDefaults* defaults = google_protobuf_FeatureSetDefaults_parse( + serialized_defaults, serialized_len, s->arena); + if (!defaults) { + upb_Status_SetErrorFormat(status, "Failed to parse defaults"); + return false; + } + if (upb_strtable_count(&s->files) > 0) { + upb_Status_SetErrorFormat(status, + "Feature set defaults can't be changed once the " + "pool has started building"); + return false; + } + int min_edition = google_protobuf_FeatureSetDefaults_minimum_edition(defaults); + int max_edition = google_protobuf_FeatureSetDefaults_maximum_edition(defaults); + if (min_edition > max_edition) { + upb_Status_SetErrorFormat(status, "Invalid edition range %s to %s", + upb_FileDef_EditionName(min_edition), + upb_FileDef_EditionName(max_edition)); + return false; + } + size_t size; + const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const* + default_list = google_protobuf_FeatureSetDefaults_defaults(defaults, &size); + int prev_edition = google_protobuf_EDITION_UNKNOWN; + for (size_t i = 0; i < size; ++i) { + int edition = google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_edition( + default_list[i]); + if (edition == google_protobuf_EDITION_UNKNOWN) { + upb_Status_SetErrorFormat(status, "Invalid edition UNKNOWN specified"); + return false; + } + if (edition <= prev_edition) { + upb_Status_SetErrorFormat(status, + "Feature set defaults are not strictly " + "increasing, %s is greater than or equal to %s", + upb_FileDef_EditionName(prev_edition), + upb_FileDef_EditionName(edition)); + return false; + } + prev_edition = edition; + } + + // Copy the defaults into the pool. + s->feature_set_defaults = defaults; + return true; +} + +bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTableExtension* ext, + const upb_FieldDef* f) { + return upb_inttable_insert(&s->exts, (uintptr_t)ext, upb_value_constptr(f), + s->arena); +} + +bool _upb_DefPool_InsertSym(upb_DefPool* s, upb_StringView sym, upb_value v, + upb_Status* status) { + // TODO: table should support an operation "tryinsert" to avoid the double + // lookup. + if (upb_strtable_lookup2(&s->syms, sym.data, sym.size, NULL)) { + upb_Status_SetErrorFormat(status, "duplicate symbol '%s'", sym.data); + return false; + } + if (!upb_strtable_insert(&s->syms, sym.data, sym.size, v, s->arena)) { + upb_Status_SetErrorMessage(status, "out of memory"); + return false; + } + return true; +} + +static const void* _upb_DefPool_Unpack(const upb_DefPool* s, const char* sym, + size_t size, upb_deftype_t type) { + upb_value v; + return upb_strtable_lookup2(&s->syms, sym, size, &v) + ? _upb_DefType_Unpack(v, type) + : NULL; +} + +bool _upb_DefPool_LookupSym(const upb_DefPool* s, const char* sym, size_t size, + upb_value* v) { + return upb_strtable_lookup2(&s->syms, sym, size, v); +} + +upb_ExtensionRegistry* _upb_DefPool_ExtReg(const upb_DefPool* s) { + return s->extreg; +} + +void** _upb_DefPool_ScratchData(const upb_DefPool* s) { + return (void**)&s->scratch_data; +} + +size_t* _upb_DefPool_ScratchSize(const upb_DefPool* s) { + return (size_t*)&s->scratch_size; +} + +void _upb_DefPool_SetPlatform(upb_DefPool* s, upb_MiniTablePlatform platform) { + assert(upb_strtable_count(&s->files) == 0); + s->platform = platform; +} + +const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindMessageByNameWithSize(s, sym, strlen(sym)); +} + +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len) { + return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_MSG); +} + +const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindEnumByNameWithSize(s, sym, strlen(sym)); +} + +const upb_EnumDef* upb_DefPool_FindEnumByNameWithSize(const upb_DefPool* s, + const char* sym, + size_t len) { + return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUM); +} + +const upb_EnumValueDef* upb_DefPool_FindEnumValueByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindEnumValueByNameWithSize(s, sym, strlen(sym)); +} + +const upb_EnumValueDef* upb_DefPool_FindEnumValueByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len) { + return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUMVAL); +} + +const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name) { + upb_value v; + return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) + : NULL; +} + +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len) { + upb_value v; + return upb_strtable_lookup2(&s->files, name, len, &v) + ? upb_value_getconstptr(v) + : NULL; +} + +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { + upb_value v; + if (!upb_strtable_lookup2(&s->syms, name, size, &v)) return NULL; + + switch (_upb_DefType_Type(v)) { + case UPB_DEFTYPE_FIELD: + return _upb_DefType_Unpack(v, UPB_DEFTYPE_FIELD); + case UPB_DEFTYPE_MSG: { + const upb_MessageDef* m = _upb_DefType_Unpack(v, UPB_DEFTYPE_MSG); + if (_upb_MessageDef_InMessageSet(m)) { + for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { + const upb_FieldDef* ext = upb_MessageDef_NestedExtension(m, i); + if (upb_FieldDef_MessageSubDef(ext) == m) { + return ext; + } + } + } + return NULL; + } + default: + break; + } + + return NULL; +} + +const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindExtensionByNameWithSize(s, sym, strlen(sym)); +} + +const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, + const char* name) { + return _upb_DefPool_Unpack(s, name, strlen(name), UPB_DEFTYPE_SERVICE); +} + +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { + return _upb_DefPool_Unpack(s, name, size, UPB_DEFTYPE_SERVICE); +} + +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name) { + upb_value v; + // TODO: non-extension fields and oneofs. + if (upb_strtable_lookup(&s->syms, name, &v)) { + switch (_upb_DefType_Type(v)) { + case UPB_DEFTYPE_EXT: { + const upb_FieldDef* f = _upb_DefType_Unpack(v, UPB_DEFTYPE_EXT); + return upb_FieldDef_File(f); + } + case UPB_DEFTYPE_MSG: { + const upb_MessageDef* m = _upb_DefType_Unpack(v, UPB_DEFTYPE_MSG); + return upb_MessageDef_File(m); + } + case UPB_DEFTYPE_ENUM: { + const upb_EnumDef* e = _upb_DefType_Unpack(v, UPB_DEFTYPE_ENUM); + return upb_EnumDef_File(e); + } + case UPB_DEFTYPE_ENUMVAL: { + const upb_EnumValueDef* ev = + _upb_DefType_Unpack(v, UPB_DEFTYPE_ENUMVAL); + return upb_EnumDef_File(upb_EnumValueDef_Enum(ev)); + } + case UPB_DEFTYPE_SERVICE: { + const upb_ServiceDef* service = + _upb_DefType_Unpack(v, UPB_DEFTYPE_SERVICE); + return upb_ServiceDef_File(service); + } + default: + UPB_UNREACHABLE(); + } + } + + const char* last_dot = strrchr(name, '.'); + if (last_dot) { + const upb_MessageDef* parent = + upb_DefPool_FindMessageByNameWithSize(s, name, last_dot - name); + if (parent) { + const char* shortname = last_dot + 1; + if (upb_MessageDef_FindByNameWithSize(parent, shortname, + strlen(shortname), NULL, NULL)) { + return upb_MessageDef_File(parent); + } + } + } + + return NULL; +} + +static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { + intptr_t iter = UPB_INTTABLE_BEGIN; + upb_StringView key; + upb_value val; + while (upb_strtable_next2(&s->syms, &key, &val, &iter)) { + const upb_FileDef* f; + switch (_upb_DefType_Type(val)) { + case UPB_DEFTYPE_EXT: + f = upb_FieldDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_EXT)); + break; + case UPB_DEFTYPE_MSG: + f = upb_MessageDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_MSG)); + break; + case UPB_DEFTYPE_ENUM: + f = upb_EnumDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_ENUM)); + break; + case UPB_DEFTYPE_ENUMVAL: + f = upb_EnumDef_File(upb_EnumValueDef_Enum( + _upb_DefType_Unpack(val, UPB_DEFTYPE_ENUMVAL))); + break; + case UPB_DEFTYPE_SERVICE: + f = upb_ServiceDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_SERVICE)); + break; + default: + UPB_UNREACHABLE(); + } + + if (f == file) upb_strtable_removeiter(&s->syms, &iter); + } +} + +static const upb_FileDef* upb_DefBuilder_AddFileToPool( + upb_DefBuilder* const builder, upb_DefPool* const s, + const google_protobuf_FileDescriptorProto* const file_proto, + const upb_StringView name, upb_Status* const status) { + if (UPB_SETJMP(builder->err) != 0) { + UPB_ASSERT(!upb_Status_IsOk(status)); + if (builder->file) { + remove_filedef(s, builder->file); + builder->file = NULL; + } + } else if (!builder->arena || !builder->tmp_arena || + !upb_strtable_init(&builder->feature_cache, 16, + builder->tmp_arena) || + !(builder->legacy_features = + google_protobuf_FeatureSet_new(builder->tmp_arena))) { + _upb_DefBuilder_OomErr(builder); + } else { + _upb_FileDef_Create(builder, file_proto); + upb_strtable_insert(&s->files, name.data, name.size, + upb_value_constptr(builder->file), builder->arena); + UPB_ASSERT(upb_Status_IsOk(status)); + upb_Arena_Fuse(s->arena, builder->arena); + } + + if (builder->arena) upb_Arena_Free(builder->arena); + if (builder->tmp_arena) upb_Arena_Free(builder->tmp_arena); + return builder->file; +} + +static const upb_FileDef* _upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + const upb_MiniTableFile* layout, upb_Status* status) { + const upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto); + + // Determine whether we already know about this file. + { + upb_value v; + if (upb_strtable_lookup2(&s->files, name.data, name.size, &v)) { + upb_Status_SetErrorFormat(status, + "duplicate file name " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(name)); + return NULL; + } + } + + upb_DefBuilder ctx = { + .symtab = s, + .tmp_buf = NULL, + .tmp_buf_size = 0, + .layout = layout, + .platform = s->platform, + .msg_count = 0, + .enum_count = 0, + .ext_count = 0, + .status = status, + .file = NULL, + .arena = upb_Arena_New(), + .tmp_arena = upb_Arena_New(), + }; + + return upb_DefBuilder_AddFileToPool(&ctx, s, file_proto, name, status); +} + +const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + upb_Status* status) { + return _upb_DefPool_AddFile(s, file_proto, NULL, status); +} + +bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable) { + /* Since this function should never fail (it would indicate a bug in upb) we + * print errors to stderr instead of returning error status to the user. */ + _upb_DefPool_Init** deps = init->deps; + google_protobuf_FileDescriptorProto* file; + upb_Arena* arena; + upb_Status status; + + upb_Status_Clear(&status); + + if (upb_DefPool_FindFileByName(s, init->filename)) { + return true; + } + + arena = upb_Arena_New(); + + for (; *deps; deps++) { + if (!_upb_DefPool_LoadDefInitEx(s, *deps, rebuild_minitable)) goto err; + } + + file = google_protobuf_FileDescriptorProto_parse_ex( + init->descriptor.data, init->descriptor.size, NULL, + kUpb_DecodeOption_AliasString, arena); + s->bytes_loaded += init->descriptor.size; + + if (!file) { + upb_Status_SetErrorFormat( + &status, + "Failed to parse compiled-in descriptor for file '%s'. This should " + "never happen.", + init->filename); + goto err; + } + + const upb_MiniTableFile* mt = rebuild_minitable ? NULL : init->layout; + if (!_upb_DefPool_AddFile(s, file, mt, &status)) { + goto err; + } + + upb_Arena_Free(arena); + return true; + +err: + fprintf(stderr, + "Error loading compiled-in descriptor for file '%s' (this should " + "never happen): %s\n", + init->filename, upb_Status_ErrorMessage(&status)); + upb_Arena_Free(arena); + return false; +} + +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s) { + return s->bytes_loaded; +} + +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s) { return s->arena; } + +const upb_FieldDef* upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTableExtension* ext) { + upb_value v; + bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v); + UPB_ASSERT(ok); + return upb_value_getconstptr(v); +} + +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum) { + const upb_MiniTable* t = upb_MessageDef_MiniTable(m); + const upb_MiniTableExtension* ext = + upb_ExtensionRegistry_Lookup(s->extreg, t, fieldnum); + return ext ? upb_DefPool_FindExtensionByMiniTable(s, ext) : NULL; +} + +const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s) { + return s->extreg; +} + +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count) { + size_t n = 0; + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + // This is O(all exts) instead of O(exts for m). If we need this to be + // efficient we may need to make extreg into a two-level table, or have a + // second per-message index. + while (upb_inttable_next(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) n++; + } + const upb_FieldDef** exts = upb_gmalloc(n * sizeof(*exts)); + iter = UPB_INTTABLE_BEGIN; + size_t i = 0; + while (upb_inttable_next(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) exts[i++] = f; + } + *count = n; + return exts; +} + +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init) { + return _upb_DefPool_LoadDefInitEx(s, init, false); +} + +const upb_ExtensionRegistry* _upb_DefPool_GeneratedExtensionRegistry( + const upb_DefPool* s) { + return upb_GeneratedRegistry_Get(s->generated_extreg); +} + + +// Must be last. + +upb_deftype_t _upb_DefType_Type(upb_value v) { + const uintptr_t num = (uintptr_t)upb_value_getconstptr(v); + return num & UPB_DEFTYPE_MASK; +} + +upb_value _upb_DefType_Pack(const void* ptr, upb_deftype_t type) { + uintptr_t num = (uintptr_t)ptr; + UPB_ASSERT((num & UPB_DEFTYPE_MASK) == 0); + num |= type; + return upb_value_constptr((const void*)num); +} + +const void* _upb_DefType_Unpack(upb_value v, upb_deftype_t type) { + uintptr_t num = (uintptr_t)upb_value_getconstptr(v); + return (num & UPB_DEFTYPE_MASK) == type + ? (const void*)(num & ~UPB_DEFTYPE_MASK) + : NULL; +} + + +// Must be last. + +bool _upb_DescState_Grow(upb_DescState* d, upb_Arena* a) { + const size_t oldbufsize = d->bufsize; + const int used = d->ptr - d->buf; + + if (!d->buf) { + d->buf = upb_Arena_Malloc(a, d->bufsize); + if (!d->buf) return false; + d->ptr = d->buf; + d->e.end = d->buf + d->bufsize; + } + + if (oldbufsize - used < kUpb_MtDataEncoder_MinSize) { + d->bufsize *= 2; + d->buf = upb_Arena_Realloc(a, d->buf, oldbufsize, d->bufsize); + if (!d->buf) return false; + d->ptr = d->buf + used; + d->e.end = d->buf + d->bufsize; + } + + return true; +} + + +#include +#include +#include + + +// Must be last. + +struct upb_EnumDef { + UPB_ALIGN_AS(8) const google_protobuf_EnumOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_MiniTableEnum* layout; // Only for proto2. + const upb_FileDef* file; + const upb_MessageDef* containing_type; // Could be merged with "file". + const char* full_name; + upb_strtable ntoi; + upb_inttable iton; + const upb_EnumValueDef* values; + const upb_EnumReservedRange* res_ranges; + const upb_StringView* res_names; + int value_count; + int res_range_count; + int res_name_count; + int32_t defaultval; + google_protobuf_SymbolVisibility visibility; + bool is_sorted; // Whether all of the values are defined in ascending order. +}; + +upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) { + return (upb_EnumDef*)&e[i]; +} + +const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) { + return e->layout; +} + +bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) { + const char* name = upb_EnumValueDef_Name(v); + const upb_value val = upb_value_constptr(v); + bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a); + if (!ok) return false; + + // Multiple enumerators can have the same number, first one wins. + const int number = upb_EnumValueDef_Number(v); + if (!upb_inttable_lookup(&e->iton, number, NULL)) { + return upb_inttable_insert(&e->iton, number, val, a); + } + return true; +} + +const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { + return e->opts; +} + +bool upb_EnumDef_HasOptions(const upb_EnumDef* e) { + return e->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e) { + return e->resolved_features; +} + +google_protobuf_SymbolVisibility upb_EnumDef_Visibility(const upb_EnumDef* e) { + return e->visibility; +} + +const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; } + +const char* upb_EnumDef_Name(const upb_EnumDef* e) { + return _upb_DefBuilder_FullToShort(e->full_name); +} + +const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e) { return e->file; } + +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e) { + return e->containing_type; +} + +int32_t upb_EnumDef_Default(const upb_EnumDef* e) { + UPB_ASSERT(upb_EnumDef_FindValueByNumber(e, e->defaultval)); + return e->defaultval; +} + +int upb_EnumDef_ReservedRangeCount(const upb_EnumDef* e) { + return e->res_range_count; +} + +const upb_EnumReservedRange* upb_EnumDef_ReservedRange(const upb_EnumDef* e, + int i) { + UPB_ASSERT(0 <= i && i < e->res_range_count); + return _upb_EnumReservedRange_At(e->res_ranges, i); +} + +int upb_EnumDef_ReservedNameCount(const upb_EnumDef* e) { + return e->res_name_count; +} + +upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) { + UPB_ASSERT(0 <= i && i < e->res_name_count); + return e->res_names[i]; +} + +int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; } + +const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, + const char* name) { + return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name)); +} + +const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* e, const char* name, size_t size) { + upb_value v; + return upb_strtable_lookup2(&e->ntoi, name, size, &v) + ? upb_value_getconstptr(v) + : NULL; +} + +const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, + int32_t num) { + upb_value v; + return upb_inttable_lookup(&e->iton, num, &v) ? upb_value_getconstptr(v) + : NULL; +} + +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num) { + // We could use upb_EnumDef_FindValueByNumber(e, num) != NULL, but we expect + // this to be faster (especially for small numbers). + return upb_MiniTableEnum_CheckValue(e->layout, num); +} + +const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { + UPB_ASSERT(0 <= i && i < e->value_count); + return _upb_EnumValueDef_At(e->values, i); +} + +static bool upb_EnumDef_IsSpecifiedAsClosed(const upb_EnumDef* e) { + return google_protobuf_FeatureSet_enum_type(e->resolved_features) == + google_protobuf_FeatureSet_CLOSED; +} + +bool upb_EnumDef_IsClosed(const upb_EnumDef* e) { + if (_upb_FileDef_ClosedEnumCheckingDisabled(e->file)) return false; + return upb_EnumDef_IsSpecifiedAsClosed(e); +} + +bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a, + upb_StringView* out) { + upb_DescState s; + _upb_DescState_Init(&s); + + const upb_EnumValueDef** sorted = NULL; + if (!e->is_sorted) { + sorted = _upb_EnumValueDefs_Sorted(e->values, e->value_count, a); + if (!sorted) return false; + } + + if (!_upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_StartEnum(&s.e, s.ptr); + + // Duplicate values are allowed but we only encode each value once. + uint32_t previous = 0; + + for (int i = 0; i < e->value_count; i++) { + const uint32_t current = + upb_EnumValueDef_Number(sorted ? sorted[i] : upb_EnumDef_Value(e, i)); + if (i != 0 && previous == current) continue; + + if (!_upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_PutEnumValue(&s.e, s.ptr, current); + previous = current; + } + + if (!_upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_EndEnum(&s.e, s.ptr); + + // There will always be room for this '\0' in the encoder buffer because + // kUpb_MtDataEncoder_MinSize is overkill for upb_MtDataEncoder_EndEnum(). + UPB_ASSERT(s.ptr < s.buf + s.bufsize); + *s.ptr = '\0'; + + out->data = s.buf; + out->size = s.ptr - s.buf; + return true; +} + +static upb_MiniTableEnum* create_enumlayout(upb_DefBuilder* ctx, + const upb_EnumDef* e) { + upb_StringView sv; + bool ok = upb_EnumDef_MiniDescriptorEncode(e, ctx->tmp_arena, &sv); + if (!ok) _upb_DefBuilder_Errf(ctx, "OOM while building enum MiniDescriptor"); + + upb_Status status; + upb_MiniTableEnum* layout = + upb_MiniTableEnum_Build(sv.data, sv.size, ctx->arena, &status); + if (!layout) + _upb_DefBuilder_Errf(ctx, "Error building enum MiniTable: %s", status.msg); + return layout; +} + +static upb_StringView* _upb_EnumReservedNames_New( + upb_DefBuilder* ctx, int n, const upb_StringView* protos) { + upb_StringView* sv = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_StringView, n); + for (int i = 0; i < n; i++) { + sv[i].data = + upb_strdup2(protos[i].data, protos[i].size, _upb_DefBuilder_Arena(ctx)); + sv[i].size = protos[i].size; + } + return sv; +} + +static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_EnumDescriptorProto* enum_proto, + const google_protobuf_FeatureSet* parent_features, + upb_EnumDef* e) { + const google_protobuf_EnumValueDescriptorProto* const* values; + const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* res_ranges; + const upb_StringView* res_names; + upb_StringView name; + size_t n_value, n_res_range, n_res_name; + + UPB_DEF_SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); + e->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_EnumOptions_features(e->opts)); + + // Must happen before _upb_DefBuilder_Add() + e->file = _upb_DefBuilder_File(ctx); + + name = google_protobuf_EnumDescriptorProto_name(enum_proto); + + e->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + _upb_DefBuilder_Add(ctx, e->full_name, + _upb_DefType_Pack(e, UPB_DEFTYPE_ENUM)); + + values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n_value); + + if (n_value == 0) { + _upb_DefBuilder_Errf(ctx, "enums must contain at least one value (%s)", + e->full_name); + } + + e->defaultval = google_protobuf_EnumValueDescriptorProto_number(values[0]); + + // When the special UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN is enabled, we have to + // exempt closed enums from this check, even when we are treating them as + // open. + // + // We rely on the fact that the proto compiler will have already ensured that + // implicit presence fields do not use closed enums, even if we are treating + // them as open. + if (!upb_EnumDef_IsSpecifiedAsClosed(e) && e->defaultval != 0) { + _upb_DefBuilder_Errf(ctx, + "for open enums, the first value must be zero (%s)", + upb_EnumDef_FullName(e)); + } + + bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_inttable_init(&e->iton, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + e->value_count = n_value; + e->values = _upb_EnumValueDefs_New(ctx, prefix, n_value, values, + e->resolved_features, e, &e->is_sorted); + + res_ranges = + google_protobuf_EnumDescriptorProto_reserved_range(enum_proto, &n_res_range); + e->res_range_count = n_res_range; + e->res_ranges = _upb_EnumReservedRanges_New(ctx, n_res_range, res_ranges, e); + + res_names = google_protobuf_EnumDescriptorProto_reserved_name(enum_proto, &n_res_name); + e->res_name_count = n_res_name; + e->res_names = _upb_EnumReservedNames_New(ctx, n_res_name, res_names); + + e->visibility = google_protobuf_EnumDescriptorProto_visibility(enum_proto); + + if (!upb_inttable_compact(&e->iton, ctx->arena)) _upb_DefBuilder_OomErr(ctx); + + if (upb_EnumDef_IsClosed(e)) { + if (ctx->layout) { + e->layout = upb_MiniTableFile_Enum(ctx->layout, ctx->enum_count++); + } else { + e->layout = create_enumlayout(ctx, e); + } + } else { + e->layout = NULL; + } +} + +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type) { + _upb_DefType_CheckPadding(sizeof(upb_EnumDef)); + + // If a containing type is defined then get the full name from that. + // Otherwise use the package name from the file def. + const char* name = containing_type ? upb_MessageDef_FullName(containing_type) + : _upb_FileDef_RawPackage(ctx->file); + + upb_EnumDef* e = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_EnumDef, n); + for (int i = 0; i < n; i++) { + create_enumdef(ctx, name, protos[i], parent_features, &e[i]); + e[i].containing_type = containing_type; + } + return e; +} + + +#include + + +// Must be last. + +struct upb_EnumReservedRange { + int32_t start; + int32_t end; +}; + +upb_EnumReservedRange* _upb_EnumReservedRange_At(const upb_EnumReservedRange* r, + int i) { + return (upb_EnumReservedRange*)&r[i]; +} + +int32_t upb_EnumReservedRange_Start(const upb_EnumReservedRange* r) { + return r->start; +} +int32_t upb_EnumReservedRange_End(const upb_EnumReservedRange* r) { + return r->end; +} + +upb_EnumReservedRange* _upb_EnumReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* protos, + const upb_EnumDef* e) { + upb_EnumReservedRange* r = + UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_EnumReservedRange, n); + + for (int i = 0; i < n; i++) { + const int32_t start = + google_protobuf_EnumDescriptorProto_EnumReservedRange_start(protos[i]); + const int32_t end = + google_protobuf_EnumDescriptorProto_EnumReservedRange_end(protos[i]); + + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + + // Note: Not a typo! Unlike extension ranges and message reserved ranges, + // the end value of an enum reserved range is *inclusive*! + if (end < start) { + _upb_DefBuilder_Errf(ctx, "Reserved range (%d, %d) is invalid, enum=%s\n", + (int)start, (int)end, upb_EnumDef_FullName(e)); + } + + r[i].start = start; + r[i].end = end; + } + + return r; +} + + +#include +#include +#include + + +// Must be last. + +struct upb_EnumValueDef { + UPB_ALIGN_AS(8) const google_protobuf_EnumValueOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_EnumDef* parent; + const char* full_name; + int32_t number; +}; + +upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i) { + return (upb_EnumValueDef*)&v[i]; +} + +static int _upb_EnumValueDef_Compare(const void* p1, const void* p2) { + const uint32_t v1 = (*(const upb_EnumValueDef**)p1)->number; + const uint32_t v2 = (*(const upb_EnumValueDef**)p2)->number; + return (v1 < v2) ? -1 : (v1 > v2); +} + +const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, + size_t n, upb_Arena* a) { + if (SIZE_MAX / sizeof(void*) < n) return NULL; + // TODO: Try to replace this arena alloc with a persistent scratch buffer. + upb_EnumValueDef** out = + (upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*)); + if (!out) return NULL; + + for (int i = 0; i < n; i++) { + out[i] = (upb_EnumValueDef*)&v[i]; + } + qsort(out, n, sizeof(void*), _upb_EnumValueDef_Compare); + + return (const upb_EnumValueDef**)out; +} + +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* v) { + return v->opts; +} + +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v) { + return v->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_EnumValueDef_ResolvedFeatures( + const upb_EnumValueDef* e) { + return e->resolved_features; +} + +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v) { + return v->parent; +} + +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) { + return v->full_name; +} + +const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) { + return _upb_DefBuilder_FullToShort(v->full_name); +} + +int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v) { return v->number; } + +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) { + // Compute index in our parent's array. + return v - upb_EnumDef_Value(v->parent, 0); +} + +static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_EnumValueDescriptorProto* val_proto, + const google_protobuf_FeatureSet* parent_features, + upb_EnumDef* e, upb_EnumValueDef* v) { + UPB_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions, + val_proto); + v->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_EnumValueOptions_features(v->opts)); + + upb_StringView name = google_protobuf_EnumValueDescriptorProto_name(val_proto); + + v->parent = e; // Must happen prior to _upb_DefBuilder_Add() + v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); + _upb_DefBuilder_Add(ctx, v->full_name, + _upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL)); + + bool ok = _upb_EnumDef_Insert(e, v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +// Allocate and initialize an array of |n| enum value defs owned by |e|. +upb_EnumValueDef* _upb_EnumValueDefs_New( + upb_DefBuilder* ctx, const char* prefix, int n, + const google_protobuf_EnumValueDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_EnumDef* e, bool* is_sorted) { + _upb_DefType_CheckPadding(sizeof(upb_EnumValueDef)); + + upb_EnumValueDef* v = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_EnumValueDef, n); + + *is_sorted = true; + uint32_t previous = 0; + for (int i = 0; i < n; i++) { + create_enumvaldef(ctx, prefix, protos[i], parent_features, e, &v[i]); + + const uint32_t current = v[i].number; + if (previous > current) *is_sorted = false; + previous = current; + } + + return v; +} + + +#include + + +// Must be last. + +struct upb_ExtensionRange { + const google_protobuf_ExtensionRangeOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + int32_t start; + int32_t end; +}; + +upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i) { + return (upb_ExtensionRange*)&r[i]; +} + +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r) { + return r->opts; +} + +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r) { + return r->opts != (void*)kUpbDefOptDefault; +} + +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r) { + return r->start; +} + +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r) { return r->end; } + +upb_ExtensionRange* _upb_ExtensionRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ExtensionRange* const* protos, + const google_protobuf_FeatureSet* parent_features, const upb_MessageDef* m) { + upb_ExtensionRange* r = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_ExtensionRange, n); + + for (int i = 0; i < n; i++) { + UPB_DEF_SET_OPTIONS(r[i].opts, DescriptorProto_ExtensionRange, + ExtensionRangeOptions, protos[i]); + r[i].resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_ExtensionRangeOptions_features(r[i].opts)); + + const int32_t start = + google_protobuf_DescriptorProto_ExtensionRange_start(protos[i]); + const int32_t end = google_protobuf_DescriptorProto_ExtensionRange_end(protos[i]); + const int32_t max = + google_protobuf_MessageOptions_message_set_wire_format(upb_MessageDef_Options(m)) + ? INT32_MAX + : kUpb_MaxFieldNumber + 1; + + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + if (start < 1 || end <= start || end > max) { + _upb_DefBuilder_Errf(ctx, + "Extension range (%d, %d) is invalid, message=%s\n", + (int)start, (int)end, upb_MessageDef_FullName(m)); + } + + r[i].start = start; + r[i].end = end; + } + + return r; +} + + +#include +#include +#include +#include +#include +#include + + +// Must be last. + +#define UPB_FIELD_TYPE_UNSPECIFIED 0 + +typedef struct { + size_t len; + char str[1]; // Null-terminated string data follows. +} str_t; + +struct upb_FieldDef { + UPB_ALIGN_AS(8) const google_protobuf_FieldOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_FileDef* file; + const upb_MessageDef* msgdef; + const char* full_name; + const char* json_name; + union { + int64_t sint; + uint64_t uint; + double dbl; + float flt; + bool boolean; + str_t* str; + void* msg; // Always NULL. + } defaultval; + union { + const upb_OneofDef* oneof; + const upb_MessageDef* extension_scope; + } scope; + union { + const upb_MessageDef* msgdef; + const upb_EnumDef* enumdef; + const google_protobuf_FieldDescriptorProto* unresolved; + } sub; + uint32_t number_; + uint16_t index_; + uint16_t layout_index; // Index into msgdef->layout->fields or file->exts + bool has_default; + bool has_json_name; + bool has_presence; + bool is_extension; + bool is_proto3_optional; + upb_FieldType type_; + upb_Label label_; +}; + +upb_FieldDef* _upb_FieldDef_At(const upb_FieldDef* f, int i) { + return (upb_FieldDef*)&f[i]; +} + +const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f) { + return f->opts; +} + +bool upb_FieldDef_HasOptions(const upb_FieldDef* f) { + return f->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f) { + return f->resolved_features; +} + +const char* upb_FieldDef_FullName(const upb_FieldDef* f) { + return f->full_name; +} + +upb_CType upb_FieldDef_CType(const upb_FieldDef* f) { + return upb_FieldType_CType(f->type_); +} + +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; } + +uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; } + +uint32_t upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { + return f->layout_index; +} + +upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; } + +uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } + +bool upb_FieldDef_IsExtension(const upb_FieldDef* f) { return f->is_extension; } + +bool _upb_FieldDef_IsPackable(const upb_FieldDef* f) { + return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsPrimitive(f); +} + +bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { + return _upb_FieldDef_IsPackable(f) && + google_protobuf_FeatureSet_repeated_field_encoding(f->resolved_features) == + google_protobuf_FeatureSet_PACKED; +} + +const char* upb_FieldDef_Name(const upb_FieldDef* f) { + return _upb_DefBuilder_FullToShort(f->full_name); +} + +const char* upb_FieldDef_JsonName(const upb_FieldDef* f) { + return f->json_name; +} + +bool upb_FieldDef_HasJsonName(const upb_FieldDef* f) { + return f->has_json_name; +} + +const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f) { return f->file; } + +const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f) { + return f->msgdef; +} + +const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f) { + return f->is_extension ? f->scope.extension_scope : NULL; +} + +const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f) { + return f->is_extension ? NULL : f->scope.oneof; +} + +const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f) { + const upb_OneofDef* oneof = upb_FieldDef_ContainingOneof(f); + if (!oneof || upb_OneofDef_IsSynthetic(oneof)) return NULL; + return oneof; +} + +upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f) { + upb_MessageValue ret; + + if (upb_FieldDef_IsRepeated(f) || upb_FieldDef_IsSubMessage(f)) { + return (upb_MessageValue){.msg_val = NULL}; + } + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return (upb_MessageValue){.bool_val = f->defaultval.boolean}; + case kUpb_CType_Int64: + return (upb_MessageValue){.int64_val = f->defaultval.sint}; + case kUpb_CType_UInt64: + return (upb_MessageValue){.uint64_val = f->defaultval.uint}; + case kUpb_CType_Enum: + case kUpb_CType_Int32: + return (upb_MessageValue){.int32_val = (int32_t)f->defaultval.sint}; + case kUpb_CType_UInt32: + return (upb_MessageValue){.uint32_val = (uint32_t)f->defaultval.uint}; + case kUpb_CType_Float: + return (upb_MessageValue){.float_val = f->defaultval.flt}; + case kUpb_CType_Double: + return (upb_MessageValue){.double_val = f->defaultval.dbl}; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + str_t* str = f->defaultval.str; + if (str) { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = str->str, .size = str->len}}; + } else { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = NULL, .size = 0}}; + } + } + default: + UPB_UNREACHABLE(); + } + + return ret; +} + +const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsSubMessage(f) ? f->sub.msgdef : NULL; +} + +const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsEnum(f) ? f->sub.enumdef : NULL; +} + +const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) { + if (upb_FieldDef_IsExtension(f)) { + const upb_FileDef* file = upb_FieldDef_File(f); + return (upb_MiniTableField*)_upb_FileDef_ExtensionMiniTable( + file, f->layout_index); + } else { + const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef); + return &layout->UPB_PRIVATE(fields)[f->layout_index]; + } +} + +const upb_MiniTableExtension* upb_FieldDef_MiniTableExtension( + const upb_FieldDef* f) { + UPB_ASSERT(upb_FieldDef_IsExtension(f)); + const upb_FileDef* file = upb_FieldDef_File(f); + return _upb_FileDef_ExtensionMiniTable(file, f->layout_index); +} + +bool _upb_FieldDef_IsClosedEnum(const upb_FieldDef* f) { + if (f->type_ != kUpb_FieldType_Enum) return false; + return upb_EnumDef_IsClosed(f->sub.enumdef); +} + +bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) { + return f->is_proto3_optional; +} + +int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { return f->layout_index; } + +bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { + if (upb_FieldDef_Type(f) != kUpb_FieldType_String) return false; + return google_protobuf_FeatureSet_utf8_validation(f->resolved_features) == + google_protobuf_FeatureSet_VERIFY; +} + +bool _upb_FieldDef_IsGroupLike(const upb_FieldDef* f) { + // Groups are always tag-delimited. + if (f->type_ != kUpb_FieldType_Group) { + return false; + } + + const upb_MessageDef* msg = upb_FieldDef_MessageSubDef(f); + + // Group fields always are always the lowercase type name. + const char* mname = upb_MessageDef_Name(msg); + const char* fname = upb_FieldDef_Name(f); + size_t name_size = strlen(fname); + if (name_size != strlen(mname)) return false; + for (size_t i = 0; i < name_size; ++i) { + if ((mname[i] | 0x20) != fname[i]) { + // Case-insensitive ascii comparison. + return false; + } + } + + if (upb_MessageDef_File(msg) != upb_FieldDef_File(f)) { + return false; + } + + // Group messages are always defined in the same scope as the field. File + // level extensions will compare NULL == NULL here, which is why the file + // comparison above is necessary to ensure both come from the same file. + return upb_FieldDef_IsExtension(f) ? upb_FieldDef_ExtensionScope(f) == + upb_MessageDef_ContainingType(msg) + : upb_FieldDef_ContainingType(f) == + upb_MessageDef_ContainingType(msg); +} + +uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) { + uint64_t out = upb_FieldDef_IsPacked(f) ? kUpb_FieldModifier_IsPacked : 0; + + if (upb_FieldDef_IsRepeated(f)) { + out |= kUpb_FieldModifier_IsRepeated; + } else if (upb_FieldDef_IsRequired(f)) { + out |= kUpb_FieldModifier_IsRequired; + } else if (!upb_FieldDef_HasPresence(f)) { + out |= kUpb_FieldModifier_IsProto3Singular; + } + + if (_upb_FieldDef_IsClosedEnum(f)) { + out |= kUpb_FieldModifier_IsClosedEnum; + } + + if (_upb_FieldDef_ValidateUtf8(f)) { + out |= kUpb_FieldModifier_ValidateUtf8; + } + + return out; +} + +bool upb_FieldDef_HasDefault(const upb_FieldDef* f) { return f->has_default; } +bool upb_FieldDef_HasPresence(const upb_FieldDef* f) { return f->has_presence; } + +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsEnum(f); +} + +bool upb_FieldDef_IsEnum(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Enum; +} + +bool upb_FieldDef_IsMap(const upb_FieldDef* f) { + return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsSubMessage(f) && + upb_MessageDef_IsMapEntry(upb_FieldDef_MessageSubDef(f)); +} + +bool upb_FieldDef_IsOptional(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Optional; +} + +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f) { + return !upb_FieldDef_IsString(f) && !upb_FieldDef_IsSubMessage(f); +} + +bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Repeated; +} + +bool upb_FieldDef_IsRequired(const upb_FieldDef* f) { + return google_protobuf_FeatureSet_field_presence(f->resolved_features) == + google_protobuf_FeatureSet_LEGACY_REQUIRED; +} + +bool upb_FieldDef_IsString(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_String || + upb_FieldDef_CType(f) == kUpb_CType_Bytes; +} + +bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Message; +} + +static bool between(int32_t x, int32_t low, int32_t high) { + return x >= low && x <= high; +} + +bool upb_FieldDef_checklabel(int32_t label) { return between(label, 1, 3); } +bool upb_FieldDef_checktype(int32_t type) { return between(type, 1, 11); } +bool upb_FieldDef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); } + +bool upb_FieldDef_checkdescriptortype(int32_t type) { + return between(type, 1, 18); +} + +static bool streql2(const char* a, size_t n, const char* b) { + return n == strlen(b) && memcmp(a, b, n) == 0; +} + +// Implement the transformation as described in the spec: +// 1. upper case all letters after an underscore. +// 2. remove all underscores. +static char* make_json_name(const char* name, size_t size, upb_Arena* a) { + char* out = upb_Arena_Malloc(a, size + 1); // +1 is to add a trailing '\0' + if (out == NULL) return NULL; + + bool ucase_next = false; + char* des = out; + for (size_t i = 0; i < size; i++) { + if (name[i] == '_') { + ucase_next = true; + } else { + *des++ = ucase_next ? toupper(name[i]) : name[i]; + ucase_next = false; + } + } + *des++ = '\0'; + return out; +} + +static str_t* newstr(upb_DefBuilder* ctx, const char* data, size_t len) { + str_t* ret = _upb_DefBuilder_Alloc(ctx, sizeof(*ret) + len); + if (!ret) _upb_DefBuilder_OomErr(ctx); + ret->len = len; + if (len) memcpy(ret->str, data, len); + ret->str[len] = '\0'; + return ret; +} + +static str_t* unescape(upb_DefBuilder* ctx, const upb_FieldDef* f, + const char* data, size_t len) { + // Size here is an upper bound; escape sequences could ultimately shrink it. + str_t* ret = _upb_DefBuilder_Alloc(ctx, sizeof(*ret) + len); + char* dst = &ret->str[0]; + const char* src = data; + const char* end = data + len; + + while (src < end) { + if (*src == '\\') { + src++; + *dst++ = _upb_DefBuilder_ParseEscape(ctx, f, &src, end); + } else { + *dst++ = *src++; + } + } + + ret->len = dst - &ret->str[0]; + return ret; +} + +static void parse_default(upb_DefBuilder* ctx, const char* str, size_t len, + upb_FieldDef* f) { + char* end; + char nullz[64]; + errno = 0; + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + case kUpb_CType_Double: + case kUpb_CType_Float: + // Standard C number parsing functions expect null-terminated strings. + if (len >= sizeof(nullz) - 1) { + _upb_DefBuilder_Errf(ctx, "Default too long: %.*s", (int)len, str); + } + memcpy(nullz, str, len); + nullz[len] = '\0'; + str = nullz; + break; + default: + break; + } + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: { + long val = strtol(str, &end, 0); + if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.sint = val; + break; + } + case kUpb_CType_Enum: { + const upb_EnumDef* e = f->sub.enumdef; + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNameWithSize(e, str, len); + if (!ev) { + goto invalid; + } + f->defaultval.sint = upb_EnumValueDef_Number(ev); + break; + } + case kUpb_CType_Int64: { + long long val = strtoll(str, &end, 0); + if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.sint = val; + break; + } + case kUpb_CType_UInt32: { + unsigned long val = strtoul(str, &end, 0); + if (val > UINT32_MAX || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.uint = val; + break; + } + case kUpb_CType_UInt64: { + unsigned long long val = strtoull(str, &end, 0); + if (val > UINT64_MAX || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.uint = val; + break; + } + case kUpb_CType_Double: { + double val = strtod(str, &end); + if (errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.dbl = val; + break; + } + case kUpb_CType_Float: { + float val = strtof(str, &end); + if (errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.flt = val; + break; + } + case kUpb_CType_Bool: { + if (streql2(str, len, "false")) { + f->defaultval.boolean = false; + } else if (streql2(str, len, "true")) { + f->defaultval.boolean = true; + } else { + goto invalid; + } + break; + } + case kUpb_CType_String: + f->defaultval.str = newstr(ctx, str, len); + break; + case kUpb_CType_Bytes: + f->defaultval.str = unescape(ctx, f, str, len); + break; + case kUpb_CType_Message: + /* Should not have a default value. */ + _upb_DefBuilder_Errf(ctx, "Message should not have a default (%s)", + upb_FieldDef_FullName(f)); + } + + return; + +invalid: + _upb_DefBuilder_Errf(ctx, "Invalid default '%.*s' for field %s of type %d", + (int)len, str, upb_FieldDef_FullName(f), + (int)upb_FieldDef_Type(f)); +} + +static void set_default_default(upb_DefBuilder* ctx, upb_FieldDef* f, + bool must_be_empty) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + f->defaultval.sint = 0; + break; + case kUpb_CType_UInt64: + case kUpb_CType_UInt32: + f->defaultval.uint = 0; + break; + case kUpb_CType_Double: + case kUpb_CType_Float: + f->defaultval.dbl = 0; + break; + case kUpb_CType_String: + case kUpb_CType_Bytes: + f->defaultval.str = newstr(ctx, NULL, 0); + break; + case kUpb_CType_Bool: + f->defaultval.boolean = false; + break; + case kUpb_CType_Enum: { + f->defaultval.sint = upb_EnumDef_Default(f->sub.enumdef); + if (must_be_empty && f->defaultval.sint != 0) { + _upb_DefBuilder_Errf(ctx, + "Implicit presence field (%s) cannot use an enum " + "type with a non-zero default (%s)", + f->full_name, + upb_EnumDef_FullName(f->sub.enumdef)); + } + break; + } + case kUpb_CType_Message: + break; + } +} + +static bool _upb_FieldDef_InferLegacyFeatures( + upb_DefBuilder* ctx, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* proto, + const google_protobuf_FieldOptions* options, google_protobuf_Edition edition, + google_protobuf_FeatureSet* features) { + bool ret = false; + + if (google_protobuf_FieldDescriptorProto_label(proto) == kUpb_Label_Required) { + if (edition == google_protobuf_EDITION_PROTO3) { + _upb_DefBuilder_Errf(ctx, "proto3 fields cannot be required (%s)", + f->full_name); + } + int val = google_protobuf_FeatureSet_LEGACY_REQUIRED; + google_protobuf_FeatureSet_set_field_presence(features, val); + ret = true; + } + + if (google_protobuf_FieldDescriptorProto_type(proto) == kUpb_FieldType_Group) { + int val = google_protobuf_FeatureSet_DELIMITED; + google_protobuf_FeatureSet_set_message_encoding(features, val); + ret = true; + } + + if (google_protobuf_FieldOptions_has_packed(options)) { + int val = google_protobuf_FieldOptions_packed(options) ? google_protobuf_FeatureSet_PACKED + : google_protobuf_FeatureSet_EXPANDED; + google_protobuf_FeatureSet_set_repeated_field_encoding(features, val); + ret = true; + } + + return ret; +} + +static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_FeatureSet* parent_features, + const google_protobuf_FieldDescriptorProto* field_proto, + upb_MessageDef* m, upb_FieldDef* f) { + // Must happen before _upb_DefBuilder_Add() + f->file = _upb_DefBuilder_File(ctx); + + const upb_StringView name = google_protobuf_FieldDescriptorProto_name(field_proto); + f->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + f->number_ = google_protobuf_FieldDescriptorProto_number(field_proto); + f->is_proto3_optional = + google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); + f->msgdef = m; + f->scope.oneof = NULL; + + UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); + + google_protobuf_Edition edition = upb_FileDef_Edition(f->file); + const google_protobuf_FeatureSet* unresolved_features = + google_protobuf_FieldOptions_features(f->opts); + bool implicit = false; + + if (_upb_DefBuilder_IsLegacyEdition(edition)) { + upb_Message_Clear(UPB_UPCAST(ctx->legacy_features), + UPB_DESC_MINITABLE(FeatureSet)); + if (_upb_FieldDef_InferLegacyFeatures(ctx, f, field_proto, f->opts, edition, + ctx->legacy_features)) { + implicit = true; + unresolved_features = ctx->legacy_features; + } + } + + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + int oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); + + if (!m) { + _upb_DefBuilder_Errf(ctx, "oneof field (%s) has no containing msg", + f->full_name); + } + + if (oneof_index < 0 || oneof_index >= upb_MessageDef_OneofCount(m)) { + _upb_DefBuilder_Errf(ctx, "oneof_index out of range (%s)", f->full_name); + } + + upb_OneofDef* oneof = (upb_OneofDef*)upb_MessageDef_Oneof(m, oneof_index); + f->scope.oneof = oneof; + parent_features = upb_OneofDef_ResolvedFeatures(oneof); + + _upb_OneofDef_Insert(ctx, oneof, f, name.data, name.size); + } + + f->resolved_features = _upb_DefBuilder_DoResolveFeatures( + ctx, parent_features, unresolved_features, implicit); + + f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); + if (f->label_ == kUpb_Label_Optional && + // TODO: remove once we can deprecate kUpb_Label_Required. + google_protobuf_FeatureSet_field_presence(f->resolved_features) == + google_protobuf_FeatureSet_LEGACY_REQUIRED) { + f->label_ = kUpb_Label_Required; + } + + if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { + _upb_DefBuilder_Errf(ctx, "field has no name"); + } + + f->has_json_name = google_protobuf_FieldDescriptorProto_has_json_name(field_proto); + if (f->has_json_name) { + const upb_StringView sv = + google_protobuf_FieldDescriptorProto_json_name(field_proto); + f->json_name = upb_strdup2(sv.data, sv.size, ctx->arena); + } else { + f->json_name = make_json_name(name.data, name.size, ctx->arena); + } + if (!f->json_name) _upb_DefBuilder_OomErr(ctx); + + const bool has_type = google_protobuf_FieldDescriptorProto_has_type(field_proto); + const bool has_type_name = + google_protobuf_FieldDescriptorProto_has_type_name(field_proto); + + f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); + + if (has_type) { + switch (f->type_) { + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + case kUpb_FieldType_Enum: + if (!has_type_name) { + _upb_DefBuilder_Errf(ctx, "field of type %d requires type name (%s)", + (int)f->type_, f->full_name); + } + break; + default: + if (has_type_name) { + _upb_DefBuilder_Errf( + ctx, "invalid type for field with type_name set (%s, %d)", + f->full_name, (int)f->type_); + } + } + } + + if ((!has_type && has_type_name) || f->type_ == kUpb_FieldType_Message) { + f->type_ = + UPB_FIELD_TYPE_UNSPECIFIED; // We'll assign this in resolve_subdef() + } else { + if (f->type_ < kUpb_FieldType_Double || f->type_ > kUpb_FieldType_SInt64) { + _upb_DefBuilder_Errf(ctx, "invalid type for field %s (%d)", f->full_name, + f->type_); + } + } + + if (f->label_ < kUpb_Label_Optional || f->label_ > kUpb_Label_Repeated) { + _upb_DefBuilder_Errf(ctx, "invalid label for field %s (%d)", f->full_name, + f->label_); + } + + /* We can't resolve the subdef or (in the case of extensions) the containing + * message yet, because it may not have been defined yet. We stash a pointer + * to the field_proto until later when we can properly resolve it. */ + f->sub.unresolved = field_proto; + + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + if (upb_FieldDef_Label(f) != kUpb_Label_Optional) { + _upb_DefBuilder_Errf(ctx, "fields in oneof must have OPTIONAL label (%s)", + f->full_name); + } + } + + f->has_presence = + (!upb_FieldDef_IsRepeated(f)) && + (f->is_extension || _upb_FileDef_ImplicitFieldPresenceDisabled(f->file) || + (f->type_ == kUpb_FieldType_Message || + f->type_ == kUpb_FieldType_Group || upb_FieldDef_ContainingOneof(f) || + google_protobuf_FeatureSet_field_presence(f->resolved_features) != + google_protobuf_FeatureSet_IMPLICIT)); +} + +static void _upb_FieldDef_CreateExt( + upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_FeatureSet* parent_features, + const google_protobuf_FieldDescriptorProto* field_proto, upb_MessageDef* m, + upb_FieldDef* f) { + f->is_extension = true; + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); + + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + _upb_DefBuilder_Errf(ctx, "oneof_index provided for extension field (%s)", + f->full_name); + } + + f->scope.extension_scope = m; + _upb_DefBuilder_Add(ctx, f->full_name, _upb_DefType_Pack(f, UPB_DEFTYPE_EXT)); + f->layout_index = ctx->ext_count++; + + if (ctx->layout) { + UPB_ASSERT(upb_MiniTableExtension_Number( + upb_FieldDef_MiniTableExtension(f)) == f->number_); + } +} + +static void _upb_FieldDef_CreateNotExt( + upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_FeatureSet* parent_features, + const google_protobuf_FieldDescriptorProto* field_proto, upb_MessageDef* m, + upb_FieldDef* f) { + f->is_extension = false; + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); + + if (!google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + if (f->is_proto3_optional) { + _upb_DefBuilder_Errf( + ctx, + "non-extension field (%s) with proto3_optional was not in a oneof", + f->full_name); + } + } + + _upb_MessageDef_InsertField(ctx, m, f); +} + +upb_FieldDef* _upb_Extensions_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m) { + _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); + upb_FieldDef* defs = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_FieldDef, n); + + for (int i = 0; i < n; i++) { + upb_FieldDef* f = &defs[i]; + + _upb_FieldDef_CreateExt(ctx, prefix, parent_features, protos[i], m, f); + f->index_ = i; + } + + return defs; +} + +upb_FieldDef* _upb_FieldDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m, bool* is_sorted) { + _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); + upb_FieldDef* defs = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_FieldDef, n); + + uint32_t previous = 0; + for (int i = 0; i < n; i++) { + upb_FieldDef* f = &defs[i]; + + _upb_FieldDef_CreateNotExt(ctx, prefix, parent_features, protos[i], m, f); + f->index_ = i; + if (!ctx->layout) { + // Speculate that the def fields are sorted. We will always sort the + // MiniTable fields, so if defs are sorted then indices will match. + // + // If this is incorrect, we will overwrite later. + f->layout_index = i; + } + + const uint32_t current = f->number_; + if (previous > current) *is_sorted = false; + previous = current; + } + + return defs; +} + +static void resolve_subdef(upb_DefBuilder* ctx, const char* prefix, + upb_FieldDef* f) { + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + upb_StringView name = google_protobuf_FieldDescriptorProto_type_name(field_proto); + bool has_name = google_protobuf_FieldDescriptorProto_has_type_name(field_proto); + switch ((int)f->type_) { + case UPB_FIELD_TYPE_UNSPECIFIED: { + // Type was not specified and must be inferred. + UPB_ASSERT(has_name); + upb_deftype_t type; + const void* def = + _upb_DefBuilder_ResolveAny(ctx, f->full_name, prefix, name, &type); + switch (type) { + case UPB_DEFTYPE_ENUM: + f->sub.enumdef = def; + f->type_ = kUpb_FieldType_Enum; + break; + case UPB_DEFTYPE_MSG: + f->sub.msgdef = def; + f->type_ = kUpb_FieldType_Message; + // TODO: remove once we can deprecate + // kUpb_FieldType_Group. + if (google_protobuf_FeatureSet_message_encoding(f->resolved_features) == + google_protobuf_FeatureSet_DELIMITED && + !upb_MessageDef_IsMapEntry(def) && + !(f->msgdef && upb_MessageDef_IsMapEntry(f->msgdef))) { + f->type_ = kUpb_FieldType_Group; + } + f->has_presence = !upb_FieldDef_IsRepeated(f); + break; + default: + _upb_DefBuilder_Errf(ctx, "Couldn't resolve type name for field %s", + f->full_name); + } + break; + } + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + UPB_ASSERT(has_name); + f->sub.msgdef = _upb_DefBuilder_Resolve(ctx, f->full_name, prefix, name, + UPB_DEFTYPE_MSG); + break; + case kUpb_FieldType_Enum: + UPB_ASSERT(has_name); + f->sub.enumdef = _upb_DefBuilder_Resolve(ctx, f->full_name, prefix, name, + UPB_DEFTYPE_ENUM); + break; + default: + // No resolution necessary. + break; + } +} + +static int _upb_FieldDef_Compare(const void* p1, const void* p2) { + const uint32_t v1 = (*(upb_FieldDef**)p1)->number_; + const uint32_t v2 = (*(upb_FieldDef**)p2)->number_; + return (v1 < v2) ? -1 : (v1 > v2); +} + +// _upb_FieldDefs_Sorted() is mostly a pure function of its inputs, but has one +// critical side effect that we depend on: it sets layout_index appropriately +// for non-sorted lists of fields. +const upb_FieldDef** _upb_FieldDefs_Sorted(const upb_FieldDef* f, int n, + upb_Arena* a) { + // TODO: Replace this arena alloc with a persistent scratch buffer. + upb_FieldDef** out = (upb_FieldDef**)upb_Arena_Malloc(a, n * sizeof(void*)); + if (!out) return NULL; + + for (int i = 0; i < n; i++) { + out[i] = (upb_FieldDef*)&f[i]; + } + qsort(out, n, sizeof(void*), _upb_FieldDef_Compare); + + for (int i = 0; i < n; i++) { + out[i]->layout_index = i; + } + return (const upb_FieldDef**)out; +} + +bool upb_FieldDef_MiniDescriptorEncode(const upb_FieldDef* f, upb_Arena* a, + upb_StringView* out) { + UPB_ASSERT(f->is_extension); + + upb_DescState s; + _upb_DescState_Init(&s); + + const int number = upb_FieldDef_Number(f); + const uint64_t modifiers = _upb_FieldDef_Modifiers(f); + + if (!_upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_EncodeExtension(&s.e, s.ptr, f->type_, number, + modifiers); + *s.ptr = '\0'; + + out->data = s.buf; + out->size = s.ptr - s.buf; + return true; +} + +static void resolve_extension(upb_DefBuilder* ctx, const char* prefix, + upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* field_proto) { + if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { + _upb_DefBuilder_Errf(ctx, "extension for field '%s' had no extendee", + f->full_name); + } + + upb_StringView name = google_protobuf_FieldDescriptorProto_extendee(field_proto); + const upb_MessageDef* m = + _upb_DefBuilder_Resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG); + f->msgdef = m; + + if (!_upb_MessageDef_IsValidExtensionNumber(m, f->number_)) { + _upb_DefBuilder_Errf( + ctx, + "field number %u in extension %s has no extension range in message %s", + (unsigned)f->number_, f->full_name, upb_MessageDef_FullName(m)); + } +} + +void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, + const upb_FieldDef* f) { + const upb_MiniTableExtension* ext = upb_FieldDef_MiniTableExtension(f); + + if (ctx->layout) { + UPB_ASSERT(upb_FieldDef_Number(f) == upb_MiniTableExtension_Number(ext)); + } else { + upb_StringView desc; + if (!upb_FieldDef_MiniDescriptorEncode(f, ctx->tmp_arena, &desc)) { + _upb_DefBuilder_OomErr(ctx); + } + + upb_MiniTableExtension* mut_ext = (upb_MiniTableExtension*)ext; + upb_MiniTableSub sub = {NULL}; + if (upb_FieldDef_IsSubMessage(f)) { + const upb_MiniTable* submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + sub = upb_MiniTableSub_FromMessage(submsg); + } else if (_upb_FieldDef_IsClosedEnum(f)) { + const upb_MiniTableEnum* subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + sub = upb_MiniTableSub_FromEnum(subenum); + } + bool ok2 = _upb_MiniTableExtension_Init(desc.data, desc.size, mut_ext, + upb_MessageDef_MiniTable(f->msgdef), + sub, ctx->platform, ctx->status); + if (!ok2) _upb_DefBuilder_Errf(ctx, "Could not build extension mini table"); + } + + bool ok = _upb_DefPool_InsertExt(ctx->symtab, ext, f); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +static void resolve_default(upb_DefBuilder* ctx, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* field_proto) { + // Implicit presence fields should always have an effective default of 0. + // This should naturally fall out of the validations that protoc performs: + // - Implicit presence fields cannot specify a default value. + // - Implicit presence fields for for enums can only use open enums, which + // are required to have zero as their default. + // - Even if we are treating all enums as open, the proto compiler will + // still reject using a nominally closed enum with an implicit presence + // field. + bool must_be_empty = !f->has_presence && !upb_FieldDef_IsRepeated(f); + + // Have to delay resolving of the default value until now because of the enum + // case, since enum defaults are specified with a label. + if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { + upb_StringView defaultval = + google_protobuf_FieldDescriptorProto_default_value(field_proto); + + if (must_be_empty) { + _upb_DefBuilder_Errf(ctx, + "fields with implicit presence cannot have " + "explicit defaults (%s)", + f->full_name); + } + + if (upb_FileDef_Edition(f->file) == google_protobuf_EDITION_PROTO3) { + _upb_DefBuilder_Errf(ctx, + "proto3 fields cannot have explicit defaults (%s)", + f->full_name); + } + + if (upb_FieldDef_IsSubMessage(f)) { + _upb_DefBuilder_Errf(ctx, + "message fields cannot have explicit defaults (%s)", + f->full_name); + } + + parse_default(ctx, defaultval.data, defaultval.size, f); + f->has_default = true; + } else { + set_default_default(ctx, f, must_be_empty); + f->has_default = false; + } +} + +void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix, + upb_FieldDef* f) { + // We have to stash this away since resolve_subdef() may overwrite it. + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + + resolve_subdef(ctx, prefix, f); + resolve_default(ctx, f, field_proto); + + if (f->is_extension) { + resolve_extension(ctx, prefix, f, field_proto); + } +} + + +#include +#include +#include + + +// Must be last. + +struct upb_FileDef { + const google_protobuf_FileOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const char* name; + const char* package; + google_protobuf_Edition edition; + + const upb_FileDef** deps; + const int32_t* public_deps; + const int32_t* weak_deps; + const upb_MessageDef* top_lvl_msgs; + const upb_EnumDef* top_lvl_enums; + const upb_FieldDef* top_lvl_exts; + const upb_ServiceDef* services; + const upb_MiniTableExtension** ext_layouts; + const upb_DefPool* symtab; + + int dep_count; + int public_dep_count; + int weak_dep_count; + int top_lvl_msg_count; + int top_lvl_enum_count; + int top_lvl_ext_count; + int service_count; + int ext_count; // All exts in the file. +}; + +UPB_API const char* upb_FileDef_EditionName(int edition) { + // TODO Synchronize this with descriptor.proto better. + switch (edition) { + case google_protobuf_EDITION_PROTO2: + return "PROTO2"; + case google_protobuf_EDITION_PROTO3: + return "PROTO3"; + case google_protobuf_EDITION_2023: + return "2023"; + default: + return "UNKNOWN"; + } +} + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) { + return f->opts; +} + +const google_protobuf_FeatureSet* upb_FileDef_ResolvedFeatures(const upb_FileDef* f) { + return f->resolved_features; +} + +bool upb_FileDef_HasOptions(const upb_FileDef* f) { + return f->opts != (void*)kUpbDefOptDefault; +} + +const char* upb_FileDef_Name(const upb_FileDef* f) { return f->name; } + +const char* upb_FileDef_Package(const upb_FileDef* f) { + return f->package ? f->package : ""; +} + +google_protobuf_Edition upb_FileDef_Edition(const upb_FileDef* f) { return f->edition; } + +const char* _upb_FileDef_RawPackage(const upb_FileDef* f) { return f->package; } + +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f) { + return f->top_lvl_msg_count; +} + +int upb_FileDef_DependencyCount(const upb_FileDef* f) { return f->dep_count; } + +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) { + return f->public_dep_count; +} + +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { + return f->weak_dep_count; +} + +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { + return f->public_deps; +} + +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) { + return f->weak_deps; +} + +bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f) { + return upb_DefPool_ClosedEnumCheckingDisabled(f->symtab); +} + +bool _upb_FileDef_ImplicitFieldPresenceDisabled(const upb_FileDef* f) { + return upb_DefPool_ImplicitFieldPresenceDisabled(f->symtab); +} + +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) { + return f->top_lvl_enum_count; +} + +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f) { + return f->top_lvl_ext_count; +} + +int upb_FileDef_ServiceCount(const upb_FileDef* f) { return f->service_count; } + +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->dep_count); + return f->deps[i]; +} + +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->public_deps[i]]; +} + +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->weak_deps[i]]; +} + +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_msg_count); + return _upb_MessageDef_At(f->top_lvl_msgs, i); +} + +const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_enum_count); + return _upb_EnumDef_At(f->top_lvl_enums, i); +} + +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_ext_count); + return _upb_FieldDef_At(f->top_lvl_exts, i); +} + +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->service_count); + return _upb_ServiceDef_At(f->services, i); +} + +const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f) { return f->symtab; } + +const upb_MiniTableExtension* _upb_FileDef_ExtensionMiniTable( + const upb_FileDef* f, int i) { + return f->ext_layouts[i]; +} + +// Note: Import cycles are not allowed so this will terminate. +bool upb_FileDef_Resolves(const upb_FileDef* f, const char* path) { + if (!strcmp(f->name, path)) return true; + + for (int i = 0; i < upb_FileDef_PublicDependencyCount(f); i++) { + const upb_FileDef* dep = upb_FileDef_PublicDependency(f, i); + if (upb_FileDef_Resolves(dep, path)) return true; + } + return false; +} + +static char* _strviewdup(upb_DefBuilder* ctx, upb_StringView view) { + char* ret = upb_strdup2(view.data, view.size, _upb_DefBuilder_Arena(ctx)); + if (!ret) _upb_DefBuilder_OomErr(ctx); + return ret; +} + +static bool streql_view(upb_StringView view, const char* b) { + return view.size == strlen(b) && memcmp(view.data, b, view.size) == 0; +} + +static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) { + size_t n; + google_protobuf_DescriptorProto_extension(msg_proto, &n); + int ext_count = n; + + const google_protobuf_DescriptorProto* const* nested_msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (size_t i = 0; i < n; i++) { + ext_count += count_exts_in_msg(nested_msgs[i]); + } + + return ext_count; +} + +const google_protobuf_FeatureSet* _upb_FileDef_FindEdition(upb_DefBuilder* ctx, + int edition) { + const google_protobuf_FeatureSetDefaults* defaults = + upb_DefPool_FeatureSetDefaults(ctx->symtab); + + int min = google_protobuf_FeatureSetDefaults_minimum_edition(defaults); + int max = google_protobuf_FeatureSetDefaults_maximum_edition(defaults); + if (edition < min) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is earlier than the minimum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(min)); + return NULL; + } + if (edition > max && edition != google_protobuf_EDITION_UNSTABLE) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is later than the maximum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(max)); + return NULL; + } + + size_t n; + const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const* d = + google_protobuf_FeatureSetDefaults_defaults(defaults, &n); + const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* result = NULL; + for (size_t i = 0; i < n; i++) { + if (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_edition(d[i]) > + edition) { + break; + } + result = d[i]; + } + if (result == NULL) { + _upb_DefBuilder_Errf(ctx, "No valid default found for edition %s", + upb_FileDef_EditionName(edition)); + return NULL; + } + + // Merge the fixed and overridable features to get the edition's default + // feature set. + const google_protobuf_FeatureSet* fixed = + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_fixed_features(result); + const google_protobuf_FeatureSet* overridable = + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_overridable_features( + result); + if (!fixed && !overridable) { + _upb_DefBuilder_Errf(ctx, "No valid default found for edition %s", + upb_FileDef_EditionName(edition)); + return NULL; + } else if (!fixed) { + return overridable; + } + return _upb_DefBuilder_DoResolveFeatures(ctx, fixed, overridable, + /*is_implicit=*/true); +} + +// Allocate and initialize one file def, and add it to the context object. +void _upb_FileDef_Create(upb_DefBuilder* ctx, + const google_protobuf_FileDescriptorProto* file_proto) { + upb_FileDef* file = _upb_DefBuilder_Alloc(ctx, sizeof(upb_FileDef)); + ctx->file = file; + + const google_protobuf_DescriptorProto* const* msgs; + const google_protobuf_EnumDescriptorProto* const* enums; + const google_protobuf_FieldDescriptorProto* const* exts; + const google_protobuf_ServiceDescriptorProto* const* services; + const upb_StringView* strs; + const int32_t* public_deps; + const int32_t* weak_deps; + size_t n; + + file->symtab = ctx->symtab; + + // Count all extensions in the file, to build a flat array of layouts. + google_protobuf_FileDescriptorProto_extension(file_proto, &n); + int ext_count = n; + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (size_t i = 0; i < n; i++) { + ext_count += count_exts_in_msg(msgs[i]); + } + file->ext_count = ext_count; + + if (ctx->layout) { + // We are using the ext layouts that were passed in. + file->ext_layouts = ctx->layout->UPB_PRIVATE(exts); + const int mt_ext_count = upb_MiniTableFile_ExtensionCount(ctx->layout); + if (mt_ext_count != file->ext_count) { + _upb_DefBuilder_Errf(ctx, + "Extension count did not match layout (%d vs %d)", + mt_ext_count, file->ext_count); + } + } else { + // We are building ext layouts from scratch. + file->ext_layouts = _upb_DefBuilder_Alloc( + ctx, sizeof(*file->ext_layouts) * file->ext_count); + upb_MiniTableExtension* ext = + UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MiniTableExtension, file->ext_count); + for (int i = 0; i < file->ext_count; i++) { + file->ext_layouts[i] = &ext[i]; + } + } + + upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto); + file->name = _strviewdup(ctx, name); + if (strlen(file->name) != name.size) { + _upb_DefBuilder_Errf(ctx, "File name contained embedded NULL"); + } + + upb_StringView package = google_protobuf_FileDescriptorProto_package(file_proto); + + if (package.size) { + _upb_DefBuilder_CheckIdentFull(ctx, package); + file->package = _strviewdup(ctx, package); + } else { + file->package = NULL; + } + + upb_StringView syntax = google_protobuf_FileDescriptorProto_syntax(file_proto); + + if (google_protobuf_FileDescriptorProto_has_edition(file_proto)) { + if (!streql_view(syntax, "editions")) { + _upb_DefBuilder_Errf(ctx, + "Setting edition requires that syntax=\"editions\", " + "but syntax is \"" UPB_STRINGVIEW_FORMAT "\"", + UPB_STRINGVIEW_ARGS(syntax)); + } + file->edition = google_protobuf_FileDescriptorProto_edition(file_proto); + } else if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { + if (streql_view(syntax, "proto2")) { + file->edition = google_protobuf_EDITION_PROTO2; + } else if (streql_view(syntax, "proto3")) { + file->edition = google_protobuf_EDITION_PROTO3; + } else if (streql_view(syntax, "editions")) { + _upb_DefBuilder_Errf( + ctx, "File has syntax=\"editions\", but no edition is specified"); + } else { + _upb_DefBuilder_Errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(syntax)); + } + } else { + // The legacy default when no edition or syntax is specified is proto2. + file->edition = google_protobuf_EDITION_PROTO2; + } + + // Read options. + UPB_DEF_SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto); + + // Resolve features. + const google_protobuf_FeatureSet* edition_defaults = + _upb_FileDef_FindEdition(ctx, file->edition); + const google_protobuf_FeatureSet* unresolved = google_protobuf_FileOptions_features(file->opts); + file->resolved_features = + _upb_DefBuilder_ResolveFeatures(ctx, edition_defaults, unresolved); + + // Verify dependencies. + strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); + file->dep_count = n; + file->deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const upb_FileDef*, n); + + for (size_t i = 0; i < n; i++) { + upb_StringView str = strs[i]; + file->deps[i] = + upb_DefPool_FindFileByNameWithSize(ctx->symtab, str.data, str.size); + if (!file->deps[i]) { + _upb_DefBuilder_Errf(ctx, + "Depends on file '" UPB_STRINGVIEW_FORMAT + "', but it has not been loaded", + UPB_STRINGVIEW_ARGS(str)); + } + } + + public_deps = google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n); + file->public_dep_count = n; + file->public_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, int32_t, n); + int32_t* mutable_public_deps = (int32_t*)file->public_deps; + for (size_t i = 0; i < n; i++) { + if (public_deps[i] >= file->dep_count) { + _upb_DefBuilder_Errf(ctx, "public_dep %d is out of range", + (int)public_deps[i]); + } + mutable_public_deps[i] = public_deps[i]; + } + + weak_deps = google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n); + file->weak_dep_count = n; + file->weak_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const int32_t, n); + int32_t* mutable_weak_deps = (int32_t*)file->weak_deps; + for (size_t i = 0; i < n; i++) { + if (weak_deps[i] >= file->dep_count) { + _upb_DefBuilder_Errf(ctx, "weak_dep %d is out of range", + (int)weak_deps[i]); + } + mutable_weak_deps[i] = weak_deps[i]; + } + + // Create enums. + enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + file->top_lvl_enum_count = n; + file->top_lvl_enums = + _upb_EnumDefs_New(ctx, n, enums, file->resolved_features, NULL); + + // Create extensions. + exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); + file->top_lvl_ext_count = n; + file->top_lvl_exts = _upb_Extensions_New( + ctx, n, exts, file->resolved_features, file->package, NULL); + + // Create messages. + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + file->top_lvl_msg_count = n; + file->top_lvl_msgs = + _upb_MessageDefs_New(ctx, n, msgs, file->resolved_features, NULL); + + // Create services. + services = google_protobuf_FileDescriptorProto_service(file_proto, &n); + file->service_count = n; + file->services = + _upb_ServiceDefs_New(ctx, n, services, file->resolved_features); + + // Now that all names are in the table, build layouts and resolve refs. + + for (int i = 0; i < file->top_lvl_msg_count; i++) { + upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i); + _upb_MessageDef_Resolve(ctx, m); + } + + for (int i = 0; i < file->top_lvl_ext_count; i++) { + upb_FieldDef* f = (upb_FieldDef*)upb_FileDef_TopLevelExtension(file, i); + _upb_FieldDef_Resolve(ctx, file->package, f); + } + + for (int i = 0; i < file->top_lvl_msg_count; i++) { + upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i); + _upb_MessageDef_CreateMiniTable(ctx, (upb_MessageDef*)m); + } + + for (int i = 0; i < file->top_lvl_ext_count; i++) { + upb_FieldDef* f = (upb_FieldDef*)upb_FileDef_TopLevelExtension(file, i); + _upb_FieldDef_BuildMiniTableExtension(ctx, f); + } + + for (int i = 0; i < file->top_lvl_msg_count; i++) { + upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i); + _upb_MessageDef_LinkMiniTable(ctx, m); + } + + if (file->ext_count) { + upb_ExtensionRegistryStatus status = upb_ExtensionRegistry_AddArray( + _upb_DefPool_ExtReg(ctx->symtab), file->ext_layouts, file->ext_count); + if (status != kUpb_ExtensionRegistryStatus_Ok) { + if (status == kUpb_ExtensionRegistryStatus_OutOfMemory) { + _upb_DefBuilder_OomErr(ctx); + } + + UPB_ASSERT(status == kUpb_ExtensionRegistryStatus_DuplicateEntry); + _upb_DefBuilder_Errf(ctx, "duplicate extension entry"); + } + } +} + + +#include +#include +#include +#include + + +// Must be last. + +/* The upb core does not generally have a concept of default instances. However + * for descriptor options we make an exception since the max size is known and + * modest (<200 bytes). All types can share a default instance since it is + * initialized to zeroes. + * + * We have to allocate an extra pointer for upb's internal metadata. */ +static UPB_ALIGN_AS(8) const + char opt_default_buf[_UPB_MAXOPT_SIZE + sizeof(void*)] = {0}; +const char* kUpbDefOptDefault = &opt_default_buf[sizeof(void*)]; + +const char* _upb_DefBuilder_FullToShort(const char* fullname) { + const char* p; + + if (fullname == NULL) { + return NULL; + } else if ((p = strrchr(fullname, '.')) == NULL) { + /* No '.' in the name, return the full string. */ + return fullname; + } else { + /* Return one past the last '.'. */ + return p + 1; + } +} + +void _upb_DefBuilder_FailJmp(upb_DefBuilder* ctx) { UPB_LONGJMP(ctx->err, 1); } + +void _upb_DefBuilder_Errf(upb_DefBuilder* ctx, const char* fmt, ...) { + va_list argp; + va_start(argp, fmt); + upb_Status_VSetErrorFormat(ctx->status, fmt, argp); + va_end(argp); + _upb_DefBuilder_FailJmp(ctx); +} + +void _upb_DefBuilder_OomErr(upb_DefBuilder* ctx) { + upb_Status_SetErrorMessage(ctx->status, "out of memory"); + _upb_DefBuilder_FailJmp(ctx); +} + +// Verify a relative identifier string. The loop is branchless for speed. +static void _upb_DefBuilder_CheckIdentNotFull(upb_DefBuilder* ctx, + upb_StringView name) { + bool good = name.size > 0; + + for (size_t i = 0; i < name.size; i++) { + const char c = name.data[i]; + const char d = c | 0x20; // force lowercase + const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); + const bool is_numer = ('0' <= c) & (c <= '9') & (i != 0); + + good &= is_alpha | is_numer; + } + + if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, false); +} + +const char* _upb_DefBuilder_MakeFullName(upb_DefBuilder* ctx, + const char* prefix, + upb_StringView name) { + _upb_DefBuilder_CheckIdentNotFull(ctx, name); + if (prefix) { + // ret = prefix + '.' + name; + size_t n = strlen(prefix); + char* ret = _upb_DefBuilder_Alloc(ctx, n + name.size + 2); + strcpy(ret, prefix); + ret[n] = '.'; + memcpy(&ret[n + 1], name.data, name.size); + ret[n + 1 + name.size] = '\0'; + return ret; + } else { + char* ret = upb_strdup2(name.data, name.size, ctx->arena); + if (!ret) _upb_DefBuilder_OomErr(ctx); + return ret; + } +} + +static bool remove_component(char* base, size_t* len) { + if (*len == 0) return false; + + for (size_t i = *len - 1; i > 0; i--) { + if (base[i] == '.') { + *len = i; + return true; + } + } + + *len = 0; + return true; +} + +const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, + const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t* type) { + if (sym.size == 0) goto notfound; + upb_value v; + if (sym.data[0] == '.') { + // Symbols starting with '.' are absolute, so we do a single lookup. + // Slice to omit the leading '.' + if (!_upb_DefPool_LookupSym(ctx->symtab, sym.data + 1, sym.size - 1, &v)) { + goto notfound; + } + } else { + // Remove components from base until we find an entry or run out. + size_t baselen = base ? strlen(base) : 0; + char* tmp = upb_gmalloc(sym.size + baselen + 1); + while (1) { + char* p = tmp; + if (baselen) { + memcpy(p, base, baselen); + p[baselen] = '.'; + p += baselen + 1; + } + memcpy(p, sym.data, sym.size); + p += sym.size; + if (_upb_DefPool_LookupSym(ctx->symtab, tmp, p - tmp, &v)) { + break; + } + if (!remove_component(tmp, &baselen)) { + upb_gfree(tmp); + goto notfound; + } + } + upb_gfree(tmp); + } + + *type = _upb_DefType_Type(v); + return _upb_DefType_Unpack(v, *type); + +notfound: + _upb_DefBuilder_Errf(ctx, "couldn't resolve name '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(sym)); +} + +const void* _upb_DefBuilder_Resolve(upb_DefBuilder* ctx, + const char* from_name_dbg, const char* base, + upb_StringView sym, upb_deftype_t type) { + upb_deftype_t found_type; + const void* ret = + _upb_DefBuilder_ResolveAny(ctx, from_name_dbg, base, sym, &found_type); + if (ret && found_type != type) { + _upb_DefBuilder_Errf(ctx, + "type mismatch when resolving %s: couldn't find " + "name " UPB_STRINGVIEW_FORMAT " with type=%d", + from_name_dbg, UPB_STRINGVIEW_ARGS(sym), (int)type); + } + return ret; +} + +// Per ASCII this will lower-case a letter. If the result is a letter, the +// input was definitely a letter. If the output is not a letter, this may +// have transformed the character unpredictably. +static char upb_ascii_lower(char ch) { return ch | 0x20; } + +// isalpha() etc. from are locale-dependent, which we don't want. +static bool upb_isbetween(uint8_t c, uint8_t low, uint8_t high) { + return low <= c && c <= high; +} + +static bool upb_isletter(char c) { + char lower = upb_ascii_lower(c); + return upb_isbetween(lower, 'a', 'z') || c == '_'; +} + +static bool upb_isalphanum(char c) { + return upb_isletter(c) || upb_isbetween(c, '0', '9'); +} + +static bool TryGetChar(const char** src, const char* end, char* ch) { + if (*src == end) return false; + *ch = **src; + *src += 1; + return true; +} + +static int TryGetHexDigit(const char** src, const char* end) { + char ch; + if (!TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '9') { + return ch - '0'; + } + ch = upb_ascii_lower(ch); + if ('a' <= ch && ch <= 'f') { + return ch - 'a' + 0xa; + } + *src -= 1; // Char wasn't actually a hex digit. + return -1; +} + +static char upb_DefBuilder_ParseHexEscape(upb_DefBuilder* ctx, + const upb_FieldDef* f, + const char** src, const char* end) { + int hex_digit = TryGetHexDigit(src, end); + if (hex_digit < 0) { + _upb_DefBuilder_Errf( + ctx, "\\x must be followed by at least one hex digit (field='%s')", + upb_FieldDef_FullName(f)); + return 0; + } + unsigned int ret = hex_digit; + while ((hex_digit = TryGetHexDigit(src, end)) >= 0) { + ret = (ret << 4) | hex_digit; + } + if (ret > 0xff) { + _upb_DefBuilder_Errf(ctx, "Value of hex escape in field %s exceeds 8 bits", + upb_FieldDef_FullName(f)); + return 0; + } + return ret; +} + +static char TryGetOctalDigit(const char** src, const char* end) { + char ch; + if (!TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '7') { + return ch - '0'; + } + *src -= 1; // Char wasn't actually an octal digit. + return -1; +} + +static char upb_DefBuilder_ParseOctalEscape(upb_DefBuilder* ctx, + const upb_FieldDef* f, + const char** src, const char* end) { + char ch = 0; + for (int i = 0; i < 3; i++) { + char digit; + if ((digit = TryGetOctalDigit(src, end)) >= 0) { + ch = (ch << 3) | digit; + } + } + return ch; +} + +char _upb_DefBuilder_ParseEscape(upb_DefBuilder* ctx, const upb_FieldDef* f, + const char** src, const char* end) { + char ch; + if (!TryGetChar(src, end, &ch)) { + _upb_DefBuilder_Errf(ctx, "unterminated escape sequence in field %s", + upb_FieldDef_FullName(f)); + return 0; + } + switch (ch) { + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '\"': + return '\"'; + case '?': + return '\?'; + case 'x': + case 'X': + return upb_DefBuilder_ParseHexEscape(ctx, f, src, end); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + *src -= 1; + return upb_DefBuilder_ParseOctalEscape(ctx, f, src, end); + } + _upb_DefBuilder_Errf(ctx, "Unknown escape sequence: \\%c", ch); +} + +void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, + bool full) { + const char* str = name.data; + const size_t len = name.size; + bool start = true; + for (size_t i = 0; i < len; i++) { + const char c = str[i]; + if (c == '.') { + if (start || !full) { + _upb_DefBuilder_Errf( + ctx, "invalid name: unexpected '.' (" UPB_STRINGVIEW_FORMAT ")", + UPB_STRINGVIEW_ARGS(name)); + } + start = true; + } else if (start) { + if (!upb_isletter(c)) { + _upb_DefBuilder_Errf(ctx, + "invalid name: path components must start with a " + "letter (" UPB_STRINGVIEW_FORMAT ")", + UPB_STRINGVIEW_ARGS(name)); + } + start = false; + } else if (!upb_isalphanum(c)) { + _upb_DefBuilder_Errf( + ctx, + "invalid name: non-alphanumeric character (" UPB_STRINGVIEW_FORMAT + ")", + UPB_STRINGVIEW_ARGS(name)); + } + } + if (start) { + _upb_DefBuilder_Errf(ctx, + "invalid name: empty part (" UPB_STRINGVIEW_FORMAT ")", + UPB_STRINGVIEW_ARGS(name)); + } + + // We should never reach this point. + UPB_ASSERT(false); +} + +upb_StringView _upb_DefBuilder_MakeKey(upb_DefBuilder* ctx, + const google_protobuf_FeatureSet* parent, + upb_StringView key) { + size_t need = key.size + sizeof(void*); + if (ctx->tmp_buf_size < need) { + ctx->tmp_buf_size = UPB_MAX(64, upb_RoundUpToPowerOfTwo(need)); + ctx->tmp_buf = upb_Arena_Malloc(ctx->tmp_arena, ctx->tmp_buf_size); + if (!ctx->tmp_buf) _upb_DefBuilder_OomErr(ctx); + } + + memcpy(ctx->tmp_buf, &parent, sizeof(void*)); + memcpy(ctx->tmp_buf + sizeof(void*), key.data, key.size); + return upb_StringView_FromDataAndSize(ctx->tmp_buf, need); +} + +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const google_protobuf_FeatureSet* parent, + upb_StringView key, + google_protobuf_FeatureSet** set) { + upb_StringView k = _upb_DefBuilder_MakeKey(ctx, parent, key); + upb_value v; + if (upb_strtable_lookup2(&ctx->feature_cache, k.data, k.size, &v)) { + *set = upb_value_getptr(v); + return false; + } + + *set = (google_protobuf_FeatureSet*)upb_Message_DeepClone( + UPB_UPCAST(parent), UPB_DESC_MINITABLE(FeatureSet), ctx->arena); + if (!*set) _upb_DefBuilder_OomErr(ctx); + + v = upb_value_ptr(*set); + if (!upb_strtable_insert(&ctx->feature_cache, k.data, k.size, v, + ctx->tmp_arena)) { + _upb_DefBuilder_OomErr(ctx); + } + + return true; +} + +const google_protobuf_FeatureSet* _upb_DefBuilder_DoResolveFeatures( + upb_DefBuilder* ctx, const google_protobuf_FeatureSet* parent, + const google_protobuf_FeatureSet* child, bool is_implicit) { + assert(parent); + if (!child) return parent; + + if (!is_implicit && + _upb_DefBuilder_IsLegacyEdition(upb_FileDef_Edition(ctx->file))) { + _upb_DefBuilder_Errf(ctx, "Features can only be specified for editions"); + } + + google_protobuf_FeatureSet* resolved; + size_t child_size; + const char* child_bytes = + google_protobuf_FeatureSet_serialize(child, ctx->tmp_arena, &child_size); + if (!child_bytes) _upb_DefBuilder_OomErr(ctx); + + upb_StringView key = upb_StringView_FromDataAndSize(child_bytes, child_size); + if (!_upb_DefBuilder_GetOrCreateFeatureSet(ctx, parent, key, &resolved)) { + return resolved; + } + + upb_DecodeStatus dec_status = + upb_Decode(child_bytes, child_size, UPB_UPCAST(resolved), + UPB_DESC_MINITABLE(FeatureSet), NULL, 0, ctx->arena); + if (dec_status != kUpb_DecodeStatus_Ok) _upb_DefBuilder_OomErr(ctx); + + return resolved; +} + + +#include + + +// Must be last. + +char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { + size_t n; + char* p; + + // Prevent overflow errors. + if (len == SIZE_MAX) return NULL; + + // Always null-terminate, even if binary data; but don't rely on the input to + // have a null-terminating byte since it may be a raw binary buffer. + n = len + 1; + p = upb_Arena_Malloc(a, n); + if (p) { + if (len != 0) memcpy(p, s, len); + p[len] = 0; + } + return p; +} + + +#include +#include + + +// Must be last. + +bool upb_Message_HasFieldByDef(const upb_Message* msg, const upb_FieldDef* f) { + const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f); + UPB_ASSERT(upb_FieldDef_HasPresence(f)); + + if (upb_MiniTableField_IsExtension(m_f)) { + return upb_Message_HasExtension(msg, (const upb_MiniTableExtension*)m_f); + } else { + return upb_Message_HasBaseField(msg, m_f); + } +} + +const upb_FieldDef* upb_Message_WhichOneofByDef(const upb_Message* msg, + const upb_OneofDef* o) { + const upb_FieldDef* f = upb_OneofDef_Field(o, 0); + if (upb_OneofDef_IsSynthetic(o)) { + UPB_ASSERT(upb_OneofDef_FieldCount(o) == 1); + return upb_Message_HasFieldByDef(msg, f) ? f : NULL; + } else { + const upb_MiniTableField* field = upb_FieldDef_MiniTable(f); + uint32_t oneof_case = upb_Message_WhichOneofFieldNumber(msg, field); + f = oneof_case ? upb_OneofDef_LookupNumber(o, oneof_case) : NULL; + UPB_ASSERT((f != NULL) == (oneof_case != 0)); + return f; + } +} + +upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, + const upb_FieldDef* f) { + upb_MessageValue default_val = upb_FieldDef_Default(f); + return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val); +} + +upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, + const upb_FieldDef* f, + upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsRepeated(f)); + if (upb_FieldDef_HasPresence(f) && !upb_Message_HasFieldByDef(msg, f)) { + // We need to skip the upb_Message_GetFieldByDef() call in this case. + goto make; + } + + upb_MessageValue val = upb_Message_GetFieldByDef(msg, f); + if (val.array_val) { + return (upb_MutableMessageValue){.array = (upb_Array*)val.array_val}; + } + + upb_MutableMessageValue ret; +make: + if (!a) return (upb_MutableMessageValue){.array = NULL}; + if (upb_FieldDef_IsMap(f)) { + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key = + upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber); + const upb_FieldDef* value = + upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_ValueFieldNumber); + ret.map = + upb_Map_New(a, upb_FieldDef_CType(key), upb_FieldDef_CType(value)); + } else if (upb_FieldDef_IsRepeated(f)) { + ret.array = upb_Array_New(a, upb_FieldDef_CType(f)); + } else { + UPB_ASSERT(upb_FieldDef_IsSubMessage(f)); + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + ret.msg = upb_Message_New(upb_MessageDef_MiniTable(m), a); + } + + val.array_val = ret.array; + upb_Message_SetFieldByDef(msg, f, val, a); + + return ret; +} + +bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue val, upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f); + + if (upb_MiniTableField_IsExtension(m_f)) { + return upb_Message_SetExtension(msg, (const upb_MiniTableExtension*)m_f, + &val, a); + } else { + upb_Message_SetBaseField(msg, m_f, &val); + return true; + } +} + +void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f); + + if (upb_MiniTableField_IsExtension(m_f)) { + upb_Message_ClearExtension(msg, (const upb_MiniTableExtension*)m_f); + } else { + upb_Message_ClearBaseField(msg, m_f); + } +} + +void upb_Message_ClearByDef(upb_Message* msg, const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Clear(msg, upb_MessageDef_MiniTable(m)); +} + +bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, const upb_FieldDef** out_f, + upb_MessageValue* out_val, size_t* iter) { + const upb_MiniTable* mt = upb_MessageDef_MiniTable(m); + size_t i = *iter; + size_t n = upb_MiniTable_FieldCount(mt); + upb_MessageValue zero = upb_MessageValue_Zero(); + UPB_UNUSED(ext_pool); + + // Iterate over normal fields, returning the first one that is set. + while (++i < n) { + const upb_MiniTableField* field = upb_MiniTable_GetFieldByIndex(mt, i); + upb_MessageValue val = upb_Message_GetField(msg, field, zero); + + // Skip field if unset or empty. + if (upb_MiniTableField_HasPresence(field)) { + if (!upb_Message_HasBaseField(msg, field)) continue; + } else { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { + case kUpb_FieldMode_Map: + if (!val.map_val || upb_Map_Size(val.map_val) == 0) continue; + break; + case kUpb_FieldMode_Array: + if (!val.array_val || upb_Array_Size(val.array_val) == 0) continue; + break; + case kUpb_FieldMode_Scalar: + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, &val)) + continue; + break; + } + } + + *out_val = val; + *out_f = + upb_MessageDef_FindFieldByNumber(m, upb_MiniTableField_Number(field)); + *iter = i; + return true; + } + + if (ext_pool) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return false; + + for (; (i - n) < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i - n]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + memcpy(out_val, &ext->data, sizeof(*out_val)); + *out_f = upb_DefPool_FindExtensionByMiniTable(ext_pool, ext->ext); + *iter = i; + return true; + } + } + } + + *iter = i; + return false; +} + +bool _upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int depth) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; + bool ret = true; + + if (--depth == 0) return false; + + _upb_Message_DiscardUnknown_shallow(msg); + + while (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) { + const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f); + if (!subm) continue; + if (upb_FieldDef_IsMap(f)) { + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(subm, 2); + const upb_MessageDef* val_m = upb_FieldDef_MessageSubDef(val_f); + upb_Map* map = (upb_Map*)val.map_val; + size_t iter = kUpb_Map_Begin; + + if (!val_m) continue; + + upb_MessageValue map_key, map_val; + while (upb_Map_Next(map, &map_key, &map_val, &iter)) { + if (!_upb_Message_DiscardUnknown((upb_Message*)map_val.msg_val, val_m, + ext_pool, depth)) { + ret = false; + } + } + } else if (upb_FieldDef_IsRepeated(f)) { + const upb_Array* arr = val.array_val; + size_t i, n = upb_Array_Size(arr); + for (i = 0; i < n; i++) { + upb_MessageValue elem = upb_Array_Get(arr, i); + if (!_upb_Message_DiscardUnknown((upb_Message*)elem.msg_val, subm, + ext_pool, depth)) { + ret = false; + } + } + } else { + if (!_upb_Message_DiscardUnknown((upb_Message*)val.msg_val, subm, + ext_pool, depth)) { + ret = false; + } + } + } + + return ret; +} + +bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int maxdepth) { + return _upb_Message_DiscardUnknown(msg, m, ext_pool, maxdepth); +} + + +#include +#include +#include + + +// Must be last. + +struct upb_MessageDef { + UPB_ALIGN_AS(8) const google_protobuf_MessageOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_MiniTable* layout; + const upb_FileDef* file; + const upb_MessageDef* containing_type; + const char* full_name; + + // Tables for looking up fields by number and name. + upb_inttable itof; + upb_strtable ntof; + + // Looking up fields by json name. + upb_strtable jtof; + + /* All nested defs. + * MEM: We could save some space here by putting nested defs in a contiguous + * region and calculating counts from offsets or vice-versa. */ + const upb_FieldDef* fields; + const upb_OneofDef* oneofs; + const upb_ExtensionRange* ext_ranges; + const upb_StringView* res_names; + const upb_MessageDef* nested_msgs; + const upb_MessageReservedRange* res_ranges; + const upb_EnumDef* nested_enums; + const upb_FieldDef* nested_exts; + + // TODO: These counters don't need anywhere near 32 bits. + int field_count; + int real_oneof_count; + int oneof_count; + int ext_range_count; + int res_range_count; + int res_name_count; + int nested_msg_count; + int nested_enum_count; + int nested_ext_count; + bool in_message_set; + bool is_sorted; + upb_WellKnown well_known_type; + google_protobuf_SymbolVisibility visibility; +}; + +static void assign_msg_wellknowntype(upb_MessageDef* m) { + const char* name = m->full_name; + if (name == NULL) { + m->well_known_type = kUpb_WellKnown_Unspecified; + return; + } + if (!strcmp(name, "google.protobuf.Any")) { + m->well_known_type = kUpb_WellKnown_Any; + } else if (!strcmp(name, "google.protobuf.FieldMask")) { + m->well_known_type = kUpb_WellKnown_FieldMask; + } else if (!strcmp(name, "google.protobuf.Duration")) { + m->well_known_type = kUpb_WellKnown_Duration; + } else if (!strcmp(name, "google.protobuf.Timestamp")) { + m->well_known_type = kUpb_WellKnown_Timestamp; + } else if (!strcmp(name, "google.protobuf.DoubleValue")) { + m->well_known_type = kUpb_WellKnown_DoubleValue; + } else if (!strcmp(name, "google.protobuf.FloatValue")) { + m->well_known_type = kUpb_WellKnown_FloatValue; + } else if (!strcmp(name, "google.protobuf.Int64Value")) { + m->well_known_type = kUpb_WellKnown_Int64Value; + } else if (!strcmp(name, "google.protobuf.UInt64Value")) { + m->well_known_type = kUpb_WellKnown_UInt64Value; + } else if (!strcmp(name, "google.protobuf.Int32Value")) { + m->well_known_type = kUpb_WellKnown_Int32Value; + } else if (!strcmp(name, "google.protobuf.UInt32Value")) { + m->well_known_type = kUpb_WellKnown_UInt32Value; + } else if (!strcmp(name, "google.protobuf.BoolValue")) { + m->well_known_type = kUpb_WellKnown_BoolValue; + } else if (!strcmp(name, "google.protobuf.StringValue")) { + m->well_known_type = kUpb_WellKnown_StringValue; + } else if (!strcmp(name, "google.protobuf.BytesValue")) { + m->well_known_type = kUpb_WellKnown_BytesValue; + } else if (!strcmp(name, "google.protobuf.Value")) { + m->well_known_type = kUpb_WellKnown_Value; + } else if (!strcmp(name, "google.protobuf.ListValue")) { + m->well_known_type = kUpb_WellKnown_ListValue; + } else if (!strcmp(name, "google.protobuf.Struct")) { + m->well_known_type = kUpb_WellKnown_Struct; + } else { + m->well_known_type = kUpb_WellKnown_Unspecified; + } +} + +upb_MessageDef* _upb_MessageDef_At(const upb_MessageDef* m, int i) { + return (upb_MessageDef*)&m[i]; +} + +bool _upb_MessageDef_IsValidExtensionNumber(const upb_MessageDef* m, int n) { + for (int i = 0; i < m->ext_range_count; i++) { + const upb_ExtensionRange* r = upb_MessageDef_ExtensionRange(m, i); + if (upb_ExtensionRange_Start(r) <= n && n < upb_ExtensionRange_End(r)) { + return true; + } + } + return false; +} + +const google_protobuf_MessageOptions* upb_MessageDef_Options(const upb_MessageDef* m) { + return m->opts; +} + +bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { + return m->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_MessageDef_ResolvedFeatures( + const upb_MessageDef* m) { + return m->resolved_features; +} + +const char* upb_MessageDef_FullName(const upb_MessageDef* m) { + return m->full_name; +} + +const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) { + return m->file; +} + +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) { + return m->containing_type; +} + +const char* upb_MessageDef_Name(const upb_MessageDef* m) { + return _upb_DefBuilder_FullToShort(m->full_name); +} + +const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m, + uint32_t i) { + upb_value val; + return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val) + : NULL; +} + +const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); +} + +const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); +} + +bool _upb_MessageDef_Insert(upb_MessageDef* m, const char* name, size_t len, + upb_value v, upb_Arena* a) { + return upb_strtable_insert(&m->ntof, name, len, v, a); +} + +bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, + const char* name, size_t len, + const upb_FieldDef** out_f, + const upb_OneofDef** out_o) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return false; + } + + const upb_FieldDef* f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); + const upb_OneofDef* o = _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); + if (out_f) *out_f = f; + if (out_o) *out_o = o; + return f || o; /* False if this was a JSON name. */ +} + +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t size) { + upb_value val; + + if (upb_strtable_lookup2(&m->jtof, name, size, &val)) { + return upb_value_getconstptr(val); + } + + if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); +} + +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) { + return m->ext_range_count; +} + +int upb_MessageDef_ReservedRangeCount(const upb_MessageDef* m) { + return m->res_range_count; +} + +int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m) { + return m->res_name_count; +} + +int upb_MessageDef_FieldCount(const upb_MessageDef* m) { + return m->field_count; +} + +int upb_MessageDef_OneofCount(const upb_MessageDef* m) { + return m->oneof_count; +} + +int upb_MessageDef_RealOneofCount(const upb_MessageDef* m) { + return m->real_oneof_count; +} + +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) { + return m->nested_msg_count; +} + +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) { + return m->nested_enum_count; +} + +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) { + return m->nested_ext_count; +} + +const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) { + return m->layout; +} + +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->ext_range_count); + return _upb_ExtensionRange_At(m->ext_ranges, i); +} + +const upb_MessageReservedRange* upb_MessageDef_ReservedRange( + const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->res_range_count); + return _upb_MessageReservedRange_At(m->res_ranges, i); +} + +upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->res_name_count); + return m->res_names[i]; +} + +const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->field_count); + return _upb_FieldDef_At(m->fields, i); +} + +const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->oneof_count); + return _upb_OneofDef_At(m->oneofs, i); +} + +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_msg_count); + return &m->nested_msgs[i]; +} + +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->nested_enum_count); + return _upb_EnumDef_At(m->nested_enums, i); +} + +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_ext_count); + return _upb_FieldDef_At(m->nested_exts, i); +} + +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { + return m->well_known_type; +} + +UPB_API google_protobuf_SymbolVisibility +upb_MessageDef_Visibility(const upb_MessageDef* m) { + return m->visibility; +} + +bool _upb_MessageDef_InMessageSet(const upb_MessageDef* m) { + return m->in_message_set; +} + +const upb_FieldDef* upb_MessageDef_FindFieldByName(const upb_MessageDef* m, + const char* name) { + return upb_MessageDef_FindFieldByNameWithSize(m, name, strlen(name)); +} + +const upb_OneofDef* upb_MessageDef_FindOneofByName(const upb_MessageDef* m, + const char* name) { + return upb_MessageDef_FindOneofByNameWithSize(m, name, strlen(name)); +} + +bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m) { + return google_protobuf_MessageOptions_map_entry(m->opts); +} + +bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m) { + return google_protobuf_MessageOptions_message_set_wire_format(m->opts); +} + +static upb_MiniTable* _upb_MessageDef_MakeMiniTable(upb_DefBuilder* ctx, + const upb_MessageDef* m) { + upb_StringView desc; + // Note: this will assign layout_index for fields, so upb_FieldDef_MiniTable() + // is safe to call only after this call. + bool ok = upb_MessageDef_MiniDescriptorEncode(m, ctx->tmp_arena, &desc); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + void** scratch_data = _upb_DefPool_ScratchData(ctx->symtab); + size_t* scratch_size = _upb_DefPool_ScratchSize(ctx->symtab); + upb_MiniTable* ret = upb_MiniTable_BuildWithBuf( + desc.data, desc.size, ctx->platform, ctx->arena, scratch_data, + scratch_size, ctx->status); + if (!ret) _upb_DefBuilder_FailJmp(ctx); + + return ret; +} + +void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m) { + for (int i = 0; i < m->field_count; i++) { + upb_FieldDef* f = (upb_FieldDef*)upb_MessageDef_Field(m, i); + _upb_FieldDef_Resolve(ctx, m->full_name, f); + } + + m->in_message_set = false; + for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { + upb_FieldDef* ext = (upb_FieldDef*)upb_MessageDef_NestedExtension(m, i); + _upb_FieldDef_Resolve(ctx, m->full_name, ext); + if (upb_FieldDef_Type(ext) == kUpb_FieldType_Message && + upb_FieldDef_Label(ext) == kUpb_Label_Optional && + upb_FieldDef_MessageSubDef(ext) == m && + google_protobuf_MessageOptions_message_set_wire_format( + upb_MessageDef_Options(upb_FieldDef_ContainingType(ext)))) { + m->in_message_set = true; + } + } + + for (int i = 0; i < upb_MessageDef_NestedMessageCount(m); i++) { + upb_MessageDef* n = (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i); + _upb_MessageDef_Resolve(ctx, n); + } +} + +void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, + const upb_FieldDef* f) { + const int32_t field_number = upb_FieldDef_Number(f); + + if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) { + _upb_DefBuilder_Errf(ctx, "invalid field number (%u)", field_number); + } + + const char* json_name = upb_FieldDef_JsonName(f); + const char* shortname = upb_FieldDef_Name(f); + const size_t shortnamelen = strlen(shortname); + + upb_value v = upb_value_constptr(f); + + upb_value existing_v; + if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) { + _upb_DefBuilder_Errf(ctx, "duplicate field name (%s)", shortname); + } + + const upb_value field_v = _upb_DefType_Pack(f, UPB_DEFTYPE_FIELD); + bool ok = + _upb_MessageDef_Insert(m, shortname, shortnamelen, field_v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + bool skip_json_conflicts = + google_protobuf_MessageOptions_deprecated_legacy_json_field_conflicts( + upb_MessageDef_Options(m)); + if (!skip_json_conflicts && strcmp(shortname, json_name) != 0 && + google_protobuf_FeatureSet_json_format(m->resolved_features) == + google_protobuf_FeatureSet_ALLOW && + upb_strtable_lookup(&m->ntof, json_name, &v)) { + _upb_DefBuilder_Errf( + ctx, "duplicate json_name for (%s) with original field name (%s)", + shortname, json_name); + } + + if (upb_strtable_lookup(&m->jtof, json_name, &v)) { + if (!skip_json_conflicts) { + _upb_DefBuilder_Errf(ctx, "duplicate json_name (%s)", json_name); + } + } else { + const size_t json_size = strlen(json_name); + ok = upb_strtable_insert(&m->jtof, json_name, json_size, + upb_value_constptr(f), ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + } + + if (upb_inttable_lookup(&m->itof, field_number, NULL)) { + _upb_DefBuilder_Errf(ctx, "duplicate field number (%u)", field_number); + } + + ok = upb_inttable_insert(&m->itof, field_number, v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) { + if (ctx->layout == NULL) { + m->layout = _upb_MessageDef_MakeMiniTable(ctx, m); + } else { + m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++); + UPB_ASSERT(m->field_count == upb_MiniTable_FieldCount(m->layout)); + + // We don't need the result of this call, but it will assign layout_index + // for all the fields in O(n lg n) time. + _upb_FieldDefs_Sorted(m->fields, m->field_count, ctx->tmp_arena); + } + + for (int i = 0; i < m->nested_msg_count; i++) { + upb_MessageDef* nested = + (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i); + _upb_MessageDef_CreateMiniTable(ctx, nested); + } +} + +void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, + const upb_MessageDef* m) { + for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { + const upb_FieldDef* ext = upb_MessageDef_NestedExtension(m, i); + _upb_FieldDef_BuildMiniTableExtension(ctx, ext); + } + + for (int i = 0; i < m->nested_msg_count; i++) { + _upb_MessageDef_LinkMiniTable(ctx, upb_MessageDef_NestedMessage(m, i)); + } + + if (ctx->layout || ctx->platform != kUpb_MiniTablePlatform_Native) return; + + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + const upb_MessageDef* sub_m = upb_FieldDef_MessageSubDef(f); + const upb_EnumDef* sub_e = upb_FieldDef_EnumSubDef(f); + const int layout_index = _upb_FieldDef_LayoutIndex(f); + upb_MiniTable* mt = (upb_MiniTable*)upb_MessageDef_MiniTable(m); + + UPB_ASSERT(layout_index < m->field_count); + upb_MiniTableField* mt_f = + (upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index]; + if (sub_m) { + UPB_ASSERT(mt_f); + UPB_ASSERT(sub_m->layout); + if (UPB_UNLIKELY(!upb_MiniTable_SetSubMessage(mt, mt_f, sub_m->layout))) { + _upb_DefBuilder_Errf(ctx, "invalid submsg for (%s)", m->full_name); + } + } else if (_upb_FieldDef_IsClosedEnum(f)) { + const upb_MiniTableEnum* mt_e = _upb_EnumDef_MiniTable(sub_e); + if (UPB_UNLIKELY(!upb_MiniTable_SetSubEnum(mt, mt_f, mt_e))) { + _upb_DefBuilder_Errf(ctx, "invalid subenum for (%s)", m->full_name); + } + } + } + +#ifndef NDEBUG + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + const int layout_index = _upb_FieldDef_LayoutIndex(f); + UPB_ASSERT(layout_index < upb_MiniTable_FieldCount(m->layout)); + const upb_MiniTableField* mt_f = + &m->layout->UPB_PRIVATE(fields)[layout_index]; + UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f)); + UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f)); + UPB_ASSERT(upb_FieldDef_HasPresence(f) == + upb_MiniTableField_HasPresence(mt_f)); + } +#endif +} + +// Returns whether packable repeated fields in the message should be considered +// packed by default. This is used only for the purpose of encoding +// MiniDescriptors, so we just return true if there are more packed fields than +// unpacked. This optimizes for smaller MiniDescriptors. +static bool _upb_MessageDef_DefaultIsPacked(const upb_MessageDef* m) { + int packed = 0; + int unpacked = 0; + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + if (_upb_FieldDef_IsPackable(f)) { + if (upb_FieldDef_IsPacked(f)) { + ++packed; + } else { + ++unpacked; + } + } + } + return packed > unpacked; +} + +static bool _upb_MessageDef_ValidateUtf8(const upb_MessageDef* m) { + bool has_string = false; + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + // Old binaries do not recognize the field-level "FlipValidateUtf8" wire + // modifier, so we do not actually have field-level control for old + // binaries. Given this, we judge that the better failure mode is to be + // more lax than intended, rather than more strict. To achieve this, we + // only mark the message with the ValidateUtf8 modifier if *all* fields + // validate UTF-8. + if (!_upb_FieldDef_ValidateUtf8(f)) return false; + if (upb_FieldDef_Type(f) == kUpb_FieldType_String) has_string = true; + } + return has_string; +} + +static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) { + uint64_t out = 0; + + if (_upb_MessageDef_DefaultIsPacked(m)) { + out |= kUpb_MessageModifier_DefaultIsPacked; + } + + if (_upb_MessageDef_ValidateUtf8(m)) { + out |= kUpb_MessageModifier_ValidateUtf8; + } + + if (m->ext_range_count) { + out |= kUpb_MessageModifier_IsExtendable; + } + + return out; +} + +static bool _upb_MessageDef_EncodeMap(upb_DescState* s, const upb_MessageDef* m, + upb_Arena* a) { + if (m->field_count != 2) return false; + + const upb_FieldDef* key_field = upb_MessageDef_Field(m, 0); + const upb_FieldDef* val_field = upb_MessageDef_Field(m, 1); + if (key_field == NULL || val_field == NULL) return false; + + UPB_ASSERT(_upb_FieldDef_LayoutIndex(key_field) == 0); + UPB_ASSERT(_upb_FieldDef_LayoutIndex(val_field) == 1); + + s->ptr = upb_MtDataEncoder_EncodeMap( + &s->e, s->ptr, upb_FieldDef_Type(key_field), upb_FieldDef_Type(val_field), + _upb_FieldDef_Modifiers(key_field), _upb_FieldDef_Modifiers(val_field)); + return true; +} + +static bool _upb_MessageDef_EncodeMessage(upb_DescState* s, + const upb_MessageDef* m, + upb_Arena* a) { + const upb_FieldDef** sorted = NULL; + if (!m->is_sorted) { + sorted = _upb_FieldDefs_Sorted(m->fields, m->field_count, a); + if (!sorted) return false; + } + + s->ptr = upb_MtDataEncoder_StartMessage(&s->e, s->ptr, + _upb_MessageDef_Modifiers(m)); + + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = sorted ? sorted[i] : upb_MessageDef_Field(m, i); + const upb_FieldType type = upb_FieldDef_Type(f); + const int number = upb_FieldDef_Number(f); + const uint64_t modifiers = _upb_FieldDef_Modifiers(f); + + if (!_upb_DescState_Grow(s, a)) return false; + s->ptr = upb_MtDataEncoder_PutField(&s->e, s->ptr, type, number, modifiers); + } + + for (int i = 0; i < m->real_oneof_count; i++) { + if (!_upb_DescState_Grow(s, a)) return false; + s->ptr = upb_MtDataEncoder_StartOneof(&s->e, s->ptr); + + const upb_OneofDef* o = upb_MessageDef_Oneof(m, i); + const int field_count = upb_OneofDef_FieldCount(o); + for (int j = 0; j < field_count; j++) { + const int number = upb_FieldDef_Number(upb_OneofDef_Field(o, j)); + + if (!_upb_DescState_Grow(s, a)) return false; + s->ptr = upb_MtDataEncoder_PutOneofField(&s->e, s->ptr, number); + } + } + + return true; +} + +static bool _upb_MessageDef_EncodeMessageSet(upb_DescState* s, + const upb_MessageDef* m, + upb_Arena* a) { + s->ptr = upb_MtDataEncoder_EncodeMessageSet(&s->e, s->ptr); + + return true; +} + +bool upb_MessageDef_MiniDescriptorEncode(const upb_MessageDef* m, upb_Arena* a, + upb_StringView* out) { + upb_DescState s; + _upb_DescState_Init(&s); + + if (!_upb_DescState_Grow(&s, a)) return false; + + if (upb_MessageDef_IsMapEntry(m)) { + if (!_upb_MessageDef_EncodeMap(&s, m, a)) return false; + } else if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) { + if (!_upb_MessageDef_EncodeMessageSet(&s, m, a)) return false; + } else { + if (!_upb_MessageDef_EncodeMessage(&s, m, a)) return false; + } + + if (!_upb_DescState_Grow(&s, a)) return false; + *s.ptr = '\0'; + + out->data = s.buf; + out->size = s.ptr - s.buf; + return true; +} + +static upb_StringView* _upb_ReservedNames_New(upb_DefBuilder* ctx, int n, + const upb_StringView* protos) { + upb_StringView* sv = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_StringView, n); + for (int i = 0; i < n; i++) { + sv[i].data = + upb_strdup2(protos[i].data, protos[i].size, _upb_DefBuilder_Arena(ctx)); + sv[i].size = protos[i].size; + } + return sv; +} + +static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_DescriptorProto* msg_proto, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type, + upb_MessageDef* m) { + const google_protobuf_OneofDescriptorProto* const* oneofs; + const google_protobuf_FieldDescriptorProto* const* fields; + const google_protobuf_DescriptorProto_ExtensionRange* const* ext_ranges; + const google_protobuf_DescriptorProto_ReservedRange* const* res_ranges; + const upb_StringView* res_names; + size_t n_oneof, n_field, n_enum, n_ext, n_msg; + size_t n_ext_range, n_res_range, n_res_name; + upb_StringView name; + + UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_MessageOptions_features(m->opts)); + + // Must happen before _upb_DefBuilder_Add() + m->file = _upb_DefBuilder_File(ctx); + + m->containing_type = containing_type; + m->is_sorted = true; + + name = google_protobuf_DescriptorProto_name(msg_proto); + + m->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + _upb_DefBuilder_Add(ctx, m->full_name, _upb_DefType_Pack(m, UPB_DEFTYPE_MSG)); + + oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof); + fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field); + ext_ranges = google_protobuf_DescriptorProto_extension_range(msg_proto, &n_ext_range); + res_ranges = google_protobuf_DescriptorProto_reserved_range(msg_proto, &n_res_range); + res_names = google_protobuf_DescriptorProto_reserved_name(msg_proto, &n_res_name); + + bool ok = upb_inttable_init(&m->itof, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_strtable_init(&m->jtof, n_field, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + m->oneof_count = n_oneof; + m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m->resolved_features, m); + + m->field_count = n_field; + m->fields = _upb_FieldDefs_New(ctx, n_field, fields, m->resolved_features, + m->full_name, m, &m->is_sorted); + + // Message Sets may not contain fields. + if (UPB_UNLIKELY(google_protobuf_MessageOptions_message_set_wire_format(m->opts))) { + if (UPB_UNLIKELY(n_field > 0)) { + _upb_DefBuilder_Errf(ctx, "invalid message set (%s)", m->full_name); + } + } + + m->ext_range_count = n_ext_range; + m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, + m->resolved_features, m); + + m->res_range_count = n_res_range; + m->res_ranges = + _upb_MessageReservedRanges_New(ctx, n_res_range, res_ranges, m); + + m->res_name_count = n_res_name; + m->res_names = _upb_ReservedNames_New(ctx, n_res_name, res_names); + + const size_t synthetic_count = _upb_OneofDefs_Finalize(ctx, m); + m->real_oneof_count = m->oneof_count - synthetic_count; + + assign_msg_wellknowntype(m); + if (!upb_inttable_compact(&m->itof, ctx->arena)) _upb_DefBuilder_OomErr(ctx); + + const google_protobuf_EnumDescriptorProto* const* enums = + google_protobuf_DescriptorProto_enum_type(msg_proto, &n_enum); + m->nested_enum_count = n_enum; + m->nested_enums = + _upb_EnumDefs_New(ctx, n_enum, enums, m->resolved_features, m); + + const google_protobuf_FieldDescriptorProto* const* exts = + google_protobuf_DescriptorProto_extension(msg_proto, &n_ext); + m->nested_ext_count = n_ext; + m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->resolved_features, + m->full_name, m); + + const google_protobuf_DescriptorProto* const* msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n_msg); + m->nested_msg_count = n_msg; + m->nested_msgs = + _upb_MessageDefs_New(ctx, n_msg, msgs, m->resolved_features, m); + + m->visibility = google_protobuf_DescriptorProto_visibility(msg_proto); +} + +// Allocate and initialize an array of |n| message defs. +upb_MessageDef* _upb_MessageDefs_New( + upb_DefBuilder* ctx, int n, const google_protobuf_DescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type) { + _upb_DefType_CheckPadding(sizeof(upb_MessageDef)); + + const char* name = containing_type ? containing_type->full_name + : _upb_FileDef_RawPackage(ctx->file); + + upb_MessageDef* m = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MessageDef, n); + for (int i = 0; i < n; i++) { + create_msgdef(ctx, name, protos[i], parent_features, containing_type, + &m[i]); + } + return m; +} + +#include + + +// Must be last. + +struct upb_MessageReservedRange { + int32_t start; + int32_t end; +}; + +upb_MessageReservedRange* _upb_MessageReservedRange_At( + const upb_MessageReservedRange* r, int i) { + return (upb_MessageReservedRange*)&r[i]; +} + +int32_t upb_MessageReservedRange_Start(const upb_MessageReservedRange* r) { + return r->start; +} +int32_t upb_MessageReservedRange_End(const upb_MessageReservedRange* r) { + return r->end; +} + +upb_MessageReservedRange* _upb_MessageReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ReservedRange* const* protos, + const upb_MessageDef* m) { + upb_MessageReservedRange* r = + UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MessageReservedRange, n); + + for (int i = 0; i < n; i++) { + const int32_t start = google_protobuf_DescriptorProto_ReservedRange_start(protos[i]); + const int32_t end = google_protobuf_DescriptorProto_ReservedRange_end(protos[i]); + const int32_t max = kUpb_MaxFieldNumber + 1; + + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + if (start < 1 || end <= start || end > max) { + _upb_DefBuilder_Errf(ctx, + "Reserved range (%d, %d) is invalid, message=%s\n", + (int)start, (int)end, upb_MessageDef_FullName(m)); + } + + r[i].start = start; + r[i].end = end; + } + + return r; +} + + + +// Must be last. + +struct upb_MethodDef { + const google_protobuf_MethodOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + upb_ServiceDef* service; + const char* full_name; + const upb_MessageDef* input_type; + const upb_MessageDef* output_type; + int index; + bool client_streaming; + bool server_streaming; +}; + +upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i) { + return (upb_MethodDef*)&m[i]; +} + +const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) { + return m->service; +} + +const google_protobuf_MethodOptions* upb_MethodDef_Options(const upb_MethodDef* m) { + return m->opts; +} + +bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { + return m->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_MethodDef_ResolvedFeatures( + const upb_MethodDef* m) { + return m->resolved_features; +} + +const char* upb_MethodDef_FullName(const upb_MethodDef* m) { + return m->full_name; +} + +const char* upb_MethodDef_Name(const upb_MethodDef* m) { + return _upb_DefBuilder_FullToShort(m->full_name); +} + +int upb_MethodDef_Index(const upb_MethodDef* m) { return m->index; } + +const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) { + return m->input_type; +} + +const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) { + return m->output_type; +} + +bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) { + return m->client_streaming; +} + +bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { + return m->server_streaming; +} + +static void create_method(upb_DefBuilder* ctx, + const google_protobuf_MethodDescriptorProto* method_proto, + const google_protobuf_FeatureSet* parent_features, + upb_ServiceDef* s, upb_MethodDef* m) { + UPB_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, + method_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_MethodOptions_features(m->opts)); + + upb_StringView name = google_protobuf_MethodDescriptorProto_name(method_proto); + + m->service = s; + m->full_name = + _upb_DefBuilder_MakeFullName(ctx, upb_ServiceDef_FullName(s), name); + m->client_streaming = + google_protobuf_MethodDescriptorProto_client_streaming(method_proto); + m->server_streaming = + google_protobuf_MethodDescriptorProto_server_streaming(method_proto); + m->input_type = _upb_DefBuilder_Resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_input_type(method_proto), UPB_DEFTYPE_MSG); + m->output_type = _upb_DefBuilder_Resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_output_type(method_proto), UPB_DEFTYPE_MSG); + _upb_ServiceDef_InsertMethod(ctx, s, m); +} + +// Allocate and initialize an array of |n| method defs belonging to |s|. +upb_MethodDef* _upb_MethodDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_MethodDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_ServiceDef* s) { + upb_MethodDef* m = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MethodDef, n); + for (int i = 0; i < n; i++) { + create_method(ctx, protos[i], parent_features, s, &m[i]); + m[i].index = i; + } + return m; +} + + +#include +#include +#include + + +// Must be last. + +struct upb_OneofDef { + UPB_ALIGN_AS(8) const google_protobuf_OneofOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_MessageDef* parent; + const char* full_name; + int field_count; + bool synthetic; + const upb_FieldDef** fields; + upb_strtable ntof; // lookup a field by name + upb_inttable itof; // lookup a field by number (index) +}; + +upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i) { + return (upb_OneofDef*)&o[i]; +} + +const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o) { + return o->opts; +} + +bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { + return o->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o) { + return o->resolved_features; +} + +const char* upb_OneofDef_FullName(const upb_OneofDef* o) { + return o->full_name; +} + +const char* upb_OneofDef_Name(const upb_OneofDef* o) { + return _upb_DefBuilder_FullToShort(o->full_name); +} + +const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) { + return o->parent; +} + +int upb_OneofDef_FieldCount(const upb_OneofDef* o) { return o->field_count; } + +const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i) { + UPB_ASSERT(i < o->field_count); + return o->fields[i]; +} + +int upb_OneofDef_numfields(const upb_OneofDef* o) { return o->field_count; } + +uint32_t upb_OneofDef_Index(const upb_OneofDef* o) { + // Compute index in our parent's array. + return o - upb_MessageDef_Oneof(o->parent, 0); +} + +bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o) { return o->synthetic; } + +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, + const char* name, + size_t size) { + upb_value val; + return upb_strtable_lookup2(&o->ntof, name, size, &val) + ? upb_value_getptr(val) + : NULL; +} + +const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, + const char* name) { + return upb_OneofDef_LookupNameWithSize(o, name, strlen(name)); +} + +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num) { + upb_value val; + return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val) + : NULL; +} + +void _upb_OneofDef_Insert(upb_DefBuilder* ctx, upb_OneofDef* o, + const upb_FieldDef* f, const char* name, + size_t size) { + o->field_count++; + if (_upb_FieldDef_IsProto3Optional(f)) o->synthetic = true; + + const int number = upb_FieldDef_Number(f); + const upb_value v = upb_value_constptr(f); + + // TODO: This lookup is unfortunate because we also perform it when + // inserting into the message's table. Unfortunately that step occurs after + // this one and moving things around could be tricky so let's leave it for + // a future refactoring. + const bool number_exists = upb_inttable_lookup(&o->itof, number, NULL); + if (UPB_UNLIKELY(number_exists)) { + _upb_DefBuilder_Errf(ctx, "oneof fields have the same number (%d)", number); + } + + // TODO: More redundant work happening here. + const bool name_exists = upb_strtable_lookup2(&o->ntof, name, size, NULL); + if (UPB_UNLIKELY(name_exists)) { + _upb_DefBuilder_Errf(ctx, "oneof fields have the same name (%.*s)", + (int)size, name); + } + + const bool ok = upb_inttable_insert(&o->itof, number, v, ctx->arena) && + upb_strtable_insert(&o->ntof, name, size, v, ctx->arena); + if (UPB_UNLIKELY(!ok)) { + _upb_DefBuilder_OomErr(ctx); + } +} + +// Returns the synthetic count. +size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m) { + int synthetic_count = 0; + + for (int i = 0; i < upb_MessageDef_OneofCount(m); i++) { + upb_OneofDef* o = (upb_OneofDef*)upb_MessageDef_Oneof(m, i); + + if (o->synthetic && o->field_count != 1) { + _upb_DefBuilder_Errf(ctx, + "Synthetic oneofs must have one field, not %d: %s", + o->field_count, upb_OneofDef_Name(o)); + } + + if (o->synthetic) { + synthetic_count++; + } else if (synthetic_count != 0) { + _upb_DefBuilder_Errf( + ctx, "Synthetic oneofs must be after all other oneofs: %s", + upb_OneofDef_Name(o)); + } + + o->fields = + UPB_DEFBUILDER_ALLOCARRAY(ctx, const upb_FieldDef*, o->field_count); + o->field_count = 0; + } + + for (int i = 0; i < upb_MessageDef_FieldCount(m); i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + upb_OneofDef* o = (upb_OneofDef*)upb_FieldDef_ContainingOneof(f); + if (o) { + o->fields[o->field_count++] = f; + } + } + + return synthetic_count; +} + +static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, + const google_protobuf_OneofDescriptorProto* oneof_proto, + const google_protobuf_FeatureSet* parent_features, + const upb_OneofDef* _o) { + upb_OneofDef* o = (upb_OneofDef*)_o; + + UPB_DEF_SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); + o->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_OneofOptions_features(o->opts)); + + upb_StringView name = google_protobuf_OneofDescriptorProto_name(oneof_proto); + + o->parent = m; + o->full_name = + _upb_DefBuilder_MakeFullName(ctx, upb_MessageDef_FullName(m), name); + o->field_count = 0; + o->synthetic = false; + + if (upb_MessageDef_FindByNameWithSize(m, name.data, name.size, NULL, NULL)) { + _upb_DefBuilder_Errf(ctx, "duplicate oneof name (%s)", o->full_name); + } + + upb_value v = _upb_DefType_Pack(o, UPB_DEFTYPE_ONEOF); + bool ok = _upb_MessageDef_Insert(m, name.data, name.size, v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_inttable_init(&o->itof, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_strtable_init(&o->ntof, 4, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +// Allocate and initialize an array of |n| oneof defs. +upb_OneofDef* _upb_OneofDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_OneofDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_MessageDef* m) { + _upb_DefType_CheckPadding(sizeof(upb_OneofDef)); + + upb_OneofDef* o = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_OneofDef, n); + for (int i = 0; i < n; i++) { + create_oneofdef(ctx, m, protos[i], parent_features, &o[i]); + } + return o; +} + + +#include +#include + + +// Must be last. + +struct upb_ServiceDef { + UPB_ALIGN_AS(8) const google_protobuf_ServiceOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_FileDef* file; + const char* full_name; + upb_MethodDef* methods; + int method_count; + int index; + upb_strtable ntom; +}; + +upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) { + return (upb_ServiceDef*)&s[index]; +} + +const google_protobuf_ServiceOptions* upb_ServiceDef_Options(const upb_ServiceDef* s) { + return s->opts; +} + +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { + return s->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_ServiceDef_ResolvedFeatures( + const upb_ServiceDef* s) { + return s->resolved_features; +} + +const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { + return s->full_name; +} + +const char* upb_ServiceDef_Name(const upb_ServiceDef* s) { + return _upb_DefBuilder_FullToShort(s->full_name); +} + +int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; } + +const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) { + return s->file; +} + +int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) { + return s->method_count; +} + +const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) { + return (i < 0 || i >= s->method_count) ? NULL + : _upb_MethodDef_At(s->methods, i); +} + +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name) { + return upb_ServiceDef_FindMethodByNameWithSize(s, name, strlen(name)); +} + +const upb_MethodDef* upb_ServiceDef_FindMethodByNameWithSize( + const upb_ServiceDef* s, const char* name, size_t len) { + upb_value val; + + if (!upb_strtable_lookup2(&s->ntom, name, len, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_METHOD); +} + +static void create_service(upb_DefBuilder* ctx, + const google_protobuf_ServiceDescriptorProto* svc_proto, + const google_protobuf_FeatureSet* parent_features, + upb_ServiceDef* s) { + UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, + svc_proto); + s->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_ServiceOptions_features(s->opts)); + + // Must happen before _upb_DefBuilder_Add() + s->file = _upb_DefBuilder_File(ctx); + + upb_StringView name = google_protobuf_ServiceDescriptorProto_name(svc_proto); + const char* package = _upb_FileDef_RawPackage(s->file); + s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name); + _upb_DefBuilder_Add(ctx, s->full_name, + _upb_DefType_Pack(s, UPB_DEFTYPE_SERVICE)); + + size_t n; + const google_protobuf_MethodDescriptorProto* const* methods = + google_protobuf_ServiceDescriptorProto_method(svc_proto, &n); + s->method_count = n; + bool ok = upb_strtable_init(&s->ntom, n, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + s->methods = _upb_MethodDefs_New(ctx, n, methods, s->resolved_features, s); +} + +upb_ServiceDef* _upb_ServiceDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_ServiceDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features) { + _upb_DefType_CheckPadding(sizeof(upb_ServiceDef)); + + upb_ServiceDef* s = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_ServiceDef, n); + for (int i = 0; i < n; i++) { + create_service(ctx, protos[i], parent_features, &s[i]); + s[i].index = i; + } + return s; +} + +void _upb_ServiceDef_InsertMethod(upb_DefBuilder* ctx, upb_ServiceDef* s, + const upb_MethodDef* m) { + const char* shortname = upb_MethodDef_Name(m); + const size_t shortnamelen = strlen(shortname); + upb_value existing_v; + if (upb_strtable_lookup(&s->ntom, shortname, &existing_v)) { + _upb_DefBuilder_Errf(ctx, "duplicate method name (%s)", shortname); + } + const upb_value method_v = _upb_DefType_Pack(m, UPB_DEFTYPE_METHOD); + bool ok = upb_strtable_insert(&s->ntom, shortname, shortnamelen, method_v, + ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + + +#include +#include +#include +#include +#include +#include +#include + + +// Must be last. + +typedef struct { + upb_Arena* arena; + jmp_buf err; +} upb_ToProto_Context; + +#define CHK_OOM(val) \ + if (!(val)) UPB_LONGJMP(ctx->err, 1); + +// We want to copy the options verbatim into the destination options proto. +// We use serialize+parse as our deep copy. +#define SET_OPTIONS(proto, desc_type, options_type, src, extreg) \ + { \ + size_t size; \ + /* MEM: could use a temporary arena here instead. */ \ + char* pb = google_protobuf_##options_type##_serialize(src, ctx->arena, &size); \ + CHK_OOM(pb); \ + google_protobuf_##options_type* dst = \ + google_protobuf_##options_type##_parse_ex(pb, size, extreg, 0, ctx->arena); \ + CHK_OOM(dst); \ + google_protobuf_##desc_type##_set_options(proto, dst); \ + } + +static upb_StringView strviewdup2(upb_ToProto_Context* ctx, + upb_StringView str) { + char* p = upb_Arena_Malloc(ctx->arena, str.size); + CHK_OOM(p); + memcpy(p, str.data, str.size); + return (upb_StringView){.data = p, .size = str.size}; +} + +static upb_StringView strviewdup(upb_ToProto_Context* ctx, const char* s) { + return strviewdup2(ctx, (upb_StringView){.data = s, .size = strlen(s)}); +} + +static upb_StringView qual_dup(upb_ToProto_Context* ctx, const char* s) { + size_t n = strlen(s); + char* p = upb_Arena_Malloc(ctx->arena, n + 1); + CHK_OOM(p); + p[0] = '.'; + memcpy(p + 1, s, n); + return (upb_StringView){.data = p, .size = n + 1}; +} + +UPB_PRINTF(2, 3) +static upb_StringView printf_dup(upb_ToProto_Context* ctx, const char* fmt, + ...) { + const size_t max = 32; + char* p = upb_Arena_Malloc(ctx->arena, max); + CHK_OOM(p); + va_list args; + va_start(args, fmt); + size_t n = _upb_vsnprintf(p, max, fmt, args); + va_end(args); + UPB_ASSERT(n < max); + return (upb_StringView){.data = p, .size = n}; +} + +static bool upb_isprint(char ch) { return ch >= 0x20 && ch <= 0x7f; } + +static int special_escape(char ch) { + switch (ch) { + // This is the same set of special escapes recognized by + // absl::CEscape(). + case '\n': + return 'n'; + case '\r': + return 'r'; + case '\t': + return 't'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '"': + return '"'; + default: + return -1; + } +} + +static upb_StringView default_bytes(upb_ToProto_Context* ctx, + upb_StringView val) { + size_t n = 0; + for (size_t i = 0; i < val.size; i++) { + char ch = val.data[i]; + if (special_escape(ch) >= 0) + n += 2; // '\C' + else if (upb_isprint(ch)) + n += 1; + else + n += 4; // '\123' + } + char* p = upb_Arena_Malloc(ctx->arena, n); + CHK_OOM(p); + char* dst = p; + const char* src = val.data; + const char* end = src + val.size; + while (src < end) { + unsigned char ch = *src++; + if (special_escape(ch) >= 0) { + *dst++ = '\\'; + *dst++ = (char)special_escape(ch); + } else if (upb_isprint(ch)) { + *dst++ = ch; + } else { + *dst++ = '\\'; + *dst++ = '0' + (ch >> 6); + *dst++ = '0' + ((ch >> 3) & 0x7); + *dst++ = '0' + (ch & 0x7); + } + } + return (upb_StringView){.data = p, .size = n}; +} + +static upb_StringView default_string(upb_ToProto_Context* ctx, + const upb_FieldDef* f) { + upb_MessageValue d = upb_FieldDef_Default(f); + upb_CType type = upb_FieldDef_CType(f); + + if (type == kUpb_CType_Float || type == kUpb_CType_Double) { + double val = type == kUpb_CType_Float ? d.float_val : d.double_val; + if (val == INFINITY) { + return strviewdup(ctx, "inf"); + } else if (val == -INFINITY) { + return strviewdup(ctx, "-inf"); + } else if (val != val) { + return strviewdup(ctx, "nan"); + } + } + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return strviewdup(ctx, d.bool_val ? "true" : "false"); + case kUpb_CType_Enum: { + const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(e, d.int32_val); + return strviewdup(ctx, upb_EnumValueDef_Name(ev)); + } + case kUpb_CType_Int64: + return printf_dup(ctx, "%" PRId64, d.int64_val); + case kUpb_CType_UInt64: + return printf_dup(ctx, "%" PRIu64, d.uint64_val); + case kUpb_CType_Int32: + return printf_dup(ctx, "%" PRId32, d.int32_val); + case kUpb_CType_UInt32: + return printf_dup(ctx, "%" PRIu32, d.uint32_val); + case kUpb_CType_Float: + return printf_dup(ctx, "%.9g", d.float_val); + case kUpb_CType_Double: + return printf_dup(ctx, "%.17g", d.double_val); + case kUpb_CType_String: + return strviewdup2(ctx, d.str_val); + case kUpb_CType_Bytes: + return default_bytes(ctx, d.str_val); + default: + UPB_UNREACHABLE(); + } +} + +static google_protobuf_DescriptorProto_ReservedRange* resrange_toproto( + upb_ToProto_Context* ctx, const upb_MessageReservedRange* r) { + google_protobuf_DescriptorProto_ReservedRange* proto = + google_protobuf_DescriptorProto_ReservedRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_ReservedRange_set_start( + proto, upb_MessageReservedRange_Start(r)); + google_protobuf_DescriptorProto_ReservedRange_set_end(proto, + upb_MessageReservedRange_End(r)); + + return proto; +} + +static google_protobuf_EnumDescriptorProto_EnumReservedRange* enumresrange_toproto( + upb_ToProto_Context* ctx, const upb_EnumReservedRange* r) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* proto = + google_protobuf_EnumDescriptorProto_EnumReservedRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start( + proto, upb_EnumReservedRange_Start(r)); + google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end( + proto, upb_EnumReservedRange_End(r)); + + return proto; +} + +static google_protobuf_FieldDescriptorProto* fielddef_toproto(upb_ToProto_Context* ctx, + const upb_FieldDef* f) { + google_protobuf_FieldDescriptorProto* proto = + google_protobuf_FieldDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_FieldDescriptorProto_set_name(proto, + strviewdup(ctx, upb_FieldDef_Name(f))); + google_protobuf_FieldDescriptorProto_set_number(proto, upb_FieldDef_Number(f)); + + if (upb_FieldDef_IsRequired(f) && + upb_FileDef_Edition(upb_FieldDef_File(f)) >= google_protobuf_EDITION_2023) { + google_protobuf_FieldDescriptorProto_set_label( + proto, google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL); + } else { + google_protobuf_FieldDescriptorProto_set_label(proto, upb_FieldDef_Label(f)); + } + if (upb_FieldDef_Type(f) == kUpb_FieldType_Group && + upb_FileDef_Edition(upb_FieldDef_File(f)) >= google_protobuf_EDITION_2023) { + google_protobuf_FieldDescriptorProto_set_type(proto, kUpb_FieldType_Message); + } else { + google_protobuf_FieldDescriptorProto_set_type(proto, upb_FieldDef_Type(f)); + } + + if (upb_FieldDef_HasJsonName(f)) { + google_protobuf_FieldDescriptorProto_set_json_name( + proto, strviewdup(ctx, upb_FieldDef_JsonName(f))); + } + + if (upb_FieldDef_IsSubMessage(f)) { + google_protobuf_FieldDescriptorProto_set_type_name( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(f)))); + } else if (upb_FieldDef_CType(f) == kUpb_CType_Enum) { + google_protobuf_FieldDescriptorProto_set_type_name( + proto, qual_dup(ctx, upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(f)))); + } + + if (upb_FieldDef_IsExtension(f)) { + google_protobuf_FieldDescriptorProto_set_extendee( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_ContainingType(f)))); + } + + if (upb_FieldDef_HasDefault(f)) { + google_protobuf_FieldDescriptorProto_set_default_value(proto, + default_string(ctx, f)); + } + + const upb_OneofDef* o = upb_FieldDef_ContainingOneof(f); + if (o) { + google_protobuf_FieldDescriptorProto_set_oneof_index(proto, upb_OneofDef_Index(o)); + } + + if (_upb_FieldDef_IsProto3Optional(f)) { + google_protobuf_FieldDescriptorProto_set_proto3_optional(proto, true); + } + + if (upb_FieldDef_HasOptions(f)) { + SET_OPTIONS(proto, FieldDescriptorProto, FieldOptions, + upb_FieldDef_Options(f), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_FieldDef_File(f)))); + } + + return proto; +} + +static google_protobuf_OneofDescriptorProto* oneofdef_toproto(upb_ToProto_Context* ctx, + const upb_OneofDef* o) { + google_protobuf_OneofDescriptorProto* proto = + google_protobuf_OneofDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_OneofDescriptorProto_set_name(proto, + strviewdup(ctx, upb_OneofDef_Name(o))); + + if (upb_OneofDef_HasOptions(o)) { + SET_OPTIONS(proto, OneofDescriptorProto, OneofOptions, + upb_OneofDef_Options(o), + _upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool( + upb_MessageDef_File(upb_OneofDef_ContainingType(o))))); + } + + return proto; +} + +static google_protobuf_EnumValueDescriptorProto* enumvaldef_toproto( + upb_ToProto_Context* ctx, const upb_EnumValueDef* e) { + google_protobuf_EnumValueDescriptorProto* proto = + google_protobuf_EnumValueDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumValueDescriptorProto_set_name( + proto, strviewdup(ctx, upb_EnumValueDef_Name(e))); + google_protobuf_EnumValueDescriptorProto_set_number(proto, upb_EnumValueDef_Number(e)); + + if (upb_EnumValueDef_HasOptions(e)) { + SET_OPTIONS(proto, EnumValueDescriptorProto, EnumValueOptions, + upb_EnumValueDef_Options(e), + _upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool( + upb_EnumDef_File(upb_EnumValueDef_Enum(e))))); + } + + return proto; +} + +static google_protobuf_EnumDescriptorProto* enumdef_toproto(upb_ToProto_Context* ctx, + const upb_EnumDef* e) { + google_protobuf_EnumDescriptorProto* proto = + google_protobuf_EnumDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumDescriptorProto_set_name(proto, + strviewdup(ctx, upb_EnumDef_Name(e))); + + int n = upb_EnumDef_ValueCount(e); + google_protobuf_EnumValueDescriptorProto** vals = + google_protobuf_EnumDescriptorProto_resize_value(proto, n, ctx->arena); + CHK_OOM(vals); + for (int i = 0; i < n; i++) { + vals[i] = enumvaldef_toproto(ctx, upb_EnumDef_Value(e, i)); + } + + n = upb_EnumDef_ReservedRangeCount(e); + google_protobuf_EnumDescriptorProto_EnumReservedRange** res_ranges = + google_protobuf_EnumDescriptorProto_resize_reserved_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_ranges[i] = enumresrange_toproto(ctx, upb_EnumDef_ReservedRange(e, i)); + } + + n = upb_EnumDef_ReservedNameCount(e); + upb_StringView* res_names = + google_protobuf_EnumDescriptorProto_resize_reserved_name(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_names[i] = upb_EnumDef_ReservedName(e, i); + } + + if (upb_EnumDef_HasOptions(e)) { + SET_OPTIONS(proto, EnumDescriptorProto, EnumOptions, upb_EnumDef_Options(e), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_EnumDef_File(e)))); + } + + google_protobuf_SymbolVisibility visibility = upb_EnumDef_Visibility(e); + if (visibility != google_protobuf_VISIBILITY_UNSET) { + google_protobuf_EnumDescriptorProto_set_visibility(proto, visibility); + } + + return proto; +} + +static google_protobuf_DescriptorProto_ExtensionRange* extrange_toproto( + upb_ToProto_Context* ctx, const upb_MessageDef* m, + const upb_ExtensionRange* e) { + google_protobuf_DescriptorProto_ExtensionRange* proto = + google_protobuf_DescriptorProto_ExtensionRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_ExtensionRange_set_start(proto, + upb_ExtensionRange_Start(e)); + google_protobuf_DescriptorProto_ExtensionRange_set_end(proto, + upb_ExtensionRange_End(e)); + + if (upb_ExtensionRange_HasOptions(e)) { + SET_OPTIONS(proto, DescriptorProto_ExtensionRange, ExtensionRangeOptions, + upb_ExtensionRange_Options(e), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_MessageDef_File(m)))); + } + + return proto; +} + +static google_protobuf_DescriptorProto* msgdef_toproto(upb_ToProto_Context* ctx, + const upb_MessageDef* m) { + google_protobuf_DescriptorProto* proto = google_protobuf_DescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_set_name(proto, + strviewdup(ctx, upb_MessageDef_Name(m))); + + int n; + + n = upb_MessageDef_FieldCount(m); + google_protobuf_FieldDescriptorProto** fields = + google_protobuf_DescriptorProto_resize_field(proto, n, ctx->arena); + CHK_OOM(fields); + for (int i = 0; i < n; i++) { + fields[i] = fielddef_toproto(ctx, upb_MessageDef_Field(m, i)); + } + + n = upb_MessageDef_OneofCount(m); + google_protobuf_OneofDescriptorProto** oneofs = + google_protobuf_DescriptorProto_resize_oneof_decl(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + oneofs[i] = oneofdef_toproto(ctx, upb_MessageDef_Oneof(m, i)); + } + + n = upb_MessageDef_NestedMessageCount(m); + google_protobuf_DescriptorProto** nested_msgs = + google_protobuf_DescriptorProto_resize_nested_type(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_msgs[i] = msgdef_toproto(ctx, upb_MessageDef_NestedMessage(m, i)); + } + + n = upb_MessageDef_NestedEnumCount(m); + google_protobuf_EnumDescriptorProto** nested_enums = + google_protobuf_DescriptorProto_resize_enum_type(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_enums[i] = enumdef_toproto(ctx, upb_MessageDef_NestedEnum(m, i)); + } + + n = upb_MessageDef_NestedExtensionCount(m); + google_protobuf_FieldDescriptorProto** nested_exts = + google_protobuf_DescriptorProto_resize_extension(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_exts[i] = + fielddef_toproto(ctx, upb_MessageDef_NestedExtension(m, i)); + } + + n = upb_MessageDef_ExtensionRangeCount(m); + google_protobuf_DescriptorProto_ExtensionRange** ext_ranges = + google_protobuf_DescriptorProto_resize_extension_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + ext_ranges[i] = + extrange_toproto(ctx, m, upb_MessageDef_ExtensionRange(m, i)); + } + + n = upb_MessageDef_ReservedRangeCount(m); + google_protobuf_DescriptorProto_ReservedRange** res_ranges = + google_protobuf_DescriptorProto_resize_reserved_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_ranges[i] = resrange_toproto(ctx, upb_MessageDef_ReservedRange(m, i)); + } + + n = upb_MessageDef_ReservedNameCount(m); + upb_StringView* res_names = + google_protobuf_DescriptorProto_resize_reserved_name(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_names[i] = upb_MessageDef_ReservedName(m, i); + } + + if (upb_MessageDef_HasOptions(m)) { + SET_OPTIONS(proto, DescriptorProto, MessageOptions, + upb_MessageDef_Options(m), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_MessageDef_File(m)))); + } + + google_protobuf_SymbolVisibility visibility = upb_MessageDef_Visibility(m); + if (visibility != google_protobuf_VISIBILITY_UNSET) { + google_protobuf_DescriptorProto_set_visibility(proto, visibility); + } + + return proto; +} + +static google_protobuf_MethodDescriptorProto* methoddef_toproto(upb_ToProto_Context* ctx, + const upb_MethodDef* m) { + google_protobuf_MethodDescriptorProto* proto = + google_protobuf_MethodDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_MethodDescriptorProto_set_name(proto, + strviewdup(ctx, upb_MethodDef_Name(m))); + + google_protobuf_MethodDescriptorProto_set_input_type( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_InputType(m)))); + google_protobuf_MethodDescriptorProto_set_output_type( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_OutputType(m)))); + + if (upb_MethodDef_ClientStreaming(m)) { + google_protobuf_MethodDescriptorProto_set_client_streaming(proto, true); + } + + if (upb_MethodDef_ServerStreaming(m)) { + google_protobuf_MethodDescriptorProto_set_server_streaming(proto, true); + } + + if (upb_MethodDef_HasOptions(m)) { + SET_OPTIONS( + proto, MethodDescriptorProto, MethodOptions, upb_MethodDef_Options(m), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_ServiceDef_File(upb_MethodDef_Service(m))))); + } + + return proto; +} + +static google_protobuf_ServiceDescriptorProto* servicedef_toproto( + upb_ToProto_Context* ctx, const upb_ServiceDef* s) { + google_protobuf_ServiceDescriptorProto* proto = + google_protobuf_ServiceDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_ServiceDescriptorProto_set_name( + proto, strviewdup(ctx, upb_ServiceDef_Name(s))); + + size_t n = upb_ServiceDef_MethodCount(s); + google_protobuf_MethodDescriptorProto** methods = + google_protobuf_ServiceDescriptorProto_resize_method(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + methods[i] = methoddef_toproto(ctx, upb_ServiceDef_Method(s, i)); + } + + if (upb_ServiceDef_HasOptions(s)) { + SET_OPTIONS(proto, ServiceDescriptorProto, ServiceOptions, + upb_ServiceDef_Options(s), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_ServiceDef_File(s)))); + } + + return proto; +} + +static google_protobuf_FileDescriptorProto* filedef_toproto(upb_ToProto_Context* ctx, + const upb_FileDef* f) { + google_protobuf_FileDescriptorProto* proto = + google_protobuf_FileDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_FileDescriptorProto_set_name(proto, + strviewdup(ctx, upb_FileDef_Name(f))); + + const char* package = upb_FileDef_Package(f); + if (package) { + size_t n = strlen(package); + if (n) { + google_protobuf_FileDescriptorProto_set_package(proto, strviewdup(ctx, package)); + } + } + + google_protobuf_Edition edition = upb_FileDef_Edition(f); + + switch (edition) { + case google_protobuf_EDITION_PROTO2: + // We could set syntax to "proto2", but C++ omits it completely, which is + // equivalent. + break; + case google_protobuf_EDITION_PROTO3: + google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "proto3")); + break; + default: + google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "editions")); + google_protobuf_FileDescriptorProto_set_edition(proto, edition); + break; + } + + size_t n; + n = upb_FileDef_DependencyCount(f); + upb_StringView* deps = + google_protobuf_FileDescriptorProto_resize_dependency(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + deps[i] = strviewdup(ctx, upb_FileDef_Name(upb_FileDef_Dependency(f, i))); + } + + n = upb_FileDef_PublicDependencyCount(f); + int32_t* public_deps = + google_protobuf_FileDescriptorProto_resize_public_dependency(proto, n, ctx->arena); + const int32_t* public_dep_nums = _upb_FileDef_PublicDependencyIndexes(f); + if (n) memcpy(public_deps, public_dep_nums, n * sizeof(int32_t)); + + n = upb_FileDef_WeakDependencyCount(f); + int32_t* weak_deps = + google_protobuf_FileDescriptorProto_resize_weak_dependency(proto, n, ctx->arena); + const int32_t* weak_dep_nums = _upb_FileDef_WeakDependencyIndexes(f); + if (n) memcpy(weak_deps, weak_dep_nums, n * sizeof(int32_t)); + + n = upb_FileDef_TopLevelMessageCount(f); + google_protobuf_DescriptorProto** msgs = + google_protobuf_FileDescriptorProto_resize_message_type(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + msgs[i] = msgdef_toproto(ctx, upb_FileDef_TopLevelMessage(f, i)); + } + + n = upb_FileDef_TopLevelEnumCount(f); + google_protobuf_EnumDescriptorProto** enums = + google_protobuf_FileDescriptorProto_resize_enum_type(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + enums[i] = enumdef_toproto(ctx, upb_FileDef_TopLevelEnum(f, i)); + } + + n = upb_FileDef_ServiceCount(f); + google_protobuf_ServiceDescriptorProto** services = + google_protobuf_FileDescriptorProto_resize_service(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + services[i] = servicedef_toproto(ctx, upb_FileDef_Service(f, i)); + } + + n = upb_FileDef_TopLevelExtensionCount(f); + google_protobuf_FieldDescriptorProto** exts = + google_protobuf_FileDescriptorProto_resize_extension(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + exts[i] = fielddef_toproto(ctx, upb_FileDef_TopLevelExtension(f, i)); + } + + if (upb_FileDef_HasOptions(f)) { + SET_OPTIONS(proto, FileDescriptorProto, FileOptions, upb_FileDef_Options(f), + _upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool(f))); + } + + return proto; +} + +static google_protobuf_DescriptorProto* upb_ToProto_ConvertMessageDef( + upb_ToProto_Context* const ctx, const upb_MessageDef* const m) { + if (UPB_SETJMP(ctx->err)) return NULL; + return msgdef_toproto(ctx, m); +} + +google_protobuf_DescriptorProto* upb_MessageDef_ToProto(const upb_MessageDef* m, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertMessageDef(&ctx, m); +} + +google_protobuf_EnumDescriptorProto* upb_ToProto_ConvertEnumDef( + upb_ToProto_Context* const ctx, const upb_EnumDef* const e) { + if (UPB_SETJMP(ctx->err)) return NULL; + return enumdef_toproto(ctx, e); +} + +google_protobuf_EnumDescriptorProto* upb_EnumDef_ToProto(const upb_EnumDef* e, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertEnumDef(&ctx, e); +} + +google_protobuf_EnumValueDescriptorProto* upb_ToProto_ConvertEnumValueDef( + upb_ToProto_Context* const ctx, const upb_EnumValueDef* e) { + if (UPB_SETJMP(ctx->err)) return NULL; + return enumvaldef_toproto(ctx, e); +} + +google_protobuf_EnumValueDescriptorProto* upb_EnumValueDef_ToProto( + const upb_EnumValueDef* e, upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertEnumValueDef(&ctx, e); +} + +google_protobuf_FieldDescriptorProto* upb_ToProto_ConvertFieldDef( + upb_ToProto_Context* const ctx, const upb_FieldDef* f) { + if (UPB_SETJMP(ctx->err)) return NULL; + return fielddef_toproto(ctx, f); +} + +google_protobuf_FieldDescriptorProto* upb_FieldDef_ToProto(const upb_FieldDef* f, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertFieldDef(&ctx, f); +} + +google_protobuf_OneofDescriptorProto* upb_ToProto_ConvertOneofDef( + upb_ToProto_Context* const ctx, const upb_OneofDef* o) { + if (UPB_SETJMP(ctx->err)) return NULL; + return oneofdef_toproto(ctx, o); +} + +google_protobuf_OneofDescriptorProto* upb_OneofDef_ToProto(const upb_OneofDef* o, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertOneofDef(&ctx, o); +} + +google_protobuf_FileDescriptorProto* upb_ToProto_ConvertFileDef( + upb_ToProto_Context* const ctx, const upb_FileDef* const f) { + if (UPB_SETJMP(ctx->err)) return NULL; + return filedef_toproto(ctx, f); +} + +google_protobuf_FileDescriptorProto* upb_FileDef_ToProto(const upb_FileDef* f, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertFileDef(&ctx, f); +} + +google_protobuf_MethodDescriptorProto* upb_ToProto_ConvertMethodDef( + upb_ToProto_Context* const ctx, const upb_MethodDef* m) { + if (UPB_SETJMP(ctx->err)) return NULL; + return methoddef_toproto(ctx, m); +} + +google_protobuf_MethodDescriptorProto* upb_MethodDef_ToProto( + const upb_MethodDef* const m, upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertMethodDef(&ctx, m); +} + +google_protobuf_ServiceDescriptorProto* upb_ToProto_ConvertServiceDef( + upb_ToProto_Context* const ctx, const upb_ServiceDef* const s) { + if (UPB_SETJMP(ctx->err)) return NULL; + return servicedef_toproto(ctx, s); +} + +google_protobuf_ServiceDescriptorProto* upb_ServiceDef_ToProto(const upb_ServiceDef* s, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertServiceDef(&ctx, s); +} + + +#include +#include +#include +#include +#include + + +// Our awkward dance for including fasttable only when it is enabled. +#if UPB_FASTTABLE +#define UPB_INCLUDE_FAST_DECODE +#endif + +#ifdef UPB_INCLUDE_FAST_DECODE +#endif + +#undef UPB_INCLUDE_FAST_DECODE + +// Must be last. + +// A few fake field types for our tables. +enum { + kUpb_FakeFieldType_FieldNotFound = 0, + kUpb_FakeFieldType_MessageSetItem = 19, +}; + +// DecodeOp: an action to be performed for a wire-type/field-type combination. +enum { + // Special ops: we don't write data to regular fields for these. + kUpb_DecodeOp_UnknownField = -1, + kUpb_DecodeOp_MessageSetItem = -2, + + // Scalar-only ops. + kUpb_DecodeOp_Scalar1Byte = 0, + kUpb_DecodeOp_Scalar4Byte = 2, + kUpb_DecodeOp_Scalar8Byte = 3, + + // Scalar/repeated ops. + kUpb_DecodeOp_String = 4, + kUpb_DecodeOp_Bytes = 5, + kUpb_DecodeOp_SubMessage = 6, + + // Repeated-only ops (also see macros below). + kUpb_DecodeOp_PackedEnum = 13, +}; + +// For packed fields it is helpful to be able to recover the lg2 of the data +// size from the op. +#define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */ +#define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */ + +typedef union { + bool bool_val; + uint32_t uint32_val; + uint64_t uint64_val; + uint32_t size; +} wireval; + +static void _upb_Decoder_AssumeEpsHasErrorHandler(upb_Decoder* d) { + UPB_ASSUME(upb_EpsCopyInputStream_HasErrorHandler(&d->input)); +} + +#define EPS(d) (_upb_Decoder_AssumeEpsHasErrorHandler(d), &(d)->input) + +static bool _upb_Decoder_Reserve(upb_Decoder* d, upb_Array* arr, size_t elem) { + bool need_realloc = + arr->UPB_PRIVATE(capacity) - arr->UPB_PRIVATE(size) < elem; + if (need_realloc && !UPB_PRIVATE(_upb_Array_Realloc)( + arr, arr->UPB_PRIVATE(size) + elem, &d->arena)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + return need_realloc; +} + +typedef struct { + const char* ptr; + uint64_t val; +} _upb_DecodeLongVarintReturn; + +// This is identical to _upb_Decoder_DecodeTag() except that the maximum value +// is INT32_MAX instead of UINT32_MAX. +UPB_FORCEINLINE +const char* upb_Decoder_DecodeSize(upb_Decoder* d, const char* ptr, + uint32_t* size) { + int sz; + ptr = upb_WireReader_ReadSize(ptr, &sz, EPS(d)); + *size = sz; + return ptr; +} + +static void _upb_Decoder_MungeInt32(wireval* val) { + if (!upb_IsLittleEndian()) { + /* The next stage will memcpy(dst, &val, 4) */ + val->uint32_val = val->uint64_val; + } +} + +static void _upb_Decoder_Munge(const upb_MiniTableField* field, wireval* val) { + switch (field->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Bool: + val->bool_val = val->uint64_val != 0; + break; + case kUpb_FieldType_SInt32: { + uint32_t n = val->uint64_val; + val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1); + break; + } + case kUpb_FieldType_SInt64: { + uint64_t n = val->uint64_val; + val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1); + break; + } + case kUpb_FieldType_Int32: + case kUpb_FieldType_UInt32: + _upb_Decoder_MungeInt32(val); + break; + case kUpb_FieldType_Enum: + UPB_UNREACHABLE(); + } +} + +static upb_Message* _upb_Decoder_NewSubMessage2(upb_Decoder* d, + const upb_MiniTable* subl, + const upb_MiniTableField* field, + upb_Message** target) { + UPB_ASSERT(subl); + upb_Message* msg = _upb_Message_New(subl, &d->arena); + if (!msg) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + + *target = msg; + return msg; +} + +static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d, + const upb_MiniTableField* field, + upb_Message** target) { + const upb_MiniTable* subl = upb_MiniTable_GetSubMessageTable(field); + return _upb_Decoder_NewSubMessage2(d, subl, field, target); +} + +static const char* _upb_Decoder_ReadString2(upb_Decoder* d, const char* ptr, + int size, upb_StringView* str, + bool validate_utf8) { + if (!_upb_Decoder_ReadString(d, &ptr, size, str, validate_utf8)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_RecurseSubMessage(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable* subl, + uint32_t expected_end_group) { + if (--d->depth < 0) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_MaxDepthExceeded); + } + ptr = _upb_Decoder_DecodeMessage(d, ptr, submsg, subl); + d->depth++; + if (d->end_group != expected_end_group) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeSubMessage(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTableField* field, + size_t size) { + ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size); + const upb_MiniTable* subl = upb_MiniTable_GetSubMessageTable(field); + UPB_ASSERT(subl); + ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP); + upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta); + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeGroup(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable* subl, + uint32_t number) { + if (upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, number); + d->end_group = DECODE_NOGROUP; + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeKnownGroup(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTableField* field) { + const upb_MiniTable* subl = upb_MiniTable_GetSubMessageTable(field); + UPB_ASSERT(subl); + return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, + field->UPB_PRIVATE(number)); +} + +#define kUpb_Decoder_EncodeVarint32MaxSize 5 +static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +UPB_FORCEINLINE +void _upb_Decoder_AddEnumValueToUnknown(upb_Decoder* d, upb_Message* msg, + const upb_MiniTableField* field, + wireval* val) { + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, + // so we just re-encode the tag and value here. + const uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; + upb_Message* unknown_msg = + field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension ? d->original_msg + : msg; + char buf[2 * kUpb_Decoder_EncodeVarint32MaxSize]; + char* end = buf; + end = upb_Decoder_EncodeVarint32(tag, end); + end = upb_Decoder_EncodeVarint32(val->uint64_val, end); + + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(unknown_msg, buf, end - buf, + &d->arena, kUpb_AddUnknown_Copy)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFixedPacked(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTableField* field, + int lg2) { + upb_StringView sv; + ptr = upb_EpsCopyInputStream_ReadStringEphemeral(&d->input, ptr, val->size, + &sv); + if (!ptr) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + int mask = (1 << lg2) - 1; + if (UPB_UNLIKELY((val->size & mask) != 0 || ptr == NULL)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + size_t count = val->size >> lg2; + if (count == 0) return ptr; + _upb_Decoder_Reserve(d, arr, count); + void* mem = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << lg2, void); + arr->UPB_PRIVATE(size) += count; + if (upb_IsLittleEndian()) { + memcpy(mem, sv.data, sv.size); + } else { + const char* src = sv.data; + const char* src_end = src + sv.size; + char* dst = mem; + if (lg2 == 2) { + for (; src < src_end; src += 4, dst += 4) { + uint32_t x; + memcpy(&x, src, 4); + x = upb_BigEndian32(x); + memcpy(dst, &x, 4); + } + } else { + UPB_ASSERT(lg2 == 3); + for (; src < src_end; src += 8, dst += 8) { + uint64_t x; + memcpy(&x, src, 8); + x = upb_BigEndian64(x); + memcpy(dst, &x, 8); + } + } + } + + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeVarintPacked(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTableField* field, + int lg2) { + int scale = 1 << lg2; + ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); + char* out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << lg2, void); + while (!upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + wireval elem; + ptr = upb_WireReader_ReadVarint(ptr, &elem.uint64_val, EPS(d)); + _upb_Decoder_Munge(field, &elem); + if (_upb_Decoder_Reserve(d, arr, 1)) { + out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << lg2, void); + } + arr->UPB_PRIVATE(size)++; + memcpy(out, &elem, scale); + out += scale; + } + upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta); + return ptr; +} + +UPB_NOINLINE +static const char* _upb_Decoder_DecodeEnumPacked( + upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr, + const upb_MiniTableField* field, wireval* val) { + const upb_MiniTableEnum* e = upb_MiniTable_GetSubEnumTable(field); + ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); + char* out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) * 4, void); + while (!upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + wireval elem; + ptr = upb_WireReader_ReadVarint(ptr, &elem.uint64_val, EPS(d)); + if (!upb_MiniTableEnum_CheckValue(e, elem.uint64_val)) { + _upb_Decoder_AddEnumValueToUnknown(d, msg, field, &elem); + continue; + } + if (_upb_Decoder_Reserve(d, arr, 1)) { + out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) * 4, void); + } + arr->UPB_PRIVATE(size)++; + memcpy(out, &elem, 4); + out += 4; + } + upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta); + return ptr; +} + +static upb_Array* _upb_Decoder_CreateArray(upb_Decoder* d, + const upb_MiniTableField* field) { + const upb_FieldType field_type = field->UPB_PRIVATE(descriptortype); + const size_t lg2 = UPB_PRIVATE(_upb_FieldType_SizeLg2)(field_type); + upb_Array* ret = UPB_PRIVATE(_upb_Array_New)(&d->arena, 4, lg2); + if (!ret) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + return ret; +} + +static const char* _upb_Decoder_DecodeToArray(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTableField* field, + wireval* val, int op) { + upb_Array** arrp = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void); + upb_Array* arr = *arrp; + void* mem; + + if (arr) { + _upb_Decoder_Reserve(d, arr, 1); + } else { + arr = _upb_Decoder_CreateArray(d, field); + *arrp = arr; + } + + switch (op) { + case kUpb_DecodeOp_Scalar1Byte: + case kUpb_DecodeOp_Scalar4Byte: + case kUpb_DecodeOp_Scalar8Byte: + /* Append scalar value. */ + mem = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << op, void); + arr->UPB_PRIVATE(size)++; + memcpy(mem, val, 1 << op); + return ptr; + case kUpb_DecodeOp_String: { + /* Append string. */ + upb_StringView* str = (upb_StringView*)upb_Array_MutableDataPtr(arr) + + arr->UPB_PRIVATE(size); + ptr = _upb_Decoder_ReadString2(d, ptr, val->size, str, + /*validate_utf8=*/true); + arr->UPB_PRIVATE(size)++; + return ptr; + } + case kUpb_DecodeOp_Bytes: { + /* Append bytes. */ + upb_StringView* str = (upb_StringView*)upb_Array_MutableDataPtr(arr) + + arr->UPB_PRIVATE(size); + ptr = _upb_Decoder_ReadString2(d, ptr, val->size, str, + /*validate_utf8=*/false); + arr->UPB_PRIVATE(size)++; + return ptr; + } + case kUpb_DecodeOp_SubMessage: { + /* Append submessage / group. */ + upb_Message** target = + UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) * sizeof(void*), upb_Message*); + upb_Message* submsg = _upb_Decoder_NewSubMessage(d, field, target); + arr->UPB_PRIVATE(size)++; + if (UPB_UNLIKELY(field->UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group)) { + return _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, field); + } else { + return _upb_Decoder_DecodeSubMessage(d, ptr, submsg, field, val->size); + } + } + case OP_FIXPCK_LG2(2): + case OP_FIXPCK_LG2(3): + return _upb_Decoder_DecodeFixedPacked(d, ptr, arr, val, field, + op - OP_FIXPCK_LG2(0)); + case OP_VARPCK_LG2(0): + case OP_VARPCK_LG2(2): + case OP_VARPCK_LG2(3): + return _upb_Decoder_DecodeVarintPacked(d, ptr, arr, val, field, + op - OP_VARPCK_LG2(0)); + case kUpb_DecodeOp_PackedEnum: + return _upb_Decoder_DecodeEnumPacked(d, ptr, msg, arr, field, val); + default: + UPB_UNREACHABLE(); + } +} + +static upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, + const upb_MiniTable* entry) { + // Maps descriptor type -> upb map size + static const uint8_t kSizeInMap[] = { + [0] = -1, // invalid descriptor type + [kUpb_FieldType_Double] = 8, + [kUpb_FieldType_Float] = 4, + [kUpb_FieldType_Int64] = 8, + [kUpb_FieldType_UInt64] = 8, + [kUpb_FieldType_Int32] = 4, + [kUpb_FieldType_Fixed64] = 8, + [kUpb_FieldType_Fixed32] = 4, + [kUpb_FieldType_Bool] = 1, + [kUpb_FieldType_String] = UPB_MAPTYPE_STRING, + [kUpb_FieldType_Group] = sizeof(void*), + [kUpb_FieldType_Message] = sizeof(void*), + [kUpb_FieldType_Bytes] = UPB_MAPTYPE_STRING, + [kUpb_FieldType_UInt32] = 4, + [kUpb_FieldType_Enum] = 4, + [kUpb_FieldType_SFixed32] = 4, + [kUpb_FieldType_SFixed64] = 8, + [kUpb_FieldType_SInt32] = 4, + [kUpb_FieldType_SInt64] = 8, + }; + + const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1]; + char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)]; + char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)]; + UPB_ASSERT(key_field->UPB_PRIVATE(offset) == offsetof(upb_MapEntry, k)); + UPB_ASSERT(val_field->UPB_PRIVATE(offset) == offsetof(upb_MapEntry, v)); + upb_Map* ret = _upb_Map_New(&d->arena, key_size, val_size); + if (!ret) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + return ret; +} + +UPB_NOINLINE static void _upb_Decoder_AddMapEntryUnknown( + upb_Decoder* d, upb_Message* msg, const upb_MiniTableField* field, + upb_Message* ent_msg, const upb_MiniTable* entry) { + char* buf; + size_t size; + upb_EncodeStatus status = + upb_Encode(ent_msg, entry, 0, &d->arena, &buf, &size); + if (status != kUpb_EncodeStatus_Ok) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + char delim_buf[2 * kUpb_Decoder_EncodeVarint32MaxSize]; + char* delim_end = delim_buf; + uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Delimited; + delim_end = upb_Decoder_EncodeVarint32(tag, delim_end); + delim_end = upb_Decoder_EncodeVarint32(size, delim_end); + upb_StringView unknown[] = { + {delim_buf, delim_end - delim_buf}, + {buf, size}, + }; + + if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 2)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } +} + +static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTableField* field, + wireval* val) { + upb_Map** map_p = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), upb_Map*); + upb_Map* map = *map_p; + upb_MapEntry ent; + UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message); + const upb_MiniTable* entry = upb_MiniTable_GetSubMessageTable(field); + + UPB_ASSERT(entry); + UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0])); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1])); + + if (!map) { + map = _upb_Decoder_CreateMap(d, entry); + *map_p = map; + } + + // Parse map entry. + memset(&ent, 0, sizeof(ent)); + + bool value_is_message = + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Message || + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group; + const upb_MiniTable* sub_table = + value_is_message + ? upb_MiniTable_GetSubMessageTable(&entry->UPB_PRIVATE(fields)[1]) + : NULL; + upb_Message* sub_msg = NULL; + + if (sub_table) { + // Create proactively to handle the case where it doesn't appear. + _upb_Decoder_NewSubMessage(d, &entry->UPB_PRIVATE(fields)[1], &sub_msg); + ent.v.val = upb_value_ptr(sub_msg); + } + + ptr = _upb_Decoder_DecodeSubMessage(d, ptr, &ent.message, field, val->size); + + if (sub_msg && sub_table->UPB_PRIVATE(required_count)) { + // If the map entry did not contain a value on the wire, `sub_msg` is an + // empty message; we must check if it is missing any required fields. If the + // value was present, this check is redundant but harmless. + _upb_Decoder_CheckRequired(d, ptr, sub_msg, sub_table); + } + + if (upb_Message_HasUnknown(&ent.message)) { + _upb_Decoder_AddMapEntryUnknown(d, msg, field, &ent.message, entry); + } else { + if (_upb_Map_Insert(map, &ent.k, map->key_size, &ent.v, map->val_size, + &d->arena) == kUpb_MapInsertStatus_OutOfMemory) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + } + return ptr; +} + +static const char* _upb_Decoder_DecodeToSubMessage( + upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTableField* field, wireval* val, int op) { + void* mem = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void); + int type = field->UPB_PRIVATE(descriptortype); + + // Set presence if necessary. + if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(field)) { + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, field); + } else if (upb_MiniTableField_IsInOneof(field)) { + // Oneof case + uint32_t* oneof_case = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, field); + if (op == kUpb_DecodeOp_SubMessage && + *oneof_case != field->UPB_PRIVATE(number)) { + memset(mem, 0, sizeof(void*)); + } + *oneof_case = field->UPB_PRIVATE(number); + } + + // Store into message. + switch (op) { + case kUpb_DecodeOp_SubMessage: { + upb_Message** submsgp = mem; + upb_Message* submsg = *submsgp; + if (!submsg) submsg = _upb_Decoder_NewSubMessage(d, field, submsgp); + if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) { + ptr = _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, field); + } else { + ptr = _upb_Decoder_DecodeSubMessage(d, ptr, submsg, field, val->size); + } + break; + } + case kUpb_DecodeOp_String: + return _upb_Decoder_ReadString2(d, ptr, val->size, mem, + /*validate_utf8=*/true); + case kUpb_DecodeOp_Bytes: + return _upb_Decoder_ReadString2(d, ptr, val->size, mem, + /*validate_utf8=*/false); + case kUpb_DecodeOp_Scalar8Byte: + memcpy(mem, val, 8); + break; + case kUpb_DecodeOp_Scalar4Byte: + memcpy(mem, val, 4); + break; + case kUpb_DecodeOp_Scalar1Byte: + memcpy(mem, val, 1); + break; + default: + UPB_UNREACHABLE(); + } + + return ptr; +} + +enum { + kStartItemTag = ((kUpb_MsgSet_Item << 3) | kUpb_WireType_StartGroup), + kEndItemTag = ((kUpb_MsgSet_Item << 3) | kUpb_WireType_EndGroup), + kTypeIdTag = ((kUpb_MsgSet_TypeId << 3) | kUpb_WireType_Varint), + kMessageTag = ((kUpb_MsgSet_Message << 3) | kUpb_WireType_Delimited), +}; + +static void upb_Decoder_AddKnownMessageSetItem( + upb_Decoder* d, upb_Message* msg, const upb_MiniTableExtension* item_mt, + const char* data, uint32_t size) { + upb_Extension* ext = + UPB_PRIVATE(_upb_Message_GetOrCreateExtension)(msg, item_mt, &d->arena); + if (UPB_UNLIKELY(!ext)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + upb_Message** submsgp = (upb_Message**)&ext->data.msg_val; + upb_Message* submsg = _upb_Decoder_NewSubMessage2( + d, ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg), + &ext->ext->UPB_PRIVATE(field), submsgp); + // upb_Decode_LimitDepth() takes uint32_t, d->depth - 1 can not be negative. + if (d->depth <= 1) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_MaxDepthExceeded); + } + upb_DecodeStatus status = upb_Decode( + data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt), + d->extreg, upb_Decode_LimitDepth(d->options, d->depth - 1), &d->arena); + if (status != kUpb_DecodeStatus_Ok) { + upb_ErrorHandler_ThrowError(&d->err, status); + } +} + +static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d, + upb_Message* msg, + uint32_t type_id, + const char* message_data, + uint32_t message_size) { + char buf[6 * kUpb_Decoder_EncodeVarint32MaxSize]; + char* ptr = buf; + ptr = upb_Decoder_EncodeVarint32(kStartItemTag, ptr); + ptr = upb_Decoder_EncodeVarint32(kTypeIdTag, ptr); + ptr = upb_Decoder_EncodeVarint32(type_id, ptr); + ptr = upb_Decoder_EncodeVarint32(kMessageTag, ptr); + ptr = upb_Decoder_EncodeVarint32(message_size, ptr); + char* split = ptr; + + ptr = upb_Decoder_EncodeVarint32(kEndItemTag, ptr); + char* end = ptr; + upb_StringView unknown[] = { + {buf, split - buf}, + {message_data, message_size}, + {split, end - split}, + }; + if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 3)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } +} + +static void upb_Decoder_AddMessageSetItem(upb_Decoder* d, upb_Message* msg, + const upb_MiniTable* t, + uint32_t type_id, const char* data, + uint32_t size) { + const upb_MiniTableExtension* item_mt = + upb_ExtensionRegistry_Lookup(d->extreg, t, type_id); + if (item_mt) { + upb_Decoder_AddKnownMessageSetItem(d, msg, item_mt, data, size); + } else { + upb_Decoder_AddUnknownMessageSetItem(d, msg, type_id, data, size); + } +} + +static const char* upb_Decoder_DecodeMessageSetItem( + upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable* layout) { + uint32_t type_id = 0; + upb_StringView preserved = {NULL, 0}; + typedef enum { + kUpb_HaveId = 1 << 0, + kUpb_HavePayload = 1 << 1, + } StateMask; + StateMask state_mask = 0; + while (!upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + uint32_t tag; + ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d)); + switch (tag) { + case kEndItemTag: + return ptr; + case kTypeIdTag: { + uint64_t tmp; + ptr = upb_WireReader_ReadVarint(ptr, &tmp, EPS(d)); + if (state_mask & kUpb_HaveId) break; // Ignore dup. + state_mask |= kUpb_HaveId; + type_id = tmp; + if (state_mask & kUpb_HavePayload) { + upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, preserved.data, + preserved.size); + } + break; + } + case kMessageTag: { + uint32_t size; + upb_StringView sv; + ptr = upb_Decoder_DecodeSize(d, ptr, &size); + ptr = upb_EpsCopyInputStream_ReadStringAlwaysAlias(&d->input, ptr, size, + &sv); + if (!ptr) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + if (state_mask & kUpb_HavePayload) break; // Ignore dup. + state_mask |= kUpb_HavePayload; + if (state_mask & kUpb_HaveId) { + upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, sv.data, + sv.size); + } else { + // Out of order, we must preserve the payload. + preserved = sv; + } + break; + } + default: + // We do not preserve unexpected fields inside a message set item. + ptr = _upb_WireReader_SkipValue(ptr, tag, d->depth, &d->input); + break; + } + } + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); +} + +static upb_MiniTableField upb_Decoder_FieldNotFoundField = { + 0, 0, 0, 0, kUpb_FakeFieldType_FieldNotFound, 0}; + +UPB_NOINLINE const upb_MiniTableField* _upb_Decoder_FindExtensionField( + upb_Decoder* d, const upb_MiniTable* t, uint32_t field_number, int ext_mode, + uint32_t wire_type) { + // Treat a message set as an extendable message if it is a delimited field. + // This provides compatibility with encoders that are unaware of message + // sets and serialize them as normal extensions. + if (ext_mode == kUpb_ExtMode_Extendable || + (ext_mode == kUpb_ExtMode_IsMessageSet && + wire_type == kUpb_WireType_Delimited)) { + const upb_MiniTableExtension* ext = + upb_ExtensionRegistry_Lookup(d->extreg, t, field_number); + if (ext) return &ext->UPB_PRIVATE(field); + } else if (ext_mode == kUpb_ExtMode_IsMessageSet) { + if (field_number == kUpb_MsgSet_Item) { + static upb_MiniTableField item = { + 0, 0, 0, 0, kUpb_FakeFieldType_MessageSetItem, 0}; + return &item; + } + } + return &upb_Decoder_FieldNotFoundField; +} + +static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, + const upb_MiniTable* t, + uint32_t field_number, + uint32_t wire_type) { + UPB_ASSERT(t); + const upb_MiniTableField* field = + upb_MiniTable_FindFieldByNumber(t, field_number); + if (field) return field; + + if (d->extreg && t->UPB_PRIVATE(ext)) { + return _upb_Decoder_FindExtensionField(d, t, field_number, + t->UPB_PRIVATE(ext), wire_type); + } + + return &upb_Decoder_FieldNotFoundField; // Unknown field. +} + +static int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { + static const int8_t kVarintOps[] = { + [kUpb_FakeFieldType_FieldNotFound] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Double] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Float] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Int64] = kUpb_DecodeOp_Scalar8Byte, + [kUpb_FieldType_UInt64] = kUpb_DecodeOp_Scalar8Byte, + [kUpb_FieldType_Int32] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_Fixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Fixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Bool] = kUpb_DecodeOp_Scalar1Byte, + [kUpb_FieldType_String] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Group] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Message] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Bytes] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_UInt32] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_Enum] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_SFixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SFixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SInt32] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_SInt64] = kUpb_DecodeOp_Scalar8Byte, + [kUpb_FakeFieldType_MessageSetItem] = kUpb_DecodeOp_UnknownField, + }; + + return kVarintOps[field->UPB_PRIVATE(descriptortype)]; +} + +UPB_FORCEINLINE +void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, + const upb_MiniTableField* field, int* op) { + // If sub-message is not linked, treat as unknown. + if (field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension) return; + const upb_MiniTable* mt_sub = upb_MiniTable_GetSubMessageTable(field); + if (mt_sub != NULL) return; // Normal case, sub-message is linked. +#ifndef NDEBUG + const upb_MiniTableField* oneof = upb_MiniTable_GetOneof(mt, field); + if (oneof) { + // All other members of the oneof must be message fields that are also + // unlinked. + do { + UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message); + const upb_MiniTable* oneof_sub = upb_MiniTable_GetSubMessageTable(oneof); + UPB_ASSERT(!oneof_sub); + } while (upb_MiniTable_NextOneofField(mt, &oneof)); + } +#endif // NDEBUG + *op = kUpb_DecodeOp_UnknownField; +} + +UPB_FORCEINLINE +void _upb_Decoder_MaybeVerifyUtf8(upb_Decoder* d, + const upb_MiniTableField* field, int* op) { + UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes); + if (_upb_Decoder_FieldRequiresUtf8Validation(d, field)) { + *op = kUpb_DecodeOp_String; + } +} + +static int _upb_Decoder_GetDelimitedOp(upb_Decoder* d, const upb_MiniTable* mt, + const upb_MiniTableField* field) { + enum { kRepeatedBase = 19 }; + + static const int8_t kDelimitedOps[] = { + // For non-repeated field type. + [kUpb_FakeFieldType_FieldNotFound] = + kUpb_DecodeOp_UnknownField, // Field not found. + [kUpb_FieldType_Double] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Float] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Int64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_UInt64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Int32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Fixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Fixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Bool] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_String] = kUpb_DecodeOp_String, + [kUpb_FieldType_Group] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Message] = kUpb_DecodeOp_SubMessage, + [kUpb_FieldType_Bytes] = kUpb_DecodeOp_Bytes, + [kUpb_FieldType_UInt32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Enum] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SFixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SFixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SInt32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SInt64] = kUpb_DecodeOp_UnknownField, + [kUpb_FakeFieldType_MessageSetItem] = kUpb_DecodeOp_SubMessage, + // For repeated field type. + [kRepeatedBase + kUpb_FieldType_Double] = OP_FIXPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_Float] = OP_FIXPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Int64] = OP_VARPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_UInt64] = OP_VARPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_Int32] = OP_VARPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Fixed64] = OP_FIXPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_Fixed32] = OP_FIXPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Bool] = OP_VARPCK_LG2(0), + [kRepeatedBase + kUpb_FieldType_String] = kUpb_DecodeOp_String, + [kRepeatedBase + kUpb_FieldType_Group] = kUpb_DecodeOp_SubMessage, + [kRepeatedBase + kUpb_FieldType_Message] = kUpb_DecodeOp_SubMessage, + [kRepeatedBase + kUpb_FieldType_Bytes] = kUpb_DecodeOp_Bytes, + [kRepeatedBase + kUpb_FieldType_UInt32] = OP_VARPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Enum] = kUpb_DecodeOp_PackedEnum, + [kRepeatedBase + kUpb_FieldType_SFixed32] = OP_FIXPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_SFixed64] = OP_FIXPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_SInt32] = OP_VARPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_SInt64] = OP_VARPCK_LG2(3), + // Omitting kUpb_FakeFieldType_MessageSetItem, because we never emit a + // repeated msgset type + }; + + int ndx = field->UPB_PRIVATE(descriptortype); + if (upb_MiniTableField_IsArray(field)) ndx += kRepeatedBase; + int op = kDelimitedOps[ndx]; + + if (op == kUpb_DecodeOp_SubMessage) { + _upb_Decoder_CheckUnlinked(d, mt, field, &op); + } else if (op == kUpb_DecodeOp_Bytes) { + _upb_Decoder_MaybeVerifyUtf8(d, field, &op); + } + + return op; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr, + const upb_MiniTable* mt, + const upb_MiniTableField* field, + uint32_t wire_type, wireval* val, + int* op) { + static const unsigned kFixed32OkMask = (1 << kUpb_FieldType_Float) | + (1 << kUpb_FieldType_Fixed32) | + (1 << kUpb_FieldType_SFixed32); + + static const unsigned kFixed64OkMask = (1 << kUpb_FieldType_Double) | + (1 << kUpb_FieldType_Fixed64) | + (1 << kUpb_FieldType_SFixed64); + + switch (wire_type) { + case kUpb_WireType_Varint: + ptr = upb_WireReader_ReadVarint(ptr, &val->uint64_val, EPS(d)); + if (upb_MiniTableField_IsClosedEnum(field)) { + const upb_MiniTableEnum* e = upb_MiniTable_GetSubEnumTable(field); + if (!upb_MiniTableEnum_CheckValue(e, val->uint64_val)) { + *op = kUpb_DecodeOp_UnknownField; + return ptr; + } + _upb_Decoder_MungeInt32(val); + } else { + _upb_Decoder_Munge(field, val); + } + *op = _upb_Decoder_GetVarintOp(field); + return ptr; + case kUpb_WireType_32Bit: + *op = kUpb_DecodeOp_Scalar4Byte; + if (((1 << field->UPB_PRIVATE(descriptortype)) & kFixed32OkMask) == 0) { + *op = kUpb_DecodeOp_UnknownField; + } + return upb_WireReader_ReadFixed32(ptr, &val->uint32_val, &d->input); + case kUpb_WireType_64Bit: + *op = kUpb_DecodeOp_Scalar8Byte; + if (((1 << field->UPB_PRIVATE(descriptortype)) & kFixed64OkMask) == 0) { + *op = kUpb_DecodeOp_UnknownField; + } + return upb_WireReader_ReadFixed64(ptr, &val->uint64_val, &d->input); + case kUpb_WireType_Delimited: + ptr = upb_Decoder_DecodeSize(d, ptr, &val->size); + *op = _upb_Decoder_GetDelimitedOp(d, mt, field); + return ptr; + case kUpb_WireType_StartGroup: + val->uint32_val = field->UPB_PRIVATE(number); + if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { + *op = kUpb_DecodeOp_SubMessage; + _upb_Decoder_CheckUnlinked(d, mt, field, op); + } else if (field->UPB_PRIVATE(descriptortype) == + kUpb_FakeFieldType_MessageSetItem) { + *op = kUpb_DecodeOp_MessageSetItem; + } else { + *op = kUpb_DecodeOp_UnknownField; + } + return ptr; + default: + break; + } + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTableField* field, + int op, wireval* val) { + uint8_t mode = field->UPB_PRIVATE(mode); + + if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) { + const upb_MiniTableExtension* ext_layout = + (const upb_MiniTableExtension*)field; + upb_Extension* ext = UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + msg, ext_layout, &d->arena); + if (UPB_UNLIKELY(!ext)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + d->original_msg = msg; + msg = &ext->data.UPB_PRIVATE(ext_msg_val); + } + + switch (mode & kUpb_FieldMode_Mask) { + case kUpb_FieldMode_Array: + return _upb_Decoder_DecodeToArray(d, ptr, msg, field, val, op); + case kUpb_FieldMode_Map: + return _upb_Decoder_DecodeToMap(d, ptr, msg, field, val); + case kUpb_FieldMode_Scalar: + return _upb_Decoder_DecodeToSubMessage(d, ptr, msg, field, val, op); + default: + UPB_UNREACHABLE(); + } +} + +static const char* _upb_Decoder_DecodeUnknownField( + upb_Decoder* d, const char* ptr, upb_Message* msg, uint32_t field_number, + uint32_t wire_type, wireval val, const char* start) { + if (field_number == 0) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + + upb_EpsCopyInputStream_StartCapture(&d->input, start); + + if (wire_type == kUpb_WireType_Delimited) { + upb_StringView sv; + ptr = upb_EpsCopyInputStream_ReadStringEphemeral(&d->input, ptr, val.size, + &sv); + if (!ptr) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } else if (wire_type == kUpb_WireType_StartGroup) { + ptr = UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, field_number << 3, + d->depth, &d->input); + } + + upb_StringView sv; + upb_EpsCopyInputStream_EndCapture(&d->input, ptr, &sv); + + upb_AddUnknownMode mode = kUpb_AddUnknown_Copy; + if (d->options & kUpb_DecodeOption_AliasString) { + if (sv.data != d->input.buffer_start) { + // If the data is not from the beginning of the input buffer, then we can + // safely attempt to coalesce this region with the previous one. + mode = kUpb_AddUnknown_AliasAllowMerge; + } else { + mode = kUpb_AddUnknown_Alias; + } + } + + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, sv.data, sv.size, &d->arena, + mode)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFieldTag(upb_Decoder* d, const char* ptr, + uint32_t* field_number, + uint32_t* wire_type) { + uint32_t tag; + UPB_ASSERT(ptr < d->input.limit_ptr); + ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d)); + *field_number = tag >> 3; + *wire_type = tag & 7; + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFieldData( + upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* mt, + uint32_t field_number, uint32_t wire_type, const char* start) { + int op; + wireval val; + + const upb_MiniTableField* field = + _upb_Decoder_FindField(d, mt, field_number, wire_type); + ptr = _upb_Decoder_DecodeWireValue(d, ptr, mt, field, wire_type, &val, &op); + + if (op >= 0) { + return _upb_Decoder_DecodeKnownField(d, ptr, msg, field, op, &val); + } else { + switch (op) { + case kUpb_DecodeOp_UnknownField: + return _upb_Decoder_DecodeUnknownField(d, ptr, msg, field_number, + wire_type, val, start); + case kUpb_DecodeOp_MessageSetItem: + return upb_Decoder_DecodeMessageSetItem(d, ptr, msg, mt); + default: + UPB_UNREACHABLE(); + } + } +} + +static const char* _upb_Decoder_EndMessage(upb_Decoder* d, const char* ptr) { + d->message_is_done = true; + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFieldNoFast(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* mt) { + uint32_t field_number; + uint32_t wire_type; + + const char* start = ptr; + ptr = _upb_Decoder_DecodeFieldTag(d, ptr, &field_number, &wire_type); + + if (wire_type == kUpb_WireType_EndGroup) { + d->end_group = field_number; + return _upb_Decoder_EndMessage(d, ptr); + } + + ptr = _upb_Decoder_DecodeFieldData(d, ptr, msg, mt, field_number, wire_type, + start); + _upb_Decoder_Trace(d, 'M'); + return ptr; +} + +UPB_FORCEINLINE +bool _upb_Decoder_TryDecodeMessageFast(upb_Decoder* d, const char** ptr, + upb_Message* msg, + const upb_MiniTable* mt, + uint64_t last_field_index, + uint64_t data) { +#ifdef UPB_ENABLE_FASTTABLE + if (mt->UPB_PRIVATE(table_mask) == (unsigned char)-1 || + (d->options & kUpb_DecodeOption_DisableFastTable)) { + // Fast table is unavailable or disabled. + return false; + } + + intptr_t table = decode_totable(mt); + const char* start = *ptr; + char* trace_next = _upb_Decoder_TraceNext(d); + + *ptr = upb_DecodeFast_Dispatch(d, *ptr, msg, table, 0, 0); + + if (d->message_is_done) { + // The entire message was successfully parsed fast. + return true; + } + + // *ptr now points to the beginning of a field that could not be parsed fast. + // It's possible that some fields were parsed fast, in which case *ptr will + // have been updated. However, it's also possible that the very first field + // encountered could not be parsed fast, in which case *ptr will be unchanged. + // + // If the fast decoder consumed any data, it must have emitted at least + // one 'F' event into the trace buffer (in addition to the 'D' event + // that is always emitted). + UPB_ASSERT(_upb_Decoder_TracePtr(d) != trace_next || *ptr == start); + _upb_Decoder_Trace(d, '<'); +#endif + return false; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeField(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable* mt, + uint64_t last_field_index, uint64_t data) { + if (_upb_Decoder_TryDecodeMessageFast(d, &ptr, msg, mt, last_field_index, + data)) { + return ptr; + } else if (upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + return _upb_Decoder_EndMessage(d, ptr); + } + + return _upb_Decoder_DecodeFieldNoFast(d, ptr, msg, mt); +} + +UPB_NOINLINE +const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* mt) { + UPB_ASSERT(mt); + UPB_ASSERT(d->message_is_done == false); + + do { + ptr = _upb_Decoder_DecodeField(d, ptr, msg, mt, 0, 0); + } while (!d->message_is_done); + d->message_is_done = false; + + return UPB_UNLIKELY(mt && mt->UPB_PRIVATE(required_count)) + ? _upb_Decoder_CheckRequired(d, ptr, msg, mt) + : ptr; +} + +static upb_DecodeStatus _upb_Decoder_DecodeTop(struct upb_Decoder* d, + const char* buf, + upb_Message* msg, + const upb_MiniTable* m) { + _upb_Decoder_DecodeMessage(d, buf, msg, m); + if (d->end_group != DECODE_NOGROUP) return kUpb_DecodeStatus_Malformed; + if (d->missing_required) return kUpb_DecodeStatus_MissingRequired; + return kUpb_DecodeStatus_Ok; +} + +static upb_DecodeStatus upb_Decoder_Decode(upb_Decoder* const decoder, + const char* const buf, + upb_Message* const msg, + const upb_MiniTable* const m, + upb_Arena* const arena) { + if (UPB_SETJMP(decoder->err.buf) == 0) { + decoder->err.code = _upb_Decoder_DecodeTop(decoder, buf, msg, m); + } else { + UPB_ASSERT(decoder->err.code != kUpb_DecodeStatus_Ok); + } + + return upb_Decoder_Destroy(decoder, arena); +} + +static uint16_t upb_DecodeOptions_GetMaxDepth(uint32_t options) { + return options >> 16; +} + +uint16_t upb_DecodeOptions_GetEffectiveMaxDepth(uint32_t options) { + uint16_t max_depth = upb_DecodeOptions_GetMaxDepth(options); + return max_depth ? max_depth : kUpb_WireFormat_DefaultDepthLimit; +} + +upb_DecodeStatus upb_Decode(const char* buf, size_t size, upb_Message* msg, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Decoder decoder; + buf = upb_Decoder_Init(&decoder, buf, size, extreg, options, arena, NULL, 0); + + return upb_Decoder_Decode(&decoder, buf, msg, mt, arena); +} + +upb_DecodeStatus upb_DecodeWithTrace(const char* buf, size_t size, + upb_Message* msg, const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena, + char* trace_buf, size_t trace_size) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Decoder decoder; + buf = upb_Decoder_Init(&decoder, buf, size, extreg, options, arena, trace_buf, + trace_size); + + return upb_Decoder_Decode(&decoder, buf, msg, mt, arena); +} + +upb_DecodeStatus upb_DecodeLengthPrefixed(const char* buf, size_t size, + upb_Message* msg, + size_t* num_bytes_read, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + // To avoid needing to make a Decoder just to decode the initial length, + // hand-decode the leading varint for the message length here. + uint64_t msg_len = 0; + for (size_t i = 0;; ++i) { + if (i >= size || i > 9) { + return kUpb_DecodeStatus_Malformed; + } + uint64_t b = *buf; + buf++; + msg_len += (b & 0x7f) << (i * 7); + if ((b & 0x80) == 0) { + *num_bytes_read = i + 1 + msg_len; + break; + } + } + + // If the total number of bytes we would read (= the bytes from the varint + // plus however many bytes that varint says we should read) is larger then the + // input buffer then error as malformed. + if (*num_bytes_read > size) { + return kUpb_DecodeStatus_Malformed; + } + if (msg_len > INT32_MAX) { + return kUpb_DecodeStatus_Malformed; + } + + return upb_Decode(buf, msg_len, msg, mt, extreg, options, arena); +} + +const char* upb_DecodeStatus_String(upb_DecodeStatus status) { + switch (status) { + case kUpb_DecodeStatus_Ok: + return "Ok"; + case kUpb_DecodeStatus_Malformed: + return "Wire format was corrupt"; + case kUpb_DecodeStatus_OutOfMemory: + return "Arena alloc failed"; + case kUpb_DecodeStatus_BadUtf8: + return "String field had bad UTF-8"; + case kUpb_DecodeStatus_MaxDepthExceeded: + return "Exceeded upb_DecodeOptions_MaxDepth"; + case kUpb_DecodeStatus_MissingRequired: + return "Missing required field"; + default: + return "Unknown decode status"; + } +} + +#undef OP_FIXPCK_LG2 +#undef OP_VARPCK_LG2 + +// We encode backwards, to avoid pre-computing lengths (one-pass encode). + + +#include +#include +#include +#include +#include + + +// Must be last. + +static uint32_t encode_zz32(int32_t n) { + return ((uint32_t)n << 1) ^ (n >> 31); +} +static uint64_t encode_zz64(int64_t n) { + return ((uint64_t)n << 1) ^ (n >> 63); +} + +typedef struct { + upb_EncodeStatus status; + jmp_buf err; + upb_Arena* arena; + // These should only be used for arithmetic and reallocation to allow full + // aliasing analysis on the ptr argument. + const char UPB_NODEREF *buf, *limit; + int options; + int depth; + _upb_mapsorter sorter; +} upb_encstate; + +UPB_NORETURN static void encode_err(upb_encstate* e, upb_EncodeStatus s) { + UPB_ASSERT(s != kUpb_EncodeStatus_Ok); + e->status = s; + UPB_LONGJMP(e->err, 1); +} + +// Subtraction is used for bounds checks, and the C standard says that pointer +// subtraction is UB if the pointers aren't part of the same array or one past +// the end, so we must avoid NULL - NULL. C++ defines it though. +static char initial_buf_sentinel; + +UPB_NOINLINE static char* encode_growbuffer(char* ptr, upb_encstate* e, + size_t bytes) { + size_t old_size = e->limit - e->buf; + size_t needed_size = bytes + (e->limit - ptr); + if (needed_size < bytes) encode_err(e, kUpb_EncodeStatus_OutOfMemory); + size_t new_size = upb_RoundUpToPowerOfTwo(UPB_MAX(128, needed_size)); + if (new_size == old_size) encode_err(e, kUpb_EncodeStatus_OutOfMemory); + void* old_buf = e->buf == &initial_buf_sentinel ? NULL : (void*)e->buf; + char* new_buf = upb_Arena_Realloc(e->arena, old_buf, old_size, new_size); + + if (!new_buf) encode_err(e, kUpb_EncodeStatus_OutOfMemory); + + // We want previous data at the end, realloc() put it at the beginning. + // TODO: This is somewhat inefficient since we are copying twice. + // Maybe create a realloc() that copies to the end of the new buffer? + if (old_size > 0) { + memmove(new_buf + new_size - old_size, new_buf, old_size); + } + + e->buf = new_buf; + e->limit = new_buf + new_size; + return new_buf + new_size - needed_size; +} + +/* Call to ensure that at least `bytes` bytes are available for writing at + * ptr. */ +UPB_FORCEINLINE +char* encode_reserve(char* ptr, upb_encstate* e, size_t bytes) { + if ((size_t)(ptr - e->buf) < bytes) { + return encode_growbuffer(ptr, e, bytes); + } + + return ptr - bytes; +} + +static char* encode_bytes_unchecked(char* ptr, upb_encstate* e, + const void* data, size_t len) { + if (len == 0) return ptr; /* memcpy() with zero size is UB */ + ptr -= len; + memcpy(ptr, data, len); + return ptr; +} + +/* Writes the given bytes to the buffer, handling reserve/advance. */ +static char* encode_bytes(char* ptr, upb_encstate* e, const void* data, + size_t len) { + if (len == 0) return ptr; /* memcpy() with zero size is UB */ + ptr = encode_reserve(ptr, e, len); + memcpy(ptr, data, len); + return ptr; +} + +static char* encode_fixed64_unchecked(char* ptr, upb_encstate* e, + uint64_t val) { + val = upb_BigEndian64(val); + return encode_bytes_unchecked(ptr, e, &val, sizeof(uint64_t)); +} + +static char* encode_fixed32_unchecked(char* ptr, upb_encstate* e, + uint32_t val) { + val = upb_BigEndian32(val); + return encode_bytes_unchecked(ptr, e, &val, sizeof(uint32_t)); +} + +#define UPB_PB_VARINT_MAX_LEN 10 +#define UPB_PB_VARINT32_MAX_LEN 5 + +#if UPB_ARM64_ASM +// Each arm64 instruction encodes to 4 bytes, and it takes two intructions +// to process each byte of output, so we branch ahead by (4 + 4) * skip to +// avoid the remaining bytes. When BTI is on, we need to use specific +// "landing pad" instructions, so we pad those with nop to make it a power +// of 2, skipping 16 bytes at each stage instead of 8. This carries some +// overhead especially on in-order cores so they're not included unless +// building with branch protection. +#if UPB_ARM64_BTI_DEFAULT +// BTI is used with jc targets here because we don't control which register will +// be used for addr; if it's x16 or x17 a `br` is treated like a call. +#define UPB_BTI_JC "bti jc\n" +#define UPB_BTI_NOP "nop\n" +#define UPB_BTI_SHIFT_IMM "4\n" +#else +#define UPB_BTI_JC +#define UPB_BTI_NOP +#define UPB_BTI_SHIFT_IMM "3\n" +#endif +UPB_NOINLINE static char* encode_longvarint(char* ptr, upb_encstate* e, + uint64_t val) { + ptr = encode_reserve(ptr, e, UPB_PB_VARINT_MAX_LEN); + uint64_t clz; + __asm__("clz %[cnt], %[val]\n" : [cnt] "=r"(clz) : [val] "r"(val)); + + uint32_t skip = + UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(clz); + + ptr += skip; + uint64_t addr, mask; + __asm__ volatile( + // Formatter keeps merging short lines + // clang-format off + "adr %[addr], 0f\n" + "add %[addr], %[addr], %[cnt], lsl #" UPB_BTI_SHIFT_IMM + "mov %w[mask], #0x80\n" + "br %[addr]\n" + // Work around llvm/llvm-project#47432, where alignment directives inside + // functions crash the compiler when generating SEH info on windows. + #ifndef __SEH__ + ".p2align " UPB_BTI_SHIFT_IMM + #endif + "0:\n" + // We don't need addr any more, but we've got the register for our whole + // assembly block so we'll use it as scratch to store the shift+masked + // values before storing them. + // The following stores are unsigned offset stores: + // strb Wt, [Xn, #imm] + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #56\n" + "strb %w[addr], [%[ptr], #8]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #49\n" + "strb %w[addr], [%[ptr], #7]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #42\n" + "strb %w[addr], [%[ptr], #6]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #35\n" + "strb %w[addr], [%[ptr], #5]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #28\n" + "strb %w[addr], [%[ptr], #4]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[mask], %w[val], lsr #21\n" + "strb %w[addr], [%[ptr], #3]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[mask], %w[val], lsr #14\n" + "strb %w[addr], [%[ptr], #2]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[mask], %w[val], lsr #7\n" + "strb %w[addr], [%[ptr], #1]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[val], #0x80\n" + "strb %w[addr], [%[ptr]]\n" + UPB_BTI_NOP + + UPB_BTI_JC + // clang-format on + : [addr] "=&r"(addr), [mask] "=&r"(mask) + : [val] "r"(val), [ptr] "r"(ptr), [cnt] "r"((uint64_t)skip) + : "memory"); + uint32_t continuations = UPB_PB_VARINT_MAX_LEN - 1 - skip; + // msan can't instrument stores in inline assembly + UPB_PRIVATE(upb_Xsan_MarkInitialized)(ptr, continuations); + // Encode the final byte after the continuation bytes. + ptr[continuations] = val >> (7 * continuations); + return ptr; +} +#undef UPB_BTI_JC +#undef UPB_BTI_NOP +#undef UPB_BTI_SHIFT_IMM +#else +UPB_NOINLINE +static char* encode_longvarint(char* ptr, upb_encstate* e, uint64_t val) { + ptr = encode_reserve(ptr, e, UPB_PB_VARINT_MAX_LEN); + size_t len = 0; + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + ptr[len++] = byte; + } while (val); + char* start = ptr + UPB_PB_VARINT_MAX_LEN - len; + memmove(start, ptr, len); + return start; +} +#endif + +UPB_FORCEINLINE +char* encode_varint_unchecked(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longvarint(ptr, e, val); + } +} +UPB_FORCEINLINE +char* encode_varint(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128 && ptr != e->buf) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longvarint(ptr, e, val); + } +} + +UPB_NOINLINE +char* encode_longlength(char* ptr, upb_encstate* e, uint64_t val) { + if (val > INT32_MAX) { + encode_err(e, kUpb_EncodeStatus_MaxSizeExceeded); + } + return encode_longvarint(ptr, e, val); +} + +UPB_FORCEINLINE +char* encode_length(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128 && ptr != e->buf) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longlength(ptr, e, val); + } +} + +UPB_FORCEINLINE +char* encode_length_unchecked(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longlength(ptr, e, val); + } +} + +static char* encode_double_unchecked(char* ptr, upb_encstate* e, double d) { + uint64_t u64; + UPB_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "bad double size"); + memcpy(&u64, &d, sizeof(uint64_t)); + return encode_fixed64_unchecked(ptr, e, u64); +} + +static char* encode_float_unchecked(char* ptr, upb_encstate* e, float d) { + uint32_t u32; + UPB_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "bad float size"); + memcpy(&u32, &d, sizeof(uint32_t)); + return encode_fixed32_unchecked(ptr, e, u32); +} + +static char* encode_tag_unchecked(char* ptr, upb_encstate* e, + uint32_t field_number, uint8_t wire_type) { + return encode_varint_unchecked(ptr, e, (field_number << 3) | wire_type); +} + +static char* encode_tag(char* ptr, upb_encstate* e, uint32_t field_number, + uint8_t wire_type) { + return encode_varint(ptr, e, (field_number << 3) | wire_type); +} + +static char* encode_fixedarray(char* ptr, upb_encstate* e, const upb_Array* arr, + size_t elem_size, uint32_t tag) { + size_t bytes = upb_Array_Size(arr) * elem_size; + const char* data = upb_Array_DataPtr(arr); + const char* arr_ptr = data + bytes - elem_size; + + if (tag || !upb_IsLittleEndian()) { + while (true) { + if (elem_size == 4) { + uint32_t val; + memcpy(&val, arr_ptr, sizeof(val)); + val = upb_BigEndian32(val); + ptr = encode_bytes(ptr, e, &val, elem_size); + } else { + UPB_ASSERT(elem_size == 8); + uint64_t val; + memcpy(&val, arr_ptr, sizeof(val)); + val = upb_BigEndian64(val); + ptr = encode_bytes(ptr, e, &val, elem_size); + } + + if (tag) { + ptr = encode_varint(ptr, e, tag); + } + if (arr_ptr == data) break; + arr_ptr -= elem_size; + } + return ptr; + } else { + return encode_bytes(ptr, e, data, bytes); + } +} + +static char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size); + +static char* encode_scalar(char* ptr, upb_encstate* e, const void* field_mem, + const upb_MiniTableField* f) { + // Max size is tag + 10 bytes for max varint or 8 for largest fixed size +#define CASE(ctype, type, wtype, encodeval) \ + { \ + const size_t bytes = UPB_PB_VARINT32_MAX_LEN + UPB_PB_VARINT_MAX_LEN; \ + ptr = encode_reserve(ptr, e, bytes); \ + ptr += bytes; \ + const ctype val = *(const ctype*)field_mem; \ + ptr = encode_##type##_unchecked(ptr, e, encodeval); \ + return encode_tag_unchecked(ptr, e, upb_MiniTableField_Number(f), wtype); \ + } + + switch (f->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Double: + CASE(double, double, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Float: + CASE(float, float, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: + CASE(uint64_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_UInt32: + CASE(uint32_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: + CASE(int32_t, varint, kUpb_WireType_Varint, (int64_t)val); + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + CASE(uint64_t, fixed64, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + CASE(uint32_t, fixed32, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Bool: + CASE(bool, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_SInt32: + CASE(int32_t, varint, kUpb_WireType_Varint, encode_zz32(val)); + case kUpb_FieldType_SInt64: + CASE(int64_t, varint, kUpb_WireType_Varint, encode_zz64(val)); + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + upb_StringView view = *(upb_StringView*)field_mem; + const size_t max_size = + UPB_PB_VARINT32_MAX_LEN + UPB_PB_VARINT32_MAX_LEN + view.size; + ptr = encode_reserve(ptr, e, max_size); + ptr += max_size; + ptr = encode_bytes_unchecked(ptr, e, view.data, view.size); + ptr = encode_length_unchecked(ptr, e, view.size); + return encode_tag_unchecked(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } + case kUpb_FieldType_Group: { + size_t size; + upb_Message* submsg = *(upb_Message**)field_mem; + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (submsg == 0) { + return ptr; + } + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_EndGroup); + ptr = encode_message(ptr, e, submsg, subm, &size); + e->depth++; + return encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_StartGroup); + } + case kUpb_FieldType_Message: { + size_t size; + upb_Message* submsg = *(upb_Message**)field_mem; + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (submsg == 0) { + return ptr; + } + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + ptr = encode_message(ptr, e, submsg, subm, &size); + e->depth++; + size_t max_size = UPB_PB_VARINT32_MAX_LEN + UPB_PB_VARINT32_MAX_LEN; + ptr = encode_reserve(ptr, e, max_size); + ptr += max_size; + ptr = encode_length_unchecked(ptr, e, size); + return encode_tag_unchecked(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } + default: + UPB_UNREACHABLE(); + } +#undef CASE +} + +static char* encode_array(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTableField* f) { + const upb_Array* arr = *UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), upb_Array*); + bool packed = upb_MiniTableField_IsPacked(f); + size_t pre_len = e->limit - ptr; + + if (arr == NULL || upb_Array_Size(arr) == 0) { + return ptr; + } + +#define VARINT_CASE(ctype, encode) \ + { \ + const ctype* start = upb_Array_DataPtr(arr); \ + const ctype* arr_ptr = start + upb_Array_Size(arr); \ + uint32_t tag = \ + packed ? 0 : (f->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; \ + do { \ + arr_ptr--; \ + ptr = encode_varint(ptr, e, encode); \ + if (tag) { \ + ptr = encode_varint(ptr, e, tag); \ + } \ + } while (arr_ptr != start); \ + } \ + break; + +#define TAG(wire_type) (packed ? 0 : (f->UPB_PRIVATE(number) << 3 | wire_type)) + + switch (f->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Double: + ptr = encode_fixedarray(ptr, e, arr, sizeof(double), + TAG(kUpb_WireType_64Bit)); + break; + case kUpb_FieldType_Float: + ptr = encode_fixedarray(ptr, e, arr, sizeof(float), + TAG(kUpb_WireType_32Bit)); + break; + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + ptr = encode_fixedarray(ptr, e, arr, sizeof(uint64_t), + TAG(kUpb_WireType_64Bit)); + break; + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + ptr = encode_fixedarray(ptr, e, arr, sizeof(uint32_t), + TAG(kUpb_WireType_32Bit)); + break; + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: + VARINT_CASE(uint64_t, *arr_ptr); + case kUpb_FieldType_UInt32: + VARINT_CASE(uint32_t, *arr_ptr); + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: + VARINT_CASE(int32_t, (int64_t)*arr_ptr); + case kUpb_FieldType_Bool: + VARINT_CASE(bool, *arr_ptr); + case kUpb_FieldType_SInt32: + VARINT_CASE(int32_t, encode_zz32(*arr_ptr)); + case kUpb_FieldType_SInt64: + VARINT_CASE(int64_t, encode_zz64(*arr_ptr)); + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + const upb_StringView* start = upb_Array_DataPtr(arr); + const upb_StringView* str_ptr = start + upb_Array_Size(arr); + do { + str_ptr--; + ptr = encode_bytes(ptr, e, str_ptr->data, str_ptr->size); + ptr = encode_length(ptr, e, str_ptr->size); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } while (str_ptr != start); + return ptr; + } + case kUpb_FieldType_Group: { + const upb_Message* const* start = upb_Array_DataPtr(arr); + const upb_Message* const* arr_ptr = start + upb_Array_Size(arr); + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + do { + size_t size; + arr_ptr--; + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_EndGroup); + ptr = encode_message(ptr, e, *arr_ptr, subm, &size); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_StartGroup); + } while (arr_ptr != start); + e->depth++; + return ptr; + } + case kUpb_FieldType_Message: { + const upb_Message* const* start = upb_Array_DataPtr(arr); + const upb_Message* const* arr_ptr = start + upb_Array_Size(arr); + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + do { + size_t size; + arr_ptr--; + ptr = encode_message(ptr, e, *arr_ptr, subm, &size); + ptr = encode_length(ptr, e, size); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } while (arr_ptr != start); + e->depth++; + return ptr; + } + } +#undef VARINT_CASE + + if (packed) { + ptr = encode_length(ptr, e, e->limit - ptr - pre_len); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } + return ptr; +} + +static char* encode_mapentry(char* ptr, upb_encstate* e, uint32_t number, + const upb_MiniTable* layout, + const upb_MapEntry* ent) { + const upb_MiniTableField* key_field = upb_MiniTable_MapKey(layout); + const upb_MiniTableField* val_field = upb_MiniTable_MapValue(layout); + size_t pre_len = e->limit - ptr; + size_t size; + ptr = encode_scalar(ptr, e, &ent->v, val_field); + ptr = encode_scalar(ptr, e, &ent->k, key_field); + size = (e->limit - ptr) - pre_len; + ptr = encode_length(ptr, e, size); + ptr = encode_tag(ptr, e, number, kUpb_WireType_Delimited); + return ptr; +} + +static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTableField* f) { + const upb_Map* map = *UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), const upb_Map*); + const upb_MiniTable* layout = upb_MiniTable_MapEntrySubMessage(f); + UPB_ASSERT(upb_MiniTable_FieldCount(layout) == 2); + + if (!map || !upb_Map_Size(map)) return ptr; + + if (e->options & kUpb_EncodeOption_Deterministic) { + if (!map->UPB_PRIVATE(is_strtable)) { + // For inttable, first encode the array part, then sort the table entries. + intptr_t iter = UPB_INTTABLE_BEGIN; + while ((size_t)++iter < map->t.inttable.array_size) { + upb_value value = map->t.inttable.array[iter]; + if (upb_inttable_arrhas(&map->t.inttable, iter)) { + upb_MapEntry ent; + memcpy(&ent.k, &iter, sizeof(iter)); + _upb_map_fromvalue(value, &ent.v, map->val_size); + ptr = encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, + &ent); + } + } + } + _upb_sortedmap sorted; + _upb_mapsorter_pushmap( + &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), + map, &sorted); + upb_MapEntry ent; + while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { + ptr = encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); + } + _upb_mapsorter_popmap(&e->sorter, &sorted); + } else { + upb_value val; + if (map->UPB_PRIVATE(is_strtable)) { + intptr_t iter = UPB_STRTABLE_BEGIN; + upb_StringView strkey; + while (upb_strtable_next2(&map->t.strtable, &strkey, &val, &iter)) { + upb_MapEntry ent; + _upb_map_fromkey(strkey, &ent.k, map->key_size); + _upb_map_fromvalue(val, &ent.v, map->val_size); + ptr = + encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); + } + } else { + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t intkey = 0; + while (upb_inttable_next(&map->t.inttable, &intkey, &val, &iter)) { + upb_MapEntry ent; + memcpy(&ent.k, &intkey, map->key_size); + _upb_map_fromvalue(val, &ent.v, map->val_size); + ptr = + encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); + } + } + } + return ptr; +} + +static bool encode_shouldencode(const upb_Message* msg, + const upb_MiniTableField* f) { + if (f->presence == 0) { + // Proto3 presence or map/array. + const void* mem = UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), void); + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: { + char ch; + memcpy(&ch, mem, 1); + return ch != 0; + } + case kUpb_FieldRep_4Byte: { + uint32_t u32; + memcpy(&u32, mem, 4); + return u32 != 0; + } + case kUpb_FieldRep_8Byte: { + uint64_t u64; + memcpy(&u64, mem, 8); + return u64 != 0; + } + case kUpb_FieldRep_StringView: { + const upb_StringView* str = (const upb_StringView*)mem; + return str->size != 0; + } + default: + UPB_UNREACHABLE(); + } + } else if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + // Proto2 presence: hasbit. + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); + } else { + // Field is in a oneof. + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == + upb_MiniTableField_Number(f); + } +} + +static char* encode_field(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTableField* field) { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { + case kUpb_FieldMode_Array: + return encode_array(ptr, e, msg, field); + case kUpb_FieldMode_Map: + return encode_map(ptr, e, msg, field); + case kUpb_FieldMode_Scalar: + return encode_scalar( + ptr, e, UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void), field); + default: + UPB_UNREACHABLE(); + } +} + +static char* encode_msgset_item(char* ptr, upb_encstate* e, + const upb_MiniTableExtension* ext, + const upb_MessageValue ext_val) { + size_t size; + ptr = encode_tag(ptr, e, kUpb_MsgSet_Item, kUpb_WireType_EndGroup); + ptr = encode_message(ptr, e, ext_val.msg_val, + upb_MiniTableExtension_GetSubMessage(ext), &size); + ptr = encode_varint(ptr, e, size); + ptr = encode_tag(ptr, e, kUpb_MsgSet_Message, kUpb_WireType_Delimited); + ptr = encode_varint(ptr, e, upb_MiniTableExtension_Number(ext)); + ptr = encode_tag(ptr, e, kUpb_MsgSet_TypeId, kUpb_WireType_Varint); + ptr = encode_tag(ptr, e, kUpb_MsgSet_Item, kUpb_WireType_StartGroup); + return ptr; +} + +static char* encode_ext(char* ptr, upb_encstate* e, + const upb_MiniTableExtension* ext, + upb_MessageValue ext_val, bool is_message_set) { + if (UPB_UNLIKELY(is_message_set)) { + ptr = encode_msgset_item(ptr, e, ext, ext_val); + } else { + ptr = encode_field(ptr, e, &ext_val.UPB_PRIVATE(ext_msg_val), + &ext->UPB_PRIVATE(field)); + } + return ptr; +} + +static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m, + const upb_Message* msg) { + if (m->UPB_PRIVATE(ext) == kUpb_ExtMode_NonExtendable) return ptr; + + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return ptr; + + /* Encode all extensions together. Unlike C++, we do not attempt to keep + * these in field number order relative to normal fields or even to each + * other. */ + uintptr_t iter = kUpb_Message_ExtensionBegin; + const upb_MiniTableExtension* ext; + upb_MessageValue ext_val; + if (!UPB_PRIVATE(_upb_Message_NextExtensionReverse)(msg, &ext, &ext_val, + &iter)) { + // Message has no extensions. + return ptr; + } + + if (e->options & kUpb_EncodeOption_Deterministic) { + _upb_sortedmap sorted; + if (!_upb_mapsorter_pushexts(&e->sorter, in, &sorted)) { + // TODO: b/378744096 - handle alloc failure + } + const upb_Extension* ext; + while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { + ptr = encode_ext(ptr, e, ext->ext, ext->data, + m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); + } + _upb_mapsorter_popmap(&e->sorter, &sorted); + } else { + do { + ptr = encode_ext(ptr, e, ext, ext_val, + m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); + } while (UPB_PRIVATE(_upb_Message_NextExtensionReverse)(msg, &ext, &ext_val, + &iter)); + } + return ptr; +} + +static char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size) { + size_t pre_len = e->limit - ptr; + + if (e->options & kUpb_EncodeOption_CheckRequired) { + if (m->UPB_PRIVATE(required_count)) { + if (!UPB_PRIVATE(_upb_Message_IsInitializedShallow)(msg, m)) { + encode_err(e, kUpb_EncodeStatus_MissingRequired); + } + } + } + + if ((e->options & kUpb_EncodeOption_SkipUnknown) == 0) { + size_t unknown_size = 0; + uintptr_t iter = kUpb_Message_UnknownBegin; + upb_StringView unknown; + // Need to write in reverse order, but iteration is in-order; scan to + // reserve capacity up front, then write in-order + while (upb_Message_NextUnknown(msg, &unknown, &iter)) { + unknown_size += unknown.size; + } + if (unknown_size != 0) { + ptr = encode_reserve(ptr, e, unknown_size); + char* tmp_ptr = ptr; + iter = kUpb_Message_UnknownBegin; + while (upb_Message_NextUnknown(msg, &unknown, &iter)) { + memcpy(tmp_ptr, unknown.data, unknown.size); + tmp_ptr += unknown.size; + } + } + } + + ptr = encode_exts(ptr, e, m, msg); + + if (upb_MiniTable_FieldCount(m)) { + const upb_MiniTableField* f = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0]; + while (f != first) { + f--; + if (encode_shouldencode(msg, f)) { + ptr = encode_field(ptr, e, msg, f); + } + } + } + + *size = (e->limit - ptr) - pre_len; + return ptr; +} + +static upb_EncodeStatus upb_Encoder_Encode(char* ptr, + upb_encstate* const encoder, + const upb_Message* const msg, + const upb_MiniTable* const l, + char** const buf, size_t* const size, + bool prepend_len) { + // Unfortunately we must continue to perform hackery here because there are + // code paths which blindly copy the returned pointer without bothering to + // check for errors until much later (b/235839510). So we still set *buf to + // NULL on error and we still set it to non-NULL on a successful empty result. + if (UPB_SETJMP(encoder->err) == 0) { + size_t encoded_msg_size; + ptr = encode_message(ptr, encoder, msg, l, &encoded_msg_size); + if (prepend_len) { + ptr = encode_length(ptr, encoder, encoded_msg_size); + } + *size = encoder->limit - ptr; + if (*size == 0) { + static char ch; + *buf = &ch; + } else { + UPB_ASSERT(ptr); + *buf = ptr; + } + } else { + UPB_ASSERT(encoder->status != kUpb_EncodeStatus_Ok); + *buf = NULL; + *size = 0; + } + + _upb_mapsorter_destroy(&encoder->sorter); + return encoder->status; +} + +static uint16_t upb_EncodeOptions_GetMaxDepth(uint32_t options) { + return options >> 16; +} + +uint16_t upb_EncodeOptions_GetEffectiveMaxDepth(uint32_t options) { + uint16_t max_depth = upb_EncodeOptions_GetMaxDepth(options); + return max_depth ? max_depth : kUpb_WireFormat_DefaultDepthLimit; +} + +static upb_EncodeStatus _upb_Encode(const upb_Message* msg, + const upb_MiniTable* l, int options, + upb_Arena* arena, char** buf, size_t* size, + bool prepend_len) { + upb_encstate e; + + e.status = kUpb_EncodeStatus_Ok; + e.arena = arena; + e.buf = &initial_buf_sentinel; + e.limit = &initial_buf_sentinel; + e.depth = upb_EncodeOptions_GetEffectiveMaxDepth(options); + e.options = options; + _upb_mapsorter_init(&e.sorter); + + return upb_Encoder_Encode(&initial_buf_sentinel, &e, msg, l, buf, size, + prepend_len); +} + +upb_EncodeStatus upb_Encode(const upb_Message* msg, const upb_MiniTable* l, + int options, upb_Arena* arena, char** buf, + size_t* size) { + return _upb_Encode(msg, l, options, arena, buf, size, false); +} + +upb_EncodeStatus upb_EncodeLengthPrefixed(const upb_Message* msg, + const upb_MiniTable* l, int options, + upb_Arena* arena, char** buf, + size_t* size) { + return _upb_Encode(msg, l, options, arena, buf, size, true); +} + +const char* upb_EncodeStatus_String(upb_EncodeStatus status) { + switch (status) { + case kUpb_EncodeStatus_Ok: + return "Ok"; + case kUpb_EncodeStatus_MissingRequired: + return "Missing required field"; + case kUpb_EncodeStatus_MaxDepthExceeded: + return "Max depth exceeded"; + case kUpb_EncodeStatus_OutOfMemory: + return "Arena alloc failed"; + default: + return "Unknown encode status"; + } +} + + + +// Must be last. + +UPB_NOINLINE +const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* m) { + UPB_ASSERT(m->UPB_PRIVATE(required_count)); + if (UPB_UNLIKELY(d->options & kUpb_DecodeOption_CheckRequired)) { + d->missing_required = + d->missing_required || + !UPB_PRIVATE(_upb_Message_IsInitializedShallow)(msg, m); + } + return ptr; +} + + +#include +#include + + +// Must be last. + +const char* UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)( + upb_EpsCopyInputStream* e) { + e->error = true; + if (e->err) upb_ErrorHandler_ThrowError(e->err, kUpb_ErrorCode_Malformed); + return NULL; +} + +const char* UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)( + struct upb_EpsCopyInputStream* e, const char* ptr, int overrun) { + if (overrun < e->limit) { + // Need to copy remaining data into patch buffer. + UPB_ASSERT(overrun < kUpb_EpsCopyInputStream_SlopBytes); + const char* old_end = ptr; + const char* new_start = &e->patch[overrun]; + memset(&e->patch[kUpb_EpsCopyInputStream_SlopBytes], 0, + kUpb_EpsCopyInputStream_SlopBytes); + memcpy(e->patch, e->end, kUpb_EpsCopyInputStream_SlopBytes); + ptr = new_start; + e->end = &e->patch[kUpb_EpsCopyInputStream_SlopBytes]; + e->limit -= kUpb_EpsCopyInputStream_SlopBytes; + e->limit_ptr = e->end + e->limit; + UPB_ASSERT(ptr < e->limit_ptr); + e->input_delta = (uintptr_t)old_end - (uintptr_t)new_start; + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + return new_start; + } else { + UPB_ASSERT(overrun > e->limit); + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } +} + + +#include +#include + + +// Must be last. + +UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint) + UPB_PRIVATE(_upb_WireReader_ReadLongVarint)( + const char* ptr, uint64_t val, upb_EpsCopyInputStream* stream) { + for (int i = 1; i < 10; i++) { + uint64_t byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ptr + i + 1, val}; + } + } + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0}; +} + +UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint) + UPB_PRIVATE(_upb_WireReader_ReadLongTag)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream) { + for (int i = 1; i < 5; i++) { + uint64_t byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + if (val > UINT32_MAX) break; + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ptr + i + 1, val}; + } + } + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0}; +} + +UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint) + UPB_PRIVATE(_upb_WireReader_ReadLongSize)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream) { + for (int i = 1; i < 5; i++) { + uint64_t byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + if (val > INT32_MAX) break; + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ptr + i + 1, val}; + } + } + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0}; +} + +const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + if (--depth_limit < 0) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } + uint32_t end_group_tag = (tag & ~7ULL) | kUpb_WireType_EndGroup; + while (!upb_EpsCopyInputStream_IsDone(stream, &ptr)) { + uint32_t tag; + ptr = upb_WireReader_ReadTag(ptr, &tag, stream); + if (!ptr) break; + if (tag == end_group_tag) return ptr; + ptr = _upb_WireReader_SkipValue(ptr, tag, depth_limit, stream); + if (!ptr) break; + } + // Encountered limit end before end group tag. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); +} + +// This should #undef all macros #defined in def.inc + +#undef UPB_SIZE +#undef UPB_PTR_AT +#undef UPB_SIZEOF_FLEX +#undef UPB_SIZEOF_FLEX_WOULD_OVERFLOW +#undef UPB_MAPTYPE_STRING +#undef UPB_EXPORT +#undef UPB_INLINE +#undef UPB_API +#undef UPBC_API +#undef UPB_API_INLINE +#undef UPB_API_INLINE_IF_NOT_GCC +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF +#undef UPB_ALIGN_AS +#undef UPB_STATIC_ASSERT +#undef UPB_STATIC_ASSERT_CONCAT +#undef UPB_STATIC_ASSERT_CONCAT_IMPL +#undef UPB_LIKELY +#undef UPB_UNLIKELY +#undef UPB_UNPREDICTABLE +#undef UPB_FORCEINLINE +#undef UPB_NOINLINE +#undef UPB_NORETURN +#undef UPB_PRINTF +#undef UPB_NODEREF +#undef UPB_MAX +#undef UPB_MIN +#undef UPB_UNUSED +#undef UPB_ASSUME +#undef UPB_ASSERT +#undef UPB_UNREACHABLE +#undef UPB_DEFAULT_MAX_BLOCK_SIZE +#undef UPB_SETJMP +#undef UPB_LONGJMP +#undef UPB_PTRADD +#undef UPB_MUSTTAIL +#undef UPB_PRESERVE_MOST +#undef UPB_PRESERVE_NONE +#undef UPB_FASTTABLE_SUPPORTED +#undef UPB_FASTTABLE_MASK +#undef UPB_FASTTABLE +#undef UPB_FASTTABLE_INIT +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN +#undef UPB_HWASAN +#undef UPB_HWASAN_POISON_TAG +#undef UPB_MSAN +#undef UPB_MALLOC_ALIGN +#undef UPB_TSAN +#undef UPB_DEPRECATED +#undef UPB_GNUC_MIN +#undef UPB_DESCRIPTOR_UPB_H_FILENAME +#undef UPB_DESC_MINITABLE +#undef UPB_IS_GOOGLE3 +#undef UPB_ATOMIC +#undef UPB_USE_C11_ATOMICS +#undef UPB_USE_MSC_ATOMICS +#undef UPB_PRIVATE +#undef UPB_ONLYBITS +#undef UPB_LINKARR_DECLARE +#undef UPB_LINKARR_APPEND +#undef UPB_LINKARR_START +#undef UPB_LINKARR_STOP +#undef UPB_FUTURE_BREAKING_CHANGES +#undef UPB_HAS_ATTRIBUTE +#undef UPB_HAS_CPP_ATTRIBUTE +#undef UPB_HAS_BUILTIN +#undef UPB_HAS_EXTENSION +#undef UPB_HAS_FEATURE +#undef UPB_XSAN_MEMBER +#undef UPB_XSAN +#undef UPB_XSAN_STRUCT_SIZE +#undef UPB_ENABLE_REF_CYCLE_CHECKS +#undef UPB_ARM64_ASM +#undef UPB_ARM64_BTI_DEFAULT +#undef UPB_DEPRECATE_AND_INLINE +#undef UPB_MAYBE_ASSUME +#undef UPB_ATTR_CONST diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.h new file mode 100755 index 0000000..6719530 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.h @@ -0,0 +1,18003 @@ +/* Amalgamated source file */ + +/* + * This is where we define internal portability macros used across upb. + * + * All of these macros are undef'd in undef.inc to avoid leaking them to users. + * + * The correct usage is: + * + * #include "upb/foobar.h" + * #include "upb/baz.h" + * + * // MUST be last included header. + * #include "upb/port/def.inc" + * + * // Code for this file. + * // <...> + * + * // Can be omitted for .c files, required for .h. + * #include "upb/port/undef.inc" + * + * This file is private and must not be included by users! + */ + +#if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(_MSC_VER) && _MSC_VER >= 1900)) +#error upb requires C99 or C++17 or MSVC >= 2015. +#endif + +// Portable check for GCC minimum version: +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +#define UPB_GNUC_MIN(x, y) \ + (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +#else +#define UPB_GNUC_MIN(x, y) 0 +#endif + +// Macros for checking for compiler attributes, defined here to avoid the +// problem described in +// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. +#ifdef __has_attribute +#define UPB_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define UPB_HAS_ATTRIBUTE(x) 0 +#endif + +#if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define UPB_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define UPB_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +// Once in a while we want to use this macro in a C++-only portion of an +// otherwise C-compatible header, so we copy and paste this from ABSL. +#if UPB_HAS_CPP_ATTRIBUTE(deprecated) && UPB_HAS_CPP_ATTRIBUTE(clang::annotate) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated, clang::annotate("inline-me")]] +#elif UPB_HAS_CPP_ATTRIBUTE(deprecated) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated]] +#else +#define UPB_DEPRECATE_AND_INLINE() +#endif + +#ifdef __has_builtin +#define UPB_HAS_BUILTIN(x) __has_builtin(x) +#else +#define UPB_HAS_BUILTIN(x) 0 +#endif + +#ifdef __has_extension +#define UPB_HAS_EXTENSION(x) __has_extension(x) +#else +#define UPB_HAS_EXTENSION(x) 0 +#endif + +#ifdef __has_feature +#define UPB_HAS_FEATURE(x) __has_feature(x) +#else +#define UPB_HAS_FEATURE(x) 0 +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef UINTPTR_MAX +Error, UINTPTR_MAX is undefined +#endif + +#if UINTPTR_MAX == 0xffffffff +#define UPB_SIZE(size32, size64) size32 +#else +#define UPB_SIZE(size32, size64) size64 +#endif + +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) + +// A flexible array member may have lower alignment requirements than the struct +// overall - in that case, it can overlap with the trailing padding of the rest +// of the struct, and a naive sizeof(base) + sizeof(flex) * count calculation +// will not take into account that overlap, and allocate more than is required. +#define UPB_SIZEOF_FLEX(type, member, count) \ + UPB_MAX(sizeof(type), offsetof(type, member[count])) + +#define UPB_SIZEOF_FLEX_WOULD_OVERFLOW(type, member, count) \ + (((SIZE_MAX - offsetof(type, member[0])) / \ + (offsetof(type, member[1]) - offsetof(type, member[0]))) < (size_t)count) + +#define UPB_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +#define UPB_MAPTYPE_STRING 0 + +// UPB_EXPORT: always generate a public symbol. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_EXPORT __attribute__((visibility("default"))) __attribute__((used)) +#else +#define UPB_EXPORT +#endif + +// UPB_INLINE: inline if possible, emit standalone code if required. +#ifdef __cplusplus +#define UPB_INLINE inline +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_INLINE static __inline__ +#else +#define UPB_INLINE static +#endif + +// UPB_INLINE_IF_NOT_GCC: because gcc can be very noisy at times. +#if defined(__GNUC__) && !defined(__clang__) +#define UPB_INLINE_IF_NOT_GCC static +#else +#define UPB_INLINE_IF_NOT_GCC UPB_INLINE +#endif + +#ifdef UPB_BUILD_API +#define UPB_API UPB_EXPORT +#define UPB_API_INLINE UPB_EXPORT +#else +#define UPB_API +#define UPB_API_INLINE UPB_INLINE +#endif + +#ifdef EXPORT_UPBC +#define UPBC_API UPB_EXPORT +#else +#define UPBC_API +#endif + +#if UPB_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#else +#define UPB_ASAN 0 +#endif + +#if UPB_HAS_FEATURE(hwaddress_sanitizer) +#define UPB_HWASAN 1 +#define UPB_HWASAN_POISON_TAG 17 +#define UPB_MALLOC_ALIGN 16 +#else +#define UPB_HWASAN 0 +#define UPB_MALLOC_ALIGN 8 +#endif + +#if UPB_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) +#define UPB_TSAN 1 +#else +#define UPB_TSAN 0 +#endif + +#if UPB_HAS_FEATURE(memory_sanitizer) +#define UPB_MSAN 1 +#else +#define UPB_MSAN 0 +#endif + +// An unfortunate concession to C++17 and MSVC, which don't support zero-sized +// structs. +#if UPB_ASAN || UPB_HWASAN || UPB_TSAN +#define UPB_XSAN_MEMBER upb_Xsan xsan; +#define UPB_XSAN(st) (&(st)->xsan) +#define UPB_XSAN_STRUCT_SIZE 1 +#else +#define UPB_XSAN_MEMBER +#define UPB_XSAN(st) (NULL) +#define UPB_XSAN_STRUCT_SIZE 0 +#endif + +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, UPB_MALLOC_ALIGN) + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_alignof) || \ + defined(__cplusplus) +#define UPB_ALIGN_OF(type) alignof(type) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_alignof) +#define UPB_ALIGN_OF(type) _Alignof(type) +#elif UPB_GNUC_MIN(2, 95) +#define UPB_ALIGN_OF(type) __alignof__(type) +#elif defined(_MSC_VER) +#define UPB_ALIGN_OF(type) __alignof(type) +#else +#define UPB_ALIGN_OF(type) \ + offsetof( \ + struct { \ + char c; \ + type member; \ + }, \ + member) +#endif + +#ifdef _MSC_VER +// Some versions of our Windows compiler don't support the C11 syntax. +#define UPB_ALIGN_AS(x) __declspec(align(x)) +#elif defined(__GNUC__) +#define UPB_ALIGN_AS(x) __attribute__((aligned(x))) +#else +#define UPB_ALIGN_AS(x) _Alignas(x) +#endif + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_static_assert) || \ + defined(__cplusplus) +#define UPB_STATIC_ASSERT(val, msg) static_assert((val), msg) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_static_assert) || \ + UPB_GNUC_MIN(4, 6) +#define UPB_STATIC_ASSERT(val, msg) _Static_assert((val), msg) +#else +// Unfortunately this hack doesn't work inside struct declarations, but it works +// everywhere else +#define UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) s1##s2 +#define UPB_STATIC_ASSERT_CONCAT(s1, s2) UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) +#ifdef __COUNTER__ +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __COUNTER__)[(condition) ? 1 : -1] +#else +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __LINE__)[(condition) ? 1 : -1] +#endif +#endif + +// Hints to the compiler about likely/unlikely branches. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_LIKELY(x) __builtin_expect((bool)(x), 1) +#define UPB_UNLIKELY(x) __builtin_expect((bool)(x), 0) +#else +#define UPB_LIKELY(x) (x) +#define UPB_UNLIKELY(x) (x) +#endif + +#if UPB_HAS_BUILTIN(__builtin_expect_with_probability) +#define UPB_UNPREDICTABLE(x) \ + __builtin_expect_with_probability((bool)(x), 1, 0.5) +#else +#define UPB_UNPREDICTABLE(x) (x) +#endif + +// Macros for function attributes on compilers that support them. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) static +#define UPB_NOINLINE __attribute__((noinline)) +#define UPB_NORETURN __attribute__((__noreturn__)) +#define UPB_PRINTF(str, first_vararg) \ + __attribute__((format(printf, str, first_vararg))) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE static +#define UPB_NORETURN __declspec(noreturn) +#define UPB_PRINTF(str, first_vararg) +#else /* !defined(__GNUC__) */ +#define UPB_FORCEINLINE static +#define UPB_NOINLINE +#define UPB_NORETURN +#define UPB_PRINTF(str, first_vararg) +#endif + +#if defined(__clang__) +#define UPB_NODEREF __attribute__((noderef)) +#else +#define UPB_NODEREF +#endif + +#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define UPB_UNUSED(var) (void)(var) + +// UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) \ + if (!(expr)) __builtin_unreachable() +#elif defined _MSC_VER +#define UPB_ASSUME(expr) \ + if (!(expr)) __assume(0) +#else +#define UPB_ASSUME(expr) \ + do { \ + } while (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + +#if UPB_HAS_BUILTIN(__builtin_constant_p) && UPB_HAS_ATTRIBUTE(const) +#define UPB_MAYBE_ASSUME(pred, x) \ + if (__builtin_constant_p(pred) && pred) UPB_ASSUME(x) +#define UPB_ATTR_CONST __attribute__((const)) +#else +#define UPB_MAYBE_ASSUME(pred, x) +#define UPB_ATTR_CONST +#endif + +/* UPB_ASSERT(): in release mode, we use the expression without letting it be + * evaluated. This prevents "unused variable" warnings. */ +#ifdef NDEBUG +#define UPB_ASSERT(expr) \ + do { \ + } while (false && (expr)) +#else +#define UPB_ASSERT(expr) assert(expr) +#endif + +#if !defined(NDEBUG) && !defined(UPB_TSAN) +#define UPB_ENABLE_REF_CYCLE_CHECKS 1 +#else +#define UPB_ENABLE_REF_CYCLE_CHECKS 0 +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __builtin_unreachable(); \ + } while (0) +#elif defined(_MSC_VER) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __assume(0); \ + } while (0) +#else +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + } while (0) +#endif + +#ifdef __ANDROID__ +#define UPB_DEFAULT_MAX_BLOCK_SIZE 8192 +#else +#define UPB_DEFAULT_MAX_BLOCK_SIZE 32768 +#endif + +/* UPB_SETJMP() / UPB_LONGJMP() */ +// Android uses a custom libc that does not implement all of posix, but it has +// had sigsetjmp/siglongjmp forever on arm and since API 12 on x86. Apple has +// sigsetjmp, but does not define the posix feature test macro. +#if defined(__APPLE__) || defined(_POSIX_C_SOURCE) || defined(__ANDROID__) +// avoid setting/restoring signal mask, which involves costly syscalls +#define UPB_SETJMP(buf) sigsetjmp(buf, 0) +#define UPB_LONGJMP(buf, val) siglongjmp(buf, val) +#elif defined(WASM_WAMR) +#define UPB_SETJMP(buf) 0 +#define UPB_LONGJMP(buf, val) abort() +#else +#define UPB_SETJMP(buf) setjmp(buf) +#define UPB_LONGJMP(buf, val) longjmp(buf, val) +#endif + +#if ((__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)) || \ + UPB_HAS_EXTENSION(c_atomic) || \ + defined(__GNUC__) // GCC supported atomics as an extension before it + // supported __has_extension +#define UPB_USE_C11_ATOMICS +#elif defined(_MSC_VER) +#define UPB_USE_MSC_ATOMICS +#endif + +#if defined(UPB_USE_C11_ATOMICS) +#define UPB_ATOMIC(T) _Atomic(T) +#elif defined(UPB_USE_MSC_ATOMICS) +#define UPB_ATOMIC(T) volatile T +#else +#define UPB_ATOMIC(T) T +#endif + +/* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */ +#define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr)) + +#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only + +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + +/* Configure whether fasttable is switched on or not. *************************/ + +#if UPB_HAS_ATTRIBUTE(musttail) +#define UPB_MUSTTAIL __attribute__((musttail)) +#else +#define UPB_MUSTTAIL +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_most) && !defined(__i386__) +#define UPB_PRESERVE_MOST __attribute__((preserve_most)) +#else +#define UPB_PRESERVE_MOST +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_none) +#define UPB_PRESERVE_NONE __attribute__((preserve_none)) +#else +#define UPB_PRESERVE_NONE +#endif + +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +#define UPB_ARM64_ASM 1 +#else +#define UPB_ARM64_ASM 0 +#endif + +/* When compiling with branch protection, we need to ensure that all branch + * targets in assembly use the appropriate landing pad instruction. These + * instructions are backwards compatible with processors that don't have + * FEAT_BTI and are treated as nops. + */ +#if UPB_ARM64_ASM && defined(__ARM_FEATURE_BTI_DEFAULT) +#if __ARM_FEATURE_BTI_DEFAULT == 1 +#define UPB_ARM64_BTI_DEFAULT 1 +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif + +/* This check is not fully robust: it does not require that we have "musttail" + * support available. We need tail calls to avoid consuming arbitrary amounts + * of stack space. + * + * GCC/Clang can mostly be trusted to generate tail calls as long as + * optimization is enabled, but, debug builds will not generate tail calls + * unless "musttail" is available. + * + * We should probably either: + * 1. require that the compiler supports musttail. + * 2. add some fallback code for when musttail isn't available (ie. return + * instead of tail calling). This is safe and portable, but this comes at + * a CPU cost. + */ +#if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__) +#define UPB_FASTTABLE_SUPPORTED 1 +#else +#define UPB_FASTTABLE_SUPPORTED 0 +#endif + +/* define UPB_ENABLE_FASTTABLE to force fast table support. + * This is useful when we want to ensure we are really getting fasttable, + * for example for testing or benchmarking. */ +#if defined(UPB_ENABLE_FASTTABLE) +#if !UPB_FASTTABLE_SUPPORTED +#error fasttable is x86-64/ARM64 only and requires GCC or Clang. +#endif +#define UPB_FASTTABLE 1 +/* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible. + * This is useful for releasing code that might be used on multiple platforms, + * for example the PHP or Ruby C extensions. */ +#elif defined(UPB_TRY_ENABLE_FASTTABLE) +#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#else +#define UPB_FASTTABLE 0 +#endif + +/* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully + * degrade to non-fasttable if the runtime or platform do not support it. */ +#if !UPB_FASTTABLE +#define UPB_FASTTABLE_INIT(...) +#define UPB_FASTTABLE_MASK(mask) -1 +#else +#define UPB_FASTTABLE_INIT(...) __VA_ARGS__ +#define UPB_FASTTABLE_MASK(mask) mask +#endif + +#undef UPB_FASTTABLE_SUPPORTED + +#if defined(__cplusplus) +#if defined(__clang__) || UPB_GNUC_MIN(6, 0) +// https://gcc.gnu.org/gcc-6/changes.html +#define UPB_DEPRECATED [[deprecated]] +#else +#define UPB_DEPRECATED +#endif +#else +#define UPB_DEPRECATED +#endif + +#if defined(UPB_IS_GOOGLE3) && \ + (!defined(UPB_BOOTSTRAP_STAGE) || UPB_BOOTSTRAP_STAGE != 0) +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_IS_GOOGLE3) && defined(UPB_BOOTSTRAP_STAGE) && \ + UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) proto2__##sym##_msg_init() +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() +#else +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init +#endif + +#undef UPB_IS_GOOGLE3 + +#ifdef __clang__ +#define UPB_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address"))) +#else +#define UPB_NO_SANITIZE_ADDRESS +#endif + +#if defined(__GNUC__) && (defined(__clang__) || UPB_GNUC_MIN(11, 0)) +#define UPB_RETAIN __attribute__((retain)) +#else +#define UPB_RETAIN +#endif + +// Linker arrays combine elements from multiple translation units into a single +// array that can be iterated over at runtime. +// +// It is an alternative to pre-main "registration" functions. +// +// Usage: +// +// // In N translation units. +// UPB_LINKARR_APPEND(foo_array) static int elems[3] = {1, 2, 3}; +// +// // At runtime: +// UPB_LINKARR_DECLARE(foo_array, int); +// +// void f() { +// const int* start = UPB_LINKARR_START(foo_array); +// const int* stop = UPB_LINKARR_STOP(foo_array); +// for (const int* p = start; p < stop; p++) { +// // Windows can introduce zero padding, so we have to skip zeroes. +// if (*p != 0) { +// vec.push_back(*p); +// } +// } +// } + +#if defined(__GNUC__) && !defined(__clang__) +// GCC can't handle mismatched retain attributes in the same section: +// https://github.com/protocolbuffers/protobuf/issues/26385 +// To work around this, we retain all linker array elements, even though this +// effectively disables tree-shaking of unused extensions when using GCC. +#define UPB_LINKARR_ATTR UPB_RETAIN +#else +#define UPB_LINKARR_ATTR +#endif + +#define UPB_LINKARR_SENTINEL UPB_RETAIN __attribute__((weak, used)) + +#if defined(__ELF__) || defined(__wasm__) + +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(__MACH__) + +/* As described in: https://stackoverflow.com/a/22366882 */ +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(_MSC_VER) + +/* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ +#define UPB_STRINGIFY_INTERNAL(x) #x +#define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) +#define UPB_CONCAT(a, b, c) a##b##c +#define UPB_LINKARR_NAME(name, index) \ + UPB_STRINGIFY(UPB_CONCAT(la_, name, index)) +#define UPB_LINKARR_APPEND(name) \ + __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $j))) +// clang-format off +#define UPB_LINKARR_DECLARE(name, type) \ + __pragma(message(UPB_LINKARR_NAME(name, $j))) \ + __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ + __pragma(section(UPB_LINKARR_NAME(name, $z), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $a)), selectany) \ + type __start_linkarr_##name; \ + __declspec(allocate(UPB_LINKARR_NAME(name, $z)), selectany) \ + type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} +// clang-format on +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#else + +// Linker arrays are not supported on this platform. Make macros no-ops. +#define UPB_LINKARR_APPEND(name) +#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_START(name) (NULL) +#define UPB_LINKARR_STOP(name) (NULL) + +#endif + +// Workaround for https://github.com/llvm/llvm-project/issues/167577 until it's +// fixed. Some function must exist for the constructor to work properly. +// TODO Remove this or gate it on a future version of clang. +#if defined(__clang__) && defined(__arm__) +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((used, visibility("hidden"))) void UPB_PRIVATE(unique_name)( \ + void) {} +#else +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) +#endif + +#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) +#define UPB_CONSTRUCTOR(name, unique_name) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ + name)(void) +#elif defined(_MSC_VER) +/* + * See: https://stackoverflow.com/questions/1113409 + * + * The /include pragma suggested in the link above doesn't work in our case + * because it requires globally unique names. We need a different solution + * to prevent optimizers from removing the constructor. Our solution is to + * create a dummy exported weak symbol that prevent this stripping. + */ +#pragma section(".CRT$XCT", read) +#define UPB_CONSTRUCTOR(name, unique_name) \ + static void __cdecl UPB_PRIVATE(name)(void); \ + __declspec(allocate(".CRT$XCT"), selectany) void( \ + __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ + __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ + &UPB_PRIVATE(name##_); \ + static void __cdecl UPB_PRIVATE(name)(void) + +#else +// No constructor support, nothing we can do except not break builds. +#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#endif + +// +// Weak alias platform support. Theoretically this should be possible to do with +// only C using attributes like __attribute__((weak, alias("foo"))), but +// Clang doesn't support this properly on macOS. So we have to use assembly. +#if defined(__APPLE__) + +// TODO: once https://github.com/llvm/llvm-project/issues/167262 is fixed +// in the LLVM linker, we should have all weak variables point to a single +// "default" empty MiniTable instead of having each leaf define its own, like +// we do with ELF below. This will reduce binary size if many messages are tree +// shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) \ + __attribute__((weak)) const upb_MiniTable name = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to; \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); \ + __asm__(".weak_definition _" #to); +#define UPB_STRONG_ALIAS(type, from, to) \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); + +#elif defined(__ELF__) + +// On ELF, weak aliases work properly, so we can have all weak MiniTables point +// to the same empty singleton MiniTable. This reduces code size if many +// MiniTables are tree shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ + __attribute__((weak)) \ + const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to \ + __attribute__((weak, alias("kUpb_WeakSingletonPlaceholderMiniTable"))); +#define UPB_STRONG_ALIAS(type, from, to) \ + extern type to __attribute__((alias(#from))); + +#else +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) weak_alias_not_supported_on_this_platform +#define UPB_STRONG_ALIAS(type, from, to) \ + strong_alias_not_supported_on_this_platform +#endif + +// Future versions of upb will include breaking changes to some APIs. +// This macro can be set to enable these API changes ahead of time, so that +// user code can be updated before upgrading versions of protobuf. +#ifdef UPB_FUTURE_BREAKING_CHANGES + +#endif + +#ifndef UPB_GENERATED_CODE_SUPPORT_H_ +#define UPB_GENERATED_CODE_SUPPORT_H_ + +// This is a bit awkward; we want to conditionally include the fast decoder, +// but we generally don't let macros like UPB_FASTTABLE leak into user code. +// We can't #include "decode_fast.h" inside the port/def.inc, because the +// inc files strictly prohibit recursive inclusion, and decode_fast.h includes +// port/def.inc. So instead we use this two-part dance to conditionally include +// decode_fast.h. +#if UPB_FASTTABLE +#define UPB_INCLUDE_FAST_DECODE +#endif + +// IWYU pragma: begin_exports + +#ifndef UPB_BASE_UPCAST_H_ +#define UPB_BASE_UPCAST_H_ + +// Must be last. + +// This macro provides a way to upcast message pointers in a way that is +// somewhat more bulletproof than blindly casting a pointer. Example: +// +// typedef struct { +// upb_Message UPB_PRIVATE(base); +// } pkg_FooMessage; +// +// void f(pkg_FooMessage* msg) { +// upb_Decode(UPB_UPCAST(msg), ...); +// } + +#define UPB_UPCAST(x) (&(x)->base##_dont_copy_me__upb_internal_use_only) + + +#endif /* UPB_BASE_UPCAST_H_ */ + +#ifndef UPB_MESSAGE_ACCESSORS_H_ +#define UPB_MESSAGE_ACCESSORS_H_ + +#include + +#ifndef UPB_BASE_STRING_VIEW_H_ +#define UPB_BASE_STRING_VIEW_H_ + +#include + +// Must be last. + +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } + +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data + +// LINT.IfChange(struct_definition) +typedef struct { + const char* data; + size_t size; +} upb_StringView; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); +} + +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { + return (a.size == b.size) && (!a.size || !memcmp(a.data, b.data, a.size)); +} + +// Compares StringViews following strcmp rules. +// Please note this comparison is neither unicode nor locale aware. +UPB_INLINE int upb_StringView_Compare(upb_StringView a, upb_StringView b) { + int result = memcmp(a.data, b.data, UPB_MIN(a.size, b.size)); + if (result != 0) return result; + if (a.size < b.size) { + return -1; + } else if (a.size > b.size) { + return 1; + } else { + return 0; + } +} + +// LINT.ThenChange( +// GoogleInternalName1, +// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string, +// //depot/google3/third_party/upb/bits/typescript/string_view.ts +// ) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_STRING_VIEW_H_ */ + +/* upb_Arena is a specific allocator implementation that uses arena allocation. + * The user provides an allocator that will be used to allocate the underlying + * arena blocks. Arenas by nature do not require the individual allocations + * to be freed. However the Arena does allow users to register cleanup + * functions that will run when the arena is destroyed. + * + * A upb_Arena is *not* thread-safe, although some functions related to its + * managing its lifetime are, and are documented as such. + * + * You could write a thread-safe arena allocator that satisfies the + * upb_alloc interface, but it would not be as efficient for the + * single-threaded case. */ + +#ifndef UPB_MEM_ARENA_H_ +#define UPB_MEM_ARENA_H_ + +#include +#include + + +#ifndef UPB_MEM_ALLOC_H_ +#define UPB_MEM_ALLOC_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct upb_alloc upb_alloc; + +/* A combined `malloc()`/`free()` function. + * If `size` is 0 then the function acts like `free()`, otherwise it acts like + * `realloc()`. Only `oldsize` bytes from a previous allocation are + * preserved. If `actual_size` is not null and the allocator supports it, the + * actual size of the resulting allocation is stored in `actual_size`. If + * `actual_size` is not null, you must zero out the memory pointed to by + * `actual_size` before calling. */ +typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize, + size_t size, size_t* actual_size); + +/* A upb_alloc is a possibly-stateful allocator object. + * + * It could either be an arena allocator (which doesn't require individual + * `free()` calls) or a regular `malloc()` (which does). The client must + * therefore free memory unless it knows that the allocator is an arena + * allocator. */ +struct upb_alloc { + upb_alloc_func* func; +}; + +UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) { + UPB_ASSERT(alloc); + return alloc->func(alloc, NULL, 0, size, NULL); +} + +typedef struct { + void* p; + size_t n; +} upb_SizedPtr; + +UPB_INLINE upb_SizedPtr upb_SizeReturningMalloc(upb_alloc* alloc, size_t size) { + UPB_ASSERT(alloc); + upb_SizedPtr result; + result.n = 0; + result.p = alloc->func(alloc, NULL, 0, size, &result.n); + result.n = result.p != NULL ? UPB_MAX(result.n, size) : 0; + return result; +} + +UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize, + size_t size) { + UPB_ASSERT(alloc); + return alloc->func(alloc, ptr, oldsize, size, NULL); +} + +UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) { + UPB_ASSERT(alloc); + alloc->func(alloc, ptr, 0, 0, NULL); +} + +UPB_INLINE void upb_free_sized(upb_alloc* alloc, void* ptr, size_t size) { + UPB_ASSERT(alloc); + alloc->func(alloc, ptr, size, 0, NULL); +} + +// The global allocator used by upb. Uses the standard malloc()/free(). + +extern upb_alloc upb_alloc_global; + +/* Functions that hard-code the global malloc. + * + * We still get benefit because we can put custom logic into our global + * allocator, like injecting out-of-memory faults in debug/testing builds. */ + +UPB_INLINE void* upb_gmalloc(size_t size) { + return upb_malloc(&upb_alloc_global, size); +} + +UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) { + return upb_realloc(&upb_alloc_global, ptr, oldsize, size); +} + +UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MEM_ALLOC_H_ */ + +#ifndef UPB_MEM_INTERNAL_ARENA_H_ +#define UPB_MEM_INTERNAL_ARENA_H_ + +#include +#include +#include + + +#ifndef UPB_PORT_SANITIZERS_H_ +#define UPB_PORT_SANITIZERS_H_ + +#include +#include +#include + +// Must be last. + +// Must be inside def.inc/undef.inc +#if UPB_HWASAN +#include +#endif + +#if UPB_MSAN +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// UPB_ARENA_SIZE_HACK depends on this struct having size 1. +typedef struct { + uint8_t state; +} upb_Xsan; + +UPB_INLINE uint8_t _upb_Xsan_NextTag(upb_Xsan *xsan) { +#if UPB_HWASAN + xsan->state++; + if (xsan->state <= UPB_HWASAN_POISON_TAG) { + xsan->state = UPB_HWASAN_POISON_TAG + 1; + } + return xsan->state; +#else + UPB_UNUSED(xsan); + return 0; +#endif +} + +enum { +#if UPB_ASAN + UPB_PRIVATE(kUpb_Asan_GuardSize) = 32, +#else + UPB_PRIVATE(kUpb_Asan_GuardSize) = 0, +#endif +}; + +UPB_INLINE uint8_t UPB_PRIVATE(_upb_Xsan_GetTag)(const void *addr) { +#if UPB_HWASAN + return __hwasan_get_tag_from_pointer(addr); +#else + UPB_UNUSED(addr); + return 0; +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_Init)(upb_Xsan *xsan) { +#if UPB_HWASAN || UPB_TSAN + xsan->state = 0; +#else + UPB_UNUSED(xsan); +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_MarkInitialized)(void* addr, size_t size) { +#if UPB_HAS_FEATURE(memory_sanitizer) + if (size) { + __msan_unpoison(addr, size); + } +#else + UPB_UNUSED(addr); + UPB_UNUSED(size); +#endif +} + +// Marks the given region as poisoned, meaning that it is not accessible until +// it is unpoisoned. +UPB_INLINE void UPB_PRIVATE(upb_Xsan_PoisonRegion)(const void *addr, + size_t size) { +#if UPB_ASAN + void __asan_poison_memory_region(void const volatile *addr, size_t size); + __asan_poison_memory_region(addr, size); +#elif UPB_HWASAN + __hwasan_tag_memory(addr, UPB_HWASAN_POISON_TAG, UPB_ALIGN_MALLOC(size)); +#else + UPB_UNUSED(addr); + UPB_UNUSED(size); +#endif +} + +UPB_INLINE void *UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)(void *addr, size_t size, + uint8_t tag) { +#if UPB_ASAN + UPB_UNUSED(tag); + void __asan_unpoison_memory_region(void const volatile *addr, size_t size); + __asan_unpoison_memory_region(addr, size); + return addr; +#elif UPB_HWASAN + __hwasan_tag_memory(addr, tag, UPB_ALIGN_MALLOC(size)); + return __hwasan_tag_pointer(addr, tag); +#else + UPB_UNUSED(size); + UPB_UNUSED(tag); + + // `addr` is the pointer that will be returned from arena alloc/realloc + // functions. In this code-path we know it must be non-NULL, but the compiler + // doesn't know this unless we add a UPB_ASSUME() annotation. + // + // This will let the optimizer optimize away NULL-checks if it can see that + // this path was taken. + UPB_ASSUME(addr); + return addr; +#endif +} + +// Allows users to read and write to the given region, which will be considered +// distinct from other regions and may only be accessed through the returned +// pointer. +// +// `addr` must be aligned to the malloc alignment. Size may be unaligned, +// and with ASAN we can respect `size` precisely, but with HWASAN we must +// round `size` up to the next multiple of the malloc alignment, so the caller +// must guarantee that rounding up `size` will not cause overlap with other +// regions. +UPB_INLINE void *UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(upb_Xsan *xsan, + void *addr, + size_t size) { + return UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)(addr, size, + _upb_Xsan_NextTag(xsan)); +} + +// Resizes the given region to a new size, *without* invalidating any existing +// pointers to the region. +// +// `tagged_addr` must be a pointer that was previously returned from +// `upb_Xsan_NewUnpoisonedRegion`. `old_size` must be the size that was +// originally passed to `upb_Xsan_NewUnpoisonedRegion`. +UPB_INLINE void *UPB_PRIVATE(upb_Xsan_ResizeUnpoisonedRegion)(void *tagged_addr, + size_t old_size, + size_t new_size) { + UPB_PRIVATE(upb_Xsan_PoisonRegion)(tagged_addr, old_size); + return UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)( + tagged_addr, new_size, UPB_PRIVATE(_upb_Xsan_GetTag)(tagged_addr)); +} + +// Compares two pointers and returns true if they are equal. This returns the +// correct result even if one or both of the pointers are tagged. +UPB_INLINE bool UPB_PRIVATE(upb_Xsan_PtrEq)(const void *a, const void *b) { +#if UPB_HWASAN + return __hwasan_tag_pointer(a, 0) == __hwasan_tag_pointer(b, 0); +#else + return a == b; +#endif +} + +// These annotations improve TSAN's ability to detect data races. By +// proactively accessing a non-atomic variable at the point where it is +// "logically" accessed, we can trigger TSAN diagnostics that might have +// otherwise been masked by subsequent atomic operations. + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_AccessReadOnly)(upb_Xsan *xsan) { +#if UPB_TSAN + // For performance we avoid using a volatile variable. + __asm__ volatile("" ::"r"(xsan->state)); +#else + UPB_UNUSED(xsan); +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_AccessReadWrite)(upb_Xsan *xsan) { +#if UPB_TSAN + // For performance we avoid using a volatile variable. + __asm__ volatile("" : "+r"(xsan->state)); +#else + UPB_UNUSED(xsan); +#endif +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_PORT_SANITIZERS_H_ + +// Must be last. + +// This is QUITE an ugly hack, which specifies the number of pointers needed +// to equal (or exceed) the storage required for one upb_Arena. +// +// We need this because the decoder inlines a upb_Arena for performance but +// the full struct is not visible outside of arena.c. Yes, I know, it's awful. +#ifndef NDEBUG +#define UPB_ARENA_BASE_SIZE_HACK 10 +#else +#define UPB_ARENA_BASE_SIZE_HACK 9 +#endif + +#define UPB_ARENA_SIZE_HACK \ + (sizeof(void*) * (UPB_ARENA_BASE_SIZE_HACK + (UPB_XSAN_STRUCT_SIZE * 2))) + \ + (sizeof(uint32_t) * 2) + +// LINT.IfChange(upb_Arena) + +struct upb_Arena { + char* UPB_ONLYBITS(ptr); + const UPB_NODEREF char* UPB_ONLYBITS(end); + UPB_XSAN_MEMBER +}; + +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/arena.ts:upb_Arena) + +#ifdef __cplusplus +extern "C" { +#endif + +void UPB_PRIVATE(_upb_Arena_SwapIn)(struct upb_Arena* des, + const struct upb_Arena* src); +void UPB_PRIVATE(_upb_Arena_SwapOut)(struct upb_Arena* des, + const struct upb_Arena* src); + +UPB_INLINE size_t UPB_PRIVATE(_upb_ArenaHas)(const struct upb_Arena* a) { + return (size_t)(a->UPB_ONLYBITS(end) - a->UPB_ONLYBITS(ptr)); +} + +UPB_INLINE size_t UPB_PRIVATE(_upb_Arena_AllocSpan)(size_t size) { + return UPB_ALIGN_MALLOC(size) + UPB_PRIVATE(kUpb_Asan_GuardSize); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)( + const struct upb_Arena* a, void* ptr, size_t size) { + return UPB_PRIVATE(upb_Xsan_PtrEq)( + (char*)ptr + UPB_PRIVATE(_upb_Arena_AllocSpan)(size), + a->UPB_ONLYBITS(ptr)); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_Arena_IsAligned)(const void* ptr) { + return (uintptr_t)ptr % UPB_MALLOC_ALIGN == 0; +} + +UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + + size_t span = UPB_PRIVATE(_upb_Arena_AllocSpan)(size); + + if (UPB_UNLIKELY(UPB_PRIVATE(_upb_ArenaHas)(a) < span)) { + void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(struct upb_Arena * a, size_t size); + return UPB_PRIVATE(_upb_Arena_SlowMalloc)(a, span); + } + + // We have enough space to do a fast malloc. + void* ret = a->UPB_ONLYBITS(ptr); + a->UPB_ONLYBITS(ptr) += span; + UPB_ASSERT(UPB_PRIVATE(_upb_Arena_IsAligned)(ret)); + UPB_ASSERT(UPB_PRIVATE(_upb_Arena_IsAligned)(a->UPB_ONLYBITS(ptr))); + + return UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(UPB_XSAN(a), ret, size); +} + +UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr, + size_t oldsize, size_t size) { + UPB_ASSERT(ptr); + UPB_ASSERT(size <= oldsize); + + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + UPB_PRIVATE(upb_Xsan_ResizeUnpoisonedRegion)(ptr, oldsize, size); + + if (UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)(a, ptr, oldsize)) { + // We can reclaim some memory. + a->UPB_ONLYBITS(ptr) -= UPB_ALIGN_MALLOC(oldsize) - UPB_ALIGN_MALLOC(size); + } else { + // We can't reclaim any memory, but we need to verify that `ptr` really + // does represent the most recent allocation. +#ifndef NDEBUG + bool _upb_Arena_WasLastAlloc(struct upb_Arena * a, void* ptr, + size_t oldsize); + UPB_ASSERT(_upb_Arena_WasLastAlloc(a, ptr, oldsize)); +#endif + } +} + +UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr, + size_t oldsize, size_t size) { + UPB_ASSERT(ptr); + UPB_ASSERT(size > oldsize); + + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + size_t extend = UPB_ALIGN_MALLOC(size) - UPB_ALIGN_MALLOC(oldsize); + + if (UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)(a, ptr, oldsize) && + UPB_PRIVATE(_upb_ArenaHas)(a) >= extend) { + a->UPB_ONLYBITS(ptr) += extend; + UPB_PRIVATE(upb_Xsan_ResizeUnpoisonedRegion)(ptr, oldsize, size); + return true; + } + + return false; +} + +UPB_API_INLINE void* upb_Arena_Realloc(struct upb_Arena* a, void* ptr, + size_t oldsize, size_t size) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + + void* ret; + + if (ptr && (size <= oldsize || upb_Arena_TryExtend(a, ptr, oldsize, size))) { + // We can extend or shrink in place. + if (size <= oldsize && + UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)(a, ptr, oldsize)) { + upb_Arena_ShrinkLast(a, ptr, oldsize, size); + } + ret = ptr; + } else { + // We need to copy into a new allocation. + ret = upb_Arena_Malloc(a, size); + if (ret && oldsize > 0) { + memcpy(ret, ptr, UPB_MIN(oldsize, size)); + } + } + + if (ret) { + // We want to invalidate pointers to the old region if hwasan is enabled, so + // we poison and unpoison even if ptr == ret. However, if reallocation fails + // we do not want to poison the old memory, or attempt to poison null. + UPB_PRIVATE(upb_Xsan_PoisonRegion)(ptr, oldsize); + return UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(UPB_XSAN(a), ret, size); + } + return ret; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MEM_INTERNAL_ARENA_H_ */ + +// Must be last. + +typedef struct upb_Arena upb_Arena; + +typedef void upb_AllocCleanupFunc(upb_alloc* alloc); + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates an arena from the given initial block (if any -- mem may be NULL). If +// an initial block is specified, the arena's lifetime cannot be extended by +// |upb_Arena_IncRefFor| or |upb_Arena_Fuse|. Additional blocks will be +// allocated from |alloc|. If |alloc| is NULL, this is a fixed-size arena and +// cannot grow. If an initial block is specified, |n| is its length; if there is +// no initial block, |n| is a hint of the size that should be allocated for the +// first block of the arena, such that `upb_Arena_Malloc(hint)` will not require +// another call to |alloc|. +UPB_API upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc); + +UPB_API void upb_Arena_Free(upb_Arena* a); +// Sets the cleanup function for the upb_alloc used by the arena. Only one +// cleanup function can be set, which will be called after all blocks are +// freed. +UPB_API void upb_Arena_SetAllocCleanup(upb_Arena* a, + upb_AllocCleanupFunc* func); + +// Fuses the lifetime of two arenas, such that no arenas that have been +// transitively fused together will be freed until all of them have reached a +// zero refcount. This operation is safe to use concurrently from multiple +// threads. +UPB_API bool upb_Arena_Fuse(const upb_Arena* a, const upb_Arena* b); + +// This operation is safe to use concurrently from multiple threads. +UPB_API bool upb_Arena_IsFused(const upb_Arena* a, const upb_Arena* b); + +// Returns the upb_alloc used by the arena. +UPB_API upb_alloc* upb_Arena_GetUpbAlloc(upb_Arena* a); + +// This operation is safe to use concurrently from multiple threads. +bool upb_Arena_IncRefFor(const upb_Arena* a, const void* owner); +// This operation is safe to use concurrently from multiple threads. +void upb_Arena_DecRefFor(const upb_Arena* a, const void* owner); + +// Creates a reference between the arenas `from` and `to`, guaranteeing that +// the latter will not be freed until `from` is freed. +// +// Users must avoid all of the following error conditions, which will be +// checked in debug mode but are UB in opt: +// +// - Creating reference cycles between arenas. +// - Creating a reference between two arenas that are fused, either now +// or in the future. +// +// Creating a reference multiple times between the same two arenas is not UB but +// is considered wasteful and may be disallowed in the future. +// +// Note that fuses can participate in reference cycles. The following set of +// calls creates a cycle A -> B -> C -> A +// Fuse(A, B); +// Ref(B, C); +// Ref(C, A); +// +// From this perspective, the second rule is just a special-case of the first. +// This set of calls is disallowed because it is effectively creating a +// cycle A -> B -> A +// Fuse(A, B); +// Ref(B, A); +// +// Fuse is special because it creates what is effectively a bidirectional +// ref, but it is not considered a cycle and will be collected correctly. +// +// Note that `from` is not `const`, so it may not be called concurrently +// with any other function on `from`. +// +// Returns whether the reference was created successfully. +bool upb_Arena_RefArena(upb_Arena* from, const upb_Arena* to); + +#ifndef NDEBUG +// Returns true if upb_Arena_RefArena(from, to) was previously called. +// Note that this does not take fuses into account, and it does not follow +// chains of references; it must have been these two arenas exactly that +// created a reference. +bool upb_Arena_HasRef(const upb_Arena* from, const upb_Arena* to); +#endif + +// This operation is safe to use concurrently from multiple threads. +uintptr_t upb_Arena_SpaceAllocated(const upb_Arena* a, size_t* fused_count); +// This operation is safe to use concurrently from multiple threads. +uint32_t upb_Arena_DebugRefCount(const upb_Arena* a); + +#if UPB_ENABLE_REF_CYCLE_CHECKS +// Returns true if there is a chain of arena refs that spans `from` -> `to`. +// Fused arenas are taken into account; for example, this series of calls +// will cause the function to return true: +// +// 1. upb_Arena_Fuse(a, b) +// 2. upb_Arena_RefArena(from, a) +// 3. upb_Arena_RefArena(b, to) +// +// However this function does not return true if `from` and `to` are directly +// fused. +bool upb_Arena_HasRefChain(const upb_Arena* from, const upb_Arena* to); +#endif + +UPB_API_INLINE upb_Arena* upb_Arena_New(void) { + return upb_Arena_Init(NULL, 0, &upb_alloc_global); +} + +UPB_API_INLINE upb_Arena* upb_Arena_NewSized(size_t size_hint) { + return upb_Arena_Init(NULL, size_hint, &upb_alloc_global); +} + +UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size); + +UPB_API_INLINE void* upb_Arena_Realloc(upb_Arena* a, void* ptr, size_t oldsize, + size_t size); + +static const size_t UPB_PRIVATE(kUpbDefaultMaxBlockSize) = + UPB_DEFAULT_MAX_BLOCK_SIZE; + +// Sets the maximum block size for all arenas. This is a global configuration +// setting that will affect all existing and future arenas. If +// upb_Arena_Malloc() is called with a size larger than this, we will exceed +// this size and allocate a larger block. +// +// This API is meant for experimentation only. It will likely be removed in +// the future. +// This operation is safe to use concurrently from multiple threads. +void upb_Arena_SetMaxBlockSize(size_t max); + +// Shrinks the last alloc from arena. +// REQUIRES: (ptr, oldsize) was the last malloc/realloc from this arena. +// We could also add a upb_Arena_TryShrinkLast() which is simply a no-op if +// this was not the last alloc. +UPB_API_INLINE void upb_Arena_ShrinkLast(upb_Arena* a, void* ptr, + size_t oldsize, size_t size); + +// Attempts to extend the given alloc from arena, in place. Is generally +// only likely to succeed for the most recent allocation from this arena. If it +// succeeds, returns true and `ptr`'s allocation is now `size` rather than +// `oldsize`. Returns false if the allocation cannot be extended; `ptr`'s +// allocation is unmodified. See also upb_Arena_Realloc. +// REQUIRES: `size > oldsize`; to shrink, use `upb_Arena_Realloc` or +// `upb_Arena_ShrinkLast`. +UPB_API_INLINE bool upb_Arena_TryExtend(upb_Arena* a, void* ptr, size_t oldsize, + size_t size); + +#ifdef UPB_TRACING_ENABLED +void upb_Arena_SetTraceHandler(void (*initArenaTraceHandler)(const upb_Arena*, + size_t size), + void (*fuseArenaTraceHandler)(const upb_Arena*, + const upb_Arena*), + void (*freeArenaTraceHandler)(const upb_Arena*)); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MEM_ARENA_H_ */ + +#ifndef UPB_MESSAGE_ARRAY_H_ +#define UPB_MESSAGE_ARRAY_H_ + +#include + + +#ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_ +#define UPB_BASE_DESCRIPTOR_CONSTANTS_H_ + +// Must be last. + +// The types a field can have. Note that this list is not identical to the +// types defined in descriptor.proto, which gives INT32 and SINT32 separate +// types (we distinguish the two with the "integer encoding" enum below). +// This enum is an internal convenience only and has no meaning outside of upb. +typedef enum { + kUpb_CType_Bool = 1, + kUpb_CType_Float = 2, + kUpb_CType_Int32 = 3, + kUpb_CType_UInt32 = 4, + kUpb_CType_Enum = 5, // Enum values are int32. TODO: rename + kUpb_CType_Message = 6, + kUpb_CType_Double = 7, + kUpb_CType_Int64 = 8, + kUpb_CType_UInt64 = 9, + kUpb_CType_String = 10, + kUpb_CType_Bytes = 11 +} upb_CType; + +// The repeated-ness of each field; this matches descriptor.proto. +typedef enum { + kUpb_Label_Optional = 1, + kUpb_Label_Required = 2, + kUpb_Label_Repeated = 3 +} upb_Label; + +// Descriptor types, as defined in descriptor.proto. +typedef enum { + kUpb_FieldType_Double = 1, + kUpb_FieldType_Float = 2, + kUpb_FieldType_Int64 = 3, + kUpb_FieldType_UInt64 = 4, + kUpb_FieldType_Int32 = 5, + kUpb_FieldType_Fixed64 = 6, + kUpb_FieldType_Fixed32 = 7, + kUpb_FieldType_Bool = 8, + kUpb_FieldType_String = 9, + kUpb_FieldType_Group = 10, + kUpb_FieldType_Message = 11, + kUpb_FieldType_Bytes = 12, + kUpb_FieldType_UInt32 = 13, + kUpb_FieldType_Enum = 14, + kUpb_FieldType_SFixed32 = 15, + kUpb_FieldType_SFixed64 = 16, + kUpb_FieldType_SInt32 = 17, + kUpb_FieldType_SInt64 = 18, +} upb_FieldType; + +#define kUpb_FieldType_SizeOf 19 + +#ifdef __cplusplus +extern "C" { +#endif + +// Convert from upb_FieldType to upb_CType +UPB_INLINE upb_CType upb_FieldType_CType(upb_FieldType field_type) { + static const upb_CType c_type[] = { + kUpb_CType_Double, // kUpb_FieldType_Double + kUpb_CType_Float, // kUpb_FieldType_Float + kUpb_CType_Int64, // kUpb_FieldType_Int64 + kUpb_CType_UInt64, // kUpb_FieldType_UInt64 + kUpb_CType_Int32, // kUpb_FieldType_Int32 + kUpb_CType_UInt64, // kUpb_FieldType_Fixed64 + kUpb_CType_UInt32, // kUpb_FieldType_Fixed32 + kUpb_CType_Bool, // kUpb_FieldType_Bool + kUpb_CType_String, // kUpb_FieldType_String + kUpb_CType_Message, // kUpb_FieldType_Group + kUpb_CType_Message, // kUpb_FieldType_Message + kUpb_CType_Bytes, // kUpb_FieldType_Bytes + kUpb_CType_UInt32, // kUpb_FieldType_UInt32 + kUpb_CType_Enum, // kUpb_FieldType_Enum + kUpb_CType_Int32, // kUpb_FieldType_SFixed32 + kUpb_CType_Int64, // kUpb_FieldType_SFixed64 + kUpb_CType_Int32, // kUpb_FieldType_SInt32 + kUpb_CType_Int64, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return c_type[field_type - 1]; +} + +UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType field_type) { + // clang-format off + const unsigned kUnpackableTypes = + (1 << kUpb_FieldType_String) | + (1 << kUpb_FieldType_Bytes) | + (1 << kUpb_FieldType_Message) | + (1 << kUpb_FieldType_Group); + // clang-format on + return (1 << field_type) & ~kUnpackableTypes; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_ARRAY_H_ +#define UPB_MESSAGE_INTERNAL_ARRAY_H_ + +#include +#include + + +// Must be last. + +#define _UPB_ARRAY_MASK_IMM 0x4 // Frozen/immutable bit. +#define _UPB_ARRAY_MASK_LG2 0x3 // Encoded elem size. +#define _UPB_ARRAY_MASK_ALL (_UPB_ARRAY_MASK_IMM | _UPB_ARRAY_MASK_LG2) + +#ifdef __cplusplus +extern "C" { +#endif + +// LINT.IfChange(upb_Array) + +// Our internal representation for repeated fields. +struct upb_Array { + // This is a tagged pointer. Bits #0 and #1 encode the elem size as follows: + // 0 maps to elem size 1 + // 1 maps to elem size 4 + // 2 maps to elem size 8 + // 3 maps to elem size 16 + // + // Bit #2 contains the frozen/immutable flag. + uintptr_t UPB_ONLYBITS(data); + + size_t UPB_ONLYBITS(size); // The number of elements in the array. + size_t UPB_PRIVATE(capacity); // Allocated storage. Measured in elements. +}; + +UPB_INLINE void UPB_PRIVATE(_upb_Array_ShallowFreeze)(struct upb_Array* arr) { + arr->UPB_ONLYBITS(data) |= _UPB_ARRAY_MASK_IMM; +} + +UPB_API_INLINE bool upb_Array_IsFrozen(const struct upb_Array* arr) { + return (arr->UPB_ONLYBITS(data) & _UPB_ARRAY_MASK_IMM) != 0; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Array_SetTaggedPtr)(struct upb_Array* array, + void* data, size_t lg2) { + UPB_ASSERT(lg2 != 1); + UPB_ASSERT(lg2 <= 4); + const size_t bits = lg2 - (lg2 != 0); + array->UPB_ONLYBITS(data) = (uintptr_t)data | bits; +} + +UPB_INLINE size_t +UPB_PRIVATE(_upb_Array_ElemSizeLg2)(const struct upb_Array* array) { + const size_t bits = array->UPB_ONLYBITS(data) & _UPB_ARRAY_MASK_LG2; + const size_t lg2 = bits + (bits != 0); + return lg2; +} + +UPB_API_INLINE const void* upb_Array_DataPtr(const struct upb_Array* array) { + UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); // Check assertions. + return (void*)(array->UPB_ONLYBITS(data) & ~(uintptr_t)_UPB_ARRAY_MASK_ALL); +} + +UPB_API_INLINE void* upb_Array_MutableDataPtr(struct upb_Array* array) { + return (void*)upb_Array_DataPtr(array); +} + +UPB_INLINE struct upb_Array* UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)( + upb_Arena* arena, size_t init_capacity, int elem_size_lg2, + bool allow_slow) { + UPB_ASSERT(elem_size_lg2 != 1); + UPB_ASSERT(elem_size_lg2 <= 4); + const size_t array_size = + UPB_ALIGN_UP(sizeof(struct upb_Array), UPB_MALLOC_ALIGN); + const size_t bytes = array_size + (init_capacity << elem_size_lg2); + size_t span = UPB_PRIVATE(_upb_Arena_AllocSpan)(bytes); + if (!allow_slow && UPB_PRIVATE(_upb_ArenaHas)(arena) < span) return NULL; + struct upb_Array* array = (struct upb_Array*)upb_Arena_Malloc(arena, bytes); + if (!array) return NULL; + UPB_PRIVATE(_upb_Array_SetTaggedPtr) + (array, UPB_PTR_AT(array, array_size, void), (size_t)elem_size_lg2); + array->UPB_ONLYBITS(size) = 0; + array->UPB_PRIVATE(capacity) = init_capacity; + return array; +} + +UPB_INLINE struct upb_Array* UPB_PRIVATE(_upb_Array_New)(upb_Arena* arena, + size_t init_capacity, + int elem_size_lg2) { + return UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)(arena, init_capacity, + elem_size_lg2, true); +} + +UPB_INLINE struct upb_Array* UPB_PRIVATE(_upb_Array_TryFastNew)( + upb_Arena* arena, size_t init_capacity, int elem_size_lg2) { + return UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)(arena, init_capacity, + elem_size_lg2, false); +} + +// Resizes the capacity of the array to be at least min_size. +bool UPB_PRIVATE(_upb_Array_Realloc)(struct upb_Array* array, size_t min_size, + upb_Arena* arena); + +UPB_FORCEINLINE +bool UPB_PRIVATE(_upb_Array_TryFastRealloc)(struct upb_Array* array, + size_t capacity, int elem_size_lg2, + upb_Arena* arena) { + size_t old_bytes = array->UPB_PRIVATE(capacity) << elem_size_lg2; + size_t new_bytes = capacity << elem_size_lg2; + UPB_ASSUME(new_bytes > old_bytes); + if (!upb_Arena_TryExtend(arena, array, old_bytes, new_bytes)) return false; + array->UPB_PRIVATE(capacity) = capacity; + return true; +} + +UPB_API_INLINE bool upb_Array_Reserve(struct upb_Array* array, size_t size, + upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(array)); + if (array->UPB_PRIVATE(capacity) < size) + return UPB_PRIVATE(_upb_Array_Realloc)(array, size, arena); + return true; +} + +// Resize without initializing new elements. +UPB_INLINE bool UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + struct upb_Array* array, size_t size, upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(array)); + UPB_ASSERT(size <= array->UPB_ONLYBITS(size) || + arena); // Allow NULL arena when shrinking. + if (!upb_Array_Reserve(array, size, arena)) return false; + array->UPB_ONLYBITS(size) = size; + return true; +} + +// This function is intended for situations where elem_size is compile-time +// constant or a known expression of the form (1 << lg2), so that the expression +// i*elem_size does not result in an actual multiplication. +UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(struct upb_Array* array, size_t i, + const void* data, + size_t elem_size) { + UPB_ASSERT(!upb_Array_IsFrozen(array)); + UPB_ASSERT(i < array->UPB_ONLYBITS(size)); + UPB_ASSERT(elem_size == 1U << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array)); + char* arr_data = (char*)upb_Array_MutableDataPtr(array); + memcpy(arr_data + (i * elem_size), data, elem_size); +} + +UPB_API_INLINE size_t upb_Array_Size(const struct upb_Array* arr) { + return arr->UPB_ONLYBITS(size); +} + +UPB_API_INLINE size_t upb_Array_Capacity(const struct upb_Array* arr) { + return arr->UPB_PRIVATE(capacity); +} + +// LINT.ThenChange(GoogleInternalName0) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#undef _UPB_ARRAY_MASK_IMM +#undef _UPB_ARRAY_MASK_LG2 +#undef _UPB_ARRAY_MASK_ALL + + +#endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_TYPES_H_ +#define UPB_MESSAGE_INTERNAL_TYPES_H_ + +#include + +// Must be last. + +#define UPB_OPAQUE(x) x##_opaque + +struct upb_Message { + union { + uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen + double d; // Forces same size for 32-bit/64-bit builds + }; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(_upb_Message_ShallowFreeze)( + struct upb_Message* msg) { + msg->UPB_OPAQUE(internal) |= 1ULL; +} + +UPB_API_INLINE bool upb_Message_IsFrozen(const struct upb_Message* msg) { + return (msg->UPB_OPAQUE(internal) & 1ULL) != 0; +} + +UPB_INLINE struct upb_Message_Internal* UPB_PRIVATE(_upb_Message_GetInternal)( + const struct upb_Message* msg) { + const uintptr_t tmp = msg->UPB_OPAQUE(internal) & ~1ULL; + return (struct upb_Message_Internal*)tmp; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetInternal)( + struct upb_Message* msg, struct upb_Message_Internal* internal) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + msg->UPB_OPAQUE(internal) = (uintptr_t)internal; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#undef UPB_OPAQUE + + +#endif /* UPB_MESSAGE_INTERNAL_TYPES_H_ */ + +// Users should include array.h or map.h instead. +// IWYU pragma: private, include "upb/message/array.h" + +#ifndef UPB_MESSAGE_VALUE_H_ +#define UPB_MESSAGE_VALUE_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { + bool bool_val; + float float_val; + double double_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + const struct upb_Array* array_val; + const struct upb_Map* map_val; + const struct upb_Message* msg_val; + upb_StringView str_val; + + // For an extension field, we are essentially treating ext->data (a + // upb_MessageValue) as if it were a message with one field that lives at + // offset 0. This works because upb_MessageValue is precisely one value that + // can hold any type of data. Recall that an extension can be of any type + // (scalar, repeated, or message). For a message extension, that will be a + // single upb_Message* at offset 0 of the upb_MessageValue. + struct upb_Message UPB_PRIVATE(ext_msg_val); +} upb_MessageValue; + +UPB_API_INLINE upb_MessageValue upb_MessageValue_Zero(void) { + upb_MessageValue zero; + memset(&zero, 0, sizeof(zero)); + return zero; +} + +typedef union { + struct upb_Array* array; + struct upb_Map* map; + struct upb_Message* msg; +} upb_MutableMessageValue; + +UPB_API_INLINE upb_MutableMessageValue upb_MutableMessageValue_Zero(void) { + upb_MutableMessageValue zero; + memset(&zero, 0, sizeof(zero)); + return zero; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_VALUE_H_ */ + +#ifndef UPB_MINI_TABLE_MESSAGE_H_ +#define UPB_MINI_TABLE_MESSAGE_H_ + +#include + + +#ifndef UPB_MINI_TABLE_ENUM_H_ +#define UPB_MINI_TABLE_ENUM_H_ + +#include + + +#ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ +#define UPB_MINI_TABLE_INTERNAL_ENUM_H_ + +#include + +// Must be last. + +struct upb_MiniTableEnum { + uint32_t UPB_PRIVATE(mask_limit); // Highest that can be tested with mask. + uint32_t UPB_PRIVATE(value_count); // Number of values after the bitfield. + uint32_t UPB_PRIVATE(data)[]; // Bitmask + enumerated values follow. +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE bool upb_MiniTableEnum_CheckValue( + const struct upb_MiniTableEnum* e, uint32_t val) { + if (UPB_LIKELY(val < 64)) { + const uint64_t mask = + e->UPB_PRIVATE(data)[0] | ((uint64_t)e->UPB_PRIVATE(data)[1] << 32); + const uint64_t bit = 1ULL << val; + return (mask & bit) != 0; + } + if (UPB_LIKELY(val < e->UPB_PRIVATE(mask_limit))) { + const uint32_t mask = e->UPB_PRIVATE(data)[val / 32]; + const uint32_t bit = 1U << (val % 32); + return (mask & bit) != 0; + } + + // OPT: binary search long lists? + const uint32_t* start = + &e->UPB_PRIVATE(data)[e->UPB_PRIVATE(mask_limit) / 32]; + const uint32_t* limit = &e->UPB_PRIVATE( + data)[e->UPB_PRIVATE(mask_limit) / 32 + e->UPB_PRIVATE(value_count)]; + for (const uint32_t* p = start; p < limit; p++) { + if (*p == val) return true; + } + return false; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_ENUM_H_ */ + +// Must be last + +typedef struct upb_MiniTableEnum upb_MiniTableEnum; + +#ifdef __cplusplus +extern "C" { +#endif + +// Validates enum value against range defined by enum mini table. +UPB_API_INLINE bool upb_MiniTableEnum_CheckValue(const upb_MiniTableEnum* e, + uint32_t val); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_ENUM_H_ */ + +#ifndef UPB_MINI_TABLE_FIELD_H_ +#define UPB_MINI_TABLE_FIELD_H_ + +#include + + +#ifndef UPB_MINI_TABLE_INTERNAL_FIELD_H_ +#define UPB_MINI_TABLE_INTERNAL_FIELD_H_ + +#include +#include + + +#ifndef UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ +#define UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Return the log2 of the storage size in bytes for a upb_CType +UPB_INLINE int UPB_PRIVATE(_upb_CType_SizeLg2)(upb_CType c_type) { + static const int8_t size[] = { + 0, // kUpb_CType_Bool + 2, // kUpb_CType_Float + 2, // kUpb_CType_Int32 + 2, // kUpb_CType_UInt32 + 2, // kUpb_CType_Enum + UPB_SIZE(2, 3), // kUpb_CType_Message + 3, // kUpb_CType_Double + 3, // kUpb_CType_Int64 + 3, // kUpb_CType_UInt64 + UPB_SIZE(3, 4), // kUpb_CType_String + UPB_SIZE(3, 4), // kUpb_CType_Bytes + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[c_type - 1]; +} + +// Return the log2 of the storage size in bytes for a upb_FieldType +UPB_INLINE size_t +UPB_PRIVATE(_upb_FieldType_SizeLg2)(upb_FieldType field_type) { + static const int8_t size[] = { + 3, // kUpb_FieldType_Double + 2, // kUpb_FieldType_Float + 3, // kUpb_FieldType_Int64 + 3, // kUpb_FieldType_UInt64 + 2, // kUpb_FieldType_Int32 + 3, // kUpb_FieldType_Fixed64 + 2, // kUpb_FieldType_Fixed32 + 0, // kUpb_FieldType_Bool + UPB_SIZE(3, 4), // kUpb_FieldType_String + UPB_SIZE(2, 3), // kUpb_FieldType_Group + UPB_SIZE(2, 3), // kUpb_FieldType_Message + UPB_SIZE(3, 4), // kUpb_FieldType_Bytes + 2, // kUpb_FieldType_UInt32 + 2, // kUpb_FieldType_Enum + 2, // kUpb_FieldType_SFixed32 + 3, // kUpb_FieldType_SFixed64 + 2, // kUpb_FieldType_SInt32 + 3, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[field_type - 1]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ */ + +// Must be last. + +// LINT.IfChange(struct_definition) +struct upb_MiniTableField { + uint32_t UPB_ONLYBITS(number); + uint16_t UPB_ONLYBITS(offset); + int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index + + // Offset from this upb_MiniTableField to the upb_MiniTableSubInternal + // for this field, in uint32_t units (so bytes/4). + // Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM + uint16_t UPB_PRIVATE(submsg_ofs); + + uint8_t UPB_PRIVATE(descriptortype); + + // upb_FieldMode | upb_LabelFlags | (upb_FieldRep << kUpb_FieldRep_Shift) + uint8_t UPB_ONLYBITS(mode); +}; + +#define kUpb_NoSub ((uint16_t)-1) +#define kUpb_SubmsgOffsetBytes 4 + +typedef enum { + kUpb_FieldMode_Map = 0, + kUpb_FieldMode_Array = 1, + kUpb_FieldMode_Scalar = 2, +} upb_FieldMode; + +// Mask to isolate the upb_FieldMode from field.mode. +#define kUpb_FieldMode_Mask 3 + +// Extra flags on the mode field. +typedef enum { + kUpb_LabelFlags_IsPacked = 4, + kUpb_LabelFlags_IsExtension = 8, + // Indicates that this descriptor type is an "alternate type": + // - for Int32, this indicates that the actual type is Enum (but was + // rewritten to Int32 because it is an open enum that requires no check). + // - for Bytes, this indicates that the actual type is String (but does + // not require any UTF-8 check). + kUpb_LabelFlags_IsAlternate = 16, +} upb_LabelFlags; + +// Note: we sort by this number when calculating layout order. +typedef enum { + kUpb_FieldRep_1Byte = 0, + kUpb_FieldRep_4Byte = 1, + kUpb_FieldRep_StringView = 2, + kUpb_FieldRep_8Byte = 3, + + kUpb_FieldRep_NativePointer = + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte), + kUpb_FieldRep_Max = kUpb_FieldRep_8Byte, +} upb_FieldRep; + +#define kUpb_FieldRep_Shift 6 + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE upb_FieldMode +UPB_PRIVATE(_upb_MiniTableField_Mode)(const struct upb_MiniTableField* f) { + return (upb_FieldMode)(f->UPB_ONLYBITS(mode) & kUpb_FieldMode_Mask); +} + +UPB_INLINE upb_FieldRep +UPB_PRIVATE(_upb_MiniTableField_GetRep)(const struct upb_MiniTableField* f) { + return (upb_FieldRep)(f->UPB_ONLYBITS(mode) >> kUpb_FieldRep_Shift); +} + +UPB_API_INLINE bool upb_MiniTableField_IsArray( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Array; +} + +UPB_API_INLINE bool upb_MiniTableField_IsMap( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Map; +} + +UPB_API_INLINE bool upb_MiniTableField_IsScalar( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Scalar; +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsAlternate)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) != 0; +} + +UPB_API_INLINE bool upb_MiniTableField_IsExtension( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsExtension) != 0; +} + +UPB_API_INLINE bool upb_MiniTableField_IsPacked( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsPacked) != 0; +} + +UPB_API_INLINE upb_FieldType +upb_MiniTableField_Type(const struct upb_MiniTableField* f) { + const upb_FieldType type = (upb_FieldType)f->UPB_PRIVATE(descriptortype); + if (UPB_PRIVATE(_upb_MiniTableField_IsAlternate)(f)) { + if (type == kUpb_FieldType_Int32) return kUpb_FieldType_Enum; + if (type == kUpb_FieldType_Bytes) return kUpb_FieldType_String; + UPB_ASSERT(false); + } + return type; +} + +UPB_API_INLINE +upb_CType upb_MiniTableField_CType(const struct upb_MiniTableField* f) { + return upb_FieldType_CType(upb_MiniTableField_Type(f)); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_HasHasbit)( + const struct upb_MiniTableField* f) { + return f->presence > 0; +} + +UPB_INLINE char UPB_PRIVATE(_upb_MiniTableField_HasbitMask)( + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)); + const uint16_t index = (uint16_t)f->presence; + return (char)(1 << (index % 8)); +} + +UPB_INLINE uint16_t UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)( + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)); + const uint16_t index = (uint16_t)f->presence; + return index / 8; +} + +UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; +} + +UPB_API_INLINE bool upb_MiniTableField_IsInOneof( + const struct upb_MiniTableField* f) { + return f->presence < 0; +} + +UPB_API_INLINE bool upb_MiniTableField_IsSubMessage( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || + f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; +} + +UPB_API_INLINE bool upb_MiniTableField_HasPresence( + const struct upb_MiniTableField* f) { + if (upb_MiniTableField_IsExtension(f)) { + return upb_MiniTableField_IsScalar(f); + } else { + return f->presence != 0; + } +} + +UPB_API_INLINE uint32_t +upb_MiniTableField_Number(const struct upb_MiniTableField* f) { + return f->UPB_ONLYBITS(number); +} + +UPB_INLINE uint16_t +UPB_PRIVATE(_upb_MiniTableField_Offset)(const struct upb_MiniTableField* f) { + return f->UPB_ONLYBITS(offset); +} + +UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_OneofOffset)( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTableField_IsInOneof(f)); + return (size_t)(~(ptrdiff_t)f->presence); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsArray(f)); + UPB_ASSUME(f->presence == 0); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsMap(f)); + UPB_ASSUME(f->presence == 0); +} + +UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)( + const struct upb_MiniTableField* f) { + const upb_FieldType field_type = upb_MiniTableField_Type(f); + return UPB_PRIVATE(_upb_FieldType_SizeLg2)(field_type); +} + +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table_field.ts) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ + +// Must be last. + +typedef struct upb_MiniTableField upb_MiniTableField; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_HasPresence(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsArray(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( + const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsExtension(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsInOneof(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsMap(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsPacked(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsScalar(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsSubMessage( + const upb_MiniTableField* f); + +UPB_API_INLINE uint32_t upb_MiniTableField_Number(const upb_MiniTableField* f); + +UPB_API_INLINE upb_FieldType +upb_MiniTableField_Type(const upb_MiniTableField* f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_FIELD_H_ */ + +#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ + +#include +#include + + +#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ +#define UPB_MINI_TABLE_INTERNAL_SUB_H_ + +// Must be last. + +union upb_MiniTableSub { + const struct upb_MiniTable* UPB_PRIVATE(submsg); + const struct upb_MiniTableEnum* UPB_PRIVATE(subenum); +}; + +typedef union upb_MiniTableSub upb_MiniTableSubInternal; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE union upb_MiniTableSub upb_MiniTableSub_FromEnum( + const struct upb_MiniTableEnum* subenum) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(subenum) = subenum; + return out; +} + +UPB_API_INLINE union upb_MiniTableSub upb_MiniTableSub_FromMessage( + const struct upb_MiniTable* submsg) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(submsg) = submsg; + return out; +} + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(subenum); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(submsg); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ + +// Must be last. + +struct upb_Decoder; +struct upb_Message; + +typedef UPB_PRESERVE_NONE const char* _upb_FieldParser( + struct upb_Decoder* d, const char* ptr, struct upb_Message* msg, + intptr_t table, uint64_t hasbits, uint64_t data); + +typedef struct { + uint64_t field_data; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef enum { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} upb_ExtMode; + +enum { + kUpb_Message_Align = 8, +}; + +// upb_MiniTable represents the memory layout of a given upb_MessageDef. +// The members are public so generated code can initialize them, +// but users MUST NOT directly read or write any of its members. + +// LINT.IfChange(minitable_struct_definition) +struct upb_MiniTable { + const struct upb_MiniTableField* UPB_ONLYBITS(fields); + + // Must be aligned to kUpb_Message_Align. Doesn't include internal members + // like unknown fields, extension dict, pointer to msglayout, etc. + uint16_t UPB_PRIVATE(size); + + uint16_t UPB_ONLYBITS(field_count); + + uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1 + uint8_t UPB_PRIVATE(dense_below); + uint8_t UPB_PRIVATE(table_mask); + uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits. + +#ifdef UPB_TRACING_ENABLED + const char* UPB_PRIVATE(full_name); +#endif + +#if UPB_FASTTABLE || !defined(__cplusplus) + // Flexible array member is not supported in C++, but it is an extension in + // every compiler that supports UPB_FASTTABLE. + _upb_FastTable_Entry UPB_PRIVATE(fasttable)[]; +#endif +}; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table.ts) + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(upb_MiniTable_CheckInvariants)( + const struct upb_MiniTable* mt) { + UPB_STATIC_ASSERT(UPB_MALLOC_ALIGN >= kUpb_Message_Align, "Under aligned"); + UPB_STATIC_ASSERT(kUpb_Message_Align >= UPB_ALIGN_OF(void*), "Under aligned"); + UPB_ASSERT(mt->UPB_PRIVATE(size) % kUpb_Message_Align == 0); +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTable_StrongReference)(const struct upb_MiniTable* mt) { +#if defined(__GNUC__) + __asm__("" : : "r"(mt)); +#else + const struct upb_MiniTable* volatile unused = mt; + (void)&unused; // Use address to avoid an extra load of "unused". +#endif + return mt; +} + +UPB_API_INLINE int upb_MiniTable_FieldCount(const struct upb_MiniTable* m) { + return m->UPB_ONLYBITS(field_count); +} + +UPB_API_INLINE bool upb_MiniTable_IsMessageSet(const struct upb_MiniTable* m) { + return m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet; +} + +UPB_API_INLINE +const struct upb_MiniTableField* upb_MiniTable_FindFieldByNumber( + const struct upb_MiniTable* m, uint32_t number) { + const uint32_t i = number - 1; // 0 wraps to UINT32_MAX + + // Ideal case: index into dense fields + if (i < m->UPB_PRIVATE(dense_below)) { + UPB_ASSERT(m->UPB_ONLYBITS(fields)[i].UPB_ONLYBITS(number) == number); + return &m->UPB_ONLYBITS(fields)[i]; + } + + // Early exit if the field number is out of range. + int32_t hi = m->UPB_ONLYBITS(field_count) - 1; + if (hi < 0 || number > m->UPB_ONLYBITS(fields)[hi].UPB_ONLYBITS(number)) { + return NULL; + } + + // Slow case: binary search + uint32_t lo = m->UPB_PRIVATE(dense_below); + const struct upb_MiniTableField* base = m->UPB_ONLYBITS(fields); + while (hi >= (int32_t)lo) { + uint32_t mid = ((uint32_t)hi + lo) / 2; + uint32_t num = base[mid].UPB_ONLYBITS(number); + // These comparison operations allow, on ARM machines, to fuse all these + // branches into one comparison followed by two CSELs to set the lo/hi + // values, followed by a BNE to continue or terminate the loop. Since binary + // search branches are generally unpredictable (50/50 in each direction), + // this is a good deal. We use signed for the high, as this decrement may + // underflow if mid is 0. + int32_t hi_mid = (int32_t)mid - 1; + uint32_t lo_mid = mid + 1; + if (num == number) { + return &base[mid]; + } + if (UPB_UNPREDICTABLE(num < number)) { + lo = lo_mid; + } else { + hi = hi_mid; + } + } + + return NULL; +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_GetFieldByIndex( + const struct upb_MiniTable* m, uint32_t i) { + UPB_ASSERT(i < m->UPB_ONLYBITS(field_count)); + return &m->UPB_ONLYBITS(fields)[i]; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_GetSubMessageTable( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Message); + upb_MiniTableSubInternal* sub = + UPB_PTR_AT(f, f->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + return sub->UPB_PRIVATE(submsg); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_SubMessage( + const struct upb_MiniTableField* f) { + if (upb_MiniTableField_CType(f) != kUpb_CType_Message) { + return NULL; + } + return upb_MiniTable_GetSubMessageTable(f); +} + +UPB_API_INLINE bool upb_MiniTable_FieldIsLinked( + const struct upb_MiniTableField* f) { + return upb_MiniTable_GetSubMessageTable(f) != NULL; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_MapEntrySubMessage( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTable_FieldIsLinked(f)); // Map entries must be linked. + UPB_ASSERT(upb_MiniTableField_IsMap(f)); // Function precondition. + return upb_MiniTable_GetSubMessageTable(f); +} + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Enum); + upb_MiniTableSubInternal* sub = + UPB_PTR_AT(f, f->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + return sub->UPB_PRIVATE(subenum); +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_MapKey( + const struct upb_MiniTable* m) { + UPB_ASSERT(upb_MiniTable_FieldCount(m) == 2); + const struct upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, 0); + UPB_ASSERT(upb_MiniTableField_Number(f) == 1); + return f; +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_MapValue( + const struct upb_MiniTable* m) { + UPB_ASSERT(upb_MiniTable_FieldCount(m) == 2); + const struct upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, 1); + UPB_ASSERT(upb_MiniTableField_Number(f) == 2); + return f; +} + +// Computes a bitmask in which the |m->required_count| lowest bits are set. +// +// Sample output: +// RequiredMask(1) => 0b1 (0x1) +// RequiredMask(5) => 0b11111 (0x1f) +UPB_INLINE uint64_t +UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) { + int n = m->UPB_PRIVATE(required_count); + UPB_ASSERT(0 < n && n <= 64); + return (1ULL << n) - 1; +} + +#ifdef UPB_TRACING_ENABLED +UPB_INLINE const char* upb_MiniTable_FullName( + const struct upb_MiniTable* mini_table) { + return mini_table->UPB_PRIVATE(full_name); +} +// Initializes tracing proto name from language runtimes that construct +// mini tables dynamically at runtime. The runtime is responsible for passing +// controlling lifetime of name such as storing in same arena as mini_table. +UPB_INLINE void upb_MiniTable_SetFullName(struct upb_MiniTable* mini_table, + const char* full_name) { + mini_table->UPB_PRIVATE(full_name) = full_name; +} +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ + +// Must be last. + +typedef struct upb_MiniTable upb_MiniTable; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( + const upb_MiniTable* m, uint32_t number); + +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( + const upb_MiniTable* m, uint32_t index); + +UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m); + +UPB_API_INLINE bool upb_MiniTable_IsMessageSet(const upb_MiniTable* m); + +// DEPRECATED: use upb_MiniTable_SubMessage() instead +// Returns the MiniTable for a message field, NULL if the field is unlinked. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( + const upb_MiniTableField* f); + +// Returns the MiniTable for a message field if it is a submessage and the field +// is linked, otherwise returns NULL. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_SubMessage( + const upb_MiniTableField* f); + +// Returns the MiniTable for a map field. The given field must refer to a map. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_MapEntrySubMessage( + const upb_MiniTableField* f); + +// Returns the MiniTableEnum for a message field, NULL if the field is unlinked. +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( + const upb_MiniTableField* f); + +// Returns the MiniTableField for the key of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapKey( + const upb_MiniTable* m); + +// Returns the MiniTableField for the value of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapValue( + const upb_MiniTable* m); + +// Returns true if this MiniTable field is linked to a MiniTable for the +// sub-message. +UPB_API_INLINE bool upb_MiniTable_FieldIsLinked(const upb_MiniTableField* f); + +// If this field is in a oneof, returns the first field in the oneof. +// +// Otherwise returns NULL. +// +// Usage: +// const upb_MiniTableField* field = upb_MiniTable_GetOneof(m, f); +// do { +// .. +// } while (upb_MiniTable_NextOneofField(m, &field); +// +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f); + +// Iterates to the next field in the oneof. If this is the last field in the +// oneof, returns false. The ordering of fields in the oneof is not +// guaranteed. +// REQUIRES: |f| is the field initialized by upb_MiniTable_GetOneof and updated +// by prior upb_MiniTable_NextOneofField calls. +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +// Temporary overloads for functions whose signature has recently changed. +UPB_DEPRECATE_AND_INLINE() +inline const upb_MiniTable* upb_MiniTable_SubMessage( + const upb_MiniTable* m, const upb_MiniTableField* f) { + return upb_MiniTable_SubMessage(f); +} + +UPB_DEPRECATE_AND_INLINE() +inline const upb_MiniTable* upb_MiniTable_GetSubMessageTable( + const upb_MiniTable* m, const upb_MiniTableField* f) { + return upb_MiniTable_GetSubMessageTable(f); +} + +UPB_DEPRECATE_AND_INLINE() +inline const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( + const upb_MiniTable* m, const upb_MiniTableField* f) { + return upb_MiniTable_GetSubEnumTable(f); +} + +UPB_DEPRECATE_AND_INLINE() +inline bool upb_MiniTable_FieldIsLinked(const upb_MiniTable* m, + const upb_MiniTableField* f) { + return upb_MiniTable_FieldIsLinked(f); +} +#endif + + +#endif /* UPB_MINI_TABLE_MESSAGE_H_ */ + +// Must be last. + +typedef struct upb_Array upb_Array; + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates a new array on the given arena that holds elements of this type. +UPB_API upb_Array* upb_Array_New(upb_Arena* a, upb_CType type); + +// Returns the number of elements in the array. +UPB_API_INLINE size_t upb_Array_Size(const upb_Array* arr); + +// Returns the number of elements in the array. +UPB_API_INLINE size_t upb_Array_Capacity(const upb_Array* arr); + +// Returns the given element, which must be within the array's current size. +UPB_API upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i); + +// Returns a non-null mutating pointer to the given element. `arr` must be an +// array of a message type, and `i` must be within the array's current size. +UPB_API struct upb_Message* upb_Array_GetMutable(upb_Array* arr, size_t i); + +// Sets the given element, which must be within the array's current size. +UPB_API void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val); + +// Appends an element to the array. Returns false on allocation failure. +UPB_API bool upb_Array_Append(upb_Array* array, upb_MessageValue val, + upb_Arena* arena); + +// Copies elements from |src| to |dst|, resizing |dst| to match |src| size. +// Returns false on allocation failure. +UPB_API bool upb_Array_Copy(upb_Array* dst, const upb_Array* src, + upb_Arena* arena); + +// Appends all elements from |src| to the end of |dst|. +// Returns false on allocation failure. +UPB_API bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src, + upb_Arena* arena); + +// Moves elements within the array using memmove(). +// Like memmove(), the source and destination elements may be overlapping. +UPB_API void upb_Array_Move(upb_Array* array, size_t dst_idx, size_t src_idx, + size_t count); + +// Inserts one or more empty elements into the array. +// Existing elements are shifted right. +// The new elements have undefined state and must be set with `upb_Array_Set()`. +// REQUIRES: `i <= upb_Array_Size(arr)` +UPB_API bool upb_Array_Insert(upb_Array* array, size_t i, size_t count, + upb_Arena* arena); + +// Deletes one or more elements from the array. +// Existing elements are shifted left. +// REQUIRES: `i + count <= upb_Array_Size(arr)` +UPB_API void upb_Array_Delete(upb_Array* array, size_t i, size_t count); + +// Reserves |size| elements of storage for the array. +UPB_API_INLINE bool upb_Array_Reserve(struct upb_Array* array, size_t size, + upb_Arena* arena); + +// Changes the size of a vector. New elements are initialized to NULL/0. +// Returns false on allocation failure. +UPB_API bool upb_Array_Resize(upb_Array* array, size_t size, upb_Arena* arena); + +// Returns pointer to array data. +UPB_API_INLINE const void* upb_Array_DataPtr(const upb_Array* arr); + +// Returns mutable pointer to array data. +UPB_API_INLINE void* upb_Array_MutableDataPtr(upb_Array* arr); + +// Mark an array and all of its descendents as frozen/immutable. +// If the array elements are messages then |m| must point to the minitable for +// those messages. Otherwise |m| must be NULL. +UPB_API void upb_Array_Freeze(upb_Array* arr, const upb_MiniTable* m); + +// Returns whether an array has been frozen. +UPB_API_INLINE bool upb_Array_IsFrozen(const upb_Array* arr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_ARRAY_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_ACCESSORS_H_ +#define UPB_MESSAGE_INTERNAL_ACCESSORS_H_ + +#include +#include +#include + + +#ifndef UPB_BASE_INTERNAL_ENDIAN_H_ +#define UPB_BASE_INTERNAL_ENDIAN_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE bool upb_IsLittleEndian(void) { + const int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t upb_BigEndian32(uint32_t val) { + if (upb_IsLittleEndian()) return val; + + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); +} + +UPB_INLINE uint64_t upb_BigEndian64(uint64_t val) { + if (upb_IsLittleEndian()) return val; + + const uint64_t hi = ((uint64_t)upb_BigEndian32((uint32_t)val)) << 32; + const uint64_t lo = upb_BigEndian32((uint32_t)(val >> 32)); + return hi | lo; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_INTERNAL_ENDIAN_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_EXTENSION_H_ +#define UPB_MESSAGE_INTERNAL_EXTENSION_H_ + +#include + + +#ifndef UPB_MESSAGE_INTERNAL_MAP_H_ +#define UPB_MESSAGE_INTERNAL_MAP_H_ + +#include +#include +#include + + +/* + * upb_table + * + * This header is INTERNAL-ONLY! Its interfaces are not public or stable! + * This file defines very fast int->upb_value (inttable) and string->upb_value + * (strtable) hash tables. + * + * The table uses chained scatter with Brent's variation (inspired by the Lua + * implementation of hash tables). The hash function for strings is Austin + * Appleby's "MurmurHash." + * + * The inttable uses uintptr_t as its key, which guarantees it can be used to + * store pointers or integers of at least 32 bits (upb isn't really useful on + * systems where sizeof(void*) < 4). + * + * The table must be homogeneous (all values of the same type). In debug + * mode, we check this on insert and lookup. + */ + +#ifndef UPB_HASH_COMMON_H_ +#define UPB_HASH_COMMON_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* upb_value ******************************************************************/ + +typedef struct { + uint64_t val; +} upb_value; + +/* For each value ctype, define the following set of functions: + * + * // Get/set an int32 from a upb_value. + * int32_t upb_value_getint32(upb_value val); + * void upb_value_setint32(upb_value *val, int32_t cval); + * + * // Construct a new upb_value from an int32. + * upb_value upb_value_int32(int32_t val); */ +#define FUNCS(name, membername, type_t, converter) \ + UPB_INLINE void upb_value_set##name(upb_value* val, type_t cval) { \ + val->val = (uint64_t)cval; \ + } \ + UPB_INLINE upb_value upb_value_##name(type_t val) { \ + upb_value ret; \ + upb_value_set##name(&ret, val); \ + return ret; \ + } \ + UPB_INLINE type_t upb_value_get##name(upb_value val) { \ + return (type_t)(converter)val.val; \ + } + +FUNCS(int32, int32, int32_t, int32_t) +FUNCS(int64, int64, int64_t, int64_t) +FUNCS(uint32, uint32, uint32_t, uint32_t) +FUNCS(uint64, uint64, uint64_t, uint64_t) +FUNCS(bool, _bool, bool, bool) +FUNCS(cstr, cstr, char*, uintptr_t) +FUNCS(uintptr, uptr, uintptr_t, uintptr_t) +FUNCS(ptr, ptr, void*, uintptr_t) +FUNCS(constptr, constptr, const void*, uintptr_t) + +#undef FUNCS + +UPB_INLINE void upb_value_setfloat(upb_value* val, float cval) { + memcpy(&val->val, &cval, sizeof(cval)); +} + +UPB_INLINE void upb_value_setdouble(upb_value* val, double cval) { + memcpy(&val->val, &cval, sizeof(cval)); +} + +UPB_INLINE upb_value upb_value_float(float cval) { + upb_value ret; + upb_value_setfloat(&ret, cval); + return ret; +} + +UPB_INLINE upb_value upb_value_double(double cval) { + upb_value ret; + upb_value_setdouble(&ret, cval); + return ret; +} + +/* upb_key *****************************************************************/ + +// A uint32 size followed by that number of bytes stored contiguously. +typedef struct { + uint32_t size; + const char data[]; +} upb_SizePrefixString; + +/* Either: + * 1. an actual integer key + * 2. a SizePrefixString*, owned by us. + * + * ...depending on whether this is a string table or an int table. */ +typedef union { + uintptr_t num; + const upb_SizePrefixString* str; +} upb_key; + +UPB_INLINE upb_StringView upb_key_strview(upb_key key) { + return upb_StringView_FromDataAndSize(key.str->data, key.str->size); +} + +/* upb_table ******************************************************************/ + +typedef struct _upb_tabent { + upb_value val; + upb_key key; + + /* Internal chaining. This is const so we can create static initializers for + * tables. We cast away const sometimes, but *only* when the containing + * upb_table is known to be non-const. This requires a bit of care, but + * the subtlety is confined to table.c. */ + const struct _upb_tabent* next; +} upb_tabent; + +typedef struct { + upb_tabent* entries; + /* Number of entries in the hash part. */ + uint32_t count; + + /* Mask to turn hash value -> bucket. The map's allocated size is mask + 1.*/ + uint32_t mask; +} upb_table; + +UPB_INLINE size_t upb_table_size(const upb_table* t) { return t->mask + 1; } + +// Internal-only functions, in .h file only out of necessity. + +UPB_INLINE upb_key upb_key_empty(void) { + upb_key ret; + memset(&ret, 0, sizeof(upb_key)); + return ret; +} + +UPB_INLINE bool upb_tabent_isempty(const upb_tabent* e) { + upb_key key = e->key; + UPB_STATIC_ASSERT(sizeof(key.num) == sizeof(key.str), "Sizes don't match"); + uintptr_t val; + memcpy(&val, &key, sizeof(val)); + // Note: for upb_inttables a tab_key is a true integer key value, but the + // inttable maintains the invariant that 0 value is always stored in the + // compact table and never as a upb_tabent* so we can always use the 0 + // key value to identify an empty tabent. + return val == 0; +} + +uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_COMMON_H_ */ + +#ifndef UPB_HASH_INT_TABLE_H_ +#define UPB_HASH_INT_TABLE_H_ + +#include +#include + + +// Must be last. + +typedef struct { + upb_table t; // For entries that don't fit in the array part. + // Array part of the table. + // Pointers on this table are const so we can create static initializers for + // tables. We cast away const sometimes, but *only* when the containing + // upb_table is known to be non-const. This requires a bit of care, but + // the subtlety is confined to table.c. + const upb_value* array; + // Track presence in the array part. Each bit at index (key % 8) at the + // presence_mask[key/8] indicates if the element is present in the array part. + const uint8_t* presence_mask; + uint32_t array_size; // Array part size. + uint32_t array_count; // Array part number of elements. +} upb_inttable; + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize a table. If memory allocation failed, false is returned and +// the table is uninitialized. +bool upb_inttable_init(upb_inttable* table, upb_Arena* a); + +// Returns the number of values in the table. +size_t upb_inttable_count(const upb_inttable* t); + +// Inserts the given key into the hashtable with the given value. +// The key must not already exist in the hash table. +// The value must not be UINTPTR_MAX. +// +// If a table resize was required but memory allocation failed, false is +// returned and the table is unchanged. +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a); + +// Looks up key in this table, returning "true" if the key was found. +// If v is non-NULL, copies the value for this key into *v. +bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v); + +// Removes an item from the table. Returns true if the remove was successful, +// and stores the removed item in *val if non-NULL. +bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val); + +// Updates an existing entry in an inttable. +// If the entry does not exist, returns false and does nothing. +// Unlike insert/remove, this does not invalidate iterators. +bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val); + +// Optimizes the table for the current set of entries, for both memory use and +// lookup time. Client should call this after all entries have been inserted; +// inserting more entries is legal, but will likely require a table resize. +// Returns false if reallocation fails. +bool upb_inttable_compact(upb_inttable* t, upb_Arena* a); + +// Clears the table. +void upb_inttable_clear(upb_inttable* t); + +// Iteration over inttable: +// +// intptr_t iter = UPB_INTTABLE_BEGIN; +// uintptr_t key; +// upb_value val; +// while (upb_inttable_next(t, &key, &val, &iter)) { +// // ... +// } + +#define UPB_INTTABLE_BEGIN -1 + +bool upb_inttable_next(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter); +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter); +void upb_inttable_setentryvalue(upb_inttable* t, intptr_t iter, upb_value v); +bool upb_inttable_done(const upb_inttable* t, intptr_t i); +uintptr_t upb_inttable_iter_key(const upb_inttable* t, intptr_t iter); +upb_value upb_inttable_iter_value(const upb_inttable* t, intptr_t iter); + +UPB_INLINE bool upb_inttable_arrhas(const upb_inttable* t, uintptr_t key) { + return (t->presence_mask[key / 8] & (1 << (key % 8))) != 0; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_INT_TABLE_H_ */ + +#ifndef UPB_HASH_STR_TABLE_H_ +#define UPB_HASH_STR_TABLE_H_ + +#include +#include +#include + + +// Must be last. + +typedef struct { + upb_table t; +} upb_strtable; + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize a table. If memory allocation failed, false is returned and +// the table is uninitialized. +bool upb_strtable_init(upb_strtable* table, size_t expected_size, upb_Arena* a); + +// Returns the number of values in the table. +UPB_INLINE size_t upb_strtable_count(const upb_strtable* t) { + return t->t.count; +} + +void upb_strtable_clear(upb_strtable* t); + +// Inserts the given key into the hashtable with the given value. +// The key must not already exist in the hash table. The key is not required +// to be NULL-terminated, and the table will make an internal copy of the key. +// +// If a table resize was required but memory allocation failed, false is +// returned and the table is unchanged. */ +bool upb_strtable_insert(upb_strtable* t, const char* key, size_t len, + upb_value val, upb_Arena* a); + +// Looks up key in this table, returning "true" if the key was found. +// If v is non-NULL, copies the value for this key into *v. +bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, + upb_value* v); + +// For NULL-terminated strings. +UPB_INLINE bool upb_strtable_lookup(const upb_strtable* t, const char* key, + upb_value* v) { + return upb_strtable_lookup2(t, key, strlen(key), v); +} + +// Removes an item from the table. Returns true if the remove was successful, +// and stores the removed item in *val if non-NULL. +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val); + +UPB_INLINE bool upb_strtable_remove(upb_strtable* t, const char* key, + upb_value* v) { + return upb_strtable_remove2(t, key, strlen(key), v); +} + +// Exposed for testing only. +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a); + +/* Iteration over strtable: + * + * intptr_t iter = UPB_STRTABLE_BEGIN; + * upb_StringView key; + * upb_value val; + * while (upb_strtable_next2(t, &key, &val, &iter)) { + * // ... + * } + */ + +#define UPB_STRTABLE_BEGIN -1 + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter); +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter); +void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v); + +/* DEPRECATED iterators, slated for removal. + * + * Iterators for string tables. We are subject to some kind of unusual + * design constraints: + * + * For high-level languages: + * - we must be able to guarantee that we don't crash or corrupt memory even if + * the program accesses an invalidated iterator. + * + * For C++11 range-based for: + * - iterators must be copyable + * - iterators must be comparable + * - it must be possible to construct an "end" value. + * + * Iteration order is undefined. + * + * Modifying the table invalidates iterators. upb_{str,int}table_done() is + * guaranteed to work even on an invalidated iterator, as long as the table it + * is iterating over has not been freed. Calling next() or accessing data from + * an invalidated iterator yields unspecified elements from the table, but it is + * guaranteed not to crash and to return real table elements (except when done() + * is true). */ +/* upb_strtable_iter **********************************************************/ + +/* upb_strtable_iter i; + * upb_strtable_begin(&i, t); + * for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { + * const char *key = upb_strtable_iter_key(&i); + * const upb_value val = upb_strtable_iter_value(&i); + * // ... + * } + */ + +typedef struct { + const upb_strtable* t; + size_t index; +} upb_strtable_iter; + +UPB_INLINE const upb_tabent* str_tabent(const upb_strtable_iter* i) { + return &i->t->t.entries[i->index]; +} + +void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t); +void upb_strtable_next(upb_strtable_iter* i); +bool upb_strtable_done(const upb_strtable_iter* i); +upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i); +upb_value upb_strtable_iter_value(const upb_strtable_iter* i); +void upb_strtable_iter_setdone(upb_strtable_iter* i); +bool upb_strtable_iter_isequal(const upb_strtable_iter* i1, + const upb_strtable_iter* i2); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_STR_TABLE_H_ */ + +// Must be last. + +typedef enum { + kUpb_MapInsertStatus_Inserted = 0, + kUpb_MapInsertStatus_Replaced = 1, + kUpb_MapInsertStatus_OutOfMemory = 2, +} upb_MapInsertStatus; + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +union upb_Map_Table { + upb_strtable strtable; + upb_inttable inttable; +}; + +struct upb_Map { + // Size of key and val, based on the map type. + // Strings are represented as '0' because they must be handled specially. + char key_size; + char val_size; + bool UPB_PRIVATE(is_frozen); + bool UPB_PRIVATE(is_strtable); + + union upb_Map_Table t; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(_upb_Map_ShallowFreeze)(struct upb_Map* map) { + map->UPB_PRIVATE(is_frozen) = true; +} + +UPB_API_INLINE bool upb_Map_IsFrozen(const struct upb_Map* map) { + return map->UPB_PRIVATE(is_frozen); +} + +// Converting between internal table representation and user values. +// +// _upb_map_tokey() and _upb_map_fromkey() are inverses. +// _upb_map_tovalue() and _upb_map_fromvalue() are inverses. +// +// These functions account for the fact that strings are treated differently +// from other types when stored in a map. + +UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + return *(upb_StringView*)key; + } else { + return upb_StringView_FromDataAndSize((const char*)key, size); + } +} + +UPB_INLINE uintptr_t _upb_map_tointkey(const void* key, size_t key_size) { + uintptr_t intkey = 0; + memcpy(&intkey, key, key_size); + return intkey; +} + +UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + memcpy(out, &key, sizeof(key)); + } else { + memcpy(out, key.data, size); + } +} + +UPB_INLINE bool _upb_map_tovalue(const void* val, size_t size, + upb_value* msgval, upb_Arena* a) { + if (size == UPB_MAPTYPE_STRING) { + upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp)); + if (!strp) return false; + *strp = *(upb_StringView*)val; + *msgval = upb_value_ptr(strp); + } else { + memcpy(msgval, val, size); + } + return true; +} + +UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_StringView)); + } else { + memcpy(out, &val, size); + } +} + +UPB_INLINE bool _upb_map_next(const struct upb_Map* map, size_t* iter) { + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter it; + it.t = &map->t.strtable; + it.index = *iter; + upb_strtable_next(&it); + *iter = it.index; + return !upb_strtable_done(&it); + } else { + uintptr_t key; + upb_value val; + intptr_t int_iter = 0; + memcpy(&int_iter, iter, sizeof(intptr_t)); + upb_inttable_next(&map->t.inttable, &key, &val, &int_iter); + memcpy(iter, &int_iter, sizeof(size_t)); + return !upb_inttable_done(&map->t.inttable, int_iter); + } +} + +UPB_INLINE void _upb_Map_Clear(struct upb_Map* map) { + UPB_ASSERT(!upb_Map_IsFrozen(map)); + + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_clear(&map->t.strtable); + } else { + upb_inttable_clear(&map->t.inttable); + } +} + +UPB_INLINE bool _upb_Map_Delete(struct upb_Map* map, const void* key, + size_t key_size, upb_value* val) { + UPB_ASSERT(!upb_Map_IsFrozen(map)); + + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView k = _upb_map_tokey(key, key_size); + return upb_strtable_remove2(&map->t.strtable, k.data, k.size, val); + } else { + uintptr_t intkey = _upb_map_tointkey(key, key_size); + return upb_inttable_remove(&map->t.inttable, intkey, val); + } +} + +UPB_INLINE bool _upb_Map_Get(const struct upb_Map* map, const void* key, + size_t key_size, void* val, size_t val_size) { + upb_value tabval = {0}; + bool ret; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView k = _upb_map_tokey(key, key_size); + ret = upb_strtable_lookup2(&map->t.strtable, k.data, k.size, &tabval); + } else { + uintptr_t intkey = _upb_map_tointkey(key, key_size); + ret = upb_inttable_lookup(&map->t.inttable, intkey, &tabval); + } + if (ret && val) { + _upb_map_fromvalue(tabval, val, val_size); + } + return ret; +} + +UPB_INLINE upb_MapInsertStatus _upb_Map_Insert(struct upb_Map* map, + const void* key, size_t key_size, + void* val, size_t val_size, + upb_Arena* a) { + UPB_ASSERT(!upb_Map_IsFrozen(map)); + + // Prep the value. + upb_value tabval = {0}; + if (!_upb_map_tovalue(val, val_size, &tabval, a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + + bool removed; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView strkey = _upb_map_tokey(key, key_size); + // TODO: add overwrite operation to minimize number of lookups. + removed = + upb_strtable_remove2(&map->t.strtable, strkey.data, strkey.size, NULL); + if (!upb_strtable_insert(&map->t.strtable, strkey.data, strkey.size, tabval, + a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + } else { + uintptr_t intkey = _upb_map_tointkey(key, key_size); + removed = upb_inttable_remove(&map->t.inttable, intkey, NULL); + if (!upb_inttable_insert(&map->t.inttable, intkey, tabval, a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + } + return removed ? kUpb_MapInsertStatus_Replaced + : kUpb_MapInsertStatus_Inserted; +} + +UPB_INLINE size_t _upb_Map_Size(const struct upb_Map* map) { + if (map->UPB_PRIVATE(is_strtable)) { + return map->t.strtable.t.count; + } else { + return upb_inttable_count(&map->t.inttable); + } +} + +// Strings/bytes are special-cased in maps. +extern char _upb_Map_CTypeSizeTable[12]; + +UPB_INLINE size_t _upb_Map_CTypeSize(upb_CType ctype) { + return (size_t)_upb_Map_CTypeSizeTable[ctype]; +} + +// Creates a new map on the given arena with this key/value type. +struct upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_MAP_H_ */ + +#ifndef UPB_MINI_TABLE_EXTENSION_H_ +#define UPB_MINI_TABLE_EXTENSION_H_ + +#include + + +#ifndef UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ +#define UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ + +#include +#include + + +// Must be last. + +struct upb_MiniTableExtension { + // Do not move this field. We need to be able to alias pointers. + struct upb_MiniTableField UPB_PRIVATE(field); + + union upb_MiniTableSub UPB_PRIVATE(sub); // NULL unless submsg or proto2 enum + const struct upb_MiniTable* UPB_PRIVATE(extendee); +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_CType +upb_MiniTableExtension_CType(const struct upb_MiniTableExtension* e) { + return upb_MiniTableField_CType(&e->UPB_PRIVATE(field)); +} + +UPB_API_INLINE uint32_t +upb_MiniTableExtension_Number(const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(field).UPB_ONLYBITS(number); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableExtension_Extendee( + const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(extendee); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableExtension_GetSubMessage( + const struct upb_MiniTableExtension* e) { + if (upb_MiniTableExtension_CType(e) != kUpb_CType_Message) { + return NULL; + } + return upb_MiniTableSub_Message(e->UPB_PRIVATE(sub)); +} + +UPB_API_INLINE const struct upb_MiniTableEnum* +upb_MiniTableExtension_GetSubEnum(const struct upb_MiniTableExtension* e) { + if (upb_MiniTableExtension_CType(e) != kUpb_CType_Enum) { + return NULL; + } + return upb_MiniTableSub_Enum(e->UPB_PRIVATE(sub)); +} + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubMessage( + struct upb_MiniTableExtension* e, const struct upb_MiniTable* m) { + if (e->UPB_PRIVATE(field).UPB_PRIVATE(descriptortype) != + kUpb_FieldType_Message && + e->UPB_PRIVATE(field).UPB_PRIVATE(descriptortype) != + kUpb_FieldType_Group) { + return false; + } + e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg) = m; + return true; +} + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubEnum( + struct upb_MiniTableExtension* e, const struct upb_MiniTableEnum* en) { + if (e->UPB_PRIVATE(field).UPB_PRIVATE(descriptortype) != + kUpb_FieldType_Enum) { + return false; + } + e->UPB_PRIVATE(sub).UPB_PRIVATE(subenum) = en; + return true; +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTableExtension_ToField( + const struct upb_MiniTableExtension* e) { + return &e->UPB_PRIVATE(field); +} + +UPB_INLINE upb_FieldRep UPB_PRIVATE(_upb_MiniTableExtension_GetRep)( + const struct upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableField_GetRep)(&e->UPB_PRIVATE(field)); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ */ + +// Must be last. + +typedef struct upb_MiniTableExtension upb_MiniTableExtension; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_CType +upb_MiniTableExtension_CType(const upb_MiniTableExtension* e); + +UPB_API_INLINE uint32_t +upb_MiniTableExtension_Number(const upb_MiniTableExtension* e); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableExtension_Extendee( + const upb_MiniTableExtension* e); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableExtension_GetSubMessage( + const upb_MiniTableExtension* e); + +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTableExtension_GetSubEnum( + const upb_MiniTableExtension* e); + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubMessage( + upb_MiniTableExtension* e, const upb_MiniTable* m); + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubEnum( + upb_MiniTableExtension* e, const upb_MiniTableEnum* m); + +UPB_API_INLINE const upb_MiniTableField* upb_MiniTableExtension_ToField( + const upb_MiniTableExtension* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_EXTENSION_H_ */ + +// Must be last. + +// The internal representation of an extension is self-describing: it contains +// enough information that we can serialize it to binary format without needing +// to look it up in a upb_ExtensionRegistry. +// +// This representation allocates 16 bytes to data on 64-bit platforms. +// This is rather wasteful for scalars (in the extreme case of bool, +// it wastes 15 bytes). We accept this because we expect messages to be +// the most common extension type. +typedef struct { + const upb_MiniTableExtension* ext; + upb_MessageValue data; +} upb_Extension; + +#ifdef __cplusplus +extern "C" { +#endif + +// Adds the given extension data to the given message. +// |ext| is copied into the message instance. +// This logically replaces any previously-added extension with this number. +upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + struct upb_Message* msg, const upb_MiniTableExtension* ext, + upb_Arena* arena); + +// Returns an extension for a message with a given mini table, +// or NULL if no extension exists with this mini table. +const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)( + const struct upb_Message* msg, const upb_MiniTableExtension* ext); + +UPB_INLINE bool UPB_PRIVATE(_upb_Extension_IsEmpty)(const upb_Extension* ext) { + switch ( + UPB_PRIVATE(_upb_MiniTableField_Mode)(&ext->ext->UPB_PRIVATE(field))) { + case kUpb_FieldMode_Scalar: + return false; + case kUpb_FieldMode_Array: + return upb_Array_Size(ext->data.array_val) == 0; + case kUpb_FieldMode_Map: + return _upb_Map_Size(ext->data.map_val) == 0; + } + UPB_UNREACHABLE(); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_EXTENSION_H_ */ + +/* +** Our memory representation for parsing tables and messages themselves. +** Functions in this file are used by generated code and possibly reflection. +** +** The definitions in this file are internal to upb. +**/ + +#ifndef UPB_MESSAGE_INTERNAL_MESSAGE_H_ +#define UPB_MESSAGE_INTERNAL_MESSAGE_H_ + +#include +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +extern const float kUpb_FltInfinity; +extern const double kUpb_Infinity; +extern const double kUpb_NaN; + +// Internal members of a upb_Message that track unknown fields and/or +// extensions. We can change this without breaking binary compatibility. + +typedef struct upb_TaggedAuxPtr { + // Two lowest bits form a tag: + // 00 - non-aliased unknown data + // 10 - aliased unknown data + // 01 - extension + // + // The main semantic difference between aliased and non-aliased unknown data + // is that non-aliased unknown data can be assumed to have the following + // layout: + // + // [upb_StringView] [data] + // + // where the StringView points to the data buffer and the data buffer is + // immediately following the StringView. + // + // The string view does not necessarily point to the start of the data buffer; + // if the initial part of the buffer is removed from the message, the string + // view will point to the beginning of the remaining buffer. + // + // For aliased unknown data, this layout is _not_ guaranteed, since the + // pointer to the StringView can be anywhere in the allocation, and the + // StringView may point to non-data memory. + uintptr_t ptr; +} upb_TaggedAuxPtr; + +UPB_INLINE bool upb_TaggedAuxPtr_IsNull(upb_TaggedAuxPtr ptr) { + return ptr.ptr == 0; +} + +UPB_INLINE bool upb_TaggedAuxPtr_IsExtension(upb_TaggedAuxPtr ptr) { + return ptr.ptr & 1; +} + +UPB_INLINE bool upb_TaggedAuxPtr_IsUnknown(upb_TaggedAuxPtr ptr) { + return (ptr.ptr != 0) && ((ptr.ptr & 1) == 0); +} + +UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownAliased(upb_TaggedAuxPtr ptr) { + return (ptr.ptr != 0) && ((ptr.ptr & 2) == 2); +} + +UPB_INLINE upb_Extension* upb_TaggedAuxPtr_Extension(upb_TaggedAuxPtr ptr) { + UPB_ASSERT(upb_TaggedAuxPtr_IsExtension(ptr)); + return (upb_Extension*)(ptr.ptr & ~3ULL); +} + +UPB_INLINE upb_StringView* upb_TaggedAuxPtr_UnknownData(upb_TaggedAuxPtr ptr) { + UPB_ASSERT(!upb_TaggedAuxPtr_IsExtension(ptr)); + return (upb_StringView*)(ptr.ptr & ~3ULL); +} + +UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) { + upb_TaggedAuxPtr ptr; + ptr.ptr = 0; + return ptr; +} + +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeExtension(const upb_Extension* e) { + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)e | 1; + return ptr; +} + +// This tag means that the original allocation for this field starts with the +// string view and ends with the end of the content referenced by the string +// view. +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeUnknownData(const upb_StringView* sv) { + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)sv; + return ptr; +} + +// This tag implies no guarantee between the relationship of the string view and +// the data it points to. +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeUnknownDataAliased(const upb_StringView* sv) { + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)sv | 2; + return ptr; +} + +typedef struct upb_Message_Internal { + // Total number of entries set in aux_data + uint32_t size; + uint32_t capacity; + // Tagged pointers to upb_StringView or upb_Extension + upb_TaggedAuxPtr aux_data[]; +} upb_Message_Internal; + +#ifdef UPB_TRACING_ENABLED +UPB_API void upb_Message_LogNewMessage(const upb_MiniTable* m, + const upb_Arena* arena); +UPB_API void upb_Message_SetNewMessageTraceHandler( + void (*handler)(const upb_MiniTable*, const upb_Arena*)); +#endif // UPB_TRACING_ENABLED + +// Inline version upb_Message_New(), for internal use. +UPB_INLINE struct upb_Message* _upb_Message_New(const upb_MiniTable* m, + upb_Arena* a) { + UPB_PRIVATE(upb_MiniTable_CheckInvariants)(m); +#ifdef UPB_TRACING_ENABLED + upb_Message_LogNewMessage(m, a); +#endif // UPB_TRACING_ENABLED + + const size_t size = m->UPB_PRIVATE(size); + // Message sizes are aligned up when constructing minitables; telling the + // compiler this avoids redoing alignment on the malloc fast path + UPB_ASSUME(size % kUpb_Message_Align == 0); + struct upb_Message* msg = (struct upb_Message*)upb_Arena_Malloc(a, size); + if (UPB_UNLIKELY(!msg)) return NULL; + memset(msg, 0, size); + return msg; +} + +// Discards the unknown fields for this message only. +void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg); + +UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)( + struct upb_Message* msg, const char* data, size_t len, upb_Arena* arena, + bool alias); + +typedef enum { + // Provided buffer is copied into the message. + kUpb_AddUnknown_Copy = 0, + + // The message will alias the provided buffer. + kUpb_AddUnknown_Alias = 1, + + // The message will alias the provided buffer, and we may merge the data with + // the immediately preceding unknown field if possible. + kUpb_AddUnknown_AliasAllowMerge = 2, +} upb_AddUnknownMode; + +// Adds unknown data (serialized protobuf data) to the given message. The data +// must represent one or more complete and well formed proto fields. +// +// If `alias_base` is NULL, the bytes from `data` will be copied into the +// destination arena. Otherwise it must be a pointer to the beginning of the +// buffer that `data` points into, which signals that the message must alias +// the bytes instead of copying them. The value of `alias_base` is also used +// to mark the boundary of the buffer, so that we do not inappropriately +// coalesce two buffers that are separate objects but happen to be contiguous +// in memory. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg, + const char* data, + size_t len, + upb_Arena* arena, + upb_AddUnknownMode mode) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (mode == kUpb_AddUnknown_AliasAllowMerge) { + // Aliasing parse of a message with sequential unknown fields is a simple + // pointer bump, so inline it. + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (in && in->size) { + upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1]; + if (upb_TaggedAuxPtr_IsUnknown(ptr)) { + upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr); + // Fast path if the field we're adding is immediately after the last + // added unknown field. + // + // The caller has guaranteed to us, by passing + // kUpb_AddUnknown_AliasAllowMerge, that there is no risk that these two + // regions of memory are from different objects that are contiguous in + // memory by coincidence. + if (existing->data + existing->size == data) { + existing->size += len; + return true; + } + } + } + } + return UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)( + msg, data, len, arena, mode != kUpb_AddUnknown_Copy); +} + +// Adds unknown data (serialized protobuf data) to the given message. +// The data is copied into the message instance. Data when concatenated together +// must represent one or more complete and well formed proto fields, but the +// individual spans may point only to partial fields. +bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, + upb_Arena* arena, + upb_StringView data[], size_t count); + +// Ensures at least one slot is available in the aux_data of this message. +// Returns false if a reallocation is needed to satisfy the request, and fails. +bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg, + upb_Arena* arena); + +#define kUpb_Message_UnknownBegin 0 +#define kUpb_Message_ExtensionBegin 0 + +UPB_INLINE bool upb_Message_NextUnknown(const struct upb_Message* msg, + upb_StringView* data, uintptr_t* iter) { + const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + size_t i = *iter; + if (in) { + while (i < in->size) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i++]; + if (upb_TaggedAuxPtr_IsUnknown(tagged_ptr)) { + *data = *upb_TaggedAuxPtr_UnknownData(tagged_ptr); + *iter = i; + return true; + } + } + } + data->size = 0; + data->data = NULL; + *iter = i; + return false; +} + +UPB_INLINE bool upb_Message_HasUnknown(const struct upb_Message* msg) { + upb_StringView data; + uintptr_t iter = kUpb_Message_UnknownBegin; + return upb_Message_NextUnknown(msg, &data, &iter); +} + +UPB_INLINE bool upb_Message_NextExtension(const struct upb_Message* msg, + const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, + uintptr_t* iter) { + const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + uintptr_t i = *iter; + if (in) { + while (i < in->size) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i++]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + + // Empty repeated fields or maps semantically don't exist. + if (UPB_PRIVATE(_upb_Extension_IsEmpty)(ext)) continue; + + *out_e = ext->ext; + *out_v = ext->data; + *iter = i; + return true; + } + } + } + *iter = i; + + return false; +} + +UPB_INLINE bool UPB_PRIVATE(_upb_Message_NextExtensionReverse)( + const struct upb_Message* msg, const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, uintptr_t* iter) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return false; + uintptr_t i = *iter; + uint32_t size = in->size; + while (i < size) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[size - 1 - i]; + i++; + if (!upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + continue; + } + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + + // Empty repeated fields or maps semantically don't exist. + if (UPB_PRIVATE(_upb_Extension_IsEmpty)(ext)) continue; + + *out_e = ext->ext; + *out_v = ext->data; + *iter = i; + return true; + } + *iter = i; + return false; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_MESSAGE_H_ */ + +// Must be last. + +#if defined(__GNUC__) && !defined(__clang__) +// GCC raises incorrect warnings in these functions. It thinks that we are +// overrunning buffers, but we carefully write the functions in this file to +// guarantee that this is impossible. GCC gets this wrong due it its failure +// to perform constant propagation as we expect: +// - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108217 +// - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108226 +// +// Unfortunately this also indicates that GCC is not optimizing away the +// switch() in cases where it should be, compromising the performance. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#if __GNUC__ >= 11 +#pragma GCC diagnostic ignored "-Wstringop-overread" +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// LINT.IfChange(presence_logic) + +// Hasbit access /////////////////////////////////////////////////////////////// + +UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbit)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); + const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); + + return (*UPB_PTR_AT(msg, offset, const char) & mask) != 0; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); + const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); + + (*UPB_PTR_AT(msg, offset, char)) |= mask; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_ClearHasbit)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); + const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); + + (*UPB_PTR_AT(msg, offset, char)) &= ~mask; +} + +// Oneof case access /////////////////////////////////////////////////////////// + +UPB_INLINE uint32_t* UPB_PRIVATE(_upb_Message_OneofCasePtr)( + struct upb_Message* msg, const upb_MiniTableField* f) { + return UPB_PTR_AT(msg, UPB_PRIVATE(_upb_MiniTableField_OneofOffset)(f), + uint32_t); +} + +UPB_INLINE uint32_t UPB_PRIVATE(_upb_Message_GetOneofCase)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint32_t* ptr = + UPB_PRIVATE(_upb_Message_OneofCasePtr)((struct upb_Message*)msg, f); + + return *ptr; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetOneofCase)( + struct upb_Message* msg, const upb_MiniTableField* f) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f); + + *ptr = upb_MiniTableField_Number(f); +} + +// Returns true if the given field is the current oneof case. +// Does nothing if it is not the current oneof case. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_ClearOneofCase)( + struct upb_Message* msg, const upb_MiniTableField* f) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f); + + if (*ptr != upb_MiniTableField_Number(f)) return false; + *ptr = 0; + return true; +} + +UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( + const struct upb_Message* message, const upb_MiniTableField* oneof_field) { + UPB_ASSUME(upb_MiniTableField_IsInOneof(oneof_field)); + return UPB_PRIVATE(_upb_Message_GetOneofCase)(message, oneof_field); +} + +UPB_API_INLINE const upb_MiniTableField* upb_Message_WhichOneof( + const struct upb_Message* msg, const upb_MiniTable* m, + const upb_MiniTableField* f) { + uint32_t field_number = upb_Message_WhichOneofFieldNumber(msg, f); + if (field_number == 0) { + // No field in the oneof is set. + return NULL; + } + return upb_MiniTable_FindFieldByNumber(m, field_number); +} + +// LINT.ThenChange(GoogleInternalName2) + +// Returns false if the message is missing any of its required fields. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_IsInitializedShallow)( + const struct upb_Message* msg, const upb_MiniTable* m) { + uint64_t bits; + memcpy(&bits, msg + 1, sizeof(bits)); + bits = upb_BigEndian64(bits); + return (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~bits) == 0; +} + +UPB_INLINE void* UPB_PRIVATE(_upb_Message_MutableDataPtr)( + struct upb_Message* msg, const upb_MiniTableField* f) { + return (char*)msg + f->UPB_ONLYBITS(offset); +} + +UPB_INLINE const void* UPB_PRIVATE(_upb_Message_DataPtr)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + return (const char*)msg + f->UPB_ONLYBITS(offset); +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetPresence)( + struct upb_Message* msg, const upb_MiniTableField* f) { + if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, f); + } else if (upb_MiniTableField_IsInOneof(f)) { + UPB_PRIVATE(_upb_Message_SetOneofCase)(msg, f); + } +} + +UPB_INLINE_IF_NOT_GCC void UPB_PRIVATE(_upb_MiniTableField_DataCopy)( + const upb_MiniTableField* f, void* to, const void* from) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: + memcpy(to, from, 1); + return; + case kUpb_FieldRep_4Byte: + memcpy(to, from, 4); + return; + case kUpb_FieldRep_8Byte: + memcpy(to, from, 8); + return; + case kUpb_FieldRep_StringView: { + memcpy(to, from, sizeof(upb_StringView)); + return; + } + } + UPB_UNREACHABLE(); +} + +UPB_INLINE_IF_NOT_GCC bool UPB_PRIVATE(_upb_MiniTableField_DataEquals)( + const upb_MiniTableField* f, const void* a, const void* b) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: + return memcmp(a, b, 1) == 0; + case kUpb_FieldRep_4Byte: + return memcmp(a, b, 4) == 0; + case kUpb_FieldRep_8Byte: + return memcmp(a, b, 8) == 0; + case kUpb_FieldRep_StringView: { + const upb_StringView sa = *(const upb_StringView*)a; + const upb_StringView sb = *(const upb_StringView*)b; + return upb_StringView_IsEqual(sa, sb); + } + } + UPB_UNREACHABLE(); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_DataClear)( + const upb_MiniTableField* f, void* val) { + const char zero[16] = {0}; + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, zero); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataIsZero)( + const upb_MiniTableField* f, const void* val) { + const char zero[16] = {0}; + return UPB_PRIVATE(_upb_MiniTableField_DataEquals)(f, val, zero); +} + +// Here we define universal getter/setter functions for message fields. +// These look very branchy and inefficient, but as long as the MiniTableField +// values are known at compile time, all the branches are optimized away and +// we are left with ideal code. This can happen either through through +// literals or UPB_ASSUME(): +// +// // Via struct literals. +// bool FooMessage_set_bool_field(const upb_Message* msg, bool val) { +// const upb_MiniTableField field = {1, 0, 0, /* etc... */}; +// // All value in "field" are compile-time known. +// upb_Message_SetBaseField(msg, &field, &value); +// } +// +// // Via UPB_ASSUME(). +// UPB_INLINE bool upb_Message_SetBool(upb_Message* msg, +// const upb_MiniTableField* field, +// bool value, upb_Arena* a) { +// UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bool); +// UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == +// kUpb_FieldRep_1Byte); +// upb_Message_SetField(msg, field, &value, a); +// } +// +// As a result, we can use these universal getters/setters for *all* message +// accessors: generated code, MiniTable accessors, and reflection. The only +// exception is the binary encoder/decoder, which need to be a bit more clever +// about how they read/write the message data, for efficiency. +// +// These functions work on both extensions and non-extensions. If the field +// of a setter is known to be a non-extension, the arena may be NULL and the +// returned bool value may be ignored since it will always succeed. + +UPB_API_INLINE bool upb_Message_HasBaseField(const struct upb_Message* msg, + const upb_MiniTableField* field) { + UPB_ASSERT(upb_MiniTableField_HasPresence(field)); + UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); + if (upb_MiniTableField_IsInOneof(field)) { + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, field) == + upb_MiniTableField_Number(field); + } else { + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, field); + } +} + +UPB_API_INLINE bool upb_Message_HasExtension(const struct upb_Message* msg, + const upb_MiniTableExtension* e) { + UPB_ASSERT(upb_MiniTableField_HasPresence(&e->UPB_PRIVATE(field))); + return UPB_PRIVATE(_upb_Message_Getext)(msg, e) != NULL; +} + +UPB_FORCEINLINE void _upb_Message_GetNonExtensionField( + const struct upb_Message* msg, const upb_MiniTableField* field, + const void* default_val, void* val) { + UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); + if ((upb_MiniTableField_IsInOneof(field) || + !UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, default_val)) && + !upb_Message_HasBaseField(msg, field)) { + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(field, val, default_val); + return; + } + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, val, UPB_PRIVATE(_upb_Message_DataPtr)(msg, field)); +} + +UPB_INLINE void _upb_Message_GetExtensionField( + const struct upb_Message* msg, const upb_MiniTableExtension* mt_ext, + const void* default_val, void* val) { + const upb_Extension* ext = UPB_PRIVATE(_upb_Message_Getext)(msg, mt_ext); + const upb_MiniTableField* f = &mt_ext->UPB_PRIVATE(field); + UPB_ASSUME(upb_MiniTableField_IsExtension(f)); + + if (ext) { + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, &ext->data); + } else { + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, default_val); + } +} + +// NOTE: The default_val is only used for fields that support presence. +// For repeated/map fields, the resulting upb_Array*/upb_Map* can be NULL if a +// upb_Array/upb_Map has not been allocated yet. Array/map fields do not have +// presence, so this is semantically identical to a pointer to an empty +// array/map, and must be treated the same for all semantic purposes. +UPB_API_INLINE upb_MessageValue upb_Message_GetField( + const struct upb_Message* msg, const upb_MiniTableField* field, + upb_MessageValue default_val) { + upb_MessageValue ret; + if (upb_MiniTableField_IsExtension(field)) { + _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, + &default_val, &ret); + } else { + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); + } + return ret; +} + +UPB_API_INLINE void upb_Message_SetBaseField(struct upb_Message* msg, + const upb_MiniTableField* f, + const void* val) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSUME(!upb_MiniTableField_IsExtension(f)); + UPB_PRIVATE(_upb_Message_SetPresence)(msg, f); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), val); +} + +UPB_API_INLINE bool upb_Message_SetExtension(struct upb_Message* msg, + const upb_MiniTableExtension* e, + const void* val, upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(a); + upb_Extension* ext = + UPB_PRIVATE(_upb_Message_GetOrCreateExtension)(msg, e, a); + if (!ext) return false; + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (&e->UPB_PRIVATE(field), &ext->data, val); + return true; +} + +// Sets the value of the given field in the given msg. The return value is true +// if the operation completed successfully, or false if memory allocation +// failed. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_SetField)(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_MessageValue val, + upb_Arena* a) { + if (upb_MiniTableField_IsExtension(f)) { + const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)f; + return upb_Message_SetExtension(msg, ext, &val, a); + } else { + upb_Message_SetBaseField(msg, f, &val); + return true; + } +} + +UPB_API_INLINE const upb_Array* upb_Message_GetArray( + const struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_Array* ret; + const upb_Array* default_val = NULL; + _upb_Message_GetNonExtensionField(msg, f, &default_val, &ret); + return ret; +} + +UPB_API_INLINE bool upb_Message_GetBool(const struct upb_Message* msg, + const upb_MiniTableField* f, + bool default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Bool); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_1Byte); + upb_MessageValue def; + def.bool_val = default_val; + return upb_Message_GetField(msg, f, def).bool_val; +} + +UPB_API_INLINE double upb_Message_GetDouble(const struct upb_Message* msg, + const upb_MiniTableField* f, + double default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Double); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + + upb_MessageValue def; + def.double_val = default_val; + return upb_Message_GetField(msg, f, def).double_val; +} + +UPB_API_INLINE float upb_Message_GetFloat(const struct upb_Message* msg, + const upb_MiniTableField* f, + float default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Float); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + + upb_MessageValue def; + def.float_val = default_val; + return upb_Message_GetField(msg, f, def).float_val; +} + +UPB_API_INLINE int32_t upb_Message_GetInt32(const struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int32 || + upb_MiniTableField_CType(f) == kUpb_CType_Enum); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + + upb_MessageValue def; + def.int32_val = default_val; + return upb_Message_GetField(msg, f, def).int32_val; +} + +UPB_API_INLINE int64_t upb_Message_GetInt64(const struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + + upb_MessageValue def; + def.int64_val = default_val; + return upb_Message_GetField(msg, f, def).int64_val; +} + +UPB_API_INLINE const struct upb_Map* upb_Message_GetMap( + const struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(f); + struct upb_Map* ret; + const struct upb_Map* default_val = NULL; + _upb_Message_GetNonExtensionField(msg, f, &default_val, &ret); + return ret; +} + +UPB_API_INLINE const struct upb_Message* upb_Message_GetMessage( + const struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + upb_MessageValue def; + def.msg_val = NULL; + return upb_Message_GetField(msg, f, def).msg_val; +} + +UPB_API_INLINE upb_Array* upb_Message_GetMutableArray( + struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + return (upb_Array*)upb_Message_GetArray(msg, f); +} + +UPB_API_INLINE struct upb_Map* upb_Message_GetMutableMap( + struct upb_Message* msg, const upb_MiniTableField* f) { + return (struct upb_Map*)upb_Message_GetMap(msg, f); +} + +UPB_API_INLINE struct upb_Message* upb_Message_GetMutableMessage( + struct upb_Message* msg, const upb_MiniTableField* f) { + return (struct upb_Message*)upb_Message_GetMessage(msg, f); +} + +UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( + struct upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena) { + UPB_ASSERT(arena); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_Array* array = upb_Message_GetMutableArray(msg, f); + if (!array) { + array = UPB_PRIVATE(_upb_Array_New)( + arena, 4, UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)(f)); + // Check again due to: https://godbolt.org/z/7WfaoKG1r + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_MessageValue val; + val.array_val = array; + UPB_PRIVATE(_upb_Message_SetField)(msg, f, val, arena); + } + return array; +} + +UPB_INLINE struct upb_Map* _upb_Message_GetOrCreateMutableMap( + struct upb_Message* msg, const upb_MiniTableField* field, size_t key_size, + size_t val_size, upb_Arena* arena) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); + struct upb_Map* map = NULL; + struct upb_Map* default_map_value = NULL; + _upb_Message_GetNonExtensionField(msg, field, &default_map_value, &map); + if (!map) { + map = _upb_Map_New(arena, key_size, val_size); + // Check again due to: https://godbolt.org/z/7WfaoKG1r + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); + upb_Message_SetBaseField(msg, field, &map); + } + return map; +} + +UPB_API_INLINE struct upb_Map* upb_Message_GetOrCreateMutableMap( + struct upb_Message* msg, const upb_MiniTable* map_entry_mini_table, + const upb_MiniTableField* f, upb_Arena* arena) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + const upb_MiniTableField* map_entry_key_field = + &map_entry_mini_table->UPB_ONLYBITS(fields)[0]; + const upb_MiniTableField* map_entry_value_field = + &map_entry_mini_table->UPB_ONLYBITS(fields)[1]; + return _upb_Message_GetOrCreateMutableMap( + msg, f, _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)), + _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_value_field)), + arena); +} + +UPB_API_INLINE struct upb_Message* upb_Message_GetOrCreateMutableMessage( + struct upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena) { + UPB_ASSERT(arena); + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + UPB_ASSUME(!upb_MiniTableField_IsExtension(f)); + struct upb_Message* sub_message = + *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*); + if (!sub_message) { + const upb_MiniTable* sub_mini_table = upb_MiniTable_SubMessage(f); + UPB_ASSERT(sub_mini_table); + sub_message = _upb_Message_New(sub_mini_table, arena); + *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*) = + sub_message; + UPB_PRIVATE(_upb_Message_SetPresence)(msg, f); + } + return sub_message; +} + +UPB_API_INLINE upb_StringView +upb_Message_GetString(const struct upb_Message* msg, + const upb_MiniTableField* f, upb_StringView default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_String || + upb_MiniTableField_CType(f) == kUpb_CType_Bytes); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_StringView); + + upb_MessageValue def; + def.str_val = default_val; + return upb_Message_GetField(msg, f, def).str_val; +} + +UPB_API_INLINE uint32_t upb_Message_GetUInt32(const struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt32); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + + upb_MessageValue def; + def.uint32_val = default_val; + return upb_Message_GetField(msg, f, def).uint32_val; +} + +UPB_API_INLINE uint64_t upb_Message_GetUInt64(const struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + + upb_MessageValue def; + def.uint64_val = default_val; + return upb_Message_GetField(msg, f, def).uint64_val; +} + +// BaseField Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE void upb_Message_SetBaseFieldBool(struct upb_Message* msg, + const upb_MiniTableField* f, + bool value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Bool); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_1Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldDouble(struct upb_Message* msg, + const upb_MiniTableField* f, + double value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Double); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldFloat(struct upb_Message* msg, + const upb_MiniTableField* f, + float value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Float); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int32 || + upb_MiniTableField_CType(f) == kUpb_CType_Enum); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldMessage(struct upb_Message* msg, + const upb_MiniTableField* f, + struct upb_Message* value) { + // TODO - Re-enable this assertion. + // UPB_ASSERT(value); + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldString(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_String || + upb_MiniTableField_CType(f) == kUpb_CType_Bytes); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_StringView); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt32); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetClosedEnum(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value) { + UPB_ASSERT(upb_MiniTableField_IsClosedEnum(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + UPB_ASSERT(upb_MiniTableEnum_CheckValue(upb_MiniTable_GetSubEnumTable(f), + (uint32_t)value)); + upb_Message_SetBaseField(msg, f, &value); +} + +// Extension Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetExtensionMessage( + struct upb_Message* msg, const upb_MiniTableExtension* e, + struct upb_Message* value, upb_Arena* a) { + UPB_ASSERT(value); + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionBool( + struct upb_Message* msg, const upb_MiniTableExtension* e, bool value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Bool); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_1Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionDouble( + struct upb_Message* msg, const upb_MiniTableExtension* e, double value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Double); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionFloat( + struct upb_Message* msg, const upb_MiniTableExtension* e, float value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Float); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, int32_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int32 || + upb_MiniTableExtension_CType(e) == kUpb_CType_Enum); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, int64_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionString( + struct upb_Message* msg, const upb_MiniTableExtension* e, + upb_StringView value, upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_String || + upb_MiniTableExtension_CType(e) == kUpb_CType_Bytes); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_StringView); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionUInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint32_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt32); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionUInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint64_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +// Universal Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetBool(struct upb_Message* msg, + const upb_MiniTableField* f, bool value, + upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionBool( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldBool(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetDouble(struct upb_Message* msg, + const upb_MiniTableField* f, + double value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionDouble( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldDouble(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetFloat(struct upb_Message* msg, + const upb_MiniTableField* f, + float value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionFloat( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldFloat(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionInt32( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldInt32(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionInt64( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldInt64(msg, f, value), true); +} + +// Sets the value of a message-typed field. The mini_tables of `msg` and +// `value` must have been linked for this to work correctly. +UPB_API_INLINE void upb_Message_SetMessage(struct upb_Message* msg, + const upb_MiniTableField* f, + struct upb_Message* value) { + UPB_ASSERT(!upb_MiniTableField_IsExtension(f)); + upb_Message_SetBaseFieldMessage(msg, f, value); +} + +// Sets the value of a `string` or `bytes` field. The bytes of the value are not +// copied, so it is the caller's responsibility to ensure that they remain valid +// for the lifetime of `msg`. That might be done by copying them into the given +// arena, or by fusing that arena with the arena the bytes live in, for example. +UPB_API_INLINE bool upb_Message_SetString(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionString( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldString(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetUInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionUInt32( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldUInt32(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetUInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionUInt64( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldUInt64(msg, f, value), true); +} + +UPB_API_INLINE void upb_Message_Clear(struct upb_Message* msg, + const upb_MiniTable* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + memset(msg, 0, m->UPB_PRIVATE(size)); + if (in) { + // Reset the internal buffer to empty. + in->size = 0; + } +} + +UPB_API_INLINE void upb_Message_ClearBaseField(struct upb_Message* msg, + const upb_MiniTableField* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + UPB_PRIVATE(_upb_Message_ClearHasbit)(msg, f); + } else if (upb_MiniTableField_IsInOneof(f)) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f); + if (*ptr != upb_MiniTableField_Number(f)) return; + *ptr = 0; + } + const char zeros[16] = {0}; + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), zeros); +} + +UPB_API_INLINE void upb_Message_ClearExtension( + struct upb_Message* msg, const upb_MiniTableExtension* e) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return; + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + if (ext->ext == e) { + in->aux_data[i] = upb_TaggedAuxPtr_Null(); + return; + } + } + } +} + +UPB_API_INLINE void upb_Message_ClearOneof(struct upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + uint32_t field_number = upb_Message_WhichOneofFieldNumber(msg, f); + if (field_number == 0) { + // No field in the oneof is set. + return; + } + + const upb_MiniTableField* field = + upb_MiniTable_FindFieldByNumber(m, field_number); + upb_Message_ClearBaseField(msg, field); +} + +UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( + struct upb_Message* msg, const upb_MiniTableField* f, size_t size, + upb_Arena* arena) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(msg, f, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)(arr, size, arena)) { + return NULL; + } + return upb_Array_MutableDataPtr(arr); +} + +UPB_API_INLINE bool upb_Message_GetExtensionBool( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + bool default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Bool); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_1Byte); + bool ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE double upb_Message_GetExtensionDouble( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + double default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Double); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + double ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE float upb_Message_GetExtensionFloat( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + float default_val) { + float ret; + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Float); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE int32_t upb_Message_GetExtensionInt32( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + int32_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int32 || + upb_MiniTableExtension_CType(e) == kUpb_CType_Enum); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + int32_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE int64_t upb_Message_GetExtensionInt64( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + int64_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + int64_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE uint32_t upb_Message_GetExtensionUInt32( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + uint32_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt32); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + uint32_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE uint64_t upb_Message_GetExtensionUInt64( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + uint64_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + uint64_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE upb_StringView upb_Message_GetExtensionString( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + upb_StringView default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_String || + upb_MiniTableExtension_CType(e) == kUpb_CType_Bytes); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_StringView); + upb_StringView ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE struct upb_Message* upb_Message_GetExtensionMessage( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + struct upb_Message* default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + struct upb_Message* ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +// Repeated +UPB_API_INLINE const upb_Array* upb_Message_GetExtensionArray( + const struct upb_Message* msg, const upb_MiniTableExtension* e) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(&e->UPB_PRIVATE(field)) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsArray(&e->UPB_PRIVATE(field))); + UPB_ASSUME(e->UPB_PRIVATE(field).presence == 0); + upb_Array* ret; + const upb_Array* default_val = NULL; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE upb_Array* upb_Message_GetExtensionMutableArray( + struct upb_Message* msg, const upb_MiniTableExtension* e) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(&e->UPB_PRIVATE(field)) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsArray(&e->UPB_PRIVATE(field))); + UPB_ASSUME(e->UPB_PRIVATE(field).presence == 0); + upb_Array* ret; + upb_Array* default_val = NULL; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + + +#endif // UPB_MESSAGE_INTERNAL_ACCESSORS_H_ + +#ifndef UPB_MESSAGE_MAP_H_ +#define UPB_MESSAGE_MAP_H_ + +#include + + +// Must be last. + +typedef struct upb_Map upb_Map; + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates a new map on the given arena with the given key/value size. +UPB_API upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, + upb_CType value_type); + +// Returns the number of entries in the map. +UPB_API size_t upb_Map_Size(const upb_Map* map); + +// Stores a value for the given key into |*val| (or the zero value if the key is +// not present). Returns whether the key was present. The |val| pointer may be +// NULL, in which case the function tests whether the given key is present. +UPB_API bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* val); + +// Returns a mutable pointer to the value for the given key. Returns NULL if the +// key is not present. +// This function is only legal to call for maps that contain messages. +UPB_API struct upb_Message* upb_Map_GetMutable(upb_Map* map, + upb_MessageValue key); + +// Removes all entries in the map. +UPB_API void upb_Map_Clear(upb_Map* map); + +// Sets the given key to the given value, returning whether the key was inserted +// or replaced. If the key was inserted, then any existing iterators will be +// invalidated. +UPB_API upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key, + upb_MessageValue val, + upb_Arena* arena); + +// Sets the given key to the given value. Returns false if memory allocation +// failed. If the key is newly inserted, then any existing iterators will be +// invalidated. +UPB_API_INLINE bool upb_Map_Set(upb_Map* map, upb_MessageValue key, + upb_MessageValue val, upb_Arena* arena) { + return upb_Map_Insert(map, key, val, arena) != + kUpb_MapInsertStatus_OutOfMemory; +} + +// Deletes this key from the table. Returns true if the key was present. +// If present and |val| is non-NULL, stores the deleted value. +UPB_API bool upb_Map_Delete(upb_Map* map, upb_MessageValue key, + upb_MessageValue* val); + +// Map iteration: +// +// size_t iter = kUpb_Map_Begin; +// upb_MessageValue key, val; +// while (upb_Map_Next(map, &key, &val, &iter)) { +// ... +// } + +#define kUpb_Map_Begin ((size_t)-1) + +// Advances to the next entry. Returns false if no more entries are present. +// Otherwise returns true and populates both *key and *value. +UPB_API bool upb_Map_Next(const upb_Map* map, upb_MessageValue* key, + upb_MessageValue* val, size_t* iter); + +// Sets the value for the entry pointed to by iter. +// WARNING: this does not currently work for string values! +UPB_API void upb_Map_SetEntryValue(upb_Map* map, size_t iter, + upb_MessageValue val); + +// DEPRECATED iterator, slated for removal. + +/* Map iteration: + * + * size_t iter = kUpb_Map_Begin; + * while (upb_MapIterator_Next(map, &iter)) { + * upb_MessageValue key = upb_MapIterator_Key(map, iter); + * upb_MessageValue val = upb_MapIterator_Value(map, iter); + * } + */ + +// Advances to the next entry. Returns false if no more entries are present. +UPB_API bool upb_MapIterator_Next(const upb_Map* map, size_t* iter); + +// Returns true if the iterator still points to a valid entry, or false if the +// iterator is past the last element. It is an error to call this function with +// kUpb_Map_Begin (you must call next() at least once first). +UPB_API bool upb_MapIterator_Done(const upb_Map* map, size_t iter); + +// Returns the key and value for this entry of the map. +UPB_API upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter); +UPB_API upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter); + +// Mark a map and all of its descendents as frozen/immutable. +// If the map values are messages then |m| must point to the minitable for +// those messages. Otherwise |m| must be NULL. +UPB_API void upb_Map_Freeze(upb_Map* map, const upb_MiniTable* m); + +// Returns whether a map has been frozen. +UPB_API_INLINE bool upb_Map_IsFrozen(const upb_Map* map); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_MAP_H_ */ + +// Public APIs for message operations that do not depend on the schema. +// +// MiniTable-based accessors live in accessors.h. + +#ifndef UPB_MESSAGE_MESSAGE_H_ +#define UPB_MESSAGE_MESSAGE_H_ + +#include +#include + + +// Must be last. + +typedef struct upb_Message upb_Message; + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates a new message with the given mini_table on the given arena. +UPB_API upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* arena); + +// +// Unknown data may be stored non-contiguously. Each segment stores a block of +// unknown fields. To iterate over segments: +// +// uintptr_t iter = kUpb_Message_UnknownBegin; +// upb_StringView data; +// while (upb_Message_NextUnknown(msg, &data, &iter)) { +// // Use data +// } +// Iterates in the order unknown fields were parsed. + +#define kUpb_Message_UnknownBegin 0 +#define kUpb_Message_ExtensionBegin 0 + +UPB_INLINE bool upb_Message_NextUnknown(const upb_Message* msg, + upb_StringView* data, uintptr_t* iter); + +UPB_INLINE bool upb_Message_HasUnknown(const upb_Message* msg); + +// Removes a segment of unknown data from the message, advancing to the next +// segment. Returns false if the removed segment was at the end of the last +// chunk. +// +// This must be done while iterating: +// +// uintptr_t iter = kUpb_Message_UnknownBegin; +// upb_StringView data; +// // Iterate chunks +// while (upb_Message_NextUnknown(msg, &data, &iter)) { +// // Iterate within a chunk, deleting ranges +// while (ShouldDeleteSubSegment(&data)) { +// // Data now points to the region to be deleted +// switch (upb_Message_DeleteUnknown(msg, &data, &iter)) { +// case kUpb_Message_DeleteUnknown_DeletedLast: return ok; +// case kUpb_Message_DeleteUnknown_IterUpdated: break; +// // If DeleteUnknown returned kUpb_Message_DeleteUnknown_IterUpdated, +// // then data now points to the remaining unknown fields after the +// // region that was just deleted. +// case kUpb_Message_DeleteUnknown_AllocFail: return err; +// } +// } +// } +// +// The range given in `data` must be contained inside the most recently +// returned region. +typedef enum upb_Message_DeleteUnknownStatus { + kUpb_DeleteUnknown_DeletedLast, + kUpb_DeleteUnknown_IterUpdated, + kUpb_DeleteUnknown_AllocFail, +} upb_Message_DeleteUnknownStatus; +upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg, + upb_StringView* data, + uintptr_t* iter, + upb_Arena* arena); + +// Returns the number of extensions present in this message. +size_t upb_Message_ExtensionCount(const upb_Message* msg); + +// Iterates extensions in wire order +UPB_INLINE bool upb_Message_NextExtension(const upb_Message* msg, + const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, + uintptr_t* iter); + +// Iterates extensions in reverse wire order +UPB_INLINE bool UPB_PRIVATE(_upb_Message_NextExtensionReverse)( + const struct upb_Message* msg, const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, uintptr_t* iter); + +// Mark a message and all of its descendents as frozen/immutable. +UPB_API void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m); + +// Returns whether a message has been frozen. +UPB_API_INLINE bool upb_Message_IsFrozen(const upb_Message* msg); + +#ifdef UPB_TRACING_ENABLED +UPB_API void upb_Message_LogNewMessage(const upb_MiniTable* m, + const upb_Arena* arena); + +UPB_API void upb_Message_SetNewMessageTraceHandler( + void (*handler)(const upb_MiniTable* m, const upb_Arena* arena)); +#endif // UPB_TRACING_ENABLED + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_MESSAGE_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Functions ending in BaseField() take a (upb_MiniTableField*) argument +// and work only on non-extension fields. +// +// Functions ending in Extension() take a (upb_MiniTableExtension*) argument +// and work only on extensions. + +UPB_API_INLINE void upb_Message_Clear(upb_Message* msg, const upb_MiniTable* m); + +UPB_API_INLINE void upb_Message_ClearBaseField(upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE void upb_Message_ClearExtension(upb_Message* msg, + const upb_MiniTableExtension* e); + +UPB_API_INLINE void upb_Message_ClearOneof(upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_Message_HasBaseField(const upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_Message_HasExtension(const upb_Message* msg, + const upb_MiniTableExtension* e); + +UPB_API_INLINE upb_MessageValue +upb_Message_GetField(const upb_Message* msg, const upb_MiniTableField* f, + upb_MessageValue default_val); + +UPB_API_INLINE const upb_Array* upb_Message_GetArray( + const upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_Message_GetBool(const upb_Message* msg, + const upb_MiniTableField* f, + bool default_val); + +UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, + const upb_MiniTableField* field, + double default_val); + +UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, + const upb_MiniTableField* f, + float default_val); + +UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, + const upb_MiniTableField* f, + int32_t default_val); + +UPB_API_INLINE int64_t upb_Message_GetInt64(const upb_Message* msg, + const upb_MiniTableField* f, + int64_t default_val); + +UPB_API_INLINE const upb_Map* upb_Message_GetMap(const upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE const upb_Message* upb_Message_GetMessage( + const upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE upb_Array* upb_Message_GetMutableArray( + upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE upb_Map* upb_Message_GetMutableMap(upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE upb_Message* upb_Message_GetMutableMessage( + upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( + upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena); + +UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap( + upb_Message* msg, const upb_MiniTable* map_entry_mini_table, + const upb_MiniTableField* f, upb_Arena* arena); + +UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( + upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena); + +UPB_API_INLINE upb_StringView +upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field, + upb_StringView default_val); + +UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, + const upb_MiniTableField* f, + uint32_t default_val); + +UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, + const upb_MiniTableField* f, + uint64_t default_val); + +UPB_API_INLINE void upb_Message_SetClosedEnum(upb_Message* msg, + const upb_MiniTableField* f, + int32_t value); + +// BaseField Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE void upb_Message_SetBaseField(upb_Message* msg, + const upb_MiniTableField* f, + const void* val); + +UPB_API_INLINE void upb_Message_SetBaseFieldBool(struct upb_Message* msg, + const upb_MiniTableField* f, + bool value); + +UPB_API_INLINE void upb_Message_SetBaseFieldDouble(struct upb_Message* msg, + const upb_MiniTableField* f, + double value); + +UPB_API_INLINE void upb_Message_SetBaseFieldFloat(struct upb_Message* msg, + const upb_MiniTableField* f, + float value); + +UPB_API_INLINE void upb_Message_SetBaseFieldInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value); + +UPB_API_INLINE void upb_Message_SetBaseFieldInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t value); + +UPB_API_INLINE void upb_Message_SetBaseFieldMessage(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_Message* value); + +UPB_API_INLINE void upb_Message_SetBaseFieldString(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value); + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value); + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value); + +// Extension Getters /////////////////////////////////////////////////////////// +UPB_API_INLINE bool upb_Message_GetExtensionBool( + const upb_Message* msg, const upb_MiniTableExtension* f, bool default_val); + +UPB_API_INLINE double upb_Message_GetExtensionDouble( + const upb_Message* msg, const upb_MiniTableExtension* f, + double default_val); + +UPB_API_INLINE float upb_Message_GetExtensionFloat( + const upb_Message* msg, const upb_MiniTableExtension* f, float default_val); + +UPB_API_INLINE int32_t upb_Message_GetExtensionInt32( + const upb_Message* msg, const upb_MiniTableExtension* f, + int32_t default_val); + +UPB_API_INLINE int64_t upb_Message_GetExtensionInt64( + const upb_Message* msg, const upb_MiniTableExtension* f, + int64_t default_val); + +UPB_API_INLINE uint32_t upb_Message_GetExtensionUInt32( + const upb_Message* msg, const upb_MiniTableExtension* f, + uint32_t default_val); + +UPB_API_INLINE uint64_t upb_Message_GetExtensionUInt64( + const upb_Message* msg, const upb_MiniTableExtension* f, + uint64_t default_val); + +UPB_API_INLINE upb_StringView upb_Message_GetExtensionString( + const upb_Message* msg, const upb_MiniTableExtension* f, + upb_StringView default_val); + +UPB_API_INLINE upb_Message* upb_Message_GetExtensionMessage( + const upb_Message* msg, const upb_MiniTableExtension* f, + struct upb_Message* default_val); + +UPB_API_INLINE const upb_Array* upb_Message_GetExtensionArray( + const upb_Message* msg, const upb_MiniTableExtension* f); + +UPB_API_INLINE upb_Array* upb_Message_GetExtensionMutableArray( + upb_Message* msg, const upb_MiniTableExtension* f); + +// Extension Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetExtension(upb_Message* msg, + const upb_MiniTableExtension* e, + const void* value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionMessage( + struct upb_Message* msg, const upb_MiniTableExtension* e, + struct upb_Message* value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionBool( + struct upb_Message* msg, const upb_MiniTableExtension* e, bool value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionDouble( + struct upb_Message* msg, const upb_MiniTableExtension* e, double value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionFloat( + struct upb_Message* msg, const upb_MiniTableExtension* e, float value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, int32_t value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, int64_t value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionString( + struct upb_Message* msg, const upb_MiniTableExtension* e, + upb_StringView value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionUInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint32_t value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionUInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint64_t value, + upb_Arena* a); + +// Universal Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, + const upb_MiniTableField* f, bool value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, + const upb_MiniTableField* f, + double value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, + const upb_MiniTableField* f, + float value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, + const upb_MiniTableField* f, + int32_t value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, + const upb_MiniTableField* f, + int64_t value, upb_Arena* a); + +// Unlike the other similarly-named setters, this function can only be +// called on base fields. Prefer upb_Message_SetBaseFieldMessage(). +UPB_API_INLINE void upb_Message_SetMessage(upb_Message* msg, + const upb_MiniTableField* f, + upb_Message* value); + +UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value, upb_Arena* a); + +//////////////////////////////////////////////////////////////////////////////// + +UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( + upb_Message* msg, const upb_MiniTableField* f, size_t size, + upb_Arena* arena); + +UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( + const upb_Message* message, const upb_MiniTableField* oneof_field); + +// For a field `f` which is in a oneof, return the field of that +// oneof that is actually set (or NULL if none). +UPB_API_INLINE const upb_MiniTableField* upb_Message_WhichOneof( + const upb_Message* msg, const upb_MiniTable* m, + const upb_MiniTableField* f); + +// Updates a map entry given an entry message. +bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* field, + upb_Message* map_entry_message, upb_Arena* arena); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#if defined(__cplusplus) +// Temporary overloads for functions whose signature has recently changed. +UPB_DEPRECATE_AND_INLINE() +inline upb_Message* upb_Message_GetOrCreateMutableMessage( + upb_Message* msg, const upb_MiniTable* mini_table, + const upb_MiniTableField* f, upb_Arena* arena) { + return upb_Message_GetOrCreateMutableMessage(msg, f, arena); +} + +UPB_DEPRECATE_AND_INLINE() +inline void upb_Message_SetClosedEnum(upb_Message* msg, + const upb_MiniTable* msg_mini_table, + const upb_MiniTableField* f, + int32_t value) { + upb_Message_SetClosedEnum(msg, f, value); +} + +UPB_DEPRECATE_AND_INLINE() +inline bool upb_Message_SetMapEntry(upb_Map* map, + const upb_MiniTable* mini_table, + const upb_MiniTableField* field, + upb_Message* map_entry_message, + upb_Arena* arena) { + return upb_Message_SetMapEntry(map, field, map_entry_message, arena); +} +#endif + + +#endif // UPB_MESSAGE_ACCESSORS_H_ + +// These functions are only used by generated code. + +#ifndef UPB_MESSAGE_MAP_GENCODE_UTIL_H_ +#define UPB_MESSAGE_MAP_GENCODE_UTIL_H_ + +// This header file is referenced by multiple files. Leave it empty. +// TODO: b/399481227 - Remove this header file, after all the references are +// cleaned up. +#endif /* UPB_MESSAGE_MAP_GENCODE_UTIL_H_ */ + +#ifndef UPB_MINI_TABLE_DECODE_H_ +#define UPB_MINI_TABLE_DECODE_H_ + +#include + + +#ifndef UPB_BASE_STATUS_H_ +#define UPB_BASE_STATUS_H_ + +#include + +// Must be last. + +#define _kUpb_Status_MaxMessage 511 + +typedef struct { + bool ok; + char msg[_kUpb_Status_MaxMessage]; // Error message; NULL-terminated. +} upb_Status; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const char* upb_Status_ErrorMessage(const upb_Status* status); +UPB_API bool upb_Status_IsOk(const upb_Status* status); + +// These are no-op if |status| is NULL. +UPB_API void upb_Status_Clear(upb_Status* status); +void upb_Status_SetErrorMessage(upb_Status* status, const char* msg); +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) + UPB_PRINTF(2, 3); +void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); +void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_STATUS_H_ */ + +#ifndef UPB_MINI_TABLE_SUB_H_ +#define UPB_MINI_TABLE_SUB_H_ + + +// Must be last. + +typedef union upb_MiniTableSub upb_MiniTableSub; + +#ifdef __cplusplus +extern "C" { +#endif + +// Constructors + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromEnum(const upb_MiniTableEnum* subenum); + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromMessage(const upb_MiniTable* submsg); + +// Getters + +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTableSub_Enum( + upb_MiniTableSub sub); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableSub_Message( + upb_MiniTableSub sub); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_SUB_H_ */ + +// Export the newer headers, for legacy users. New users should include the +// more specific headers directly. +// IWYU pragma: begin_exports + +#ifndef UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ +#define UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Builds a upb_MiniTableEnum from an enum mini descriptor. +// The mini descriptor must be for an enum, not a message. +UPB_API upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len, + upb_Arena* arena, + upb_Status* status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ + +// Functions for linking MiniTables together once they are built from a +// MiniDescriptor. +// +// These functions have names like upb_MiniTable_Link() because they operate on +// MiniTables. We put them here, rather than in the mini_table/ directory, +// because they are only needed when building MiniTables from MiniDescriptors. +// The interfaces in mini_table/ assume that MiniTables are immutable. + +#ifndef UPB_MINI_DESCRIPTOR_LINK_H_ +#define UPB_MINI_DESCRIPTOR_LINK_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Links a sub-message field to a MiniTable for that sub-message. If a +// sub-message field is not linked, it will be treated as an unknown field +// during parsing, and setting the field will not be allowed. It is possible +// to link the message field later, at which point it will no longer be treated +// as unknown. However there is no synchronization for this operation, which +// means parallel mutation requires external synchronization. +// Returns success/failure. +UPB_API bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, + upb_MiniTableField* field, + const upb_MiniTable* sub); + +// Links an enum field to a MiniTable for that enum. +// All enum fields must be linked prior to parsing. +// Returns success/failure. +UPB_API bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, + upb_MiniTableField* field, + const upb_MiniTableEnum* sub); + +// Returns a list of fields that require linking at runtime, to connect the +// MiniTable to its sub-messages and sub-enums. The list of fields will be +// written to the `subs` array, which must have been allocated by the caller +// and must be large enough to hold a list of all fields in the message. +// +// The order of the fields returned by this function is significant: it matches +// the order expected by upb_MiniTable_Link() below. +// +// The return value packs the sub-message count and sub-enum count into a single +// integer like so: +// return (msg_count << 16) | enum_count; +UPB_API uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, + const upb_MiniTableField** subs); + +// Links a message to its sub-messages and sub-enums. The caller must pass +// arrays of sub-tables and sub-enums, in the same length and order as is +// returned by upb_MiniTable_GetSubList() above. However, individual elements +// of the sub_tables may be NULL if those sub-messages were tree shaken. +// +// Returns false if either array is too short, or if any of the tables fails +// to link. +UPB_API bool upb_MiniTable_Link(upb_MiniTable* mt, + const upb_MiniTable** sub_tables, + size_t sub_table_count, + const upb_MiniTableEnum** sub_enums, + size_t sub_enum_count); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_DESCRIPTOR_LINK_H_ +// IWYU pragma: end_exports + +// Must be last. + +typedef enum { + kUpb_MiniTablePlatform_32Bit, + kUpb_MiniTablePlatform_64Bit, + kUpb_MiniTablePlatform_Native = + UPB_SIZE(kUpb_MiniTablePlatform_32Bit, kUpb_MiniTablePlatform_64Bit), +} upb_MiniTablePlatform; + +#ifdef __cplusplus +extern "C" { +#endif + +// Builds a mini table from the data encoded in the buffer [data, len]. If any +// errors occur, returns NULL and sets a status message. In the success case, +// the caller must call upb_MiniTable_SetSub*() for all message or proto2 enum +// fields to link the table to the appropriate sub-tables. +upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, upb_Status* status); + +UPB_API_INLINE upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len, + upb_Arena* arena, + upb_Status* status) { + return _upb_MiniTable_Build(data, len, kUpb_MiniTablePlatform_Native, arena, + status); +} + +// Initializes a MiniTableExtension buffer that has already been allocated. +// This is needed by upb_FileDef and upb_MessageDef, which allocate all of the +// extensions together in a single contiguous array. +const char* _upb_MiniTableExtension_Init(const char* data, size_t len, + upb_MiniTableExtension* ext, + const upb_MiniTable* extendee, + upb_MiniTableSub sub, + upb_MiniTablePlatform platform, + upb_Status* status); + +UPB_API_INLINE const char* upb_MiniTableExtension_Init( + const char* data, size_t len, upb_MiniTableExtension* ext, + const upb_MiniTable* extendee, upb_MiniTableSub sub, upb_Status* status) { + return _upb_MiniTableExtension_Init(data, len, ext, extendee, sub, + kUpb_MiniTablePlatform_Native, status); +} + +UPB_API upb_MiniTableExtension* _upb_MiniTableExtension_Build( + const char* data, size_t len, const upb_MiniTable* extendee, + upb_MiniTableSub sub, upb_MiniTablePlatform platform, upb_Arena* arena, + upb_Status* status); + +UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( + const char* data, size_t len, const upb_MiniTable* extendee, + upb_Arena* arena, upb_Status* status) { + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(NULL); + return _upb_MiniTableExtension_Build( + data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); +} + +UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( + const char* data, size_t len, const upb_MiniTable* extendee, + const upb_MiniTable* submsg, upb_Arena* arena, upb_Status* status) { + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(submsg); + return _upb_MiniTableExtension_Build( + data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); +} + +UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildEnum( + const char* data, size_t len, const upb_MiniTable* extendee, + const upb_MiniTableEnum* subenum, upb_Arena* arena, upb_Status* status) { + upb_MiniTableSub sub = upb_MiniTableSub_FromEnum(subenum); + return _upb_MiniTableExtension_Build( + data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); +} + +// Like upb_MiniTable_Build(), but the user provides a buffer of layout data so +// it can be reused from call to call, avoiding repeated +// upb_grealloc()/upb_gfree(). +// +// The caller owns `*buf` both before and after the call, and must upb_gfree() +// it when it is no longer in use. The function will upb_grealloc() `*buf` as +// necessary, updating `*size` accordingly. +upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, void** buf, + size_t* buf_size, upb_Status* status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_DECODE_H_ */ + +#ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ +#define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* Extension registry: a dynamic data structure that stores a map of: + * (upb_MiniTable, number) -> extension info + * + * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing + * binary format. + * + * upb_ExtensionRegistry is part of the mini-table (msglayout) family of + * objects. Like all mini-table objects, it is suitable for reflection-less + * builds that do not want to expose names into the binary. + * + * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory + * allocation and dynamic initialization: + * * If reflection is being used, then upb_DefPool will construct an appropriate + * upb_ExtensionRegistry automatically. + * * For a mini-table only build, the user must manually construct the + * upb_ExtensionRegistry and populate it with all of the extensions the user + * cares about. + * * A third alternative is to manually unpack relevant extensions after the + * main parse is complete, similar to how Any works. This is perhaps the + * nicest solution from the perspective of reducing dependencies, avoiding + * dynamic memory allocation, and avoiding the need to parse uninteresting + * extensions. The downsides are: + * (1) parse errors are not caught during the main parse + * (2) the CPU hit of parsing comes during access, which could cause an + * undesirable stutter in application performance. + * + * Users cannot directly get or put into this map. Users can only add the + * extensions from a generated module and pass the extension registry to the + * binary decoder. + * + * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use + * reflection do not need to populate a upb_ExtensionRegistry directly. + */ + +typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; + +// LINT.IfChange +typedef enum { + kUpb_ExtensionRegistryStatus_Ok = 0, + kUpb_ExtensionRegistryStatus_DuplicateEntry = 1, + kUpb_ExtensionRegistryStatus_OutOfMemory = 2, + kUpb_ExtensionRegistryStatus_InvalidExtension = 3, +} upb_ExtensionRegistryStatus; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/sys/mini_table/extension_registry.rs) + +// Creates a upb_ExtensionRegistry in the given arena. +// The arena must outlive any use of the extreg. +UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); + +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e); + +// Adds the given extension info for the array |e| of size |count| into the +// registry. If there are any errors, the entire array is backed out. +// The extensions must outlive the registry. +// Possible errors include OOM or an extension number that already exists. +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count); + +// Looks up the extension (if any) defined for message type |t| and field +// number |num|. Returns the extension if found, otherwise NULL. +UPB_API const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( + const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num); + +// Returns the number of extensions in the registry. For testing/debugging only. +UPB_API size_t upb_ExtensionRegistry_Size(const upb_ExtensionRegistry* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ */ + +#ifndef UPB_MINI_TABLE_FILE_H_ +#define UPB_MINI_TABLE_FILE_H_ + + +#ifndef UPB_MINI_TABLE_INTERNAL_FILE_H_ +#define UPB_MINI_TABLE_INTERNAL_FILE_H_ + +// Must be last. + +struct upb_MiniTableFile { + const struct upb_MiniTable** UPB_PRIVATE(msgs); + const struct upb_MiniTableEnum** UPB_PRIVATE(enums); + const struct upb_MiniTableExtension** UPB_PRIVATE(exts); + int UPB_PRIVATE(msg_count); + int UPB_PRIVATE(enum_count); + int UPB_PRIVATE(ext_count); +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE int upb_MiniTableFile_EnumCount( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(enum_count); +} + +UPB_API_INLINE int upb_MiniTableFile_ExtensionCount( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(ext_count); +} + +UPB_API_INLINE int upb_MiniTableFile_MessageCount( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(msg_count); +} + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableFile_Enum( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(enum_count)); + return f->UPB_PRIVATE(enums)[i]; +} + +UPB_API_INLINE const struct upb_MiniTableExtension* upb_MiniTableFile_Extension( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(ext_count)); + return f->UPB_PRIVATE(exts)[i]; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableFile_Message( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(msg_count)); + return f->UPB_PRIVATE(msgs)[i]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_FILE_H_ */ + +// Must be last. + +typedef struct upb_MiniTableFile upb_MiniTableFile; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTableFile_Enum( + const upb_MiniTableFile* f, int i); + +UPB_API_INLINE int upb_MiniTableFile_EnumCount(const upb_MiniTableFile* f); + +UPB_API_INLINE const upb_MiniTableExtension* upb_MiniTableFile_Extension( + const upb_MiniTableFile* f, int i); + +UPB_API_INLINE int upb_MiniTableFile_ExtensionCount(const upb_MiniTableFile* f); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableFile_Message( + const upb_MiniTableFile* f, int i); + +UPB_API_INLINE int upb_MiniTableFile_MessageCount(const upb_MiniTableFile* f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_FILE_H_ */ + +#ifndef UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_ +#define UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct UPB_PRIVATE(upb_GeneratedExtensionListEntry) { + const struct upb_MiniTableExtension** start; + const struct upb_MiniTableExtension** stop; + const struct UPB_PRIVATE(upb_GeneratedExtensionListEntry) * next; +} UPB_PRIVATE(upb_GeneratedExtensionListEntry); + +struct upb_GeneratedRegistryRef { + struct upb_Arena* UPB_PRIVATE(arena); + const struct upb_ExtensionRegistry* UPB_PRIVATE(registry); +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_ */ + +// upb_decode: parsing into a upb_Message using a upb_MiniTable. + +#ifndef UPB_WIRE_DECODE_H_ +#define UPB_WIRE_DECODE_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// LINT.IfChange +enum { + /* If set, strings and unknown fields will alias the input buffer instead of + * copying into the arena. */ + kUpb_DecodeOption_AliasString = 1, + + /* If set, the parse will return failure if any message is missing any + * required fields when the message data ends. The parse will still continue, + * and the failure will only be reported at the end. + * + * IMPORTANT CAVEATS: + * + * 1. This can throw a false positive failure if an incomplete message is seen + * on the wire but is later completed when the sub-message occurs again. + * For this reason, a second pass is required to verify a failure, to be + * truly robust. + * + * 2. This can return a false success if you are decoding into a message that + * already has some sub-message fields present. If the sub-message does + * not occur in the binary payload, we will never visit it and discover the + * incomplete sub-message. For this reason, this check is only useful for + * implementing ParseFromString() semantics. For MergeFromString(), a + * post-parse validation step will always be necessary. */ + kUpb_DecodeOption_CheckRequired = 2, + + /* EXPERIMENTAL: + * + * If set, decoding will enforce UTF-8 validation for string fields, even for + * proto2 or fields with `features.utf8_validation = NONE`. Normally, only + * proto3 string fields will be validated for UTF-8. Decoding will return + * kUpb_DecodeStatus_BadUtf8 for non-UTF-8 strings, which is the same behavior + * as non-UTF-8 proto3 string fields. + */ + kUpb_DecodeOption_AlwaysValidateUtf8 = 8, + + /* EXPERIMENTAL: + * + * If set, the fasttable decoder will not be used. */ + kUpb_DecodeOption_DisableFastTable = 16, +}; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/wire.rs:decode_status) + +UPB_INLINE uint32_t upb_DecodeOptions_MaxDepth(uint16_t depth) { + return (uint32_t)depth << 16; +} + +uint16_t upb_DecodeOptions_GetEffectiveMaxDepth(uint32_t options); + +// Enforce an upper bound on recursion depth. +UPB_INLINE int upb_Decode_LimitDepth(uint32_t decode_options, uint32_t limit) { + uint32_t max_depth = upb_DecodeOptions_GetEffectiveMaxDepth(decode_options); + if (max_depth > limit) max_depth = limit; + return (int)(upb_DecodeOptions_MaxDepth(max_depth) | + (decode_options & 0xffff)); +} + +// LINT.IfChange +typedef enum { + kUpb_DecodeStatus_Ok = 0, + kUpb_DecodeStatus_OutOfMemory = 1, // Arena alloc failed + kUpb_DecodeStatus_Malformed = 2, // Wire format was corrupt + kUpb_DecodeStatus_BadUtf8 = 3, // String field had bad UTF-8 + kUpb_DecodeStatus_MaxDepthExceeded = + 4, // Exceeded upb_DecodeOptions_MaxDepth + + // kUpb_DecodeOption_CheckRequired failed (see above), but the parse otherwise + // succeeded. + kUpb_DecodeStatus_MissingRequired = 5, +} upb_DecodeStatus; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/sys/wire/wire.rs:decode_status) + +UPB_API upb_DecodeStatus upb_Decode(const char* buf, size_t size, + upb_Message* msg, const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena); + +// Same as upb_Decode but with a varint-encoded length prepended. +// On success 'num_bytes_read' will be set to the how many bytes were read, +// on failure the contents of num_bytes_read is undefined. +UPB_API upb_DecodeStatus upb_DecodeLengthPrefixed( + const char* buf, size_t size, upb_Message* msg, size_t* num_bytes_read, + const upb_MiniTable* mt, const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena); + +// For testing: decode with tracing. +UPB_API upb_DecodeStatus upb_DecodeWithTrace( + const char* buf, size_t size, upb_Message* msg, const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, int options, upb_Arena* arena, + char* trace_buf, size_t trace_size); + +// Utility function for wrapper languages to get an error string from a +// upb_DecodeStatus. +UPB_API const char* upb_DecodeStatus_String(upb_DecodeStatus status); +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_DECODE_H_ */ + +// upb_Encode: parsing from a upb_Message using a upb_MiniTable. + +#ifndef UPB_WIRE_ENCODE_H_ +#define UPB_WIRE_ENCODE_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + /* If set, the results of serializing will be deterministic across all + * instances of this binary. There are no guarantees across different + * binary builds. + * + * If your proto contains maps, the encoder will need to malloc()/free() + * memory during encode. */ + kUpb_EncodeOption_Deterministic = 1, + + // When set, unknown fields are not encoded. + kUpb_EncodeOption_SkipUnknown = 2, + + // When set, the encode will fail if any required fields are missing. + kUpb_EncodeOption_CheckRequired = 4, +}; + +// LINT.IfChange +typedef enum { + kUpb_EncodeStatus_Ok = 0, + kUpb_EncodeStatus_OutOfMemory = 1, // Arena alloc failed + kUpb_EncodeStatus_MaxDepthExceeded = 2, + + // One or more required fields are missing. Only returned if + // kUpb_EncodeOption_CheckRequired is set. + kUpb_EncodeStatus_MissingRequired = 3, + + // The message is larger than protobuf's 2GB size limit. + kUpb_EncodeStatus_MaxSizeExceeded = 4, +} upb_EncodeStatus; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/sys/wire/wire.rs:encode_status) + +UPB_INLINE uint32_t upb_EncodeOptions_MaxDepth(uint16_t depth) { + return (uint32_t)depth << 16; +} + +uint16_t upb_EncodeOptions_GetEffectiveMaxDepth(uint32_t options); + +// Enforce an upper bound on recursion depth. +UPB_INLINE int upb_Encode_LimitDepth(uint32_t encode_options, uint32_t limit) { + uint32_t max_depth = upb_EncodeOptions_GetEffectiveMaxDepth(encode_options); + if (max_depth > limit) max_depth = limit; + return (int)(upb_EncodeOptions_MaxDepth(max_depth) | + (encode_options & 0xffff)); +} + +UPB_API upb_EncodeStatus upb_Encode(const upb_Message* msg, + const upb_MiniTable* l, int options, + upb_Arena* arena, char** buf, size_t* size); + +// Encodes the message prepended by a varint of the serialized length. +UPB_API upb_EncodeStatus upb_EncodeLengthPrefixed(const upb_Message* msg, + const upb_MiniTable* l, + int options, upb_Arena* arena, + char** buf, size_t* size); +// Utility function for wrapper languages to get an error string from a +// upb_EncodeStatus. +UPB_API const char* upb_EncodeStatus_String(upb_EncodeStatus status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_ENCODE_H_ */ +#ifdef UPB_INCLUDE_FAST_DECODE +#endif +// IWYU pragma: end_exports + +#undef UPB_INCLUDE_FAST_DECODE + +#endif // UPB_GENERATED_CODE_SUPPORT_H_ +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable google__protobuf__FileDescriptorSet_msg_init; +extern const upb_MiniTable google__protobuf__FileDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__DescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__DescriptorProto__ExtensionRange_msg_init; +extern const upb_MiniTable google__protobuf__DescriptorProto__ReservedRange_msg_init; +extern const upb_MiniTable google__protobuf__ExtensionRangeOptions_msg_init; +extern const upb_MiniTable google__protobuf__ExtensionRangeOptions__Declaration_msg_init; +extern const upb_MiniTable google__protobuf__FieldDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__OneofDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__EnumDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init; +extern const upb_MiniTable google__protobuf__EnumValueDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__ServiceDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__MethodDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__FileOptions_msg_init; +extern const upb_MiniTable google__protobuf__MessageOptions_msg_init; +extern const upb_MiniTable google__protobuf__FieldOptions_msg_init; +extern const upb_MiniTable google__protobuf__FieldOptions__EditionDefault_msg_init; +extern const upb_MiniTable google__protobuf__FieldOptions__FeatureSupport_msg_init; +extern const upb_MiniTable google__protobuf__OneofOptions_msg_init; +extern const upb_MiniTable google__protobuf__EnumOptions_msg_init; +extern const upb_MiniTable google__protobuf__EnumValueOptions_msg_init; +extern const upb_MiniTable google__protobuf__ServiceOptions_msg_init; +extern const upb_MiniTable google__protobuf__MethodOptions_msg_init; +extern const upb_MiniTable google__protobuf__UninterpretedOption_msg_init; +extern const upb_MiniTable google__protobuf__UninterpretedOption__NamePart_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSet_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSet__VisibilityFeature_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSetDefaults_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init; +extern const upb_MiniTable google__protobuf__SourceCodeInfo_msg_init; +extern const upb_MiniTable google__protobuf__SourceCodeInfo__Location_msg_init; +extern const upb_MiniTable google__protobuf__GeneratedCodeInfo_msg_init; +extern const upb_MiniTable google__protobuf__GeneratedCodeInfo__Annotation_msg_init; + +extern const upb_MiniTableEnum google__protobuf__Edition_enum_init; +extern const upb_MiniTableEnum google__protobuf__ExtensionRangeOptions__VerificationState_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__EnforceNamingStyle_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__EnumType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__FieldPresence_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__JsonFormat_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__MessageEncoding_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__Utf8Validation_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Label_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Type_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__CType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__JSType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__OptionRetention_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__OptionTargetType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FileOptions__OptimizeMode_enum_init; +extern const upb_MiniTableEnum google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init; +extern const upb_MiniTableEnum google__protobuf__MethodOptions__IdempotencyLevel_enum_init; +extern const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init; +extern const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ */ + +#ifndef UPB_BASE_INTERNAL_LOG2_H_ +#define UPB_BASE_INTERNAL_LOG2_H_ + +#include +#include +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE int upb_Log2Ceiling(size_t x) { + if (x <= 1) return 0; +#if SIZE_MAX == ULLONG_MAX && UPB_HAS_BUILTIN(__builtin_clzll) + return (sizeof(size_t) * CHAR_BIT) - __builtin_clzll(x - 1); +#elif SIZE_MAX == ULONG_MAX && UPB_HAS_BUILTIN(__builtin_clzl) + return (sizeof(size_t) * CHAR_BIT) - __builtin_clzl(x - 1); +#elif SIZE_MAX == UINT_MAX && UPB_HAS_BUILTIN(__builtin_clz) + return (sizeof(size_t) * CHAR_BIT) - __builtin_clz(x - 1); +#else + if (x > SIZE_MAX / 2) return sizeof(size_t) * CHAR_BIT; + int lg2 = 0; + while ((1 << lg2) < x) lg2++; + return lg2; +#endif +} + +// Returns the smallest power of two that is greater than or equal to x. Returns +// SIZE_MAX if the computation would overflow. +UPB_INLINE size_t upb_RoundUpToPowerOfTwo(size_t x) { + int lg2 = upb_Log2Ceiling(x); + UPB_ASSERT(lg2 >= 0 && lg2 <= (int)sizeof(size_t) * CHAR_BIT); + if (lg2 == sizeof(size_t) * CHAR_BIT) { + return SIZE_MAX; + } + return ((size_t)1) << lg2; +} + +UPB_INLINE bool upb_ShlOverflow(size_t* a, unsigned int b) { + if (*a > (SIZE_MAX >> b)) { + return true; + } + *a <<= b; + return false; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_INTERNAL_LOG2_H_ */ + +#ifndef UPB_HASH_EXT_TABLE_H_ +#define UPB_HASH_EXT_TABLE_H_ + +#include +#include + + +// Must be last. + +typedef struct { + upb_table t; +} upb_exttable; + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize a table. If memory allocation failed, false is returned and +// the table is uninitialized. +bool upb_exttable_init(upb_exttable* table, size_t expected_size, upb_Arena* a); + +// Returns the number of values in the table. +UPB_INLINE size_t upb_exttable_count(const upb_exttable* t) { + return t->t.count; +} + +void upb_exttable_clear(upb_exttable* t); + +// Inserts the given key and value into the hashtable. +// The key must not already exist in the hash table, and must not be NULL. +// +// If a table resize was required but memory allocation failed, false is +// returned and the table is unchanged. +bool upb_exttable_insert(upb_exttable* t, const void* k, const uint32_t* v, + upb_Arena* a); + +// Looks up key and ext_number in this table, returning the value if the key was +// found, or NULL otherwise. +const uint32_t* upb_exttable_lookup(const upb_exttable* t, const void* k, + uint32_t ext_number); + +// Removes an item from the table. Returns the removed item if the remove was +// successful, or NULL if the key was not found. +const uint32_t* upb_exttable_remove(upb_exttable* t, const void* k, + uint32_t ext_number); + +size_t upb_exttable_size(const upb_exttable* t); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_EXT_TABLE_H_ */ + +#ifndef UPB_JSON_DECODE_H_ +#define UPB_JSON_DECODE_H_ + +#include + + +#ifndef UPB_REFLECTION_DEF_H_ +#define UPB_REFLECTION_DEF_H_ + +// IWYU pragma: begin_exports + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_DEF_POOL_H_ +#define UPB_REFLECTION_DEF_POOL_H_ + + +// IWYU pragma: private, include "upb/reflection/def.h" + +// Declarations common to all public def types. + +#ifndef UPB_REFLECTION_COMMON_H_ +#define UPB_REFLECTION_COMMON_H_ + +#ifndef GOOGLE_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H__ +#define GOOGLE_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H__ + +// IWYU pragma: begin_exports + +#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +// This header is checked in. +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 1 +// This header is generated at build time by the bootstrapping process. +#else +// This is the normal header, generated by upb_c_proto_library(). +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct google_protobuf_FileDescriptorSet { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FileDescriptorSet; + +typedef struct google_protobuf_FileDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FileDescriptorProto; + +typedef struct google_protobuf_DescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_DescriptorProto; + +typedef struct google_protobuf_DescriptorProto_ExtensionRange { + upb_Message UPB_PRIVATE(base); +} google_protobuf_DescriptorProto_ExtensionRange; + +typedef struct google_protobuf_DescriptorProto_ReservedRange { + upb_Message UPB_PRIVATE(base); +} google_protobuf_DescriptorProto_ReservedRange; + +typedef struct google_protobuf_ExtensionRangeOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ExtensionRangeOptions; + +typedef struct google_protobuf_ExtensionRangeOptions_Declaration { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ExtensionRangeOptions_Declaration; + +typedef struct google_protobuf_FieldDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldDescriptorProto; + +typedef struct google_protobuf_OneofDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_OneofDescriptorProto; + +typedef struct google_protobuf_EnumDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumDescriptorProto; + +typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumDescriptorProto_EnumReservedRange; + +typedef struct google_protobuf_EnumValueDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumValueDescriptorProto; + +typedef struct google_protobuf_ServiceDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ServiceDescriptorProto; + +typedef struct google_protobuf_MethodDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_MethodDescriptorProto; + +typedef struct google_protobuf_FileOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FileOptions; + +typedef struct google_protobuf_MessageOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_MessageOptions; + +typedef struct google_protobuf_FieldOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldOptions; + +typedef struct google_protobuf_FieldOptions_EditionDefault { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldOptions_EditionDefault; + +typedef struct google_protobuf_FieldOptions_FeatureSupport { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldOptions_FeatureSupport; + +typedef struct google_protobuf_OneofOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_OneofOptions; + +typedef struct google_protobuf_EnumOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumOptions; + +typedef struct google_protobuf_EnumValueOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumValueOptions; + +typedef struct google_protobuf_ServiceOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ServiceOptions; + +typedef struct google_protobuf_MethodOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_MethodOptions; + +typedef struct google_protobuf_UninterpretedOption { + upb_Message UPB_PRIVATE(base); +} google_protobuf_UninterpretedOption; + +typedef struct google_protobuf_UninterpretedOption_NamePart { + upb_Message UPB_PRIVATE(base); +} google_protobuf_UninterpretedOption_NamePart; + +typedef struct google_protobuf_FeatureSet { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSet; + +typedef struct google_protobuf_FeatureSet_VisibilityFeature { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSet_VisibilityFeature; + +typedef struct google_protobuf_FeatureSetDefaults { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSetDefaults; + +typedef struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault; + +typedef struct google_protobuf_SourceCodeInfo { + upb_Message UPB_PRIVATE(base); +} google_protobuf_SourceCodeInfo; + +typedef struct google_protobuf_SourceCodeInfo_Location { + upb_Message UPB_PRIVATE(base); +} google_protobuf_SourceCodeInfo_Location; + +typedef struct google_protobuf_GeneratedCodeInfo { + upb_Message UPB_PRIVATE(base); +} google_protobuf_GeneratedCodeInfo; + +typedef struct google_protobuf_GeneratedCodeInfo_Annotation { + upb_Message UPB_PRIVATE(base); +} google_protobuf_GeneratedCodeInfo_Annotation; + + +typedef enum { + google_protobuf_EDITION_UNKNOWN = 0, + google_protobuf_EDITION_1_TEST_ONLY = 1, + google_protobuf_EDITION_2_TEST_ONLY = 2, + google_protobuf_EDITION_LEGACY = 900, + google_protobuf_EDITION_PROTO2 = 998, + google_protobuf_EDITION_PROTO3 = 999, + google_protobuf_EDITION_2023 = 1000, + google_protobuf_EDITION_2024 = 1001, + google_protobuf_EDITION_2026 = 1002, + google_protobuf_EDITION_UNSTABLE = 9999, + google_protobuf_EDITION_99997_TEST_ONLY = 99997, + google_protobuf_EDITION_99998_TEST_ONLY = 99998, + google_protobuf_EDITION_99999_TEST_ONLY = 99999, + google_protobuf_EDITION_MAX = 2147483647 +} google_protobuf_Edition; + +typedef enum { + google_protobuf_ExtensionRangeOptions_DECLARATION = 0, + google_protobuf_ExtensionRangeOptions_UNVERIFIED = 1 +} google_protobuf_ExtensionRangeOptions_VerificationState; + +typedef enum { + google_protobuf_FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN = 0, + google_protobuf_FeatureSet_STYLE2024 = 1, + google_protobuf_FeatureSet_STYLE_LEGACY = 2, + google_protobuf_FeatureSet_STYLE2026 = 3 +} google_protobuf_FeatureSet_EnforceNamingStyle; + +typedef enum { + google_protobuf_FeatureSet_ENUM_TYPE_UNKNOWN = 0, + google_protobuf_FeatureSet_OPEN = 1, + google_protobuf_FeatureSet_CLOSED = 2 +} google_protobuf_FeatureSet_EnumType; + +typedef enum { + google_protobuf_FeatureSet_FIELD_PRESENCE_UNKNOWN = 0, + google_protobuf_FeatureSet_EXPLICIT = 1, + google_protobuf_FeatureSet_IMPLICIT = 2, + google_protobuf_FeatureSet_LEGACY_REQUIRED = 3 +} google_protobuf_FeatureSet_FieldPresence; + +typedef enum { + google_protobuf_FeatureSet_JSON_FORMAT_UNKNOWN = 0, + google_protobuf_FeatureSet_ALLOW = 1, + google_protobuf_FeatureSet_LEGACY_BEST_EFFORT = 2 +} google_protobuf_FeatureSet_JsonFormat; + +typedef enum { + google_protobuf_FeatureSet_MESSAGE_ENCODING_UNKNOWN = 0, + google_protobuf_FeatureSet_LENGTH_PREFIXED = 1, + google_protobuf_FeatureSet_DELIMITED = 2 +} google_protobuf_FeatureSet_MessageEncoding; + +typedef enum { + google_protobuf_FeatureSet_REPEATED_FIELD_ENCODING_UNKNOWN = 0, + google_protobuf_FeatureSet_PACKED = 1, + google_protobuf_FeatureSet_EXPANDED = 2 +} google_protobuf_FeatureSet_RepeatedFieldEncoding; + +typedef enum { + google_protobuf_FeatureSet_UTF8_VALIDATION_UNKNOWN = 0, + google_protobuf_FeatureSet_VERIFY = 2, + google_protobuf_FeatureSet_NONE = 3 +} google_protobuf_FeatureSet_Utf8Validation; + +typedef enum { + google_protobuf_FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN = 0, + google_protobuf_FeatureSet_VisibilityFeature_EXPORT_ALL = 1, + google_protobuf_FeatureSet_VisibilityFeature_EXPORT_TOP_LEVEL = 2, + google_protobuf_FeatureSet_VisibilityFeature_LOCAL_ALL = 3, + google_protobuf_FeatureSet_VisibilityFeature_STRICT = 4 +} google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility; + +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + +typedef enum { + google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, + google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, + google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3, + google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4, + google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5, + google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6, + google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7, + google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8, + google_protobuf_FieldDescriptorProto_TYPE_STRING = 9, + google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10, + google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11, + google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12, + google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13, + google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16, + google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17, + google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 +} google_protobuf_FieldDescriptorProto_Type; + +typedef enum { + google_protobuf_FieldOptions_STRING = 0, + google_protobuf_FieldOptions_CORD = 1, + google_protobuf_FieldOptions_STRING_PIECE = 2 +} google_protobuf_FieldOptions_CType; + +typedef enum { + google_protobuf_FieldOptions_JS_NORMAL = 0, + google_protobuf_FieldOptions_JS_STRING = 1, + google_protobuf_FieldOptions_JS_NUMBER = 2 +} google_protobuf_FieldOptions_JSType; + +typedef enum { + google_protobuf_FieldOptions_RETENTION_UNKNOWN = 0, + google_protobuf_FieldOptions_RETENTION_RUNTIME = 1, + google_protobuf_FieldOptions_RETENTION_SOURCE = 2 +} google_protobuf_FieldOptions_OptionRetention; + +typedef enum { + google_protobuf_FieldOptions_TARGET_TYPE_UNKNOWN = 0, + google_protobuf_FieldOptions_TARGET_TYPE_FILE = 1, + google_protobuf_FieldOptions_TARGET_TYPE_EXTENSION_RANGE = 2, + google_protobuf_FieldOptions_TARGET_TYPE_MESSAGE = 3, + google_protobuf_FieldOptions_TARGET_TYPE_FIELD = 4, + google_protobuf_FieldOptions_TARGET_TYPE_ONEOF = 5, + google_protobuf_FieldOptions_TARGET_TYPE_ENUM = 6, + google_protobuf_FieldOptions_TARGET_TYPE_ENUM_ENTRY = 7, + google_protobuf_FieldOptions_TARGET_TYPE_SERVICE = 8, + google_protobuf_FieldOptions_TARGET_TYPE_METHOD = 9 +} google_protobuf_FieldOptions_OptionTargetType; + +typedef enum { + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; + +typedef enum { + google_protobuf_GeneratedCodeInfo_Annotation_NONE = 0, + google_protobuf_GeneratedCodeInfo_Annotation_SET = 1, + google_protobuf_GeneratedCodeInfo_Annotation_ALIAS = 2 +} google_protobuf_GeneratedCodeInfo_Annotation_Semantic; + +typedef enum { + google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, + google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, + google_protobuf_MethodOptions_IDEMPOTENT = 2 +} google_protobuf_MethodOptions_IdempotencyLevel; + +typedef enum { + google_protobuf_VISIBILITY_UNSET = 0, + google_protobuf_VISIBILITY_LOCAL = 1, + google_protobuf_VISIBILITY_EXPORT = 2 +} google_protobuf_SymbolVisibility; + + + +/* google.protobuf.FileDescriptorSet */ +UPB_INLINE google_protobuf_FileDescriptorSet* google_protobuf_FileDescriptorSet_new(upb_Arena* arena) { + return (google_protobuf_FileDescriptorSet*)_upb_Message_New(&google__protobuf__FileDescriptorSet_msg_init, arena); +} +UPB_INLINE google_protobuf_FileDescriptorSet* google_protobuf_FileDescriptorSet_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FileDescriptorSet* ret = google_protobuf_FileDescriptorSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorSet_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FileDescriptorSet* google_protobuf_FileDescriptorSet_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileDescriptorSet* ret = google_protobuf_FileDescriptorSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorSet_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorSet_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FileDescriptorSet_serialize_ex(const google_protobuf_FileDescriptorSet* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorSet_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FileDescriptorSet_clear_file(google_protobuf_FileDescriptorSet* msg) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FileDescriptorProto* const* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet* msg, + size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FileDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorSet_file_upb_array( + const google_protobuf_FileDescriptorSet* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorSet_file_mutable_upb_array( + google_protobuf_FileDescriptorSet* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_mutable_file(google_protobuf_FileDescriptorSet* msg, + size_t* size) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FileDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + return (google_protobuf_FileDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file( + google_protobuf_FileDescriptorSet* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FileDescriptorProto* sub = + (struct google_protobuf_FileDescriptorProto*)_upb_Message_New(&google__protobuf__FileDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.FileDescriptorProto */ +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_FileDescriptorProto*)_upb_Message_New(&google__protobuf__FileDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FileDescriptorProto* ret = google_protobuf_FileDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileDescriptorProto* ret = google_protobuf_FileDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FileDescriptorProto_serialize_ex(const google_protobuf_FileDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_name(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_package(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_message_type(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_message_type_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_message_type_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_enum_type(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_enum_type_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_enum_type_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_service(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_ServiceDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_service_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_service_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_extension(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_extension_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_extension_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_options(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto* msg) { + const google_protobuf_FileOptions* default_val = NULL; + const google_protobuf_FileOptions* ret; + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_source_code_info(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto* msg) { + const google_protobuf_SourceCodeInfo* default_val = NULL; + const google_protobuf_SourceCodeInfo* ret; + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_public_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_public_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_public_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_weak_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_weak_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_weak_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_syntax(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_edition(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FileDescriptorProto_edition(const google_protobuf_FileDescriptorProto* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_edition(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_option_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_FileDescriptorProto_option_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_option_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_option_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_mutable_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + return (google_protobuf_DescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto* sub = + (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + return (google_protobuf_EnumDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumDescriptorProto* sub = + (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_ServiceDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + return (google_protobuf_ServiceDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_ServiceDescriptorProto* sub = + (struct google_protobuf_ServiceDescriptorProto*)_upb_Message_New(&google__protobuf__ServiceDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + return (google_protobuf_FieldDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldDescriptorProto* sub = + (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto* msg, google_protobuf_FileOptions* value) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_FileOptions* sub = (struct google_protobuf_FileOptions*)google_protobuf_FileDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FileOptions*)_upb_Message_New(&google__protobuf__FileOptions_msg_init, arena); + if (sub) google_protobuf_FileDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto* msg, google_protobuf_SourceCodeInfo* value) { + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_SourceCodeInfo* sub = (struct google_protobuf_SourceCodeInfo*)google_protobuf_FileDescriptorProto_source_code_info(msg); + if (sub == NULL) { + sub = (struct google_protobuf_SourceCodeInfo*)_upb_Message_New(&google__protobuf__SourceCodeInfo_msg_init, arena); + if (sub) google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub); + } + return sub; +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_edition(google_protobuf_FileDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_mutable_option_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_resize_option_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_option_dependency(google_protobuf_FileDescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} + +/* google.protobuf.DescriptorProto */ +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_DescriptorProto* ret = google_protobuf_DescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto* ret = google_protobuf_DescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_DescriptorProto_serialize_ex(const google_protobuf_DescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_name(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_field(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_field_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_field_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_nested_type(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_nested_type_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_nested_type_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_enum_type(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_enum_type_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_enum_type_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_extension_range(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto_ExtensionRange* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_extension_range_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_extension_range_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_extension(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_extension_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_extension_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_options(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto* msg) { + const google_protobuf_MessageOptions* default_val = NULL; + const google_protobuf_MessageOptions* ret; + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MessageOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_oneof_decl(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_OneofDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_oneof_decl_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_oneof_decl_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_reserved_range(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto_ReservedRange* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_reserved_range_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_reserved_range_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_reserved_name(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_reserved_name_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_reserved_name_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_visibility(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_visibility(const google_protobuf_DescriptorProto* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_visibility(const google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_field(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + return (google_protobuf_FieldDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldDescriptorProto* sub = + (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + return (google_protobuf_DescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto* sub = + (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + return (google_protobuf_EnumDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumDescriptorProto* sub = + (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto_ExtensionRange**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + return (google_protobuf_DescriptorProto_ExtensionRange**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto_ExtensionRange* sub = + (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ExtensionRange_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + return (google_protobuf_FieldDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldDescriptorProto* sub = + (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto* msg, google_protobuf_MessageOptions* value) { + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MessageOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProto_mutable_options( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_MessageOptions* sub = (struct google_protobuf_MessageOptions*)google_protobuf_DescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MessageOptions*)_upb_Message_New(&google__protobuf__MessageOptions_msg_init, arena); + if (sub) google_protobuf_DescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_mutable_oneof_decl(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_OneofDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + return (google_protobuf_OneofDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_OneofDescriptorProto* sub = + (struct google_protobuf_OneofDescriptorProto*)_upb_Message_New(&google__protobuf__OneofDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto_ReservedRange**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + return (google_protobuf_DescriptorProto_ReservedRange**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto_ReservedRange* sub = + (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ReservedRange_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE upb_StringView* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_visibility(google_protobuf_DescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.DescriptorProto.ExtensionRange */ +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_ExtensionRange_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto_ExtensionRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ExtensionRange_msg_init, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_ExtensionRange_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_DescriptorProto_ExtensionRange* ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_ExtensionRange_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto_ExtensionRange* ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ExtensionRange_serialize_ex(const google_protobuf_DescriptorProto_ExtensionRange* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_clear_start(google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_clear_end(google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_clear_options(google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const google_protobuf_ExtensionRangeOptions* default_val = NULL; + const google_protobuf_ExtensionRangeOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange* msg, google_protobuf_ExtensionRangeOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_mutable_options( + google_protobuf_DescriptorProto_ExtensionRange* msg, upb_Arena* arena) { + struct google_protobuf_ExtensionRangeOptions* sub = (struct google_protobuf_ExtensionRangeOptions*)google_protobuf_DescriptorProto_ExtensionRange_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ExtensionRangeOptions*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions_msg_init, arena); + if (sub) google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.DescriptorProto.ReservedRange */ +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto_ReservedRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ReservedRange_msg_init, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_DescriptorProto_ReservedRange* ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ReservedRange_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto_ReservedRange* ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ReservedRange_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ReservedRange_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ReservedRange_serialize_ex(const google_protobuf_DescriptorProto_ReservedRange* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ReservedRange_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_clear_start(google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_clear_end(google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.ExtensionRangeOptions */ +UPB_INLINE google_protobuf_ExtensionRangeOptions* google_protobuf_ExtensionRangeOptions_new(upb_Arena* arena) { + return (google_protobuf_ExtensionRangeOptions*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions* google_protobuf_ExtensionRangeOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions* ret = google_protobuf_ExtensionRangeOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ExtensionRangeOptions* google_protobuf_ExtensionRangeOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions* ret = google_protobuf_ExtensionRangeOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_serialize_ex(const google_protobuf_ExtensionRangeOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_declaration(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ExtensionRangeOptions_Declaration* const* google_protobuf_ExtensionRangeOptions_declaration(const google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_ExtensionRangeOptions_Declaration* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ExtensionRangeOptions_declaration_upb_array( + const google_protobuf_ExtensionRangeOptions* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ExtensionRangeOptions_declaration_mutable_upb_array( + google_protobuf_ExtensionRangeOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_verification(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_ExtensionRangeOptions_verification(const google_protobuf_ExtensionRangeOptions* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_has_verification(const google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_features(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_ExtensionRangeOptions_features(const google_protobuf_ExtensionRangeOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_has_features(const google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_uninterpreted_option(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ExtensionRangeOptions_uninterpreted_option_upb_array( + const google_protobuf_ExtensionRangeOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ExtensionRangeOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_ExtensionRangeOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration** google_protobuf_ExtensionRangeOptions_mutable_declaration(google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_ExtensionRangeOptions_Declaration**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration** google_protobuf_ExtensionRangeOptions_resize_declaration(google_protobuf_ExtensionRangeOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + return (google_protobuf_ExtensionRangeOptions_Declaration**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_add_declaration( + google_protobuf_ExtensionRangeOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_ExtensionRangeOptions_Declaration* sub = + (struct google_protobuf_ExtensionRangeOptions_Declaration*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_verification(google_protobuf_ExtensionRangeOptions* msg, int32_t value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_features(google_protobuf_ExtensionRangeOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_ExtensionRangeOptions_mutable_features( + google_protobuf_ExtensionRangeOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_ExtensionRangeOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_ExtensionRangeOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_mutable_uninterpreted_option(google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option( + google_protobuf_ExtensionRangeOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.ExtensionRangeOptions.Declaration */ +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_Declaration_new(upb_Arena* arena) { + return (google_protobuf_ExtensionRangeOptions_Declaration*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_Declaration_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions_Declaration* ret = google_protobuf_ExtensionRangeOptions_Declaration_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_Declaration_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions_Declaration* ret = google_protobuf_ExtensionRangeOptions_Declaration_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_Declaration_serialize(const google_protobuf_ExtensionRangeOptions_Declaration* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_Declaration_serialize_ex(const google_protobuf_ExtensionRangeOptions_Declaration* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_number(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_ExtensionRangeOptions_Declaration_number(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_number(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_full_name(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_ExtensionRangeOptions_Declaration_full_name(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_full_name(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_type(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_ExtensionRangeOptions_Declaration_type(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_type(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_reserved(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_repeated(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_repeated(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_repeated(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_number(google_protobuf_ExtensionRangeOptions_Declaration* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_full_name(google_protobuf_ExtensionRangeOptions_Declaration* msg, upb_StringView value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_type(google_protobuf_ExtensionRangeOptions_Declaration* msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_reserved(google_protobuf_ExtensionRangeOptions_Declaration* msg, bool value) { + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_repeated(google_protobuf_ExtensionRangeOptions_Declaration* msg, bool value) { + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FieldDescriptorProto */ +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldDescriptorProto* ret = google_protobuf_FieldDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldDescriptorProto* ret = google_protobuf_FieldDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldDescriptorProto_serialize_ex(const google_protobuf_FieldDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_name(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_extendee(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_number(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_label(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_type(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_type_name(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_default_value(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_options(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto* msg) { + const google_protobuf_FieldOptions* default_val = NULL; + const google_protobuf_FieldOptions* ret; + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_oneof_index(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_json_name(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_proto3_optional(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto* msg, google_protobuf_FieldOptions* value) { + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options( + google_protobuf_FieldDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions*)_upb_Message_New(&google__protobuf__FieldOptions_msg_init, arena); + if (sub) google_protobuf_FieldDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto* msg, bool value) { + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.OneofDescriptorProto */ +UPB_INLINE google_protobuf_OneofDescriptorProto* google_protobuf_OneofDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_OneofDescriptorProto*)_upb_Message_New(&google__protobuf__OneofDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_OneofDescriptorProto* google_protobuf_OneofDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_OneofDescriptorProto* ret = google_protobuf_OneofDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_OneofDescriptorProto* google_protobuf_OneofDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_OneofDescriptorProto* ret = google_protobuf_OneofDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_OneofDescriptorProto_serialize_ex(const google_protobuf_OneofDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_clear_name(google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_clear_options(google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto* msg) { + const google_protobuf_OneofOptions* default_val = NULL; + const google_protobuf_OneofOptions* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto* msg, google_protobuf_OneofOptions* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_mutable_options( + google_protobuf_OneofDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_OneofOptions* sub = (struct google_protobuf_OneofOptions*)google_protobuf_OneofDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_OneofOptions*)_upb_Message_New(&google__protobuf__OneofOptions_msg_init, arena); + if (sub) google_protobuf_OneofDescriptorProto_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.EnumDescriptorProto */ +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumDescriptorProto* ret = google_protobuf_EnumDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumDescriptorProto* ret = google_protobuf_EnumDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_serialize_ex(const google_protobuf_EnumDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_name(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_value(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumValueDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumDescriptorProto_value_upb_array( + const google_protobuf_EnumDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumDescriptorProto_value_mutable_upb_array( + google_protobuf_EnumDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_options(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto* msg) { + const google_protobuf_EnumOptions* default_val = NULL; + const google_protobuf_EnumOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_reserved_range(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumDescriptorProto_reserved_range_upb_array( + const google_protobuf_EnumDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumDescriptorProto_reserved_range_mutable_upb_array( + google_protobuf_EnumDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_reserved_name(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumDescriptorProto_reserved_name_upb_array( + const google_protobuf_EnumDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumDescriptorProto_reserved_name_mutable_upb_array( + google_protobuf_EnumDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_visibility(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_visibility(const google_protobuf_EnumDescriptorProto* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_visibility(const google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_mutable_value(google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumValueDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + return (google_protobuf_EnumValueDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value( + google_protobuf_EnumDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumValueDescriptorProto* sub = + (struct google_protobuf_EnumValueDescriptorProto*)_upb_Message_New(&google__protobuf__EnumValueDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto* msg, google_protobuf_EnumOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_mutable_options( + google_protobuf_EnumDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_EnumOptions* sub = (struct google_protobuf_EnumOptions*)google_protobuf_EnumDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumOptions*)_upb_Message_New(&google__protobuf__EnumOptions_msg_init, arena); + if (sub) google_protobuf_EnumDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_mutable_reserved_range(google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range( + google_protobuf_EnumDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = + (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_Message_New(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE upb_StringView* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_visibility(google_protobuf_EnumDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_Arena* arena) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_Message_New(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_EnumReservedRange_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize_ex(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_clear_start(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_clear_end(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.EnumValueDescriptorProto */ +UPB_INLINE google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumValueDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_EnumValueDescriptorProto*)_upb_Message_New(&google__protobuf__EnumValueDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumValueDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumValueDescriptorProto* ret = google_protobuf_EnumValueDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumValueDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumValueDescriptorProto* ret = google_protobuf_EnumValueDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumValueDescriptorProto_serialize_ex(const google_protobuf_EnumValueDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_clear_name(google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_clear_number(google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_clear_options(google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto* msg) { + const google_protobuf_EnumValueOptions* default_val = NULL; + const google_protobuf_EnumValueOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto* msg, google_protobuf_EnumValueOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_mutable_options( + google_protobuf_EnumValueDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_EnumValueOptions* sub = (struct google_protobuf_EnumValueOptions*)google_protobuf_EnumValueDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumValueOptions*)_upb_Message_New(&google__protobuf__EnumValueOptions_msg_init, arena); + if (sub) google_protobuf_EnumValueDescriptorProto_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.ServiceDescriptorProto */ +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_ServiceDescriptorProto*)_upb_Message_New(&google__protobuf__ServiceDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ServiceDescriptorProto* ret = google_protobuf_ServiceDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ServiceDescriptorProto* ret = google_protobuf_ServiceDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ServiceDescriptorProto_serialize_ex(const google_protobuf_ServiceDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_clear_name(google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_clear_method(google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_MethodDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ServiceDescriptorProto_method_upb_array( + const google_protobuf_ServiceDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ServiceDescriptorProto_method_mutable_upb_array( + google_protobuf_ServiceDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_clear_options(google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto* msg) { + const google_protobuf_ServiceOptions* default_val = NULL; + const google_protobuf_ServiceOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_mutable_method(google_protobuf_ServiceDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_MethodDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + return (google_protobuf_MethodDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method( + google_protobuf_ServiceDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_MethodDescriptorProto* sub = + (struct google_protobuf_MethodDescriptorProto*)_upb_Message_New(&google__protobuf__MethodDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto* msg, google_protobuf_ServiceOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_mutable_options( + google_protobuf_ServiceDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_ServiceOptions* sub = (struct google_protobuf_ServiceOptions*)google_protobuf_ServiceDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ServiceOptions*)_upb_Message_New(&google__protobuf__ServiceOptions_msg_init, arena); + if (sub) google_protobuf_ServiceDescriptorProto_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.MethodDescriptorProto */ +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_MethodDescriptorProto*)_upb_Message_New(&google__protobuf__MethodDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_MethodDescriptorProto* ret = google_protobuf_MethodDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MethodDescriptorProto* ret = google_protobuf_MethodDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_MethodDescriptorProto_serialize_ex(const google_protobuf_MethodDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_name(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_input_type(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_output_type(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_options(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto* msg) { + const google_protobuf_MethodOptions* default_val = NULL; + const google_protobuf_MethodOptions* ret; + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_client_streaming(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_server_streaming(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto* msg, google_protobuf_MethodOptions* value) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options( + google_protobuf_MethodDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_MethodOptions* sub = (struct google_protobuf_MethodOptions*)google_protobuf_MethodDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MethodOptions*)_upb_Message_New(&google__protobuf__MethodOptions_msg_init, arena); + if (sub) google_protobuf_MethodDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto* msg, bool value) { + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto* msg, bool value) { + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FileOptions */ +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_new(upb_Arena* arena) { + return (google_protobuf_FileOptions*)_upb_Message_New(&google__protobuf__FileOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FileOptions* ret = google_protobuf_FileOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileOptions* ret = google_protobuf_FileOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FileOptions_serialize_ex(const google_protobuf_FileOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_package(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_outer_classname(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_optimize_for(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_multiple_files(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_go_package(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_cc_generic_services(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_generic_services(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_py_generic_services(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_generate_equals_and_hash(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_deprecated(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_string_check_utf8(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_cc_enable_arenas(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions* msg) { + bool default_val = true; + bool ret; + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_objc_class_prefix(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_csharp_namespace(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_swift_prefix(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_php_class_prefix(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_php_namespace(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_php_metadata_namespace(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_ruby_package(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_features(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FileOptions_features(const google_protobuf_FileOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_features(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_uninterpreted_option(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileOptions_uninterpreted_option_upb_array( + const google_protobuf_FileOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_FileOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions* msg, int32_t value) { + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_features(google_protobuf_FileOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FileOptions_mutable_features( + google_protobuf_FileOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FileOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FileOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option( + google_protobuf_FileOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.MessageOptions */ +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_new(upb_Arena* arena) { + return (google_protobuf_MessageOptions*)_upb_Message_New(&google__protobuf__MessageOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_MessageOptions* ret = google_protobuf_MessageOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MessageOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MessageOptions* ret = google_protobuf_MessageOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MessageOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MessageOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_MessageOptions_serialize_ex(const google_protobuf_MessageOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MessageOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_MessageOptions_clear_message_set_wire_format(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_no_standard_descriptor_accessor(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_deprecated(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_map_entry(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_deprecated_legacy_json_field_conflicts(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_deprecated_legacy_json_field_conflicts(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated_legacy_json_field_conflicts(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_features(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_MessageOptions_features(const google_protobuf_MessageOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_features(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_uninterpreted_option(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_MessageOptions_uninterpreted_option_upb_array( + const google_protobuf_MessageOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_MessageOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_MessageOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated_legacy_json_field_conflicts(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_features(google_protobuf_MessageOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_MessageOptions_mutable_features( + google_protobuf_MessageOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_MessageOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_MessageOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_mutable_uninterpreted_option(google_protobuf_MessageOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option( + google_protobuf_MessageOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.FieldOptions */ +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_new(upb_Arena* arena) { + return (google_protobuf_FieldOptions*)_upb_Message_New(&google__protobuf__FieldOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldOptions* ret = google_protobuf_FieldOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldOptions* ret = google_protobuf_FieldOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldOptions_serialize_ex(const google_protobuf_FieldOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldOptions_clear_ctype(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_packed(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_deprecated(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_lazy(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_jstype(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_weak(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_unverified_lazy(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_unverified_lazy(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_unverified_lazy(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_debug_redact(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_debug_redact(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_debug_redact(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_retention(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_retention(const google_protobuf_FieldOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_retention(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_targets(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_FieldOptions_targets(const google_protobuf_FieldOptions* msg, + size_t* size) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FieldOptions_targets_upb_array( + const google_protobuf_FieldOptions* msg, size_t* size) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FieldOptions_targets_mutable_upb_array( + google_protobuf_FieldOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FieldOptions_clear_edition_defaults(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions_EditionDefault* const* google_protobuf_FieldOptions_edition_defaults(const google_protobuf_FieldOptions* msg, + size_t* size) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldOptions_EditionDefault* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FieldOptions_edition_defaults_upb_array( + const google_protobuf_FieldOptions* msg, size_t* size) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FieldOptions_edition_defaults_mutable_upb_array( + google_protobuf_FieldOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FieldOptions_clear_features(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FieldOptions_features(const google_protobuf_FieldOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_features(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_feature_support(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_feature_support(const google_protobuf_FieldOptions* msg) { + const google_protobuf_FieldOptions_FeatureSupport* default_val = NULL; + const google_protobuf_FieldOptions_FeatureSupport* ret; + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_feature_support(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_uninterpreted_option(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FieldOptions_uninterpreted_option_upb_array( + const google_protobuf_FieldOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FieldOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_FieldOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions* msg, int32_t value) { + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions* msg, int32_t value) { + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_unverified_lazy(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_debug_redact(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_retention(google_protobuf_FieldOptions* msg, int32_t value) { + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE int32_t* google_protobuf_FieldOptions_mutable_targets(google_protobuf_FieldOptions* msg, + size_t* size) { + upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_FieldOptions_resize_targets(google_protobuf_FieldOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FieldOptions_add_targets(google_protobuf_FieldOptions* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE google_protobuf_FieldOptions_EditionDefault** google_protobuf_FieldOptions_mutable_edition_defaults(google_protobuf_FieldOptions* msg, + size_t* size) { + upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldOptions_EditionDefault**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldOptions_EditionDefault** google_protobuf_FieldOptions_resize_edition_defaults(google_protobuf_FieldOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + return (google_protobuf_FieldOptions_EditionDefault**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_add_edition_defaults( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldOptions_EditionDefault* sub = + (struct google_protobuf_FieldOptions_EditionDefault*)_upb_Message_New(&google__protobuf__FieldOptions__EditionDefault_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_FieldOptions_set_features(google_protobuf_FieldOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FieldOptions_mutable_features( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FieldOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FieldOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FieldOptions_set_feature_support(google_protobuf_FieldOptions* msg, google_protobuf_FieldOptions_FeatureSupport* value) { + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_mutable_feature_support( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + struct google_protobuf_FieldOptions_FeatureSupport* sub = (struct google_protobuf_FieldOptions_FeatureSupport*)google_protobuf_FieldOptions_feature_support(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions_FeatureSupport*)_upb_Message_New(&google__protobuf__FieldOptions__FeatureSupport_msg_init, arena); + if (sub) google_protobuf_FieldOptions_set_feature_support(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.FieldOptions.EditionDefault */ +UPB_INLINE google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_EditionDefault_new(upb_Arena* arena) { + return (google_protobuf_FieldOptions_EditionDefault*)_upb_Message_New(&google__protobuf__FieldOptions__EditionDefault_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_EditionDefault_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldOptions_EditionDefault* ret = google_protobuf_FieldOptions_EditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__EditionDefault_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_EditionDefault_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldOptions_EditionDefault* ret = google_protobuf_FieldOptions_EditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__EditionDefault_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldOptions_EditionDefault_serialize(const google_protobuf_FieldOptions_EditionDefault* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__EditionDefault_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldOptions_EditionDefault_serialize_ex(const google_protobuf_FieldOptions_EditionDefault* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__EditionDefault_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_clear_value(google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldOptions_EditionDefault_value(const google_protobuf_FieldOptions_EditionDefault* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_EditionDefault_has_value(const google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_clear_edition(google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_EditionDefault_edition(const google_protobuf_FieldOptions_EditionDefault* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_EditionDefault_has_edition(const google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_set_value(google_protobuf_FieldOptions_EditionDefault* msg, upb_StringView value) { + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_set_edition(google_protobuf_FieldOptions_EditionDefault* msg, int32_t value) { + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FieldOptions.FeatureSupport */ +UPB_INLINE google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_FeatureSupport_new(upb_Arena* arena) { + return (google_protobuf_FieldOptions_FeatureSupport*)_upb_Message_New(&google__protobuf__FieldOptions__FeatureSupport_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_FeatureSupport_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldOptions_FeatureSupport* ret = google_protobuf_FieldOptions_FeatureSupport_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__FeatureSupport_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_FeatureSupport_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldOptions_FeatureSupport* ret = google_protobuf_FieldOptions_FeatureSupport_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__FeatureSupport_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldOptions_FeatureSupport_serialize(const google_protobuf_FieldOptions_FeatureSupport* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__FeatureSupport_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldOptions_FeatureSupport_serialize_ex(const google_protobuf_FieldOptions_FeatureSupport* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__FeatureSupport_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_edition_introduced(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_FeatureSupport_edition_introduced(const google_protobuf_FieldOptions_FeatureSupport* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_edition_introduced(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_edition_deprecated(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_FeatureSupport_edition_deprecated(const google_protobuf_FieldOptions_FeatureSupport* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_edition_deprecated(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_deprecation_warning(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldOptions_FeatureSupport_deprecation_warning(const google_protobuf_FieldOptions_FeatureSupport* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_deprecation_warning(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_edition_removed(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_FeatureSupport_edition_removed(const google_protobuf_FieldOptions_FeatureSupport* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_edition_removed(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_removal_error(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldOptions_FeatureSupport_removal_error(const google_protobuf_FieldOptions_FeatureSupport* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_removal_error(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_edition_introduced(google_protobuf_FieldOptions_FeatureSupport* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_edition_deprecated(google_protobuf_FieldOptions_FeatureSupport* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_deprecation_warning(google_protobuf_FieldOptions_FeatureSupport* msg, upb_StringView value) { + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_edition_removed(google_protobuf_FieldOptions_FeatureSupport* msg, int32_t value) { + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_removal_error(google_protobuf_FieldOptions_FeatureSupport* msg, upb_StringView value) { + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.OneofOptions */ +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_new(upb_Arena* arena) { + return (google_protobuf_OneofOptions*)_upb_Message_New(&google__protobuf__OneofOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_OneofOptions* ret = google_protobuf_OneofOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_OneofOptions* ret = google_protobuf_OneofOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_OneofOptions_serialize_ex(const google_protobuf_OneofOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_OneofOptions_clear_features(google_protobuf_OneofOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_OneofOptions_features(const google_protobuf_OneofOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_OneofOptions_has_features(const google_protobuf_OneofOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_OneofOptions_clear_uninterpreted_option(google_protobuf_OneofOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_OneofOptions_uninterpreted_option_upb_array( + const google_protobuf_OneofOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_OneofOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_OneofOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_OneofOptions_set_features(google_protobuf_OneofOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_OneofOptions_mutable_features( + google_protobuf_OneofOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_OneofOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_OneofOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mutable_uninterpreted_option(google_protobuf_OneofOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option( + google_protobuf_OneofOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.EnumOptions */ +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_new(upb_Arena* arena) { + return (google_protobuf_EnumOptions*)_upb_Message_New(&google__protobuf__EnumOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumOptions* ret = google_protobuf_EnumOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumOptions* ret = google_protobuf_EnumOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumOptions_serialize_ex(const google_protobuf_EnumOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumOptions_clear_allow_alias(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_deprecated(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_deprecated_legacy_json_field_conflicts(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumOptions_deprecated_legacy_json_field_conflicts(const google_protobuf_EnumOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated_legacy_json_field_conflicts(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_features(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_EnumOptions_features(const google_protobuf_EnumOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_features(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_uninterpreted_option(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumOptions_uninterpreted_option_upb_array( + const google_protobuf_EnumOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_EnumOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions* msg, bool value) { + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions* msg, bool value) { + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated_legacy_json_field_conflicts(google_protobuf_EnumOptions* msg, bool value) { + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumOptions_set_features(google_protobuf_EnumOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_EnumOptions_mutable_features( + google_protobuf_EnumOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_EnumOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_EnumOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mutable_uninterpreted_option(google_protobuf_EnumOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option( + google_protobuf_EnumOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.EnumValueOptions */ +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_new(upb_Arena* arena) { + return (google_protobuf_EnumValueOptions*)_upb_Message_New(&google__protobuf__EnumValueOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumValueOptions* ret = google_protobuf_EnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumValueOptions* ret = google_protobuf_EnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumValueOptions_serialize_ex(const google_protobuf_EnumValueOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_deprecated(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_features(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_EnumValueOptions_features(const google_protobuf_EnumValueOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_features(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_debug_redact(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumValueOptions_debug_redact(const google_protobuf_EnumValueOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_debug_redact(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_feature_support(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions_FeatureSupport* google_protobuf_EnumValueOptions_feature_support(const google_protobuf_EnumValueOptions* msg) { + const google_protobuf_FieldOptions_FeatureSupport* default_val = NULL; + const google_protobuf_FieldOptions_FeatureSupport* ret; + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_feature_support(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_uninterpreted_option(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumValueOptions_uninterpreted_option_upb_array( + const google_protobuf_EnumValueOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumValueOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_EnumValueOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions* msg, bool value) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_features(google_protobuf_EnumValueOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_EnumValueOptions_mutable_features( + google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_EnumValueOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_EnumValueOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_debug_redact(google_protobuf_EnumValueOptions* msg, bool value) { + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_feature_support(google_protobuf_EnumValueOptions* msg, google_protobuf_FieldOptions_FeatureSupport* value) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FieldOptions_FeatureSupport* google_protobuf_EnumValueOptions_mutable_feature_support( + google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + struct google_protobuf_FieldOptions_FeatureSupport* sub = (struct google_protobuf_FieldOptions_FeatureSupport*)google_protobuf_EnumValueOptions_feature_support(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions_FeatureSupport*)_upb_Message_New(&google__protobuf__FieldOptions__FeatureSupport_msg_init, arena); + if (sub) google_protobuf_EnumValueOptions_set_feature_support(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_mutable_uninterpreted_option(google_protobuf_EnumValueOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option( + google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.ServiceOptions */ +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_new(upb_Arena* arena) { + return (google_protobuf_ServiceOptions*)_upb_Message_New(&google__protobuf__ServiceOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ServiceOptions* ret = google_protobuf_ServiceOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ServiceOptions* ret = google_protobuf_ServiceOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ServiceOptions_serialize_ex(const google_protobuf_ServiceOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ServiceOptions_clear_deprecated(google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ServiceOptions_clear_features(google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_ServiceOptions_features(const google_protobuf_ServiceOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceOptions_has_features(const google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ServiceOptions_clear_uninterpreted_option(google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ServiceOptions_uninterpreted_option_upb_array( + const google_protobuf_ServiceOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ServiceOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_ServiceOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions* msg, bool value) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ServiceOptions_set_features(google_protobuf_ServiceOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_ServiceOptions_mutable_features( + google_protobuf_ServiceOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_ServiceOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_ServiceOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_mutable_uninterpreted_option(google_protobuf_ServiceOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option( + google_protobuf_ServiceOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.MethodOptions */ +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_new(upb_Arena* arena) { + return (google_protobuf_MethodOptions*)_upb_Message_New(&google__protobuf__MethodOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_MethodOptions* ret = google_protobuf_MethodOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MethodOptions* ret = google_protobuf_MethodOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_MethodOptions_serialize_ex(const google_protobuf_MethodOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_MethodOptions_clear_deprecated(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodOptions_clear_idempotency_level(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodOptions_clear_features(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_MethodOptions_features(const google_protobuf_MethodOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodOptions_has_features(const google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodOptions_clear_uninterpreted_option(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_MethodOptions_uninterpreted_option_upb_array( + const google_protobuf_MethodOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_MethodOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_MethodOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions* msg, bool value) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions* msg, int32_t value) { + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodOptions_set_features(google_protobuf_MethodOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_MethodOptions_mutable_features( + google_protobuf_MethodOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_MethodOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_MethodOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option( + google_protobuf_MethodOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.UninterpretedOption */ +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_new(upb_Arena* arena) { + return (google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_UninterpretedOption* ret = google_protobuf_UninterpretedOption_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_UninterpretedOption* ret = google_protobuf_UninterpretedOption_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_serialize_ex(const google_protobuf_UninterpretedOption* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_name(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption_NamePart* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_UninterpretedOption_name_upb_array( + const google_protobuf_UninterpretedOption* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_UninterpretedOption_name_mutable_upb_array( + google_protobuf_UninterpretedOption* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_identifier_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_positive_int_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption* msg) { + uint64_t default_val = (uint64_t)0ull; + uint64_t ret; + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_negative_int_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption* msg) { + int64_t default_val = (int64_t)0ll; + int64_t ret; + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_double_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption* msg) { + double default_val = 0; + double ret; + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_string_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_aggregate_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_mutable_name(google_protobuf_UninterpretedOption* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption_NamePart**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + return (google_protobuf_UninterpretedOption_NamePart**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name( + google_protobuf_UninterpretedOption* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption_NamePart* sub = + (struct google_protobuf_UninterpretedOption_NamePart*)_upb_Message_New(&google__protobuf__UninterpretedOption__NamePart_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption* msg, upb_StringView value) { + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption* msg, uint64_t value) { + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption* msg, int64_t value) { + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption* msg, double value) { + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption* msg, upb_StringView value) { + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption* msg, upb_StringView value) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.UninterpretedOption.NamePart */ +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_NamePart_new(upb_Arena* arena) { + return (google_protobuf_UninterpretedOption_NamePart*)_upb_Message_New(&google__protobuf__UninterpretedOption__NamePart_msg_init, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_NamePart_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_UninterpretedOption_NamePart* ret = google_protobuf_UninterpretedOption_NamePart_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption__NamePart_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_NamePart_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_UninterpretedOption_NamePart* ret = google_protobuf_UninterpretedOption_NamePart_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption__NamePart_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption__NamePart_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_NamePart_serialize_ex(const google_protobuf_UninterpretedOption_NamePart* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption__NamePart_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_clear_name_part(google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_clear_is_extension(google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart* msg, bool value) { + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FeatureSet */ +UPB_INLINE google_protobuf_FeatureSet* google_protobuf_FeatureSet_new(upb_Arena* arena) { + return (google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSet* google_protobuf_FeatureSet_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSet* ret = google_protobuf_FeatureSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSet* google_protobuf_FeatureSet_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSet* ret = google_protobuf_FeatureSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSet_serialize(const google_protobuf_FeatureSet* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSet_serialize_ex(const google_protobuf_FeatureSet* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FeatureSet_clear_field_presence(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_field_presence(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_field_presence(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_enum_type(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_enum_type(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_enum_type(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_repeated_field_encoding(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_utf8_validation(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_utf8_validation(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_utf8_validation(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_message_encoding(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_message_encoding(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_message_encoding(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_json_format(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_json_format(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_json_format(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_enforce_naming_style(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_enforce_naming_style(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_enforce_naming_style(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_default_symbol_visibility(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_default_symbol_visibility(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_default_symbol_visibility(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FeatureSet_set_field_presence(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_enum_type(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_repeated_field_encoding(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_utf8_validation(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_message_encoding(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_json_format(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_enforce_naming_style(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_default_symbol_visibility(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FeatureSet.VisibilityFeature */ +UPB_INLINE google_protobuf_FeatureSet_VisibilityFeature* google_protobuf_FeatureSet_VisibilityFeature_new(upb_Arena* arena) { + return (google_protobuf_FeatureSet_VisibilityFeature*)_upb_Message_New(&google__protobuf__FeatureSet__VisibilityFeature_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSet_VisibilityFeature* google_protobuf_FeatureSet_VisibilityFeature_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSet_VisibilityFeature* ret = google_protobuf_FeatureSet_VisibilityFeature_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSet_VisibilityFeature* google_protobuf_FeatureSet_VisibilityFeature_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSet_VisibilityFeature* ret = google_protobuf_FeatureSet_VisibilityFeature_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSet_VisibilityFeature_serialize(const google_protobuf_FeatureSet_VisibilityFeature* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSet_VisibilityFeature_serialize_ex(const google_protobuf_FeatureSet_VisibilityFeature* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, options, arena, &ptr, len); + return ptr; +} + + +/* google.protobuf.FeatureSetDefaults */ +UPB_INLINE google_protobuf_FeatureSetDefaults* google_protobuf_FeatureSetDefaults_new(upb_Arena* arena) { + return (google_protobuf_FeatureSetDefaults*)_upb_Message_New(&google__protobuf__FeatureSetDefaults_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSetDefaults* google_protobuf_FeatureSetDefaults_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSetDefaults* ret = google_protobuf_FeatureSetDefaults_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSetDefaults* google_protobuf_FeatureSetDefaults_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSetDefaults* ret = google_protobuf_FeatureSetDefaults_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_serialize(const google_protobuf_FeatureSetDefaults* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_serialize_ex(const google_protobuf_FeatureSetDefaults* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_clear_defaults(google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const* google_protobuf_FeatureSetDefaults_defaults(const google_protobuf_FeatureSetDefaults* msg, + size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FeatureSetDefaults_defaults_upb_array( + const google_protobuf_FeatureSetDefaults* msg, size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FeatureSetDefaults_defaults_mutable_upb_array( + google_protobuf_FeatureSetDefaults* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_clear_minimum_edition(google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSetDefaults_minimum_edition(const google_protobuf_FeatureSetDefaults* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_has_minimum_edition(const google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_clear_maximum_edition(google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSetDefaults_maximum_edition(const google_protobuf_FeatureSetDefaults* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_has_maximum_edition(const google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault** google_protobuf_FeatureSetDefaults_mutable_defaults(google_protobuf_FeatureSetDefaults* msg, + size_t* size) { + upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault** google_protobuf_FeatureSetDefaults_resize_defaults(google_protobuf_FeatureSetDefaults* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + return (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_add_defaults( + google_protobuf_FeatureSetDefaults* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* sub = + (struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault*)_upb_Message_New(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_set_minimum_edition(google_protobuf_FeatureSetDefaults* msg, int32_t value) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_set_maximum_edition(google_protobuf_FeatureSetDefaults* msg, int32_t value) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault */ +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_new(upb_Arena* arena) { + return (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault*)_upb_Message_New(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* ret = google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* ret = google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_serialize(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_serialize_ex(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_clear_edition(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_edition(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_has_edition(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_clear_overridable_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_overridable_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_has_overridable_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_clear_fixed_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_fixed_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_has_fixed_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_edition(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, int32_t value) { + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_overridable_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_mutable_overridable_features( + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_overridable_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_overridable_features(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_fixed_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_mutable_fixed_features( + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_fixed_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_fixed_features(msg, sub); + } + return sub; +} + +/* google.protobuf.SourceCodeInfo */ +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_new(upb_Arena* arena) { + return (google_protobuf_SourceCodeInfo*)_upb_Message_New(&google__protobuf__SourceCodeInfo_msg_init, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_SourceCodeInfo* ret = google_protobuf_SourceCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_SourceCodeInfo* ret = google_protobuf_SourceCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_serialize_ex(const google_protobuf_SourceCodeInfo* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_clear_location(google_protobuf_SourceCodeInfo* msg) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_SourceCodeInfo_Location* const* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo* msg, + size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_SourceCodeInfo_Location* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_location_upb_array( + const google_protobuf_SourceCodeInfo* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_location_mutable_upb_array( + google_protobuf_SourceCodeInfo* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_mutable_location(google_protobuf_SourceCodeInfo* msg, + size_t* size) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_SourceCodeInfo_Location**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + return (google_protobuf_SourceCodeInfo_Location**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location( + google_protobuf_SourceCodeInfo* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_SourceCodeInfo_Location* sub = + (struct google_protobuf_SourceCodeInfo_Location*)_upb_Message_New(&google__protobuf__SourceCodeInfo__Location_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.SourceCodeInfo.Location */ +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_new(upb_Arena* arena) { + return (google_protobuf_SourceCodeInfo_Location*)_upb_Message_New(&google__protobuf__SourceCodeInfo__Location_msg_init, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_SourceCodeInfo_Location* ret = google_protobuf_SourceCodeInfo_Location_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo__Location_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_SourceCodeInfo_Location* ret = google_protobuf_SourceCodeInfo_Location_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo__Location_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo__Location_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_Location_serialize_ex(const google_protobuf_SourceCodeInfo_Location* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo__Location_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_path(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_Location_path_upb_array( + const google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_Location_path_mutable_upb_array( + google_protobuf_SourceCodeInfo_Location* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_span(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_Location_span_upb_array( + const google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_Location_span_mutable_upb_array( + google_protobuf_SourceCodeInfo_Location* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_leading_comments(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_trailing_comments(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_Location_leading_detached_comments_upb_array( + const google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_Location_leading_detached_comments_mutable_upb_array( + google_protobuf_SourceCodeInfo_Location* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location* msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location* msg, upb_StringView value) { + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE upb_StringView* google_protobuf_SourceCodeInfo_Location_mutable_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} + +/* google.protobuf.GeneratedCodeInfo */ +UPB_INLINE google_protobuf_GeneratedCodeInfo* google_protobuf_GeneratedCodeInfo_new(upb_Arena* arena) { + return (google_protobuf_GeneratedCodeInfo*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo_msg_init, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo* google_protobuf_GeneratedCodeInfo_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo* ret = google_protobuf_GeneratedCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_GeneratedCodeInfo* google_protobuf_GeneratedCodeInfo_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo* ret = google_protobuf_GeneratedCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_serialize_ex(const google_protobuf_GeneratedCodeInfo* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_clear_annotation(google_protobuf_GeneratedCodeInfo* msg) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_GeneratedCodeInfo_Annotation* const* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo* msg, + size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_GeneratedCodeInfo_Annotation* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_GeneratedCodeInfo_annotation_upb_array( + const google_protobuf_GeneratedCodeInfo* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_GeneratedCodeInfo_annotation_mutable_upb_array( + google_protobuf_GeneratedCodeInfo* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_mutable_annotation(google_protobuf_GeneratedCodeInfo* msg, + size_t* size) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_GeneratedCodeInfo_Annotation**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + return (google_protobuf_GeneratedCodeInfo_Annotation**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation( + google_protobuf_GeneratedCodeInfo* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_GeneratedCodeInfo_Annotation* sub = + (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.GeneratedCodeInfo.Annotation */ +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_new(upb_Arena* arena) { + return (google_protobuf_GeneratedCodeInfo_Annotation*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo_Annotation* ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo_Annotation* ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_Annotation_serialize_ex(const google_protobuf_GeneratedCodeInfo_Annotation* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_path(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation* msg, + size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_GeneratedCodeInfo_Annotation_path_upb_array( + const google_protobuf_GeneratedCodeInfo_Annotation* msg, size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_GeneratedCodeInfo_Annotation_path_mutable_upb_array( + google_protobuf_GeneratedCodeInfo_Annotation* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_source_file(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_begin(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_end(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_semantic(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_semantic(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_semantic(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation* msg, + size_t* size) { + upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_semantic(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* Max size 32 is google.protobuf.FileOptions */ +/* Max size 64 is google.protobuf.FileOptions */ +#define _UPB_MAXOPT_SIZE UPB_SIZE(112, 200) +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_H_ */ +#endif + +// IWYU pragma: end_exports + +#endif // GOOGLE_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H__ + +// Forward declarations for circular references. +typedef struct upb_DefPool upb_DefPool; +typedef struct upb_EnumDef upb_EnumDef; +typedef struct upb_EnumReservedRange upb_EnumReservedRange; +typedef struct upb_EnumValueDef upb_EnumValueDef; +typedef struct upb_ExtensionRange upb_ExtensionRange; +typedef struct upb_FieldDef upb_FieldDef; +typedef struct upb_FileDef upb_FileDef; +typedef struct upb_MessageDef upb_MessageDef; +typedef struct upb_MessageReservedRange upb_MessageReservedRange; +typedef struct upb_MethodDef upb_MethodDef; +typedef struct upb_OneofDef upb_OneofDef; +typedef struct upb_ServiceDef upb_ServiceDef; + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +typedef struct upb_DefBuilder upb_DefBuilder; + +#endif /* UPB_REFLECTION_COMMON_H_ */ + +#ifndef UPB_REFLECTION_DEF_TYPE_H_ +#define UPB_REFLECTION_DEF_TYPE_H_ + + +// Must be last. + +// Inside a symtab we store tagged pointers to specific def types. +typedef enum { + UPB_DEFTYPE_MASK = 7, + + // Only inside symtab table. + UPB_DEFTYPE_EXT = 0, + UPB_DEFTYPE_MSG = 1, + UPB_DEFTYPE_ENUM = 2, + UPB_DEFTYPE_ENUMVAL = 3, + UPB_DEFTYPE_SERVICE = 4, + + // Only inside message table. + UPB_DEFTYPE_FIELD = 0, + UPB_DEFTYPE_ONEOF = 1, + + // Only inside service table. + UPB_DEFTYPE_METHOD = 0, +} upb_deftype_t; + +#ifdef __cplusplus +extern "C" { +#endif + +// Our 3-bit pointer tagging requires all pointers to be multiples of 8. +// The arena will always yield 8-byte-aligned addresses, however we put +// the defs into arrays. For each element in the array to be 8-byte-aligned, +// the sizes of each def type must also be a multiple of 8. +// +// If any of these asserts fail, we need to add or remove padding on 32-bit +// machines (64-bit machines will have 8-byte alignment already due to +// pointers, which all of these structs have). +UPB_INLINE void _upb_DefType_CheckPadding(size_t size) { + UPB_ASSERT((size & UPB_DEFTYPE_MASK) == 0); +} + +upb_deftype_t _upb_DefType_Type(upb_value v); + +upb_value _upb_DefType_Pack(const void* ptr, upb_deftype_t type); + +const void* _upb_DefType_Unpack(upb_value v, upb_deftype_t type); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_TYPE_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API void upb_DefPool_Free(upb_DefPool* s); + +UPB_API upb_DefPool* upb_DefPool_New(void); + +UPB_API const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults( + const upb_DefPool* s); + +UPB_API bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status); + +UPB_API const upb_MessageDef* upb_DefPool_FindMessageByName( + const upb_DefPool* s, const char* sym); + +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); + +UPB_API const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym); + +UPB_API const upb_EnumDef* upb_DefPool_FindEnumByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); + +UPB_API const upb_EnumValueDef* upb_DefPool_FindEnumValueByName( + const upb_DefPool* s, const char* sym); + +UPB_API const upb_EnumValueDef* upb_DefPool_FindEnumValueByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); + +UPB_API const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name); + +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len); + +const upb_FieldDef* upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTableExtension* ext); + +UPB_API const upb_FieldDef* upb_DefPool_FindExtensionByName( + const upb_DefPool* s, const char* sym); + +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* name, size_t size); + +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum); + +UPB_API const upb_ServiceDef* upb_DefPool_FindServiceByName( + const upb_DefPool* s, const char* name); + +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size); + +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name); + +UPB_API const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + upb_Status* status); + +UPB_API const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s); + +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count); + +// If called, closed enums will be treated as open enums. This is non-standard +// behavior and will cause conformance tests to fail, but it is more useful +// behavior overall and can be used in situations where where the +// non-conformance is acceptable. +// +// This function may only be called immediately after upb_DefPool_New(). +// It is an error to call it on an existing def pool or after defs have +// already been added to the pool. +// +// Note: we still require that implicit presence fields have zero as their +// default value. +UPB_API void upb_DefPool_DisableClosedEnumChecking(upb_DefPool* s); +bool upb_DefPool_ClosedEnumCheckingDisabled(const upb_DefPool* s); + +// If called, implicit field presence will be disabled. +// This is non-standard behavior and will cause conformance tests to fail, but +// it can be used in situations where where the non-conformance is acceptable. +// +// This function may only be called immediately after upb_DefPool_New(). +// It is an error to call it on an existing def pool or after defs have +// already been added to the pool. +UPB_API void upb_DefPool_DisableImplicitFieldPresence(upb_DefPool* s); +bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_POOL_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ENUM_DEF_H_ +#define UPB_REFLECTION_ENUM_DEF_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num); +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e); +int32_t upb_EnumDef_Default(const upb_EnumDef* e); +UPB_API const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e); +const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, + const char* name); +UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* e, const char* name, size_t size); +UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNumber( + const upb_EnumDef* e, int32_t num); +UPB_API const char* upb_EnumDef_FullName(const upb_EnumDef* e); +bool upb_EnumDef_HasOptions(const upb_EnumDef* e); +bool upb_EnumDef_IsClosed(const upb_EnumDef* e); + +// Creates a mini descriptor string for an enum, returns true on success. +bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a, + upb_StringView* out); + +const char* upb_EnumDef_Name(const upb_EnumDef* e); +const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e); +const google_protobuf_FeatureSet* upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e); +google_protobuf_SymbolVisibility upb_EnumDef_Visibility(const upb_EnumDef* e); + +upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i); +int upb_EnumDef_ReservedNameCount(const upb_EnumDef* e); + +const upb_EnumReservedRange* upb_EnumDef_ReservedRange(const upb_EnumDef* e, + int i); +int upb_EnumDef_ReservedRangeCount(const upb_EnumDef* e); + +UPB_API const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i); +UPB_API int upb_EnumDef_ValueCount(const upb_EnumDef* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_ +#define UPB_REFLECTION_ENUM_VALUE_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v); +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v); +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v); +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v); +UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v); +UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v); +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* v); +const google_protobuf_FeatureSet* upb_EnumValueDef_ResolvedFeatures( + const upb_EnumValueDef* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_VALUE_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_EXTENSION_RANGE_H_ +#define UPB_REFLECTION_EXTENSION_RANGE_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r); +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r); + +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r); +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r); +const google_protobuf_FeatureSet* upb_ExtensionRange_ResolvedFeatures( + const upb_ExtensionRange* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_EXTENSION_RANGE_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_FIELD_DEF_H_ +#define UPB_REFLECTION_FIELD_DEF_H_ + +#include + + +// Must be last. + +// Maximum field number allowed for FieldDefs. +// This is an inherent limit of the protobuf wire format. +#define kUpb_MaxFieldNumber ((1 << 29) - 1) + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f); +UPB_API const upb_MessageDef* upb_FieldDef_ContainingType( + const upb_FieldDef* f); +UPB_API upb_CType upb_FieldDef_CType(const upb_FieldDef* f); +UPB_API upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f); +UPB_API const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f); +UPB_API const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f); +const char* upb_FieldDef_FullName(const upb_FieldDef* f); +bool upb_FieldDef_HasDefault(const upb_FieldDef* f); +bool upb_FieldDef_HasJsonName(const upb_FieldDef* f); +bool upb_FieldDef_HasOptions(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_HasPresence(const upb_FieldDef* f); +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f); +uint32_t upb_FieldDef_Index(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsEnum(const upb_FieldDef* f); +bool upb_FieldDef_IsExtension(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsMap(const upb_FieldDef* f); +bool upb_FieldDef_IsOptional(const upb_FieldDef* f); +bool _upb_FieldDef_IsPackable(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsPacked(const upb_FieldDef* f); +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsRepeated(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsRequired(const upb_FieldDef* f); +bool upb_FieldDef_IsString(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f); +UPB_API const char* upb_FieldDef_JsonName(const upb_FieldDef* f); +UPB_API upb_Label upb_FieldDef_Label(const upb_FieldDef* f); +uint32_t upb_FieldDef_LayoutIndex(const upb_FieldDef* f); +UPB_API const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f); +bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f); +bool _upb_FieldDef_IsGroupLike(const upb_FieldDef* f); + +// Creates a mini descriptor string for a field, returns true on success. +bool upb_FieldDef_MiniDescriptorEncode(const upb_FieldDef* f, upb_Arena* a, + upb_StringView* out); + +const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f); +const upb_MiniTableExtension* upb_FieldDef_MiniTableExtension( + const upb_FieldDef* f); +UPB_API const char* upb_FieldDef_Name(const upb_FieldDef* f); +UPB_API uint32_t upb_FieldDef_Number(const upb_FieldDef* f); +const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f); +const google_protobuf_FeatureSet* upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f); +UPB_API const upb_OneofDef* upb_FieldDef_RealContainingOneof( + const upb_FieldDef* f); +UPB_API upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FIELD_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_FILE_DEF_H_ +#define UPB_REFLECTION_FILE_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const char* upb_FileDef_EditionName(int edition); + +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i); +int upb_FileDef_DependencyCount(const upb_FileDef* f); +bool upb_FileDef_HasOptions(const upb_FileDef* f); +UPB_API const char* upb_FileDef_Name(const upb_FileDef* f); +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f); +const google_protobuf_FeatureSet* upb_FileDef_ResolvedFeatures(const upb_FileDef* f); +const char* upb_FileDef_Package(const upb_FileDef* f); +google_protobuf_Edition upb_FileDef_Edition(const upb_FileDef* f); +UPB_API const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f); + +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i); +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f); + +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i); +int upb_FileDef_ServiceCount(const upb_FileDef* f); + +const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i); +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f); + +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i); +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f); + +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i); +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f); + +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i); +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f); + +// Returns whether |symbol| is transitively included by |f| +bool upb_FileDef_Resolves(const upb_FileDef* f, const char* symbol); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FILE_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_MESSAGE_DEF_H_ +#define UPB_REFLECTION_MESSAGE_DEF_H_ + + +// Must be last. + +// Well-known field tag numbers for map-entry messages. +#define kUpb_MapEntry_KeyFieldNumber 1 +#define kUpb_MapEntry_ValueFieldNumber 2 + +// Well-known field tag numbers for Any messages. +#define kUpb_Any_TypeFieldNumber 1 +#define kUpb_Any_ValueFieldNumber 2 + +// Well-known field tag numbers for duration messages. +#define kUpb_Duration_SecondsFieldNumber 1 +#define kUpb_Duration_NanosFieldNumber 2 + +// Well-known field tag numbers for timestamp messages. +#define kUpb_Timestamp_SecondsFieldNumber 1 +#define kUpb_Timestamp_NanosFieldNumber 2 + +// All the different kind of well known type messages. For simplicity of check, +// number wrappers and string wrappers are grouped together. Make sure the +// order and number of these groups are not changed. +typedef enum { + kUpb_WellKnown_Unspecified, + kUpb_WellKnown_Any, + kUpb_WellKnown_FieldMask, + kUpb_WellKnown_Duration, + kUpb_WellKnown_Timestamp, + + // number wrappers + kUpb_WellKnown_DoubleValue, + kUpb_WellKnown_FloatValue, + kUpb_WellKnown_Int64Value, + kUpb_WellKnown_UInt64Value, + kUpb_WellKnown_Int32Value, + kUpb_WellKnown_UInt32Value, + + // string wrappers + kUpb_WellKnown_StringValue, + kUpb_WellKnown_BytesValue, + kUpb_WellKnown_BoolValue, + kUpb_WellKnown_Value, + kUpb_WellKnown_ListValue, + kUpb_WellKnown_Struct, +} upb_WellKnown; + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m); + +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i); +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m); + +UPB_API const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, + int i); +UPB_API int upb_MessageDef_FieldCount(const upb_MessageDef* m); + +UPB_API const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m); + +// Returns a field by either JSON name or regular proto name. +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t size); +UPB_INLINE const upb_FieldDef* upb_MessageDef_FindByJsonName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindByJsonNameWithSize(m, name, strlen(name)); +} + +// Lookup of either field or oneof by name. Returns whether either was found. +// If the return is true, then the found def will be set, and the non-found +// one set to NULL. +UPB_API bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, + const char* name, size_t size, + const upb_FieldDef** f, + const upb_OneofDef** o); +UPB_INLINE bool upb_MessageDef_FindByName(const upb_MessageDef* m, + const char* name, + const upb_FieldDef** f, + const upb_OneofDef** o) { + return upb_MessageDef_FindByNameWithSize(m, name, strlen(name), f, o); +} + +const upb_FieldDef* upb_MessageDef_FindFieldByName(const upb_MessageDef* m, + const char* name); +UPB_API const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size); +UPB_API const upb_FieldDef* upb_MessageDef_FindFieldByNumber( + const upb_MessageDef* m, uint32_t i); +const upb_OneofDef* upb_MessageDef_FindOneofByName(const upb_MessageDef* m, + const char* name); +UPB_API const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size); +UPB_API const char* upb_MessageDef_FullName(const upb_MessageDef* m); +bool upb_MessageDef_HasOptions(const upb_MessageDef* m); +bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m); +bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m); + +// Creates a mini descriptor string for a message, returns true on success. +bool upb_MessageDef_MiniDescriptorEncode(const upb_MessageDef* m, upb_Arena* a, + upb_StringView* out); + +UPB_API const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m); +const char* upb_MessageDef_Name(const upb_MessageDef* m); + +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i); +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i); +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i); + +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m); +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m); +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m); + +UPB_API const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, + int i); +UPB_API int upb_MessageDef_OneofCount(const upb_MessageDef* m); +int upb_MessageDef_RealOneofCount(const upb_MessageDef* m); + +const google_protobuf_MessageOptions* upb_MessageDef_Options(const upb_MessageDef* m); +const google_protobuf_FeatureSet* upb_MessageDef_ResolvedFeatures( + const upb_MessageDef* m); + +upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i); +int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m); + +const upb_MessageReservedRange* upb_MessageDef_ReservedRange( + const upb_MessageDef* m, int i); +int upb_MessageDef_ReservedRangeCount(const upb_MessageDef* m); + +UPB_API upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m); +UPB_API google_protobuf_SymbolVisibility +upb_MessageDef_Visibility(const upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_METHOD_DEF_H_ +#define UPB_REFLECTION_METHOD_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m); +const char* upb_MethodDef_FullName(const upb_MethodDef* m); +bool upb_MethodDef_HasOptions(const upb_MethodDef* m); +int upb_MethodDef_Index(const upb_MethodDef* m); +UPB_API const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m); +UPB_API const char* upb_MethodDef_Name(const upb_MethodDef* m); +UPB_API const google_protobuf_MethodOptions* upb_MethodDef_Options( + const upb_MethodDef* m); +const google_protobuf_FeatureSet* upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m); +UPB_API const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m); +UPB_API bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m); +UPB_API const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_METHOD_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ONEOF_DEF_H_ +#define UPB_REFLECTION_ONEOF_DEF_H_ + +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const upb_MessageDef* upb_OneofDef_ContainingType( + const upb_OneofDef* o); +UPB_API const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i); +UPB_API int upb_OneofDef_FieldCount(const upb_OneofDef* o); +const char* upb_OneofDef_FullName(const upb_OneofDef* o); +bool upb_OneofDef_HasOptions(const upb_OneofDef* o); +uint32_t upb_OneofDef_Index(const upb_OneofDef* o); +bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o); +const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, + const char* name); +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, + const char* name, + size_t size); +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num); +UPB_API const char* upb_OneofDef_Name(const upb_OneofDef* o); +int upb_OneofDef_numfields(const upb_OneofDef* o); +const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o); +const google_protobuf_FeatureSet* upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ONEOF_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_SERVICE_DEF_H_ +#define UPB_REFLECTION_SERVICE_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s); +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name); +const upb_MethodDef* upb_ServiceDef_FindMethodByNameWithSize( + const upb_ServiceDef* s, const char* name, size_t len); +UPB_API const char* upb_ServiceDef_FullName(const upb_ServiceDef* s); +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s); +int upb_ServiceDef_Index(const upb_ServiceDef* s); +UPB_API const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, + int i); +UPB_API int upb_ServiceDef_MethodCount(const upb_ServiceDef* s); +const char* upb_ServiceDef_Name(const upb_ServiceDef* s); +UPB_API const google_protobuf_ServiceOptions* upb_ServiceDef_Options( + const upb_ServiceDef* s); +const google_protobuf_FeatureSet* upb_ServiceDef_ResolvedFeatures( + const upb_ServiceDef* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_SERVICE_DEF_H_ */ +// IWYU pragma: end_exports + +#endif /* UPB_REFLECTION_DEF_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +enum { upb_JsonDecode_IgnoreUnknown = 1 }; + +enum { + kUpb_JsonDecodeResult_Ok = 0, + kUpb_JsonDecodeResult_Error = 2, +}; + +UPB_API int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size, + upb_Message* msg, + const upb_MessageDef* m, + const upb_DefPool* symtab, + int options, upb_Arena* arena, + upb_Status* status); + +UPB_API_INLINE bool upb_JsonDecode(const char* buf, size_t size, + upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* symtab, int options, + upb_Arena* arena, upb_Status* status) { + return upb_JsonDecodeDetectingNonconformance(buf, size, msg, m, symtab, + options, arena, status) == + kUpb_JsonDecodeResult_Ok; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_JSONDECODE_H_ */ + +#ifndef UPB_LEX_ATOI_H_ +#define UPB_LEX_ATOI_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// We use these hand-written routines instead of strto[u]l() because the "long +// long" variants aren't in c89. Also our version allows setting a ptr limit. +// Return the new position of the pointer after parsing the int, or NULL on +// integer overflow. + +const char* upb_BufToUint64(const char* ptr, const char* end, uint64_t* val); +const char* upb_BufToInt64(const char* ptr, const char* end, int64_t* val, + bool* is_neg); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_ATOI_H_ */ + +#ifndef UPB_LEX_UNICODE_H_ +#define UPB_LEX_UNICODE_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns true iff a codepoint is the value for a high surrogate. +UPB_INLINE bool upb_Unicode_IsHigh(uint32_t cp) { + return (cp >= 0xd800 && cp <= 0xdbff); +} + +// Returns true iff a codepoint is the value for a low surrogate. +UPB_INLINE bool upb_Unicode_IsLow(uint32_t cp) { + return (cp >= 0xdc00 && cp <= 0xdfff); +} + +// Returns the high 16-bit surrogate value for a supplementary codepoint. +// Does not sanity-check the input. +UPB_INLINE uint16_t upb_Unicode_ToHigh(uint32_t cp) { + return (cp >> 10) + 0xd7c0; +} + +// Returns the low 16-bit surrogate value for a supplementary codepoint. +// Does not sanity-check the input. +UPB_INLINE uint16_t upb_Unicode_ToLow(uint32_t cp) { + return (cp & 0x3ff) | 0xdc00; +} + +// Returns the 32-bit value corresponding to a pair of 16-bit surrogates. +// Does not sanity-check the input. +UPB_INLINE uint32_t upb_Unicode_FromPair(uint32_t high, uint32_t low) { + return ((high & 0x3ff) << 10) + (low & 0x3ff) + 0x10000; +} + +// Outputs a codepoint as UTF8. +// Returns the number of bytes written (1-4 on success, 0 on error). +// Does not sanity-check the input. Specifically does not check for surrogates. +int upb_Unicode_ToUTF8(uint32_t cp, char* out); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_UNICODE_H_ */ + +#ifndef UPB_REFLECTION_MESSAGE_H_ +#define UPB_REFLECTION_MESSAGE_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns a mutable pointer to a map, array, or submessage value. If the given +// arena is non-NULL this will construct a new object if it was not previously +// present. May not be called for primitive fields. +UPB_API upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, + const upb_FieldDef* f, + upb_Arena* a); + +// Returns the field that is set in the oneof, or NULL if none are set. +UPB_API const upb_FieldDef* upb_Message_WhichOneofByDef(const upb_Message* msg, + const upb_OneofDef* o); + +// Clear all data and unknown fields. +void upb_Message_ClearByDef(upb_Message* msg, const upb_MessageDef* m); + +// Clears any field presence and sets the value back to its default. +UPB_API void upb_Message_ClearFieldByDef(upb_Message* msg, + const upb_FieldDef* f); + +// May only be called for fields where upb_FieldDef_HasPresence(f) == true. +UPB_API bool upb_Message_HasFieldByDef(const upb_Message* msg, + const upb_FieldDef* f); + +// Returns the value in the message associated with this field def. +UPB_API upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, + const upb_FieldDef* f); + +// Sets the given field to the given value. For a msg/array/map/string, the +// caller must ensure that the target data outlives |msg| (by living either in +// the same arena or a different arena that outlives it). +// +// Returns false if allocation fails. +UPB_API bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue val, upb_Arena* a); + +// Iterate over present fields. +// +// size_t iter = kUpb_Message_Begin; +// const upb_FieldDef *f; +// upb_MessageValue val; +// while (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) { +// process_field(f, val); +// } +// +// If ext_pool is NULL, no extensions will be returned. If the given symtab +// returns extensions that don't match what is in this message, those extensions +// will be skipped. + +#define kUpb_Message_Begin -1 + +UPB_API bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, + const upb_FieldDef** f, upb_MessageValue* val, + size_t* iter); + +// Clears all unknown field data from this message and all submessages. +UPB_API bool upb_Message_DiscardUnknown(upb_Message* msg, + const upb_MessageDef* m, + const upb_DefPool* ext_pool, + int maxdepth); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_H_ */ + +#ifndef UPB_JSON_ENCODE_H_ +#define UPB_JSON_ENCODE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + /* When set, emits 0/default values. TODO: proto3 only? */ + upb_JsonEncode_EmitDefaults = 1 << 0, + + /* When set, use normal (snake_case) field names instead of JSON (camelCase) + names. */ + upb_JsonEncode_UseProtoNames = 1 << 1, + + /* When set, emits enums as their integer values instead of as their names. */ + upb_JsonEncode_FormatEnumsAsIntegers = 1 << 2 +}; + +/* Encodes the given |msg| to JSON format. The message's reflection is given in + * |m|. The DefPool in |ext_pool| is used to find extensions (if NULL, + * extensions will not be printed). + * + * Output is placed in the given buffer, and always NULL-terminated. The output + * size (excluding NULL) is returned. This means that a return value >= |size| + * implies that the output was truncated. (These are the same semantics as + * snprintf()). */ +UPB_API size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, + char* buf, size_t size, upb_Status* status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_JSONENCODE_H_ */ + +#ifndef UPB_LEX_ROUND_TRIP_H_ +#define UPB_LEX_ROUND_TRIP_H_ + +// Must be last. + +// Encodes a float or double that is round-trippable, but as short as possible. +// These routines are not fully optimal (not guaranteed to be shortest), but are +// short-ish and match the implementation that has been used in protobuf since +// the beginning. + +// The given buffer size must be at least kUpb_RoundTripBufferSize. +enum { kUpb_RoundTripBufferSize = 32 }; + +#ifdef __cplusplus +extern "C" { +#endif + +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size); +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_ROUND_TRIP_H_ */ + +#ifndef UPB_PORT_VSNPRINTF_COMPAT_H_ +#define UPB_PORT_VSNPRINTF_COMPAT_H_ + +// Must be last. + +UPB_INLINE int _upb_vsnprintf(char* buf, size_t size, const char* fmt, + va_list ap) { +#if defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) + // The msvc runtime has a non-conforming vsnprintf() that requires the + // following compatibility code to become conformant. + int n = -1; + if (size != 0) n = _vsnprintf_s(buf, size, _TRUNCATE, fmt, ap); + if (n == -1) n = _vscprintf(fmt, ap); + return n; +#else + return vsnprintf(buf, size, fmt, ap); +#endif +} + + +#endif // UPB_PORT_VSNPRINTF_COMPAT_H_ + +#ifndef UPB_LEX_STRTOD_H_ +#define UPB_LEX_STRTOD_H_ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +double _upb_NoLocaleStrtod(const char *str, char **endptr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_STRTOD_H_ */ + +#ifndef UPB_PORT_ATOMIC_H_ +#define UPB_PORT_ATOMIC_H_ + + +#ifdef UPB_USE_C11_ATOMICS + +// IWYU pragma: begin_exports +#include +#include +// IWYU pragma: end_exports + +#define upb_Atomic_Init(addr, val) atomic_init(addr, val) +#define upb_Atomic_Load(addr, order) atomic_load_explicit(addr, order) +#define upb_Atomic_Store(addr, val, order) \ + atomic_store_explicit(addr, val, order) +#define upb_Atomic_Exchange(addr, val, order) \ + atomic_exchange_explicit(addr, val, order) +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + atomic_compare_exchange_strong_explicit(addr, expected, desired, \ + success_order, failure_order) +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + atomic_compare_exchange_weak_explicit(addr, expected, desired, \ + success_order, failure_order) +#define upb_Atomic_Add(addr, val, order) \ + atomic_fetch_add_explicit(addr, val, order) +#define upb_Atomic_Sub(addr, val, order) \ + atomic_fetch_sub_explicit(addr, val, order) + +#elif defined(UPB_USE_MSC_ATOMICS) +#include +#include +#include + +#define upb_Atomic_Init(addr, val) (*(addr) = val) + +#pragma intrinsic(_InterlockedExchange) +static int32_t upb_Atomic_LoadMsc32(int32_t volatile* addr) { + // Compare exchange with an unlikely value reduces the risk of a spurious + // (but harmless) store + return _InterlockedCompareExchange(addr, 0xDEADC0DE, 0xDEADC0DE); +} + +#pragma intrinsic(_InterlockedCompareExchange) +static bool upb_Atomic_CompareExchangeMscP32(int32_t volatile* addr, + int32_t* expected, + int32_t desired) { + int32_t expect_val = *expected; + int32_t actual_val = _InterlockedCompareExchange(addr, desired, expect_val); + if (expect_val != actual_val) { + *expected = actual_val; + return false; + } + return true; +} + +#if defined(_WIN64) +// MSVC, without C11 atomics, does not have any way in pure C to force +// load-acquire store-release behavior, so we hack it with exchanges. +#pragma intrinsic(_InterlockedCompareExchange64) +static uintptr_t upb_Atomic_LoadMsc64(uint64_t volatile* addr) { + // Compare exchange with an unlikely value reduces the risk of a spurious + // (but harmless) store + return _InterlockedCompareExchange64(addr, 0xDEADC0DEBAADF00D, + 0xDEADC0DEBAADF00D); +} + +#pragma intrinsic(_InterlockedCompareExchange64) +static bool upb_Atomic_CompareExchangeMscP64(uint64_t volatile* addr, + uint64_t* expected, + uint64_t desired) { + uint64_t expect_val = *expected; + uint64_t actual_val = + _InterlockedCompareExchange64(addr, desired, expect_val); + if (expect_val != actual_val) { + *expected = actual_val; + return false; + } + return true; +} + +#pragma intrinsic(_InterlockedExchange64) +// If _Generic is available, use it to avoid emitting a "'uintptr_t' differs in +// levels of indirection from 'void *'" or -Wint-conversion compiler warning. +#if __STDC_VERSION__ >= 201112L +#define upb_Atomic_Store(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: (void)_InterlockedExchange64( \ + (uint64_t volatile*)(addr), (uint64_t)val), \ + UPB_ATOMIC(int32_t)*: (void)_InterlockedExchange( \ + (int32_t volatile*)(addr), (int32_t)val), \ + default: (void)_InterlockedExchange64((uint64_t volatile*)addr, \ + (uint64_t)val)) + +#define upb_Atomic_Load(addr, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: upb_Atomic_LoadMsc64( \ + (uint64_t volatile*)(addr)), \ + UPB_ATOMIC(int32_t)*: upb_Atomic_LoadMsc32((int32_t volatile*)(addr)), \ + default: (void*)upb_Atomic_LoadMsc64((uint64_t volatile*)(addr))) + +#define upb_Atomic_Exchange(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: _InterlockedExchange64( \ + (uint64_t volatile*)(addr), (uint64_t)val), \ + UPB_ATOMIC(int32_t)*: _InterlockedExchange((int32_t volatile*)(addr), \ + (int32_t)val), \ + default: (void*)_InterlockedExchange64((uint64_t volatile*)addr, \ + (uint64_t)val)) + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + _Generic(addr, \ + UPB_ATOMIC(int32_t)*: upb_Atomic_CompareExchangeMscP32( \ + (int32_t volatile*)(addr), (int32_t*)expected, \ + (int32_t)desired), \ + default: upb_Atomic_CompareExchangeMscP64((uint64_t volatile*)(addr), \ + (uint64_t*)expected, \ + (uint64_t)desired)) + +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + _Generic(addr, \ + UPB_ATOMIC(int32_t)*: upb_Atomic_CompareExchangeMscP32( \ + (int32_t volatile*)(addr), (int32_t*)expected, \ + (int32_t)desired), \ + default: upb_Atomic_CompareExchangeMscP64((uint64_t volatile*)(addr), \ + (uint64_t*)expected, \ + (uint64_t)desired)) + +#else + +UPB_INLINE void _upb_Atomic_StoreP(void volatile* addr, uint64_t val, + size_t size) { + if (size == sizeof(int32_t)) { + (void)_InterlockedExchange((int32_t volatile*)addr, (int32_t)val); + } else { + (void)_InterlockedExchange64((uint64_t volatile*)addr, val); + } +} + +#define upb_Atomic_Store(addr, val, order) \ + _upb_Atomic_StoreP(addr, val, sizeof(*addr)) + +UPB_INLINE int64_t _upb_Atomic_LoadP(void volatile* addr, size_t size) { + if (size == sizeof(int32_t)) { + return (int64_t)upb_Atomic_LoadMsc32((int32_t volatile*)addr); + } else { + return upb_Atomic_LoadMsc64((uint64_t volatile*)addr); + } +} + +#define upb_Atomic_Load(addr, order) \ + (void*)_upb_Atomic_LoadP((void volatile*)addr, sizeof(*addr)) + +UPB_INLINE int64_t _upb_Atomic_ExchangeP(void volatile* addr, uint64_t val, + size_t size) { + if (size == sizeof(int32_t)) { + return (int64_t)_InterlockedExchange((int32_t volatile*)addr, (int32_t)val); + } else { + return (int64_t)_InterlockedExchange64((uint64_t volatile*)addr, val); + } +} + +#define upb_Atomic_Exchange(addr, val, order) \ + (void*)_upb_Atomic_ExchangeP((void volatile*)addr, (uint64_t)val, \ + sizeof(*addr)) + +UPB_INLINE bool _upb_Atomic_CompareExchangeMscP(void volatile* addr, + void* expected, + uint64_t desired, size_t size) { + if (size == sizeof(int32_t)) { + return upb_Atomic_CompareExchangeMscP32( + (int32_t volatile*)addr, (int32_t*)expected, (int32_t)desired); + } else { + return upb_Atomic_CompareExchangeMscP64((uint64_t volatile*)addr, + (uint64_t*)expected, desired); + } +} + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + _upb_Atomic_CompareExchangeMscP(addr, expected, (uint64_t)desired, \ + sizeof(*addr)) + +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + _upb_Atomic_CompareExchangeMscP(addr, expected, (uint64_t)desired, \ + sizeof(*addr)) + +#endif + +#else // 32 bit pointers +#pragma intrinsic(_InterlockedExchange) +#define upb_Atomic_Store(addr, val, order) \ + (void)_InterlockedExchange((uint32_t volatile*)addr, (uint32_t)val) + +// If _Generic is available, use it to avoid emitting 'uintptr_t' differs in +// levels of indirection from 'void *' +#if __STDC_VERSION__ >= 201112L +#define upb_Atomic_Load(addr, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: (uintptr_t)upb_Atomic_LoadMsc32( \ + (uint32_t volatile*)(addr)), \ + UPB_ATOMIC(int32_t)*: upb_Atomic_LoadMsc32((int32_t volatile*)(addr)), \ + default: (void*)upb_Atomic_LoadMsc32((uint32_t volatile*)(addr))) + +#define upb_Atomic_Exchange(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: _InterlockedExchange((uint32_t volatile*)(addr), \ + (uint32_t)val), \ + default: (void*)_InterlockedExchange((uint32_t volatile*)addr, \ + (uint32_t)val)) +#else +#define upb_Atomic_Load(addr, order) \ + (void*)upb_Atomic_LoadMsc32((uint32_t volatile*)(addr)) + +#define upb_Atomic_Exchange(addr, val, order) \ + (void*)_InterlockedExchange((uint32_t volatile*)addr, (uint32_t)val) +#endif + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + upb_Atomic_CompareExchangeMscP32((uint32_t volatile*)addr, \ + (uint32_t*)expected, (uint32_t)desired) + +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + upb_Atomic_CompareExchangeMscP32((uint32_t volatile*)addr, \ + (uint32_t*)expected, (uint32_t)desired) +#endif + +#pragma intrinsic(_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedExchangeAdd64) + +// If _Generic is available, use it to switch between 32 and 64 bit types. +#if __STDC_VERSION__ >= 201112L +#define upb_Atomic_Add(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(int64_t)*: _InterlockedExchangeAdd64(addr, (int64_t)val), \ + UPB_ATOMIC(int32_t)*: _InterlockedExchangeAdd(addr, (int32_t)val)) +#define upb_Atomic_Sub(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(int64_t)*: _InterlockedExchangeAdd64(addr, -(int64_t)val), \ + UPB_ATOMIC(int32_t)*: _InterlockedExchangeAdd(addr, -(int32_t)val)) +#else +#define upb_Atomic_Add(addr, val, order) \ + sizeof(*addr) == sizeof(int32_t) \ + ? _InterlockedExchangeAdd((uint32_t volatile*)addr, (int32_t)val) \ + : _InterlockedExchangeAdd64((uint64_t volatile*)addr, (int64_t)val) +#define upb_Atomic_Sub(addr, val, order) \ + sizeof(*addr) == sizeof(int32_t) \ + ? _InterlockedExchangeAdd((uint32_t volatile*)addr, -(int32_t)val) \ + : _InterlockedExchangeAdd64((uint64_t volatile*)addr, -(int64_t)val) +#endif + +#else // No atomics + +#if !defined(UPB_SUPPRESS_MISSING_ATOMICS) +// NOLINTNEXTLINE +#error Your compiler does not support atomic instructions, which UPB uses. If you do not use UPB on multiple threads, you can suppress this error by defining UPB_SUPPRESS_MISSING_ATOMICS. +#endif + +#include + +#define upb_Atomic_Init(addr, val) (*addr = val) +#define upb_Atomic_Load(addr, order) (*addr) +#define upb_Atomic_Store(addr, val, order) (*(addr) = val) + +UPB_INLINE void* _upb_NonAtomic_Exchange(void* addr, void* value) { + void* old; + memcpy(&old, addr, sizeof(value)); + memcpy(addr, &value, sizeof(value)); + return old; +} + +#define upb_Atomic_Exchange(addr, val, order) _upb_NonAtomic_Exchange(addr, val) + +// `addr` and `expected` are logically double pointers. +UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, + void* expected, + void* desired) { + if (memcmp(addr, expected, sizeof(desired)) == 0) { + memcpy(addr, &desired, sizeof(desired)); + return true; + } else { + memcpy(expected, addr, sizeof(desired)); + return false; + } +} + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + _upb_NonAtomic_CompareExchangeStrongP((void*)addr, (void*)expected, \ + (void*)desired) +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + upb_Atomic_CompareExchangeStrong(addr, expected, desired, 0, 0) + +#define upb_Atomic_Add(addr, val, order) (*addr += val) +#define upb_Atomic_Sub(addr, val, order) (*addr -= val) + +#endif + + +#endif // UPB_PORT_ATOMIC_H_ + +#ifndef UPB_MESSAGE_COMPAT_H_ +#define UPB_MESSAGE_COMPAT_H_ + +#include + + +// Must be last. + +// upb does not support mixing minitables from different sources but these +// functions are still used by some existing users so for now we make them +// available here. This may or may not change in the future so do not add +// them to new code. + +#ifdef __cplusplus +extern "C" { +#endif + +// Same as upb_Message_NextExtension but iterates in reverse wire order +bool upb_Message_NextExtensionReverse(const upb_Message* msg, + const upb_MiniTableExtension** result, + uintptr_t* iter); +// Returns the minitable with the given field number, or NULL on failure. +const upb_MiniTableExtension* upb_Message_FindExtensionByNumber( + const upb_Message* msg, uint32_t field_number); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_COMPAT_H_ */ + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +#ifndef UPB_MESSAGE_INTERNAL_MAP_SORTER_H_ +#define UPB_MESSAGE_INTERNAL_MAP_SORTER_H_ + +#include +#include +#include + + +#ifndef UPB_MESSAGE_INTERNAL_MAP_ENTRY_H_ +#define UPB_MESSAGE_INTERNAL_MAP_ENTRY_H_ + +#include + + +// Map entries aren't actually stored for map fields, they are only used during +// parsing. (It helps a lot if all map entry messages have the same layout.) +// The mini_table layout code will ensure that all map entries have this layout. +// +// Note that users can and do create map entries directly, which will also use +// this layout. + +typedef struct { + struct upb_Message message; + // We only need 2 hasbits max, but due to alignment we'll use 8 bytes here, + // and the uint64_t helps make this clear. + uint64_t hasbits; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + double d[2]; // Padding for 32-bit builds. + } k; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + double d[2]; // Padding for 32-bit builds. + } v; +} upb_MapEntry; + +#endif // UPB_MESSAGE_INTERNAL_MAP_ENTRY_H_ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// _upb_mapsorter sorts maps and provides ordered iteration over the entries. +// Since maps can be recursive (map values can be messages which contain other +// maps), _upb_mapsorter can contain a stack of maps. + +typedef struct { + void const** entries; + int size; + int cap; +} _upb_mapsorter; + +typedef struct { + int start; + int pos; + int end; +} _upb_sortedmap; + +UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter* s) { + s->entries = NULL; + s->size = 0; + s->cap = 0; +} + +UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter* s) { + if (s->entries) upb_gfree(s->entries); +} + +UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter* s, + const struct upb_Map* map, + _upb_sortedmap* sorted, upb_MapEntry* ent) { + if (sorted->pos == sorted->end) return false; + const upb_tabent* tabent = (const upb_tabent*)s->entries[sorted->pos++]; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView key = upb_key_strview(tabent->key); + _upb_map_fromkey(key, &ent->k, map->key_size); + } else { + uintptr_t key = tabent->key.num; + memcpy(&ent->k, &key, map->key_size); + } + upb_value val = {tabent->val.val}; + _upb_map_fromvalue(val, &ent->v, map->val_size); + return true; +} + +UPB_INLINE bool _upb_sortedmap_nextext(_upb_mapsorter* s, + _upb_sortedmap* sorted, + const upb_Extension** ext) { + if (sorted->pos == sorted->end) return false; + *ext = (const upb_Extension*)s->entries[sorted->pos++]; + return true; +} + +UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter* s, + _upb_sortedmap* sorted) { + s->size = sorted->start; +} + +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const struct upb_Map* map, _upb_sortedmap* sorted); + +bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, + _upb_sortedmap* sorted); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_MAP_SORTER_H_ */ + +#ifndef UPB_MESSAGE_COMPARE_H_ +#define UPB_MESSAGE_COMPARE_H_ + +#include + + +// Must be last. + +enum { + // If set, upb_Message_IsEqual() will attempt to compare unknown fields. + // By its very nature this comparison is inexact. + kUpb_CompareOption_IncludeUnknownFields = (1 << 0) +}; + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns true if no known fields or extensions are set in the message. +UPB_API bool upb_Message_IsEmpty(const upb_Message* msg, + const upb_MiniTable* m); + +UPB_API bool upb_Message_IsEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, int options); + +// If |ctype| is a message then |m| must point to its minitable. +UPB_API_INLINE bool upb_MessageValue_IsEqual(upb_MessageValue val1, + upb_MessageValue val2, + upb_CType ctype, + const upb_MiniTable* m, + int options) { + switch (ctype) { + case kUpb_CType_Bool: + return val1.bool_val == val2.bool_val; + + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + return val1.int32_val == val2.int32_val; + + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return val1.int64_val == val2.int64_val; + + case kUpb_CType_String: + case kUpb_CType_Bytes: + return upb_StringView_IsEqual(val1.str_val, val2.str_val); + + case kUpb_CType_Message: + return upb_Message_IsEqual(val1.msg_val, val2.msg_val, m, options); + + default: + UPB_UNREACHABLE(); + return false; + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MESSAGE_COMPARE_H_ + +#ifndef UPB_MESSAGE_INTERNAL_COMPARE_UNKNOWN_H_ +#define UPB_MESSAGE_INTERNAL_COMPARE_UNKNOWN_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns true if unknown fields from the two messages are equal when sorted +// and varints are made canonical. +// +// This function is discouraged, as the comparison is inherently lossy without +// schema data: +// +// 1. We don't know whether delimited fields are sub-messages. Unknown +// sub-messages will therefore not have their fields sorted and varints +// canonicalized. +// 2. We don't know about oneof/non-repeated fields, which should semantically +// discard every value except the last. + +typedef enum { + kUpb_UnknownCompareResult_Equal = 0, + kUpb_UnknownCompareResult_NotEqual = 1, + kUpb_UnknownCompareResult_OutOfMemory = 2, + kUpb_UnknownCompareResult_MaxDepthExceeded = 3, +} upb_UnknownCompareResult; + +upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( + const upb_Message* msg1, const upb_Message* msg2, int max_depth); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_COMPARE_UNKNOWN_H_ */ + +#ifndef GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ +#define GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ + +#include +#include + + +// Must be last. + +#define kUpb_BaseField_Begin ((size_t)-1) +bool UPB_PRIVATE(_upb_Message_NextBaseField)(const upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField** out_f, + upb_MessageValue* out_v, + uintptr_t* iter); + +#endif // GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ + +#ifndef UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ +#define UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ + +#include +#include + + +#ifndef GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__ +#define GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__ + +#include + +// Must be last. + +// upb_ErrorHandler is a standard longjmp()-based exception handler for UPB. +// It is used for efficient error handling in cases where longjmp() is safe to +// use, such as in highly performance-sensitive C parsing code. +// +// This structure contains both a jmp_buf and an error code; the error code is +// stored in the structure prior to calling longjmp(). This is necessary because +// per the C standard, it is not possible to store the result of setjmp(), so +// the error code must be passed out-of-band. +// +// upb_ErrorHandler is generally not C++-compatible, because longjmp() does not +// run C++ destructors. So any library that supports upb_ErrorHandler should +// also support a regular return-based error handling mechanism. (Note: we +// could conceivably extend this to take a callback, which could either call +// longjmp() or throw a C++ exception. But since C++ exceptions are forbidden +// by the C++ style guide, there's not likely to be a demand for this.) +// +// To support both cases (longjmp() or return-based status) efficiently, code +// can be written like this: +// +// UPB_ATTR_CONST bool upb_Arena_HasErrHandler(const upb_Arena* a); +// +// INLINE void* upb_Arena_Malloc(upb_Arena* a, size_t size) { +// if (UPB_UNLIKELY(a->end - a->ptr < size)) { +// void* ret = upb_Arena_MallocFallback(a, size); +// UPB_MAYBE_ASSUME(upb_Arena_HasErrHandler(a), ret != NULL); +// return ret; +// } +// void* ret = a->ptr; +// a->ptr += size; +// UPB_ASSUME(ret != NULL); +// return ret; +// } +// +// If the optimizer can prove that an error handler is present, it can assume +// that upb_Arena_Malloc() will not return NULL. + +// We need to standardize on any error code that might be thrown by an error +// handler. + +typedef enum { + kUpb_ErrorCode_Ok = 0, + kUpb_ErrorCode_OutOfMemory = 1, + kUpb_ErrorCode_Malformed = 2, +} upb_ErrorCode; + +typedef struct { + int code; + jmp_buf buf; +} upb_ErrorHandler; + +UPB_INLINE void upb_ErrorHandler_Init(upb_ErrorHandler* e) { + e->code = kUpb_ErrorCode_Ok; +} + +UPB_INLINE UPB_NORETURN void upb_ErrorHandler_ThrowError(upb_ErrorHandler* e, + int code) { + UPB_ASSERT(code != kUpb_ErrorCode_Ok); + e->code = code; + UPB_LONGJMP(e->buf, 1); +} + + +#endif // GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__ + +#ifndef UPB_WIRE_INTERNAL_EPS_COPY_INPUT_STREAM_H_ +#define UPB_WIRE_INTERNAL_EPS_COPY_INPUT_STREAM_H_ + +#include +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// The maximum number of bytes a single protobuf field can take up in the +// wire format. We only want to do one bounds check per field, so the input +// stream guarantees that after upb_EpsCopyInputStream_IsDone() is called, +// the decoder can read this many bytes without performing another bounds +// check. The stream will copy into a patch buffer as necessary to guarantee +// this invariant. Since tags can only be up to 5 bytes, and a max-length scalar +// field can be 10 bytes, only 15 is required; but sizing up to 16 permits more +// efficient fixed size copies. +#define kUpb_EpsCopyInputStream_SlopBytes 16 + +struct upb_EpsCopyInputStream { + const char* end; // Can read up to SlopBytes bytes beyond this. + const char* limit_ptr; // For bounds checks, = end + UPB_MIN(limit, 0) + uintptr_t input_delta; // Diff between the original input pointer and patch + const char* buffer_start; // Pointer to the original input buffer + const char* capture_start; // If non-NULL, the start of the captured region. + ptrdiff_t limit; // Submessage limit relative to end + upb_ErrorHandler* err; // Error handler to use when things go wrong. + bool error; // To distinguish between EOF and error. +#ifndef NDEBUG + int guaranteed_bytes; +#endif + // Allocate double the size of what's required; this permits a fixed-size copy + // from the input buffer, regardless of how many bytes actually remain in the + // input buffer. + char patch[kUpb_EpsCopyInputStream_SlopBytes * 2]; +}; + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)( + struct upb_EpsCopyInputStream* e); + +UPB_INLINE bool upb_EpsCopyInputStream_IsError( + struct upb_EpsCopyInputStream* e) { + return e->error; +} + +UPB_INLINE void upb_EpsCopyInputStream_InitWithErrorHandler( + struct upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_ErrorHandler* err) { + e->buffer_start = *ptr; + e->capture_start = NULL; + e->err = err; + if (size <= kUpb_EpsCopyInputStream_SlopBytes) { + memset(&e->patch, 0, 32); + if (size) memcpy(&e->patch, *ptr, size); + e->input_delta = (uintptr_t)*ptr - (uintptr_t)e->patch; + *ptr = e->patch; + e->end = *ptr + size; + e->limit = 0; + } else { + e->end = *ptr + size - kUpb_EpsCopyInputStream_SlopBytes; + e->limit = kUpb_EpsCopyInputStream_SlopBytes; + e->input_delta = 0; + } + e->limit_ptr = e->end; + e->error = false; + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); +} + +UPB_INLINE void upb_EpsCopyInputStream_Init(struct upb_EpsCopyInputStream* e, + const char** ptr, size_t size) { + upb_EpsCopyInputStream_InitWithErrorHandler(e, ptr, size, NULL); +} + +UPB_ATTR_CONST +UPB_INLINE bool upb_EpsCopyInputStream_HasErrorHandler( + const struct upb_EpsCopyInputStream* e) { + return e && e->err != NULL; +} + +// Call this function to signal an error. If an error handler is set, it will be +// called and the function will never return. Otherwise, returns NULL to +// indicate an error. +const char* UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)( + struct upb_EpsCopyInputStream* e); + +UPB_INLINE const char* UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)( + struct upb_EpsCopyInputStream* e, const char* ptr) { + UPB_MAYBE_ASSUME(upb_EpsCopyInputStream_HasErrorHandler(e), ptr != NULL); + return ptr; +} + +//////////////////////////////////////////////////////////////////////////////// + +// Debug checks that attempt to ensure that no code paths will overrun the slop +// bytes even in the worst case. Since we are frequently parsing varints, it's +// possible that the user is trying to parse too many varints before calling +// upb_EpsCopyInputStream_IsDone(), but this error case is not detected because +// the varints are short. These checks ensure that will not overrun the slop +// bytes, even if each varint is its maximum possible length. + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)( + struct upb_EpsCopyInputStream* e) { +#ifndef NDEBUG + e->guaranteed_bytes = kUpb_EpsCopyInputStream_SlopBytes; +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)( + struct upb_EpsCopyInputStream* e) { +#ifndef NDEBUG + e->guaranteed_bytes = 0; +#endif +} + +// Signals the maximum number that the operation about to be performed may +// consume. +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)( + struct upb_EpsCopyInputStream* e, int n) { +#ifndef NDEBUG + if (e) { + UPB_ASSERT(e->guaranteed_bytes >= n); + e->guaranteed_bytes -= n; + } +#endif +} + +//////////////////////////////////////////////////////////////////////////////// + +typedef enum { + // The current stream position is at a limit. + kUpb_IsDoneStatus_Done, + + // The current stream position is not at a limit. + kUpb_IsDoneStatus_NotDone, + + // The current stream position is not at a limit, and the stream needs to + // be flipped to a new buffer before more data can be read. + kUpb_IsDoneStatus_NeedFallback, +} upb_IsDoneStatus; + +// Returns the status of the current stream position. This is a low-level +// function, it is simpler to call upb_EpsCopyInputStream_IsDone() if possible. +UPB_INLINE upb_IsDoneStatus UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneStatus)( + struct upb_EpsCopyInputStream* e, const char* ptr, int* overrun) { + *overrun = ptr - e->end; + if (UPB_LIKELY(ptr < e->limit_ptr)) { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + return kUpb_IsDoneStatus_NotDone; + } else if (UPB_LIKELY(*overrun == e->limit)) { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + return kUpb_IsDoneStatus_Done; + } else { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + return kUpb_IsDoneStatus_NeedFallback; + } +} + +const char* UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)( + struct upb_EpsCopyInputStream* e, const char* ptr, int overrun); + +UPB_INLINE bool upb_EpsCopyInputStream_IsDone(struct upb_EpsCopyInputStream* e, + const char** ptr) { + int overrun; + switch (UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneStatus)(e, *ptr, &overrun)) { + case kUpb_IsDoneStatus_Done: + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + return true; + case kUpb_IsDoneStatus_NotDone: + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + return false; + case kUpb_IsDoneStatus_NeedFallback: + *ptr = + UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(e, *ptr, overrun); + if (*ptr) { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + } else { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + } + return *ptr == NULL; + } + UPB_UNREACHABLE(); +} + +UPB_INLINE bool upb_EpsCopyInputStream_CheckSize( + const struct upb_EpsCopyInputStream* e, const char* ptr, int size) { + UPB_ASSERT(size >= 0); + return size <= e->limit - (ptr - e->end); +} + +// Returns a pointer into an input buffer that corresponds to the parsing +// pointer `ptr`. The returned pointer may be the same as `ptr`, but also may +// be different if we are currently parsing out of the patch buffer. +UPB_INLINE const char* UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)( + struct upb_EpsCopyInputStream* e, const char* ptr) { + // This somewhat silly looking add-and-subtract behavior provides provenance + // from the original input buffer's pointer. After optimization it produces + // the same assembly as just casting `(uintptr_t)ptr+input_delta` + // https://godbolt.org/z/zosG88oPn + size_t position = + (uintptr_t)ptr + e->input_delta - (uintptr_t)e->buffer_start; + return e->buffer_start + position; +} + +UPB_INLINE void upb_EpsCopyInputStream_StartCapture( + struct upb_EpsCopyInputStream* e, const char* ptr) { + UPB_ASSERT(e->capture_start == NULL); + e->capture_start = UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)(e, ptr); +} + +UPB_INLINE bool upb_EpsCopyInputStream_EndCapture( + struct upb_EpsCopyInputStream* e, const char* ptr, upb_StringView* sv) { + UPB_ASSERT(e->capture_start != NULL); + if (ptr - e->end > e->limit) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + const char* end = UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)(e, ptr); + sv->data = e->capture_start; + sv->size = end - sv->data; + e->capture_start = NULL; + return true; +} + +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringAlwaysAlias( + struct upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv) { + UPB_ASSERT(size <= PTRDIFF_MAX); + // The `size` must be within the input buffer. If `ptr` is in the input + // buffer, then using the slop bytes is fine (because they are real bytes from + // the tail of the input buffer). If `ptr` is in the patch buffer, then slop + // bytes represent bytes that do not actually exist in the original input + // buffer, so we must fail if the size extends into the slop bytes. + const char* limit = + e->end + (e->input_delta == 0) * kUpb_EpsCopyInputStream_SlopBytes; + if ((ptrdiff_t)size > limit - ptr) { + // For the moment, we consider this an error. In a multi-buffer world, + // it could be that the requested string extends into the next buffer, which + // is not an error and should be recoverable. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + const char* input = UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)(e, ptr); + *sv = upb_StringView_FromDataAndSize(input, size); + return ptr + size; +} + +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringEphemeral( + struct upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv) { + UPB_ASSERT(size <= PTRDIFF_MAX); + // Size must be within the current buffer (including slop bytes). + const char* limit = e->end + kUpb_EpsCopyInputStream_SlopBytes; + if ((ptrdiff_t)size > limit - ptr) { + // For the moment, we consider this an error. In a multi-buffer world, + // it could be that the requested string extends into the next buffer, which + // is not an error and should be recoverable. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + *sv = upb_StringView_FromDataAndSize(ptr, size); + return ptr + size; +} + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)( + struct upb_EpsCopyInputStream* e) { + UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit)); +} + +UPB_INLINE ptrdiff_t upb_EpsCopyInputStream_PushLimit( + struct upb_EpsCopyInputStream* e, const char* ptr, size_t size) { + UPB_ASSERT(size <= PTRDIFF_MAX); + ptrdiff_t limit = (ptrdiff_t)size + (ptr - e->end); + ptrdiff_t delta = e->limit - limit; + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); + e->limit = limit; + e->limit_ptr = e->end + UPB_MIN(0, limit); + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); + if (UPB_UNLIKELY(delta < 0)) { + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + return delta; +} + +// Pops the last limit that was pushed on this stream. This may only be called +// once IsDone() returns true. The user must pass the delta that was returned +// from PushLimit(). +UPB_INLINE void upb_EpsCopyInputStream_PopLimit( + struct upb_EpsCopyInputStream* e, const char* ptr, ptrdiff_t saved_delta) { + UPB_ASSERT(ptr - e->end == e->limit); + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); + e->limit += saved_delta; + e->limit_ptr = e->end + UPB_MIN(0, e->limit); + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); +} + +typedef const char* upb_EpsCopyInputStream_ParseDelimitedFunc( + struct upb_EpsCopyInputStream* e, const char* ptr, int size, void* ctx); + +UPB_FORCEINLINE bool upb_EpsCopyInputStream_TryParseDelimitedFast( + struct upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_EpsCopyInputStream_ParseDelimitedFunc* func, void* ctx) { + UPB_ASSERT(size <= PTRDIFF_MAX); + if ((ptrdiff_t)size > e->limit_ptr - *ptr) { + return false; + } + + // Fast case: Sub-message is <128 bytes and fits in the current buffer. + // This means we can preserve limit/limit_ptr verbatim. + const char* saved_limit_ptr = e->limit_ptr; + int saved_limit = e->limit; + e->limit_ptr = *ptr + size; + e->limit = e->limit_ptr - e->end; + UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit)); + *ptr = func(e, *ptr, size, ctx); + e->limit_ptr = saved_limit_ptr; + e->limit = saved_limit; + UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit)); + return true; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_INTERNAL_EPS_COPY_INPUT_STREAM_H_ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct upb_EpsCopyInputStream upb_EpsCopyInputStream; + +// Initializes a upb_EpsCopyInputStream using the contents of the buffer +// [*ptr, size]. Updates `*ptr` as necessary to guarantee that at least +// kUpb_EpsCopyInputStream_SlopBytes are available to read. +UPB_INLINE void upb_EpsCopyInputStream_Init(upb_EpsCopyInputStream* e, + const char** ptr, size_t size); + +// Like the previous function, but registers an error handler that will be +// called for any errors encountered. +UPB_INLINE void upb_EpsCopyInputStream_InitWithErrorHandler( + upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_ErrorHandler* err); + +// Returns true if the stream has an error handler. +// +// This function is marked const, which indicates to the compiler that the +// return value is solely a function of the pointer value. This is not +// entirely true if the stream is reinitialized with +// upb_EpsCopyInputStream_Init*(), so users must not call this function in +// any context where the stream may be reinitialized between calls to this +// function, and the presence of an error handler changes when reinitialized. +UPB_ATTR_CONST +UPB_INLINE bool upb_EpsCopyInputStream_HasErrorHandler( + const upb_EpsCopyInputStream* e); + +// Returns true if the stream is in the error state. A stream enters the error +// state when the user reads past a limit (caught in IsDone()) or the +// ZeroCopyInputStream returns an error. +UPB_INLINE bool upb_EpsCopyInputStream_IsError(upb_EpsCopyInputStream* e); + +// Returns true if the stream has hit a limit, either the current delimited +// limit or the overall end-of-stream. As a side effect, this function may flip +// the pointer to a new buffer if there are less than +// kUpb_EpsCopyInputStream_SlopBytes of data to be read in the current buffer. +// +// Postcondition: if the function returns false, there are at least +// kUpb_EpsCopyInputStream_SlopBytes of data available to read at *ptr. +// +// If this returns true, the user must call upb_EpsCopyInputStream_IsError() +// to distinguish between EOF and error. +UPB_INLINE bool upb_EpsCopyInputStream_IsDone(upb_EpsCopyInputStream* e, + const char** ptr); + +// Returns true if the given delimited field size is valid (it does not extend +// beyond any previously-pushed limits). `ptr` should point to the beginning +// of the field data, after the delimited size. +// +// Note that this does *not* guarantee that all of the data for this field is in +// the current buffer. +UPB_INLINE bool upb_EpsCopyInputStream_CheckSize( + const upb_EpsCopyInputStream* e, const char* ptr, int size); + +// Marks the start of a capture operation. Only one capture operation may be +// active at a time. The capture operation will be finalized by a call to +// upb_EpsCopyInputStream_EndCapture(). The captured string will be returned in +// sv, and will point to the original input buffer if possible. +UPB_INLINE void upb_EpsCopyInputStream_StartCapture(upb_EpsCopyInputStream* e, + const char* ptr); + +// Ends a capture operation and returns the captured string. This may only be +// called once per capture operation. Returns false if the capture operation +// was invalid (the parsing pointer extends beyond the end of the stream). +UPB_INLINE bool upb_EpsCopyInputStream_EndCapture(upb_EpsCopyInputStream* e, + const char* ptr, + upb_StringView* sv); + +// Reads a string from the stream and advances the pointer accordingly. The +// returned string view will always alias the input buffer. +// +// Returns NULL if size extends beyond the end of the current input buffer. +// Currently, we only support a single input buffer, so this function will only +// fail if `size` overflows the end of the stream. +// +// If/when we support multiple input buffers, there may be cases where this +// function returns failure, even if the requested region is valid, because the +// requested region spans multiple buffers. In this case, the caller must +// attempt to read the string using other string reading functions before +// signaling an error. +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringAlwaysAlias( + upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv); + +// Reads a string from the stream and advances the pointer accordingly. The +// returned string view is ephemeral, only valid until the next call to +// upb_EpsCopyInputStream. It may point to the patch buffer. +// +// Returns NULL if size extends beyond the end of the current buffer (which may +// be the patch buffer). +// +// IMPORTANT NOTE: If `size` extends beyond the end of the stream, the returned +// data may contain garbage bytes from the patch buffer. For efficiency, this +// function does not check that `size` is within the current limit or even the +// end of the stream. +// +// The bytes are guaranteed to be safe to read ephemerally, but they may contain +// garbage data that does not correspond to anything in the input. This error +// will be detected later, when calling upb_EpsCopyInputStream_IsDone() (because +// we will not end at the proper limit), but it may result in nonsense bytes +// ending up in the output. +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringEphemeral( + upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv); + +// Pushes a limit onto the stack of limits for the current stream. The limit +// will extend for `size` bytes beyond the position in `ptr`. Future calls to +// upb_EpsCopyInputStream_IsDone() will return `true` when the stream position +// reaches this limit. +// +// Returns a delta that the caller must store and supply to PopLimit() below. +// +// A return value of <0 indicates that `size` is too large, and exceeds a +// previous limit. If this occurs, the stream is in an error state and must no +// longer be used. +UPB_INLINE ptrdiff_t upb_EpsCopyInputStream_PushLimit(upb_EpsCopyInputStream* e, + const char* ptr, + size_t size); + +// Pops the last limit that was pushed on this stream. This may only be called +// once IsDone() returns true. The user must pass the delta that was returned +// from PushLimit(). +UPB_INLINE void upb_EpsCopyInputStream_PopLimit(upb_EpsCopyInputStream* e, + const char* ptr, + ptrdiff_t saved_delta); + +// Tries to perform a fast-path handling of the given delimited message data. +// If the sub-message beginning at `*ptr` and extending for `len` is short and +// fits within this buffer, calls `func` with `ctx` as a parameter, where the +// pushing and popping of limits is handled automatically and with lower cost +// than the normal PushLimit()/PopLimit() sequence. +UPB_FORCEINLINE bool upb_EpsCopyInputStream_TryParseDelimitedFast( + upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_EpsCopyInputStream_ParseDelimitedFunc* func, void* ctx); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +// Temporary overloads for functions whose signature has recently changed. +UPB_DEPRECATE_AND_INLINE() +UPB_INLINE void upb_EpsCopyInputStream_Init(upb_EpsCopyInputStream* e, + const char** ptr, size_t size, + bool enable_aliasing) { + upb_EpsCopyInputStream_Init(e, ptr, size); +} +#endif + + +#endif // UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ + +#ifndef UPB_WIRE_READER_H_ +#define UPB_WIRE_READER_H_ + +#include +#include +#include + + +#ifndef UPB_WIRE_INTERNAL_READER_H_ +#define UPB_WIRE_INTERNAL_READER_H_ + +#include +#include + + +// Must be last. + +#define kUpb_WireReader_WireTypeBits 3 +#define kUpb_WireReader_WireTypeMask 7 + +typedef struct { + const char* ptr; + uint64_t val; +} UPB_PRIVATE(_upb_WireReader_LongVarint); + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_PRIVATE(_upb_WireReader_LongVarint) +UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream); +UPB_PRIVATE(_upb_WireReader_LongVarint) +UPB_PRIVATE(_upb_WireReader_ReadLongTag)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream); +UPB_PRIVATE(_upb_WireReader_LongVarint) +UPB_PRIVATE(_upb_WireReader_ReadLongSize)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream); + +UPB_FORCEINLINE const char* upb_WireReader_ReadVarint( + const char* ptr, uint64_t* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 10); + uint8_t byte = *ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; + return ptr + 1; + } + UPB_PRIVATE(_upb_WireReader_LongVarint) res; + res = UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(ptr, byte, stream); + *val = res.val; + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr); +} + +UPB_FORCEINLINE const char* upb_WireReader_ReadTag( + const char* ptr, uint32_t* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 5); + uint8_t byte = *ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; + return ptr + 1; + } + UPB_PRIVATE(_upb_WireReader_LongVarint) res; + res = UPB_PRIVATE(_upb_WireReader_ReadLongTag)(ptr, byte, stream); + *val = res.val; + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr); +} + +UPB_FORCEINLINE const char* upb_WireReader_ReadSize( + const char* ptr, int* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 5); + uint8_t byte = *ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; + return ptr + 1; + } + UPB_PRIVATE(_upb_WireReader_LongVarint) res; + res = UPB_PRIVATE(_upb_WireReader_ReadLongSize)(ptr, byte, stream); + *val = res.val; + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr); +} + +UPB_API_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { + return tag >> kUpb_WireReader_WireTypeBits; +} + +UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { + return tag & kUpb_WireReader_WireTypeMask; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_INTERNAL_READER_H_ + +#ifndef UPB_WIRE_TYPES_H_ +#define UPB_WIRE_TYPES_H_ + +// A list of types as they are encoded on the wire. +typedef enum { + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; + +#endif /* UPB_WIRE_TYPES_H_ */ + +// Must be last. + +// The upb_WireReader interface is suitable for general-purpose parsing of +// protobuf binary wire format. It is designed to be used along with +// upb_EpsCopyInputStream for buffering, and all parsing routines in this file +// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is +// available to read without any bounds checks. + +#ifdef __cplusplus +extern "C" { +#endif + +// Parses a tag into `tag`, and returns a pointer past the end of the tag, or +// NULL if there was an error in the tag data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_FORCEINLINE const char* upb_WireReader_ReadTag( + const char* ptr, uint32_t* tag, upb_EpsCopyInputStream* stream); + +// Given a tag, returns the field number. +UPB_API_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag); + +// Given a tag, returns the wire type. +UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag); + +UPB_FORCEINLINE const char* upb_WireReader_ReadVarint( + const char* ptr, uint64_t* val, upb_EpsCopyInputStream* stream); + +// Skips data for a varint, returning a pointer past the end of the varint, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_SkipVarint( + const char* ptr, upb_EpsCopyInputStream* stream) { + uint64_t val; + return upb_WireReader_ReadVarint(ptr, &val, stream); +} + +// Reads a varint indicating the size of a delimited field into `size`, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size, + upb_EpsCopyInputStream* stream); + +// Reads a fixed32 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed32( + const char* ptr, void* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 4); + uint32_t uval; + memcpy(&uval, ptr, 4); + uval = upb_BigEndian32(uval); + memcpy(val, &uval, 4); + return ptr + 4; +} + +// Reads a fixed64 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed64( + const char* ptr, void* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 8); + uint64_t uval; + memcpy(&uval, ptr, 8); + uval = upb_BigEndian64(uval); + memcpy(val, &uval, 8); + return ptr + 8; +} + +const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream); + +// Skips data for a group, returning a pointer past the end of the group, or +// NULL if there was an error parsing the group. The `tag` argument should be +// the start group tag that begins the group. The `depth_limit` argument +// indicates how many levels of recursion the group is allowed to have before +// reporting a parse error (this limit exists to protect against stack +// overflow). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipGroup( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + const char* ret = + UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, 100, stream); + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, ret); +} + +UPB_INLINE const char* _upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + switch (upb_WireReader_GetWireType(tag)) { + case kUpb_WireType_Varint: + return upb_WireReader_SkipVarint(ptr, stream); + case kUpb_WireType_32Bit: + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 4); + return ptr + 4; + case kUpb_WireType_64Bit: + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 8); + return ptr + 8; + case kUpb_WireType_Delimited: { + int size; + ptr = upb_WireReader_ReadSize(ptr, &size, stream); + if (!ptr || !upb_EpsCopyInputStream_CheckSize(stream, ptr, size)) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } + ptr += size; + return ptr; + } + case kUpb_WireType_StartGroup: + return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, depth_limit, + stream); + case kUpb_WireType_EndGroup: + // Should be handled before now. + default: + // Unknown wire type. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } +} + +// Skips data for a wire value of any type, returning a pointer past the end of +// the data, or NULL if there was an error parsing the group. The `tag` argument +// should be the tag that was just parsed. The `depth_limit` argument indicates +// how many levels of recursion a group is allowed to have before reporting a +// parse error (this limit exists to protect against stack overflow). +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipValue(ptr, tag, 100, stream); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_READER_H_ + +#ifndef UPB_MESSAGE_COPY_H_ +#define UPB_MESSAGE_COPY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Deep clones a message using the provided target arena. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); + +// Shallow clones a message using the provided target arena. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); + +// Deep clones array contents. +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena); + +// Deep clones map contents. +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena); + +// Deep copies the message from src to dst. +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m, upb_Arena* arena); + +// Shallow copies the message from src to dst. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MESSAGE_COPY_H_ +#ifndef GOOGLE_UPB_UPB_MESSAGE_MERGE_H__ +#define GOOGLE_UPB_UPB_MESSAGE_MERGE_H__ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + upb_Arena* arena); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // GOOGLE_UPB_UPB_MESSAGE_MERGE_H__ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE char _upb_ToBase92(int8_t ch) { + extern const char _kUpb_ToBase92[]; + UPB_ASSERT(0 <= ch && ch < 92); + return _kUpb_ToBase92[ch]; +} + +UPB_INLINE char _upb_FromBase92(uint8_t ch) { + extern const int8_t _kUpb_FromBase92[]; + if (' ' > ch || ch > '~') return -1; + return _kUpb_FromBase92[ch - ' ']; +} + +UPB_INLINE const char* _upb_Base92_DecodeVarint(const char* ptr, + const char* end, char first_ch, + uint8_t min, uint8_t max, + uint32_t* out_val) { + uint32_t val = 0; + uint32_t shift = 0; + const int bits_per_char = + upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min)); + char ch = first_ch; + while (1) { + uint32_t bits = _upb_FromBase92(ch) - _upb_FromBase92(min); + val |= bits << shift; + if (ptr == end || *ptr < min || max < *ptr) { + *out_val = val; + UPB_ASSUME(ptr != NULL); + return ptr; + } + ch = *ptr++; + shift += bits_per_char; + if (shift >= 32) return NULL; + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ + + +// Must be last. + +// upb_MdDecoder: used internally for decoding MiniDescriptors for messages, +// extensions, and enums. +typedef struct { + const char* end; + upb_Status* status; + jmp_buf err; +} upb_MdDecoder; + +UPB_PRINTF(2, 3) +UPB_NORETURN UPB_INLINE void upb_MdDecoder_ErrorJmp(upb_MdDecoder* d, + const char* fmt, ...) { + if (d->status) { + va_list argp; + upb_Status_SetErrorMessage(d->status, "Error building mini table: "); + va_start(argp, fmt); + upb_Status_VAppendErrorFormat(d->status, fmt, argp); + va_end(argp); + } + UPB_LONGJMP(d->err, 1); +} + +UPB_INLINE void upb_MdDecoder_CheckOutOfMemory(upb_MdDecoder* d, + const void* ptr) { + if (!ptr) upb_MdDecoder_ErrorJmp(d, "Out of memory"); +} + +UPB_INLINE const char* upb_MdDecoder_DecodeBase92Varint( + upb_MdDecoder* d, const char* ptr, char first_ch, uint8_t min, uint8_t max, + uint32_t* out_val) { + ptr = _upb_Base92_DecodeVarint(ptr, d->end, first_ch, min, max, out_val); + if (!ptr) upb_MdDecoder_ErrorJmp(d, "Overlong varint"); + return ptr; +} + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_WIRE_CONSTANTS_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_WIRE_CONSTANTS_H_ + + +// Must be last. + +typedef enum { + kUpb_EncodedType_Double = 0, + kUpb_EncodedType_Float = 1, + kUpb_EncodedType_Fixed32 = 2, + kUpb_EncodedType_Fixed64 = 3, + kUpb_EncodedType_SFixed32 = 4, + kUpb_EncodedType_SFixed64 = 5, + kUpb_EncodedType_Int32 = 6, + kUpb_EncodedType_UInt32 = 7, + kUpb_EncodedType_SInt32 = 8, + kUpb_EncodedType_Int64 = 9, + kUpb_EncodedType_UInt64 = 10, + kUpb_EncodedType_SInt64 = 11, + kUpb_EncodedType_OpenEnum = 12, + kUpb_EncodedType_Bool = 13, + kUpb_EncodedType_Bytes = 14, + kUpb_EncodedType_String = 15, + kUpb_EncodedType_Group = 16, + kUpb_EncodedType_Message = 17, + kUpb_EncodedType_ClosedEnum = 18, + + kUpb_EncodedType_RepeatedBase = 20, +} upb_EncodedType; + +typedef enum { + kUpb_EncodedFieldModifier_FlipPacked = 1 << 0, + kUpb_EncodedFieldModifier_IsRequired = 1 << 1, + kUpb_EncodedFieldModifier_IsProto3Singular = 1 << 2, + kUpb_EncodedFieldModifier_FlipValidateUtf8 = 1 << 3, +} upb_EncodedFieldModifier; + +enum { + kUpb_EncodedValue_MinField = ' ', + kUpb_EncodedValue_MaxField = 'I', + kUpb_EncodedValue_MinModifier = 'L', + kUpb_EncodedValue_MaxModifier = '[', + kUpb_EncodedValue_End = '^', + kUpb_EncodedValue_MinSkip = '_', + kUpb_EncodedValue_MaxSkip = '~', + kUpb_EncodedValue_OneofSeparator = '~', + kUpb_EncodedValue_FieldSeparator = '|', + kUpb_EncodedValue_MinOneofField = ' ', + kUpb_EncodedValue_MaxOneofField = 'b', + kUpb_EncodedValue_MaxEnumMask = 'A', +}; + +enum { + kUpb_EncodedVersion_EnumV1 = '!', + kUpb_EncodedVersion_ExtensionV1 = '#', + kUpb_EncodedVersion_MapV1 = '%', + kUpb_EncodedVersion_MessageV1 = '$', + kUpb_EncodedVersion_MessageSetV1 = '&', +}; + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_WIRE_CONSTANTS_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_ + +// Must be last. + +typedef enum { + kUpb_FieldModifier_IsRepeated = 1 << 0, + kUpb_FieldModifier_IsPacked = 1 << 1, + kUpb_FieldModifier_IsClosedEnum = 1 << 2, + kUpb_FieldModifier_IsProto3Singular = 1 << 3, + kUpb_FieldModifier_IsRequired = 1 << 4, + kUpb_FieldModifier_ValidateUtf8 = 1 << 5, +} kUpb_FieldModifier; + +// These modifiers are also used on the wire. +typedef enum { + kUpb_MessageModifier_ValidateUtf8 = 1 << 0, + kUpb_MessageModifier_DefaultIsPacked = 1 << 1, + kUpb_MessageModifier_IsExtendable = 1 << 2, +} kUpb_MessageModifier; + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ + +#include + + +// Must be last. + +// If the input buffer has at least this many bytes available, the encoder call +// is guaranteed to succeed (as long as field number order is maintained). +#define kUpb_MtDataEncoder_MinSize 16 + +typedef struct { + char* end; // Limit of the buffer passed as a parameter. + // Aliased to internal-only members in .cc. + char internal[32]; +} upb_MtDataEncoder; + +#ifdef __cplusplus +extern "C" { +#endif + +// Encodes field/oneof information for a given message. The sequence of calls +// should look like: +// +// upb_MtDataEncoder e; +// char buf[256]; +// char* ptr = buf; +// e.end = ptr + sizeof(buf); +// unit64_t msg_mod = ...; // bitwise & of kUpb_MessageModifiers or zero +// ptr = upb_MtDataEncoder_StartMessage(&e, ptr, msg_mod); +// // Fields *must* be in field number order. +// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...); +// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...); +// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...); +// +// // If oneofs are present. Oneofs must be encoded after regular fields. +// ptr = upb_MiniTable_StartOneof(&e, ptr) +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// +// ptr = upb_MiniTable_StartOneof(&e, ptr); +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// +// Oneofs must be encoded after all regular fields. +char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr, + uint64_t msg_mod); +char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod); +char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr); +char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr, + uint32_t field_num); + +// Encodes the set of values for a given enum. The values must be given in +// order (after casting to uint32_t), and repeats are not allowed. +char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr); +char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr, + uint32_t val); +char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr); + +// Encodes an entire mini descriptor for an extension. +char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod); + +// Encodes an entire mini descriptor for a map. +char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr, + upb_FieldType key_type, + upb_FieldType value_type, uint64_t key_mod, + uint64_t value_mod); + +// Encodes an entire mini descriptor for a message set. +char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ */ + +#ifndef UPB_MINI_TABLE_GENERATED_REGISTRY_H_ +#define UPB_MINI_TABLE_GENERATED_REGISTRY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* Generated registry: a global singleton that gathers all extensions linked + * into the binary. + * + * This singleton is thread-safe and lock-free, implemented using atomics. The + * registry is lazily initialized the first time it is loaded. When all + * references are released, the registry will be destroyed. New loads + * afterwards will simply reload the same registry as needed. + * + * The extension minitables are registered in gencode using linker arrays. Each + * .proto file produces a weak, hidden, constructor function that adds all + * visible extensions from the array into the registry. In each binary, only + * one copy of the constructor will actually be preserved by the linker, and + * that copy will add all of the extensions for the entire binary. All of these + * are added to a global linked list of minitables pre-main, which are then used + * to construct this singleton as needed. + */ + +typedef struct upb_GeneratedRegistryRef upb_GeneratedRegistryRef; + +// Loads the generated registry, returning a reference to it. The reference +// must be held for the lifetime of any ExtensionRegistry obtained from it. +// +// Returns NULL on failure. +UPB_API const upb_GeneratedRegistryRef* upb_GeneratedRegistry_Load(void); + +// Releases a reference to the generated registry. This may destroy the +// registry if there are no other references to it. +// +// NULL is a valid argument and is simply ignored for easier error handling in +// callers. +UPB_API void upb_GeneratedRegistry_Release(const upb_GeneratedRegistryRef* r); + +// Returns the extension registry contained by a reference to the generated +// registry. +// +// The reference must be held for the lifetime of the registry. +UPB_API const upb_ExtensionRegistry* upb_GeneratedRegistry_Get( + const upb_GeneratedRegistryRef* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_TABLE_GENERATED_REGISTRY_H_ + +#ifndef UPB_REFLECTION_DEF_POOL_INTERNAL_H_ +#define UPB_REFLECTION_DEF_POOL_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s); +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s); +upb_ExtensionRegistry* _upb_DefPool_ExtReg(const upb_DefPool* s); + +bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTableExtension* ext, + const upb_FieldDef* f); +bool _upb_DefPool_InsertSym(upb_DefPool* s, upb_StringView sym, upb_value v, + upb_Status* status); +bool _upb_DefPool_LookupSym(const upb_DefPool* s, const char* sym, size_t size, + upb_value* v); + +void** _upb_DefPool_ScratchData(const upb_DefPool* s); +size_t* _upb_DefPool_ScratchSize(const upb_DefPool* s); +void _upb_DefPool_SetPlatform(upb_DefPool* s, upb_MiniTablePlatform platform); + +// For generated code only: loads a generated descriptor. +typedef struct _upb_DefPool_Init { + struct _upb_DefPool_Init** deps; // Dependencies of this file. + const upb_MiniTableFile* layout; + const char* filename; + upb_StringView descriptor; // Serialized descriptor. +} _upb_DefPool_Init; + +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init); + +// Should only be directly called by tests. This variant lets us suppress +// the use of compiled-in tables, forcing a rebuild of the tables at runtime. +bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable); + +const upb_ExtensionRegistry* _upb_DefPool_GeneratedExtensionRegistry( + const upb_DefPool* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_POOL_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_DEF_BUILDER_INTERNAL_H_ +#define UPB_REFLECTION_DEF_BUILDER_INTERNAL_H_ + +#include +#include +#include +#include + + +// Must be last. + +// We want to copy the options verbatim into the destination options proto. +// We use serialize+parse as our deep copy. +#define UPB_DEF_SET_OPTIONS(target, desc_type, options_type, proto) \ + if (google_protobuf_##desc_type##_has_options(proto)) { \ + size_t size; \ + char* pb = google_protobuf_##options_type##_serialize( \ + google_protobuf_##desc_type##_options(proto), ctx->tmp_arena, &size); \ + if (!pb) _upb_DefBuilder_OomErr(ctx); \ + target = google_protobuf_##options_type##_parse_ex( \ + pb, size, _upb_DefPool_GeneratedExtensionRegistry(ctx->symtab), 0, \ + _upb_DefBuilder_Arena(ctx)); \ + if (!target) _upb_DefBuilder_OomErr(ctx); \ + } else { \ + target = (const google_protobuf_##options_type*)kUpbDefOptDefault; \ + } + +#ifdef __cplusplus +extern "C" { +#endif + +struct upb_DefBuilder { + upb_DefPool* symtab; + upb_strtable feature_cache; // Caches features by identity. + google_protobuf_FeatureSet* legacy_features; // For computing legacy features. + char* tmp_buf; // Temporary buffer in tmp_arena. + size_t tmp_buf_size; // Size of temporary buffer. + upb_FileDef* file; // File we are building. + upb_Arena* arena; // Allocate defs here. + upb_Arena* tmp_arena; // For temporary allocations. + upb_Status* status; // Record errors here. + const upb_MiniTableFile* layout; // NULL if we should build layouts. + upb_MiniTablePlatform platform; // Platform we are targeting. + int enum_count; // Count of enums built so far. + int msg_count; // Count of messages built so far. + int ext_count; // Count of extensions built so far. + jmp_buf err; // longjmp() on error. +}; + +extern const char* kUpbDefOptDefault; + +// ctx->status has already been set elsewhere so just fail/longjmp() +UPB_NORETURN void _upb_DefBuilder_FailJmp(upb_DefBuilder* ctx); + +UPB_NORETURN void _upb_DefBuilder_Errf(upb_DefBuilder* ctx, const char* fmt, + ...) UPB_PRINTF(2, 3); +UPB_NORETURN void _upb_DefBuilder_OomErr(upb_DefBuilder* ctx); + +const char* _upb_DefBuilder_MakeFullName(upb_DefBuilder* ctx, + const char* prefix, + upb_StringView name); + +// Given a symbol and the base symbol inside which it is defined, +// find the symbol's definition. +const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, + const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t* type); + +const void* _upb_DefBuilder_Resolve(upb_DefBuilder* ctx, + const char* from_name_dbg, const char* base, + upb_StringView sym, upb_deftype_t type); + +char _upb_DefBuilder_ParseEscape(upb_DefBuilder* ctx, const upb_FieldDef* f, + const char** src, const char* end); + +const char* _upb_DefBuilder_FullToShort(const char* fullname); + +UPB_INLINE void* _upb_DefBuilder_Alloc(upb_DefBuilder* ctx, size_t bytes) { + if (bytes == 0) return NULL; + void* ret = upb_Arena_Malloc(ctx->arena, bytes); + if (!ret) _upb_DefBuilder_OomErr(ctx); + return ret; +} + +/* Allocates an array of `count` elements, checking for size_t overflow */ +UPB_INLINE void* _upb_DefBuilder_AllocCounted(upb_DefBuilder* ctx, size_t size, + size_t count) { + if (count == 0) return NULL; + if (SIZE_MAX / size < count) { + _upb_DefBuilder_OomErr(ctx); + } + return _upb_DefBuilder_Alloc(ctx, size * count); +} + +#define UPB_DEFBUILDER_ALLOCARRAY(ctx, type, count) \ + ((type*)_upb_DefBuilder_AllocCounted(ctx, sizeof(type), (count))) + +// Adds a symbol |v| to the symtab, which must be a def pointer previously +// packed with pack_def(). The def's pointer to upb_FileDef* must be set before +// adding, so we know which entries to remove if building this file fails. +UPB_INLINE void _upb_DefBuilder_Add(upb_DefBuilder* ctx, const char* name, + upb_value v) { + upb_StringView sym = {.data = name, .size = strlen(name)}; + bool ok = _upb_DefPool_InsertSym(ctx->symtab, sym, v, ctx->status); + if (!ok) _upb_DefBuilder_FailJmp(ctx); +} + +UPB_INLINE upb_Arena* _upb_DefBuilder_Arena(const upb_DefBuilder* ctx) { + return ctx->arena; +} + +UPB_INLINE upb_FileDef* _upb_DefBuilder_File(const upb_DefBuilder* ctx) { + return ctx->file; +} + +// This version of CheckIdent() is only called by other, faster versions after +// they detect a parsing error. +void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, + bool full); + +// Verify a full identifier string. This is slightly more complicated than +// verifying a relative identifier string because we must track '.' chars. +UPB_INLINE void _upb_DefBuilder_CheckIdentFull(upb_DefBuilder* ctx, + upb_StringView name) { + bool good = name.size > 0; + bool start = true; + + for (size_t i = 0; i < name.size; i++) { + const char c = name.data[i]; + const char d = c | 0x20; // force lowercase + const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); + const bool is_numer = ('0' <= c) & (c <= '9') & !start; + const bool is_dot = (c == '.') & !start; + + good &= is_alpha | is_numer | is_dot; + start = is_dot; + } + + if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); +} + +UPB_INLINE bool _upb_DefBuilder_IsLegacyEdition(google_protobuf_Edition edition) { + // Should only be called for a real edition, not a placeholder like + // EDITION_LEGACY. + UPB_ASSERT(edition >= google_protobuf_EDITION_PROTO2); + return edition <= google_protobuf_EDITION_PROTO3; +} + +// Returns true if the returned feature set is new and must be populated. +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const google_protobuf_FeatureSet* parent, + upb_StringView key, + google_protobuf_FeatureSet** set); + +const google_protobuf_FeatureSet* _upb_DefBuilder_DoResolveFeatures( + upb_DefBuilder* ctx, const google_protobuf_FeatureSet* parent, + const google_protobuf_FeatureSet* child, bool is_implicit); + +UPB_INLINE const google_protobuf_FeatureSet* _upb_DefBuilder_ResolveFeatures( + upb_DefBuilder* ctx, const google_protobuf_FeatureSet* parent, + const google_protobuf_FeatureSet* child) { + return _upb_DefBuilder_DoResolveFeatures(ctx, parent, child, false); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_BUILDER_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_FILE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_FILE_DEF_INTERNAL_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_MiniTableExtension* _upb_FileDef_ExtensionMiniTable( + const upb_FileDef* f, int i); +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f); +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f); +bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f); +bool _upb_FileDef_ImplicitFieldPresenceDisabled(const upb_FileDef* f); + +// upb_FileDef_Package() returns "" if f->package is NULL, this does not. +const char* _upb_FileDef_RawPackage(const upb_FileDef* f); + +void _upb_FileDef_Create(upb_DefBuilder* ctx, + const google_protobuf_FileDescriptorProto* file_proto); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FILE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_MESSAGE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_MESSAGE_DEF_INTERNAL_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_MessageDef* _upb_MessageDef_At(const upb_MessageDef* m, int i); +bool _upb_MessageDef_InMessageSet(const upb_MessageDef* m); +bool _upb_MessageDef_Insert(upb_MessageDef* m, const char* name, size_t size, + upb_value v, upb_Arena* a); +void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, + const upb_FieldDef* f); +bool _upb_MessageDef_IsValidExtensionNumber(const upb_MessageDef* m, int n); +void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m); +void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, + const upb_MessageDef* m); +void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m); + +// Allocate and initialize an array of |n| message defs. +upb_MessageDef* _upb_MessageDefs_New( + upb_DefBuilder* ctx, int n, const google_protobuf_DescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ +#define UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + +// This file contains the serialized FeatureSetDefaults object for +// language-independent features and (possibly at some point) for upb-specific +// features. This is used for feature resolution under Editions. +// NOLINTBEGIN +// clang-format off +#define UPB_INTERNAL_UPB_EDITION_DEFAULTS "\n\027\030\204\007\"\000*\020\010\001\020\002\030\002 \003(\0010\0028\002@\001\n\027\030\347\007\"\000*\020\010\002\020\001\030\001 \002(\0010\0018\002@\001\n\027\030\350\007\"\014\010\001\020\001\030\001 \002(\0010\001*\0048\002@\001\n\027\030\351\007\"\020\010\001\020\001\030\001 \002(\0010\0018\001@\002*\000\n\027\030\217N\"\020\010\001\020\001\030\001 \002(\0010\0018\003@\002*\000 \346\007(\351\007" +// clang-format on +// NOLINTEND + +#endif // UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + +#ifndef UPB_REFLECTION_DESC_STATE_INTERNAL_H_ +#define UPB_REFLECTION_DESC_STATE_INTERNAL_H_ + + +// Must be last. + +// Manages the storage for mini descriptor strings as they are being encoded. +// TODO: Move some of this state directly into the encoder, maybe. +typedef struct { + upb_MtDataEncoder e; + size_t bufsize; + char* buf; + char* ptr; +} upb_DescState; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void _upb_DescState_Init(upb_DescState* d) { + d->bufsize = kUpb_MtDataEncoder_MinSize * 2; + d->buf = NULL; + d->ptr = NULL; +} + +bool _upb_DescState_Grow(upb_DescState* d, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DESC_STATE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ENUM_DEF_INTERNAL_H_ +#define UPB_REFLECTION_ENUM_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i); +bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a); +const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); + +// Allocate and initialize an array of |n| enum defs. +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ENUM_RESERVED_RANGE_INTERNAL_H_ +#define UPB_REFLECTION_ENUM_RESERVED_RANGE_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_EnumReservedRange* _upb_EnumReservedRange_At(const upb_EnumReservedRange* r, + int i); + +// Allocate and initialize an array of |n| reserved ranges owned by |e|. +upb_EnumReservedRange* _upb_EnumReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* protos, + const upb_EnumDef* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_RESERVED_RANGE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_ENUM_VALUE_DEF_INTERNAL_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i); + +// Allocate and initialize an array of |n| enum value defs owned by |e|. +upb_EnumValueDef* _upb_EnumValueDefs_New( + upb_DefBuilder* ctx, const char* prefix, int n, + const google_protobuf_EnumValueDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_EnumDef* e, bool* is_sorted); + +const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, + size_t n, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_VALUE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_INTERNAL_STRDUP2_H_ +#define UPB_REFLECTION_INTERNAL_STRDUP2_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Variant that works with a length-delimited rather than NULL-delimited string, +// as supported by strtable. +char* upb_strdup2(const char* s, size_t len, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_INTERNAL_STRDUP2_H_ */ + +#ifndef UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ +#define UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i); + +// Allocate and initialize an array of |n| extension ranges owned by |m|. +upb_ExtensionRange* _upb_ExtensionRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ExtensionRange* const* protos, + const google_protobuf_FeatureSet* parent_features, const upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_FIELD_DEF_INTERNAL_H_ +#define UPB_REFLECTION_FIELD_DEF_INTERNAL_H_ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_FieldDef* _upb_FieldDef_At(const upb_FieldDef* f, int i); + +bool _upb_FieldDef_IsClosedEnum(const upb_FieldDef* f); +bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f); +int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f); +uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f); +void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix, + upb_FieldDef* f); +void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, + const upb_FieldDef* f); + +// Allocate and initialize an array of |n| extensions (field defs). +upb_FieldDef* _upb_Extensions_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m); + +// Allocate and initialize an array of |n| field defs. +upb_FieldDef* _upb_FieldDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m, bool* is_sorted); + +// Allocate and return a list of pointers to the |n| field defs in |ff|, +// sorted by field number. +const upb_FieldDef** _upb_FieldDefs_Sorted(const upb_FieldDef* f, int n, + upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FIELD_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ONEOF_DEF_INTERNAL_H_ +#define UPB_REFLECTION_ONEOF_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i); +void _upb_OneofDef_Insert(upb_DefBuilder* ctx, upb_OneofDef* o, + const upb_FieldDef* f, const char* name, size_t size); + +// Allocate and initialize an array of |n| oneof defs owned by |m|. +upb_OneofDef* _upb_OneofDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_OneofDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_MessageDef* m); + +size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ONEOF_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int i); + +// Allocate and initialize an array of |n| service defs. +upb_ServiceDef* _upb_ServiceDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_ServiceDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features); + +void _upb_ServiceDef_InsertMethod(upb_DefBuilder* ctx, upb_ServiceDef* s, + const upb_MethodDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_MESSAGE_RESERVED_RANGE_INTERNAL_H_ +#define UPB_REFLECTION_MESSAGE_RESERVED_RANGE_INTERNAL_H_ + + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_MESSAGE_RESERVED_RANGE_H_ +#define UPB_REFLECTION_MESSAGE_RESERVED_RANGE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t upb_MessageReservedRange_Start(const upb_MessageReservedRange* r); +int32_t upb_MessageReservedRange_End(const upb_MessageReservedRange* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_RESERVED_RANGE_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_MessageReservedRange* _upb_MessageReservedRange_At( + const upb_MessageReservedRange* r, int i); + +// Allocate and initialize an array of |n| reserved ranges owned by |m|. +upb_MessageReservedRange* _upb_MessageReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ReservedRange* const* protos, + const upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_RESERVED_RANGE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_METHOD_DEF_INTERNAL_H_ +#define UPB_REFLECTION_METHOD_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i); + +// Allocate and initialize an array of |n| method defs owned by |s|. +upb_MethodDef* _upb_MethodDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_MethodDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_ServiceDef* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_METHOD_DEF_INTERNAL_H_ */ + +#ifndef UPB_UTIL_DEF_TO_PROTO_H_ +#define UPB_UTIL_DEF_TO_PROTO_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +// Functions for converting defs back to the equivalent descriptor proto. +// Ultimately the goal is that a round-trip proto->def->proto is lossless. Each +// function returns a new proto created in arena `a`, or NULL if memory +// allocation failed. +google_protobuf_DescriptorProto* upb_MessageDef_ToProto(const upb_MessageDef* m, + upb_Arena* a); +google_protobuf_EnumDescriptorProto* upb_EnumDef_ToProto(const upb_EnumDef* e, + upb_Arena* a); +google_protobuf_EnumValueDescriptorProto* upb_EnumValueDef_ToProto( + const upb_EnumValueDef* e, upb_Arena* a); +google_protobuf_FieldDescriptorProto* upb_FieldDef_ToProto( + const upb_FieldDef* f, upb_Arena* a); +google_protobuf_OneofDescriptorProto* upb_OneofDef_ToProto( + const upb_OneofDef* o, upb_Arena* a); +google_protobuf_FileDescriptorProto* upb_FileDef_ToProto(const upb_FileDef* f, + upb_Arena* a); +google_protobuf_MethodDescriptorProto* upb_MethodDef_ToProto( + const upb_MethodDef* m, upb_Arena* a); +google_protobuf_ServiceDescriptorProto* upb_ServiceDef_ToProto( + const upb_ServiceDef* s, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_UTIL_DEF_TO_PROTO_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ENUM_RESERVED_RANGE_H_ +#define UPB_REFLECTION_ENUM_RESERVED_RANGE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t upb_EnumReservedRange_Start(const upb_EnumReservedRange* r); +int32_t upb_EnumReservedRange_End(const upb_EnumReservedRange* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_RESERVED_RANGE_H_ */ + +#ifndef UPB_WIRE_INTERNAL_CONSTANTS_H_ +#define UPB_WIRE_INTERNAL_CONSTANTS_H_ + +#define kUpb_WireFormat_DefaultDepthLimit 100 + +// MessageSet wire format is: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required bytes message = 3; +// } +// } + +enum { + kUpb_MsgSet_Item = 1, + kUpb_MsgSet_TypeId = 2, + kUpb_MsgSet_Message = 3, +}; + +#endif /* UPB_WIRE_INTERNAL_CONSTANTS_H_ */ + +/* + * Internal implementation details of the decoder that are shared between + * decode.c and decode_fast.c. + */ + +#ifndef UPB_WIRE_INTERNAL_DECODER_H_ +#define UPB_WIRE_INTERNAL_DECODER_H_ + +#include +#include +#include +#include + +#include "utf8_range.h" + +// Must be last. + +#define DECODE_NOGROUP (uint32_t)-1 + +typedef struct upb_Decoder { + upb_EpsCopyInputStream input; + const upb_ExtensionRegistry* extreg; + upb_Message* original_msg; // Pointer to preserve data to + int depth; // Tracks recursion depth to bound stack usage. + uint32_t end_group; // field number of END_GROUP tag, else DECODE_NOGROUP. + uint16_t options; + bool missing_required; + bool message_is_done; + union { + upb_Arena arena; + void* foo[UPB_ARENA_SIZE_HACK / sizeof(void*)]; + }; + upb_ErrorHandler err; + +#ifndef NDEBUG + char* trace_buf; + char* trace_ptr; + char* trace_end; +#endif +} upb_Decoder; + +UPB_INLINE const char* upb_Decoder_Init(upb_Decoder* d, const char* buf, + size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena, + char* trace_buf, size_t trace_size) { + upb_ErrorHandler_Init(&d->err); + upb_EpsCopyInputStream_InitWithErrorHandler(&d->input, &buf, size, &d->err); + + UPB_STATIC_ASSERT((int)kUpb_DecodeStatus_Ok == (int)kUpb_ErrorCode_Ok, + "mismatched error codes"); + UPB_STATIC_ASSERT( + (int)kUpb_DecodeStatus_OutOfMemory == (int)kUpb_ErrorCode_OutOfMemory, + "mismatched error codes"); + UPB_STATIC_ASSERT( + (int)kUpb_DecodeStatus_Malformed == (int)kUpb_ErrorCode_Malformed, + "mismatched error codes"); + + if (options & kUpb_DecodeOption_AlwaysValidateUtf8) { + // Fasttable decoder does not support this option. + options |= kUpb_DecodeOption_DisableFastTable; + } + + d->extreg = extreg; + d->depth = upb_DecodeOptions_GetEffectiveMaxDepth(options); + d->end_group = DECODE_NOGROUP; + d->options = (uint16_t)options; + d->missing_required = false; + d->message_is_done = false; +#ifndef NDEBUG + d->trace_buf = trace_buf; + d->trace_ptr = trace_buf; + d->trace_end = UPB_PTRADD(trace_buf, trace_size); +#endif + if (trace_buf) *trace_buf = 0; // Null-terminate. + + // Violating the encapsulation of the arena for performance reasons. + // This is a temporary arena that we swap into and swap out of when we are + // done. The temporary arena only needs to be able to handle allocation, + // not fuse or free, so it does not need many of the members to be initialized + // (particularly parent_or_count). + UPB_PRIVATE(_upb_Arena_SwapIn)(&d->arena, arena); + return buf; +} + +UPB_INLINE upb_DecodeStatus upb_Decoder_Destroy(upb_Decoder* d, + upb_Arena* arena) { + UPB_PRIVATE(_upb_Arena_SwapOut)(arena, &d->arena); + return (upb_DecodeStatus)d->err.code; +} + +#ifndef NDEBUG +UPB_INLINE bool _upb_Decoder_TraceBufferFull(upb_Decoder* d) { + return d->trace_ptr == d->trace_end - 1; +} + +UPB_INLINE bool _upb_Decoder_TraceBufferAlmostFull(upb_Decoder* d) { + return d->trace_ptr == d->trace_end - 2; +} +#endif + +UPB_INLINE char* _upb_Decoder_TraceNext(upb_Decoder* d) { +#ifndef NDEBUG + return _upb_Decoder_TraceBufferAlmostFull(d) ? NULL : d->trace_ptr + 1; +#else + return NULL; +#endif +} + +UPB_INLINE char* _upb_Decoder_TracePtr(upb_Decoder* d) { +#ifndef NDEBUG + return d->trace_ptr; +#else + return NULL; +#endif +} + +// Trace events are used to trace the progress of the decoder. +// Events: +// 'D' Fast dispatch +// 'F' Field successfully parsed fast. +// '<' Fallback to MiniTable parser. +// 'M' Field successfully parsed with MiniTable. +// 'X' Truncated -- trace buffer is full, further events were discarded. +UPB_INLINE void _upb_Decoder_Trace(upb_Decoder* d, char event) { +#ifndef NDEBUG + if (d->trace_ptr == NULL) return; + if (_upb_Decoder_TraceBufferFull(d)) { + d->trace_ptr[-1] = 'X'; // Truncated. + return; + } + d->trace_ptr[0] = event; + d->trace_ptr[1] = '\0'; + d->trace_ptr++; +#endif +}; + +UPB_INLINE +bool _upb_Decoder_VerifyUtf8Inline(const char* ptr, int len) { + return utf8_range_IsValid(ptr, len); +} + +const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* m); + +/* x86-64 pointers always have the high 16 bits matching. So we can shift + * left 8 and right 8 without loss of information. */ +UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { + return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask); +} + +UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { + return (const upb_MiniTable*)(table >> 8); +} + +const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* layout); + +UPB_INLINE bool _upb_Decoder_FieldRequiresUtf8Validation( + const upb_Decoder* d, const upb_MiniTableField* field) { + if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_String) return true; + + if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes && + (field->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) && + (d->options & kUpb_DecodeOption_AlwaysValidateUtf8)) { + return true; + } + + return false; +} + +UPB_INLINE bool _upb_Decoder_ReadString(upb_Decoder* d, const char** ptr, + size_t size, upb_StringView* sv, + bool validate_utf8) { + upb_StringView tmp; + *ptr = + upb_EpsCopyInputStream_ReadStringAlwaysAlias(&d->input, *ptr, size, &tmp); + if (*ptr == NULL) return false; + if (validate_utf8 && !utf8_range_IsValid(tmp.data, tmp.size)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_BadUtf8); + return false; + } + if ((d->options & kUpb_DecodeOption_AliasString) == 0) { + char* data = (char*)upb_Arena_Malloc(&d->arena, tmp.size); + if (!data) return false; + memcpy(data, tmp.data, tmp.size); + tmp.data = data; + } + *sv = tmp; + return true; +} + + +#endif /* UPB_WIRE_INTERNAL_DECODER_H_ */ +#ifndef GOOGLE_UPB_UPB_WIRE_WRITER_H__ +#define GOOGLE_UPB_UPB_WIRE_WRITER_H__ + +#include + +// Must be last. + +UPB_FORCEINLINE uint32_t +UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) { + // Calculate how many bytes of the possible 10 bytes we will *not* encode, + // because they are part of a zero prefix. For the number 300, it would use 2 + // bytes encoded, so the number of bytes to skip would be 8. Adding 7 to the + // clz input ensures that we're rounding up. + return (((uint32_t)clz + 7) * 9) >> 6; +} + + +#endif // GOOGLE_UPB_UPB_WIRE_WRITER_H__ + +// This should #undef all macros #defined in def.inc + +#undef UPB_SIZE +#undef UPB_PTR_AT +#undef UPB_SIZEOF_FLEX +#undef UPB_SIZEOF_FLEX_WOULD_OVERFLOW +#undef UPB_MAPTYPE_STRING +#undef UPB_EXPORT +#undef UPB_INLINE +#undef UPB_API +#undef UPBC_API +#undef UPB_API_INLINE +#undef UPB_API_INLINE_IF_NOT_GCC +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF +#undef UPB_ALIGN_AS +#undef UPB_STATIC_ASSERT +#undef UPB_STATIC_ASSERT_CONCAT +#undef UPB_STATIC_ASSERT_CONCAT_IMPL +#undef UPB_LIKELY +#undef UPB_UNLIKELY +#undef UPB_UNPREDICTABLE +#undef UPB_FORCEINLINE +#undef UPB_NOINLINE +#undef UPB_NORETURN +#undef UPB_PRINTF +#undef UPB_NODEREF +#undef UPB_MAX +#undef UPB_MIN +#undef UPB_UNUSED +#undef UPB_ASSUME +#undef UPB_ASSERT +#undef UPB_UNREACHABLE +#undef UPB_DEFAULT_MAX_BLOCK_SIZE +#undef UPB_SETJMP +#undef UPB_LONGJMP +#undef UPB_PTRADD +#undef UPB_MUSTTAIL +#undef UPB_PRESERVE_MOST +#undef UPB_PRESERVE_NONE +#undef UPB_FASTTABLE_SUPPORTED +#undef UPB_FASTTABLE_MASK +#undef UPB_FASTTABLE +#undef UPB_FASTTABLE_INIT +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN +#undef UPB_HWASAN +#undef UPB_HWASAN_POISON_TAG +#undef UPB_MSAN +#undef UPB_MALLOC_ALIGN +#undef UPB_TSAN +#undef UPB_DEPRECATED +#undef UPB_GNUC_MIN +#undef UPB_DESCRIPTOR_UPB_H_FILENAME +#undef UPB_DESC_MINITABLE +#undef UPB_IS_GOOGLE3 +#undef UPB_ATOMIC +#undef UPB_USE_C11_ATOMICS +#undef UPB_USE_MSC_ATOMICS +#undef UPB_PRIVATE +#undef UPB_ONLYBITS +#undef UPB_LINKARR_DECLARE +#undef UPB_LINKARR_APPEND +#undef UPB_LINKARR_START +#undef UPB_LINKARR_STOP +#undef UPB_FUTURE_BREAKING_CHANGES +#undef UPB_HAS_ATTRIBUTE +#undef UPB_HAS_CPP_ATTRIBUTE +#undef UPB_HAS_BUILTIN +#undef UPB_HAS_EXTENSION +#undef UPB_HAS_FEATURE +#undef UPB_XSAN_MEMBER +#undef UPB_XSAN +#undef UPB_XSAN_STRUCT_SIZE +#undef UPB_ENABLE_REF_CYCLE_CHECKS +#undef UPB_ARM64_ASM +#undef UPB_ARM64_BTI_DEFAULT +#undef UPB_DEPRECATE_AND_INLINE +#undef UPB_MAYBE_ASSUME +#undef UPB_ATTR_CONST diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.c new file mode 100755 index 0000000..dd182bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.c @@ -0,0 +1,69 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby <-> upb data conversion functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#include "shared_convert.h" + +bool shared_Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + upb_CType type, const upb_MessageDef* msgdef, + upb_Status* status) { + switch (type) { + case kUpb_CType_Bool: + return memcmp(&val1, &val2, 1) == 0; + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + return memcmp(&val1, &val2, 4) == 0; + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return memcmp(&val1, &val2, 8) == 0; + case kUpb_CType_String: + case kUpb_CType_Bytes: + return val1.str_val.size == val2.str_val.size && + memcmp(val1.str_val.data, val2.str_val.data, val1.str_val.size) == + 0; + case kUpb_CType_Message: { + const upb_MiniTable* m = upb_MessageDef_MiniTable(msgdef); + const int options = 0; + return upb_Message_IsEqual(val1.msg_val, val2.msg_val, m, options); + } + default: + upb_Status_SetErrorMessage(status, "Internal error, unexpected type"); + return false; + } +} + +uint64_t shared_Msgval_GetHash(upb_MessageValue val, upb_CType type, + const upb_MessageDef* msgdef, uint64_t seed, + upb_Status* status) { + switch (type) { + case kUpb_CType_Bool: + return _upb_Hash(&val, 1, seed); + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + return _upb_Hash(&val, 4, seed); + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return _upb_Hash(&val, 8, seed); + case kUpb_CType_String: + case kUpb_CType_Bytes: + return _upb_Hash(val.str_val.data, val.str_val.size, seed); + case kUpb_CType_Message: + return shared_Message_Hash(val.msg_val, msgdef, seed, status); + default: + upb_Status_SetErrorMessage(status, "Internal error, unexpected type"); + return 0; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.h new file mode 100755 index 0000000..ca1e91d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.h @@ -0,0 +1,26 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby <-> upb data conversion functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#ifndef RUBY_PROTOBUF_SHARED_CONVERT_H_ +#define RUBY_PROTOBUF_SHARED_CONVERT_H_ + +#include "ruby-upb.h" +#include "shared_message.h" + +bool shared_Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + upb_CType type, const upb_MessageDef* msgdef, + upb_Status* status); + +uint64_t shared_Msgval_GetHash(upb_MessageValue val, upb_CType type, + const upb_MessageDef* msgdef, uint64_t seed, + upb_Status* status); + +#endif // RUBY_PROTOBUF_SHARED_CONVERT_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.c new file mode 100755 index 0000000..122682e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.c @@ -0,0 +1,37 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby Message functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#include "shared_message.h" + +// Support function for Message_Hash. Returns a hash value for the given +// message. +uint64_t shared_Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed, upb_Status* status) { + upb_Arena* arena = upb_Arena_New(); + char* data; + size_t size; + + // Hash a deterministically serialized payloads with no unknown fields. + upb_EncodeStatus encode_status = upb_Encode( + msg, upb_MessageDef_MiniTable(m), + kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_Deterministic, arena, + &data, &size); + + if (encode_status == kUpb_EncodeStatus_Ok) { + uint64_t ret = _upb_Hash(data, size, seed); + upb_Arena_Free(arena); + return ret; + } + + upb_Arena_Free(arena); + upb_Status_SetErrorMessage(status, "Error calculating hash"); + return 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.h new file mode 100755 index 0000000..5072208 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.h @@ -0,0 +1,21 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby Message functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#ifndef RUBY_PROTOBUF_SHARED_MESSAGE_H_ +#define RUBY_PROTOBUF_SHARED_MESSAGE_H_ + +#include "ruby-upb.h" + +// Returns a hash value for the given message. +uint64_t shared_Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed, upb_Status* status); + +#endif // RUBY_PROTOBUF_SHARED_MESSAGE_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/LICENSE b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/LICENSE new file mode 100755 index 0000000..e59f14f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2019 Yibo Cai +Copyright 2022 Google LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c new file mode 100755 index 0000000..f3301cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c @@ -0,0 +1,207 @@ +// Copyright 2023 Google LLC +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + +/* This is a wrapper for the Google range-sse.cc algorithm which checks whether + * a sequence of bytes is a valid UTF-8 sequence and finds the longest valid + * prefix of the UTF-8 sequence. + * + * The key difference is that it checks for as much ASCII symbols as possible + * and then falls back to the range-sse.cc algorithm. The changes to the + * algorithm are cosmetic, mostly to trick the clang compiler to produce optimal + * code. + * + * For API see the utf8_validity.h header. + */ +#include "utf8_range.h" + +#include +#include +#include + +#if defined(__GNUC__) +#define FORCE_INLINE_ATTR __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +#define FORCE_INLINE_ATTR __forceinline +#else +#define FORCE_INLINE_ATTR inline +#endif + +static FORCE_INLINE_ATTR uint64_t utf8_range_UnalignedLoad64( + const void* p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +static FORCE_INLINE_ATTR int utf8_range_AsciiIsAscii(unsigned char c) { + return c < 128; +} + +static FORCE_INLINE_ATTR int utf8_range_IsTrailByteOk(const char c) { + return (int8_t)(c) <= (int8_t)(0xBF); +} + +/* If return_position is false then it returns 1 if |data| is a valid utf8 + * sequence, otherwise returns 0. + * If return_position is set to true, returns the length in bytes of the prefix + of |data| that is all structurally valid UTF-8. + */ +static size_t utf8_range_ValidateUTF8Naive(const char* data, const char* end, + int return_position) { + /* We return err_pos in the loop which is always 0 if !return_position */ + size_t err_pos = 0; + size_t codepoint_bytes = 0; + /* The early check is done because of early continue's on codepoints of all + * sizes, i.e. we first check for ascii and if it is, we call continue, then + * for 2 byte codepoints, etc. This is done in order to reduce indentation and + * improve readability of the codepoint validity check. + */ + while (data + codepoint_bytes < end) { + if (return_position) { + err_pos += codepoint_bytes; + } + data += codepoint_bytes; + const size_t len = end - data; + const unsigned char byte1 = data[0]; + + /* We do not skip many ascii bytes at the same time as this function is + used for tail checking (< 16 bytes) and for non x86 platforms. We also + don't think that cases where non-ASCII codepoints are followed by ascii + happen often. For small strings it also introduces some penalty. For + purely ascii UTF8 strings (which is the overwhelming case) we call + SkipAscii function which is multiplatform and extremely fast. + */ + /* [00..7F] ASCII -> 1 byte */ + if (utf8_range_AsciiIsAscii(byte1)) { + codepoint_bytes = 1; + continue; + } + /* [C2..DF], [80..BF] -> 2 bytes */ + if (len >= 2 && byte1 >= 0xC2 && byte1 <= 0xDF && + utf8_range_IsTrailByteOk(data[1])) { + codepoint_bytes = 2; + continue; + } + if (len >= 3) { + const unsigned char byte2 = data[1]; + const unsigned char byte3 = data[2]; + + /* Is byte2, byte3 between [0x80, 0xBF] + * Check for 0x80 was done above. + */ + if (!utf8_range_IsTrailByteOk(byte2) || + !utf8_range_IsTrailByteOk(byte3)) { + return err_pos; + } + + if (/* E0, A0..BF, 80..BF */ + ((byte1 == 0xE0 && byte2 >= 0xA0) || + /* E1..EC, 80..BF, 80..BF */ + (byte1 >= 0xE1 && byte1 <= 0xEC) || + /* ED, 80..9F, 80..BF */ + (byte1 == 0xED && byte2 <= 0x9F) || + /* EE..EF, 80..BF, 80..BF */ + (byte1 >= 0xEE && byte1 <= 0xEF))) { + codepoint_bytes = 3; + continue; + } + if (len >= 4) { + const unsigned char byte4 = data[3]; + /* Is byte4 between 0x80 ~ 0xBF */ + if (!utf8_range_IsTrailByteOk(byte4)) { + return err_pos; + } + + if (/* F0, 90..BF, 80..BF, 80..BF */ + ((byte1 == 0xF0 && byte2 >= 0x90) || + /* F1..F3, 80..BF, 80..BF, 80..BF */ + (byte1 >= 0xF1 && byte1 <= 0xF3) || + /* F4, 80..8F, 80..BF, 80..BF */ + (byte1 == 0xF4 && byte2 <= 0x8F))) { + codepoint_bytes = 4; + continue; + } + } + } + return err_pos; + } + if (return_position) { + err_pos += codepoint_bytes; + } + /* if return_position is false, this returns 1. + * if return_position is true, this returns err_pos. + */ + return err_pos + (1 - return_position); +} + +#if defined(__SSE4_1__) || (defined(__ARM_NEON) && defined(__ARM_64BIT_STATE)) +/* Returns the number of bytes needed to skip backwards to get to the first + byte of codepoint. + */ +static inline int utf8_range_CodepointSkipBackwards(int32_t codepoint_word) { + const int8_t* const codepoint = (const int8_t*)(&codepoint_word); + if (!utf8_range_IsTrailByteOk(codepoint[3])) { + return 1; + } else if (!utf8_range_IsTrailByteOk(codepoint[2])) { + return 2; + } else if (!utf8_range_IsTrailByteOk(codepoint[1])) { + return 3; + } + return 0; +} +#endif // __SSE4_1__ + +/* Skipping over ASCII as much as possible, per 8 bytes. It is intentional + as most strings to check for validity consist only of 1 byte codepoints. + */ +static inline const char* utf8_range_SkipAscii(const char* data, + const char* end) { + while (8 <= end - data && + (utf8_range_UnalignedLoad64(data) & 0x8080808080808080) == 0) { + data += 8; + } + while (data < end && utf8_range_AsciiIsAscii(*data)) { + ++data; + } + return data; +} + +#if defined(__SSE4_1__) +#include "utf8_range_sse.inc" +#elif defined(__ARM_NEON) && defined(__ARM_64BIT_STATE) +#include "utf8_range_neon.inc" +#endif + +static FORCE_INLINE_ATTR size_t utf8_range_Validate( + const char* data, size_t len, int return_position) { + if (len == 0) return 1 - return_position; + // Save buffer start address for later use + const char* const data_original = data; + const char* const end = data + len; + data = utf8_range_SkipAscii(data, end); + /* SIMD algorithm always outperforms the naive version for any data of + length >=16. + */ + if (end - data < 16) { + return (return_position ? (data - data_original) : 0) + + utf8_range_ValidateUTF8Naive(data, end, return_position); + } +#if defined(__SSE4_1__) || (defined(__ARM_NEON) && defined(__ARM_64BIT_STATE)) + return utf8_range_ValidateUTF8Simd( + data_original, data, end, return_position); +#else + return (return_position ? (data - data_original) : 0) + + utf8_range_ValidateUTF8Naive(data, end, return_position); +#endif +} + +bool utf8_range_IsValid(const char* data, size_t len) { + return utf8_range_Validate(data, len, /*return_position=*/0) != 0; +} + +size_t utf8_range_ValidPrefix(const char* data, size_t len) { + return utf8_range_Validate(data, len, /*return_position=*/1); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h new file mode 100755 index 0000000..5942d80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h @@ -0,0 +1,23 @@ +#ifndef THIRD_PARTY_UTF8_RANGE_UTF8_RANGE_H_ +#define THIRD_PARTY_UTF8_RANGE_UTF8_RANGE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns 1 if the sequence of characters is a valid UTF-8 sequence, otherwise +// 0. +bool utf8_range_IsValid(const char* data, size_t len); + +// Returns the length in bytes of the prefix of str that is all +// structurally valid UTF-8. +size_t utf8_range_ValidPrefix(const char* data, size_t len); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // THIRD_PARTY_UTF8_RANGE_UTF8_RANGE_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc new file mode 100755 index 0000000..ab73754 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc @@ -0,0 +1,117 @@ +#include + +/* This code is almost the same as SSE implementation, please reference + * utf8-range-sse.inc for detailed explanation. + * The only difference is the range adjustment step. NEON code is more + * straightforward. + */ + +static FORCE_INLINE_ATTR size_t utf8_range_ValidateUTF8Simd( + const char* data_original, const char* data, const char* end, + int return_position) { + const uint8x16_t first_len_tbl = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, + }; + const uint8x16_t first_range_tbl = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, + }; + const uint8x16_t range_min_tbl = { + 0x00, 0x80, 0x80, 0x80, 0xA0, 0x80, 0x90, 0x80, + 0xC2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + const uint8x16_t range_max_tbl = { + 0x7F, 0xBF, 0xBF, 0xBF, 0xBF, 0x9F, 0xBF, 0x8F, + 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + /* Range adjustment in NEON uint8x16x2 table. Note that lanes are interleaved + * in register. The table below is plotted vertically to ease understanding. + * The 1st column is for E0~EF, 2nd column for F0~FF. + */ + // clang-format off + const uint8_t range_adjust_tbl_data[] = { + /* index -> 0~15 16~31 <- index */ + /* E0 -> */ 2, 3, /* <- F0 */ + 0, 0, + 0, 0, + 0, 0, + 0, 4, /* <- F4 */ + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + /* ED -> */ 3, 0, + 0, 0, + 0, 0, + }; + // clang-format on + const uint8x16x2_t range_adjust_tbl = vld2q_u8(range_adjust_tbl_data); + + const uint8x16_t const_1 = vdupq_n_u8(1); + const uint8x16_t const_2 = vdupq_n_u8(2); + const uint8x16_t const_e0 = vdupq_n_u8(0xE0); + + uint8x16_t prev_input = vdupq_n_u8(0); + uint8x16_t prev_first_len = vdupq_n_u8(0); + uint8x16_t error = vdupq_n_u8(0); + + while (end - data >= 16) { + const uint8x16_t input = vld1q_u8((const uint8_t*)data); + + const uint8x16_t high_nibbles = vshrq_n_u8(input, 4); + + const uint8x16_t first_len = vqtbl1q_u8(first_len_tbl, high_nibbles); + + uint8x16_t range = vqtbl1q_u8(first_range_tbl, high_nibbles); + + range = vorrq_u8(range, vextq_u8(prev_first_len, first_len, 15)); + + uint8x16_t shift2 = vextq_u8(prev_first_len, first_len, 14); + shift2 = vqsubq_u8(shift2, const_1); + range = vorrq_u8(range, shift2); + + uint8x16_t shift3 = vextq_u8(prev_first_len, first_len, 13); + shift3 = vqsubq_u8(shift3, const_2); + range = vorrq_u8(range, shift3); + + uint8x16_t shift1 = vextq_u8(prev_input, input, 15); + shift1 = vsubq_u8(shift1, const_e0); + range = vaddq_u8(range, vqtbl2q_u8(range_adjust_tbl, shift1)); + + const uint8x16_t min_range = vqtbl1q_u8(range_min_tbl, range); + const uint8x16_t max_range = vqtbl1q_u8(range_max_tbl, range); + + if (return_position) { + error = vcltq_u8(input, min_range); + error = vorrq_u8(error, vcgtq_u8(input, max_range)); + if (vmaxvq_u32(vreinterpretq_u32_u8(error))) { + break; + } + } else { + error = vorrq_u8(error, vcltq_u8(input, min_range)); + error = vorrq_u8(error, vcgtq_u8(input, max_range)); + } + + prev_input = input; + prev_first_len = first_len; + + data += 16; + } + + if (return_position && data == data_original) { + return utf8_range_ValidateUTF8Naive(data, end, return_position); + } + const int32_t prev = vgetq_lane_s32(vreinterpretq_s32_u8(prev_input), 3); + data -= utf8_range_CodepointSkipBackwards(prev); + if (return_position) { + return (data - data_original) + + utf8_range_ValidateUTF8Naive(data, end, return_position); + } + if (vmaxvq_u32(vreinterpretq_u32_u8(error))) { + return 0; + } + return utf8_range_ValidateUTF8Naive(data, end, return_position); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc new file mode 100755 index 0000000..c93fa96 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc @@ -0,0 +1,272 @@ +#include +#include +#include + +static FORCE_INLINE_ATTR size_t utf8_range_ValidateUTF8Simd( + const char* data_original, const char* data, const char* end, + int return_position) { + /* This code checks that utf-8 ranges are structurally valid 16 bytes at once + * using superscalar instructions. + * The mapping between ranges of codepoint and their corresponding utf-8 + * sequences is below. + */ + + /* + * U+0000...U+007F 00...7F + * U+0080...U+07FF C2...DF 80...BF + * U+0800...U+0FFF E0 A0...BF 80...BF + * U+1000...U+CFFF E1...EC 80...BF 80...BF + * U+D000...U+D7FF ED 80...9F 80...BF + * U+E000...U+FFFF EE...EF 80...BF 80...BF + * U+10000...U+3FFFF F0 90...BF 80...BF 80...BF + * U+40000...U+FFFFF F1...F3 80...BF 80...BF 80...BF + * U+100000...U+10FFFF F4 80...8F 80...BF 80...BF + */ + + /* First we compute the type for each byte, as given by the table below. + * This type will be used as an index later on. + */ + + /* + * Index Min Max Byte Type + * 0 00 7F Single byte sequence + * 1,2,3 80 BF Second, third and fourth byte for many of the sequences. + * 4 A0 BF Second byte after E0 + * 5 80 9F Second byte after ED + * 6 90 BF Second byte after F0 + * 7 80 8F Second byte after F4 + * 8 C2 F4 First non ASCII byte + * 9..15 7F 80 Invalid byte + */ + + /* After the first step we compute the index for all bytes, then we permute + the bytes according to their indices to check the ranges from the range + table. + * The range for a given type can be found in the range_min_table and + range_max_table, the range for type/index X is in range_min_table[X] ... + range_max_table[X]. + */ + + /* Algorithm: + * Put index zero to all bytes. + * Find all non ASCII characters, give them index 8. + * For each tail byte in a codepoint sequence, give it an index corresponding + to the 1 based index from the end. + * If the first byte of the codepoint is in the [C0...DF] range, we write + index 1 in the following byte. + * If the first byte of the codepoint is in the range [E0...EF], we write + indices 2 and 1 in the next two bytes. + * If the first byte of the codepoint is in the range [F0...FF] we write + indices 3,2,1 into the next three bytes. + * For finding the number of bytes we need to look at high nibbles (4 bits) + and do the lookup from the table, it can be done with shift by 4 + shuffle + instructions. We call it `first_len`. + * Then we shift first_len by 8 bits to get the indices of the 2nd bytes. + * Saturating sub 1 and shift by 8 bits to get the indices of the 3rd bytes. + * Again to get the indices of the 4th bytes. + * Take OR of all that 4 values and check within range. + */ + /* For example: + * input C3 80 68 E2 80 20 A6 F0 A0 80 AC 20 F0 93 80 80 + * first_len 1 0 0 2 0 0 0 3 0 0 0 0 3 0 0 0 + * 1st byte 8 0 0 8 0 0 0 8 0 0 0 0 8 0 0 0 + * 2nd byte 0 1 0 0 2 0 0 0 3 0 0 0 0 3 0 0 // Shift + sub + * 3rd byte 0 0 0 0 0 1 0 0 0 2 0 0 0 0 2 0 // Shift + sub + * 4th byte 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 // Shift + sub + * Index 8 1 0 8 2 1 0 8 3 2 1 0 8 3 2 1 // OR of results + */ + + /* Checking for errors: + * Error checking is done by looking up the high nibble (4 bits) of each byte + against an error checking table. + * Because the lookup value for the second byte depends of the value of the + first byte in codepoint, we use saturated operations to adjust the index. + * Specifically we need to add 2 for E0, 3 for ED, 3 for F0 and 4 for F4 to + match the correct index. + * If we subtract from all bytes EF then EO -> 241, ED -> 254, F0 -> 1, + F4 -> 5 + * Do saturating sub 240, then E0 -> 1, ED -> 14 and we can do lookup to + match the adjustment + * Add saturating 112, then F0 -> 113, F4 -> 117, all that were > 16 will + be more 128 and lookup in ef_fe_table will return 0 but for F0 + and F4 it will be 4 and 5 accordingly + */ + /* + * Then just check the appropriate ranges with greater/smaller equal + instructions. Check tail with a naive algorithm. + * To save from previous 16 byte checks we just align previous_first_len to + get correct continuations of the codepoints. + */ + + /* + * Map high nibble of "First Byte" to legal character length minus 1 + * 0x00 ~ 0xBF --> 0 + * 0xC0 ~ 0xDF --> 1 + * 0xE0 ~ 0xEF --> 2 + * 0xF0 ~ 0xFF --> 3 + */ + const __m128i first_len_table = + _mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3); + + /* Map "First Byte" to 8-th item of range table (0xC2 ~ 0xF4) */ + const __m128i first_range_table = + _mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8); + + /* + * Range table, map range index to min and max values + */ + const __m128i range_min_table = + _mm_setr_epi8(0x00, 0x80, 0x80, 0x80, 0xA0, 0x80, 0x90, 0x80, 0xC2, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F); + + const __m128i range_max_table = + _mm_setr_epi8(0x7F, 0xBF, 0xBF, 0xBF, 0xBF, 0x9F, 0xBF, 0x8F, 0xF4, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80); + + /* + * Tables for fast handling of four special First Bytes(E0,ED,F0,F4), after + * which the Second Byte are not 80~BF. It contains "range index adjustment". + * +------------+---------------+------------------+----------------+ + * | First Byte | original range| range adjustment | adjusted range | + * +------------+---------------+------------------+----------------+ + * | E0 | 2 | 2 | 4 | + * +------------+---------------+------------------+----------------+ + * | ED | 2 | 3 | 5 | + * +------------+---------------+------------------+----------------+ + * | F0 | 3 | 3 | 6 | + * +------------+---------------+------------------+----------------+ + * | F4 | 4 | 4 | 8 | + * +------------+---------------+------------------+----------------+ + */ + + /* df_ee_table[1] -> E0, df_ee_table[14] -> ED as ED - E0 = 13 */ + // The values represent the adjustment in the Range Index table for a correct + // index. + const __m128i df_ee_table = + _mm_setr_epi8(0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0); + + /* ef_fe_table[1] -> F0, ef_fe_table[5] -> F4, F4 - F0 = 4 */ + // The values represent the adjustment in the Range Index table for a correct + // index. + const __m128i ef_fe_table = + _mm_setr_epi8(0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + __m128i prev_input = _mm_set1_epi8(0); + __m128i prev_first_len = _mm_set1_epi8(0); + __m128i error = _mm_set1_epi8(0); + + while (end - data >= 16) { + const __m128i input = _mm_loadu_si128((const __m128i*)(data)); + + /* high_nibbles = input >> 4 */ + const __m128i high_nibbles = + _mm_and_si128(_mm_srli_epi16(input, 4), _mm_set1_epi8(0x0F)); + + /* first_len = legal character length minus 1 */ + /* 0 for 00~7F, 1 for C0~DF, 2 for E0~EF, 3 for F0~FF */ + /* first_len = first_len_table[high_nibbles] */ + __m128i first_len = _mm_shuffle_epi8(first_len_table, high_nibbles); + + /* First Byte: set range index to 8 for bytes within 0xC0 ~ 0xFF */ + /* range = first_range_table[high_nibbles] */ + __m128i range = _mm_shuffle_epi8(first_range_table, high_nibbles); + + /* Second Byte: set range index to first_len */ + /* 0 for 00~7F, 1 for C0~DF, 2 for E0~EF, 3 for F0~FF */ + /* range |= (first_len, prev_first_len) << 1 byte */ + range = _mm_or_si128(range, _mm_alignr_epi8(first_len, prev_first_len, 15)); + + /* Third Byte: set range index to saturate_sub(first_len, 1) */ + /* 0 for 00~7F, 0 for C0~DF, 1 for E0~EF, 2 for F0~FF */ + __m128i tmp1; + __m128i tmp2; + /* tmp1 = saturate_sub(first_len, 1) */ + tmp1 = _mm_subs_epu8(first_len, _mm_set1_epi8(1)); + /* tmp2 = saturate_sub(prev_first_len, 1) */ + tmp2 = _mm_subs_epu8(prev_first_len, _mm_set1_epi8(1)); + /* range |= (tmp1, tmp2) << 2 bytes */ + range = _mm_or_si128(range, _mm_alignr_epi8(tmp1, tmp2, 14)); + + /* Fourth Byte: set range index to saturate_sub(first_len, 2) */ + /* 0 for 00~7F, 0 for C0~DF, 0 for E0~EF, 1 for F0~FF */ + /* tmp1 = saturate_sub(first_len, 2) */ + tmp1 = _mm_subs_epu8(first_len, _mm_set1_epi8(2)); + /* tmp2 = saturate_sub(prev_first_len, 2) */ + tmp2 = _mm_subs_epu8(prev_first_len, _mm_set1_epi8(2)); + /* range |= (tmp1, tmp2) << 3 bytes */ + range = _mm_or_si128(range, _mm_alignr_epi8(tmp1, tmp2, 13)); + + /* + * Now we have below range indices calculated + * Correct cases: + * - 8 for C0~FF + * - 3 for 1st byte after F0~FF + * - 2 for 1st byte after E0~EF or 2nd byte after F0~FF + * - 1 for 1st byte after C0~DF or 2nd byte after E0~EF or + * 3rd byte after F0~FF + * - 0 for others + * Error cases: + * >9 for non ascii First Byte overlapping + * E.g., F1 80 C2 90 --> 8 3 10 2, where 10 indicates error + */ + + /* Adjust Second Byte range for special First Bytes(E0,ED,F0,F4) */ + /* Overlaps lead to index 9~15, which are illegal in range table */ + __m128i shift1; + __m128i pos; + __m128i range2; + /* shift1 = (input, prev_input) << 1 byte */ + shift1 = _mm_alignr_epi8(input, prev_input, 15); + pos = _mm_sub_epi8(shift1, _mm_set1_epi8(0xEF)); + /* + * shift1: | EF F0 ... FE | FF 00 ... ... DE | DF E0 ... EE | + * pos: | 0 1 15 | 16 17 239| 240 241 255| + * pos-240: | 0 0 0 | 0 0 0 | 0 1 15 | + * pos+112: | 112 113 127| >= 128 | >= 128 | + */ + tmp1 = _mm_subs_epu8(pos, _mm_set1_epi8(-16)); + range2 = _mm_shuffle_epi8(df_ee_table, tmp1); + tmp2 = _mm_adds_epu8(pos, _mm_set1_epi8(112)); + range2 = _mm_add_epi8(range2, _mm_shuffle_epi8(ef_fe_table, tmp2)); + + range = _mm_add_epi8(range, range2); + + /* Load min and max values per calculated range index */ + __m128i min_range = _mm_shuffle_epi8(range_min_table, range); + __m128i max_range = _mm_shuffle_epi8(range_max_table, range); + + /* Check value range */ + if (return_position) { + error = _mm_cmplt_epi8(input, min_range); + error = _mm_or_si128(error, _mm_cmpgt_epi8(input, max_range)); + /* 5% performance drop from this conditional branch */ + if (!_mm_testz_si128(error, error)) { + break; + } + } else { + error = _mm_or_si128(error, _mm_cmplt_epi8(input, min_range)); + error = _mm_or_si128(error, _mm_cmpgt_epi8(input, max_range)); + } + + prev_input = input; + prev_first_len = first_len; + + data += 16; + } + /* If we got to the end, we don't need to skip any bytes backwards */ + if (return_position && data == data_original) { + return utf8_range_ValidateUTF8Naive(data, end, return_position); + } + /* Find previous codepoint (not 80~BF) */ + data -= utf8_range_CodepointSkipBackwards(_mm_extract_epi32(prev_input, 3)); + if (return_position) { + return (data - data_original) + + utf8_range_ValidateUTF8Naive(data, end, return_position); + } + /* Test if there was any error */ + if (!_mm_testz_si128(error, error)) { + return 0; + } + /* Check the tail */ + return utf8_range_ValidateUTF8Naive(data, end, return_position); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.1/protobuf_c.bundle b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.1/protobuf_c.bundle new file mode 100755 index 0000000..6d66cff Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.1/protobuf_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.2/protobuf_c.bundle b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.2/protobuf_c.bundle new file mode 100755 index 0000000..81660e9 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.2/protobuf_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.3/protobuf_c.bundle b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.3/protobuf_c.bundle new file mode 100755 index 0000000..0901428 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.3/protobuf_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.4/protobuf_c.bundle b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.4/protobuf_c.bundle new file mode 100755 index 0000000..2ca8c1a Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/3.4/protobuf_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/4.0/protobuf_c.bundle b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/4.0/protobuf_c.bundle new file mode 100755 index 0000000..137177d Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/4.0/protobuf_c.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf.rb new file mode 100755 index 0000000..fdfa9b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf.rb @@ -0,0 +1,61 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +# require mixins before we hook them into the java & c code +require 'google/protobuf/message_exts' +require 'google/protobuf/internal/object_cache' + +# We define these before requiring the platform-specific modules. +# That way the module init can grab references to these. +module Google + module Protobuf + class Error < StandardError; end + class ParseError < Error; end + class TypeError < ::TypeError; end + + PREFER_FFI = case ENV['PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION'] + when nil, "", /^native$/i + false + when /^ffi$/i + true + else + warn "Unexpected value `#{ENV['PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION']}` for environment variable `PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION`. Should be either \"FFI\", \"NATIVE\"." + false + end + + def self.encode(msg, options = {}) + msg.to_proto(options) + end + + def self.encode_json(msg, options = {}) + msg.to_json(options) + end + + def self.decode(klass, proto, options = {}) + klass.decode(proto, options) + end + + def self.decode_json(klass, json, options = {}) + klass.decode_json(json, options) + end + + IMPLEMENTATION = if PREFER_FFI + begin + require 'google/protobuf_ffi' + :FFI + rescue LoadError + warn "Caught exception `#{$!.message}` while loading FFI implementation of google/protobuf." + warn "Falling back to native implementation." + require 'google/protobuf_native' + :NATIVE + end + else + require 'google/protobuf_native' + :NATIVE + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/any_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/any_pb.rb new file mode 100755 index 0000000..c53e405 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/any_pb.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/any.proto + +require 'google/protobuf' + + +descriptor_data = "\n\x19google/protobuf/any.proto\x12\x0fgoogle.protobuf\"&\n\x03\x41ny\x12\x10\n\x08type_url\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x42v\n\x13\x63om.google.protobufB\x08\x41nyProtoP\x01Z,google.golang.org/protobuf/types/known/anypb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + Any = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Any").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/api_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/api_pb.rb new file mode 100755 index 0000000..e786a8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/api_pb.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/api.proto + +require 'google/protobuf' + +require 'google/protobuf/source_context_pb' +require 'google/protobuf/type_pb' + + +descriptor_data = "\n\x19google/protobuf/api.proto\x12\x0fgoogle.protobuf\x1a$google/protobuf/source_context.proto\x1a\x1agoogle/protobuf/type.proto\"\x92\x02\n\x03\x41pi\x12\x0c\n\x04name\x18\x01 \x01(\t\x12(\n\x07methods\x18\x02 \x03(\x0b\x32\x17.google.protobuf.Method\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12&\n\x06mixins\x18\x06 \x03(\x0b\x32\x16.google.protobuf.Mixin\x12\'\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.Syntax\x12\x0f\n\x07\x65\x64ition\x18\x08 \x01(\t\"\xee\x01\n\x06Method\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10request_type_url\x18\x02 \x01(\t\x12\x19\n\x11request_streaming\x18\x03 \x01(\x08\x12\x19\n\x11response_type_url\x18\x04 \x01(\t\x12\x1a\n\x12response_streaming\x18\x05 \x01(\x08\x12(\n\x07options\x18\x06 \x03(\x0b\x32\x17.google.protobuf.Option\x12+\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.SyntaxB\x02\x18\x01\x12\x13\n\x07\x65\x64ition\x18\x08 \x01(\tB\x02\x18\x01\"#\n\x05Mixin\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04root\x18\x02 \x01(\tBv\n\x13\x63om.google.protobufB\x08\x41piProtoP\x01Z,google.golang.org/protobuf/types/known/apipb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + Api = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Api").msgclass + Method = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Method").msgclass + Mixin = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Mixin").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/descriptor_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/descriptor_pb.rb new file mode 100755 index 0000000..4142ff7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/descriptor_pb.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/descriptor.proto + +require 'google/protobuf' + + +descriptor_data = "\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"U\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xa1\x04\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x19\n\x11option_dependency\x18\x0f \x03(\t\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\x12)\n\x07\x65\x64ition\x18\x0e \x01(\x0e\x32\x18.google.protobuf.Edition\"\xe0\x05\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProto\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x12\x35\n\nvisibility\x18\x0b \x01(\x0e\x32!.google.protobuf.SymbolVisibility\x1a\x65\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\x12\x37\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptions\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"\xed\x03\n\x15\x45xtensionRangeOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\x12L\n\x0b\x64\x65\x63laration\x18\x02 \x03(\x0b\x32\x32.google.protobuf.ExtensionRangeOptions.DeclarationB\x03\x88\x01\x02\x12-\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12_\n\x0cverification\x18\x03 \x01(\x0e\x32\x38.google.protobuf.ExtensionRangeOptions.VerificationState:\nUNVERIFIEDB\x03\x88\x01\x02\x1ah\n\x0b\x44\x65\x63laration\x12\x0e\n\x06number\x18\x01 \x01(\x05\x12\x11\n\tfull_name\x18\x02 \x01(\t\x12\x0c\n\x04type\x18\x03 \x01(\t\x12\x10\n\x08reserved\x18\x05 \x01(\x08\x12\x10\n\x08repeated\x18\x06 \x01(\x08J\x04\x08\x04\x10\x05\"4\n\x11VerificationState\x12\x0f\n\x0b\x44\x45\x43LARATION\x10\x00\x12\x0e\n\nUNVERIFIED\x10\x01*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd5\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12\x11\n\tjson_name\x18\n \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\x12\x17\n\x0fproto3_optional\x18\x11 \x01(\x08\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REPEATED\x10\x03\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptions\"\xdb\x02\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\x12N\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRange\x12\x15\n\rreserved_name\x18\x05 \x03(\t\x12\x35\n\nvisibility\x18\x06 \x01(\x0e\x32!.google.protobuf.SymbolVisibility\x1a/\n\x11\x45numReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x9e\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptionsJ\x04\x08\x04\x10\x05R\x06stream\"\xc1\x01\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\x12\x1f\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lse\"\x98\x08\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\xe6\x01\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lseB\xc1\x01\xb2\x01\xbd\x01\x08\xe6\x07 \xe9\x07*\xb4\x01This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.\x12)\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04true\x12\x19\n\x11objc_class_prefix\x18$ \x01(\t\x12\x18\n\x10\x63sharp_namespace\x18% \x01(\t\x12\x14\n\x0cswift_prefix\x18\' \x01(\t\x12\x18\n\x10php_class_prefix\x18( \x01(\t\x12\x15\n\rphp_namespace\x18) \x01(\t\x12\x1e\n\x16php_metadata_namespace\x18, \x01(\t\x12\x14\n\x0cruby_package\x18- \x01(\t\x12-\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08*\x10+J\x04\x08&\x10\'R\x14php_generic_services\"\xef\x02\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12\x32\n&deprecated_legacy_json_field_conflicts\x18\x0b \x01(\x08\x42\x02\x18\x01\x12-\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xc6\x0b\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12?\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x17\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lseB\x02\x18\x01\x12\x1b\n\x0c\x64\x65\x62ug_redact\x18\x10 \x01(\x08:\x05\x66\x61lse\x12@\n\tretention\x18\x11 \x01(\x0e\x32-.google.protobuf.FieldOptions.OptionRetention\x12?\n\x07targets\x18\x13 \x03(\x0e\x32..google.protobuf.FieldOptions.OptionTargetType\x12\x46\n\x10\x65\x64ition_defaults\x18\x14 \x03(\x0b\x32,.google.protobuf.FieldOptions.EditionDefault\x12-\n\x08\x66\x65\x61tures\x18\x15 \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x45\n\x0f\x66\x65\x61ture_support\x18\x16 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupport\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\x1aJ\n\x0e\x45\x64itionDefault\x12)\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.Edition\x12\r\n\x05value\x18\x02 \x01(\t\x1a\xe3\x01\n\x0e\x46\x65\x61tureSupport\x12\x34\n\x12\x65\x64ition_introduced\x18\x01 \x01(\x0e\x32\x18.google.protobuf.Edition\x12\x34\n\x12\x65\x64ition_deprecated\x18\x02 \x01(\x0e\x32\x18.google.protobuf.Edition\x12\x1b\n\x13\x64\x65precation_warning\x18\x03 \x01(\t\x12\x31\n\x0f\x65\x64ition_removed\x18\x04 \x01(\x0e\x32\x18.google.protobuf.Edition\x12\x15\n\rremoval_error\x18\x05 \x01(\t\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02\"U\n\x0fOptionRetention\x12\x15\n\x11RETENTION_UNKNOWN\x10\x00\x12\x15\n\x11RETENTION_RUNTIME\x10\x01\x12\x14\n\x10RETENTION_SOURCE\x10\x02\"\x8c\x02\n\x10OptionTargetType\x12\x17\n\x13TARGET_TYPE_UNKNOWN\x10\x00\x12\x14\n\x10TARGET_TYPE_FILE\x10\x01\x12\x1f\n\x1bTARGET_TYPE_EXTENSION_RANGE\x10\x02\x12\x17\n\x13TARGET_TYPE_MESSAGE\x10\x03\x12\x15\n\x11TARGET_TYPE_FIELD\x10\x04\x12\x15\n\x11TARGET_TYPE_ONEOF\x10\x05\x12\x14\n\x10TARGET_TYPE_ENUM\x10\x06\x12\x1a\n\x16TARGET_TYPE_ENUM_ENTRY\x10\x07\x12\x17\n\x13TARGET_TYPE_SERVICE\x10\x08\x12\x16\n\x12TARGET_TYPE_METHOD\x10\t*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x12\x10\x13\"\x95\x01\n\x0cOneofOptions\x12-\n\x08\x66\x65\x61tures\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xfe\x01\n\x0b\x45numOptions\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x32\n&deprecated_legacy_json_field_conflicts\x18\x06 \x01(\x08\x42\x02\x18\x01\x12-\n\x08\x66\x65\x61tures\x18\x07 \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"\x98\x02\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12-\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x1b\n\x0c\x64\x65\x62ug_redact\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x45\n\x0f\x66\x65\x61ture_support\x18\x04 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupport\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xb2\x01\n\x0eServiceOptions\x12-\n\x08\x66\x65\x61tures\x18\" \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xe4\x02\n\rMethodOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12_\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWN\x12-\n\x08\x66\x65\x61tures\x18# \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xa3\x0e\n\nFeatureSet\x12\x82\x01\n\x0e\x66ield_presence\x18\x01 \x01(\x0e\x32).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPLICIT\x18\x84\x07\xa2\x01\r\x12\x08IMPLICIT\x18\xe7\x07\xa2\x01\r\x12\x08\x45XPLICIT\x18\xe8\x07\xb2\x01\x03\x08\xe8\x07\x12\x62\n\tenum_type\x18\x02 \x01(\x0e\x32$.google.protobuf.FeatureSet.EnumTypeB)\x88\x01\x01\x98\x01\x06\x98\x01\x01\xa2\x01\x0b\x12\x06\x43LOSED\x18\x84\x07\xa2\x01\t\x12\x04OPEN\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07\x12\x81\x01\n\x17repeated_field_encoding\x18\x03 \x01(\x0e\x32\x31.google.protobuf.FeatureSet.RepeatedFieldEncodingB-\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPANDED\x18\x84\x07\xa2\x01\x0b\x12\x06PACKED\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07\x12n\n\x0futf8_validation\x18\x04 \x01(\x0e\x32*.google.protobuf.FeatureSet.Utf8ValidationB)\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\t\x12\x04NONE\x18\x84\x07\xa2\x01\x0b\x12\x06VERIFY\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07\x12m\n\x10message_encoding\x18\x05 \x01(\x0e\x32+.google.protobuf.FeatureSet.MessageEncodingB&\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\x14\x12\x0fLENGTH_PREFIXED\x18\x84\x07\xb2\x01\x03\x08\xe8\x07\x12v\n\x0bjson_format\x18\x06 \x01(\x0e\x32&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\x07\xa2\x01\n\x12\x05\x41LLOW\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07\x12\xa8\x01\n\x14\x65nforce_naming_style\x18\x07 \x01(\x0e\x32..google.protobuf.FeatureSet.EnforceNamingStyleBZ\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\x07\x98\x01\x08\x98\x01\t\xa2\x01\x11\x12\x0cSTYLE_LEGACY\x18\x84\x07\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\x07\xa2\x01\x0e\x12\tSTYLE2026\x18\x8fN\xb2\x01\x03\x08\xe9\x07\x12\xa0\x01\n\x19\x64\x65\x66\x61ult_symbol_visibility\x18\x08 \x01(\x0e\x32\x45.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityB6\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\nEXPORT_ALL\x18\x84\x07\xa2\x01\x15\x12\x10\x45XPORT_TOP_LEVEL\x18\xe9\x07\xb2\x01\x03\x08\xe9\x07\x1a\xa1\x01\n\x11VisibilityFeature\"\x81\x01\n\x17\x44\x65\x66\x61ultSymbolVisibility\x12%\n!DEFAULT_SYMBOL_VISIBILITY_UNKNOWN\x10\x00\x12\x0e\n\nEXPORT_ALL\x10\x01\x12\x14\n\x10\x45XPORT_TOP_LEVEL\x10\x02\x12\r\n\tLOCAL_ALL\x10\x03\x12\n\n\x06STRICT\x10\x04J\x08\x08\x01\x10\x80\x80\x80\x80\x02\"\\\n\rFieldPresence\x12\x1a\n\x16\x46IELD_PRESENCE_UNKNOWN\x10\x00\x12\x0c\n\x08\x45XPLICIT\x10\x01\x12\x0c\n\x08IMPLICIT\x10\x02\x12\x13\n\x0fLEGACY_REQUIRED\x10\x03\"7\n\x08\x45numType\x12\x15\n\x11\x45NUM_TYPE_UNKNOWN\x10\x00\x12\x08\n\x04OPEN\x10\x01\x12\n\n\x06\x43LOSED\x10\x02\"V\n\x15RepeatedFieldEncoding\x12#\n\x1fREPEATED_FIELD_ENCODING_UNKNOWN\x10\x00\x12\n\n\x06PACKED\x10\x01\x12\x0c\n\x08\x45XPANDED\x10\x02\"I\n\x0eUtf8Validation\x12\x1b\n\x17UTF8_VALIDATION_UNKNOWN\x10\x00\x12\n\n\x06VERIFY\x10\x02\x12\x08\n\x04NONE\x10\x03\"\x04\x08\x01\x10\x01\"S\n\x0fMessageEncoding\x12\x1c\n\x18MESSAGE_ENCODING_UNKNOWN\x10\x00\x12\x13\n\x0fLENGTH_PREFIXED\x10\x01\x12\r\n\tDELIMITED\x10\x02\"H\n\nJsonFormat\x12\x17\n\x13JSON_FORMAT_UNKNOWN\x10\x00\x12\t\n\x05\x41LLOW\x10\x01\x12\x16\n\x12LEGACY_BEST_EFFORT\x10\x02\"f\n\x12\x45nforceNamingStyle\x12 \n\x1c\x45NFORCE_NAMING_STYLE_UNKNOWN\x10\x00\x12\r\n\tSTYLE2024\x10\x01\x12\x10\n\x0cSTYLE_LEGACY\x10\x02\x12\r\n\tSTYLE2026\x10\x03*\x06\x08\xe8\x07\x10\x8bN*\x06\x08\x8bN\x10\x90N*\x06\x08\x90N\x10\x91NJ\x06\x08\xe7\x07\x10\xe8\x07\"\x98\x03\n\x12\x46\x65\x61tureSetDefaults\x12N\n\x08\x64\x65\x66\x61ults\x18\x01 \x03(\x0b\x32<.google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault\x12\x31\n\x0fminimum_edition\x18\x04 \x01(\x0e\x32\x18.google.protobuf.Edition\x12\x31\n\x0fmaximum_edition\x18\x05 \x01(\x0e\x32\x18.google.protobuf.Edition\x1a\xcb\x01\n\x18\x46\x65\x61tureSetEditionDefault\x12)\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.Edition\x12\x39\n\x14overridable_features\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.FeatureSet\x12\x33\n\x0e\x66ixed_features\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03R\x08\x66\x65\x61tures\"\xe3\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x86\x01\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\t\x12!\n\x19leading_detached_comments\x18\x06 \x03(\t*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\x9c\x02\n\x11GeneratedCodeInfo\x12\x41\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.Annotation\x1a\xc3\x01\n\nAnnotation\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x05\x12H\n\x08semantic\x18\x05 \x01(\x0e\x32\x36.google.protobuf.GeneratedCodeInfo.Annotation.Semantic\"(\n\x08Semantic\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03SET\x10\x01\x12\t\n\x05\x41LIAS\x10\x02*\xd1\x02\n\x07\x45\x64ition\x12\x13\n\x0f\x45\x44ITION_UNKNOWN\x10\x00\x12\x13\n\x0e\x45\x44ITION_LEGACY\x10\x84\x07\x12\x13\n\x0e\x45\x44ITION_PROTO2\x10\xe6\x07\x12\x13\n\x0e\x45\x44ITION_PROTO3\x10\xe7\x07\x12\x11\n\x0c\x45\x44ITION_2023\x10\xe8\x07\x12\x11\n\x0c\x45\x44ITION_2024\x10\xe9\x07\x12\x11\n\x0c\x45\x44ITION_2026\x10\xea\x07\x12\x15\n\x10\x45\x44ITION_UNSTABLE\x10\x8fN\x12\x17\n\x13\x45\x44ITION_1_TEST_ONLY\x10\x01\x12\x17\n\x13\x45\x44ITION_2_TEST_ONLY\x10\x02\x12\x1d\n\x17\x45\x44ITION_99997_TEST_ONLY\x10\x9d\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99998_TEST_ONLY\x10\x9e\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99999_TEST_ONLY\x10\x9f\x8d\x06\x12\x13\n\x0b\x45\x44ITION_MAX\x10\xff\xff\xff\xff\x07*U\n\x10SymbolVisibility\x12\x14\n\x10VISIBILITY_UNSET\x10\x00\x12\x14\n\x10VISIBILITY_LOCAL\x10\x01\x12\x15\n\x11VISIBILITY_EXPORT\x10\x02\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + FileDescriptorSet = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FileDescriptorSet").msgclass + FileDescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FileDescriptorProto").msgclass + DescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.DescriptorProto").msgclass + DescriptorProto::ExtensionRange = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.DescriptorProto.ExtensionRange").msgclass + DescriptorProto::ReservedRange = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.DescriptorProto.ReservedRange").msgclass + ExtensionRangeOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.ExtensionRangeOptions").msgclass + ExtensionRangeOptions::Declaration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.ExtensionRangeOptions.Declaration").msgclass + ExtensionRangeOptions::VerificationState = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.ExtensionRangeOptions.VerificationState").enummodule + FieldDescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldDescriptorProto").msgclass + FieldDescriptorProto::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldDescriptorProto.Type").enummodule + FieldDescriptorProto::Label = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldDescriptorProto.Label").enummodule + OneofDescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.OneofDescriptorProto").msgclass + EnumDescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.EnumDescriptorProto").msgclass + EnumDescriptorProto::EnumReservedRange = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.EnumDescriptorProto.EnumReservedRange").msgclass + EnumValueDescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.EnumValueDescriptorProto").msgclass + ServiceDescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.ServiceDescriptorProto").msgclass + MethodDescriptorProto = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.MethodDescriptorProto").msgclass + FileOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FileOptions").msgclass + FileOptions::OptimizeMode = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FileOptions.OptimizeMode").enummodule + MessageOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.MessageOptions").msgclass + FieldOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldOptions").msgclass + FieldOptions::EditionDefault = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldOptions.EditionDefault").msgclass + FieldOptions::FeatureSupport = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldOptions.FeatureSupport").msgclass + FieldOptions::CType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldOptions.CType").enummodule + FieldOptions::JSType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldOptions.JSType").enummodule + FieldOptions::OptionRetention = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldOptions.OptionRetention").enummodule + FieldOptions::OptionTargetType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldOptions.OptionTargetType").enummodule + OneofOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.OneofOptions").msgclass + EnumOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.EnumOptions").msgclass + EnumValueOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.EnumValueOptions").msgclass + ServiceOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.ServiceOptions").msgclass + MethodOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.MethodOptions").msgclass + MethodOptions::IdempotencyLevel = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.MethodOptions.IdempotencyLevel").enummodule + UninterpretedOption = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.UninterpretedOption").msgclass + UninterpretedOption::NamePart = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.UninterpretedOption.NamePart").msgclass + FeatureSet = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet").msgclass + FeatureSet::VisibilityFeature = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.VisibilityFeature").msgclass + FeatureSet::VisibilityFeature::DefaultSymbolVisibility = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility").enummodule + FeatureSet::FieldPresence = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.FieldPresence").enummodule + FeatureSet::EnumType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.EnumType").enummodule + FeatureSet::RepeatedFieldEncoding = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.RepeatedFieldEncoding").enummodule + FeatureSet::Utf8Validation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.Utf8Validation").enummodule + FeatureSet::MessageEncoding = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.MessageEncoding").enummodule + FeatureSet::JsonFormat = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.JsonFormat").enummodule + FeatureSet::EnforceNamingStyle = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSet.EnforceNamingStyle").enummodule + FeatureSetDefaults = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSetDefaults").msgclass + FeatureSetDefaults::FeatureSetEditionDefault = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault").msgclass + SourceCodeInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.SourceCodeInfo").msgclass + SourceCodeInfo::Location = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.SourceCodeInfo.Location").msgclass + GeneratedCodeInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.GeneratedCodeInfo").msgclass + GeneratedCodeInfo::Annotation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.GeneratedCodeInfo.Annotation").msgclass + GeneratedCodeInfo::Annotation::Semantic = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.GeneratedCodeInfo.Annotation.Semantic").enummodule + Edition = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Edition").enummodule + SymbolVisibility = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.SymbolVisibility").enummodule + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/duration_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/duration_pb.rb new file mode 100755 index 0000000..f969776 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/duration_pb.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/duration.proto + +require 'google/protobuf' + + +descriptor_data = "\n\x1egoogle/protobuf/duration.proto\x12\x0fgoogle.protobuf\"*\n\x08\x44uration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42\x83\x01\n\x13\x63om.google.protobufB\rDurationProtoP\x01Z1google.golang.org/protobuf/types/known/durationpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + Duration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Duration").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/empty_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/empty_pb.rb new file mode 100755 index 0000000..da9c723 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/empty_pb.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/empty.proto + +require 'google/protobuf' + + +descriptor_data = "\n\x1bgoogle/protobuf/empty.proto\x12\x0fgoogle.protobuf\"\x07\n\x05\x45mptyB}\n\x13\x63om.google.protobufB\nEmptyProtoP\x01Z.google.golang.org/protobuf/types/known/emptypb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + Empty = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Empty").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor.rb new file mode 100755 index 0000000..c30da20 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor.rb @@ -0,0 +1,175 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + ## + # Message Descriptor - Descriptor for short. + class Descriptor + attr :descriptor_pool, :msg_class + include Enumerable + + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + include Google::Protobuf::Internal::PointerHelper + + # @param value [Descriptor] Descriptor to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _ = nil) + msg_def_ptr = value.nil? ? nil : value.instance_variable_get(:@msg_def) + return ::FFI::Pointer::NULL if msg_def_ptr.nil? + raise "Underlying msg_def was null!" if msg_def_ptr.null? + msg_def_ptr + end + + ## + # @param msg_def [::FFI::Pointer] MsgDef pointer to be wrapped + # @param _ [Object] Unused + def from_native(msg_def, _ = nil) + return nil if msg_def.nil? or msg_def.null? + file_def = Google::Protobuf::FFI.get_message_file_def msg_def + descriptor_from_file_def(file_def, msg_def) + end + end + + def to_native + self.class.to_native(self) + end + + ## + # Great write up of this strategy: + # See https://blog.appsignal.com/2018/08/07/ruby-magic-changing-the-way-ruby-creates-objects.html + def self.new(*arguments, &block) + raise "Descriptor objects may not be created from Ruby." + end + + def to_s + inspect + end + + def inspect + "Descriptor - (not the message class) #{name}" + end + + def file_descriptor + @descriptor_pool.send(:get_file_descriptor, Google::Protobuf::FFI.get_message_file_def(@msg_def)) + end + + def name + @name ||= Google::Protobuf::FFI.get_message_fullname(self) + end + + def each_oneof &block + n = Google::Protobuf::FFI.oneof_count(self) + 0.upto(n-1) do |i| + yield(Google::Protobuf::FFI.get_oneof_by_index(self, i)) + end + nil + end + + def each &block + n = Google::Protobuf::FFI.field_count(self) + 0.upto(n-1) do |i| + yield(Google::Protobuf::FFI.get_field_by_index(self, i)) + end + nil + end + + def lookup(name) + Google::Protobuf::FFI.get_field_by_name(self, name, name.size) + end + + def lookup_oneof(name) + Google::Protobuf::FFI.get_oneof_by_name(self, name, name.size) + end + + def msgclass + @msg_class ||= build_message_class + end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.message_options(self, size_ptr, temporary_arena) + opts = Google::Protobuf::MessageOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + opts.clear_features() + opts.freeze + end + end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.message_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::DescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + + private + + extend Google::Protobuf::Internal::Convert + + def initialize(msg_def, descriptor_pool) + @msg_def = msg_def + @msg_class = nil + @descriptor_pool = descriptor_pool + end + + def self.private_constructor(msg_def, descriptor_pool) + instance = allocate + instance.send(:initialize, msg_def, descriptor_pool) + instance + end + + def wrapper? + if defined? @wrapper + @wrapper + else + @wrapper = case Google::Protobuf::FFI.get_well_known_type self + when :DoubleValue, :FloatValue, :Int64Value, :UInt64Value, :Int32Value, :UInt32Value, :StringValue, :BytesValue, :BoolValue + true + else + false + end + end + end + + def self.get_message(msg, descriptor, arena) + return nil if msg.nil? or msg.null? + message = OBJECT_CACHE.get(msg.address) + if message.nil? + message = descriptor.msgclass.send(:private_constructor, arena, msg: msg) + end + message + end + + def pool + @descriptor_pool + end + end + + class FFI + # MessageDef + attach_function :new_message_from_def, :upb_Message_New, [MiniTable.by_ref, Internal::Arena], :Message + attach_function :field_count, :upb_MessageDef_FieldCount, [Descriptor], :int + attach_function :get_message_file_def, :upb_MessageDef_File, [:pointer], :FileDef + attach_function :get_message_fullname, :upb_MessageDef_FullName, [Descriptor], :string + attach_function :get_mini_table, :upb_MessageDef_MiniTable, [Descriptor], MiniTable.ptr + attach_function :oneof_count, :upb_MessageDef_OneofCount, [Descriptor], :int + attach_function :message_options, :Descriptor_serialized_options, [Descriptor, :pointer, Internal::Arena], :pointer + attach_function :get_well_known_type, :upb_MessageDef_WellKnownType, [Descriptor], WellKnown + attach_function :find_msg_def_by_name, :upb_MessageDef_FindByNameWithSize, [Descriptor, :string, :size_t, :FieldDefPointer, :OneofDefPointer], :bool + attach_function :message_to_proto, :Descriptor_serialized_to_proto, [Descriptor, :pointer, Internal::Arena], :pointer + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor_pool.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor_pool.rb new file mode 100755 index 0000000..c39b3d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/descriptor_pool.rb @@ -0,0 +1,83 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class FFI + # DefPool + attach_function :add_serialized_file, :upb_DefPool_AddFile, [:DefPool, :FileDescriptorProto, Status.by_ref], :FileDef + attach_function :free_descriptor_pool, :upb_DefPool_Free, [:DefPool], :void + attach_function :create_descriptor_pool,:upb_DefPool_New, [], :DefPool + attach_function :disable_closed_enum_checking, :upb_DefPool_DisableClosedEnumChecking, [:DefPool], :void + attach_function :get_extension_registry,:upb_DefPool_ExtensionRegistry, [:DefPool], :ExtensionRegistry + attach_function :lookup_enum, :upb_DefPool_FindEnumByName, [:DefPool, :string], EnumDescriptor + attach_function :lookup_extension, :upb_DefPool_FindExtensionByName,[:DefPool, :string], FieldDescriptor + attach_function :lookup_msg, :upb_DefPool_FindMessageByName, [:DefPool, :string], Descriptor + attach_function :lookup_service, :upb_DefPool_FindServiceByName, [:DefPool, :string], ServiceDescriptor + attach_function :lookup_file, :upb_DefPool_FindFileByName, [:DefPool, :string], FileDescriptor + + # FileDescriptorProto + attach_function :parse, :FileDescriptorProto_parse, [:binary_string, :size_t, Internal::Arena], :FileDescriptorProto + end + class DescriptorPool + attr :descriptor_pool + attr_accessor :descriptor_class_by_def + + def initialize + @descriptor_pool = ::FFI::AutoPointer.new(Google::Protobuf::FFI.create_descriptor_pool, Google::Protobuf::FFI.method(:free_descriptor_pool)) + @descriptor_class_by_def = {} + + # Ruby treats all enums as open. + Google::Protobuf::FFI.disable_closed_enum_checking(@descriptor_pool) + + # Should always be the last expression of the initializer to avoid + # leaking references to this object before construction is complete. + Google::Protobuf::OBJECT_CACHE.try_add @descriptor_pool.address, self + end + + def add_serialized_file(file_contents) + # Allocate memory sized to file_contents + memBuf = ::FFI::MemoryPointer.new(:char, file_contents.bytesize) + # Insert the data + memBuf.put_bytes(0, file_contents) + temporary_arena = Google::Protobuf::FFI.create_arena + file_descriptor_proto = Google::Protobuf::FFI.parse memBuf, file_contents.bytesize, temporary_arena + raise ArgumentError.new("Unable to parse FileDescriptorProto") if file_descriptor_proto.null? + + status = Google::Protobuf::FFI::Status.new + file_descriptor = Google::Protobuf::FFI.add_serialized_file @descriptor_pool, file_descriptor_proto, status + if file_descriptor.null? + raise TypeError.new("Unable to build file to DescriptorPool: #{Google::Protobuf::FFI.error_message(status)}") + else + @descriptor_class_by_def[file_descriptor.address] = FileDescriptor.new file_descriptor, self + end + end + + def lookup name + Google::Protobuf::FFI.lookup_msg(@descriptor_pool, name) || + Google::Protobuf::FFI.lookup_enum(@descriptor_pool, name) || + Google::Protobuf::FFI.lookup_extension(@descriptor_pool, name) || + Google::Protobuf::FFI.lookup_service(@descriptor_pool, name) || + Google::Protobuf::FFI.lookup_file(@descriptor_pool, name) + end + + def self.generated_pool + @@generated_pool ||= DescriptorPool.new + end + + private + + # Implementation details below are subject to breaking changes without + # warning and are intended for use only within the gem. + + def get_file_descriptor file_def + return nil if file_def.null? + @descriptor_class_by_def[file_def.address] ||= FileDescriptor.new(file_def, self) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/enum_descriptor.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/enum_descriptor.rb new file mode 100755 index 0000000..f95e091 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/enum_descriptor.rb @@ -0,0 +1,183 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class EnumDescriptor + attr :descriptor_pool, :enum_def + include Enumerable + + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + include Google::Protobuf::Internal::PointerHelper + + # @param value [EnumDescriptor] EnumDescriptor to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _) + value.instance_variable_get(:@enum_def) || ::FFI::Pointer::NULL + end + + ## + # @param enum_def [::FFI::Pointer] EnumDef pointer to be wrapped + # @param _ [Object] Unused + def from_native(enum_def, _) + return nil if enum_def.nil? or enum_def.null? + file_def = Google::Protobuf::FFI.get_message_file_def enum_def + descriptor_from_file_def(file_def, enum_def) + end + end + + def self.new(*arguments, &block) + raise "Descriptor objects may not be created from Ruby." + end + + def file_descriptor + @descriptor_pool.send(:get_file_descriptor, Google::Protobuf::FFI.get_enum_file_descriptor(self)) + end + + def name + Google::Protobuf::FFI.get_enum_fullname(self) + end + + def to_s + inspect + end + + def inspect + "#{self.class.name}: #{name}" + end + + def lookup_name(name) + self.class.send(:lookup_name, self, name) + end + + def lookup_value(number) + self.class.send(:lookup_value, self, number) + end + + def each &block + n = Google::Protobuf::FFI.enum_value_count(self) + 0.upto(n - 1) do |i| + enum_value = Google::Protobuf::FFI.enum_value_by_index(self, i) + yield(Google::Protobuf::FFI.enum_name(enum_value).to_sym, Google::Protobuf::FFI.enum_number(enum_value)) + end + nil + end + + def enummodule + if @module.nil? + @module = build_enum_module + end + @module + end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.enum_options(self, size_ptr, temporary_arena) + opts = Google::Protobuf::EnumOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + opts.clear_features() + opts.freeze + end + end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.enum_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::EnumDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + + private + + def initialize(enum_def, descriptor_pool) + @descriptor_pool = descriptor_pool + @enum_def = enum_def + @module = nil + end + + def self.private_constructor(enum_def, descriptor_pool) + instance = allocate + instance.send(:initialize, enum_def, descriptor_pool) + instance + end + + def self.lookup_value(enum_def, number) + enum_value = Google::Protobuf::FFI.enum_value_by_number(enum_def, number) + if enum_value.null? + nil + else + Google::Protobuf::FFI.enum_name(enum_value).to_sym + end + end + + def self.lookup_name(enum_def, name) + enum_value = Google::Protobuf::FFI.enum_value_by_name(enum_def, name.to_s, name.size) + if enum_value.null? + nil + else + Google::Protobuf::FFI.enum_number(enum_value) + end + end + + def build_enum_module + descriptor = self + dynamic_module = Module.new do + @descriptor = descriptor + + class << self + attr_accessor :descriptor + end + + def self.lookup(number) + descriptor.lookup_value number + end + + def self.resolve(name) + descriptor.lookup_name name + end + end + + self.each do |name, value| + if name[0] < 'A' || name[0] > 'Z' + if name[0] >= 'a' and name[0] <= 'z' + name = name[0].upcase + name[1..-1] # auto capitalize + else + warn( + "Enum value '#{name}' does not start with an uppercase letter " + + "as is required for Ruby constants.") + next + end + end + dynamic_module.const_set(name.to_sym, value) + end + dynamic_module + end + end + + class FFI + # EnumDescriptor + attach_function :get_enum_file_descriptor, :upb_EnumDef_File, [EnumDescriptor], :FileDef + attach_function :enum_value_by_name, :upb_EnumDef_FindValueByNameWithSize,[EnumDescriptor, :string, :size_t], :EnumValueDef + attach_function :enum_value_by_number, :upb_EnumDef_FindValueByNumber, [EnumDescriptor, :int], :EnumValueDef + attach_function :get_enum_fullname, :upb_EnumDef_FullName, [EnumDescriptor], :string + attach_function :enum_options, :EnumDescriptor_serialized_options, [EnumDescriptor, :pointer, Internal::Arena], :pointer + attach_function :enum_to_proto, :EnumDescriptor_serialized_to_proto, [EnumDescriptor, :pointer, Internal::Arena], :pointer + attach_function :enum_value_by_index, :upb_EnumDef_Value, [EnumDescriptor, :int], :EnumValueDef + attach_function :enum_value_count, :upb_EnumDef_ValueCount, [EnumDescriptor], :int + attach_function :enum_name, :upb_EnumValueDef_Name, [:EnumValueDef], :string + attach_function :enum_number, :upb_EnumValueDef_Number, [:EnumValueDef], :int + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/ffi.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/ffi.rb new file mode 100755 index 0000000..0a91669 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/ffi.rb @@ -0,0 +1,213 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class FFI + extend ::FFI::Library + # Workaround for Bazel's use of symlinks + JRuby's __FILE__ and `caller` + # that resolves them. + if ENV['BAZEL'] == 'true' + ffi_lib ::FFI::Compiler::Loader.find 'protobuf_c_ffi', ENV['PWD'] + else + ffi_lib ::FFI::Compiler::Loader.find 'protobuf_c_ffi' + end + + ## Map + Upb_Map_Begin = -1 + + ## Encoding Status + Upb_Status_MaxMessage = 511 + Upb_Encode_Deterministic = 1 + Upb_Encode_SkipUnknown = 2 + + ## JSON Encoding options + # When set, emits 0/default values. TODO: proto3 only? + Upb_JsonEncode_EmitDefaults = 1 + # When set, use normal (snake_case) field names instead of JSON (camelCase) names. + Upb_JsonEncode_UseProtoNames = 2 + # When set, emits enums as their integer values instead of as their names. + Upb_JsonEncode_FormatEnumsAsIntegers = 4 + + ## JSON Decoding options + Upb_JsonDecode_IgnoreUnknown = 1 + + ## JSON Decoding results + Upb_JsonDecodeResult_Ok = 0 + Upb_JsonDecodeResult_Error = 2 + + typedef :pointer, :Array + typedef :pointer, :DefPool + typedef :pointer, :EnumValueDef + typedef :pointer, :ExtensionRegistry + typedef :pointer, :FieldDefPointer + typedef :pointer, :FileDef + typedef :pointer, :FileDescriptorProto + typedef :pointer, :Map + typedef :pointer, :Message # Instances of a message + typedef :pointer, :OneofDefPointer + typedef :pointer, :binary_string + if ::FFI::Platform::ARCH == "aarch64" + typedef :u_int8_t, :uint8_t + typedef :u_int16_t, :uint16_t + typedef :u_int32_t, :uint32_t + typedef :u_int64_t, :uint64_t + end + + FieldType = enum( + :double, 1, + :float, + :int64, + :uint64, + :int32, + :fixed64, + :fixed32, + :bool, + :string, + :group, + :message, + :bytes, + :uint32, + :enum, + :sfixed32, + :sfixed64, + :sint32, + :sint64 + ) + + CType = enum( + :bool, 1, + :float, + :int32, + :uint32, + :enum, + :message, + :double, + :int64, + :uint64, + :string, + :bytes + ) + + Label = enum( + :optional, 1, + :required, + :repeated + ) + + # All the different kind of well known type messages. For simplicity of check, + # number wrappers and string wrappers are grouped together. Make sure the + # order and merber of these groups are not changed. + + WellKnown = enum( + :Unspecified, + :Any, + :FieldMask, + :Duration, + :Timestamp, + # number wrappers + :DoubleValue, + :FloatValue, + :Int64Value, + :UInt64Value, + :Int32Value, + :UInt32Value, + # string wrappers + :StringValue, + :BytesValue, + :BoolValue, + :Value, + :ListValue, + :Struct + ) + + DecodeStatus = enum( + :Ok, + :Malformed, # Wire format was corrupt + :OutOfMemory, # Arena alloc failed + :BadUtf8, # String field had bad UTF-8 + :MaxDepthExceeded, # Exceeded UPB_DECODE_MAXDEPTH + + # CheckRequired failed, but the parse otherwise succeeded. + :MissingRequired, + ) + + EncodeStatus = enum( + :Ok, + :OutOfMemory, # Arena alloc failed + :MaxDepthExceeded, # Exceeded UPB_DECODE_MAXDEPTH + + # CheckRequired failed, but the parse otherwise succeeded. + :MissingRequired, + ) + + class StringView < ::FFI::Struct + layout :data, :pointer, + :size, :size_t + end + + class MiniTable < ::FFI::Struct + layout :fields, :pointer, + :size, :uint16_t, + :field_count, :uint16_t, + :ext, :uint8_t, # upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 + :dense_below, :uint8_t, + :table_mask, :uint8_t, + :required_count, :uint8_t # Required fields have the lowest hasbits. + # To statically initialize the tables of variable length, we need a flexible + # array member, and we need to compile in gnu99 mode (constant initialization + # of flexible array members is a GNU extension, not in C99 unfortunately. */ + # _upb_FastTable_Entry fasttable[]; + end + + class Status < ::FFI::Struct + layout :ok, :bool, + :msg, [:char, Upb_Status_MaxMessage] + + def initialize + super + FFI.clear self + end + end + + class MessageValue < ::FFI::Union + layout :bool_val, :bool, + :float_val, :float, + :double_val, :double, + :int32_val, :int32_t, + :int64_val, :int64_t, + :uint32_val, :uint32_t, + :uint64_val,:uint64_t, + :map_val, :pointer, + :msg_val, :pointer, + :array_val,:pointer, + :str_val, StringView + end + + Upb_Message_Begin = -1 + + class MutableMessageValue < ::FFI::Union + layout :map, :Map, + :msg, :Message, + :array, :Array + end + + # Status + attach_function :clear, :upb_Status_Clear, [Status.by_ref], :void + attach_function :error_message, :upb_Status_ErrorMessage, [Status.by_ref], :string + + # Generic + attach_function :memcmp, [:pointer, :pointer, :size_t], :int + attach_function :memcpy, [:pointer, :pointer, :size_t], :int + + # Alternatives to pre-processor macros + def self.decode_max_depth(i) + i << 16 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/field_descriptor.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/field_descriptor.rb new file mode 100755 index 0000000..2ec6d8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/field_descriptor.rb @@ -0,0 +1,346 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class FieldDescriptor + attr :field_def, :descriptor_pool + + include Google::Protobuf::Internal::Convert + + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + include Google::Protobuf::Internal::PointerHelper + + # @param value [FieldDescriptor] FieldDescriptor to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _) + field_def_ptr = value.instance_variable_get(:@field_def) + warn "Underlying field_def was nil!" if field_def_ptr.nil? + raise "Underlying field_def was null!" if !field_def_ptr.nil? and field_def_ptr.null? + field_def_ptr + end + + ## + # @param field_def [::FFI::Pointer] FieldDef pointer to be wrapped + # @param _ [Object] Unused + def from_native(field_def, _ = nil) + return nil if field_def.nil? or field_def.null? + file_def = Google::Protobuf::FFI.file_def_by_raw_field_def(field_def) + descriptor_from_file_def(file_def, field_def) + end + end + + def self.new(*arguments, &block) + raise "Descriptor objects may not be created from Ruby." + end + + def to_s + inspect + end + + def inspect + "#{self.class.name}: #{name}" + end + + def name + @name ||= Google::Protobuf::FFI.get_full_name(self) + end + + def json_name + @json_name ||= Google::Protobuf::FFI.get_json_name(self) + end + + def number + @number ||= Google::Protobuf::FFI.get_number(self) + end + + def type + @type ||= Google::Protobuf::FFI.get_type(self) + end + + # DEPRECATED: Use required? or repeated? instead. + def label + @label ||= Google::Protobuf::FFI.get_label(self) + end + + def default + return nil if Google::Protobuf::FFI.is_sub_message(self) + if Google::Protobuf::FFI.is_repeated(self) + message_value = Google::Protobuf::FFI::MessageValue.new + else + message_value = Google::Protobuf::FFI.get_default(self) + end + enum_def = Google::Protobuf::FFI.get_subtype_as_enum(self) + if enum_def.null? + convert_upb_to_ruby message_value, c_type + else + convert_upb_to_ruby message_value, c_type, enum_def + end + end + + def submsg_name + if defined? @submsg_name + @submsg_name + else + @submsg_name = case c_type + when :enum + Google::Protobuf::FFI.get_enum_fullname Google::Protobuf::FFI.get_subtype_as_enum self + when :message + Google::Protobuf::FFI.get_message_fullname Google::Protobuf::FFI.get_subtype_as_message self + else + nil + end + end + end + + ## + # Tests if this field has been set on the argument message. + # + # @param msg [Google::Protobuf::Message] + # @return [Object] Value of the field on this message. + # @raise [TypeError] If the field is not defined on this message. + def get(msg) + if msg.class.descriptor == Google::Protobuf::FFI.get_containing_message_def(self) + msg.send :get_field, self + else + raise TypeError.new "get method called on wrong message type" + end + end + + def subtype + if defined? @subtype + @subtype + else + @subtype = case c_type + when :enum + Google::Protobuf::FFI.get_subtype_as_enum(self) + when :message + Google::Protobuf::FFI.get_subtype_as_message(self) + else + nil + end + end + end + + ## + # Tests if this field has been set on the argument message. + # + # @param msg [Google::Protobuf::Message] + # @return [Boolean] True iff message has this field set + # @raise [TypeError] If this field does not exist on the message + # @raise [ArgumentError] If this field does not track presence + def has?(msg) + if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self) + raise TypeError.new "has method called on wrong message type" + end + unless has_presence? + raise ArgumentError.new "does not track presence" + end + + Google::Protobuf::FFI.get_message_has msg.instance_variable_get(:@msg), self + end + + ## + # Tests if this field tracks presence. + # + # @return [Boolean] True iff this field tracks presence + def has_presence? + @has_presence ||= Google::Protobuf::FFI.get_has_presence(self) + end + + ## + # Tests if this is a repeated field that uses packed encoding. + # + # @return [Boolean] True iff this field is packed + def is_packed? + @is_packed ||= Google::Protobuf::FFI.get_is_packed(self) + end + + # @param msg [Google::Protobuf::Message] + def clear(msg) + if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self) + raise TypeError.new "clear method called on wrong message type" + end + Google::Protobuf::FFI.clear_message_field msg.instance_variable_get(:@msg), self + nil + end + + ## + # call-seq: + # FieldDescriptor.set(message, value) + # + # Sets the value corresponding to this field to the given value on the given + # message. Raises an exception if message is of the wrong type. Performs the + # ordinary type-checks for field setting. + # + # @param msg [Google::Protobuf::Message] + # @param value [Object] + def set(msg, value) + if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self) + raise TypeError.new "set method called on wrong message type" + end + unless set_value_on_message value, msg.instance_variable_get(:@msg), msg.instance_variable_get(:@arena) + raise RuntimeError.new "allocation failed" + end + nil + end + + def map? + @map ||= Google::Protobuf::FFI.is_map self + end + + def required? + @required ||= Google::Protobuf::FFI.is_required self + end + + def repeated? + @repeated ||= Google::Protobuf::FFI.is_repeated self + end + + def sub_message? + @sub_message ||= Google::Protobuf::FFI.is_sub_message self + end + + def wrapper? + if defined? @wrapper + @wrapper + else + message_descriptor = Google::Protobuf::FFI.get_subtype_as_message(self) + @wrapper = message_descriptor.nil? ? false : message_descriptor.send(:wrapper?) + end + end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.field_options(self, size_ptr, temporary_arena) + opts = Google::Protobuf::FieldOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + opts.clear_features() + opts.freeze + end + end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.field_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::FieldDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + + private + + def initialize(field_def, descriptor_pool) + @field_def = field_def + @descriptor_pool = descriptor_pool + end + + def self.private_constructor(field_def, descriptor_pool) + instance = allocate + instance.send(:initialize, field_def, descriptor_pool) + instance + end + + # TODO Can this be added to the public API? + def real_containing_oneof + @real_containing_oneof ||= Google::Protobuf::FFI.real_containing_oneof self + end + + # Implementation details below are subject to breaking changes without + # warning and are intended for use only within the gem. + + ## + # Sets the field this FieldDescriptor represents to the given value on the given message. + # @param value [Object] Value to be set + # @param msg [::FFI::Pointer] Pointer the the upb_Message + # @param arena [Arena] Arena of the message that owns msg + def set_value_on_message(value, msg, arena, wrap: false) + message_to_alter = msg + field_def_to_set = self + if map? + raise TypeError.new "Expected map" unless value.is_a? Google::Protobuf::Map + message_descriptor = subtype + + key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1) + key_field_type = Google::Protobuf::FFI.get_type(key_field_def) + raise TypeError.new "Map key type does not match field's key type" unless key_field_type == value.send(:key_type) + + value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2) + value_field_type = Google::Protobuf::FFI.get_type(value_field_def) + raise TypeError.new "Map value type does not match field's value type" unless value_field_type == value.send(:value_type) + + raise TypeError.new "Map value type has wrong message/enum class" unless value_field_def.subtype == value.send(:descriptor) + + arena.fuse(value.send(:arena)) + message_value = Google::Protobuf::FFI::MessageValue.new + message_value[:map_val] = value.send(:map_ptr) + elsif repeated? + raise TypeError.new "Expected repeated field array" unless value.is_a? RepeatedField + raise TypeError.new "Repeated field array has wrong message/enum class" unless value.send(:type) == type + arena.fuse(value.send(:arena)) + message_value = Google::Protobuf::FFI::MessageValue.new + message_value[:array_val] = value.send(:array) + else + if value.nil? and (sub_message? or !real_containing_oneof.nil?) + Google::Protobuf::FFI.clear_message_field message_to_alter, field_def_to_set + return true + end + if wrap + value_field_def = Google::Protobuf::FFI.get_field_by_number subtype, 1 + type_for_conversion = Google::Protobuf::FFI.get_c_type(value_field_def) + raise RuntimeError.new "Not expecting to get a msg or enum when unwrapping" if [:enum, :message].include? type_for_conversion + message_value = convert_ruby_to_upb(value, arena, type_for_conversion, nil) + message_to_alter = Google::Protobuf::FFI.get_mutable_message(msg, self, arena)[:msg] + field_def_to_set = value_field_def + else + message_value = convert_ruby_to_upb(value, arena, c_type, subtype) + end + end + Google::Protobuf::FFI.set_message_field message_to_alter, field_def_to_set, message_value, arena + end + + def c_type + @c_type ||= Google::Protobuf::FFI.get_c_type(self) + end + end + + class FFI + # MessageDef + attach_function :get_field_by_index, :upb_MessageDef_Field, [Descriptor, :int], FieldDescriptor + attach_function :get_field_by_name, :upb_MessageDef_FindFieldByNameWithSize,[Descriptor, :string, :size_t], FieldDescriptor + attach_function :get_field_by_number, :upb_MessageDef_FindFieldByNumber, [Descriptor, :uint32_t], FieldDescriptor + + # FieldDescriptor + attach_function :field_options, :FieldDescriptor_serialized_options, [FieldDescriptor, :pointer, Internal::Arena], :pointer + attach_function :get_containing_message_def, :upb_FieldDef_ContainingType, [FieldDescriptor], Descriptor + attach_function :get_c_type, :upb_FieldDef_CType, [FieldDescriptor], CType + attach_function :get_default, :upb_FieldDef_Default, [FieldDescriptor], MessageValue.by_value + attach_function :get_subtype_as_enum, :upb_FieldDef_EnumSubDef, [FieldDescriptor], EnumDescriptor + attach_function :get_has_presence, :upb_FieldDef_HasPresence, [FieldDescriptor], :bool + attach_function :get_is_packed, :upb_FieldDef_IsPacked, [FieldDescriptor], :bool + attach_function :is_map, :upb_FieldDef_IsMap, [FieldDescriptor], :bool + attach_function :is_required, :upb_FieldDef_IsRequired, [FieldDescriptor], :bool + attach_function :is_repeated, :upb_FieldDef_IsRepeated, [FieldDescriptor], :bool + attach_function :is_sub_message, :upb_FieldDef_IsSubMessage, [FieldDescriptor], :bool + attach_function :get_json_name, :upb_FieldDef_JsonName, [FieldDescriptor], :string + attach_function :get_label, :upb_FieldDef_Label, [FieldDescriptor], Label + attach_function :get_subtype_as_message, :upb_FieldDef_MessageSubDef, [FieldDescriptor], Descriptor + attach_function :get_full_name, :upb_FieldDef_Name, [FieldDescriptor], :string + attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t + attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType + attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef + attach_function :field_to_proto, :FieldDescriptor_serialized_to_proto,[FieldDescriptor, :pointer, Internal::Arena], :pointer + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/file_descriptor.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/file_descriptor.rb new file mode 100755 index 0000000..72e6a0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/file_descriptor.rb @@ -0,0 +1,85 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class FFI + # FileDescriptor + attach_function :file_def_name, :upb_FileDef_Name, [:FileDef], :string + attach_function :file_def_pool, :upb_FileDef_Pool, [:FileDef], :DefPool + attach_function :file_options, :FileDescriptor_serialized_options, [:FileDef, :pointer, Internal::Arena], :pointer + attach_function :file_to_proto, :FileDescriptor_serialized_to_proto, [:FileDef, :pointer, Internal::Arena], :pointer + end + + class FileDescriptor + attr :descriptor_pool, :file_def + + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + include Google::Protobuf::Internal::PointerHelper + + # @param value [FileDescriptor] FileDescriptor to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _) + file_def_ptr = value.nil? ? nil : value.instance_variable_get(:@file_def) + return ::FFI::Pointer::NULL if file_def_ptr.nil? + raise "Underlying file_def was null!" if file_def_ptr.null? + file_def_ptr + end + + ## + # @param file_def [::FFI::Pointer] FileDef pointer to be wrapped + # @param _ [Object] Unused + def from_native(file_def, _ = nil) + return nil if file_def.nil? or file_def.null? + descriptor_from_file_def(file_def) + end + end + + def initialize(file_def, descriptor_pool) + @descriptor_pool = descriptor_pool + @file_def = file_def + end + + def to_s + inspect + end + + def inspect + "#{self.class.name}: #{name}" + end + + def name + Google::Protobuf::FFI.file_def_name(@file_def) + end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.file_options(@file_def, size_ptr, temporary_arena) + opts = Google::Protobuf::FileOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + opts.clear_features() + opts.freeze + end + end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.file_to_proto(@file_def, size_ptr, temporary_arena) + Google::Protobuf::FileDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/arena.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/arena.rb new file mode 100755 index 0000000..da3b2c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/arena.rb @@ -0,0 +1,60 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +## +# Implementation details below are subject to breaking changes without +# warning and are intended for use only within the gem. +module Google + module Protobuf + module Internal + class Arena + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + + # @param value [Arena] Arena to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _) + value.instance_variable_get(:@arena) || ::FFI::Pointer::NULL + end + + ## + # @param value [::FFI::Pointer] Arena pointer to be wrapped + # @param _ [Object] Unused + def from_native(value, _) + new(value) + end + end + + def initialize(pointer) + @arena = ::FFI::AutoPointer.new(pointer, Google::Protobuf::FFI.method(:free_arena)) + @pinned_messages = [] + end + + def fuse(other_arena) + return if other_arena == self + unless Google::Protobuf::FFI.fuse_arena(self, other_arena) + raise RuntimeError.new "Unable to fuse arenas. This should never happen since Ruby does not use initial blocks" + end + end + end + end + + class FFI + # Arena + attach_function :create_arena, :Arena_create, [], Internal::Arena + attach_function :fuse_arena, :upb_Arena_Fuse, [Internal::Arena, Internal::Arena], :bool + # Argument takes a :pointer rather than a typed Arena here due to + # implementation details of FFI::AutoPointer. + attach_function :free_arena, :upb_Arena_Free, [:pointer], :void + attach_function :arena_malloc, :upb_Arena_Malloc, [Internal::Arena, :size_t], :pointer + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/convert.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/convert.rb new file mode 100755 index 0000000..649b90a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/convert.rb @@ -0,0 +1,292 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +## +# Implementation details below are subject to breaking changes without +# warning and are intended for use only within the gem. +module Google + module Protobuf + module Internal + module Convert + + # Arena should be the + # @param value [Object] Value to convert + # @param arena [Arena] Arena that owns the Message where the MessageValue + # will be set + # @return [Google::Protobuf::FFI::MessageValue] + def convert_ruby_to_upb(value, arena, c_type, msg_or_enum_def) + raise ArgumentError.new "Expected Descriptor or EnumDescriptor, instead got #{msg_or_enum_def.class}" unless [NilClass, Descriptor, EnumDescriptor].include? msg_or_enum_def.class + return_value = Google::Protobuf::FFI::MessageValue.new + case c_type + when :float + raise TypeError.new "Expected number type for float field '#{name}' (given #{value.class})." unless value.respond_to? :to_f + return_value[:float_val] = value.to_f + when :double + raise TypeError.new "Expected number type for double field '#{name}' (given #{value.class})." unless value.respond_to? :to_f + return_value[:double_val] = value.to_f + when :bool + raise TypeError.new "Invalid argument for boolean field '#{name}' (given #{value.class})." unless [TrueClass, FalseClass].include? value.class + return_value[:bool_val] = value + when :string + raise TypeError.new "Invalid argument for string field '#{name}' (given #{value.class})." unless value.is_a?(String) or value.is_a?(Symbol) + value = value.to_s if value.is_a?(Symbol) + if value.encoding == Encoding::UTF_8 + unless value.valid_encoding? + raise Encoding::InvalidByteSequenceError.new "String is invalid UTF-8" + end + string_value = value + else + string_value = value.to_s.encode("UTF-8") + end + return_value[:str_val][:size] = string_value.bytesize + return_value[:str_val][:data] = Google::Protobuf::FFI.arena_malloc(arena, string_value.bytesize) + # TODO - how important is it to still use arena malloc, versus the following? + # buffer = ::FFI::MemoryPointer.new(:char, string_value.bytesize) + # buffer.put_bytes(0, string_value) + # return_value[:str_val][:data] = buffer + raise NoMemoryError.new "Cannot allocate #{string_value.bytesize} bytes for string on Arena" if return_value[:str_val][:data].nil? || return_value[:str_val][:data].null? + return_value[:str_val][:data].write_string(string_value) + when :bytes + raise TypeError.new "Invalid argument for bytes field '#{name}' (given #{value.class})." unless value.is_a? String + string_value = value.encode("ASCII-8BIT") + return_value[:str_val][:size] = string_value.bytesize + return_value[:str_val][:data] = Google::Protobuf::FFI.arena_malloc(arena, string_value.bytesize) + raise NoMemoryError.new "Cannot allocate #{string_value.bytesize} bytes for bytes on Arena" if return_value[:str_val][:data].nil? || return_value[:str_val][:data].null? + return_value[:str_val][:data].write_string_length(string_value, string_value.bytesize) + when :message + raise TypeError.new "nil message not allowed here." if value.nil? + if value.is_a? Hash + raise RuntimeError.new "Attempted to initialize message from Hash for field #{name} but have no definition" if msg_or_enum_def.nil? + new_message = msg_or_enum_def.msgclass. + send(:private_constructor, arena, initial_value: value) + return_value[:msg_val] = new_message.instance_variable_get(:@msg) + return return_value + end + + descriptor = value.class.respond_to?(:descriptor) ? value.class.descriptor : nil + if descriptor != msg_or_enum_def + wkt = Google::Protobuf::FFI.get_well_known_type(msg_or_enum_def) + case wkt + when :Timestamp + raise TypeError.new "Invalid type #{value.class} to assign to submessage field '#{name}'." unless value.kind_of? Time + new_message = Google::Protobuf::FFI.new_message_from_def Google::Protobuf::FFI.get_mini_table(msg_or_enum_def), arena + sec = Google::Protobuf::FFI::MessageValue.new + sec[:int64_val] = value.tv_sec + sec_field_def = Google::Protobuf::FFI.get_field_by_number msg_or_enum_def, 1 + raise "Should be impossible" unless Google::Protobuf::FFI.set_message_field new_message, sec_field_def, sec, arena + nsec_field_def = Google::Protobuf::FFI.get_field_by_number msg_or_enum_def, 2 + nsec = Google::Protobuf::FFI::MessageValue.new + nsec[:int32_val] = value.tv_nsec + raise "Should be impossible" unless Google::Protobuf::FFI.set_message_field new_message, nsec_field_def, nsec, arena + return_value[:msg_val] = new_message + when :Duration + raise TypeError.new "Invalid type #{value.class} to assign to submessage field '#{name}'." unless value.kind_of? Numeric + new_message = Google::Protobuf::FFI.new_message_from_def Google::Protobuf::FFI.get_mini_table(msg_or_enum_def), arena + sec = Google::Protobuf::FFI::MessageValue.new + sec[:int64_val] = value + sec_field_def = Google::Protobuf::FFI.get_field_by_number msg_or_enum_def, 1 + raise "Should be impossible" unless Google::Protobuf::FFI.set_message_field new_message, sec_field_def, sec, arena + nsec_field_def = Google::Protobuf::FFI.get_field_by_number msg_or_enum_def, 2 + nsec = Google::Protobuf::FFI::MessageValue.new + nsec[:int32_val] = ((value.to_f - value.to_i) * 1000000000).round + raise "Should be impossible" unless Google::Protobuf::FFI.set_message_field new_message, nsec_field_def, nsec, arena + return_value[:msg_val] = new_message + else + raise TypeError.new "Invalid type #{value.class} to assign to submessage field '#{name}'." + end + else + arena.fuse(value.instance_variable_get(:@arena)) + return_value[:msg_val] = value.instance_variable_get :@msg + end + when :enum + return_value[:int32_val] = case value + when Numeric + value.to_i + when String, Symbol + enum_number = EnumDescriptor.send(:lookup_name, msg_or_enum_def, value.to_s) + #TODO add the bad value to the error message after tests pass + raise RangeError.new "Unknown symbol value for enum field '#{name}'." if enum_number.nil? + enum_number + else + raise TypeError.new "Expected number or symbol type for enum field '#{name}'." + end + #TODO After all tests pass, improve error message across integer type by including actual offending value + when :int32 + raise TypeError.new "Expected number type for integral field '#{name}' (given #{value.class})." unless value.is_a? Numeric + raise RangeError.new "Non-integral floating point value assigned to integer field '#{name}' (given #{value.class})." if value.floor != value + raise RangeError.new "Value assigned to int32 field '#{name}' (given #{value.class}) with more than 32-bits." unless value.to_i.bit_length < 32 + return_value[:int32_val] = value.to_i + when :uint32 + raise TypeError.new "Expected number type for integral field '#{name}' (given #{value.class})." unless value.is_a? Numeric + raise RangeError.new "Non-integral floating point value assigned to integer field '#{name}' (given #{value.class})." if value.floor != value + raise RangeError.new "Assigning negative value to unsigned integer field '#{name}' (given #{value.class})." if value < 0 + raise RangeError.new "Value assigned to uint32 field '#{name}' (given #{value.class}) with more than 32-bits." unless value.to_i.bit_length < 33 + return_value[:uint32_val] = value.to_i + when :int64 + raise TypeError.new "Expected number type for integral field '#{name}' (given #{value.class})." unless value.is_a? Numeric + raise RangeError.new "Non-integral floating point value assigned to integer field '#{name}' (given #{value.class})." if value.floor != value + raise RangeError.new "Value assigned to int64 field '#{name}' (given #{value.class}) with more than 64-bits." unless value.to_i.bit_length < 64 + return_value[:int64_val] = value.to_i + when :uint64 + raise TypeError.new "Expected number type for integral field '#{name}' (given #{value.class})." unless value.is_a? Numeric + raise RangeError.new "Non-integral floating point value assigned to integer field '#{name}' (given #{value.class})." if value.floor != value + raise RangeError.new "Assigning negative value to unsigned integer field '#{name}' (given #{value.class})." if value < 0 + raise RangeError.new "Value assigned to uint64 field '#{name}' (given #{value.class}) with more than 64-bits." unless value.to_i.bit_length < 65 + return_value[:uint64_val] = value.to_i + else + raise RuntimeError.new "Unsupported type #{c_type}" + end + return_value + end + + ## + # Safe to call without an arena if the caller has checked that c_type + # is not :message. + # @param message_value [Google::Protobuf::FFI::MessageValue] Value to be converted. + # @param c_type [Google::Protobuf::FFI::CType] Enum representing the type of message_value + # @param msg_or_enum_def [::FFI::Pointer] Pointer to the MsgDef or EnumDef definition + # @param arena [Google::Protobuf::Internal::Arena] Arena to create Message instances, if needed + def convert_upb_to_ruby(message_value, c_type, msg_or_enum_def = nil, arena = nil) + throw TypeError.new "Expected MessageValue but got #{message_value.class}" unless message_value.is_a? Google::Protobuf::FFI::MessageValue + + case c_type + when :bool + message_value[:bool_val] + when :int32 + message_value[:int32_val] + when :uint32 + message_value[:uint32_val] + when :double + message_value[:double_val] + when :int64 + message_value[:int64_val] + when :uint64 + message_value[:uint64_val] + when :string + if message_value[:str_val][:size].zero? + "" + else + message_value[:str_val][:data].read_string_length(message_value[:str_val][:size]).force_encoding("UTF-8").freeze + end + when :bytes + if message_value[:str_val][:size].zero? + "" + else + message_value[:str_val][:data].read_string_length(message_value[:str_val][:size]).force_encoding("ASCII-8BIT").freeze + end + when :float + message_value[:float_val] + when :enum + EnumDescriptor.send(:lookup_value, msg_or_enum_def, message_value[:int32_val]) || message_value[:int32_val] + when :message + raise "Null Arena for message" if arena.nil? + Descriptor.send(:get_message, message_value[:msg_val], msg_or_enum_def, arena) + else + raise RuntimeError.new "Unexpected type #{c_type}" + end + end + + def to_h_internal(msg, message_descriptor) + return nil if msg.nil? or msg.null? + hash = {} + iter = ::FFI::MemoryPointer.new(:size_t, 1) + iter.write(:size_t, Google::Protobuf::FFI::Upb_Message_Begin) + message_value = Google::Protobuf::FFI::MessageValue.new + field_def_ptr = ::FFI::MemoryPointer.new :pointer + + while Google::Protobuf::FFI::message_next(msg, message_descriptor, nil, field_def_ptr, message_value, iter) do + field_descriptor = FieldDescriptor.from_native field_def_ptr.get_pointer(0) + + if field_descriptor.map? + hash_entry = map_create_hash(message_value[:map_val], field_descriptor) + elsif field_descriptor.repeated? + hash_entry = repeated_field_create_array(message_value[:array_val], field_descriptor, field_descriptor.type) + else + hash_entry = scalar_create_hash(message_value, field_descriptor.type, field_descriptor: field_descriptor) + end + + hash[field_descriptor.name.to_sym] = hash_entry + end + + hash + end + + def map_create_hash(map_ptr, field_descriptor) + return {} if map_ptr.nil? or map_ptr.null? + return_value = {} + + message_descriptor = field_descriptor.send(:subtype) + key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1) + key_field_type = Google::Protobuf::FFI.get_type(key_field_def) + + value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2) + value_field_type = Google::Protobuf::FFI.get_type(value_field_def) + + iter = ::FFI::MemoryPointer.new(:size_t, 1) + iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin) + while Google::Protobuf::FFI.map_next(map_ptr, iter) do + iter_size_t = iter.read(:size_t) + key_message_value = Google::Protobuf::FFI.map_key(map_ptr, iter_size_t) + value_message_value = Google::Protobuf::FFI.map_value(map_ptr, iter_size_t) + hash_key = convert_upb_to_ruby(key_message_value, key_field_type) + hash_value = scalar_create_hash(value_message_value, value_field_type, msg_or_enum_descriptor: value_field_def.subtype) + return_value[hash_key] = hash_value + end + return_value + end + + def repeated_field_create_array(array, field_descriptor, type) + return_value = [] + n = (array.nil? || array.null?) ? 0 : Google::Protobuf::FFI.array_size(array) + 0.upto(n - 1) do |i| + message_value = Google::Protobuf::FFI.get_msgval_at(array, i) + return_value << scalar_create_hash(message_value, type, field_descriptor: field_descriptor) + end + return_value + end + + # @param field_descriptor [FieldDescriptor] Descriptor of the field to convert to a hash. + def scalar_create_hash(message_value, type, field_descriptor: nil, msg_or_enum_descriptor: nil) + if [:message, :enum].include? type + if field_descriptor.nil? + if msg_or_enum_descriptor.nil? + raise "scalar_create_hash requires either a FieldDescriptor, MessageDescriptor, or EnumDescriptor as an argument, but received only nil" + end + else + msg_or_enum_descriptor = field_descriptor.subtype + end + if type == :message + to_h_internal(message_value[:msg_val], msg_or_enum_descriptor) + elsif type == :enum + convert_upb_to_ruby message_value, type, msg_or_enum_descriptor + end + else + convert_upb_to_ruby message_value, type + end + end + + def message_value_deep_copy(message_value, type, descriptor, arena) + raise unless message_value.is_a? Google::Protobuf::FFI::MessageValue + new_message_value = Google::Protobuf::FFI::MessageValue.new + case type + when :string, :bytes + # TODO - how important is it to still use arena malloc, versus using FFI MemoryPointers? + new_message_value[:str_val][:size] = message_value[:str_val][:size] + new_message_value[:str_val][:data] = Google::Protobuf::FFI.arena_malloc(arena, message_value[:str_val][:size]) + raise NoMemoryError.new "Allocation failed" if new_message_value[:str_val][:data].nil? or new_message_value[:str_val][:data].null? + Google::Protobuf::FFI.memcpy(new_message_value[:str_val][:data], message_value[:str_val][:data], message_value[:str_val][:size]) + when :message + new_message_value[:msg_val] = descriptor.msgclass.send(:deep_copy, message_value[:msg_val], arena).instance_variable_get(:@msg) + else + Google::Protobuf::FFI.memcpy(new_message_value.to_ptr, message_value.to_ptr, Google::Protobuf::FFI::MessageValue.size) + end + new_message_value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/pointer_helper.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/pointer_helper.rb new file mode 100755 index 0000000..fdf4df3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/pointer_helper.rb @@ -0,0 +1,36 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2023 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + module Internal + module PointerHelper + # Utility code to defensively walk the object graph from a file_def to + # the pool, and either retrieve the wrapper object for the given pointer + # or create one. Assumes that the caller is the wrapper class for the + # given pointer and that it implements `private_constructor`. + def descriptor_from_file_def(file_def, pointer = nil) + pointer = file_def if pointer.nil? + raise RuntimeError.new "FileDef is nil" if file_def.nil? + raise RuntimeError.new "FileDef is null" if file_def.null? + pool_def = Google::Protobuf::FFI.file_def_pool file_def + raise RuntimeError.new "PoolDef is nil" if pool_def.nil? + raise RuntimeError.new "PoolDef is null" if pool_def.null? + pool = Google::Protobuf::OBJECT_CACHE.get(pool_def.address) + raise "Cannot find pool in ObjectCache!" if pool.nil? + descriptor = pool.descriptor_class_by_def[pointer.address] + if descriptor.nil? + pool.descriptor_class_by_def[pointer.address] = private_constructor(pointer, pool) + else + descriptor + end + end + end + end + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/type_safety.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/type_safety.rb new file mode 100755 index 0000000..6cdb3e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/internal/type_safety.rb @@ -0,0 +1,25 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +# A to_native DataConverter method that raises an error if the value is not of the same type. +# Adapted from to https://www.varvet.com/blog/advanced-topics-in-ruby-ffi/ +module Google + module Protobuf + module Internal + module TypeSafety + def to_native(value, ctx = nil) + if value.kind_of?(self) or value.nil? + super + else + raise TypeError.new "Expected a kind of #{name}, was #{value.class}" + end + end + end + end + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/map.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/map.rb new file mode 100755 index 0000000..fc80609 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/map.rb @@ -0,0 +1,433 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class FFI + # Map + attach_function :map_clear, :upb_Map_Clear, [:Map], :void + attach_function :map_delete, :upb_Map_Delete, [:Map, MessageValue.by_value, MessageValue.by_ref], :bool + attach_function :map_get, :upb_Map_Get, [:Map, MessageValue.by_value, MessageValue.by_ref], :bool + attach_function :create_map, :upb_Map_New, [Internal::Arena, CType, CType], :Map + attach_function :map_size, :upb_Map_Size, [:Map], :size_t + attach_function :map_set, :upb_Map_Set, [:Map, MessageValue.by_value, MessageValue.by_value, Internal::Arena], :bool + attach_function :map_freeze, :upb_Map_Freeze, [:Map, MiniTable.by_ref], :void + attach_function :map_frozen?, :upb_Map_IsFrozen, [:Map], :bool + + # MapIterator + attach_function :map_next, :upb_MapIterator_Next, [:Map, :pointer], :bool + attach_function :map_done, :upb_MapIterator_Done, [:Map, :size_t], :bool + attach_function :map_key, :upb_MapIterator_Key, [:Map, :size_t], MessageValue.by_value + attach_function :map_value, :upb_MapIterator_Value, [:Map, :size_t], MessageValue.by_value + end + class Map + include Enumerable + ## + # call-seq: + # Map.new(key_type, value_type, value_typeclass = nil, init_hashmap = {}) + # => new map + # + # Allocates a new Map container. This constructor may be called with 2, 3, or 4 + # arguments. The first two arguments are always present and are symbols (taking + # on the same values as field-type symbols in message descriptors) that + # indicate the type of the map key and value fields. + # + # The supported key types are: :int32, :int64, :uint32, :uint64, :bool, + # :string, :bytes. + # + # The supported value types are: :int32, :int64, :uint32, :uint64, :bool, + # :string, :bytes, :enum, :message. + # + # The third argument, value_typeclass, must be present if value_type is :enum + # or :message. As in RepeatedField#new, this argument must be a message class + # (for :message) or enum module (for :enum). + # + # The last argument, if present, provides initial content for map. Note that + # this may be an ordinary Ruby hashmap or another Map instance with identical + # key and value types. Also note that this argument may be present whether or + # not value_typeclass is present (and it is unambiguously separate from + # value_typeclass because value_typeclass's presence is strictly determined by + # value_type). The contents of this initial hashmap or Map instance are + # shallow-copied into the new Map: the original map is unmodified, but + # references to underlying objects will be shared if the value type is a + # message type. + def self.new(key_type, value_type, value_typeclass = nil, init_hashmap = {}) + instance = allocate + # TODO This argument mangling doesn't agree with the type signature, + # but does align with the text of the comments and is required to make unit tests pass. + if init_hashmap.empty? and ![:enum, :message].include?(value_type) + init_hashmap = value_typeclass + value_typeclass = nil + end + instance.send(:initialize, key_type, value_type, value_type_class: value_typeclass, initial_values: init_hashmap) + instance + end + + ## + # call-seq: + # Map.keys => [list_of_keys] + # + # Returns the list of keys contained in the map, in unspecified order. + def keys + return_value = [] + internal_iterator do |iterator| + key_message_value = Google::Protobuf::FFI.map_key(@map_ptr, iterator) + return_value << convert_upb_to_ruby(key_message_value, key_type) + end + return_value + end + + ## + # call-seq: + # Map.values => [list_of_values] + # + # Returns the list of values contained in the map, in unspecified order. + def values + return_value = [] + internal_iterator do |iterator| + value_message_value = Google::Protobuf::FFI.map_value(@map_ptr, iterator) + return_value << convert_upb_to_ruby(value_message_value, value_type, descriptor, arena) + end + return_value + end + + ## + # call-seq: + # Map.[](key) => value + # + # Accesses the element at the given key. Throws an exception if the key type is + # incorrect. Returns nil when the key is not present in the map. + def [](key) + value = Google::Protobuf::FFI::MessageValue.new + key_message_value = convert_ruby_to_upb(key, arena, key_type, nil) + if Google::Protobuf::FFI.map_get(@map_ptr, key_message_value, value) + convert_upb_to_ruby(value, value_type, descriptor, arena) + end + end + + ## + # call-seq: + # Map.[]=(key, value) => value + # + # Inserts or overwrites the value at the given key with the given new value. + # Throws an exception if the key type is incorrect. Returns the new value that + # was just inserted. + def []=(key, value) + raise FrozenError.new "can't modify frozen #{self.class}" if frozen? + key_message_value = convert_ruby_to_upb(key, arena, key_type, nil) + value_message_value = convert_ruby_to_upb(value, arena, value_type, descriptor) + Google::Protobuf::FFI.map_set(@map_ptr, key_message_value, value_message_value, arena) + value + end + + def has_key?(key) + key_message_value = convert_ruby_to_upb(key, arena, key_type, nil) + Google::Protobuf::FFI.map_get(@map_ptr, key_message_value, nil) + end + + ## + # call-seq: + # Map.delete(key) => old_value + # + # Deletes the value at the given key, if any, returning either the old value or + # nil if none was present. Throws an exception if the key is of the wrong type. + def delete(key) + raise FrozenError.new "can't modify frozen #{self.class}" if frozen? + value = Google::Protobuf::FFI::MessageValue.new + key_message_value = convert_ruby_to_upb(key, arena, key_type, nil) + if Google::Protobuf::FFI.map_delete(@map_ptr, key_message_value, value) + convert_upb_to_ruby(value, value_type, descriptor, arena) + else + nil + end + end + + def clear + raise FrozenError.new "can't modify frozen #{self.class}" if frozen? + Google::Protobuf::FFI.map_clear(@map_ptr) + nil + end + + def length + Google::Protobuf::FFI.map_size(@map_ptr) + end + alias size length + + ## + # Is this object frozen? + # Returns true if either this Ruby wrapper or the underlying + # representation are frozen. Freezes the wrapper if the underlying + # representation is already frozen but this wrapper isn't. + def frozen? + unless Google::Protobuf::FFI.map_frozen? @map_ptr + raise RuntimeError.new "Ruby frozen Map with mutable representation" if super + return false + end + method(:freeze).super_method.call unless super + true + end + + ## + # Freezes the map object. We have to intercept this so we can freeze the + # underlying representation, not just the Ruby wrapper. Returns self. + def freeze + if method(:frozen?).super_method.call + unless Google::Protobuf::FFI.map_frozen? @map_ptr + raise RuntimeError.new "Underlying representation of map still mutable despite frozen wrapper" + end + return self + end + unless Google::Protobuf::FFI.map_frozen? @map_ptr + mini_table = (value_type == :message) ? Google::Protobuf::FFI.get_mini_table(@descriptor) : nil + Google::Protobuf::FFI.map_freeze(@map_ptr, mini_table) + end + super + end + + ## + # call-seq: + # Map.dup => new_map + # + # Duplicates this map with a shallow copy. References to all non-primitive + # element objects (e.g., submessages) are shared. + def dup + internal_dup + end + alias clone dup + + ## + # call-seq: + # Map.==(other) => boolean + # + # Compares this map to another. Maps are equal if they have identical key sets, + # and for each key, the values in both maps compare equal. Elements are + # compared as per normal Ruby semantics, by calling their :== methods (or + # performing a more efficient comparison for primitive types). + # + # Maps with dissimilar key types or value types/typeclasses are never equal, + # even if value comparison (for example, between integers and floats) would + # have otherwise indicated that every element has equal value. + def ==(other) + if other.is_a? Hash + other = self.class.send(:private_constructor, key_type, value_type, descriptor, initial_values: other) + elsif !other.is_a? Google::Protobuf::Map + return false + end + + return true if object_id == other.object_id + return false if key_type != other.send(:key_type) or value_type != other.send(:value_type) or descriptor != other.send(:descriptor) or length != other.length + other_map_ptr = other.send(:map_ptr) + each_msg_val do |key_message_value, value_message_value| + other_value = Google::Protobuf::FFI::MessageValue.new + return false unless Google::Protobuf::FFI.map_get(other_map_ptr, key_message_value, other_value) + return false unless Google::Protobuf::FFI.message_value_equal(value_message_value, other_value, value_type, descriptor) + end + true + end + + def hash + return_value = 0 + each_msg_val do |key_message_value, value_message_value| + return_value += Google::Protobuf::FFI.message_value_hash(key_message_value, key_type, nil, 0) + return_value += Google::Protobuf::FFI.message_value_hash(value_message_value, value_type, descriptor, 0) + end + return_value + end + + ## + # call-seq: + # Map.to_h => {} + # + # Returns a Ruby Hash object containing all the values within the map + def to_h + return {} if map_ptr.nil? or map_ptr.null? + return_value = {} + each_msg_val do |key_message_value, value_message_value| + hash_key = convert_upb_to_ruby(key_message_value, key_type) + hash_value = scalar_create_hash(value_message_value, value_type, msg_or_enum_descriptor: descriptor) + return_value[hash_key] = hash_value + end + return_value + end + + def inspect + key_value_pairs = [] + each_msg_val do |key_message_value, value_message_value| + key_string = convert_upb_to_ruby(key_message_value, key_type).inspect + if value_type == :message + sub_msg_descriptor = Google::Protobuf::FFI.get_subtype_as_message(descriptor) + value_string = sub_msg_descriptor.msgclass.send(:inspect_internal, value_message_value[:msg_val]) + else + value_string = convert_upb_to_ruby(value_message_value, value_type, descriptor).inspect + end + key_value_pairs << "#{key_string}=>#{value_string}" + end + "{#{key_value_pairs.join(", ")}}" + end + + ## + # call-seq: + # Map.merge(other_map) => map + # + # Copies key/value pairs from other_map into a copy of this map. If a key is + # set in other_map and this map, the value from other_map overwrites the value + # in the new copy of this map. Returns the new copy of this map with merged + # contents. + def merge(other) + internal_merge(other) + end + + ## + # call-seq: + # Map.each(&block) + # + # Invokes &block on each |key, value| pair in the map, in unspecified order. + # Note that Map also includes Enumerable; map thus acts like a normal Ruby + # sequence. + def each &block + each_msg_val do |key_message_value, value_message_value| + key_value = convert_upb_to_ruby(key_message_value, key_type) + value_value = convert_upb_to_ruby(value_message_value, value_type, descriptor, arena) + yield key_value, value_value + end + nil + end + + private + attr :arena, :map_ptr, :key_type, :value_type, :descriptor, :name + + include Google::Protobuf::Internal::Convert + + def internal_iterator + iter = ::FFI::MemoryPointer.new(:size_t, 1) + iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin) + while Google::Protobuf::FFI.map_next(@map_ptr, iter) do + iter_size_t = iter.read(:size_t) + yield iter_size_t + end + end + + def each_msg_val &block + internal_iterator do |iterator| + key_message_value = Google::Protobuf::FFI.map_key(@map_ptr, iterator) + value_message_value = Google::Protobuf::FFI.map_value(@map_ptr, iterator) + yield key_message_value, value_message_value + end + end + + def internal_dup + instance = self.class.send(:private_constructor, key_type, value_type, descriptor, arena: arena) + new_map_ptr = instance.send(:map_ptr) + each_msg_val do |key_message_value, value_message_value| + Google::Protobuf::FFI.map_set(new_map_ptr, key_message_value, value_message_value, arena) + end + instance + end + + def internal_merge_into_self(other) + case other + when Hash + other.each do |key, value| + key_message_value = convert_ruby_to_upb(key, arena, key_type, nil) + value_message_value = convert_ruby_to_upb(value, arena, value_type, descriptor) + Google::Protobuf::FFI.map_set(@map_ptr, key_message_value, value_message_value, arena) + end + when Google::Protobuf::Map + unless key_type == other.send(:key_type) and value_type == other.send(:value_type) and descriptor == other.descriptor + raise ArgumentError.new "Attempt to merge Map with mismatching types" #TODO Improve error message by adding type information + end + arena.fuse(other.send(:arena)) + iter = ::FFI::MemoryPointer.new(:size_t, 1) + iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin) + other.send(:each_msg_val) do |key_message_value, value_message_value| + Google::Protobuf::FFI.map_set(@map_ptr, key_message_value, value_message_value, arena) + end + else + raise ArgumentError.new "Unknown type merging into Map" #TODO improve this error message by including type information + end + self + end + + def internal_merge(other) + internal_dup.internal_merge_into_self(other) + end + + def initialize(key_type, value_type, value_type_class: nil, initial_values: nil, arena: nil, map: nil, descriptor: nil, name: nil) + @name = name || 'Map' + + unless [:int32, :int64, :uint32, :uint64, :bool, :string, :bytes].include? key_type + raise ArgumentError.new "Invalid key type for map." #TODO improve error message to include what type was passed + end + @key_type = key_type + + unless [:int32, :int64, :uint32, :uint64, :bool, :string, :bytes, :enum, :message].include? value_type + raise ArgumentError.new "Invalid value type for map." #TODO improve error message to include what type was passed + end + @value_type = value_type + + if !descriptor.nil? + raise ArgumentError "Expected descriptor to be a Descriptor or EnumDescriptor" unless [EnumDescriptor, Descriptor].include? descriptor.class + @descriptor = descriptor + elsif [:message, :enum].include? value_type + raise ArgumentError.new "Expected at least 3 arguments for message/enum." if value_type_class.nil? + descriptor = value_type_class.respond_to?(:descriptor) ? value_type_class.descriptor : nil + raise ArgumentError.new "Type class #{value_type_class} has no descriptor. Please pass a class or enum as returned by the DescriptorPool." if descriptor.nil? + @descriptor = descriptor + else + @descriptor = nil + end + + @arena = arena || Google::Protobuf::FFI.create_arena + @map_ptr = map || Google::Protobuf::FFI.create_map(@arena, @key_type, @value_type) + + internal_merge_into_self(initial_values) unless initial_values.nil? + + # Should always be the last expression of the initializer to avoid + # leaking references to this object before construction is complete. + OBJECT_CACHE.try_add(@map_ptr.address, self) + end + + ## + # Constructor that uses the type information from the given + # FieldDescriptor to configure the new Map instance. + # @param field [FieldDescriptor] Type information for the new Map + # @param arena [Arena] Owning message's arena + # @param value [Hash|Map] Initial value + # @param map [::FFI::Pointer] Existing upb_Map + def self.construct_for_field(field, arena: nil, value: nil, map: nil) + raise ArgumentError.new "Expected Hash object as initializer value for map field '#{field.name}' (given #{value.class})." unless value.nil? or value.is_a? Hash + instance = allocate + raise ArgumentError.new "Expected field with type :message, instead got #{field.class}" unless field.type == :message + message_descriptor = field.send(:subtype) + key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1) + key_field_type = Google::Protobuf::FFI.get_type(key_field_def) + + value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2) + value_field_type = Google::Protobuf::FFI.get_type(value_field_def) + instance.send(:initialize, key_field_type, value_field_type, initial_values: value, name: field.name, arena: arena, map: map, descriptor: value_field_def.subtype) + instance + end + + def self.private_constructor(key_type, value_type, descriptor, initial_values: nil, arena: nil) + instance = allocate + instance.send(:initialize, key_type, value_type, descriptor: descriptor, initial_values: initial_values, arena: arena) + instance + end + + extend Google::Protobuf::Internal::Convert + + def self.deep_copy(map) + instance = allocate + instance.send(:initialize, map.send(:key_type), map.send(:value_type), descriptor: map.send(:descriptor)) + map.send(:each_msg_val) do |key_message_value, value_message_value| + Google::Protobuf::FFI.map_set(instance.send(:map_ptr), key_message_value, message_value_deep_copy(value_message_value, map.send(:value_type), map.send(:descriptor), instance.send(:arena)), instance.send(:arena)) + end + instance + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/message.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/message.rb new file mode 100755 index 0000000..3de3017 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/message.rb @@ -0,0 +1,783 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2023 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + + +# Decorates Descriptor with the `build_message_class` method that defines +# Message classes. +module Google + module Protobuf + class FFI + # Message + attach_function :clear_message_field, :upb_Message_ClearFieldByDef, [:Message, FieldDescriptor], :void + attach_function :get_message_value, :upb_Message_GetFieldByDef, [:Message, FieldDescriptor], MessageValue.by_value + attach_function :get_message_has, :upb_Message_HasFieldByDef, [:Message, FieldDescriptor], :bool + attach_function :set_message_field, :upb_Message_SetFieldByDef, [:Message, FieldDescriptor, MessageValue.by_value, Internal::Arena], :bool + attach_function :encode_message, :upb_Encode, [:Message, MiniTable.by_ref, :size_t, Internal::Arena, :pointer, :pointer], EncodeStatus + attach_function :json_decode_message_detecting_nonconformance, :upb_JsonDecodeDetectingNonconformance, [:binary_string, :size_t, :Message, Descriptor, :DefPool, :int, Internal::Arena, Status.by_ref], :int + attach_function :json_encode_message, :upb_JsonEncode, [:Message, Descriptor, :DefPool, :int, :binary_string, :size_t, Status.by_ref], :size_t + attach_function :decode_message, :upb_Decode, [:binary_string, :size_t, :Message, MiniTable.by_ref, :ExtensionRegistry, :int, Internal::Arena], DecodeStatus + attach_function :get_mutable_message, :upb_Message_Mutable, [:Message, FieldDescriptor, Internal::Arena], MutableMessageValue.by_value + attach_function :get_message_which_oneof, :upb_Message_WhichOneofByDef, [:Message, OneofDescriptor], FieldDescriptor + attach_function :message_discard_unknown, :upb_Message_DiscardUnknown, [:Message, Descriptor, :DefPool, :int], :bool + attach_function :message_next, :upb_Message_Next, [:Message, Descriptor, :DefPool, :FieldDefPointer, MessageValue.by_ref, :pointer], :bool + attach_function :message_freeze, :upb_Message_Freeze, [:Message, MiniTable.by_ref], :void + attach_function :message_frozen?, :upb_Message_IsFrozen, [:Message], :bool + + # MessageValue + attach_function :message_value_equal, :shared_Msgval_IsEqual, [MessageValue.by_value, MessageValue.by_value, CType, Descriptor], :bool + attach_function :message_value_hash, :shared_Msgval_GetHash, [MessageValue.by_value, CType, Descriptor, :uint64_t], :uint64_t + end + + class Descriptor + def build_message_class + descriptor = self + Class.new(Google::Protobuf::const_get(:AbstractMessage)) do + @descriptor = descriptor + class << self + attr_accessor :descriptor + private + attr_accessor :oneof_field_names + include ::Google::Protobuf::Internal::Convert + end + + alias original_method_missing method_missing + def method_missing(method_name, *args) + method_missing_internal method_name, *args, mode: :method_missing + end + + def respond_to_missing?(method_name, include_private = false) + method_missing_internal(method_name, mode: :respond_to_missing?) || super + end + + ## + # Public constructor. Automatically allocates from a new Arena. + def self.new(initial_value = nil) + instance = allocate + instance.send(:initialize, initial_value) + instance + end + + ## + # Is this object frozen? + # Returns true if either this Ruby wrapper or the underlying + # representation are frozen. Freezes the wrapper if the underlying + # representation is already frozen but this wrapper isn't. + def frozen? + unless Google::Protobuf::FFI.message_frozen? @msg + raise RuntimeError.new "Ruby frozen Message with mutable representation" if super + return false + end + method(:freeze).super_method.call unless super + true + end + + ## + # Freezes the map object. We have to intercept this so we can freeze the + # underlying representation, not just the Ruby wrapper. Returns self. + def freeze + if method(:frozen?).super_method.call + unless Google::Protobuf::FFI.message_frozen? @msg + raise RuntimeError.new "Underlying representation of message still mutable despite frozen wrapper" + end + return self + end + unless Google::Protobuf::FFI.message_frozen? @msg + Google::Protobuf::FFI.message_freeze(@msg, Google::Protobuf::FFI.get_mini_table(self.class.descriptor)) + end + super + end + + def dup + duplicate = self.class.private_constructor(@arena) + mini_table = Google::Protobuf::FFI.get_mini_table(self.class.descriptor) + size = mini_table[:size] + duplicate.instance_variable_get(:@msg).write_string_length(@msg.read_string_length(size), size) + duplicate + end + alias clone dup + + def eql?(other) + return false unless self.class === other + encoding_options = Google::Protobuf::FFI::Upb_Encode_Deterministic | Google::Protobuf::FFI::Upb_Encode_SkipUnknown + temporary_arena = Google::Protobuf::FFI.create_arena + mini_table = Google::Protobuf::FFI.get_mini_table(self.class.descriptor) + size_one = ::FFI::MemoryPointer.new(:size_t, 1) + encoding_one = ::FFI::MemoryPointer.new(:pointer, 1) + encoding_status = Google::Protobuf::FFI.encode_message(@msg, mini_table, encoding_options, temporary_arena, encoding_one.to_ptr, size_one) + raise ParseError.new "Error comparing messages due to #{encoding_status} while encoding LHS of `eql?()`" unless encoding_status == :Ok + + size_two = ::FFI::MemoryPointer.new(:size_t, 1) + encoding_two = ::FFI::MemoryPointer.new(:pointer, 1) + encoding_status = Google::Protobuf::FFI.encode_message(other.instance_variable_get(:@msg), mini_table, encoding_options, temporary_arena, encoding_two.to_ptr, size_two) + raise ParseError.new "Error comparing messages due to #{encoding_status} while encoding RHS of `eql?()`" unless encoding_status == :Ok + + if encoding_one.null? or encoding_two.null? + raise ParseError.new "Error comparing messages" + end + size_one.read(:size_t) == size_two.read(:size_t) and Google::Protobuf::FFI.memcmp(encoding_one.read(:pointer), encoding_two.read(:pointer), size_one.read(:size_t)).zero? + end + alias == eql? + + def hash + encoding_options = Google::Protobuf::FFI::Upb_Encode_Deterministic | Google::Protobuf::FFI::Upb_Encode_SkipUnknown + temporary_arena = Google::Protobuf::FFI.create_arena + mini_table_ptr = Google::Protobuf::FFI.get_mini_table(self.class.descriptor) + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + encoding = ::FFI::MemoryPointer.new(:pointer, 1) + encoding_status = Google::Protobuf::FFI.encode_message(@msg, mini_table_ptr, encoding_options, temporary_arena, encoding.to_ptr, size_ptr) + if encoding_status != :Ok or encoding.null? + raise ParseError.new "Error calculating hash" + end + encoding.read(:pointer).read_string(size_ptr.read(:size_t)).hash + end + + def to_h + to_h_internal @msg, self.class.descriptor + end + + ## + # call-seq: + # Message.inspect => string + # + # Returns a human-readable string representing this message. It will be + # formatted as "". Each + # field's value is represented according to its own #inspect method. + def inspect + self.class.inspect_internal @msg + end + + def to_s + self.inspect + end + + ## + # call-seq: + # Message.[](index) => value + # Accesses a field's value by field name. The provided field name + # should be a string. + def [](name) + raise TypeError.new "Expected String for name but got #{name.class}" unless name.is_a? String + index_internal name + end + + ## + # call-seq: + # Message.[]=(index, value) + # Sets a field's value by field name. The provided field name should + # be a string. + # @param name [String] Name of the field to be set + # @param value [Object] Value to set the field to + def []=(name, value) + raise TypeError.new "Expected String for name but got #{name.class}" unless name.is_a? String + index_assign_internal(value, name: name) + end + + ## + # call-seq: + # MessageClass.decode(data, options) => message + # + # Decodes the given data (as a string containing bytes in protocol buffers wire + # format) under the interpretation given by this message class's definition + # and returns a message object with the corresponding field values. + # @param data [String] Binary string in Protobuf wire format to decode + # @param options [Hash] options for the decoder + # @option options [Integer] :recursion_limit Set to maximum decoding depth for message (default is 64) + def self.decode(data, options = {}) + raise ArgumentError.new "Expected hash arguments." unless options.is_a? Hash + raise ArgumentError.new "Expected string for binary protobuf data." unless data.is_a? String + decoding_options = 0 + depth = options[:recursion_limit] + + if depth.is_a? Numeric + decoding_options |= Google::Protobuf::FFI.decode_max_depth(depth.to_i) + end + + message = new + mini_table_ptr = Google::Protobuf::FFI.get_mini_table(message.class.descriptor) + status = Google::Protobuf::FFI.decode_message( + data, + data.bytesize, + message.instance_variable_get(:@msg), + mini_table_ptr, + Google::Protobuf::FFI.get_extension_registry(message.class.descriptor.send(:pool).descriptor_pool), + decoding_options, + message.instance_variable_get(:@arena) + ) + raise ParseError.new "Error occurred during parsing" unless status == :Ok + message + end + + ## + # call-seq: + # MessageClass.encode(msg, options) => bytes + # + # Encodes the given message object to its serialized form in protocol buffers + # wire format. + # @param options [Hash] options for the encoder + # @option options [Integer] :recursion_limit Set to maximum encoding depth for message (default is 64) + def self.encode(message, options = {}) + raise ArgumentError.new "Message of wrong type." unless message.is_a? self + raise ArgumentError.new "Expected hash arguments." unless options.is_a? Hash + + encoding_options = 0 + depth = options[:recursion_limit] + + if depth.is_a? Numeric + encoding_options |= Google::Protobuf::FFI.decode_max_depth(depth.to_i) + end + + encode_internal(message.instance_variable_get(:@msg), encoding_options) do |encoding, size, _| + if encoding.nil? or encoding.null? + raise RuntimeError.new "Exceeded maximum depth (possibly cycle)" + else + encoding.read_string_length(size).force_encoding("ASCII-8BIT").freeze + end + end + end + + ## + # all-seq: + # MessageClass.decode_json(data, options = {}) => message + # + # Decodes the given data (as a string containing bytes in protocol buffers wire + # format) under the interpretation given by this message class's definition + # and returns a message object with the corresponding field values. + # + # @param options [Hash] options for the decoder + # @option options [Boolean] :ignore_unknown_fields Set true to ignore unknown fields (default is to raise an error) + # @return [Message] + def self.decode_json(data, options = {}) + decoding_options = 0 + unless options.is_a? Hash + if options.respond_to? :to_h + options = options.to_h + else + #TODO can this error message be improve to include what was received? + raise ArgumentError.new "Expected hash arguments" + end + end + raise ArgumentError.new "Expected string for JSON data." unless data.is_a? String + raise RuntimeError.new "Cannot parse a wrapper directly" if descriptor.send(:wrapper?) + + if options[:ignore_unknown_fields] + decoding_options |= Google::Protobuf::FFI::Upb_JsonDecode_IgnoreUnknown + end + + message = new + pool_def = message.class.descriptor.instance_variable_get(:@descriptor_pool).descriptor_pool + status = Google::Protobuf::FFI::Status.new + result = Google::Protobuf::FFI.json_decode_message_detecting_nonconformance(data, data.bytesize, message.instance_variable_get(:@msg), message.class.descriptor, pool_def, decoding_options, message.instance_variable_get(:@arena), status) + case result + when Google::Protobuf::FFI::Upb_JsonDecodeResult_Error + raise ParseError.new "Error occurred during parsing: #{Google::Protobuf::FFI.error_message(status)}" + end + message + end + + def self.encode_json(message, options = {}) + encoding_options = 0 + unless options.is_a? Hash + if options.respond_to? :to_h + options = options.to_h + else + #TODO can this error message be improve to include what was received? + raise ArgumentError.new "Expected hash arguments" + end + end + + if options[:preserve_proto_fieldnames] + encoding_options |= Google::Protobuf::FFI::Upb_JsonEncode_UseProtoNames + end + if options[:emit_defaults] + encoding_options |= Google::Protobuf::FFI::Upb_JsonEncode_EmitDefaults + end + if options[:format_enums_as_integers] + encoding_options |= Google::Protobuf::FFI::Upb_JsonEncode_FormatEnumsAsIntegers + end + + buffer_size = 1024 + buffer = ::FFI::MemoryPointer.new(:char, buffer_size) + status = Google::Protobuf::FFI::Status.new + msg = message.instance_variable_get(:@msg) + pool_def = message.class.descriptor.instance_variable_get(:@descriptor_pool).descriptor_pool + size = Google::Protobuf::FFI::json_encode_message(msg, message.class.descriptor, pool_def, encoding_options, buffer, buffer_size, status) + unless status[:ok] + raise ParseError.new "Error occurred during encoding: #{Google::Protobuf::FFI.error_message(status)}" + end + + if size >= buffer_size + buffer_size = size + 1 + buffer = ::FFI::MemoryPointer.new(:char, buffer_size) + status.clear + size = Google::Protobuf::FFI::json_encode_message(msg, message.class.descriptor, pool_def, encoding_options, buffer, buffer_size, status) + unless status[:ok] + raise ParseError.new "Error occurred during encoding: #{Google::Protobuf::FFI.error_message(status)}" + end + if size >= buffer_size + raise ParseError.new "Inconsistent JSON encoding sizes - was #{buffer_size - 1}, now #{size}" + end + end + + buffer.read_string_length(size).force_encoding("UTF-8").freeze + end + + private + # Implementation details below are subject to breaking changes without + # warning and are intended for use only within the gem. + + include Google::Protobuf::Internal::Convert + + ## + # Checks ObjectCache for a sentinel empty frozen Map of the key and + # value types matching the field descriptor's MessageDef and returns + # the cache entry. If an entry is not found, one is created and added + # to the cache keyed by the MessageDef pointer first. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def empty_frozen_map(field_descriptor) + sub_message_def = Google::Protobuf::FFI.get_subtype_as_message field_descriptor + frozen_map = OBJECT_CACHE.get sub_message_def + if frozen_map.nil? + frozen_map = Google::Protobuf::Map.send(:construct_for_field, field_descriptor) + OBJECT_CACHE.try_add(sub_message_def, frozen_map.freeze) + end + raise "Empty Frozen Map is not frozen" unless frozen_map.frozen? + frozen_map + end + + ## + # Returns a frozen Map instance for the given field. If the message + # already has a value for that field, it is used. If not, a sentinel + # (per FieldDescriptor) empty frozen Map is returned instead. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def frozen_map_from_field_descriptor(field_descriptor) + message_value = Google::Protobuf::FFI.get_message_value @msg, field_descriptor + return empty_frozen_map field_descriptor if message_value[:map_val].null? + get_map_field(message_value[:map_val], field_descriptor).freeze + end + + ## + # Returns a Map instance for the given field. If the message is frozen + # the return value is also frozen. If not, a mutable instance is + # returned instead. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def map_from_field_descriptor(field_descriptor) + return frozen_map_from_field_descriptor field_descriptor if frozen? + mutable_message_value = Google::Protobuf::FFI.get_mutable_message @msg, field_descriptor, @arena + get_map_field(mutable_message_value[:map], field_descriptor) + end + + ## + # Checks ObjectCache for a sentinel empty frozen RepeatedField of the + # value type matching the field descriptor's MessageDef and returns + # the cache entry. If an entry is not found, one is created and added + # to the cache keyed by the MessageDef pointer first. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def empty_frozen_repeated_field(field_descriptor) + sub_message_def = Google::Protobuf::FFI.get_subtype_as_message field_descriptor + frozen_repeated_field = OBJECT_CACHE.get sub_message_def + if frozen_repeated_field.nil? + frozen_repeated_field = Google::Protobuf::RepeatedField.send(:construct_for_field, field_descriptor) + OBJECT_CACHE.try_add(sub_message_def, frozen_repeated_field.freeze) + end + raise "Empty frozen RepeatedField is not frozen" unless frozen_repeated_field.frozen? + frozen_repeated_field + end + + ## + # Returns a frozen RepeatedField instance for the given field. If the + # message already has a value for that field, it is used. If not, a + # sentinel (per FieldDescriptor) empty frozen RepeatedField is + # returned instead. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def frozen_repeated_field_from_field_descriptor(field_descriptor) + message_value = Google::Protobuf::FFI.get_message_value @msg, field_descriptor + return empty_frozen_repeated_field field_descriptor if message_value[:array_val].null? + get_repeated_field(message_value[:array_val], field_descriptor).freeze + end + + ## + # Returns a RepeatedField instance for the given field. If the message + # is frozen the return value is also frozen. If not, a mutable + # instance is returned instead. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def repeated_field_from_field_descriptor(field_descriptor) + return frozen_repeated_field_from_field_descriptor field_descriptor if frozen? + mutable_message_value = Google::Protobuf::FFI.get_mutable_message @msg, field_descriptor, @arena + get_repeated_field(mutable_message_value[:array], field_descriptor) + end + + ## + # Returns a Message instance for the given field. If the message + # is frozen nil is always returned. Otherwise, a mutable instance is + # returned instead. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def message_from_field_descriptor(field_descriptor) + return nil if frozen? + return nil unless Google::Protobuf::FFI.get_message_has @msg, field_descriptor + mutable_message = Google::Protobuf::FFI.get_mutable_message @msg, field_descriptor, @arena + sub_message = mutable_message[:msg] + sub_message_def = Google::Protobuf::FFI.get_subtype_as_message field_descriptor + Descriptor.send(:get_message, sub_message, sub_message_def, @arena) + end + + ## + # Returns a scalar value for the given field. If the message + # is frozen the return value is also frozen. + # @param field_descriptor [FieldDescriptor] Field to retrieve. + def scalar_from_field_descriptor(field_descriptor) + c_type = field_descriptor.send(:c_type) + message_value = Google::Protobuf::FFI.get_message_value @msg, field_descriptor + msg_or_enum_def = c_type == :enum ? Google::Protobuf::FFI.get_subtype_as_enum(field_descriptor) : nil + return_value = convert_upb_to_ruby message_value, c_type, msg_or_enum_def + frozen? ? return_value.freeze : return_value + end + + ## + # Dynamically define accessors methods for every field of @descriptor. + # Methods with names that conflict with existing methods are skipped. + def self.setup_accessors! + @descriptor.each do |field_descriptor| + field_name = field_descriptor.name + unless instance_methods(true).include?(field_name.to_sym) + # Dispatching to either index_internal or get_field is logically + # correct, but slightly slower due to having to perform extra + # lookups on each invocation rather than doing it once here. + if field_descriptor.map? + define_method(field_name) do + map_from_field_descriptor field_descriptor + end + elsif field_descriptor.repeated? + define_method(field_name) do + repeated_field_from_field_descriptor field_descriptor + end + elsif field_descriptor.sub_message? + define_method(field_name) do + message_from_field_descriptor field_descriptor + end + else + define_method(field_name) do + scalar_from_field_descriptor field_descriptor + end + end + define_method("#{field_name}=") do |value| + index_assign_internal(value, field_descriptor: field_descriptor) + end + define_method("clear_#{field_name}") do + clear_internal(field_descriptor) + end + if field_descriptor.type == :enum + if field_descriptor.repeated? + define_method("#{field_name}_const") do + return_value = [] + repeated_field_from_field_descriptor(field_descriptor).send(:each_msg_val) do |msg_val| + return_value << msg_val[:int32_val] + end + return_value + end + else + define_method("#{field_name}_const") do + message_value = Google::Protobuf::FFI.get_message_value @msg, field_descriptor + message_value[:int32_val] + end + end + end + if !field_descriptor.repeated? and field_descriptor.wrapper? + define_method("#{field_name}_as_value") do + get_field(field_descriptor, unwrap: true) + end + define_method("#{field_name}_as_value=") do |value| + if value.nil? + clear_internal(field_descriptor) + else + index_assign_internal(value, field_descriptor: field_descriptor, wrap: true) + end + end + end + if field_descriptor.has_presence? + define_method("has_#{field_name}?") do + Google::Protobuf::FFI.get_message_has(@msg, field_descriptor) + end + end + end + end + end + + ## + # Dynamically define accessors methods for every OneOf field of + # @descriptor. + def self.setup_oneof_accessors! + @oneof_field_names = [] + @descriptor.each_oneof do |oneof_descriptor| + self.add_oneof_accessors_for! oneof_descriptor + end + end + + ## + # Dynamically define accessors methods for the given OneOf field. + # Methods with names that conflict with existing methods are skipped. + # @param oneof_descriptor [OneofDescriptor] Field to create accessors + # for. + def self.add_oneof_accessors_for!(oneof_descriptor) + field_name = oneof_descriptor.name.to_sym + @oneof_field_names << field_name + unless instance_methods(true).include?(field_name) + define_method(field_name) do + field_descriptor = Google::Protobuf::FFI.get_message_which_oneof(@msg, oneof_descriptor) + if field_descriptor.nil? + return + else + return field_descriptor.name.to_sym + end + end + define_method("clear_#{field_name}") do + field_descriptor = Google::Protobuf::FFI.get_message_which_oneof(@msg, oneof_descriptor) + unless field_descriptor.nil? + clear_internal(field_descriptor) + end + end + define_method("has_#{field_name}?") do + !Google::Protobuf::FFI.get_message_which_oneof(@msg, oneof_descriptor).nil? + end + end + end + + setup_accessors! + setup_oneof_accessors! + + def self.private_constructor(arena, msg: nil, initial_value: nil) + instance = allocate + instance.send(:initialize, initial_value, arena, msg) + instance + end + + def self.inspect_field(field_descriptor, c_type, message_value) + if field_descriptor.sub_message? + sub_msg_descriptor = Google::Protobuf::FFI.get_subtype_as_message(field_descriptor) + sub_msg_descriptor.msgclass.send(:inspect_internal, message_value[:msg_val]) + else + convert_upb_to_ruby(message_value, c_type, field_descriptor.subtype).inspect + end + end + + # @param msg [::FFI::Pointer] Pointer to the Message + def self.inspect_internal(msg) + field_output = [] + descriptor.each do |field_descriptor| + next if field_descriptor.has_presence? && !Google::Protobuf::FFI.get_message_has(msg, field_descriptor) + if field_descriptor.map? + # TODO Adapted - from map#each_msg_val and map#inspect- can this be refactored to reduce echo without introducing a arena allocation? + message_descriptor = field_descriptor.subtype + key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1) + key_field_type = Google::Protobuf::FFI.get_type(key_field_def) + + value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2) + value_field_type = Google::Protobuf::FFI.get_type(value_field_def) + + message_value = Google::Protobuf::FFI.get_message_value(msg, field_descriptor) + iter = ::FFI::MemoryPointer.new(:size_t, 1) + iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin) + key_value_pairs = [] + while Google::Protobuf::FFI.map_next(message_value[:map_val], iter) do + iter_size_t = iter.read(:size_t) + key_message_value = Google::Protobuf::FFI.map_key(message_value[:map_val], iter_size_t) + value_message_value = Google::Protobuf::FFI.map_value(message_value[:map_val], iter_size_t) + key_string = convert_upb_to_ruby(key_message_value, key_field_type).inspect + value_string = inspect_field(value_field_def, value_field_type, value_message_value) + key_value_pairs << "#{key_string}=>#{value_string}" + end + field_output << "#{field_descriptor.name}: {#{key_value_pairs.join(", ")}}" + elsif field_descriptor.repeated? + # TODO Adapted - from repeated_field#each - can this be refactored to reduce echo? + repeated_field_output = [] + message_value = Google::Protobuf::FFI.get_message_value(msg, field_descriptor) + array = message_value[:array_val] + n = array.null? ? 0 : Google::Protobuf::FFI.array_size(array) + 0.upto(n - 1) do |i| + element = Google::Protobuf::FFI.get_msgval_at(array, i) + repeated_field_output << inspect_field(field_descriptor, field_descriptor.send(:c_type), element) + end + field_output << "#{field_descriptor.name}: [#{repeated_field_output.join(", ")}]" + else + message_value = Google::Protobuf::FFI.get_message_value msg, field_descriptor + rendered_value = inspect_field(field_descriptor, field_descriptor.send(:c_type), message_value) + field_output << "#{field_descriptor.name}: #{rendered_value}" + end + end + "<#{name}: #{field_output.join(', ')}>" + end + + def self.deep_copy(msg, arena = nil) + arena ||= Google::Protobuf::FFI.create_arena + encode_internal(msg) do |encoding, size, mini_table_ptr| + message = private_constructor(arena) + if encoding.nil? or encoding.null? or Google::Protobuf::FFI.decode_message(encoding, size, message.instance_variable_get(:@msg), mini_table_ptr, nil, 0, arena) != :Ok + raise ParseError.new "Error occurred copying proto" + end + message + end + end + + def self.encode_internal(msg, encoding_options = 0) + temporary_arena = Google::Protobuf::FFI.create_arena + + mini_table_ptr = Google::Protobuf::FFI.get_mini_table(descriptor) + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + pointer_ptr = ::FFI::MemoryPointer.new(:pointer, 1) + encoding_status = Google::Protobuf::FFI.encode_message(msg, mini_table_ptr, encoding_options, temporary_arena, pointer_ptr.to_ptr, size_ptr) + raise "Encoding failed due to #{encoding_status}" unless encoding_status == :Ok + yield pointer_ptr.read(:pointer), size_ptr.read(:size_t), mini_table_ptr + end + + def method_missing_internal(method_name, *args, mode: nil) + raise ArgumentError.new "method_missing_internal called with invalid mode #{mode.inspect}" unless [:respond_to_missing?, :method_missing].include? mode + + #TODO not being allowed is not the same thing as not responding, but this is needed to pass tests + if method_name.to_s.end_with? '=' + if self.class.send(:oneof_field_names).include? method_name.to_s[0..-2].to_sym + return false if mode == :respond_to_missing? + raise RuntimeError.new "Oneof accessors are read-only." + end + end + + original_method_missing(method_name, *args) if mode == :method_missing + end + + def clear_internal(field_def) + raise FrozenError.new "can't modify frozen #{self.class}" if frozen? + Google::Protobuf::FFI.clear_message_field(@msg, field_def) + end + + # Accessor for field by name. Does not delegate to methods setup by + # self.setup_accessors! in order to avoid conflicts with bad field + # names e.g. `dup` or `class` which are perfectly valid for proto + # fields. + def index_internal(name) + field_descriptor = self.class.descriptor.lookup(name) + get_field field_descriptor unless field_descriptor.nil? + end + + #TODO - well known types keeps us on our toes by overloading methods. + # How much of the public API needs to be defended? + def index_assign_internal(value, name: nil, field_descriptor: nil, wrap: false) + raise FrozenError.new "can't modify frozen #{self.class}" if frozen? + if field_descriptor.nil? + field_descriptor = self.class.descriptor.lookup(name) + if field_descriptor.nil? + raise ArgumentError.new "Unknown field: #{name}" + end + end + unless field_descriptor.send :set_value_on_message, value, @msg, @arena, wrap: wrap + raise RuntimeError.new "allocation failed" + end + end + + ## + # @param initial_value [Object] initial value of this Message + # @param arena [Arena] Optional; Arena where this message will be allocated + # @param msg [::FFI::Pointer] Optional; Message to initialize; creates + # one if omitted or nil. + def initialize(initial_value = nil, arena = nil, msg = nil) + @arena = arena || Google::Protobuf::FFI.create_arena + @msg = msg || Google::Protobuf::FFI.new_message_from_def(Google::Protobuf::FFI.get_mini_table(self.class.descriptor), @arena) + + unless initial_value.nil? + raise ArgumentError.new "Expected hash arguments or message, not #{initial_value.class}" unless initial_value.respond_to? :each + + field_def_ptr = ::FFI::MemoryPointer.new :pointer + oneof_def_ptr = ::FFI::MemoryPointer.new :pointer + + initial_value.each do |key, value| + raise ArgumentError.new "Expected string or symbols as hash keys when initializing proto from hash." unless [String, Symbol].include? key.class + + unless Google::Protobuf::FFI.find_msg_def_by_name self.class.descriptor, key.to_s, key.to_s.bytesize, field_def_ptr, oneof_def_ptr + raise ArgumentError.new "Unknown field name '#{key}' in initialization map entry." + end + raise NotImplementedError.new "Haven't added oneofsupport yet" unless oneof_def_ptr.get_pointer(0).null? + raise NotImplementedError.new "Expected a field def" if field_def_ptr.get_pointer(0).null? + + field_descriptor = FieldDescriptor.from_native field_def_ptr.get_pointer(0) + + next if value.nil? + if field_descriptor.map? + index_assign_internal(Google::Protobuf::Map.send(:construct_for_field, field_descriptor, arena: @arena, value: value), name: key.to_s) + elsif field_descriptor.repeated? + index_assign_internal(RepeatedField.send(:construct_for_field, field_descriptor, arena: @arena, values: value), name: key.to_s) + else + index_assign_internal(value, name: key.to_s) + end + end + end + + # Should always be the last expression of the initializer to avoid + # leaking references to this object before construction is complete. + Google::Protobuf::OBJECT_CACHE.try_add @msg.address, self + end + + ## + # Gets a field of this message identified by FieldDescriptor. + # + # @param field [FieldDescriptor] Field to retrieve. + # @param unwrap [Boolean](false) If true, unwraps wrappers. + def get_field(field, unwrap: false) + if field.map? + map_from_field_descriptor field + elsif field.repeated? + repeated_field_from_field_descriptor field + elsif field.sub_message? + return nil unless Google::Protobuf::FFI.get_message_has @msg, field + if unwrap + if field.has?(self) + sub_message_def = Google::Protobuf::FFI.get_subtype_as_message field + wrapper_message_value = Google::Protobuf::FFI.get_message_value @msg, field + fields = Google::Protobuf::FFI.field_count(sub_message_def) + raise "Sub message has #{fields} fields! Expected exactly 1." unless fields == 1 + value_field_def = Google::Protobuf::FFI.get_field_by_number sub_message_def, 1 + message_value = Google::Protobuf::FFI.get_message_value wrapper_message_value[:msg_val], value_field_def + convert_upb_to_ruby message_value, Google::Protobuf::FFI.get_c_type(value_field_def) + else + nil + end + else + message_from_field_descriptor field + end + else + scalar_from_field_descriptor field + end + end + + ## + # Gets a RepeatedField from the ObjectCache or creates a new one. + # @param array [::FFI::Pointer] Pointer to the upb_Array + # @param field [Google::Protobuf::FieldDescriptor] Type of the repeated field + def get_repeated_field(array, field) + return nil if array.nil? or array.null? + repeated_field = OBJECT_CACHE.get(array.address) + if repeated_field.nil? + repeated_field = RepeatedField.send(:construct_for_field, field, arena: @arena, array: array) + repeated_field.freeze if frozen? + end + repeated_field + end + + ## + # Gets a Map from the ObjectCache or creates a new one. + # @param map [::FFI::Pointer] Pointer to the upb_Map + # @param field [Google::Protobuf::FieldDescriptor] Type of the map field + def get_map_field(map, field) + return nil if map.nil? or map.null? + map_field = OBJECT_CACHE.get(map.address) + if map_field.nil? + map_field = Google::Protobuf::Map.send(:construct_for_field, field, arena: @arena, map: map) + map_field.freeze if frozen? + end + map_field + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/method_descriptor.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/method_descriptor.rb new file mode 100755 index 0000000..f879d49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/method_descriptor.rb @@ -0,0 +1,124 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2024 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class MethodDescriptor + attr :method_def, :descriptor_pool + + include Google::Protobuf::Internal::Convert + + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + include Google::Protobuf::Internal::PointerHelper + + # @param value [MethodDescriptor] MethodDescriptor to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _) + method_def_ptr = value.nil? ? nil : value.instance_variable_get(:@method_def) + return ::FFI::Pointer::NULL if method_def_ptr.nil? + raise "Underlying method_def was null!" if method_def_ptr.null? + method_def_ptr + end + + ## + # @param service_def [::FFI::Pointer] MethodDef pointer to be wrapped + # @param _ [Object] Unused + def from_native(method_def, _ = nil) + return nil if method_def.nil? or method_def.null? + service_def = Google::Protobuf::FFI.raw_service_def_by_raw_method_def(method_def) + file_def = Google::Protobuf::FFI.file_def_by_raw_service_def(service_def) + descriptor_from_file_def(file_def, method_def) + end + end + + def self.new(*arguments, &block) + raise "Descriptor objects may not be created from Ruby." + end + + def to_s + inspect + end + + def inspect + "#{self.class.name}: #{name}" + end + + def name + @name ||= Google::Protobuf::FFI.get_method_name(self) + end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.method_options(self, size_ptr, temporary_arena) + Google::Protobuf::MethodOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).freeze + end + end + + def input_type + @input_type ||= Google::Protobuf::FFI.method_input_type(self) + end + + def output_type + @output_type ||= Google::Protobuf::FFI.method_output_type(self) + end + + def client_streaming + @client_streaming ||= Google::Protobuf::FFI.method_client_streaming(self) + end + + def server_streaming + @server_streaming ||= Google::Protobuf::FFI.method_server_streaming(self) + end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.method_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::MethodDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + + private + + def initialize(method_def, descriptor_pool) + @method_def = method_def + @descriptor_pool = descriptor_pool + end + + def self.private_constructor(method_def, descriptor_pool) + instance = allocate + instance.send(:initialize, method_def, descriptor_pool) + instance + end + + def c_type + @c_type ||= Google::Protobuf::FFI.get_c_type(self) + end + end + + class FFI + # MethodDef + attach_function :raw_service_def_by_raw_method_def, :upb_MethodDef_Service, [:pointer], :pointer + attach_function :get_method_name, :upb_MethodDef_Name, [MethodDescriptor], :string + attach_function :method_options, :MethodDescriptor_serialized_options, [MethodDescriptor, :pointer, Internal::Arena], :pointer + attach_function :method_input_type, :upb_MethodDef_InputType, [MethodDescriptor], Descriptor + attach_function :method_output_type, :upb_MethodDef_OutputType, [MethodDescriptor], Descriptor + attach_function :method_client_streaming, :upb_MethodDef_ClientStreaming, [MethodDescriptor], :bool + attach_function :method_server_streaming, :upb_MethodDef_ServerStreaming, [MethodDescriptor], :bool + attach_function :method_to_proto, :MethodDescriptor_serialized_to_proto, [MethodDescriptor, :pointer, Internal::Arena], :pointer + end + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/object_cache.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/object_cache.rb new file mode 100755 index 0000000..61f5c8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/object_cache.rb @@ -0,0 +1,30 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + private + + SIZEOF_LONG = ::FFI::MemoryPointer.new(:long).size + SIZEOF_VALUE = ::FFI::Pointer::SIZE + + def self.interpreter_supports_non_finalized_keys_in_weak_map? + ! defined? JRUBY_VERSION + end + + def self.cache_implementation + if interpreter_supports_non_finalized_keys_in_weak_map? and SIZEOF_LONG >= SIZEOF_VALUE + Google::Protobuf::Internal::ObjectCache + else + Google::Protobuf::Internal::LegacyObjectCache + end + end + + public + OBJECT_CACHE = cache_implementation.new + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/oneof_descriptor.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/oneof_descriptor.rb new file mode 100755 index 0000000..3733900 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/oneof_descriptor.rb @@ -0,0 +1,107 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2022 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class OneofDescriptor + attr :descriptor_pool, :oneof_def + include Enumerable + + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + include Google::Protobuf::Internal::PointerHelper + + # @param value [OneofDescriptor] FieldDescriptor to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _ = nil) + value.instance_variable_get(:@oneof_def) || ::FFI::Pointer::NULL + end + + ## + # @param oneof_def [::FFI::Pointer] OneofDef pointer to be wrapped + # @param _ [Object] Unused + def from_native(oneof_def, _ = nil) + return nil if oneof_def.nil? or oneof_def.null? + message_descriptor = Google::Protobuf::FFI.get_oneof_containing_type oneof_def + raise RuntimeError.new "Message Descriptor is nil" if message_descriptor.nil? + file_def = Google::Protobuf::FFI.get_message_file_def message_descriptor.to_native + descriptor_from_file_def(file_def, oneof_def) + end + end + + def self.new(*arguments, &block) + raise "OneofDescriptor objects may not be created from Ruby." + end + + def name + Google::Protobuf::FFI.get_oneof_name(self) + end + + def each &block + n = Google::Protobuf::FFI.get_oneof_field_count(self) + 0.upto(n-1) do |i| + yield(Google::Protobuf::FFI.get_oneof_field_by_index(self, i)) + end + nil + end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.oneof_options(self, size_ptr, temporary_arena) + opts = Google::Protobuf::OneofOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + opts.clear_features() + opts.freeze + end + end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.oneof_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::OneofDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + + private + + def initialize(oneof_def, descriptor_pool) + @descriptor_pool = descriptor_pool + @oneof_def = oneof_def + end + + def self.private_constructor(oneof_def, descriptor_pool) + instance = allocate + instance.send(:initialize, oneof_def, descriptor_pool) + instance + end + end + + class FFI + # MessageDef + attach_function :get_oneof_by_name, :upb_MessageDef_FindOneofByNameWithSize, [Descriptor, :string, :size_t], OneofDescriptor + attach_function :get_oneof_by_index, :upb_MessageDef_Oneof, [Descriptor, :int], OneofDescriptor + + # OneofDescriptor + attach_function :get_oneof_name, :upb_OneofDef_Name, [OneofDescriptor], :string + attach_function :get_oneof_field_count, :upb_OneofDef_FieldCount, [OneofDescriptor], :int + attach_function :get_oneof_field_by_index, :upb_OneofDef_Field, [OneofDescriptor, :int], FieldDescriptor + attach_function :get_oneof_containing_type,:upb_OneofDef_ContainingType, [:pointer], Descriptor + attach_function :oneof_options, :OneOfDescriptor_serialized_options, [OneofDescriptor, :pointer, Internal::Arena], :pointer + attach_function :oneof_to_proto, :OneOfDescriptor_serialized_to_proto, [OneofDescriptor, :pointer, Internal::Arena], :pointer + + # FieldDescriptor + attach_function :real_containing_oneof, :upb_FieldDef_RealContainingOneof, [FieldDescriptor], OneofDescriptor + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/repeated_field.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/repeated_field.rb new file mode 100755 index 0000000..5c3306e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/repeated_field.rb @@ -0,0 +1,411 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +# +# This class makes RepeatedField act (almost-) like a Ruby Array. +# It has convenience methods that extend the core C or Java based +# methods. +# +# This is a best-effort to mirror Array behavior. Two comments: +# 1) patches always welcome :) +# 2) if performance is an issue, feel free to rewrite the method +# in C. The source code has plenty of examples +# +# KNOWN ISSUES +# - #[]= doesn't allow less used approaches such as `arr[1, 2] = 'fizz'` +# - #concat should return the orig array +# - #push should accept multiple arguments and push them all at the same time +# +module Google + module Protobuf + class FFI + # Array + attach_function :append_array, :upb_Array_Append, [:Array, MessageValue.by_value, Internal::Arena], :bool + attach_function :get_msgval_at, :upb_Array_Get, [:Array, :size_t], MessageValue.by_value + attach_function :create_array, :upb_Array_New, [Internal::Arena, CType], :Array + attach_function :array_resize, :upb_Array_Resize, [:Array, :size_t, Internal::Arena], :bool + attach_function :array_set, :upb_Array_Set, [:Array, :size_t, MessageValue.by_value], :void + attach_function :array_size, :upb_Array_Size, [:Array], :size_t + attach_function :array_freeze, :upb_Array_Freeze, [:Array, MiniTable.by_ref], :void + attach_function :array_frozen?, :upb_Array_IsFrozen, [:Array], :bool + end + + class RepeatedField + include Enumerable + + ## + # call-seq: + # RepeatedField.new(type, type_class = nil, initial_values = []) + # + # Creates a new repeated field. The provided type must be a Ruby symbol, and + # an take on the same values as those accepted by FieldDescriptor#type=. If + # the type is :message or :enum, type_class must be non-nil, and must be the + # Ruby class or module returned by Descriptor#msgclass or + # EnumDescriptor#enummodule, respectively. An initial list of elements may also + # be provided. + def self.new(type, type_class = nil, initial_values = []) + instance = allocate + # TODO This argument mangling doesn't agree with the type signature in the comments + # but is required to make unit tests pass; + if type_class.is_a?(Enumerable) and initial_values.empty? and ![:enum, :message].include?(type) + initial_values = type_class + type_class = nil + end + instance.send(:initialize, type, type_class: type_class, initial_values: initial_values) + instance + end + + ## + # call-seq: + # RepeatedField.each(&block) + # + # Invokes the block once for each element of the repeated field. RepeatedField + # also includes Enumerable; combined with this method, the repeated field thus + # acts like an ordinary Ruby sequence. + def each &block + each_msg_val do |element| + yield(convert_upb_to_ruby(element, type, descriptor, arena)) + end + self + end + + def [](*args) + count = length + if args.size < 1 + raise ArgumentError.new "Index or range is a required argument." + end + if args[0].is_a? Range + if args.size > 1 + raise ArgumentError.new "Expected 1 when passing Range argument, but got #{args.size}" + end + range = args[0] + # Handle begin-less and/or endless ranges, when supported. + index_of_first = range.respond_to?(:begin) ? range.begin : range.last + index_of_first = 0 if index_of_first.nil? + end_of_range = range.respond_to?(:end) ? range.end : range.last + index_of_last = end_of_range.nil? ? -1 : end_of_range + + if index_of_last < 0 + index_of_last += count + end + unless range.exclude_end? and !end_of_range.nil? + index_of_last += 1 + end + index_of_first += count if index_of_first < 0 + length = index_of_last - index_of_first + return [] if length.zero? + elsif args[0].is_a? Integer + index_of_first = args[0] + index_of_first += count if index_of_first < 0 + if args.size > 2 + raise ArgumentError.new "Expected 1 or 2 arguments, but got #{args.size}" + end + if args.size == 1 # No length specified, return one element + if array.null? or index_of_first < 0 or index_of_first >= count + return nil + else + return convert_upb_to_ruby(Google::Protobuf::FFI.get_msgval_at(array, index_of_first), type, descriptor, arena) + end + else + length = [args[1],count].min + end + else + raise NotImplementedError + end + + if array.null? or index_of_first < 0 or index_of_first >= count + nil + else + if index_of_first + length > count + length = count - index_of_first + end + if length < 0 + nil + else + subarray(index_of_first, length) + end + end + end + alias at [] + + + def []=(index, value) + raise FrozenError if frozen? + count = length + index += count if index < 0 + return nil if index < 0 + if index >= count + resize(index+1) + empty_message_value = Google::Protobuf::FFI::MessageValue.new # Implicitly clear + count.upto(index-1) do |i| + Google::Protobuf::FFI.array_set(array, i, empty_message_value) + end + end + Google::Protobuf::FFI.array_set(array, index, convert_ruby_to_upb(value, arena, type, descriptor)) + nil + end + + def push(*elements) + raise FrozenError if frozen? + internal_push(*elements) + end + + def <<(element) + raise FrozenError if frozen? + push element + end + + def replace(replacements) + raise FrozenError if frozen? + clear + push(*replacements) + end + + def clear + raise FrozenError if frozen? + resize 0 + self + end + + def length + array.null? ? 0 : Google::Protobuf::FFI.array_size(array) + end + alias size :length + + ## + # Is this object frozen? + # Returns true if either this Ruby wrapper or the underlying + # representation are frozen. Freezes the wrapper if the underlying + # representation is already frozen but this wrapper isn't. + def frozen? + unless Google::Protobuf::FFI.array_frozen? array + raise RuntimeError.new "Ruby frozen RepeatedField with mutable representation" if super + return false + end + method(:freeze).super_method.call unless super + true + end + + ## + # Freezes the RepeatedField object. We have to intercept this so we can + # freeze the underlying representation, not just the Ruby wrapper. Returns + # self. + def freeze + if method(:frozen?).super_method.call + unless Google::Protobuf::FFI.array_frozen? array + raise RuntimeError.new "Underlying representation of repeated field still mutable despite frozen wrapper" + end + return self + end + unless Google::Protobuf::FFI.array_frozen? array + mini_table = (type == :message) ? Google::Protobuf::FFI.get_mini_table(@descriptor) : nil + Google::Protobuf::FFI.array_freeze(array, mini_table) + end + super + end + + def dup + instance = self.class.allocate + instance.send(:initialize, type, descriptor: descriptor, arena: arena) + each_msg_val do |element| + instance.send(:append_msg_val, element) + end + instance + end + alias clone dup + + def ==(other) + return true if other.object_id == object_id + if other.is_a? RepeatedField + return false unless other.length == length + each_msg_val_with_index do |msg_val, i| + other_msg_val = Google::Protobuf::FFI.get_msgval_at(other.send(:array), i) + unless Google::Protobuf::FFI.message_value_equal(msg_val, other_msg_val, type, descriptor) + return false + end + end + return true + elsif other.is_a? Enumerable + return to_ary == other.to_a + end + false + end + + ## + # call-seq: + # RepeatedField.to_ary => array + # + # Used when converted implicitly into array, e.g. compared to an Array. + # Also called as a fallback of Object#to_a + def to_ary + return_value = [] + each do |element| + return_value << element + end + return_value + end + + def hash + return_value = 0 + each_msg_val do |msg_val| + return_value = Google::Protobuf::FFI.message_value_hash(msg_val, type, descriptor, return_value) + end + return_value + end + + def +(other) + if other.is_a? RepeatedField + if type != other.instance_variable_get(:@type) or descriptor != other.instance_variable_get(:@descriptor) + raise ArgumentError.new "Attempt to append RepeatedField with different element type." + end + fuse_arena(other.send(:arena)) + super_set = dup + other.send(:each_msg_val) do |msg_val| + super_set.send(:append_msg_val, msg_val) + end + super_set + elsif other.is_a? Enumerable + super_set = dup + super_set.push(*other.to_a) + else + raise ArgumentError.new "Unknown type appending to RepeatedField" + end + end + + def concat(other) + raise ArgumentError.new "Expected Enumerable, but got #{other.class}" unless other.is_a? Enumerable + push(*other.to_a) + end + + private + include Google::Protobuf::Internal::Convert + + attr :name, :arena, :array, :type, :descriptor + + def internal_push(*elements) + elements.each do |element| + append_msg_val convert_ruby_to_upb(element, arena, type, descriptor) + end + self + end + + def pop_one + raise FrozenError if frozen? + count = length + return nil if length.zero? + last_element = Google::Protobuf::FFI.get_msgval_at(array, count-1) + return_value = convert_upb_to_ruby(last_element, type, descriptor, arena) + resize(count-1) + return_value + end + + def subarray(start, length) + return_result = [] + (start..(start + length - 1)).each do |i| + element = Google::Protobuf::FFI.get_msgval_at(array, i) + return_result << convert_upb_to_ruby(element, type, descriptor, arena) + end + return_result + end + + def each_msg_val_with_index &block + n = array.null? ? 0 : Google::Protobuf::FFI.array_size(array) + 0.upto(n-1) do |i| + yield Google::Protobuf::FFI.get_msgval_at(array, i), i + end + end + + def each_msg_val &block + each_msg_val_with_index do |msg_val, _| + yield msg_val + end + end + + # @param msg_val [Google::Protobuf::FFI::MessageValue] Value to append + def append_msg_val(msg_val) + unless Google::Protobuf::FFI.append_array(array, msg_val, arena) + raise NoMemoryError.new "Could not allocate room for #{msg_val} in Arena" + end + end + + # @param new_size [Integer] New size of the array + def resize(new_size) + unless Google::Protobuf::FFI.array_resize(array, new_size, arena) + raise NoMemoryError.new "Array resize to #{new_size} failed!" + end + end + + def initialize(type, type_class: nil, initial_values: nil, name: nil, arena: nil, array: nil, descriptor: nil) + @name = name || 'RepeatedField' + raise ArgumentError.new "Expected argument type to be a Symbol" unless type.is_a? Symbol + field_number = Google::Protobuf::FFI::FieldType[type] + raise ArgumentError.new "Unsupported type '#{type}'" if field_number.nil? + if !descriptor.nil? + @descriptor = descriptor + elsif [:message, :enum].include? type + raise ArgumentError.new "Expected at least 2 arguments for message/enum." if type_class.nil? + descriptor = type_class.respond_to?(:descriptor) ? type_class.descriptor : nil + raise ArgumentError.new "Type class #{type_class} has no descriptor. Please pass a class or enum as returned by the DescriptorPool." if descriptor.nil? + @descriptor = descriptor + else + @descriptor = nil + end + @type = type + + @arena = arena || Google::Protobuf::FFI.create_arena + @array = array || Google::Protobuf::FFI.create_array(@arena, @type) + unless initial_values.nil? + unless initial_values.is_a? Enumerable + raise ArgumentError.new "Expected array as initializer value for repeated field '#{name}' (given #{initial_values.class})." + end + internal_push(*initial_values) + end + + # Should always be the last expression of the initializer to avoid + # leaking references to this object before construction is complete. + OBJECT_CACHE.try_add(@array.address, self) + end + + ## + # Constructor that uses the type information from the given + # FieldDescriptor to configure the new RepeatedField instance. + # @param field [FieldDescriptor] Type information for the new RepeatedField + # @param arena [Arena] Owning message's arena + # @param values [Enumerable] Initial values + # @param array [::FFI::Pointer] Existing upb_Array + def self.construct_for_field(field, arena: nil, values: nil, array: nil) + instance = allocate + options = {initial_values: values, name: field.name, arena: arena, array: array} + if [:enum, :message].include? field.type + options[:descriptor] = field.subtype + end + instance.send(:initialize, field.type, **options) + instance + end + + def fuse_arena(arena) + arena.fuse(arena) + end + + extend Google::Protobuf::Internal::Convert + + def self.deep_copy(repeated_field) + instance = allocate + instance.send(:initialize, repeated_field.send(:type), descriptor: repeated_field.send(:descriptor)) + instance.send(:resize, repeated_field.length) + new_array = instance.send(:array) + repeated_field.send(:each_msg_val_with_index) do |element, i| + Google::Protobuf::FFI.array_set(new_array, i, message_value_deep_copy(element, repeated_field.send(:type), repeated_field.send(:descriptor), instance.send(:arena))) + end + instance + end + + end + end +end + +require 'google/protobuf/repeated_field' diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/service_descriptor.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/service_descriptor.rb new file mode 100755 index 0000000..72fd679 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/ffi/service_descriptor.rb @@ -0,0 +1,117 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2024 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + class ServiceDescriptor + attr :service_def, :descriptor_pool + include Enumerable + + include Google::Protobuf::Internal::Convert + + # FFI Interface methods and setup + extend ::FFI::DataConverter + native_type ::FFI::Type::POINTER + + class << self + prepend Google::Protobuf::Internal::TypeSafety + include Google::Protobuf::Internal::PointerHelper + + # @param value [ServiceDescriptor] ServiceDescriptor to convert to an FFI native type + # @param _ [Object] Unused + def to_native(value, _) + service_def_ptr = value.nil? ? nil : value.instance_variable_get(:@service_def) + return ::FFI::Pointer::NULL if service_def_ptr.nil? + raise "Underlying service_def was null!" if service_def_ptr.null? + service_def_ptr + end + + ## + # @param service_def [::FFI::Pointer] ServiceDef pointer to be wrapped + # @param _ [Object] Unused + def from_native(service_def, _ = nil) + return nil if service_def.nil? or service_def.null? + file_def = Google::Protobuf::FFI.file_def_by_raw_service_def(service_def) + descriptor_from_file_def(file_def, service_def) + end + end + + def self.new(*arguments, &block) + raise "Descriptor objects may not be created from Ruby." + end + + def to_s + inspect + end + + def inspect + "#{self.class.name}: #{name}" + end + + def name + @name ||= Google::Protobuf::FFI.get_service_full_name(self) + end + + def file_descriptor + @descriptor_pool.send(:get_file_descriptor, Google::Protobuf::FFI.file_def_by_raw_service_def(@service_def)) + end + + def each &block + n = Google::Protobuf::FFI.method_count(self) + 0.upto(n-1) do |i| + yield(Google::Protobuf::FFI.get_method_by_index(self, i)) + end + nil + end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.service_options(self, size_ptr, temporary_arena) + Google::Protobuf::ServiceOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).freeze + end + end + + def to_proto + @to_proto ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.service_to_proto(self, size_ptr, temporary_arena) + Google::Protobuf::ServiceDescriptorProto.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze) + end + end + + private + + def initialize(service_def, descriptor_pool) + @service_def = service_def + @descriptor_pool = descriptor_pool + end + + def self.private_constructor(service_def, descriptor_pool) + instance = allocate + instance.send(:initialize, service_def, descriptor_pool) + instance + end + + def c_type + @c_type ||= Google::Protobuf::FFI.get_c_type(self) + end + end + + class FFI + # ServiceDef + attach_function :file_def_by_raw_service_def, :upb_ServiceDef_File, [:pointer], :FileDef + attach_function :get_service_full_name, :upb_ServiceDef_FullName, [ServiceDescriptor], :string + attach_function :method_count, :upb_ServiceDef_MethodCount, [ServiceDescriptor], :int + attach_function :get_method_by_index, :upb_ServiceDef_Method, [ServiceDescriptor, :int], MethodDescriptor + attach_function :service_options, :ServiceDescriptor_serialized_options, [ServiceDescriptor, :pointer, Internal::Arena], :pointer + attach_function :service_to_proto, :ServiceDescriptor_serialized_to_proto, [ServiceDescriptor, :pointer, Internal::Arena], :pointer + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/field_mask_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/field_mask_pb.rb new file mode 100755 index 0000000..5240768 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/field_mask_pb.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/field_mask.proto + +require 'google/protobuf' + + +descriptor_data = "\n google/protobuf/field_mask.proto\x12\x0fgoogle.protobuf\"\x1a\n\tFieldMask\x12\r\n\x05paths\x18\x01 \x03(\tB\x85\x01\n\x13\x63om.google.protobufB\x0e\x46ieldMaskProtoP\x01Z2google.golang.org/protobuf/types/known/fieldmaskpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + FieldMask = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FieldMask").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/internal/object_cache.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/internal/object_cache.rb new file mode 100755 index 0000000..38e9bb5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/internal/object_cache.rb @@ -0,0 +1,99 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2023 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + module Internal + # A pointer -> Ruby Object cache that keeps references to Ruby wrapper + # objects. This allows us to look up any Ruby wrapper object by the address + # of the object it is wrapping. That way we can avoid ever creating two + # different wrapper objects for the same C object, which saves memory and + # preserves object identity. + # + # We use WeakMap for the cache. If sizeof(long) > sizeof(VALUE), we also + # need a secondary Hash to store WeakMap keys, because our pointer keys may + # need to be stored as Bignum instead of Fixnum. Since WeakMap is weak for + # both keys and values, a Bignum key will cause the WeakMap entry to be + # collected immediately unless there is another reference to the Bignum. + # This happens on 64-bit Windows, on which pointers are 64 bits but longs + # are 32 bits. In this case, we enable the secondary Hash to hold the keys + # and prevent them from being collected. + class ObjectCache + def initialize + @map = ObjectSpace::WeakMap.new + @mutex = Mutex.new + end + + def get(key) + @map[key] + end + + def try_add(key, value) + @map[key] || @mutex.synchronize do + @map[key] ||= value + end + end + end + + class LegacyObjectCache + def initialize + @secondary_map = {} + @map = ObjectSpace::WeakMap.new + @mutex = Mutex.new + end + + def get(key) + value = if secondary_key = @secondary_map[key] + @map[secondary_key] + else + @mutex.synchronize do + @map[(@secondary_map[key] ||= Object.new)] + end + end + + # GC if we could remove at least 2000 entries or 20% of the table size + # (whichever is greater). Since the cost of the GC pass is O(N), we + # want to make sure that we condition this on overall table size, to + # avoid O(N^2) CPU costs. + cutoff = (@secondary_map.size * 0.2).ceil + cutoff = 2_000 if cutoff < 2_000 + if (@secondary_map.size - @map.size) > cutoff + purge + end + + value + end + + def try_add(key, value) + if secondary_key = @secondary_map[key] + if old_value = @map[secondary_key] + return old_value + end + end + + @mutex.synchronize do + secondary_key ||= (@secondary_map[key] ||= Object.new) + @map[secondary_key] ||= value + end + end + + private + + def purge + @mutex.synchronize do + @secondary_map.each do |key, secondary_key| + unless @map.key?(secondary_key) + @secondary_map.delete(key) + end + end + end + nil + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/message_exts.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/message_exts.rb new file mode 100755 index 0000000..a014304 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/message_exts.rb @@ -0,0 +1,39 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +module Google + module Protobuf + module MessageExts + + #this is only called in jruby; mri loades the ClassMethods differently + def self.included(klass) + klass.extend(ClassMethods) + end + + module ClassMethods + end + + def to_json(options = {}) + self.class.encode_json(self, options) + end + + def to_proto(options = {}) + self.class.encode(self, options) + end + + def to_hash + self.to_h + end + + end + class AbstractMessage + include MessageExts + extend MessageExts::ClassMethods + end + private_constant :AbstractMessage + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/plugin_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/plugin_pb.rb new file mode 100755 index 0000000..a8aebec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/plugin_pb.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/compiler/plugin.proto + +require 'google/protobuf' + +require 'google/protobuf/descriptor_pb' + + +descriptor_data = "\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"F\n\x07Version\x12\r\n\x05major\x18\x01 \x01(\x05\x12\r\n\x05minor\x18\x02 \x01(\x05\x12\r\n\x05patch\x18\x03 \x01(\x05\x12\x0e\n\x06suffix\x18\x04 \x01(\t\"\x81\x02\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12\x45\n\x17source_file_descriptors\x18\x11 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12;\n\x10\x63ompiler_version\x18\x03 \x01(\x0b\x32!.google.protobuf.compiler.Version\"\x92\x03\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x1a\n\x12supported_features\x18\x02 \x01(\x04\x12\x17\n\x0fminimum_edition\x18\x03 \x01(\x05\x12\x17\n\x0fmaximum_edition\x18\x04 \x01(\x05\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a\x7f\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t\x12?\n\x13generated_code_info\x18\x10 \x01(\x0b\x32\".google.protobuf.GeneratedCodeInfo\"W\n\x07\x46\x65\x61ture\x12\x10\n\x0c\x46\x45\x41TURE_NONE\x10\x00\x12\x1b\n\x17\x46\x45\x41TURE_PROTO3_OPTIONAL\x10\x01\x12\x1d\n\x19\x46\x45\x41TURE_SUPPORTS_EDITIONS\x10\x02\x42r\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtosZ)google.golang.org/protobuf/types/pluginpb\xaa\x02\x18Google.Protobuf.Compiler" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + module Compiler + Version = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.compiler.Version").msgclass + CodeGeneratorRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.compiler.CodeGeneratorRequest").msgclass + CodeGeneratorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.compiler.CodeGeneratorResponse").msgclass + CodeGeneratorResponse::File = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.compiler.CodeGeneratorResponse.File").msgclass + CodeGeneratorResponse::Feature = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.compiler.CodeGeneratorResponse.Feature").enummodule + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/repeated_field.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/repeated_field.rb new file mode 100755 index 0000000..53de122 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/repeated_field.rb @@ -0,0 +1,177 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +require 'forwardable' + +# +# This class makes RepeatedField act (almost-) like a Ruby Array. +# It has convenience methods that extend the core C or Java based +# methods. +# +# This is a best-effort to mirror Array behavior. Two comments: +# 1) patches always welcome :) +# 2) if performance is an issue, feel free to rewrite the method +# in jruby and C. The source code has plenty of examples +# +# KNOWN ISSUES +# - #[]= doesn't allow less used approaches such as `arr[1, 2] = 'fizz'` +# - #concat should return the orig array +# - #push should accept multiple arguments and push them all at the same time +# +module Google + module Protobuf + class RepeatedField + extend Forwardable + + # methods defined in C or Java: + # + + # [], at + # []= + # concat + # clear + # dup, clone + # each + # push, << + # replace + # length, size + # == + # to_ary, to_a + # also all enumerable + # + # NOTE: using delegators rather than method_missing to make the + # relationship explicit instead of implicit + def_delegators :to_ary, + :&, :*, :-, :'<=>', + :assoc, :bsearch, :bsearch_index, :combination, :compact, :count, + :cycle, :difference, :dig, :drop, :drop_while, :eql?, :fetch, :find_index, :flatten, + :include?, :index, :inspect, :intersection, :join, + :pack, :permutation, :product, :pretty_print, :pretty_print_cycle, + :rassoc, :repeated_combination, :repeated_permutation, :reverse, + :rindex, :rotate, :sample, :shuffle, :shelljoin, + :to_s, :transpose, :union, :uniq, :| + + + def first(n=nil) + if n.nil? + return self[0] + elsif n < 0 + raise ArgumentError, "negative array size" + else + return self[0...n] + end + end + + + def last(n=nil) + if n.nil? + return self[-1] + elsif n < 0 + raise ArgumentError, "negative array size" + else + start = [self.size-n, 0].max + return self[start...self.size] + end + end + + + def pop(n=nil) + if n + results = [] + n.times{ results << pop_one } + return results + else + return pop_one + end + end + + + def empty? + self.size == 0 + end + + # array aliases into enumerable + alias_method :slice, :[] + alias_method :values_at, :select + alias_method :map, :collect + + + class << self + def define_array_wrapper_method(method_name) + define_method(method_name) do |*args, &block| + arr = self.to_a + result = arr.send(method_name, *args) + self.replace(arr) + return result if result + return block ? block.call : result + end + end + private :define_array_wrapper_method + + + def define_array_wrapper_with_result_method(method_name) + define_method(method_name) do |*args, &block| + # result can be an Enumerator, Array, or nil + # Enumerator can sometimes be returned if a block is an optional argument and it is not passed in + # nil usually specifies that no change was made + result = self.to_a.send(method_name, *args, &block) + if result + new_arr = result.to_a + self.replace(new_arr) + if result.is_a?(Enumerator) + # generate a fresh enum; rewinding the exiting one, in Ruby 2.2, will + # reset the enum with the same length, but all the #next calls will + # return nil + result = new_arr.to_enum + # generate a wrapper enum so any changes which occur by a chained + # enum can be captured + ie = ProxyingEnumerator.new(self, result) + result = ie.to_enum + end + end + result + end + end + private :define_array_wrapper_with_result_method + end + + + %w(delete delete_at shift slice! unshift).each do |method_name| + define_array_wrapper_method(method_name) + end + + + %w(collect! compact! delete_if each_index fill flatten! insert reverse! + rotate! select! shuffle! sort! sort_by! uniq!).each do |method_name| + define_array_wrapper_with_result_method(method_name) + end + alias_method :keep_if, :select! + alias_method :map!, :collect! + alias_method :reject!, :delete_if + + + # propagates changes made by user of enumerator back to the original repeated field. + # This only applies in cases where the calling function which created the enumerator, + # such as #sort!, modifies itself rather than a new array, such as #sort + class ProxyingEnumerator < Struct.new(:repeated_field, :external_enumerator) + def each(*args, &block) + results = [] + external_enumerator.each_with_index do |val, i| + result = yield(val) + results << result + #nil means no change occurred from yield; usually occurs when #to_a is called + if result + repeated_field[i] = result if result != val + end + end + results + end + end + + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/source_context_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/source_context_pb.rb new file mode 100755 index 0000000..74aec1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/source_context_pb.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/source_context.proto + +require 'google/protobuf' + + +descriptor_data = "\n$google/protobuf/source_context.proto\x12\x0fgoogle.protobuf\"\"\n\rSourceContext\x12\x11\n\tfile_name\x18\x01 \x01(\tB\x8a\x01\n\x13\x63om.google.protobufB\x12SourceContextProtoP\x01Z6google.golang.org/protobuf/types/known/sourcecontextpb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + SourceContext = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.SourceContext").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/struct_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/struct_pb.rb new file mode 100755 index 0000000..6c1cde7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/struct_pb.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/struct.proto + +require 'google/protobuf' + + +descriptor_data = "\n\x1cgoogle/protobuf/struct.proto\x12\x0fgoogle.protobuf\"\x84\x01\n\x06Struct\x12\x33\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.protobuf.Struct.FieldsEntry\x1a\x45\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"\xea\x01\n\x05Value\x12\x30\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00\x12\x16\n\x0cnumber_value\x18\x02 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x04 \x01(\x08H\x00\x12/\n\x0cstruct_value\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x12\x30\n\nlist_value\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.ListValueH\x00\x42\x06\n\x04kind\"3\n\tListValue\x12&\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.Value*\x1b\n\tNullValue\x12\x0e\n\nNULL_VALUE\x10\x00\x42\x7f\n\x13\x63om.google.protobufB\x0bStructProtoP\x01Z/google.golang.org/protobuf/types/known/structpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + Struct = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Struct").msgclass + Value = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Value").msgclass + ListValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.ListValue").msgclass + NullValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.NullValue").enummodule + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/timestamp_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/timestamp_pb.rb new file mode 100755 index 0000000..87930df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/timestamp_pb.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/timestamp.proto + +require 'google/protobuf' + + +descriptor_data = "\n\x1fgoogle/protobuf/timestamp.proto\x12\x0fgoogle.protobuf\"+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42\x85\x01\n\x13\x63om.google.protobufB\x0eTimestampProtoP\x01Z2google.golang.org/protobuf/types/known/timestamppb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + Timestamp = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Timestamp").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/type_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/type_pb.rb new file mode 100755 index 0000000..c3fc087 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/type_pb.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/type.proto + +require 'google/protobuf' + +require 'google/protobuf/any_pb' +require 'google/protobuf/source_context_pb' + + +descriptor_data = "\n\x1agoogle/protobuf/type.proto\x12\x0fgoogle.protobuf\x1a\x19google/protobuf/any.proto\x1a$google/protobuf/source_context.proto\"\xe8\x01\n\x04Type\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x16.google.protobuf.Field\x12\x0e\n\x06oneofs\x18\x03 \x03(\t\x12(\n\x07options\x18\x04 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x06 \x01(\x0e\x32\x17.google.protobuf.Syntax\x12\x0f\n\x07\x65\x64ition\x18\x07 \x01(\t\"\xd5\x05\n\x05\x46ield\x12)\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.google.protobuf.Field.Kind\x12\x37\n\x0b\x63\x61rdinality\x18\x02 \x01(\x0e\x32\".google.protobuf.Field.Cardinality\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x10\n\x08type_url\x18\x06 \x01(\t\x12\x13\n\x0boneof_index\x18\x07 \x01(\x05\x12\x0e\n\x06packed\x18\x08 \x01(\x08\x12(\n\x07options\x18\t \x03(\x0b\x32\x17.google.protobuf.Option\x12\x11\n\tjson_name\x18\n \x01(\t\x12\x15\n\rdefault_value\x18\x0b \x01(\t\"\xc8\x02\n\x04Kind\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"t\n\x0b\x43\x61rdinality\x12\x17\n\x13\x43\x41RDINALITY_UNKNOWN\x10\x00\x12\x18\n\x14\x43\x41RDINALITY_OPTIONAL\x10\x01\x12\x18\n\x14\x43\x41RDINALITY_REQUIRED\x10\x02\x12\x18\n\x14\x43\x41RDINALITY_REPEATED\x10\x03\"\xdf\x01\n\x04\x45num\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\tenumvalue\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.EnumValue\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x05 \x01(\x0e\x32\x17.google.protobuf.Syntax\x12\x0f\n\x07\x65\x64ition\x18\x06 \x01(\t\"S\n\tEnumValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\";\n\x06Option\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x05value\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any*C\n\x06Syntax\x12\x11\n\rSYNTAX_PROTO2\x10\x00\x12\x11\n\rSYNTAX_PROTO3\x10\x01\x12\x13\n\x0fSYNTAX_EDITIONS\x10\x02\x42{\n\x13\x63om.google.protobufB\tTypeProtoP\x01Z-google.golang.org/protobuf/types/known/typepb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Type").msgclass + Field = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Field").msgclass + Field::Kind = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Field.Kind").enummodule + Field::Cardinality = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Field.Cardinality").enummodule + Enum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Enum").msgclass + EnumValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.EnumValue").msgclass + Option = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Option").msgclass + Syntax = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Syntax").enummodule + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/well_known_types.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/well_known_types.rb new file mode 100755 index 0000000..c2df723 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/well_known_types.rb @@ -0,0 +1,211 @@ +#!/usr/bin/ruby +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +require 'google/protobuf/any_pb' +require 'google/protobuf/duration_pb' +require 'google/protobuf/field_mask_pb' +require 'google/protobuf/struct_pb' +require 'google/protobuf/timestamp_pb' + +module Google + module Protobuf + + Any.class_eval do + def self.pack(msg, type_url_prefix='type.googleapis.com/') + any = self.new + any.pack(msg, type_url_prefix) + any + end + + def pack(msg, type_url_prefix='type.googleapis.com/') + if type_url_prefix.empty? or type_url_prefix[-1] != '/' then + self.type_url = "#{type_url_prefix}/#{msg.class.descriptor.name}" + else + self.type_url = "#{type_url_prefix}#{msg.class.descriptor.name}" + end + self.value = msg.to_proto + end + + def unpack(klass) + if self.is(klass) then + klass.decode(self.value) + else + nil + end + end + + def type_name + return self.type_url.split("/")[-1] + end + + def is(klass) + return self.type_name == klass.descriptor.name + end + end + + Timestamp.class_eval do + def to_time + Time.at(seconds, nanos, :nanosecond) + end + + def self.from_time(time) + new.from_time(time) + end + + def from_time(time) + self.seconds = time.to_i + self.nanos = time.nsec + self + end + + def to_i + self.seconds + end + + def to_f + self.seconds + (self.nanos.quo(1_000_000_000)) + end + end + + Duration.class_eval do + def to_f + self.seconds + (self.nanos.to_f / 1_000_000_000) + end + end + + class UnexpectedStructType < Google::Protobuf::Error; end + + Value.class_eval do + def to_ruby(recursive = false) + case self.kind + when :struct_value + if recursive + self.struct_value.to_h + else + self.struct_value + end + when :list_value + if recursive + self.list_value.to_a + else + self.list_value + end + when :null_value + nil + when :number_value + self.number_value + when :string_value + self.string_value + when :bool_value + self.bool_value + else + raise UnexpectedStructType + end + end + + def self.from_ruby(value) + self.new.from_ruby(value) + end + + def from_ruby(value) + case value + when NilClass + self.null_value = :NULL_VALUE + when Numeric + self.number_value = value + when String + self.string_value = value + when TrueClass + self.bool_value = true + when FalseClass + self.bool_value = false + when Struct + self.struct_value = value + when Hash + self.struct_value = Struct.from_hash(value) + when ListValue + self.list_value = value + when Array + self.list_value = ListValue.from_a(value) + else + raise UnexpectedStructType + end + + self + end + end + + Struct.class_eval do + def [](key) + self.fields[key].to_ruby + rescue NoMethodError + nil + end + + def []=(key, value) + unless key.is_a?(String) + raise UnexpectedStructType, "Struct keys must be strings." + end + self.fields[key] ||= Google::Protobuf::Value.new + self.fields[key].from_ruby(value) + end + + def to_h + ret = {} + self.fields.each { |key, val| ret[key] = val.to_ruby(true) } + ret + end + + def self.from_hash(hash) + ret = Struct.new + hash.each { |key, val| ret[key] = val } + ret + end + + def has_key?(key) + self.fields.has_key?(key) + end + end + + ListValue.class_eval do + include Enumerable + + def length + self.values.length + end + + def [](index) + self.values[index].to_ruby + end + + def []=(index, value) + self.values[index].from_ruby(value) + end + + def <<(value) + wrapper = Google::Protobuf::Value.new + wrapper.from_ruby(value) + self.values << wrapper + end + + def each + self.values.each { |x| yield(x.to_ruby) } + end + + def to_a + self.values.map { |x| x.to_ruby(true) } + end + + def self.from_a(arr) + ret = ListValue.new + arr.each { |val| ret << val } + ret + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/wrappers_pb.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/wrappers_pb.rb new file mode 100755 index 0000000..ec43b6c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf/wrappers_pb.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/wrappers.proto + +require 'google/protobuf' + + +descriptor_data = "\n\x1egoogle/protobuf/wrappers.proto\x12\x0fgoogle.protobuf\"\x1c\n\x0b\x44oubleValue\x12\r\n\x05value\x18\x01 \x01(\x01\"\x1b\n\nFloatValue\x12\r\n\x05value\x18\x01 \x01(\x02\"\x1b\n\nInt64Value\x12\r\n\x05value\x18\x01 \x01(\x03\"\x1c\n\x0bUInt64Value\x12\r\n\x05value\x18\x01 \x01(\x04\"\x1b\n\nInt32Value\x12\r\n\x05value\x18\x01 \x01(\x05\"\x1c\n\x0bUInt32Value\x12\r\n\x05value\x18\x01 \x01(\r\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\t\"\x1b\n\nBytesValue\x12\r\n\x05value\x18\x01 \x01(\x0c\x42\x83\x01\n\x13\x63om.google.protobufB\rWrappersProtoP\x01Z1google.golang.org/protobuf/types/known/wrapperspb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Google + module Protobuf + DoubleValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.DoubleValue").msgclass + FloatValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.FloatValue").msgclass + Int64Value = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Int64Value").msgclass + UInt64Value = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.UInt64Value").msgclass + Int32Value = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Int32Value").msgclass + UInt32Value = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.UInt32Value").msgclass + BoolValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.BoolValue").msgclass + StringValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.StringValue").msgclass + BytesValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.BytesValue").msgclass + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_ffi.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_ffi.rb new file mode 100755 index 0000000..731848f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_ffi.rb @@ -0,0 +1,52 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2023 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +require 'ffi-compiler/loader' +require 'google/protobuf/ffi/ffi' +require 'google/protobuf/ffi/internal/type_safety' +require 'google/protobuf/ffi/internal/pointer_helper' +require 'google/protobuf/ffi/internal/arena' +require 'google/protobuf/ffi/internal/convert' +require 'google/protobuf/ffi/descriptor' +require 'google/protobuf/ffi/enum_descriptor' +require 'google/protobuf/ffi/field_descriptor' +require 'google/protobuf/ffi/oneof_descriptor' +require 'google/protobuf/ffi/method_descriptor' +require 'google/protobuf/ffi/service_descriptor' +require 'google/protobuf/ffi/file_descriptor' +require 'google/protobuf/ffi/descriptor_pool' +require 'google/protobuf/ffi/map' +require 'google/protobuf/ffi/object_cache' +require 'google/protobuf/ffi/repeated_field' +require 'google/protobuf/ffi/message' + +module Google + module Protobuf + def self.deep_copy(object) + case object + when RepeatedField + RepeatedField.send(:deep_copy, object) + when Google::Protobuf::Map + Google::Protobuf::Map.deep_copy(object) + when Google::Protobuf::MessageExts + object.class.send(:deep_copy, object.instance_variable_get(:@msg)) + else + raise NotImplementedError + end + end + + def self.discard_unknown(message) + raise FrozenError if message.frozen? + raise ArgumentError.new "Expected message, got #{message.class} instead." if message.instance_variable_get(:@msg).nil? + pool_def = message.class.descriptor.instance_variable_get(:@descriptor_pool).descriptor_pool + unless Google::Protobuf::FFI.message_discard_unknown(message.instance_variable_get(:@msg), message.class.descriptor, pool_def, 128) + raise RuntimeError.new "Messages nested too deeply." + end + nil + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_native.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_native.rb new file mode 100755 index 0000000..9605b6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/protobuf_native.rb @@ -0,0 +1,19 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2023 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +if RUBY_PLATFORM == "java" + require 'json' + require 'google/protobuf_java' +else + begin + require "google/#{RUBY_VERSION.sub(/\.\d+$/, '')}/protobuf_c" + rescue LoadError + require 'google/protobuf_c' + end +end + +require 'google/protobuf/repeated_field' diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/tasks/ffi.rake b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/tasks/ffi.rake new file mode 100755 index 0000000..e983c1a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/lib/google/tasks/ffi.rake @@ -0,0 +1,100 @@ +# # @param task [FFI::Compiler::CompileTask] task to configure +def configure_common_compile_task(task) + if FileUtils.pwd.include? 'ext' + src_dir = '.' + third_party_path = 'third_party/utf8_range' + else + src_dir = 'ext/google/protobuf_c' + third_party_path = 'ext/google/protobuf_c/third_party/utf8_range' + end + + task.add_include_path third_party_path + task.add_define 'NDEBUG' + task.cflags << "-std=gnu99 -O3" + [ + :convert, :defs, :map, :message, :protobuf, :repeated_field + ].each { |file| task.exclude << "/#{file}.c" } + task.ext_dir = src_dir + task.source_dirs = [src_dir] + if RbConfig::CONFIG['target_os'] =~ /darwin|linux/ + task.cflags << "-Wall -Wsign-compare -Wno-declaration-after-statement" + end +end + +# FFI::CompilerTask's constructor walks the filesystem at task definition time +# to create subtasks for each source file, so files from third_party must be +# copied into place before the task is defined for it to work correctly. +# TODO Is there a sane way to check for generated protos under lib too? +def with_generated_files + expected_path = FileUtils.pwd.include?('ext') ? 'third_party/utf8_range' : 'ext/google/protobuf_c/third_party/utf8_range' + if File.directory?(expected_path) + yield + else + task :default do + # It is possible, especially in cases like the first invocation of + # `rake test` following `rake clean` or a fresh checkout that the + # `copy_third_party` task has been executed since initial task definition. + # If so, run the task definition block now and invoke it explicitly. + if File.directory?(expected_path) + yield + Rake::Task[:default].invoke + else + raise "Missing directory #{File.absolute_path(expected_path)}." + + " Did you forget to run `rake copy_third_party` before building" + + " native extensions?" + end + end + end +end + +begin + require "ffi-compiler/compile_task" + + desc "Compile Protobuf library for FFI" + namespace "ffi-protobuf" do + with_generated_files do + # Compile Ruby UPB separately in order to limit use of -DUPB_BUILD_API to one + # compilation unit. + desc "Compile UPB library for FFI" + namespace "ffi-upb" do + with_generated_files do + FFI::Compiler::CompileTask.new('ruby-upb') do |c| + configure_common_compile_task c + c.add_define "UPB_BUILD_API" + c.exclude << "/glue.c" + c.exclude << "/shared_message.c" + c.exclude << "/shared_convert.c" + if RbConfig::CONFIG['target_os'] =~ /darwin|linux/ + c.cflags << "-fvisibility=hidden" + end + end + end + end + + FFI::Compiler::CompileTask.new 'protobuf_c_ffi' do |c| + configure_common_compile_task c + # Ruby UPB was already compiled with different flags. + c.exclude << "/utf8_range.c" + c.exclude << "/ruby-upb.c" + end + + # Setup dependencies so that the .o files generated by building ffi-upb are + # available to link here. + # TODO Can this be simplified? Can the single shared library be used + # instead of the object files? + protobuf_c_task = Rake::Task[:default] + protobuf_c_shared_lib_task = Rake::Task[protobuf_c_task.prereqs.last] + ruby_upb_shared_lib_task = Rake::Task[:"ffi-upb:default"].prereqs.first + Rake::Task[ruby_upb_shared_lib_task].prereqs.each do |dependency| + protobuf_c_shared_lib_task.prereqs.prepend dependency + end + end + end +rescue LoadError + desc "Compile Protobuf library for FFI" + namespace "ffi-protobuf" do + task :default do + warn "Skipping build of FFI; `gem install ffi-compiler` to enable." + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/linux.yml b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/linux.yml new file mode 100644 index 0000000..8b27239 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/linux.yml @@ -0,0 +1,23 @@ +name: Testing on Ubuntu +on: + - push + - pull_request +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + ruby: [ '3.1', '3.2', '3.3', '3.4', 'head' ] + os: [ 'ubuntu-latest' ] + name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + - name: unit testing + run: | + gem install bundler rake + bundle install --jobs 4 --retry 3 + bundle exec rake diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/windows.yml b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/windows.yml new file mode 100644 index 0000000..b7d9424 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.github/workflows/windows.yml @@ -0,0 +1,23 @@ +name: Testing on Windows +on: + - push + - pull_request +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + ruby: [ '3.1', '3.2', '3.3', '3.4', 'head' ] + os: [ 'windows-latest' ] + name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + - name: unit testing + run: | + gem install bundler rake + bundle install --jobs 4 --retry 3 + bundle exec rake diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitignore b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitignore new file mode 100644 index 0000000..e887a3e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitignore @@ -0,0 +1,12 @@ +*.bundle +*.bundle +*.gem +*.jar +*.o +*.rbc +*.so +*.swp +Gemfile.lock +Makefile +tags +tmp diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitmodules b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitmodules new file mode 100644 index 0000000..7e46b5c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/.gitmodules @@ -0,0 +1,6 @@ +[submodule "http-parser"] + path = ext/ruby_http_parser/vendor/http-parser + url = https://github.com/nodejs/http-parser.git +[submodule "http-parser-java"] + path = ext/ruby_http_parser/vendor/http-parser-java + url = https://github.com/tmm1/http-parser.java diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Gemfile b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Gemfile new file mode 100644 index 0000000..851fabc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gemspec diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/LICENSE-MIT b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/LICENSE-MIT new file mode 100644 index 0000000..35f0bf0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/LICENSE-MIT @@ -0,0 +1,20 @@ +Copyright 2009,2010 Marc-André Cournoyer +Copyright 2010,2011 Aman Gupta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/README.md b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/README.md new file mode 100644 index 0000000..e29ef2c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/README.md @@ -0,0 +1,90 @@ +# http_parser.rb + +A simple callback-based HTTP request/response parser for writing http +servers, clients and proxies. + +This gem is built on top of [joyent/http-parser](https://github.com/joyent/http-parser) and its java port [http-parser/http-parser.java](https://github.com/http-parser/http-parser.java). + +## Supported Platforms + +This gem aims to work on all major Ruby platforms, including: + +- MRI 1.8, 1.9 and 2.0; should work on MRI 2.4+ +- Rubinius +- JRuby +- win32 + +## Usage + +```ruby +require "http/parser" + +parser = Http::Parser.new + +parser.on_headers_complete = proc do + p parser.http_version + + p parser.http_method # for requests + p parser.request_url + + p parser.status_code # for responses + + p parser.headers +end + +parser.on_body = proc do |chunk| + # One chunk of the body + p chunk +end + +parser.on_message_complete = proc do |env| + # Headers and body is all parsed + puts "Done!" +end +``` + +# Feed raw data from the socket to the parser +`parser << raw_data` + +## Advanced Usage + +### Accept callbacks on an object + +```ruby +module MyHttpConnection + def connection_completed + @parser = Http::Parser.new(self) + end + + def receive_data(data) + @parser << data + end + + def on_message_begin + @headers = nil + @body = '' + end + + def on_headers_complete(headers) + @headers = headers + end + + def on_body(chunk) + @body << chunk + end + + def on_message_complete + p [@headers, @body] + end +end +``` + +### Stop parsing after headers + +```ruby +parser = Http::Parser.new +parser.on_headers_complete = proc{ :stop } + +offset = parser << request_data +body = request_data[offset..-1] +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Rakefile b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Rakefile new file mode 100644 index 0000000..1820ad1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/Rakefile @@ -0,0 +1,8 @@ +require 'bundler/gem_tasks' + +# default task +task :compile => :submodules +task :default => [:compile, :spec] + +# load tasks +Dir['tasks/*.rake'].sort.each { |f| load f } diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/standalone.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/standalone.rb new file mode 100755 index 0000000..6b4dcb6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/standalone.rb @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +$:.unshift File.dirname(__FILE__) + "/../lib" +require "rubygems" +require "http/parser" +require "benchmark/ips" + +request = <<-REQUEST +GET / HTTP/1.1 +Host: www.example.com +Connection: keep-alive +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.78 S +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Encoding: gzip,deflate,sdch +Accept-Language: en-US,en;q=0.8 +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 + +REQUEST +request.gsub!(/\n/m, "\r\n") + +Benchmark.ips do |ips| + ips.report("instance") { Http::Parser.new } + ips.report("parsing") { Http::Parser.new << request } +end diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/thin.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/thin.rb new file mode 100644 index 0000000..fe0dd6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/bench/thin.rb @@ -0,0 +1,58 @@ +$:.unshift File.dirname(__FILE__) + "/../lib" +require "rubygems" +require "thin_parser" +require "http_parser" +require "benchmark" +require "stringio" + +data = "POST /postit HTTP/1.1\r\n" + + "Host: localhost:3000\r\n" + + "User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9\r\n" + + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n" + + "Accept-Language: en-us,en;q=0.5\r\n" + + "Accept-Encoding: gzip,deflate\r\n" + + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" + + "Keep-Alive: 300\r\n" + + "Connection: keep-alive\r\n" + + "Content-Type: text/html\r\n" + + "Content-Length: 37\r\n" + + "\r\n" + + "name=marc&email=macournoyer@gmail.com" + +def thin(data) + env = {"rack.input" => StringIO.new} + Thin::HttpParser.new.execute(env, data, 0) + env +end + +def http_parser(data) + body = StringIO.new + env = nil + + parser = HTTP::RequestParser.new + parser.on_headers_complete = proc { |e| env = e } + parser.on_body = proc { |c| body << c } + parser << data + + env["rack-input"] = body + env +end + +# p thin(data) +# p http_parser(data) + +TESTS = 30_000 +Benchmark.bmbm do |results| + results.report("thin:") { TESTS.times { thin data } } + results.report("http-parser:") { TESTS.times { http_parser data } } +end + +# On my MBP core duo 2.2Ghz +# Rehearsal ------------------------------------------------ +# thin: 1.470000 0.000000 1.470000 ( 1.474737) +# http-parser: 1.270000 0.020000 1.290000 ( 1.292758) +# --------------------------------------- total: 2.760000sec +# +# user system total real +# thin: 1.150000 0.030000 1.180000 ( 1.173767) +# http-parser: 1.250000 0.010000 1.260000 ( 1.263796) diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/.gitignore b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/.gitignore new file mode 100644 index 0000000..cb899d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/.gitignore @@ -0,0 +1 @@ +ryah_http_parser.* diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/RubyHttpParserService.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/RubyHttpParserService.java new file mode 100644 index 0000000..2ea3e8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/RubyHttpParserService.java @@ -0,0 +1,18 @@ +import java.io.IOException; + +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.runtime.load.BasicLibraryService; + +import org.ruby_http_parser.*; + +public class RubyHttpParserService implements BasicLibraryService { + public boolean basicLoad(final Ruby runtime) throws IOException { + RubyModule mHTTP = runtime.defineModule("HTTP"); + RubyClass cParser = mHTTP.defineClassUnder("Parser", runtime.getObject(), RubyHttpParser.ALLOCATOR); + cParser.defineAnnotatedMethods(RubyHttpParser.class); + cParser.defineClassUnder("Error", runtime.getClass("IOError"),runtime.getClass("IOError").getAllocator()); + return true; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ext_help.h b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ext_help.h new file mode 100644 index 0000000..f9a0bf6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ext_help.h @@ -0,0 +1,23 @@ +#ifndef ext_help_h +#define ext_help_h + +#define RAISE_NOT_NULL(T) if(T == NULL) rb_raise(rb_eArgError, "NULL found for " # T " when shouldn't be."); +#ifdef TypedData_Get_Struct +#define DATA_GET_STRUCT(from,type,name) TypedData_Get_Struct(from,type,&type##_type,name) +#else +#define DATA_GET_STRUCT(from,type,name) Data_Get_Struct(from,type,name) +#endif +#define DATA_GET(from,type,name) DATA_GET_STRUCT(from,type,name); RAISE_NOT_NULL(name); +#define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "Wrong argument type for " # V " required " # T); + +/* for compatibility with Ruby 1.8.5, which doesn't declare RSTRING_PTR */ +#ifndef RSTRING_PTR +#define RSTRING_PTR(s) (RSTRING(s)->ptr) +#endif + +/* for compatibility with Ruby 1.8.5, which doesn't declare RSTRING_LEN */ +#ifndef RSTRING_LEN +#define RSTRING_LEN(s) (RSTRING(s)->len) +#endif + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/extconf.rb new file mode 100644 index 0000000..0433f9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/extconf.rb @@ -0,0 +1,24 @@ +require 'mkmf' + +# check out code if it hasn't been already +if Dir[File.expand_path('../vendor/http-parser/*', __FILE__)].empty? + Dir.chdir(File.expand_path('../../../', __FILE__)) do + xsystem 'git submodule init' + xsystem 'git submodule update' + end +end + +# mongrel and http-parser both define http_parser_(init|execute), so we +# rename functions in http-parser before using them. +vendor_dir = File.expand_path('../vendor/http-parser/', __FILE__) +src_dir = File.expand_path('../', __FILE__) +%w[ http_parser.c http_parser.h ].each do |file| + File.open(File.join(src_dir, "ryah_#{file}"), 'w'){ |f| + f.write File.read(File.join(vendor_dir, file)).gsub('http_parser', 'ryah_http_parser') + } +end + +$CFLAGS << " -I\"#{src_dir}\"" + +dir_config("ruby_http_parser") +create_makefile("ruby_http_parser") diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java new file mode 100644 index 0000000..1b97269 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java @@ -0,0 +1,502 @@ +package org.ruby_http_parser; + +import http_parser.HTTPException; +import http_parser.HTTPMethod; +import http_parser.HTTPParser; +import http_parser.lolevel.HTTPCallback; +import http_parser.lolevel.HTTPDataCallback; +import http_parser.lolevel.ParserSettings; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; + +import org.jcodings.Encoding; +import org.jcodings.specific.UTF8Encoding; +import org.jruby.Ruby; +import org.jruby.RubyArray; +import org.jruby.RubyClass; +import org.jruby.RubyHash; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.RubyString; +import org.jruby.RubySymbol; +import org.jruby.anno.JRubyMethod; +import org.jruby.exceptions.RaiseException; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.util.ByteList; + +public class RubyHttpParser extends RubyObject { + + @JRubyMethod(name = "strict?", module = true) + public static IRubyObject strict(IRubyObject recv) { + return recv.getRuntime().newBoolean(true); + } + + public static ObjectAllocator ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klass) { + return new RubyHttpParser(runtime, klass); + } + }; + + byte[] fetchBytes(ByteBuffer b, int pos, int len) { + byte[] by = new byte[len]; + int saved = b.position(); + b.position(pos); + b.get(by); + b.position(saved); + return by; + } + + public class StopException extends RuntimeException { + } + + private Ruby runtime; + private HTTPParser parser; + private ParserSettings settings; + + private RubyClass eParserError; + + private RubyHash headers; + + private IRubyObject on_message_begin; + private IRubyObject on_headers_complete; + private IRubyObject on_body; + private IRubyObject on_message_complete; + + private IRubyObject requestUrl; + private IRubyObject requestPath; + private IRubyObject queryString; + private IRubyObject fragment; + + private IRubyObject header_value_type; + private IRubyObject upgradeData; + + private IRubyObject callback_object; + + private boolean completed; + + private byte[] _current_header; + private byte[] _last_header; + + private static final Encoding UTF8 = UTF8Encoding.INSTANCE; + + private static final List VALUE_TYPES = new ArrayList( + Arrays.asList("mixed", "arrays", "strings") + ); + + public RubyHttpParser(final Ruby runtime, RubyClass clazz) { + super(runtime, clazz); + + this.runtime = runtime; + this.eParserError = (RubyClass) runtime.getModule("HTTP").getClass("Parser").getConstant("Error"); + + this.on_message_begin = null; + this.on_headers_complete = null; + this.on_body = null; + this.on_message_complete = null; + + this.callback_object = null; + + this.completed = false; + + this.header_value_type = runtime.getModule("HTTP").getClass("Parser") + .getInstanceVariable("@default_header_value_type"); + + initSettings(); + init(); + } + + private void initSettings() { + this.settings = new ParserSettings(); + + this.settings.on_url = new HTTPDataCallback() { + public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) { + byte[] data = fetchBytes(buf, pos, len); + if (runtime.is1_9() || runtime.is2_0()) { + ((RubyString) requestUrl).cat(data, 0, data.length, UTF8); + } else { + ((RubyString) requestUrl).cat(data); + } + return 0; + } + }; + + this.settings.on_header_field = new HTTPDataCallback() { + public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) { + byte[] data = fetchBytes(buf, pos, len); + + if (_current_header == null) + _current_header = data; + else { + byte[] tmp = new byte[_current_header.length + data.length]; + System.arraycopy(_current_header, 0, tmp, 0, _current_header.length); + System.arraycopy(data, 0, tmp, _current_header.length, data.length); + _current_header = tmp; + } + + return 0; + } + }; + final RubySymbol arraysSym = runtime.newSymbol("arrays"); + final RubySymbol mixedSym = runtime.newSymbol("mixed"); + final RubySymbol stopSym = runtime.newSymbol("stop"); + final RubySymbol resetSym = runtime.newSymbol("reset"); + this.settings.on_header_value = new HTTPDataCallback() { + public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) { + byte[] data = fetchBytes(buf, pos, len); + ThreadContext context = headers.getRuntime().getCurrentContext(); + IRubyObject key, val; + int new_field = 0; + + if (_current_header != null) { + new_field = 1; + _last_header = _current_header; + _current_header = null; + } + + key = RubyString.newString(runtime, new ByteList(_last_header, UTF8, false)); + val = headers.op_aref(context, key); + + if (new_field == 1) { + if (val.isNil()) { + if (header_value_type == arraysSym) { + headers.op_aset(context, key, + RubyArray.newArrayLight(runtime, RubyString.newStringLight(runtime, 10, UTF8))); + } else { + headers.op_aset(context, key, RubyString.newStringLight(runtime, 10, UTF8)); + } + } else { + if (header_value_type == mixedSym) { + if (val instanceof RubyString) { + headers.op_aset(context, key, + RubyArray.newArrayLight(runtime, val, RubyString.newStringLight(runtime, 10, UTF8))); + } else { + ((RubyArray) val).add(RubyString.newStringLight(runtime, 10, UTF8)); + } + } else if (header_value_type == arraysSym) { + ((RubyArray) val).add(RubyString.newStringLight(runtime, 10, UTF8)); + } else { + if (runtime.is1_9() || runtime.is2_0()) { + ((RubyString) val).cat(',', UTF8).cat(' ', UTF8); + } else { + ((RubyString) val).cat(',').cat(' '); + } + } + } + val = headers.op_aref(context, key); + } + + if (val instanceof RubyArray) { + val = ((RubyArray) val).entry(-1); + } + + if (runtime.is1_9() || runtime.is2_0()) { + ((RubyString) val).cat(data, 0, data.length, UTF8); + } else { + ((RubyString) val).cat(data); + } + + return 0; + } + }; + + this.settings.on_message_begin = new HTTPCallback() { + public int cb(http_parser.lolevel.HTTPParser p) { + headers = new RubyHash(runtime); + + if (runtime.is1_9() || runtime.is2_0()) { + requestUrl = RubyString.newEmptyString(runtime, UTF8); + requestPath = RubyString.newEmptyString(runtime, UTF8); + queryString = RubyString.newEmptyString(runtime, UTF8); + fragment = RubyString.newEmptyString(runtime, UTF8); + upgradeData = RubyString.newEmptyString(runtime, UTF8); + } else { + requestUrl = RubyString.newEmptyString(runtime); + requestPath = RubyString.newEmptyString(runtime); + queryString = RubyString.newEmptyString(runtime); + fragment = RubyString.newEmptyString(runtime); + upgradeData = RubyString.newEmptyString(runtime); + } + + IRubyObject ret = runtime.getNil(); + + if (callback_object != null) { + if (((RubyObject) callback_object).respondsTo("on_message_begin")) { + ThreadContext context = callback_object.getRuntime().getCurrentContext(); + ret = callback_object.callMethod(context, "on_message_begin"); + } + } else if (on_message_begin != null) { + ThreadContext context = on_message_begin.getRuntime().getCurrentContext(); + ret = on_message_begin.callMethod(context, "call"); + } + + if (ret == stopSym) { + throw new StopException(); + } else { + return 0; + } + } + }; + this.settings.on_message_complete = new HTTPCallback() { + public int cb(http_parser.lolevel.HTTPParser p) { + IRubyObject ret = runtime.getNil(); + + completed = true; + + if (callback_object != null) { + if (((RubyObject) callback_object).respondsTo("on_message_complete")) { + ThreadContext context = callback_object.getRuntime().getCurrentContext(); + ret = callback_object.callMethod(context, "on_message_complete"); + } + } else if (on_message_complete != null) { + ThreadContext context = on_message_complete.getRuntime().getCurrentContext(); + ret = on_message_complete.callMethod(context, "call"); + } + + if (ret == stopSym) { + throw new StopException(); + } else { + return 0; + } + } + }; + this.settings.on_headers_complete = new HTTPCallback() { + public int cb(http_parser.lolevel.HTTPParser p) { + IRubyObject ret = runtime.getNil(); + + if (callback_object != null) { + if (((RubyObject) callback_object).respondsTo("on_headers_complete")) { + ThreadContext context = callback_object.getRuntime().getCurrentContext(); + ret = callback_object.callMethod(context, "on_headers_complete", headers); + } + } else if (on_headers_complete != null) { + ThreadContext context = on_headers_complete.getRuntime().getCurrentContext(); + ret = on_headers_complete.callMethod(context, "call", headers); + } + + if (ret == stopSym) { + throw new StopException(); + } else if (ret == resetSym) { + return 1; + } else { + return 0; + } + } + }; + this.settings.on_body = new HTTPDataCallback() { + public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) { + IRubyObject ret = runtime.getNil(); + byte[] data = fetchBytes(buf, pos, len); + + if (callback_object != null) { + if (((RubyObject) callback_object).respondsTo("on_body")) { + ThreadContext context = callback_object.getRuntime().getCurrentContext(); + ret = callback_object.callMethod(context, "on_body", + RubyString.newString(runtime, new ByteList(data, UTF8, false))); + } + } else if (on_body != null) { + ThreadContext context = on_body.getRuntime().getCurrentContext(); + ret = on_body.callMethod(context, "call", RubyString.newString(runtime, new ByteList(data, UTF8, false))); + } + + if (ret == stopSym) { + throw new StopException(); + } else { + return 0; + } + } + }; + } + + private void init() { + this.parser = new HTTPParser(); + this.parser.HTTP_PARSER_STRICT = true; + this.headers = null; + + this.requestUrl = runtime.getNil(); + this.requestPath = runtime.getNil(); + this.queryString = runtime.getNil(); + this.fragment = runtime.getNil(); + + this.upgradeData = runtime.getNil(); + } + + @JRubyMethod(name = "initialize") + public IRubyObject initialize() { + return this; + } + + @JRubyMethod(name = "initialize") + public IRubyObject initialize(IRubyObject arg) { + callback_object = arg; + return initialize(); + } + + @JRubyMethod(name = "initialize") + public IRubyObject initialize(IRubyObject arg, IRubyObject arg2) { + header_value_type = arg2; + return initialize(arg); + } + + @JRubyMethod(name = "on_message_begin=") + public IRubyObject set_on_message_begin(IRubyObject cb) { + on_message_begin = cb; + return cb; + } + + @JRubyMethod(name = "on_headers_complete=") + public IRubyObject set_on_headers_complete(IRubyObject cb) { + on_headers_complete = cb; + return cb; + } + + @JRubyMethod(name = "on_body=") + public IRubyObject set_on_body(IRubyObject cb) { + on_body = cb; + return cb; + } + + @JRubyMethod(name = "on_message_complete=") + public IRubyObject set_on_message_complete(IRubyObject cb) { + on_message_complete = cb; + return cb; + } + + @JRubyMethod(name = "<<") + public IRubyObject execute(IRubyObject data) { + RubyString str = (RubyString) data; + ByteList byteList = str.getByteList(); + ByteBuffer buf = ByteBuffer.wrap(byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize()); + boolean stopped = false; + + try { + this.parser.execute(this.settings, buf); + } catch (HTTPException e) { + throw new RaiseException(runtime, eParserError, e.getMessage(), true); + } catch (StopException e) { + stopped = true; + } + + if (parser.getUpgrade()) { + byte[] upData = fetchBytes(buf, buf.position(), buf.limit() - buf.position()); + if (runtime.is1_9() || runtime.is2_0()) { + ((RubyString) upgradeData).cat(upData, 0, upData.length, UTF8); + } else { + ((RubyString) upgradeData).cat(upData); + } + } else if (buf.hasRemaining() && !completed) { + if (!stopped) + throw new RaiseException(runtime, eParserError, "Could not parse data entirely", true); + } + + return RubyNumeric.int2fix(runtime, buf.position()); + } + + @JRubyMethod(name = "keep_alive?") + public IRubyObject shouldKeepAlive() { + return runtime.newBoolean(parser.shouldKeepAlive()); + } + + @JRubyMethod(name = "upgrade?") + public IRubyObject shouldUpgrade() { + return runtime.newBoolean(parser.getUpgrade()); + } + + @JRubyMethod(name = "http_major") + public IRubyObject httpMajor() { + if (parser.getMajor() == 0 && parser.getMinor() == 0) + return runtime.getNil(); + else + return RubyNumeric.int2fix(runtime, parser.getMajor()); + } + + @JRubyMethod(name = "http_minor") + public IRubyObject httpMinor() { + if (parser.getMajor() == 0 && parser.getMinor() == 0) + return runtime.getNil(); + else + return RubyNumeric.int2fix(runtime, parser.getMinor()); + } + + @JRubyMethod(name = "http_version") + public IRubyObject httpVersion() { + if (parser.getMajor() == 0 && parser.getMinor() == 0) + return runtime.getNil(); + else + return runtime.newArray(httpMajor(), httpMinor()); + } + + @JRubyMethod(name = "http_method") + public IRubyObject httpMethod() { + HTTPMethod method = parser.getHTTPMethod(); + if (method != null) + return runtime.newString(new String(method.bytes)); + else + return runtime.getNil(); + } + + @JRubyMethod(name = "status_code") + public IRubyObject statusCode() { + int code = parser.getStatusCode(); + if (code != 0) + return RubyNumeric.int2fix(runtime, code); + else + return runtime.getNil(); + } + + @JRubyMethod(name = "headers") + public IRubyObject getHeaders() { + return headers == null ? runtime.getNil() : headers; + } + + @JRubyMethod(name = "request_url") + public IRubyObject getRequestUrl() { + return requestUrl == null ? runtime.getNil() : requestUrl; + } + + @JRubyMethod(name = "request_path") + public IRubyObject getRequestPath() { + return requestPath == null ? runtime.getNil() : requestPath; + } + + @JRubyMethod(name = "query_string") + public IRubyObject getQueryString() { + return queryString == null ? runtime.getNil() : queryString; + } + + @JRubyMethod(name = "fragment") + public IRubyObject getFragment() { + return fragment == null ? runtime.getNil() : fragment; + } + + @JRubyMethod(name = "header_value_type") + public IRubyObject getHeaderValueType() { + return header_value_type == null ? runtime.getNil() : header_value_type; + } + + @JRubyMethod(name = "header_value_type=") + public IRubyObject set_header_value_type(IRubyObject val) { + String valString = val.toString(); + if (!VALUE_TYPES.contains(valString)) { + throw runtime.newArgumentError("Invalid header value type"); + } + header_value_type = val; + return val; + } + + @JRubyMethod(name = "upgrade_data") + public IRubyObject upgradeData() { + return upgradeData == null ? runtime.getNil() : upgradeData; + } + + @JRubyMethod(name = "reset!") + public IRubyObject reset() { + init(); + return runtime.getTrue(); + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ruby_http_parser.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ruby_http_parser.c new file mode 100644 index 0000000..c506e22 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/ruby_http_parser.c @@ -0,0 +1,569 @@ +#include "ruby.h" +#include "ext_help.h" +#include "ryah_http_parser.h" + +#define GET_WRAPPER(N, from) ParserWrapper *N = (ParserWrapper *)(from)->data; +#define HASH_CAT(h, k, ptr, len) \ + do { \ + VALUE __v = rb_hash_aref(h, k); \ + if (__v != Qnil) { \ + rb_str_cat(__v, ptr, len); \ + } else { \ + rb_hash_aset(h, k, rb_str_new(ptr, len)); \ + } \ + } while(0) + +typedef struct ParserWrapper { + ryah_http_parser parser; + + VALUE status; + VALUE request_url; + + VALUE headers; + + VALUE upgrade_data; + + VALUE on_message_begin; + VALUE on_headers_complete; + VALUE on_body; + VALUE on_message_complete; + + VALUE callback_object; + VALUE stopped; + VALUE completed; + + VALUE header_value_type; + + VALUE last_field_name; + VALUE curr_field_name; + + enum ryah_http_parser_type type; +} ParserWrapper; + +void ParserWrapper_init(ParserWrapper *wrapper) { + ryah_http_parser_init(&wrapper->parser, wrapper->type); + wrapper->parser.status_code = 0; + wrapper->parser.http_major = 0; + wrapper->parser.http_minor = 0; + + wrapper->status = Qnil; + wrapper->request_url = Qnil; + + wrapper->upgrade_data = Qnil; + + wrapper->headers = Qnil; + wrapper->completed = Qfalse; + + wrapper->last_field_name = Qnil; + wrapper->curr_field_name = Qnil; +} + +void ParserWrapper_mark(void *data) { + if(data) { + ParserWrapper *wrapper = (ParserWrapper *) data; + rb_gc_mark_maybe(wrapper->status); + rb_gc_mark_maybe(wrapper->request_url); + rb_gc_mark_maybe(wrapper->upgrade_data); + rb_gc_mark_maybe(wrapper->headers); + rb_gc_mark_maybe(wrapper->on_message_begin); + rb_gc_mark_maybe(wrapper->on_headers_complete); + rb_gc_mark_maybe(wrapper->on_body); + rb_gc_mark_maybe(wrapper->on_message_complete); + rb_gc_mark_maybe(wrapper->callback_object); + rb_gc_mark_maybe(wrapper->last_field_name); + rb_gc_mark_maybe(wrapper->curr_field_name); + } +} + +void ParserWrapper_free(void *data) { + if(data) { + free(data); + } +} + +static const rb_data_type_t ParserWrapper_type = { + "ParserWrapper", + { + ParserWrapper_mark, + ParserWrapper_free, + }, +}; + +static VALUE cParser; +static VALUE cRequestParser; +static VALUE cResponseParser; + +static VALUE eParserError; + +static ID Icall; +static ID Ion_message_begin; +static ID Ion_headers_complete; +static ID Ion_body; +static ID Ion_message_complete; + +static VALUE Sstop; +static VALUE Sreset; +static VALUE Sarrays; +static VALUE Sstrings; +static VALUE Smixed; + +/** Callbacks **/ + +int on_message_begin(ryah_http_parser *parser) { + GET_WRAPPER(wrapper, parser); + + wrapper->status = rb_str_new2(""); + wrapper->request_url = rb_str_new2(""); + wrapper->headers = rb_hash_new(); + wrapper->upgrade_data = rb_str_new2(""); + + VALUE ret = Qnil; + + if (wrapper->callback_object != Qnil && rb_respond_to(wrapper->callback_object, Ion_message_begin)) { + ret = rb_funcall(wrapper->callback_object, Ion_message_begin, 0); + } else if (wrapper->on_message_begin != Qnil) { + ret = rb_funcall(wrapper->on_message_begin, Icall, 0); + } + + if (ret == Sstop) { + wrapper->stopped = Qtrue; + return -1; + } else { + return 0; + } +} + +int on_status(ryah_http_parser *parser, const char *at, size_t length) { + GET_WRAPPER(wrapper, parser); + + if (at && length) { + if (wrapper->status == Qnil) { + wrapper->status = rb_str_new(at, length); + } else { + rb_str_cat(wrapper->status, at, length); + } + } + return 0; +} + +int on_url(ryah_http_parser *parser, const char *at, size_t length) { + GET_WRAPPER(wrapper, parser); + if (at && length) { + if (wrapper->request_url == Qnil) { + wrapper->request_url = rb_str_new(at, length); + } else { + rb_str_cat(wrapper->request_url, at, length); + } + } + return 0; +} + +int on_header_field(ryah_http_parser *parser, const char *at, size_t length) { + GET_WRAPPER(wrapper, parser); + + if (wrapper->curr_field_name == Qnil) { + wrapper->last_field_name = Qnil; + wrapper->curr_field_name = rb_str_new(at, length); + } else { + rb_str_cat(wrapper->curr_field_name, at, length); + } + return 0; +} + +int on_header_value(ryah_http_parser *parser, const char *at, size_t length) { + GET_WRAPPER(wrapper, parser); + + int new_field = 0; + VALUE current_value; + + if (wrapper->last_field_name == Qnil) { + new_field = 1; + wrapper->last_field_name = wrapper->curr_field_name; + wrapper->curr_field_name = Qnil; + } + + current_value = rb_hash_aref(wrapper->headers, wrapper->last_field_name); + + if (new_field == 1) { + if (current_value == Qnil) { + if (wrapper->header_value_type == Sarrays) { + rb_hash_aset(wrapper->headers, wrapper->last_field_name, rb_ary_new3(1, rb_str_new2(""))); + } else { + rb_hash_aset(wrapper->headers, wrapper->last_field_name, rb_str_new2("")); + } + } else { + if (wrapper->header_value_type == Smixed) { + if (TYPE(current_value) == T_STRING) { + rb_hash_aset(wrapper->headers, wrapper->last_field_name, rb_ary_new3(2, current_value, rb_str_new2(""))); + } else { + rb_ary_push(current_value, rb_str_new2("")); + } + } else if (wrapper->header_value_type == Sarrays) { + rb_ary_push(current_value, rb_str_new2("")); + } else { + rb_str_cat(current_value, ", ", 2); + } + } + current_value = rb_hash_aref(wrapper->headers, wrapper->last_field_name); + } + + if (TYPE(current_value) == T_ARRAY) { + current_value = rb_ary_entry(current_value, -1); + } + + rb_str_cat(current_value, at, length); + + return 0; +} + +int on_headers_complete(ryah_http_parser *parser) { + GET_WRAPPER(wrapper, parser); + + VALUE ret = Qnil; + + if (wrapper->callback_object != Qnil && rb_respond_to(wrapper->callback_object, Ion_headers_complete)) { + ret = rb_funcall(wrapper->callback_object, Ion_headers_complete, 1, wrapper->headers); + } else if (wrapper->on_headers_complete != Qnil) { + ret = rb_funcall(wrapper->on_headers_complete, Icall, 1, wrapper->headers); + } + + if (ret == Sstop) { + wrapper->stopped = Qtrue; + return -1; + } else if (ret == Sreset){ + return 1; + } else { + return 0; + } +} + +int on_body(ryah_http_parser *parser, const char *at, size_t length) { + GET_WRAPPER(wrapper, parser); + + VALUE ret = Qnil; + + if (wrapper->callback_object != Qnil && rb_respond_to(wrapper->callback_object, Ion_body)) { + ret = rb_funcall(wrapper->callback_object, Ion_body, 1, rb_str_new(at, length)); + } else if (wrapper->on_body != Qnil) { + ret = rb_funcall(wrapper->on_body, Icall, 1, rb_str_new(at, length)); + } + + if (ret == Sstop) { + wrapper->stopped = Qtrue; + return -1; + } else { + return 0; + } +} + +int on_message_complete(ryah_http_parser *parser) { + GET_WRAPPER(wrapper, parser); + + VALUE ret = Qnil; + wrapper->completed = Qtrue; + + if (wrapper->callback_object != Qnil && rb_respond_to(wrapper->callback_object, Ion_message_complete)) { + ret = rb_funcall(wrapper->callback_object, Ion_message_complete, 0); + } else if (wrapper->on_message_complete != Qnil) { + ret = rb_funcall(wrapper->on_message_complete, Icall, 0); + } + + if (ret == Sstop) { + wrapper->stopped = Qtrue; + return -1; + } else { + return 0; + } +} + +static ryah_http_parser_settings settings = { + .on_message_begin = on_message_begin, + .on_status = on_status, + .on_url = on_url, + .on_header_field = on_header_field, + .on_header_value = on_header_value, + .on_headers_complete = on_headers_complete, + .on_body = on_body, + .on_message_complete = on_message_complete +}; + +VALUE Parser_alloc_by_type(VALUE klass, enum ryah_http_parser_type type) { + ParserWrapper *wrapper = ALLOC_N(ParserWrapper, 1); + wrapper->type = type; + wrapper->parser.data = wrapper; + + wrapper->on_message_begin = Qnil; + wrapper->on_headers_complete = Qnil; + wrapper->on_body = Qnil; + wrapper->on_message_complete = Qnil; + + wrapper->callback_object = Qnil; + + ParserWrapper_init(wrapper); + + return TypedData_Wrap_Struct(klass, &ParserWrapper_type, wrapper); +} + +VALUE Parser_alloc(VALUE klass) { + return Parser_alloc_by_type(klass, HTTP_BOTH); +} + +VALUE RequestParser_alloc(VALUE klass) { + return Parser_alloc_by_type(klass, HTTP_REQUEST); +} + +VALUE ResponseParser_alloc(VALUE klass) { + return Parser_alloc_by_type(klass, HTTP_RESPONSE); +} + +VALUE Parser_strict_p(VALUE klass) { + return HTTP_PARSER_STRICT == 1 ? Qtrue : Qfalse; +} + +VALUE Parser_initialize(int argc, VALUE *argv, VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + VALUE default_header_value_type = Qnil; + + if (argc > 0 && RB_TYPE_P(argv[argc-1], T_HASH)) { + ID keyword_ids[1]; + keyword_ids[0] = rb_intern("default_header_value_type"); + rb_get_kwargs(argv[argc-1], keyword_ids, 0, 1, &default_header_value_type); + if (default_header_value_type == Qundef) { + default_header_value_type = Qnil; + } + --argc; + } + + if (argc == 1) { + wrapper->callback_object = argv[0]; + } + + if (argc == 2) { + wrapper->callback_object = argv[0]; + default_header_value_type = argv[1]; + } + + if (default_header_value_type == Qnil) { + wrapper->header_value_type = rb_iv_get(CLASS_OF(self), "@default_header_value_type"); + } else { + wrapper->header_value_type = default_header_value_type; + } + + return self; +} + +VALUE Parser_execute(VALUE self, VALUE data) { + ParserWrapper *wrapper = NULL; + + Check_Type(data, T_STRING); + char *ptr = RSTRING_PTR(data); + long len = RSTRING_LEN(data); + + DATA_GET(self, ParserWrapper, wrapper); + + wrapper->stopped = Qfalse; + size_t nparsed = ryah_http_parser_execute(&wrapper->parser, &settings, ptr, len); + + if (wrapper->parser.upgrade) { + if (RTEST(wrapper->stopped) && !RTEST(wrapper->completed)) + nparsed += 1; + + if (nparsed < len) + rb_str_cat(wrapper->upgrade_data, ptr + nparsed, len - nparsed); + + } else if (nparsed != (size_t)len) { + if (!RTEST(wrapper->stopped) && !RTEST(wrapper->completed)) + rb_raise(eParserError, "Could not parse data entirely (%zu != %zu)", nparsed, len); + else + nparsed += 1; // error states fail on the current character + } + + return INT2FIX(nparsed); +} + +VALUE Parser_set_on_message_begin(VALUE self, VALUE callback) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + wrapper->on_message_begin = callback; + return callback; +} + +VALUE Parser_set_on_headers_complete(VALUE self, VALUE callback) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + wrapper->on_headers_complete = callback; + return callback; +} + +VALUE Parser_set_on_body(VALUE self, VALUE callback) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + wrapper->on_body = callback; + return callback; +} + +VALUE Parser_set_on_message_complete(VALUE self, VALUE callback) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + wrapper->on_message_complete = callback; + return callback; +} + +VALUE Parser_keep_alive_p(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + return http_should_keep_alive(&wrapper->parser) == 1 ? Qtrue : Qfalse; +} + +VALUE Parser_upgrade_p(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + return wrapper->parser.upgrade ? Qtrue : Qfalse; +} + +VALUE Parser_http_version(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + if (wrapper->parser.http_major == 0 && wrapper->parser.http_minor == 0) + return Qnil; + else + return rb_ary_new3(2, INT2FIX(wrapper->parser.http_major), INT2FIX(wrapper->parser.http_minor)); +} + +VALUE Parser_http_major(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + if (wrapper->parser.http_major == 0 && wrapper->parser.http_minor == 0) + return Qnil; + else + return INT2FIX(wrapper->parser.http_major); +} + +VALUE Parser_http_minor(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + if (wrapper->parser.http_major == 0 && wrapper->parser.http_minor == 0) + return Qnil; + else + return INT2FIX(wrapper->parser.http_minor); +} + +VALUE Parser_http_method(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + if (wrapper->parser.type == HTTP_REQUEST) + return rb_str_new2(http_method_str(wrapper->parser.method)); + else + return Qnil; +} + +VALUE Parser_status_code(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + if (wrapper->parser.status_code) + return INT2FIX(wrapper->parser.status_code); + else + return Qnil; +} + +#define DEFINE_GETTER(name) \ + VALUE Parser_##name(VALUE self) { \ + ParserWrapper *wrapper = NULL; \ + DATA_GET(self, ParserWrapper, wrapper); \ + return wrapper->name; \ + } + +DEFINE_GETTER(status); +DEFINE_GETTER(request_url); +DEFINE_GETTER(headers); +DEFINE_GETTER(upgrade_data); +DEFINE_GETTER(header_value_type); + +VALUE Parser_set_header_value_type(VALUE self, VALUE val) { + if (val != Sarrays && val != Sstrings && val != Smixed) { + rb_raise(rb_eArgError, "Invalid header value type"); + } + + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + wrapper->header_value_type = val; + return wrapper->header_value_type; +} + +VALUE Parser_reset(VALUE self) { + ParserWrapper *wrapper = NULL; + DATA_GET(self, ParserWrapper, wrapper); + + ParserWrapper_init(wrapper); + + return Qtrue; +} + +void Init_ruby_http_parser() { +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + + VALUE mHTTP = rb_define_module("HTTP"); + cParser = rb_define_class_under(mHTTP, "Parser", rb_cObject); + cRequestParser = rb_define_class_under(mHTTP, "RequestParser", cParser); + cResponseParser = rb_define_class_under(mHTTP, "ResponseParser", cParser); + + eParserError = rb_define_class_under(cParser, "Error", rb_eIOError); + Icall = rb_intern("call"); + Ion_message_begin = rb_intern("on_message_begin"); + Ion_headers_complete = rb_intern("on_headers_complete"); + Ion_body = rb_intern("on_body"); + Ion_message_complete = rb_intern("on_message_complete"); + Sstop = ID2SYM(rb_intern("stop")); + Sreset = ID2SYM(rb_intern("reset")); + + Sarrays = ID2SYM(rb_intern("arrays")); + Sstrings = ID2SYM(rb_intern("strings")); + Smixed = ID2SYM(rb_intern("mixed")); + + rb_define_alloc_func(cParser, Parser_alloc); + rb_define_alloc_func(cRequestParser, RequestParser_alloc); + rb_define_alloc_func(cResponseParser, ResponseParser_alloc); + + rb_define_singleton_method(cParser, "strict?", Parser_strict_p, 0); + rb_define_method(cParser, "initialize", Parser_initialize, -1); + + rb_define_method(cParser, "on_message_begin=", Parser_set_on_message_begin, 1); + rb_define_method(cParser, "on_headers_complete=", Parser_set_on_headers_complete, 1); + rb_define_method(cParser, "on_body=", Parser_set_on_body, 1); + rb_define_method(cParser, "on_message_complete=", Parser_set_on_message_complete, 1); + rb_define_method(cParser, "<<", Parser_execute, 1); + + rb_define_method(cParser, "keep_alive?", Parser_keep_alive_p, 0); + rb_define_method(cParser, "upgrade?", Parser_upgrade_p, 0); + + rb_define_method(cParser, "http_version", Parser_http_version, 0); + rb_define_method(cParser, "http_major", Parser_http_major, 0); + rb_define_method(cParser, "http_minor", Parser_http_minor, 0); + + rb_define_method(cParser, "http_method", Parser_http_method, 0); + rb_define_method(cParser, "status_code", Parser_status_code, 0); + + rb_define_method(cParser, "status", Parser_status, 0); + rb_define_method(cParser, "request_url", Parser_request_url, 0); + rb_define_method(cParser, "headers", Parser_headers, 0); + rb_define_method(cParser, "upgrade_data", Parser_upgrade_data, 0); + rb_define_method(cParser, "header_value_type", Parser_header_value_type, 0); + rb_define_method(cParser, "header_value_type=", Parser_set_header_value_type, 1); + + rb_define_method(cParser, "reset!", Parser_reset, 0); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/.gitkeep b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/AUTHORS b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/AUTHORS new file mode 100644 index 0000000..abe99de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/AUTHORS @@ -0,0 +1,32 @@ +# Authors ordered by first contribution. +Ryan Dahl +Jeremy Hinegardner +Sergey Shepelev +Joe Damato +tomika +Phoenix Sol +Cliff Frey +Ewen Cheslack-Postava +Santiago Gala +Tim Becker +Jeff Terrace +Ben Noordhuis +Nathan Rajlich +Mark Nottingham +Aman Gupta +Tim Becker +Sean Cunningham +Peter Griess +Salman Haq +Cliff Frey +Jon Kolb +Fouad Mardini +Paul Querna +Felix Geisendörfer +koichik +Andre Caron +Ivo Raisr +James McLaughlin +David Gwynne +LE ROUX Thomas +Randy Rizun diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT new file mode 100644 index 0000000..a0ae8dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT @@ -0,0 +1,48 @@ +Copyright 2010 Tim Becker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +--- END OF LICENSE + +This code mainly based on code with the following license: + + +http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright +Igor Sysoev. + +Additional changes are licensed under the same terms as NGINX and +copyright Joyent, Inc. and other Node contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/README.md b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/README.md new file mode 100644 index 0000000..0a6a432 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/README.md @@ -0,0 +1,183 @@ +HTTP Parser +=========== + +This is a parser for HTTP written in Java, based quite heavily on +the Ryan Dahl's C Version: `http-parser` available here: + + http://github.com/ry/http-parser + +It parses both requests and responses. The parser is designed to be used +in performance HTTP applications. + +Features: + + * No dependencies (probably won't be able to keep it up) + * Handles persistent streams (keep-alive). + * Decodes chunked encoding. + * Upgrade support + +The parser extracts the following information from HTTP messages: + + * Header fields and values + * Content-Length + * Request method + * Response status code + * Transfer-Encoding + * HTTP version + * Request URL + * Message body + +Building +-------- + +use `ant compile|test|jar` + +Usage +----- + + TODO: in the present form, usage of the Java version of the parser + shouldn't be too difficult to figure out for someone familiar with the + C version. + + More documentation will follow shortly, in case you're looking for an + easy to use http library, this lib is probably not what you are + looking for anyway ... + + All text after this paragraph (and most of the text above it) are from + the original C version of the README and are currently only here for + reference. In case you encounter any difficulties, find bugs, need + help or have suggestions, feel free to contact me at + (tim.becker@kuriositaet.de). + + +One `http_parser` object is used per TCP connection. Initialize the struct +using `http_parser_init()` and set the callbacks. That might look something +like this for a request parser: + + http_parser_settings settings; + settings.on_path = my_path_callback; + settings.on_header_field = my_header_field_callback; + /* ... */ + + http_parser *parser = malloc(sizeof(http_parser)); + http_parser_init(parser, HTTP_REQUEST); + parser->data = my_socket; + +When data is received on the socket execute the parser and check for errors. + + size_t len = 80*1024, nparsed; + char buf[len]; + ssize_t recved; + + recved = recv(fd, buf, len, 0); + + if (recved < 0) { + /* Handle error. */ + } + + /* Start up / continue the parser. + * Note we pass recved==0 to signal that EOF has been recieved. + */ + nparsed = http_parser_execute(parser, &settings, buf, recved); + + if (parser->upgrade) { + /* handle new protocol */ + } else if (nparsed != recved) { + /* Handle error. Usually just close the connection. */ + } + +HTTP needs to know where the end of the stream is. For example, sometimes +servers send responses without Content-Length and expect the client to +consume input (for the body) until EOF. To tell http_parser about EOF, give +`0` as the forth parameter to `http_parser_execute()`. Callbacks and errors +can still be encountered during an EOF, so one must still be prepared +to receive them. + +Scalar valued message information such as `status_code`, `method`, and the +HTTP version are stored in the parser structure. This data is only +temporally stored in `http_parser` and gets reset on each new message. If +this information is needed later, copy it out of the structure during the +`headers_complete` callback. + +The parser decodes the transfer-encoding for both requests and responses +transparently. That is, a chunked encoding is decoded before being sent to +the on_body callback. + + +The Special Problem of Upgrade +------------------------------ + +HTTP supports upgrading the connection to a different protocol. An +increasingly common example of this is the Web Socket protocol which sends +a request like + + GET /demo HTTP/1.1 + Upgrade: WebSocket + Connection: Upgrade + Host: example.com + Origin: http://example.com + WebSocket-Protocol: sample + +followed by non-HTTP data. + +(See http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 for more +information the Web Socket protocol.) + +To support this, the parser will treat this as a normal HTTP message without a +body. Issuing both on_headers_complete and on_message_complete callbacks. However +http_parser_execute() will stop parsing at the end of the headers and return. + +The user is expected to check if `parser->upgrade` has been set to 1 after +`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied +offset by the return value of `http_parser_execute()`. + + +Callbacks +--------- + +During the `http_parser_execute()` call, the callbacks set in +`http_parser_settings` will be executed. The parser maintains state and +never looks behind, so buffering the data is not necessary. If you need to +save certain data for later usage, you can do that from the callbacks. + +There are two types of callbacks: + +* notification `typedef int (*http_cb) (http_parser*);` + Callbacks: on_message_begin, on_headers_complete, on_message_complete. +* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);` + Callbacks: (requests only) on_uri, + (common) on_header_field, on_header_value, on_body; + +Callbacks must return 0 on success. Returning a non-zero value indicates +error to the parser, making it exit immediately. + +In case you parse HTTP message in chunks (i.e. `read()` request line +from socket, parse, read half headers, parse, etc) your data callbacks +may be called more than once. Http-parser guarantees that data pointer is only +valid for the lifetime of callback. You can also `read()` into a heap allocated +buffer to avoid copying memory around if this fits your application. + +Reading headers may be a tricky task if you read/parse headers partially. +Basically, you need to remember whether last header callback was field or value +and apply following logic: + + (on_header_field and on_header_value shortened to on_h_*) + ------------------------ ------------ -------------------------------------------- + | State (prev. callback) | Callback | Description/action | + ------------------------ ------------ -------------------------------------------- + | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | + | | | into it | + ------------------------ ------------ -------------------------------------------- + | value | on_h_field | New header started. | + | | | Copy current name,value buffers to headers | + | | | list and allocate new buffer for new name | + ------------------------ ------------ -------------------------------------------- + | field | on_h_field | Previous name continues. Reallocate name | + | | | buffer and append callback data to it | + ------------------------ ------------ -------------------------------------------- + | field | on_h_value | Value for current header started. Allocate | + | | | new buffer and copy callback data to it | + ------------------------ ------------ -------------------------------------------- + | value | on_h_value | Value continues. Reallocate value buffer | + | | | and append callback data to it | + ------------------------ ------------ -------------------------------------------- diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/TODO b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/TODO new file mode 100644 index 0000000..eb46a08 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/TODO @@ -0,0 +1,28 @@ +decide how to handle errs per default: + - ry: "set state to dead", return `read` + - current: call on_error w/ details, if no on_error handler set, + throw Exception, else call on_error and behave like orig... + +some tests from test.c left to port + (scan ...) +documentation + +hi level callback interface +eventloop +state() as a function (?) + - perhaps, the idea being to be able to log/debug better... +more tests + - in particular, port available c tests +impl bits of servlet api. + +DONE + +Sun Jul 18 12:19:18 CEST 2010 + +error handling + - consider callback based error handling and the current highlevel + "nice" logging moved to high level http impl. + - use Exceptions "ProtocolException"? + +better testing + - no junit to avoid dependencies diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/build.xml b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/build.xml new file mode 100755 index 0000000..d2c6af4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c new file mode 100644 index 0000000..e961ae8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c @@ -0,0 +1,2175 @@ +/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev + * + * Additional changes are licensed under the same terms as NGINX and + * copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "http_parser.h" +#include +#include +#include +#include +#include +#include + +#ifndef ULLONG_MAX +# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ +#endif + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifndef BIT_AT +# define BIT_AT(a, i) \ + (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ + (1 << ((unsigned int) (i) & 7)))) +#endif + +#ifndef ELEM_AT +# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) +#endif + +#define SET_ERRNO(e) \ +do { \ + parser->http_errno = (e); \ +} while(0) + + +/* Run the notify callback FOR, returning ER if it fails */ +#define CALLBACK_NOTIFY_(FOR, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (settings->on_##FOR) { \ + if (0 != settings->on_##FOR(parser)) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + \ + /* We either errored above or got paused; get out */ \ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ + return (ER); \ + } \ + } \ +} while (0) + +/* Run the notify callback FOR and consume the current byte */ +#define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) + +/* Run the notify callback FOR and don't consume the current byte */ +#define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) + +/* Run data callback FOR with LEN bytes, returning ER if it fails */ +#define CALLBACK_DATA_(FOR, LEN, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (FOR##_mark) { \ + if (settings->on_##FOR) { \ + if (0 != settings->on_##FOR(parser, FOR##_mark, (LEN))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + \ + /* We either errored above or got paused; get out */ \ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ + return (ER); \ + } \ + } \ + FOR##_mark = NULL; \ + } \ +} while (0) + +/* Run the data callback FOR and consume the current byte */ +#define CALLBACK_DATA(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) + +/* Run the data callback FOR and don't consume the current byte */ +#define CALLBACK_DATA_NOADVANCE(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) + +/* Set the mark FOR; non-destructive if mark is already set */ +#define MARK(FOR) \ +do { \ + if (!FOR##_mark) { \ + FOR##_mark = p; \ + } \ +} while (0) + + +#define PROXY_CONNECTION "proxy-connection" +#define CONNECTION "connection" +#define CONTENT_LENGTH "content-length" +#define TRANSFER_ENCODING "transfer-encoding" +#define UPGRADE "upgrade" +#define CHUNKED "chunked" +#define KEEP_ALIVE "keep-alive" +#define CLOSE "close" + + +static const char *method_strings[] = + { +#define XX(num, name, string) #string, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +static const char tokens[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, '!', 0, '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', 0, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'x', 'y', 'z', 0, 0, 0, '^', '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'x', 'y', 'z', 0, '|', 0, '~', 0 }; + + +static const int8_t unhex[256] = + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + + +#if HTTP_PARSER_STRICT +# define T(v) 0 +#else +# define T(v) v +#endif + + +static const uint8_t normal_url_char[32] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; + +#undef T + +enum state + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_first_http_major + , s_res_http_major + , s_res_first_http_minor + , s_res_http_minor + , s_res_first_status_code + , s_res_status_code + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_server_start + , s_req_server + , s_req_server_with_at + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_first_http_major + , s_req_http_major + , s_req_first_http_minor + , s_req_http_minor + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_start + , s_header_value + , s_header_value_lws + + , s_header_almost_done + + , s_chunk_size_start + , s_chunk_size + , s_chunk_parameters + , s_chunk_size_almost_done + + , s_headers_almost_done + , s_headers_done + + /* Important: 's_headers_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + + , s_message_done + }; + + +#define PARSING_HEADER(state) (state <= s_headers_done) + + +enum header_states + { h_general = 0 + , h_C + , h_CO + , h_CON + + , h_matching_connection + , h_matching_proxy_connection + , h_matching_content_length + , h_matching_transfer_encoding + , h_matching_upgrade + + , h_connection + , h_content_length + , h_transfer_encoding + , h_upgrade + + , h_matching_transfer_encoding_chunked + , h_matching_connection_keep_alive + , h_matching_connection_close + + , h_transfer_encoding_chunked + , h_connection_keep_alive + , h_connection_close + }; + +enum http_host_state + { + s_http_host_dead = 1 + , s_http_userinfo_start + , s_http_userinfo + , s_http_host_start + , s_http_host_v6_start + , s_http_host + , s_http_host_v6 + , s_http_host_v6_end + , s_http_host_port_start + , s_http_host_port +}; + +/* Macros for character classes; depends on strict-mode */ +#define CR '\r' +#define LF '\n' +#define LOWER(c) (unsigned char)(c | 0x20) +#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') +#define IS_NUM(c) ((c) >= '0' && (c) <= '9') +#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) +#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) +#define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ + (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ + (c) == ')') +#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ + (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ + (c) == '$' || (c) == ',') + +#if HTTP_PARSER_STRICT +#define TOKEN(c) (tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) +#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') +#else +#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) \ + (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) +#define IS_HOST_CHAR(c) \ + (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') +#endif + + +#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) + + +#if HTTP_PARSER_STRICT +# define STRICT_CHECK(cond) \ +do { \ + if (cond) { \ + SET_ERRNO(HPE_STRICT); \ + goto error; \ + } \ +} while (0) +# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) +#else +# define STRICT_CHECK(cond) +# define NEW_MESSAGE() start_state +#endif + + +/* Map errno values to strings for human-readable output */ +#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, +static struct { + const char *name; + const char *description; +} http_strerror_tab[] = { + HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) +}; +#undef HTTP_STRERROR_GEN + +int http_message_needs_eof(const http_parser *parser); + +/* Our URL parser. + * + * This is designed to be shared by http_parser_execute() for URL validation, + * hence it has a state transition + byte-for-byte interface. In addition, it + * is meant to be embedded in http_parser_parse_url(), which does the dirty + * work of turning state transitions URL components for its API. + * + * This function should only be invoked with non-space characters. It is + * assumed that the caller cares about (and can detect) the transition between + * URL and non-URL states by looking for these. + */ +static enum state +parse_url_char(enum state s, const char ch) +{ + if (ch == ' ' || ch == '\r' || ch == '\n') { + return s_dead; + } + +#if HTTP_PARSER_STRICT + if (ch == '\t' || ch == '\f') { + return s_dead; + } +#endif + + switch (s) { + case s_req_spaces_before_url: + /* Proxied requests are followed by scheme of an absolute URI (alpha). + * All methods except CONNECT are followed by '/' or '*'. + */ + + if (ch == '/' || ch == '*') { + return s_req_path; + } + + if (IS_ALPHA(ch)) { + return s_req_schema; + } + + break; + + case s_req_schema: + if (IS_ALPHA(ch)) { + return s; + } + + if (ch == ':') { + return s_req_schema_slash; + } + + break; + + case s_req_schema_slash: + if (ch == '/') { + return s_req_schema_slash_slash; + } + + break; + + case s_req_schema_slash_slash: + if (ch == '/') { + return s_req_server_start; + } + + break; + + case s_req_server_with_at: + if (ch == '@') { + return s_dead; + } + + /* FALLTHROUGH */ + case s_req_server_start: + case s_req_server: + if (ch == '/') { + return s_req_path; + } + + if (ch == '?') { + return s_req_query_string_start; + } + + if (ch == '@') { + return s_req_server_with_at; + } + + if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { + return s_req_server; + } + + break; + + case s_req_path: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + return s_req_query_string_start; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_query_string_start: + case s_req_query_string: + if (IS_URL_CHAR(ch)) { + return s_req_query_string; + } + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + return s_req_query_string; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_fragment_start: + if (IS_URL_CHAR(ch)) { + return s_req_fragment; + } + + switch (ch) { + case '?': + return s_req_fragment; + + case '#': + return s; + } + + break; + + case s_req_fragment: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + case '#': + return s; + } + + break; + + default: + break; + } + + /* We should never fall out of the switch above unless there's an error */ + return s_dead; +} + +size_t http_parser_execute (http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len) +{ + char c, ch; + int8_t unhex_val; + const char *p = data; + const char *header_field_mark = 0; + const char *header_value_mark = 0; + const char *url_mark = 0; + const char *body_mark = 0; + + /* We're in an error state. Don't bother doing anything. */ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return 0; + } + + if (len == 0) { + switch (parser->state) { + case s_body_identity_eof: + /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if + * we got paused. + */ + CALLBACK_NOTIFY_NOADVANCE(message_complete); + return 0; + + case s_dead: + case s_start_req_or_res: + case s_start_res: + case s_start_req: + return 0; + + default: + SET_ERRNO(HPE_INVALID_EOF_STATE); + return 1; + } + } + + + if (parser->state == s_header_field) + header_field_mark = data; + if (parser->state == s_header_value) + header_value_mark = data; + switch (parser->state) { + case s_req_path: + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_server: + case s_req_server_with_at: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + url_mark = data; + break; + } + + for (p=data; p != data + len; p++) { + ch = *p; + + if (PARSING_HEADER(parser->state)) { + ++parser->nread; + /* Buffer overflow attack */ + if (parser->nread > HTTP_MAX_HEADER_SIZE) { + SET_ERRNO(HPE_HEADER_OVERFLOW); + goto error; + } + } + + reexecute_byte: + switch (parser->state) { + + case s_dead: + /* this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + if (ch == CR || ch == LF) + break; + + SET_ERRNO(HPE_CLOSED_CONNECTION); + goto error; + + case s_start_req_or_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (ch == 'H') { + parser->state = s_res_or_resp_H; + + CALLBACK_NOTIFY(message_begin); + } else { + parser->type = HTTP_REQUEST; + parser->state = s_start_req; + goto reexecute_byte; + } + + break; + } + + case s_res_or_resp_H: + if (ch == 'T') { + parser->type = HTTP_RESPONSE; + parser->state = s_res_HT; + } else { + if (ch != 'E') { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + parser->type = HTTP_REQUEST; + parser->method = HTTP_HEAD; + parser->index = 2; + parser->state = s_req_method; + } + break; + + case s_start_res: + { + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + switch (ch) { + case 'H': + parser->state = s_res_H; + break; + + case CR: + case LF: + break; + + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + CALLBACK_NOTIFY(message_begin); + break; + } + + case s_res_H: + STRICT_CHECK(ch != 'T'); + parser->state = s_res_HT; + break; + + case s_res_HT: + STRICT_CHECK(ch != 'T'); + parser->state = s_res_HTT; + break; + + case s_res_HTT: + STRICT_CHECK(ch != 'P'); + parser->state = s_res_HTTP; + break; + + case s_res_HTTP: + STRICT_CHECK(ch != '/'); + parser->state = s_res_first_http_major; + break; + + case s_res_first_http_major: + if (ch < '0' || ch > '9') { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + parser->state = s_res_http_major; + break; + + /* major HTTP version or dot */ + case s_res_http_major: + { + if (ch == '.') { + parser->state = s_res_first_http_minor; + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (parser->http_major > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_res_first_http_minor: + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + parser->state = s_res_http_minor; + break; + + /* minor HTTP version or end of request line */ + case s_res_http_minor: + { + if (ch == ' ') { + parser->state = s_res_first_status_code; + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (parser->http_minor > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + case s_res_first_status_code: + { + if (!IS_NUM(ch)) { + if (ch == ' ') { + break; + } + + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + parser->status_code = ch - '0'; + parser->state = s_res_status_code; + break; + } + + case s_res_status_code: + { + if (!IS_NUM(ch)) { + switch (ch) { + case ' ': + parser->state = s_res_status; + break; + case CR: + parser->state = s_res_line_almost_done; + break; + case LF: + parser->state = s_header_field_start; + break; + default: + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + break; + } + + parser->status_code *= 10; + parser->status_code += ch - '0'; + + if (parser->status_code > 999) { + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + + break; + } + + case s_res_status: + /* the human readable status. e.g. "NOT FOUND" + * we are not humans so just ignore this */ + if (ch == CR) { + parser->state = s_res_line_almost_done; + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + break; + } + break; + + case s_res_line_almost_done: + STRICT_CHECK(ch != LF); + parser->state = s_header_field_start; + CALLBACK_NOTIFY(status_complete); + break; + + case s_start_req: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (!IS_ALPHA(ch)) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + parser->method = (enum http_method) 0; + parser->index = 1; + switch (ch) { + case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; + case 'D': parser->method = HTTP_DELETE; break; + case 'G': parser->method = HTTP_GET; break; + case 'H': parser->method = HTTP_HEAD; break; + case 'L': parser->method = HTTP_LOCK; break; + case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; + case 'N': parser->method = HTTP_NOTIFY; break; + case 'O': parser->method = HTTP_OPTIONS; break; + case 'P': parser->method = HTTP_POST; + /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ + break; + case 'R': parser->method = HTTP_REPORT; break; + case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; + case 'T': parser->method = HTTP_TRACE; break; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + parser->state = s_req_method; + + CALLBACK_NOTIFY(message_begin); + + break; + } + + case s_req_method: + { + const char *matcher; + if (ch == '\0') { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + matcher = method_strings[parser->method]; + if (ch == ' ' && matcher[parser->index] == '\0') { + parser->state = s_req_spaces_before_url; + } else if (ch == matcher[parser->index]) { + ; /* nada */ + } else if (parser->method == HTTP_CONNECT) { + if (parser->index == 1 && ch == 'H') { + parser->method = HTTP_CHECKOUT; + } else if (parser->index == 2 && ch == 'P') { + parser->method = HTTP_COPY; + } else { + goto error; + } + } else if (parser->method == HTTP_MKCOL) { + if (parser->index == 1 && ch == 'O') { + parser->method = HTTP_MOVE; + } else if (parser->index == 1 && ch == 'E') { + parser->method = HTTP_MERGE; + } else if (parser->index == 1 && ch == '-') { + parser->method = HTTP_MSEARCH; + } else if (parser->index == 2 && ch == 'A') { + parser->method = HTTP_MKACTIVITY; + } else { + goto error; + } + } else if (parser->method == HTTP_SUBSCRIBE) { + if (parser->index == 1 && ch == 'E') { + parser->method = HTTP_SEARCH; + } else { + goto error; + } + } else if (parser->index == 1 && parser->method == HTTP_POST) { + if (ch == 'R') { + parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ + } else if (ch == 'U') { + parser->method = HTTP_PUT; /* or HTTP_PURGE */ + } else if (ch == 'A') { + parser->method = HTTP_PATCH; + } else { + goto error; + } + } else if (parser->index == 2) { + if (parser->method == HTTP_PUT) { + if (ch == 'R') parser->method = HTTP_PURGE; + } else if (parser->method == HTTP_UNLOCK) { + if (ch == 'S') parser->method = HTTP_UNSUBSCRIBE; + } + } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { + parser->method = HTTP_PROPPATCH; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + ++parser->index; + break; + } + + case s_req_spaces_before_url: + { + if (ch == ' ') break; + + MARK(url); + if (parser->method == HTTP_CONNECT) { + parser->state = s_req_server_start; + } + + parser->state = parse_url_char((enum state)parser->state, ch); + if (parser->state == s_dead) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + + break; + } + + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + { + switch (ch) { + /* No whitespace allowed here */ + case ' ': + case CR: + case LF: + SET_ERRNO(HPE_INVALID_URL); + goto error; + default: + parser->state = parse_url_char((enum state)parser->state, ch); + if (parser->state == s_dead) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + + break; + } + + case s_req_server: + case s_req_server_with_at: + case s_req_path: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + { + switch (ch) { + case ' ': + parser->state = s_req_http_start; + CALLBACK_DATA(url); + break; + case CR: + case LF: + parser->http_major = 0; + parser->http_minor = 9; + parser->state = (ch == CR) ? + s_req_line_almost_done : + s_header_field_start; + CALLBACK_DATA(url); + break; + default: + parser->state = parse_url_char((enum state)parser->state, ch); + if (parser->state == s_dead) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + break; + } + + case s_req_http_start: + switch (ch) { + case 'H': + parser->state = s_req_http_H; + break; + case ' ': + break; + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + break; + + case s_req_http_H: + STRICT_CHECK(ch != 'T'); + parser->state = s_req_http_HT; + break; + + case s_req_http_HT: + STRICT_CHECK(ch != 'T'); + parser->state = s_req_http_HTT; + break; + + case s_req_http_HTT: + STRICT_CHECK(ch != 'P'); + parser->state = s_req_http_HTTP; + break; + + case s_req_http_HTTP: + STRICT_CHECK(ch != '/'); + parser->state = s_req_first_http_major; + break; + + /* first digit of major HTTP version */ + case s_req_first_http_major: + if (ch < '1' || ch > '9') { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + parser->state = s_req_http_major; + break; + + /* major HTTP version or dot */ + case s_req_http_major: + { + if (ch == '.') { + parser->state = s_req_first_http_minor; + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (parser->http_major > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_req_first_http_minor: + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + parser->state = s_req_http_minor; + break; + + /* minor HTTP version or end of request line */ + case s_req_http_minor: + { + if (ch == CR) { + parser->state = s_req_line_almost_done; + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + break; + } + + /* XXX allow spaces after digit? */ + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (parser->http_minor > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* end of request line */ + case s_req_line_almost_done: + { + if (ch != LF) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + parser->state = s_header_field_start; + break; + } + + case s_header_field_start: + { + if (ch == CR) { + parser->state = s_headers_almost_done; + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + parser->state = s_headers_almost_done; + goto reexecute_byte; + } + + c = TOKEN(ch); + + if (!c) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + MARK(header_field); + + parser->index = 0; + parser->state = s_header_field; + + switch (c) { + case 'c': + parser->header_state = h_C; + break; + + case 'p': + parser->header_state = h_matching_proxy_connection; + break; + + case 't': + parser->header_state = h_matching_transfer_encoding; + break; + + case 'u': + parser->header_state = h_matching_upgrade; + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_field: + { + c = TOKEN(ch); + + if (c) { + switch (parser->header_state) { + case h_general: + break; + + case h_C: + parser->index++; + parser->header_state = (c == 'o' ? h_CO : h_general); + break; + + case h_CO: + parser->index++; + parser->header_state = (c == 'n' ? h_CON : h_general); + break; + + case h_CON: + parser->index++; + switch (c) { + case 'n': + parser->header_state = h_matching_connection; + break; + case 't': + parser->header_state = h_matching_content_length; + break; + default: + parser->header_state = h_general; + break; + } + break; + + /* connection */ + + case h_matching_connection: + parser->index++; + if (parser->index > sizeof(CONNECTION)-1 + || c != CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* proxy-connection */ + + case h_matching_proxy_connection: + parser->index++; + if (parser->index > sizeof(PROXY_CONNECTION)-1 + || c != PROXY_CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* content-length */ + + case h_matching_content_length: + parser->index++; + if (parser->index > sizeof(CONTENT_LENGTH)-1 + || c != CONTENT_LENGTH[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { + parser->header_state = h_content_length; + } + break; + + /* transfer-encoding */ + + case h_matching_transfer_encoding: + parser->index++; + if (parser->index > sizeof(TRANSFER_ENCODING)-1 + || c != TRANSFER_ENCODING[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { + parser->header_state = h_transfer_encoding; + } + break; + + /* upgrade */ + + case h_matching_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE)-1 + || c != UPGRADE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(UPGRADE)-2) { + parser->header_state = h_upgrade; + } + break; + + case h_connection: + case h_content_length: + case h_transfer_encoding: + case h_upgrade: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + assert(0 && "Unknown header_state"); + break; + } + break; + } + + if (ch == ':') { + parser->state = s_header_value_start; + CALLBACK_DATA(header_field); + break; + } + + if (ch == CR) { + parser->state = s_header_almost_done; + CALLBACK_DATA(header_field); + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + CALLBACK_DATA(header_field); + break; + } + + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + case s_header_value_start: + { + if (ch == ' ' || ch == '\t') break; + + MARK(header_value); + + parser->state = s_header_value; + parser->index = 0; + + if (ch == CR) { + parser->header_state = h_general; + parser->state = s_header_almost_done; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + CALLBACK_DATA(header_value); + break; + } + + c = LOWER(ch); + + switch (parser->header_state) { + case h_upgrade: + parser->flags |= F_UPGRADE; + parser->header_state = h_general; + break; + + case h_transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + parser->header_state = h_matching_transfer_encoding_chunked; + } else { + parser->header_state = h_general; + } + break; + + case h_content_length: + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = ch - '0'; + break; + + case h_connection: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + parser->header_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + parser->header_state = h_matching_connection_close; + } else { + parser->header_state = h_general; + } + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_value: + { + + if (ch == CR) { + parser->state = s_header_almost_done; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + parser->state = s_header_almost_done; + CALLBACK_DATA_NOADVANCE(header_value); + goto reexecute_byte; + } + + c = LOWER(ch); + + switch (parser->header_state) { + case h_general: + break; + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + { + uint64_t t; + + if (ch == ' ') break; + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + t = parser->content_length; + t *= 10; + t += ch - '0'; + + /* Overflow? */ + if (t < parser->content_length || t == ULLONG_MAX) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_chunked: + parser->index++; + if (parser->index > sizeof(CHUNKED)-1 + || c != CHUNKED[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CHUNKED)-2) { + parser->header_state = h_transfer_encoding_chunked; + } + break; + + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + parser->index++; + if (parser->index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(KEEP_ALIVE)-2) { + parser->header_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + parser->index++; + if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CLOSE)-2) { + parser->header_state = h_connection_close; + } + break; + + case h_transfer_encoding_chunked: + case h_connection_keep_alive: + case h_connection_close: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + parser->state = s_header_value; + parser->header_state = h_general; + break; + } + break; + } + + case s_header_almost_done: + { + STRICT_CHECK(ch != LF); + + parser->state = s_header_value_lws; + + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + default: + break; + } + + break; + } + + case s_header_value_lws: + { + if (ch == ' ' || ch == '\t') + parser->state = s_header_value_start; + else + { + parser->state = s_header_field_start; + goto reexecute_byte; + } + break; + } + + case s_headers_almost_done: + { + STRICT_CHECK(ch != LF); + + if (parser->flags & F_TRAILING) { + /* End of a chunked request */ + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + break; + } + + parser->state = s_headers_done; + + /* Set this here so that on_headers_complete() callbacks can see it */ + parser->upgrade = + (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT); + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + * + * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so + * we have to simulate it by handling a change in errno below. + */ + if (settings->on_headers_complete) { + switch (settings->on_headers_complete(parser)) { + case 0: + break; + + case 1: + parser->flags |= F_SKIPBODY; + break; + + default: + SET_ERRNO(HPE_CB_headers_complete); + return p - data; /* Error */ + } + } + + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return p - data; + } + + goto reexecute_byte; + } + + case s_headers_done: + { + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + /* Exit, the rest of the connect is in a different protocol. */ + if (parser->upgrade) { + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + return (p - data) + 1; + } + + if (parser->flags & F_SKIPBODY) { + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header */ + parser->state = s_chunk_size_start; + } else { + if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + } else if (parser->content_length != ULLONG_MAX) { + /* Content-Length header given and non-zero */ + parser->state = s_body_identity; + } else { + if (parser->type == HTTP_REQUEST || + !http_message_needs_eof(parser)) { + /* Assume content-length 0 - read the next */ + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + } else { + /* Read body until EOF */ + parser->state = s_body_identity_eof; + } + } + } + + break; + } + + case s_body_identity: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* The difference between advancing content_length and p is because + * the latter will automaticaly advance on the next loop iteration. + * Further, if content_length ends up at 0, we want to see the last + * byte again for our message complete callback. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + parser->state = s_message_done; + + /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. + * + * The alternative to doing this is to wait for the next byte to + * trigger the data callback, just as in every other case. The + * problem with this is that this makes it difficult for the test + * harness to distinguish between complete-on-EOF and + * complete-on-length. It's not clear that this distinction is + * important for applications, but let's keep it for now. + */ + CALLBACK_DATA_(body, p - body_mark + 1, p - data); + goto reexecute_byte; + } + + break; + } + + /* read until EOF */ + case s_body_identity_eof: + MARK(body); + p = data + len - 1; + + break; + + case s_message_done: + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + break; + + case s_chunk_size_start: + { + assert(parser->nread == 1); + assert(parser->flags & F_CHUNKED); + + unhex_val = unhex[(unsigned char)ch]; + if (unhex_val == -1) { + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + parser->content_length = unhex_val; + parser->state = s_chunk_size; + break; + } + + case s_chunk_size: + { + uint64_t t; + + assert(parser->flags & F_CHUNKED); + + if (ch == CR) { + parser->state = s_chunk_size_almost_done; + break; + } + + unhex_val = unhex[(unsigned char)ch]; + + if (unhex_val == -1) { + if (ch == ';' || ch == ' ') { + parser->state = s_chunk_parameters; + break; + } + + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + t = parser->content_length; + t *= 16; + t += unhex_val; + + /* Overflow? */ + if (t < parser->content_length || t == ULLONG_MAX) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + case s_chunk_parameters: + { + assert(parser->flags & F_CHUNKED); + /* just ignore this shit. TODO check for overflow */ + if (ch == CR) { + parser->state = s_chunk_size_almost_done; + break; + } + break; + } + + case s_chunk_size_almost_done: + { + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + if (parser->content_length == 0) { + parser->flags |= F_TRAILING; + parser->state = s_header_field_start; + } else { + parser->state = s_chunk_data; + } + break; + } + + case s_chunk_data: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->flags & F_CHUNKED); + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* See the explanation in s_body_identity for why the content + * length and data pointers are managed this way. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + parser->state = s_chunk_data_almost_done; + } + + break; + } + + case s_chunk_data_almost_done: + assert(parser->flags & F_CHUNKED); + assert(parser->content_length == 0); + STRICT_CHECK(ch != CR); + parser->state = s_chunk_data_done; + CALLBACK_DATA(body); + break; + + case s_chunk_data_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + parser->nread = 0; + parser->state = s_chunk_size_start; + break; + + default: + assert(0 && "unhandled state"); + SET_ERRNO(HPE_INVALID_INTERNAL_STATE); + goto error; + } + } + + /* Run callbacks for any marks that we have leftover after we ran our of + * bytes. There should be at most one of these set, so it's OK to invoke + * them in series (unset marks will not result in callbacks). + * + * We use the NOADVANCE() variety of callbacks here because 'p' has already + * overflowed 'data' and this allows us to correct for the off-by-one that + * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' + * value that's in-bounds). + */ + + assert(((header_field_mark ? 1 : 0) + + (header_value_mark ? 1 : 0) + + (url_mark ? 1 : 0) + + (body_mark ? 1 : 0)) <= 1); + + CALLBACK_DATA_NOADVANCE(header_field); + CALLBACK_DATA_NOADVANCE(header_value); + CALLBACK_DATA_NOADVANCE(url); + CALLBACK_DATA_NOADVANCE(body); + + return len; + +error: + if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { + SET_ERRNO(HPE_UNKNOWN); + } + + return (p - data); +} + + +/* Does the parser need to see an EOF to find the end of the message? */ +int +http_message_needs_eof (const http_parser *parser) +{ + if (parser->type == HTTP_REQUEST) { + return 0; + } + + /* See RFC 2616 section 4.4 */ + if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ + parser->status_code == 204 || /* No Content */ + parser->status_code == 304 || /* Not Modified */ + parser->flags & F_SKIPBODY) { /* response to a HEAD request */ + return 0; + } + + if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { + return 0; + } + + return 1; +} + + +int +http_should_keep_alive (const http_parser *parser) +{ + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; + } + } else { + /* HTTP/1.0 or earlier */ + if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { + return 0; + } + } + + return !http_message_needs_eof(parser); +} + + +const char * +http_method_str (enum http_method m) +{ + return ELEM_AT(method_strings, m, ""); +} + + +void +http_parser_init (http_parser *parser, enum http_parser_type t) +{ + void *data = parser->data; /* preserve application data */ + memset(parser, 0, sizeof(*parser)); + parser->data = data; + parser->type = t; + parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); + parser->http_errno = HPE_OK; +} + +const char * +http_errno_name(enum http_errno err) { + assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); + return http_strerror_tab[err].name; +} + +const char * +http_errno_description(enum http_errno err) { + assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); + return http_strerror_tab[err].description; +} + +static enum http_host_state +http_parse_host_char(enum http_host_state s, const char ch) { + switch(s) { + case s_http_userinfo: + case s_http_userinfo_start: + if (ch == '@') { + return s_http_host_start; + } + + if (IS_USERINFO_CHAR(ch)) { + return s_http_userinfo; + } + break; + + case s_http_host_start: + if (ch == '[') { + return s_http_host_v6_start; + } + + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + break; + + case s_http_host: + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + /* FALLTHROUGH */ + case s_http_host_v6_end: + if (ch == ':') { + return s_http_host_port_start; + } + + break; + + case s_http_host_v6: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_start: + if (IS_HEX(ch) || ch == ':' || ch == '.') { + return s_http_host_v6; + } + + break; + + case s_http_host_port: + case s_http_host_port_start: + if (IS_NUM(ch)) { + return s_http_host_port; + } + + break; + + default: + break; + } + return s_http_host_dead; +} + +static int +http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { + enum http_host_state s; + + const char *p; + size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; + + u->field_data[UF_HOST].len = 0; + + s = found_at ? s_http_userinfo_start : s_http_host_start; + + for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { + enum http_host_state new_s = http_parse_host_char(s, *p); + + if (new_s == s_http_host_dead) { + return 1; + } + + switch(new_s) { + case s_http_host: + if (s != s_http_host) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6: + if (s != s_http_host_v6) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_port: + if (s != s_http_host_port) { + u->field_data[UF_PORT].off = p - buf; + u->field_data[UF_PORT].len = 0; + u->field_set |= (1 << UF_PORT); + } + u->field_data[UF_PORT].len++; + break; + + case s_http_userinfo: + if (s != s_http_userinfo) { + u->field_data[UF_USERINFO].off = p - buf ; + u->field_data[UF_USERINFO].len = 0; + u->field_set |= (1 << UF_USERINFO); + } + u->field_data[UF_USERINFO].len++; + break; + + default: + break; + } + s = new_s; + } + + /* Make sure we don't end somewhere unexpected */ + switch (s) { + case s_http_host_start: + case s_http_host_v6_start: + case s_http_host_v6: + case s_http_host_port_start: + case s_http_userinfo: + case s_http_userinfo_start: + return 1; + default: + break; + } + + return 0; +} + +int +http_parser_parse_url(const char *buf, size_t buflen, int is_connect, + struct http_parser_url *u) +{ + enum state s; + const char *p; + enum http_parser_url_fields uf, old_uf; + int found_at = 0; + + u->port = u->field_set = 0; + s = is_connect ? s_req_server_start : s_req_spaces_before_url; + uf = old_uf = UF_MAX; + + for (p = buf; p < buf + buflen; p++) { + s = parse_url_char(s, *p); + + /* Figure out the next field that we're operating on */ + switch (s) { + case s_dead: + return 1; + + /* Skip delimeters */ + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_query_string_start: + case s_req_fragment_start: + continue; + + case s_req_schema: + uf = UF_SCHEMA; + break; + + case s_req_server_with_at: + found_at = 1; + + /* FALLTROUGH */ + case s_req_server: + uf = UF_HOST; + break; + + case s_req_path: + uf = UF_PATH; + break; + + case s_req_query_string: + uf = UF_QUERY; + break; + + case s_req_fragment: + uf = UF_FRAGMENT; + break; + + default: + assert(!"Unexpected state"); + return 1; + } + + /* Nothing's changed; soldier on */ + if (uf == old_uf) { + u->field_data[uf].len++; + continue; + } + + u->field_data[uf].off = p - buf; + u->field_data[uf].len = 1; + + u->field_set |= (1 << uf); + old_uf = uf; + } + + /* host must be present if there is a schema */ + /* parsing http:///toto will fail */ + if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) { + if (http_parse_host(buf, u, found_at) != 0) { + return 1; + } + } + + /* CONNECT requests can only contain "hostname:port" */ + if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { + return 1; + } + + if (u->field_set & (1 << UF_PORT)) { + /* Don't bother with endp; we've already validated the string */ + unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } + + u->port = (uint16_t) v; + } + + return 0; +} + +void +http_parser_pause(http_parser *parser, int paused) { + /* Users should only be pausing/unpausing a parser that is not in an error + * state. In non-debug builds, there's not much that we can do about this + * other than ignore it. + */ + if (HTTP_PARSER_ERRNO(parser) == HPE_OK || + HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { + SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); + } else { + assert(0 && "Attempting to pause parser in error state"); + } +} + +int +http_body_is_final(const struct http_parser *parser) { + return parser->state == s_message_done; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.gyp b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.gyp new file mode 100644 index 0000000..c6eada7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.gyp @@ -0,0 +1,79 @@ +# This file is used with the GYP meta build system. +# http://code.google.com/p/gyp/ +# To build try this: +# svn co http://gyp.googlecode.com/svn/trunk gyp +# ./gyp/gyp -f make --depth=`pwd` http_parser.gyp +# ./out/Debug/test +{ + 'target_defaults': { + 'default_configuration': 'Debug', + 'configurations': { + # TODO: hoist these out and put them somewhere common, because + # RuntimeLibrary MUST MATCH across the entire project + 'Debug': { + 'defines': [ 'DEBUG', '_DEBUG' ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 1, # static debug + }, + }, + }, + 'Release': { + 'defines': [ 'NDEBUG' ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 0, # static release + }, + }, + } + }, + 'msvs_settings': { + 'VCCLCompilerTool': { + }, + 'VCLibrarianTool': { + }, + 'VCLinkerTool': { + 'GenerateDebugInformation': 'true', + }, + }, + 'conditions': [ + ['OS == "win"', { + 'defines': [ + 'WIN32' + ], + }] + ], + }, + + 'targets': [ + { + 'target_name': 'http_parser', + 'type': 'static_library', + 'include_dirs': [ '.' ], + 'direct_dependent_settings': { + 'include_dirs': [ '.' ], + }, + 'defines': [ 'HTTP_PARSER_STRICT=0' ], + 'sources': [ './http_parser.c', ], + 'conditions': [ + ['OS=="win"', { + 'msvs_settings': { + 'VCCLCompilerTool': { + # Compile as C++. http_parser.c is actually C99, but C++ is + # close enough in this case. + 'CompileAs': 2, + }, + }, + }] + ], + }, + + { + 'target_name': 'test', + 'type': 'executable', + 'dependencies': [ 'http_parser' ], + 'sources': [ 'test.c' ] + } + ] +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h new file mode 100644 index 0000000..2fff4bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h @@ -0,0 +1,304 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef http_parser_h +#define http_parser_h +#ifdef __cplusplus +extern "C" { +#endif + +#define HTTP_PARSER_VERSION_MAJOR 2 +#define HTTP_PARSER_VERSION_MINOR 0 + +#include +#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) +#include +#include +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run + * faster + */ +#ifndef HTTP_PARSER_STRICT +# define HTTP_PARSER_STRICT 1 +#endif + +/* Maximium header size allowed */ +#define HTTP_MAX_HEADER_SIZE (80*1024) + + +typedef struct http_parser http_parser; +typedef struct http_parser_settings http_parser_settings; + + +/* Callbacks should return non-zero to indicate an error. The parser will + * then halt execution. + * + * The one exception is on_headers_complete. In a HTTP_RESPONSE parser + * returning '1' from on_headers_complete will tell the parser that it + * should not expect a body. This is used when receiving a response to a + * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + * chunked' headers that indicate the presence of a body. + * + * http_data_cb does not return data chunks. It will be call arbitrarally + * many times for each string. E.G. you might get 10 callbacks for "on_url" + * each providing just a few characters more data. + */ +typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); +typedef int (*http_cb) (http_parser*); + + +/* Request Methods */ +#define HTTP_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + /* pathological */ \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + /* webdav */ \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + /* subversion */ \ + XX(16, REPORT, REPORT) \ + XX(17, MKACTIVITY, MKACTIVITY) \ + XX(18, CHECKOUT, CHECKOUT) \ + XX(19, MERGE, MERGE) \ + /* upnp */ \ + XX(20, MSEARCH, M-SEARCH) \ + XX(21, NOTIFY, NOTIFY) \ + XX(22, SUBSCRIBE, SUBSCRIBE) \ + XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \ + /* RFC-5789 */ \ + XX(24, PATCH, PATCH) \ + XX(25, PURGE, PURGE) \ + +enum http_method + { +#define XX(num, name, string) HTTP_##name = num, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; + + +/* Flag values for http_parser.flags field */ +enum flags + { F_CHUNKED = 1 << 0 + , F_CONNECTION_KEEP_ALIVE = 1 << 1 + , F_CONNECTION_CLOSE = 1 << 2 + , F_TRAILING = 1 << 3 + , F_UPGRADE = 1 << 4 + , F_SKIPBODY = 1 << 5 + }; + + +/* Map for errno-related constants + * + * The provided argument should be a macro that takes 2 arguments. + */ +#define HTTP_ERRNO_MAP(XX) \ + /* No error */ \ + XX(OK, "success") \ + \ + /* Callback-related errors */ \ + XX(CB_message_begin, "the on_message_begin callback failed") \ + XX(CB_status_complete, "the on_status_complete callback failed") \ + XX(CB_url, "the on_url callback failed") \ + XX(CB_header_field, "the on_header_field callback failed") \ + XX(CB_header_value, "the on_header_value callback failed") \ + XX(CB_headers_complete, "the on_headers_complete callback failed") \ + XX(CB_body, "the on_body callback failed") \ + XX(CB_message_complete, "the on_message_complete callback failed") \ + \ + /* Parsing-related errors */ \ + XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ + XX(HEADER_OVERFLOW, \ + "too many header bytes seen; overflow detected") \ + XX(CLOSED_CONNECTION, \ + "data received after completed connection: close message") \ + XX(INVALID_VERSION, "invalid HTTP version") \ + XX(INVALID_STATUS, "invalid HTTP status code") \ + XX(INVALID_METHOD, "invalid HTTP method") \ + XX(INVALID_URL, "invalid URL") \ + XX(INVALID_HOST, "invalid host") \ + XX(INVALID_PORT, "invalid port") \ + XX(INVALID_PATH, "invalid path") \ + XX(INVALID_QUERY_STRING, "invalid query string") \ + XX(INVALID_FRAGMENT, "invalid fragment") \ + XX(LF_EXPECTED, "LF character expected") \ + XX(INVALID_HEADER_TOKEN, "invalid character in header") \ + XX(INVALID_CONTENT_LENGTH, \ + "invalid character in content-length header") \ + XX(INVALID_CHUNK_SIZE, \ + "invalid character in chunk size header") \ + XX(INVALID_CONSTANT, "invalid constant string") \ + XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ + XX(STRICT, "strict mode assertion failed") \ + XX(PAUSED, "parser is paused") \ + XX(UNKNOWN, "an unknown error occurred") + + +/* Define HPE_* values for each errno value above */ +#define HTTP_ERRNO_GEN(n, s) HPE_##n, +enum http_errno { + HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) +}; +#undef HTTP_ERRNO_GEN + + +/* Get an http_errno value from an http_parser */ +#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) + + +struct http_parser { + /** PRIVATE **/ + unsigned char type : 2; /* enum http_parser_type */ + unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */ + unsigned char state; /* enum state from http_parser.c */ + unsigned char header_state; /* enum header_state from http_parser.c */ + unsigned char index; /* index into current matcher */ + + uint32_t nread; /* # bytes read in various scenarios */ + uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ + + /** READ-ONLY **/ + unsigned short http_major; + unsigned short http_minor; + unsigned short status_code; /* responses only */ + unsigned char method; /* requests only */ + unsigned char http_errno : 7; + + /* 1 = Upgrade header was present and the parser has exited because of that. + * 0 = No upgrade header present. + * Should be checked when http_parser_execute() returns in addition to + * error checking. + */ + unsigned char upgrade : 1; + + /** PUBLIC **/ + void *data; /* A pointer to get hook to the "connection" or "socket" object */ +}; + + +struct http_parser_settings { + http_cb on_message_begin; + http_data_cb on_url; + http_cb on_status_complete; + http_data_cb on_header_field; + http_data_cb on_header_value; + http_cb on_headers_complete; + http_data_cb on_body; + http_cb on_message_complete; +}; + + +enum http_parser_url_fields + { UF_SCHEMA = 0 + , UF_HOST = 1 + , UF_PORT = 2 + , UF_PATH = 3 + , UF_QUERY = 4 + , UF_FRAGMENT = 5 + , UF_USERINFO = 6 + , UF_MAX = 7 + }; + + +/* Result structure for http_parser_parse_url(). + * + * Callers should index into field_data[] with UF_* values iff field_set + * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and + * because we probably have padding left over), we convert any port to + * a uint16_t. + */ +struct http_parser_url { + uint16_t field_set; /* Bitmask of (1 << UF_*) values */ + uint16_t port; /* Converted UF_PORT string */ + + struct { + uint16_t off; /* Offset into buffer in which field starts */ + uint16_t len; /* Length of run in buffer */ + } field_data[UF_MAX]; +}; + + +void http_parser_init(http_parser *parser, enum http_parser_type type); + + +size_t http_parser_execute(http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len); + + +/* If http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns 0, then this should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ +int http_should_keep_alive(const http_parser *parser); + +/* Returns a string version of the HTTP method. */ +const char *http_method_str(enum http_method m); + +/* Return a string name of the given error */ +const char *http_errno_name(enum http_errno err); + +/* Return a string description of the given error */ +const char *http_errno_description(enum http_errno err); + +/* Parse a URL; return nonzero on failure */ +int http_parser_parse_url(const char *buf, size_t buflen, + int is_connect, + struct http_parser_url *u); + +/* Pause or un-pause the parser; a nonzero value pauses */ +void http_parser_pause(http_parser *parser, int paused); + +/* Checks if this is the final chunk of the body. */ +int http_body_is_final(const http_parser *parser); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/Http-parser.java.iml b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/Http-parser.java.iml new file mode 100644 index 0000000..741121a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/Http-parser.java.iml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/FieldData.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/FieldData.java new file mode 100644 index 0000000..774179f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/FieldData.java @@ -0,0 +1,41 @@ +package http_parser; + +public class FieldData { + public int off; + public int len; + + public FieldData(){} + + public FieldData(int off, int len){ + this.off = off; + this.len = len; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FieldData fieldData = (FieldData) o; + + if (len != fieldData.len) return false; + if (off != fieldData.off) return false; + + return true; + } + + @Override + public int hashCode() { + int result = off; + result = 31 * result + len; + return result; + } + + @Override + public String toString() { + return "FieldData{" + + "off=" + off + + ", len=" + len + + '}'; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java new file mode 100644 index 0000000..5380b0f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPCallback.java @@ -0,0 +1,8 @@ +package http_parser; + +public abstract class HTTPCallback implements http_parser.lolevel.HTTPCallback{ + public int cb (http_parser.lolevel.HTTPParser parser) { + return this.cb((HTTPParser)parser); + } + public abstract int cb (HTTPParser parser); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java new file mode 100644 index 0000000..bfe576f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPDataCallback.java @@ -0,0 +1,34 @@ +package http_parser; + +import java.nio.ByteBuffer; + +public abstract class HTTPDataCallback implements http_parser.lolevel.HTTPDataCallback{ + /* + Very raw and extremly foolhardy! DANGER! + The whole Buffer concept is difficult enough to grasp as it is, + we pass in a buffer with an arbitrary position. + + The interesting data is located at position pos and is len + bytes long. + + The contract of this callback is that the buffer is + returned in the state that it was passed in, so implementing + this require good citizenship, you'll need to remember the current + position, change the position to get at the data you're interested + in and then set the position back to how you found it... + + Therefore: there is an abstract implementation that implements + cb as described above, and provides a new callback + with signature @see cb(byte[], int, int) + */ + public int cb(http_parser.lolevel.HTTPParser p, ByteBuffer buf, int pos, int len) { + byte [] by = new byte[len]; + int saved = buf.position(); + buf.position(pos); + buf.get(by); + buf.position(saved); + return cb((HTTPParser)p, by, 0, len); + } + + public abstract int cb(HTTPParser p, byte[] by, int pos, int len); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java new file mode 100644 index 0000000..a74206e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPErrorCallback.java @@ -0,0 +1,12 @@ +package http_parser; + + +import java.nio.ByteBuffer; + +public abstract class HTTPErrorCallback implements http_parser.lolevel.HTTPErrorCallback{ + public void cb (http_parser.lolevel.HTTPParser parser, String mes, ByteBuffer buf, int initial_position) { + this.cb((HTTPParser)parser, Util.error(mes, buf, initial_position)); + } + + public abstract void cb(HTTPParser parser, String error); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java new file mode 100644 index 0000000..9ccaf14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java @@ -0,0 +1,9 @@ +package http_parser; + +@SuppressWarnings("serial") +public class HTTPException extends RuntimeException { + +public HTTPException(String mes) { + super(mes); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java new file mode 100644 index 0000000..7c080c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java @@ -0,0 +1,107 @@ +package http_parser; + +import java.nio.charset.Charset; + +public enum HTTPMethod { + HTTP_DELETE("DELETE")// = 0 + , HTTP_GET("GET") + , HTTP_HEAD("HEAD") + , HTTP_POST("POST") + , HTTP_PUT("PUT") + , HTTP_PATCH("PATCH") + /* pathological */ + , HTTP_CONNECT("CONNECT") + , HTTP_OPTIONS("OPTIONS") + , HTTP_TRACE("TRACE") + /* webdav */ + , HTTP_COPY("COPY") + , HTTP_LOCK("LOCK") + , HTTP_MKCOL("MKCOL") + , HTTP_MOVE("MOVE") + , HTTP_PROPFIND("PROPFIND") + , HTTP_PROPPATCH("PROPPATCH") + , HTTP_UNLOCK("UNLOCK") + , HTTP_REPORT("REPORT") + , HTTP_MKACTIVITY("MKACTIVITY") + , HTTP_CHECKOUT("CHECKOUT") + , HTTP_MERGE("MERGE") + , HTTP_MSEARCH("M-SEARCH") + , HTTP_NOTIFY("NOTIFY") + , HTTP_SUBSCRIBE("SUBSCRIBE") + , HTTP_UNSUBSCRIBE("UNSUBSCRIBE") + , HTTP_PURGE("PURGE") + ; + + private static Charset ASCII; + static { + ASCII = Charset.forName("US-ASCII");; + } + public byte[] bytes; + + HTTPMethod(String name) { + // good grief, Charlie Brown, the following is necessary because + // java is retarded: + // illegal reference to static field from initializer + // this.bytes = name.getBytes(ASCII); + // yet it's not illegal to reference static fields from + // methods called from initializer. + init(name); + } + public static HTTPMethod parse(String s) { + if ("HTTP_DELETE".equalsIgnoreCase(s)) {return HTTP_DELETE;} + else if ("DELETE".equalsIgnoreCase(s)) {return HTTP_DELETE;} + else if ("HTTP_GET".equalsIgnoreCase(s)) {return HTTP_GET;} + else if ("GET".equalsIgnoreCase(s)) {return HTTP_GET;} + else if ("HTTP_HEAD".equalsIgnoreCase(s)) {return HTTP_HEAD;} + else if ("HEAD".equalsIgnoreCase(s)) {return HTTP_HEAD;} + else if ("HTTP_POST".equalsIgnoreCase(s)) {return HTTP_POST;} + else if ("POST".equalsIgnoreCase(s)) {return HTTP_POST;} + else if ("HTTP_PUT".equalsIgnoreCase(s)) {return HTTP_PUT;} + else if ("PUT".equalsIgnoreCase(s)) {return HTTP_PUT;} + else if ("HTTP_PATCH".equalsIgnoreCase(s)) {return HTTP_PATCH;} + else if ("PATCH".equalsIgnoreCase(s)) {return HTTP_PATCH;} + else if ("HTTP_CONNECT".equalsIgnoreCase(s)) {return HTTP_CONNECT;} + else if ("CONNECT".equalsIgnoreCase(s)) {return HTTP_CONNECT;} + else if ("HTTP_OPTIONS".equalsIgnoreCase(s)) {return HTTP_OPTIONS;} + else if ("OPTIONS".equalsIgnoreCase(s)) {return HTTP_OPTIONS;} + else if ("HTTP_TRACE".equalsIgnoreCase(s)) {return HTTP_TRACE;} + else if ("TRACE".equalsIgnoreCase(s)) {return HTTP_TRACE;} + else if ("HTTP_COPY".equalsIgnoreCase(s)) {return HTTP_COPY;} + else if ("COPY".equalsIgnoreCase(s)) {return HTTP_COPY;} + else if ("HTTP_LOCK".equalsIgnoreCase(s)) {return HTTP_LOCK;} + else if ("LOCK".equalsIgnoreCase(s)) {return HTTP_LOCK;} + else if ("HTTP_MKCOL".equalsIgnoreCase(s)) {return HTTP_MKCOL;} + else if ("MKCOL".equalsIgnoreCase(s)) {return HTTP_MKCOL;} + else if ("HTTP_MOVE".equalsIgnoreCase(s)) {return HTTP_MOVE;} + else if ("MOVE".equalsIgnoreCase(s)) {return HTTP_MOVE;} + else if ("HTTP_PROPFIND".equalsIgnoreCase(s)){return HTTP_PROPFIND;} + else if ("PROPFIND".equalsIgnoreCase(s)) {return HTTP_PROPFIND;} + else if ("HTTP_PROPPATCH".equalsIgnoreCase(s)){return HTTP_PROPPATCH;} + else if ("PROPPATCH".equalsIgnoreCase(s)) {return HTTP_PROPPATCH;} + else if ("HTTP_UNLOCK".equalsIgnoreCase(s)) {return HTTP_UNLOCK;} + else if ("UNLOCK".equalsIgnoreCase(s)) {return HTTP_UNLOCK;} + else if ("HTTP_REPORT".equalsIgnoreCase(s)) {return HTTP_REPORT;} + else if ("REPORT".equalsIgnoreCase(s)){return HTTP_REPORT;} + else if ("HTTP_MKACTIVITY".equalsIgnoreCase(s)) {return HTTP_MKACTIVITY;} + else if ("MKACTIVITY".equalsIgnoreCase(s)){return HTTP_MKACTIVITY;} + else if ("HTTP_CHECKOUT".equalsIgnoreCase(s)) {return HTTP_CHECKOUT;} + else if ("CHECKOUT".equalsIgnoreCase(s)){return HTTP_CHECKOUT;} + else if ("HTTP_MERGE".equalsIgnoreCase(s)) {return HTTP_MERGE;} + else if ("MERGE".equalsIgnoreCase(s)){return HTTP_MERGE;} + else if ("HTTP_MSEARCH".equalsIgnoreCase(s)) {return HTTP_MSEARCH;} + else if ("M-SEARCH".equalsIgnoreCase(s)) {return HTTP_MSEARCH;} + else if ("HTTP_NOTIFY".equalsIgnoreCase(s)) {return HTTP_NOTIFY;} + else if ("NOTIFY".equalsIgnoreCase(s)) {return HTTP_NOTIFY;} + else if ("HTTP_SUBSCRIBE".equalsIgnoreCase(s)) {return HTTP_SUBSCRIBE;} + else if ("SUBSCRIBE".equalsIgnoreCase(s)) {return HTTP_SUBSCRIBE;} + else if ("HTTP_UNSUBSCRIBE".equalsIgnoreCase(s)) {return HTTP_UNSUBSCRIBE;} + else if ("UNSUBSCRIBE".equalsIgnoreCase(s)) {return HTTP_UNSUBSCRIBE;} + else if ("PATCH".equalsIgnoreCase(s)) {return HTTP_PATCH;} + else if ("PURGE".equalsIgnoreCase(s)) {return HTTP_PURGE;} + else {return null;} + } + void init (String name) { + ASCII = null == ASCII ? Charset.forName("US-ASCII") : ASCII; + this.bytes = name.getBytes(ASCII); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java new file mode 100644 index 0000000..7ab4fb4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java @@ -0,0 +1,36 @@ +package http_parser; + +import java.nio.ByteBuffer; + +public class HTTPParser extends http_parser.lolevel.HTTPParser { + + public HTTPParser() { super(); } + public HTTPParser(ParserType type) { super(type); } + + public int getMajor() { + return super.http_major; + } + + public int getMinor() { + return super.http_minor; + } + + public int getStatusCode() { + return super.status_code; + } + + public HTTPMethod getHTTPMethod() { + return super.method; + } + + public boolean getUpgrade() { + return super.upgrade; + } + + public boolean shouldKeepAlive() { + return super.http_should_keep_alive(); + } + public void execute(ParserSettings settings, ByteBuffer data) { + this.execute(settings.getLoLevelSettings(), data); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParserUrl.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParserUrl.java new file mode 100644 index 0000000..d371634 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParserUrl.java @@ -0,0 +1,76 @@ +package http_parser; + +import http_parser.lolevel.*; +import http_parser.lolevel.HTTPParser; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.Arrays; + +/** + */ +public class HTTPParserUrl { + + public int field_set; + public int port; + + public FieldData[] field_data = new FieldData[]{ + new FieldData(0,0), + new FieldData(0,0), + new FieldData(0,0), + new FieldData(0,0), + new FieldData(0,0), + new FieldData(0,0) + }; //UF_MAX + + public HTTPParserUrl(){} + + public HTTPParserUrl(int field_set, int port, FieldData[] field_data){ + this.field_set = field_set; + this.port = port; + this.field_data = field_data; + } + + public String getFieldValue(HTTPParser.UrlFields field, ByteBuffer data) throws UnsupportedEncodingException { + FieldData fd = this.field_data[field.getIndex()]; + if(fd.off == 0 & fd.len == 0) return ""; + byte[] dst = new byte[fd.len]; + int current_pos = data.position(); + data.position(fd.off); + data.get(dst,0,fd.len); + data.position(current_pos); + String v = new String(dst, "UTF8"); + return v; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + HTTPParserUrl that = (HTTPParserUrl) o; + + if (field_set != that.field_set) return false; + if (port != that.port) return false; + if (!Arrays.equals(field_data, that.field_data)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = field_set; + result = 31 * result + port; + result = 31 * result + Arrays.hashCode(field_data); + return result; + } + + @Override + public String toString() { + return "HTTPParserUrl{" + + "field_set=" + field_set + + ", port=" + port + + ", field_data=" + (field_data == null ? null : Arrays.asList(field_data)) + + '}'; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java new file mode 100644 index 0000000..9a5e6e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserSettings.java @@ -0,0 +1,256 @@ +package http_parser; + + + +import primitive.collection.ByteList; + +public class ParserSettings extends http_parser.lolevel.ParserSettings { + + public HTTPCallback on_message_begin; + public HTTPDataCallback on_path; + public HTTPDataCallback on_query_string; + public HTTPDataCallback on_url; + public HTTPDataCallback on_fragment; + public HTTPCallback on_status_complete; + public HTTPDataCallback on_header_field; + public HTTPDataCallback on_header_value; + + public HTTPCallback on_headers_complete; + public HTTPDataCallback on_body; + public HTTPCallback on_message_complete; + + public HTTPErrorCallback on_error; + + private HTTPCallback _on_message_begin; + private HTTPDataCallback _on_path; + private HTTPDataCallback _on_query_string; + private HTTPDataCallback _on_url; + private HTTPDataCallback _on_fragment; + private HTTPCallback _on_status_complete; + private HTTPDataCallback _on_header_field; + private HTTPDataCallback _on_header_value; + private HTTPCallback _on_headers_complete; + private HTTPDataCallback _on_body; + private HTTPCallback _on_message_complete; + private HTTPErrorCallback _on_error; + + private http_parser.lolevel.ParserSettings settings; + + protected ByteList field = new ByteList(); + protected ByteList value = new ByteList(); + protected ByteList body = new ByteList(); + + public ParserSettings() { + this.settings = new http_parser.lolevel.ParserSettings(); + createMirrorCallbacks(); + attachCallbacks(); + } + + protected http_parser.lolevel.ParserSettings getLoLevelSettings() { + return this.settings; + } + + private void createMirrorCallbacks() { + this._on_message_begin = new HTTPCallback() { + public int cb(HTTPParser p) { + if (null != ParserSettings.this.on_message_begin) { + return ParserSettings.this.on_message_begin.cb(p); + } + return 0; + } + }; + this._on_path = new HTTPDataCallback() { + @Override + public int cb(HTTPParser p, byte[] by, int pos, int len) { + if (null != ParserSettings.this.on_path) { + return ParserSettings.this.on_path.cb(p, by, pos, len); + } + return 0; + } + }; + this._on_query_string = new HTTPDataCallback() { + @Override + public int cb(HTTPParser p, byte[] by, int pos, int len) { + if (null != ParserSettings.this.on_query_string) { + return ParserSettings.this.on_query_string.cb(p, by, pos, len); + } + return 0; + } + }; + this._on_url = new HTTPDataCallback() { + @Override + public int cb(HTTPParser p, byte[] by, int pos, int len) { + if (null != ParserSettings.this.on_url) { + return ParserSettings.this.on_url.cb(p, by, pos, len); + } + return 0; + } + }; + this._on_fragment = new HTTPDataCallback() { + @Override + public int cb(HTTPParser p, byte[] by, int pos, int len) { + if (null != ParserSettings.this.on_fragment) { + return ParserSettings.this.on_fragment.cb(p, by, pos, len); + } + return 0; + } + }; + this._on_status_complete = new HTTPCallback() { + @Override + public int cb(HTTPParser p) { + if (null != ParserSettings.this.on_status_complete) { + return ParserSettings.this.on_status_complete.cb(p); + } + return 0; + } + }; + this._on_error = new HTTPErrorCallback() { + @Override + public void cb(HTTPParser parser, String error) { + if (null != ParserSettings.this.on_error) { + ParserSettings.this.on_error.cb(parser, error); + } else { + throw new HTTPException(error); + } + + } + }; + + + +// (on_header_field and on_header_value shortened to on_h_*) +// ------------------------ ------------ -------------------------------------------- +// | State (prev. callback) | Callback | Description/action | +// ------------------------ ------------ -------------------------------------------- +// | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | +// | | | into it | +// ------------------------ ------------ -------------------------------------------- +// | value | on_h_field | New header started. | +// | | | Copy current name,value buffers to headers | +// | | | list and allocate new buffer for new name | +// ------------------------ ------------ -------------------------------------------- +// | field | on_h_field | Previous name continues. Reallocate name | +// | | | buffer and append callback data to it | +// ------------------------ ------------ -------------------------------------------- +// | field | on_h_value | Value for current header started. Allocate | +// | | | new buffer and copy callback data to it | +// ------------------------ ------------ -------------------------------------------- +// | value | on_h_value | Value continues. Reallocate value buffer | +// | | | and append callback data to it | +// ------------------------ ------------ -------------------------------------------- + this._on_header_field = new HTTPDataCallback() { + @Override + public int cb(HTTPParser p, byte[] by, int pos, int len) { + // previous value complete, call on_value with full value, reset value. + if (0 != ParserSettings.this.value.size()) { + // check we're even interested... + if (null != ParserSettings.this.on_header_value) { + byte [] valueArr = ParserSettings.this.value.toArray(); + int ret = ParserSettings.this.on_header_value.cb(p, valueArr, 0, valueArr.length); + if (0 != ret) { + return ret; + } + ParserSettings.this.value.clear(); + } + } + + if (null == ParserSettings.this.on_header_field) { + return 0; + } + + ParserSettings.this.field.addAll(by); + return 0; + } + }; + this._on_header_value = new HTTPDataCallback() { + @Override + public int cb(HTTPParser p, byte[] by, int pos, int len) { + + // previous field complete, call on_field with full field value, reset field. + if (0 != ParserSettings.this.field.size()) { + // check we're even interested... + if (null != ParserSettings.this.on_header_field) { + byte [] fieldArr = ParserSettings.this.field.toArray(); + int ret = ParserSettings.this.on_header_field.cb(p, fieldArr, 0, fieldArr.length); + if (0 != ret) { + return ret; + } + ParserSettings.this.field.clear(); + } + } + + if (null == ParserSettings.this.on_header_value) { + return 0; + } + ParserSettings.this.value.addAll(by); + return 0; + } + }; + this._on_headers_complete = new HTTPCallback() { + @Override + public int cb(HTTPParser parser) { + // is there an uncompleted value ... ? + if (0 != ParserSettings.this.value.size()) { + // check we're even interested... + if (null != ParserSettings.this.on_header_value) { + byte [] valueArr = ParserSettings.this.value.toArray(); + int ret = ParserSettings.this.on_header_value.cb(parser, valueArr, 0, valueArr.length); + if (0 != ret) { + return ret; + } + ParserSettings.this.value.clear(); + } + } + if (null != ParserSettings.this.on_headers_complete) { + return ParserSettings.this.on_headers_complete.cb(parser); + } + return 0; + } + + }; + this._on_body = new HTTPDataCallback() { + @Override + public int cb(HTTPParser p, byte[] by, int pos, int len) { + if (null != ParserSettings.this.on_body) { + ParserSettings.this.body.addAll(by, pos, len); + } + return 0; + } + }; + + this._on_message_complete = new HTTPCallback() { + @Override + public int cb(HTTPParser parser) { + if (null != ParserSettings.this.on_body) { + byte [] body = ParserSettings.this.body.toArray(); + int ret = ParserSettings.this.on_body.cb(parser, body, 0, body.length); + if (0!=ret) { + return ret; + } + ParserSettings.this.body.clear(); + } + if (null != ParserSettings.this.on_message_complete) { + return ParserSettings.this.on_message_complete.cb(parser); + } + return 0; + } + }; + + } + + private void attachCallbacks() { + // these are certainly set, because we mirror them ... + this.settings.on_message_begin = this._on_message_begin; + this.settings.on_path = this._on_path; + this.settings.on_query_string = this._on_query_string; + this.settings.on_url = this._on_url; + this.settings.on_fragment = this._on_fragment; + this.settings.on_status_complete = this._on_status_complete; + this.settings.on_header_field = this._on_header_field; + this.settings.on_header_value = this._on_header_value; + this.settings.on_headers_complete = this._on_headers_complete; + this.settings.on_body = this._on_body; + this.settings.on_message_complete = this._on_message_complete; + this.settings.on_error = this._on_error; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java new file mode 100644 index 0000000..a51f5b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java @@ -0,0 +1,13 @@ +package http_parser; + +public enum ParserType { +HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH; + + public static ParserType parse(String s) { + if ("HTTP_REQUEST".equalsIgnoreCase(s)) { return HTTP_REQUEST; } + else if ("HTTP_RESPONSE".equalsIgnoreCase(s)) { return HTTP_RESPONSE; } + else if ("HTTP_BOTH".equalsIgnoreCase(s)) { return HTTP_BOTH; } + else { return null; } + } +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/Util.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/Util.java new file mode 100644 index 0000000..575003a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/Util.java @@ -0,0 +1,111 @@ +package http_parser; + +import java.nio.ByteBuffer; + +public class Util { +// public static String toString(http_parser.lolevel.HTTPParser p) { +// StringBuilder builder = new StringBuilder(); +// +// // the stuff up to the break is ephermeral and only meaningful +// // while the parser is parsing. In general, this method is +// // probably only useful during debugging. +// +// builder.append("state :"); builder.append(p.state); builder.append("\n"); +// builder.append("header_state :"); builder.append(p.header_state); builder.append("\n"); +// builder.append("strict :"); builder.append(p.strict); builder.append("\n"); +// builder.append("index :"); builder.append(p.index); builder.append("\n"); +// builder.append("flags :"); builder.append(p.flags); builder.append("\n"); +// builder.append("nread :"); builder.append(p.nread); builder.append("\n"); +// builder.append("content_length :"); builder.append(p.content_length); builder.append("\n"); +// +// +// builder.append("type :"); builder.append(p.type); builder.append("\n"); +// builder.append("http_major :"); builder.append(p.http_major); builder.append("\n"); +// builder.append("http_minor :"); builder.append(p.http_minor); builder.append("\n"); +// builder.append("status_code :"); builder.append(p.status_code); builder.append("\n"); +// builder.append("method :"); builder.append(p.method); builder.append("\n"); +// builder.append("upgrade :"); builder.append(p.upgrade); builder.append("\n"); +// +// return builder.toString(); +// +// } + + public static String error (String mes, ByteBuffer b, int beginning) { + // the error message should look like this: + // + // Bla expected something, but it's not there (mes) + // GEt / HTTP 1_1 + // ............^. + // + // |----------------- 72 -------------------------| + + // This is ridiculously complicated and probably riddled with + // off-by-one errors, should be moved into high level interface. + // TODO. + + // also: need to keep track of the initial buffer position in + // execute so that we don't screw up any `mark()` that may have + // been set outside of our control to be nice. + + final int mes_width = 72; + int p = b.position(); // error position + int end = b.limit(); // this is the end + int m = end - beginning; // max mes length + + StringBuilder builder = new StringBuilder(); + int p_adj = p; + + byte [] orig = new byte[0]; + if (m <= mes_width) { + orig = new byte[m]; + b.position(beginning); + b.get(orig, 0, m); + p_adj = p-beginning; + + + } else { + // we'll need to trim bit off the beginning and/or end + orig = new byte[mes_width]; + // three possibilities: + // a.) plenty of stuff around p + // b.) plenty of stuff in front of p + // c.) plenty of stuff behind p + // CAN'T be not enough stuff aorund p in total, because + // m>meswidth (see if to this else) + + int before = p-beginning; + int after = end - p; + if ( (before > mes_width/2) && (after > mes_width/2)) { + // plenty of stuff in front of and behind error + p_adj = mes_width/2; + b.position(p - mes_width/2); + b.get(orig, 0, mes_width); + } else if (before <= mes_width/2) { + // take all of the begining. + b.position(beginning); + // and as much of the rest as possible + + b.get(orig, 0, mes_width); + + } else { + // plenty of stuff before + before = end-mes_width; + b.position(before); + p_adj = p - before; + b.get(orig, 0, mes_width); + } + } + + builder.append(new String(orig)); + builder.append("\n"); + for (int i = 0; i!= p_adj; ++i) { + builder.append("."); + } + builder.append("^"); + + + b.position(p); // restore position + return builder.toString(); + + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java new file mode 100644 index 0000000..95c29b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java @@ -0,0 +1,5 @@ +package http_parser.lolevel; + +public interface HTTPCallback { + public int cb (HTTPParser parser); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java new file mode 100644 index 0000000..6cad156 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java @@ -0,0 +1,25 @@ +package http_parser.lolevel; + +import java.nio.ByteBuffer; + +public interface HTTPDataCallback { + /* + very raw and extremly foolhardy! DANGER! + The whole Buffer concept is difficult enough to grasp as it is, + we pass in a buffer with an arbitrary position. + + The interesting data is located at position pos and is len + bytes long. + + The contract of this callback is that the buffer is + returned in the state that it was passed in, so implementing + this require good citizenship, you'll need to remember the current + position, change the position to get at the data you're interested + in and then set the position back to how you found it... + + //TODO: there should be an abstract implementation that implements + cb as described above, marks it final an provides a new callback + with signature cb(byte[], int, int) + */ + public int cb(HTTPParser p, ByteBuffer buf, int pos, int len); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java new file mode 100644 index 0000000..d38d9d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java @@ -0,0 +1,7 @@ +package http_parser.lolevel; + +import java.nio.ByteBuffer; + +public interface HTTPErrorCallback { + public void cb (HTTPParser parser, String mes, ByteBuffer buf, int initial_position); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java new file mode 100644 index 0000000..42022ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java @@ -0,0 +1,2161 @@ +package http_parser.lolevel; + +import java.nio.ByteBuffer; +import http_parser.HTTPException; +import http_parser.HTTPMethod; +import http_parser.HTTPParserUrl; +import http_parser.ParserType; +import static http_parser.lolevel.HTTPParser.C.*; +import static http_parser.lolevel.HTTPParser.State.*; + +public class HTTPParser { + /* lots of unsigned chars here, not sure what + to about them, `bytes` in java suck... */ + + ParserType type; + State state; + HState header_state; + boolean strict; + + int index; + int flags; // TODO + + int nread; + long content_length; + + int p_start; // updated each call to execute to indicate where the buffer was before we began calling it. + + /** READ-ONLY **/ + public int http_major; + public int http_minor; + public int status_code; /* responses only */ + public HTTPMethod method; /* requests only */ + + /* true = Upgrade header was present and the parser has exited because of that. + * false = No upgrade header present. + * Should be checked when http_parser_execute() returns in addition to + * error checking. + */ + public boolean upgrade; + + /** PUBLIC **/ + // TODO : this is used in c to maintain application state. + // is this even necessary? we have state in java ? + // consider + // Object data; /* A pointer to get hook to the "connection" or "socket" object */ + + + /* + * technically we could combine all of these (except for url_mark) into one + * variable, saving stack space, but it seems more clear to have them + * separated. + */ + int header_field_mark = -1; + int header_value_mark = -1; + int url_mark = -1; + int body_mark = -1; + + /** + * Construct a Parser for ParserType.HTTP_BOTH, meaning it + * determines whether it's parsing a request or a response. + */ + public HTTPParser() { + this(ParserType.HTTP_BOTH); + } + + /** + * Construct a Parser and initialise it to parse either + * requests or responses. + */ + public HTTPParser(ParserType type) { + this.type = type; + switch(type) { + case HTTP_REQUEST: + this.state = State.start_req; + break; + case HTTP_RESPONSE: + this.state = State.start_res; + break; + case HTTP_BOTH: + this.state = State.start_req_or_res; + break; + default: + throw new HTTPException("can't happen, invalid ParserType enum"); + } + } + + /* + * Utility to facilitate System.out.println style debugging (the way god intended) + */ + static void p(Object o) {System.out.println(o);} + + /** Comment from C version follows + * + * Our URL parser. + * + * This is designed to be shared by http_parser_execute() for URL validation, + * hence it has a state transition + byte-for-byte interface. In addition, it + * is meant to be embedded in http_parser_parse_url(), which does the dirty + * work of turning state transitions URL components for its API. + * + * This function should only be invoked with non-space characters. It is + * assumed that the caller cares about (and can detect) the transition between + * URL and non-URL states by looking for these. + */ + public State parse_url_char(byte ch) { + + int chi = ch & 0xff; // utility, ch without signedness for table lookups. + + if(SPACE == ch){ + throw new HTTPException("space as url char"); + } + + switch(state) { + case req_spaces_before_url: + /* Proxied requests are followed by scheme of an absolute URI (alpha). + * All methods except CONNECT are followed by '/' or '*'. + */ + if(SLASH == ch || STAR == ch){ + return req_path; + } + if(isAtoZ(ch)){ + return req_schema; + } + break; + case req_schema: + if(isAtoZ(ch)){ + return req_schema; + } + if(COLON == ch){ + return req_schema_slash; + } + break; + case req_schema_slash: + if(SLASH == ch){ + return req_schema_slash_slash; + } + break; + case req_schema_slash_slash: + if(SLASH == ch){ + return req_host_start; + } + break; + case req_host_start: + if (ch == (byte)'[') { + return req_host_v6_start; + } + if (isHostChar(ch)) { + return req_host; + } + break; + + case req_host: + if (isHostChar(ch)) { + return req_host; + } + + /* FALLTHROUGH */ + case req_host_v6_end: + switch (ch) { + case ':': + return req_port_start; + case '/': + return req_path; + case '?': + return req_query_string_start; + } + break; + + case req_host_v6: + if (ch == ']') { + return req_host_v6_end; + } + + /* FALLTHROUGH */ + case req_host_v6_start: + if (isHex(ch) || ch == ':') { + return req_host_v6; + } + break; + + case req_port: + switch (ch) { + case '/': + return req_path; + case '?': + return req_query_string_start; + } + + /* FALLTHROUGH */ + case req_port_start: + if (isDigit(ch)) { + return req_port; + } + break; + + case req_path: + if (isNormalUrlChar(chi)) { + return req_path; + } + switch (ch) { + case '?': + return req_query_string_start; + case '#': + return req_fragment_start; + } + + break; + + case req_query_string_start: + case req_query_string: + if (isNormalUrlChar(chi)) { + return req_query_string; + } + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + return req_query_string; + + case '#': + return req_fragment_start; + } + + break; + + case req_fragment_start: + if (isNormalUrlChar(chi)) { + return req_fragment; + } + switch (ch) { + case '?': + return req_fragment; + + case '#': + return req_fragment_start; + } + break; + + case req_fragment: + if (isNormalUrlChar(ch)) { + return req_fragment; + } + + switch (ch) { + case '?': + case '#': + return req_fragment; + } + + break; + default: + break; + } + + /* We should never fall out of the switch above unless there's an error */ + return dead; + } + + /** Execute the parser with the currently available data contained in + * the buffer. The buffers position() and limit() need to be set + * correctly (obviously) and a will be updated approriately when the + * method returns to reflect the consumed data. + */ + public int execute(ParserSettings settings, ByteBuffer data) { + + int p = data.position(); + this.p_start = p; // this is used for pretty printing errors. + // and returning the amount of processed bytes. + + + // In case the headers don't provide information about the content + // length, `execute` needs to be called with an empty buffer to + // indicate that all the data has been send be the client/server, + // else there is no way of knowing the message is complete. + int len = (data.limit() - data.position()); + if (0 == len) { +// if (State.body_identity_eof == state) { +// settings.call_on_message_complete(this); +// } + switch (state) { + case body_identity_eof: + settings.call_on_message_complete(this); + return data.position() - this.p_start; + + case dead: + case start_req_or_res: + case start_res: + case start_req: + return data.position() - this.p_start; + + default: + // should we really consider this an error!? + throw new HTTPException("empty bytes! "+state); // error + } + } + + + // in case the _previous_ call to the parser only has data to get to + // the middle of certain fields, we need to update marks to point at + // the beginning of the current buffer. + switch (state) { + case header_field: + header_field_mark = p; + break; + case header_value: + header_value_mark = p; + break; + case req_path: + case req_schema: + case req_schema_slash: + case req_schema_slash_slash: + case req_host_start: + case req_host_v6_start: + case req_host_v6: + case req_host_v6_end: + case req_host: + case req_port_start: + case req_port: + case req_query_string_start: + case req_query_string: + case req_fragment_start: + case req_fragment: + url_mark = p; + break; + } + boolean reexecute = false; + int pe = 0; + byte ch = 0; + int chi = 0; + byte c = -1; + int to_read = 0; + + // this is where the work gets done, traverse the available data... + while (data.position() != data.limit() || reexecute) { +// p(state + ": r: " + reexecute + " :: " +p ); + + if(!reexecute){ + p = data.position(); + pe = data.limit(); + ch = data.get(); // the current character to process. + chi = ch & 0xff; // utility, ch without signedness for table lookups. + c = -1; // utility variably used for up- and downcasing etc. + to_read = 0; // used to keep track of how much of body, etc. is left to read + + if (parsing_header(state)) { + ++nread; + if (nread > HTTP_MAX_HEADER_SIZE) { + return error(settings, "possible buffer overflow", data); + } + } + } + reexecute = false; +// p(state + " ::: " + ch + " : " + (((CR == ch) || (LF == ch)) ? ch : ("'" + (char)ch + "'")) +": "+p ); + + switch (state) { + /* + * this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + case dead: + if (CR == ch || LF == ch){ + break; + } + return error(settings, "Connection already closed", data); + + + + case start_req_or_res: + if (CR == ch || LF == ch){ + break; + } + flags = 0; + content_length = -1; + + if (H == ch) { + state = State.res_or_resp_H; + } else { + type = ParserType.HTTP_REQUEST; + method = start_req_method_assign(ch); + if (null == method) { + return error(settings, "invalid method", data); + } + index = 1; + state = State.req_method; + } + settings.call_on_message_begin(this); + break; + + + + case res_or_resp_H: + if (T == ch) { + type = ParserType.HTTP_RESPONSE; + state = State.res_HT; + } else { + if (E != ch) { + return error(settings, "not E", data); + } + type = ParserType.HTTP_REQUEST; + method = HTTPMethod.HTTP_HEAD; + index = 2; + state = State.req_method; + } + break; + + + + case start_res: + flags = 0; + content_length = -1; + + switch(ch) { + case H: + state = State.res_H; + break; + case CR: + case LF: + break; + default: + return error(settings, "Not H or CR/LF", data); + } + + settings.call_on_message_begin(this); + break; + + + + case res_H: + if (strict && T != ch) { + return error(settings, "Not T", data); + } + state = State.res_HT; + break; + case res_HT: + if (strict && T != ch) { +return error(settings, "Not T2", data); + } + state = State.res_HTT; + break; + case res_HTT: + if (strict && P != ch) { +return error(settings, "Not P", data); + } + state = State.res_HTTP; + break; + case res_HTTP: + if (strict && SLASH != ch) { +return error(settings, "Not '/'", data); + } + state = State.res_first_http_major; + break; + + + + case res_first_http_major: + if (!isDigit(ch)) { +return error(settings, "Not a digit", data); + } + http_major = (int) ch - 0x30; + state = State.res_http_major; + break; + + /* major HTTP version or dot */ + case res_http_major: + if (DOT == ch) { + state = State.res_first_http_minor; + break; + } + if (!isDigit(ch)) { +return error(settings, "Not a digit", data); + } + http_major *= 10; + http_major += (ch - 0x30); + + if (http_major > 999) { +return error(settings, "invalid http major version: ", data); + } + break; + + /* first digit of minor HTTP version */ + case res_first_http_minor: + if (!isDigit(ch)) { +return error(settings, "Not a digit", data); + } + http_minor = (int)ch - 0x30; + state = State.res_http_minor; + break; + + /* minor HTTP version or end of request line */ + case res_http_minor: + if (SPACE == ch) { + state = State.res_first_status_code; + break; + } + if (!isDigit(ch)) { +return error(settings, "Not a digit", data); + } + http_minor *= 10; + http_minor += (ch - 0x30); + if (http_minor > 999) { +return error(settings, "invalid http minor version: ", data); + } + break; + + + + case res_first_status_code: + if (!isDigit(ch)) { + if (SPACE == ch) { + break; + } +return error(settings, "Not a digit (status code)", data); + } + status_code = (int)ch - 0x30; + state = State.res_status_code; + break; + + case res_status_code: + if (!isDigit(ch)) { + switch(ch) { + case SPACE: + state = State.res_status; + break; + case CR: + state = State.res_line_almost_done; + break; + case LF: + state = State.header_field_start; + break; + default: +return error(settings, "not a valid status code", data); + } + break; + } + status_code *= 10; + status_code += (int)ch - 0x30; + if (status_code > 999) { +return error(settings, "ridiculous status code:", data); + } + + if (status_code > 99) { + settings.call_on_status_complete(this); + } + break; + + case res_status: + /* the human readable status. e.g. "NOT FOUND" + * we are not humans so just ignore this + * we are not men, we are devo. */ + + if (CR == ch) { + state = State.res_line_almost_done; + break; + } + if (LF == ch) { + state = State.header_field_start; + break; + } + break; + + case res_line_almost_done: + if (strict && LF != ch) { +return error(settings, "not LF", data); + } + state = State.header_field_start; + break; + + + + case start_req: + if (CR==ch || LF == ch) { + break; + } + flags = 0; + content_length = -1; + + if(!isAtoZ(ch)){ + return error(settings, "invalid method", data); + } + + method = start_req_method_assign(ch); + if (null == method) { + return error(settings, "invalid method", data); + } + index = 1; + state = State.req_method; + + settings.call_on_message_begin(this); + break; + + + + case req_method: + if (0 == ch) { + return error(settings, "NULL in method", data); + } + + byte [] arr = method.bytes; + + if (SPACE == ch && index == arr.length) { + state = State.req_spaces_before_url; + } else if (arr[index] == ch) { + // wuhu! + } else if (HTTPMethod.HTTP_CONNECT == method) { + if (1 == index && H == ch) { + method = HTTPMethod.HTTP_CHECKOUT; + } else if (2 == index && P == ch) { + method = HTTPMethod.HTTP_COPY; + } + } else if (HTTPMethod.HTTP_MKCOL == method) { + if (1 == index && O == ch) { + method = HTTPMethod.HTTP_MOVE; + } else if (1 == index && E == ch) { + method = HTTPMethod.HTTP_MERGE; + } else if (1 == index && DASH == ch) { /* M-SEARCH */ + method = HTTPMethod.HTTP_MSEARCH; + } else if (2 == index && A == ch) { + method = HTTPMethod.HTTP_MKACTIVITY; + } + } else if (1 == index && HTTPMethod.HTTP_POST == method) { + if(R == ch) { + method = HTTPMethod.HTTP_PROPFIND; /* or HTTP_PROPPATCH */ + }else if(U == ch){ + method = HTTPMethod.HTTP_PUT; /* or HTTP_PURGE */ + }else if(A == ch){ + method = HTTPMethod.HTTP_PATCH; + } + } else if (2 == index) { + if(HTTPMethod.HTTP_PUT == method) { + if(R == ch){ + method = HTTPMethod.HTTP_PURGE; + } + }else if(HTTPMethod.HTTP_UNLOCK == method){ + if(S == ch){ + method = HTTPMethod.HTTP_UNSUBSCRIBE; + } + } + }else if(4 == index && HTTPMethod.HTTP_PROPFIND == method && P == ch){ + method = HTTPMethod.HTTP_PROPPATCH; + } else { + return error(settings, "Invalid HTTP method", data); + } + + ++index; + break; + + + + /******************* URL *******************/ + case req_spaces_before_url: + if (SPACE == ch) { + break; + } + url_mark = p; + if(HTTPMethod.HTTP_CONNECT == method){ + state = req_host_start; + } + + state = parse_url_char(ch); + if(state == dead){ + return error(settings, "Invalid something", data); + } + break; + + + case req_schema: + case req_schema_slash: + case req_schema_slash_slash: + case req_host_start: + case req_host_v6_start: + case req_host_v6: + case req_port_start: + switch (ch) { + /* No whitespace allowed here */ + case SPACE: + case CR: + case LF: + return error(settings, "unexpected char in path", data); + default: + state = parse_url_char(ch); + if(dead == state){ + return error(settings, "unexpected char in path", data); + } + } + break; + + case req_host: + case req_host_v6_end: + case req_port: + case req_path: + case req_query_string_start: + case req_query_string: + case req_fragment_start: + case req_fragment: + switch (ch) { + case SPACE: + settings.call_on_url(this, data, url_mark, p-url_mark); + settings.call_on_path(this, data, url_mark, p - url_mark); + url_mark = -1; + state = State.req_http_start; + break; + case CR: + case LF: + http_major = 0; + http_minor = 9; + state = (CR == ch) ? req_line_almost_done : header_field_start; + settings.call_on_url(this, data, url_mark, p-url_mark); //TODO check params!!! + settings.call_on_path(this, data, url_mark, p-url_mark); + url_mark = -1; + break; + default: + state = parse_url_char(ch); + if(dead == state){ + return error(settings, "unexpected char in path", data); + } + } + break; + /******************* URL *******************/ + + + + /******************* HTTP 1.1 *******************/ + case req_http_start: + switch (ch) { + case H: + state = State.req_http_H; + break; + case SPACE: + break; + default: + return error(settings, "error in req_http_H", data); + } + break; + + case req_http_H: + if (strict && T != ch) { + return error(settings, "unexpected char", data); + } + state = State.req_http_HT; + break; + + case req_http_HT: + if (strict && T != ch) { + return error(settings, "unexpected char", data); + } + state = State.req_http_HTT; + break; + + case req_http_HTT: + if (strict && P != ch) { + return error(settings, "unexpected char", data); + } + state = State.req_http_HTTP; + break; + + case req_http_HTTP: + if (strict && SLASH != ch) { + return error(settings, "unexpected char", data); + } + state = req_first_http_major; + break; + + /* first digit of major HTTP version */ + case req_first_http_major: + if (!isDigit(ch)) { +return error(settings, "non digit in http major", data); + } + http_major = (int)ch - 0x30; + state = State.req_http_major; + break; + + /* major HTTP version or dot */ + case req_http_major: + if (DOT == ch) { + state = State.req_first_http_minor; + break; + } + + if (!isDigit(ch)) { +return error(settings, "non digit in http major", data); + } + + http_major *= 10; + http_major += (int)ch - 0x30; + + if (http_major > 999) { +return error(settings, "ridiculous http major", data); + }; + break; + + /* first digit of minor HTTP version */ + case req_first_http_minor: + if (!isDigit(ch)) { +return error(settings, "non digit in http minor", data); + } + http_minor = (int)ch - 0x30; + state = State.req_http_minor; + break; + + case req_http_minor: + if (ch == CR) { + state = State.req_line_almost_done; + break; + } + + if (ch == LF) { + state = State.header_field_start; + break; + } + + /* XXX allow spaces after digit? */ + + if (!isDigit(ch)) { +return error(settings, "non digit in http minor", data); + } + + http_minor *= 10; + http_minor += (int)ch - 0x30; + + + if (http_minor > 999) { +return error(settings, "ridiculous http minor", data); + }; + + break; + + /* end of request line */ + case req_line_almost_done: + { + if (ch != LF) { +return error(settings, "missing LF after request line", data); + } + state = header_field_start; + break; + } + + /******************* HTTP 1.1 *******************/ + + + + /******************* Header *******************/ + case header_field_start: + { + if (ch == CR) { + state = headers_almost_done; + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + state = State.headers_almost_done; + reexecute = true; + break; + } + + c = token(ch); + + if (0 == c) { + return error(settings, "invalid char in header:", data); + } + + header_field_mark = p; + + index = 0; + state = State.header_field; + + switch (c) { + case C: + header_state = HState.C; + break; + + case P: + header_state = HState.matching_proxy_connection; + break; + + case T: + header_state = HState.matching_transfer_encoding; + break; + + case U: + header_state = HState.matching_upgrade; + break; + + default: + header_state = HState.general; + break; + } + break; + } + + + + case header_field: + { + c = token(ch); + if (0 != c) { + switch (header_state) { + case general: + break; + + case C: + index++; + header_state = (O == c ? HState.CO : HState.general); + break; + + case CO: + index++; + header_state = (N == c ? HState.CON : HState.general); + break; + + case CON: + index++; + switch (c) { + case N: + header_state = HState.matching_connection; + break; + case T: + header_state = HState.matching_content_length; + break; + default: + header_state = HState.general; + break; + } + break; + + /* connection */ + + case matching_connection: + index++; + if (index > CONNECTION.length || c != CONNECTION[index]) { + header_state = HState.general; + } else if (index == CONNECTION.length-1) { + header_state = HState.connection; + } + break; + + /* proxy-connection */ + + case matching_proxy_connection: + index++; + if (index > PROXY_CONNECTION.length || c != PROXY_CONNECTION[index]) { + header_state = HState.general; + } else if (index == PROXY_CONNECTION.length-1) { + header_state = HState.connection; + } + break; + + /* content-length */ + + case matching_content_length: + index++; + if (index > CONTENT_LENGTH.length || c != CONTENT_LENGTH[index]) { + header_state = HState.general; + } else if (index == CONTENT_LENGTH.length-1) { + header_state = HState.content_length; + } + break; + + /* transfer-encoding */ + + case matching_transfer_encoding: + index++; + if (index > TRANSFER_ENCODING.length || c != TRANSFER_ENCODING[index]) { + header_state = HState.general; + } else if (index == TRANSFER_ENCODING.length-1) { + header_state = HState.transfer_encoding; + } + break; + + /* upgrade */ + + case matching_upgrade: + index++; + if (index > UPGRADE.length || c != UPGRADE[index]) { + header_state = HState.general; + } else if (index == UPGRADE.length-1) { + header_state = HState.upgrade; + } + break; + + case connection: + case content_length: + case transfer_encoding: + case upgrade: + if (SPACE != ch) header_state = HState.general; + break; + + default: +return error(settings, "Unknown Header State", data); + } // switch: header_state + break; + } // 0 != c + + if (COLON == ch) { + settings.call_on_header_field(this, data, header_field_mark, p-header_field_mark); + header_field_mark = -1; + + state = State.header_value_start; + break; + } + + if (CR == ch) { + state = State.header_almost_done; + settings.call_on_header_field(this, data, header_field_mark, p-header_field_mark); + + header_field_mark = -1; + break; + } + + if (ch == LF) { + settings.call_on_header_field(this, data, header_field_mark, p-header_field_mark); + header_field_mark = -1; + + state = State.header_field_start; + break; + } + +return error(settings, "invalid header field", data); + } + + + + case header_value_start: + { + if ((SPACE == ch) || (TAB == ch)) break; + + header_value_mark = p; + + state = State.header_value; + index = 0; + + + if (CR == ch) { + settings.call_on_header_value(this, data, header_value_mark, p-header_value_mark); + header_value_mark = -1; + + header_state = HState.general; + state = State.header_almost_done; + break; + } + + if (LF == ch) { + settings.call_on_header_value(this, data, header_value_mark, p-header_value_mark); + header_value_mark = -1; + + state = State.header_field_start; + break; + } + + + c = upper(ch); + + switch (header_state) { + case upgrade: + flags |= F_UPGRADE; + header_state = HState.general; + break; + + case transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if (C == c) { + header_state = HState.matching_transfer_encoding_chunked; + } else { + header_state = HState.general; + } + break; + + case content_length: + if (!isDigit(ch)) { +return error(settings, "Content-Length not numeric", data); + } + content_length = (int)ch - 0x30; + break; + + case connection: + /* looking for 'Connection: keep-alive' */ + if (K == c) { + header_state = HState.matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (C == c) { + header_state = HState.matching_connection_close; + } else { + header_state = HState.general; + } + break; + + default: + header_state = HState.general; + break; + } + break; + } // header value start + + + + case header_value: + { + + if (CR == ch) { + settings.call_on_header_value(this, data, header_value_mark, p-header_value_mark); + header_value_mark = -1; + + state = State.header_almost_done; + break; + } + + if (LF == ch) { + settings.call_on_header_value(this, data, header_value_mark, p-header_value_mark); + header_value_mark = -1; + state = header_almost_done; + reexecute = true; + break; + } + + c = upper(ch); + switch (header_state) { + case general: + break; + + case connection: + case transfer_encoding: +return error(settings, "Shouldn't be here", data); + + case content_length: + if (SPACE == ch) { + break; + } + if (!isDigit(ch)) { +return error(settings, "Content-Length not numeric", data); + } + + long t = content_length; + t *= 10; + t += (long)ch - 0x30; + + /* Overflow? */ + // t will wrap and become negative ... + if (t < content_length) { + return error(settings, "Invalid content length", data); + } + content_length = t; + break; + + /* Transfer-Encoding: chunked */ + case matching_transfer_encoding_chunked: + index++; + if (index > CHUNKED.length || c != CHUNKED[index]) { + header_state = HState.general; + } else if (index == CHUNKED.length-1) { + header_state = HState.transfer_encoding_chunked; + } + break; + + /* looking for 'Connection: keep-alive' */ + case matching_connection_keep_alive: + index++; + if (index > KEEP_ALIVE.length || c != KEEP_ALIVE[index]) { + header_state = HState.general; + } else if (index == KEEP_ALIVE.length-1) { + header_state = HState.connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case matching_connection_close: + index++; + if (index > CLOSE.length || c != CLOSE[index]) { + header_state = HState.general; + } else if (index == CLOSE.length-1) { + header_state = HState.connection_close; + } + break; + + case transfer_encoding_chunked: + case connection_keep_alive: + case connection_close: + if (SPACE != ch) header_state = HState.general; + break; + + default: + state = State.header_value; + header_state = HState.general; + break; + } + break; + } // header_value + + + + case header_almost_done: + if (!header_almost_done(ch)) { + return error(settings, "incorrect header ending, expecting LF", data); + } + break; + + case header_value_lws: + if (SPACE == ch || TAB == ch ){ + state = header_value_start; + } else { + state = header_field_start; + reexecute = true; + } + break; + + case headers_almost_done: + if (LF != ch) { + return error(settings, "header not properly completed", data); + } + if (0 != (flags & F_TRAILING)) { + /* End of a chunked request */ + state = new_message(); + settings.call_on_headers_complete(this); + settings.call_on_message_complete(this); + break; + } + + state = headers_done; + + if (0 != (flags & F_UPGRADE) || HTTPMethod.HTTP_CONNECT == method) { + upgrade = true; + } + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + */ + + /* (responses to HEAD request contain a CONTENT-LENGTH header + * but no content) + * + * Consider what to do here: I don't like the idea of the callback + * interface having a different contract in the case of HEAD + * responses. The alternatives would be either to: + * + * a.) require the header_complete callback to implement a different + * interface or + * + * b.) provide an overridden execute(bla, bla, boolean + * parsingHeader) implementation ... + */ + + /*TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO */ + if (null != settings.on_headers_complete) { + settings.call_on_headers_complete(this); + //return; + } + + // if (null != settings.on_headers_complete) { + // switch (settings.on_headers_complete.cb(parser)) { + // case 0: + // break; + // + // case 1: + // flags |= F_SKIPBODY; + // break; + // + // default: + // return p - data; /* Error */ // TODO // RuntimeException ? + // } + // } + reexecute = true; + break; + + case headers_done: + if (strict && (LF != ch)) { + return error(settings, "STRICT CHECK", data); //TODO correct error msg + } + + nread = 0; + + // Exit, the rest of the connect is in a different protocol. + if (upgrade) { + state = new_message(); + settings.call_on_message_complete(this); + return data.position()-this.p_start; + } + + if (0 != (flags & F_SKIPBODY)) { + state = new_message(); + settings.call_on_message_complete(this); + } else if (0 != (flags & F_CHUNKED)) { + /* chunked encoding - ignore Content-Length header */ + state = State.chunk_size_start; + } else { + if (content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + state = new_message(); + settings.call_on_message_complete(this); + } else if (content_length != -1) { + /* Content-Length header given and non-zero */ + state = State.body_identity; + } else { + if (type == ParserType.HTTP_REQUEST || !http_message_needs_eof()) { + /* Assume content-length 0 - read the next */ + state = new_message(); + settings.call_on_message_complete(this); + } else { + /* Read body until EOF */ + state = State.body_identity_eof; + } + } + } + + break; + /******************* Header *******************/ + + + + + /******************* Body *******************/ + case body_identity: + to_read = min(pe - p, content_length); //TODO change to use buffer? + body_mark = p; + + if (to_read > 0) { + settings.call_on_body(this, data, p, to_read); + data.position(p+to_read); + content_length -= to_read; + + if (content_length == 0) { + state = message_done; + reexecute = true; + } + } + break; + + + + case body_identity_eof: + to_read = pe - p; // TODO change to use buffer ? + if (to_read > 0) { + settings.call_on_body(this, data, p, to_read); + data.position(p+to_read); + } + break; + + case message_done: + state = new_message(); + settings.call_on_message_complete(this); + break; + /******************* Body *******************/ + + + + /******************* Chunk *******************/ + case chunk_size_start: + if (1 != this.nread) { +return error(settings, "nread != 1 (chunking)", data); + + } + if (0 == (flags & F_CHUNKED)) { +return error(settings, "not chunked", data); + } + + c = UNHEX[chi]; + if (c == -1) { +return error(settings, "invalid hex char in chunk content length", data); + } + content_length = c; + state = State.chunk_size; + break; + + + + case chunk_size: + if (0 == (flags & F_CHUNKED)) { + return error(settings, "not chunked", data); + } + + if (CR == ch) { + state = State.chunk_size_almost_done; + break; + } + + c = UNHEX[chi]; + + if (c == -1) { + if (SEMI == ch || SPACE == ch) { + state = State.chunk_parameters; + break; + } + return error(settings, "invalid hex char in chunk content length", data); + } + long t = content_length; + + t *= 16; + t += c; + if(t < content_length){ + return error(settings, "invalid content length", data); + } + content_length = t; + break; + + + + case chunk_parameters: + if (0 == (flags & F_CHUNKED)) { +return error(settings, "not chunked", data); + } + /* just ignore this shit. TODO check for overflow */ + if (CR == ch) { + state = State.chunk_size_almost_done; + break; + } + break; + + + + case chunk_size_almost_done: + if (0 == (flags & F_CHUNKED)) { +return error(settings, "not chunked", data); + } + if (strict && LF != ch) { +return error(settings, "expected LF at end of chunk size", data); + } + + this.nread = 0; + + if (0 == content_length) { + flags |= F_TRAILING; + state = State.header_field_start; + } else { + state = State.chunk_data; + } + break; + + + + case chunk_data: + //TODO Apply changes from C version for s_chunk_data + if (0 == (flags & F_CHUNKED)) { + return error(settings, "not chunked", data); + } + + to_read = min(pe-p, content_length); + if (to_read > 0) { + settings.call_on_body(this, data, p, to_read); + data.position(p+to_read); + } + + if (to_read == content_length) { + state = State.chunk_data_almost_done; + } + + content_length -= to_read; + break; + + + + case chunk_data_almost_done: + if (0 == (flags & F_CHUNKED)) { +return error(settings, "not chunked", data); + } + if (strict && CR != ch) { +return error(settings, "chunk data terminated incorrectly, expected CR", data); + } + state = State.chunk_data_done; + //TODO CALLBACK_DATA(body) + // settings.call_on_body(this, data,p,?); + break; + + + + case chunk_data_done: + if (0 == (flags & F_CHUNKED)) { +return error(settings, "not chunked", data); + } + if (strict && LF != ch) { +return error(settings, "chunk data terminated incorrectly, expected LF", data); + } + state = State.chunk_size_start; + break; + /******************* Chunk *******************/ + + + + default: +return error(settings, "unhandled state", data); + + } // switch + } // while + + p = data.position(); + + + /* Reaching this point assumes that we only received part of a + * message, inform the callbacks about the progress made so far*/ + + settings.call_on_header_field(this, data, header_field_mark, p-header_field_mark); + settings.call_on_header_value(this, data, header_value_mark, p-header_value_mark); + settings.call_on_url (this, data, url_mark, p-url_mark); + settings.call_on_path (this, data, url_mark, p-url_mark); + + return data.position()-this.p_start; + } // execute + + int error (ParserSettings settings, String mes, ByteBuffer data) { + settings.call_on_error(this, mes, data, this.p_start); + this.state = State.dead; + return data.position()-this.p_start; + } + + public boolean http_message_needs_eof() { + if(type == ParserType.HTTP_REQUEST){ + return false; + } + /* See RFC 2616 section 4.4 */ + if ((status_code / 100 == 1) || /* 1xx e.g. Continue */ + (status_code == 204) || /* No Content */ + (status_code == 304) || /* Not Modified */ + (flags & F_SKIPBODY) != 0) { /* response to a HEAD request */ + return false; + } + if ((flags & F_CHUNKED) != 0 || content_length != -1) { + return false; + } + + return true; + } + + /* If http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns true, then this will be should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ + public boolean http_should_keep_alive() { + if (http_major > 0 && http_minor > 0) { + /* HTTP/1.1 */ + if ( 0 != (flags & F_CONNECTION_CLOSE) ) { + return false; + } + } else { + /* HTTP/1.0 or earlier */ + if ( 0 == (flags & F_CONNECTION_KEEP_ALIVE) ) { + return false; + } + } + return !http_message_needs_eof(); + } + + public int parse_url(ByteBuffer data, boolean is_connect, HTTPParserUrl u) { + + UrlFields uf = UrlFields.UF_MAX; + UrlFields old_uf = UrlFields.UF_MAX; + u.port = 0; + u.field_set = 0; + state = (is_connect ? State.req_host_start : State.req_spaces_before_url); + int p_init = data.position(); + int p = 0; + byte ch = 0; + while (data.position() != data.limit()) { + p = data.position(); + ch = data.get(); + state = parse_url_char(ch); + switch(state) { + case dead: + return 1; + + /* Skip delimeters */ + case req_schema_slash: + case req_schema_slash_slash: + case req_host_start: + case req_host_v6_start: + case req_host_v6_end: + case req_port_start: + case req_query_string_start: + case req_fragment_start: + continue; + + case req_schema: + uf = UrlFields.UF_SCHEMA; + break; + + case req_host: + case req_host_v6: + uf = UrlFields.UF_HOST; + break; + + case req_port: + uf = UrlFields.UF_PORT; + break; + + case req_path: + uf = UrlFields.UF_PATH; + break; + + case req_query_string: + uf = UrlFields.UF_QUERY; + break; + + case req_fragment: + uf = UrlFields.UF_FRAGMENT; + break; + + default: + return 1; + } + /* Nothing's changed; soldier on */ + if (uf == old_uf) { + u.field_data[uf.getIndex()].len++; + continue; + } + + u.field_data[uf.getIndex()].off = p - p_init; + u.field_data[uf.getIndex()].len = 1; + + u.field_set |= (1 << uf.getIndex()); + old_uf = uf; + + } + + /* CONNECT requests can only contain "hostname:port" */ + if (is_connect && u.field_set != ((1 << UrlFields.UF_HOST.getIndex())|(1 << UrlFields.UF_PORT.getIndex()))) { + return 1; + } + + /* Make sure we don't end somewhere unexpected */ + switch (state) { + case req_host_v6_start: + case req_host_v6: + case req_host_v6_end: + case req_host: + case req_port_start: + return 1; + default: + break; + } + + if (0 != (u.field_set & (1 << UrlFields.UF_PORT.getIndex()))) { + /* Don't bother with endp; we've already validated the string */ + int v = strtoi(data, p_init + u.field_data[UrlFields.UF_PORT.getIndex()].off); + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } + + u.port = v; + } + + return 0; + } + + //hacky reimplementation of srttoul, tailored for our simple needs + //we only need to parse port val, so no negative values etc + int strtoi(ByteBuffer data, int start_pos) { + data.position(start_pos); + byte ch; + String str = ""; + while(data.position() < data.limit()) { + ch = data.get(); + if(Character.isWhitespace((char)ch)){ + continue; + } + if(isDigit(ch)){ + str = str + (char)ch; //TODO replace with something less hacky + }else{ + break; + } + } + return Integer.parseInt(str); + } + + boolean isDigit(byte b) { + if (b >= 0x30 && b <=0x39) { + return true; + } + return false; + } + + boolean isHex(byte b) { + return isDigit(b) || (lower(b) >= 0x61 /*a*/ && lower(b) <= 0x66 /*f*/); + } + + boolean isAtoZ(byte b) { + byte c = lower(b); + return (c>= 0x61 /*a*/ && c <= 0x7a /*z*/); + } + + + byte lower (byte b) { + return (byte)(b|0x20); + } + + byte upper(byte b) { + char c = (char)(b); + return (byte)Character.toUpperCase(c); + } + + byte token(byte b) { + if(!strict){ + return (b == (byte)' ') ? (byte)' ' : (byte)tokens[b] ; + }else{ + return (byte)tokens[b]; + } + } + + boolean isHostChar(byte ch){ + if(!strict){ + return (isAtoZ(ch)) || isDigit(ch) || DOT == ch || DASH == ch || UNDER == ch ; + }else{ + return (isAtoZ(ch)) || isDigit(ch) || DOT == ch || DASH == ch; + } + } + + boolean isNormalUrlChar(int chi) { + if(!strict){ + return (chi > 0x80) || normal_url_char[chi]; + }else{ + return normal_url_char[chi]; + } + } + + HTTPMethod start_req_method_assign(byte c){ + switch (c) { + case C: return HTTPMethod.HTTP_CONNECT; /* or COPY, CHECKOUT */ + case D: return HTTPMethod.HTTP_DELETE; + case G: return HTTPMethod.HTTP_GET; + case H: return HTTPMethod.HTTP_HEAD; + case L: return HTTPMethod.HTTP_LOCK; + case M: return HTTPMethod.HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ + case N: return HTTPMethod.HTTP_NOTIFY; + case O: return HTTPMethod.HTTP_OPTIONS; + case P: return HTTPMethod.HTTP_POST; /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ + case R: return HTTPMethod.HTTP_REPORT; + case S: return HTTPMethod.HTTP_SUBSCRIBE; + case T: return HTTPMethod.HTTP_TRACE; + case U: return HTTPMethod.HTTP_UNLOCK; /* or UNSUBSCRIBE */ + } + return null; // ugh. + } + + boolean header_almost_done(byte ch) { + if (strict && LF != ch) { + return false; + } + + state = State.header_value_lws; + // TODO java enums support some sort of bitflag mechanism !? + switch (header_state) { + case connection_keep_alive: + flags |= F_CONNECTION_KEEP_ALIVE; + break; + case connection_close: + flags |= F_CONNECTION_CLOSE; + break; + case transfer_encoding_chunked: + flags |= F_CHUNKED; + break; + default: + break; + } + return true; + } + +// boolean headers_almost_done (byte ch, ParserSettings settings) { +// } // headers_almost_done + + + final int min (int a, int b) { + return a < b ? a : b; + } + + final int min (int a, long b) { + return a < b ? a : (int)b; + } + + /* probably not the best place to hide this ... */ + public boolean HTTP_PARSER_STRICT; + State new_message() { + if (HTTP_PARSER_STRICT){ + return http_should_keep_alive() ? start_state() : State.dead; + } else { + return start_state(); + } + + } + + State start_state() { + return type == ParserType.HTTP_REQUEST ? State.start_req : State.start_res; + } + + + boolean parsing_header(State state) { + + switch (state) { + case chunk_data : + case chunk_data_almost_done : + case chunk_data_done : + case body_identity : + case body_identity_eof : + case message_done : + return false; + + } + return true; + } + + /* "Dial C for Constants" */ + static class C { + static final int HTTP_MAX_HEADER_SIZE = 80 * 1024; + + static final int F_CHUNKED = 1 << 0; + static final int F_CONNECTION_KEEP_ALIVE = 1 << 1; + static final int F_CONNECTION_CLOSE = 1 << 2; + static final int F_TRAILING = 1 << 3; + static final int F_UPGRADE = 1 << 4; + static final int F_SKIPBODY = 1 << 5; + + static final byte [] UPCASE = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 0x38,0x39,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x41,0x42,0x43,0x44,0x45,0x46,0x47, 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, 0x58,0x59,0x5a,0x00,0x00,0x00,0x00,0x5f, + 0x00,0x41,0x42,0x43,0x44,0x45,0x46,0x47, 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, 0x58,0x59,0x5a,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; + static final byte [] CONNECTION = { + 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, + }; + static final byte [] PROXY_CONNECTION = { + 0x50, 0x52, 0x4f, 0x58, 0x59, 0x2d, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, + }; + static final byte [] CONTENT_LENGTH = { + 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, 0x2d, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, + }; + static final byte [] TRANSFER_ENCODING = { + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x46, 0x45, 0x52, 0x2d, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, + }; + static final byte [] UPGRADE = { + 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, 0x45, + }; + static final byte [] CHUNKED = { + 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x45, 0x44, + }; + static final byte [] KEEP_ALIVE = { + 0x4b, 0x45, 0x45, 0x50, 0x2d, 0x41, 0x4c, 0x49, 0x56, 0x45, + }; + static final byte [] CLOSE = { + 0x43, 0x4c, 0x4f, 0x53, 0x45, + }; + + /* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ + + static final char [] tokens = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, '!', 0, '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', 0 , +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'X', 'Y', 'Z', 0, 0, 0, 0, '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'X', 'Y', 'Z', 0, '|', 0, '~', 0, +/* hi bit set, not ascii */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }; + + static final byte [] UNHEX = + { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + + static final boolean [] normal_url_char = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + false, false, false, false, false, false, false, false, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + false, false, false, false, false, false, false, false, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + false, false, false, false, false, false, false, false, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + false, false, false, false, false, false, false, false, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + false, true, true, false, true, true, true, true, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + true, true, true, true, true, true, true, true, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + true, true, true, true, true, true, true, true, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + true, true, true, true, true, true, true, false, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + true, true, true, true, true, true, true, true, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + true, true, true, true, true, true, true, true, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + true, true, true, true, true, true, true, true, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + true, true, true, true, true, true, true, true, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + true, true, true, true, true, true, true, true, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + true, true, true, true, true, true, true, true, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + true, true, true, true, true, true, true, true, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + true, true, true, true, true, true, true, false, + +/* hi bit set, not ascii */ +/* Remainder of non-ASCII range are accepted as-is to support implicitly UTF-8 + * encoded paths. This is out of spec, but clients generate this and most other + * HTTP servers support it. We should, too. */ + + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + + }; + + public static final byte A = 0x41; + public static final byte B = 0x42; + public static final byte C = 0x43; + public static final byte D = 0x44; + public static final byte E = 0x45; + public static final byte F = 0x46; + public static final byte G = 0x47; + public static final byte H = 0x48; + public static final byte I = 0x49; + public static final byte J = 0x4a; + public static final byte K = 0x4b; + public static final byte L = 0x4c; + public static final byte M = 0x4d; + public static final byte N = 0x4e; + public static final byte O = 0x4f; + public static final byte P = 0x50; + public static final byte Q = 0x51; + public static final byte R = 0x52; + public static final byte S = 0x53; + public static final byte T = 0x54; + public static final byte U = 0x55; + public static final byte V = 0x56; + public static final byte W = 0x57; + public static final byte X = 0x58; + public static final byte Y = 0x59; + public static final byte Z = 0x5a; + public static final byte UNDER = 0x5f; + public static final byte CR = 0x0d; + public static final byte LF = 0x0a; + public static final byte DOT = 0x2e; + public static final byte SPACE = 0x20; + public static final byte TAB = 0x09; + public static final byte SEMI = 0x3b; + public static final byte COLON = 0x3a; + public static final byte HASH = 0x23; + public static final byte QMARK = 0x3f; + public static final byte SLASH = 0x2f; + public static final byte DASH = 0x2d; + public static final byte STAR = 0x2a; + public static final byte NULL = 0x00; + } + + enum State { + + dead + + , start_req_or_res + , res_or_resp_H + , start_res + , res_H + , res_HT + , res_HTT + , res_HTTP + , res_first_http_major + , res_http_major + , res_first_http_minor + , res_http_minor + , res_first_status_code + , res_status_code + , res_status + , res_line_almost_done + + , start_req + + , req_method + , req_spaces_before_url + , req_schema + , req_schema_slash + , req_schema_slash_slash + , req_host_start + , req_host_v6_start + , req_host_v6 + , req_host_v6_end + , req_host + , req_port_start + , req_port + , req_path + , req_query_string_start + , req_query_string + , req_fragment_start + , req_fragment + , req_http_start + , req_http_H + , req_http_HT + , req_http_HTT + , req_http_HTTP + , req_first_http_major + , req_http_major + , req_first_http_minor + , req_http_minor + , req_line_almost_done + + , header_field_start + , header_field + , header_value_start + , header_value + , header_value_lws + + , header_almost_done + + , chunk_size_start + , chunk_size + , chunk_parameters + , chunk_size_almost_done + + , headers_almost_done + , headers_done +// This space intentionally not left blank, comment from c, for orientation... +// the c version uses <= s_header_almost_done in java, we list the states explicitly +// in `parsing_header()` +/* Important: 's_headers_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + , chunk_data + , chunk_data_almost_done + , chunk_data_done + + , body_identity + , body_identity_eof + , message_done + + } + enum HState { + general + , C + , CO + , CON + + , matching_connection + , matching_proxy_connection + , matching_content_length + , matching_transfer_encoding + , matching_upgrade + + , connection + , content_length + , transfer_encoding + , upgrade + + , matching_transfer_encoding_chunked + , matching_connection_keep_alive + , matching_connection_close + + , transfer_encoding_chunked + , connection_keep_alive + , connection_close + } + public enum UrlFields { + UF_SCHEMA(0) + , UF_HOST(1) + , UF_PORT(2) + , UF_PATH(3) + , UF_QUERY(4) + , UF_FRAGMENT(5) + , UF_MAX(6); + + + private final int index; + + private UrlFields(int index) { + this.index = index; + } + public int getIndex() { + return index; + } + + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java new file mode 100644 index 0000000..1ebdd4f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java @@ -0,0 +1,83 @@ +package http_parser.lolevel; +import java.nio.ByteBuffer; +import http_parser.HTTPException; +public class ParserSettings { + + public HTTPCallback on_message_begin; + public HTTPDataCallback on_path; + public HTTPDataCallback on_query_string; + public HTTPDataCallback on_url; + public HTTPDataCallback on_fragment; + public HTTPCallback on_status_complete; + public HTTPDataCallback on_header_field; + public HTTPDataCallback on_header_value; + public HTTPCallback on_headers_complete; + public HTTPDataCallback on_body; + public HTTPCallback on_message_complete; + public HTTPErrorCallback on_error; + + void call_on_message_begin (HTTPParser p) { + call_on(on_message_begin, p); + } + + void call_on_message_complete (HTTPParser p) { + call_on(on_message_complete, p); + } + + // this one is a little bit different: + // the current `position` of the buffer is the location of the + // error, `ini_pos` indicates where the position of + // the buffer when it was passed to the `execute` method of the parser, i.e. + // using this information and `limit` we'll know all the valid data + // in the buffer around the error we can use to print pretty error + // messages. + void call_on_error (HTTPParser p, String mes, ByteBuffer buf, int ini_pos) { + if (null != on_error) { + on_error.cb(p, mes, buf, ini_pos); + return; + } + // if on_error gets called it MUST throw an exception, else the parser + // will attempt to continue parsing, which it can't because it's + // in an invalid state. + throw new HTTPException(mes); + } + + void call_on_header_field (HTTPParser p, ByteBuffer buf, int pos, int len) { + call_on(on_header_field, p, buf, pos, len); + } + void call_on_query_string (HTTPParser p, ByteBuffer buf, int pos, int len) { + call_on(on_query_string, p, buf, pos, len); + } + void call_on_fragment (HTTPParser p, ByteBuffer buf, int pos, int len) { + call_on(on_fragment, p, buf, pos, len); + } + void call_on_status_complete(HTTPParser p) { + call_on(on_status_complete, p); + } + void call_on_path (HTTPParser p, ByteBuffer buf, int pos, int len) { + call_on(on_path, p, buf, pos, len); + } + void call_on_header_value (HTTPParser p, ByteBuffer buf, int pos, int len) { + call_on(on_header_value, p, buf, pos, len); + } + void call_on_url (HTTPParser p, ByteBuffer buf, int pos, int len) { + call_on(on_url, p, buf, pos, len); + } + void call_on_body(HTTPParser p, ByteBuffer buf, int pos, int len) { + call_on(on_body, p, buf, pos, len); + } + void call_on_headers_complete(HTTPParser p) { + call_on(on_headers_complete, p); + } + void call_on (HTTPCallback cb, HTTPParser p) { + // cf. CALLBACK2 macro + if (null != cb) { + cb.cb(p); + } + } + void call_on (HTTPDataCallback cb, HTTPParser p, ByteBuffer buf, int pos, int len) { + if (null != cb && -1 != pos) { + cb.cb(p,buf,pos,len); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java new file mode 100644 index 0000000..62f0a0e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Message.java @@ -0,0 +1,374 @@ +package http_parser.lolevel; + +import java.nio.*; +import java.io.*; +import java.util.*; + +import http_parser.HTTPMethod; +import http_parser.HTTPParserUrl; +import http_parser.ParserType; +import http_parser.lolevel.TestLoaderNG.Header; +import http_parser.lolevel.TestLoaderNG.LastHeader; + +import primitive.collection.ByteList; + +import static http_parser.lolevel.Util.str; + +public class Message { + String name; + byte [] raw; + ParserType type; + HTTPMethod method; + int status_code; + String request_path; // byte [] ? + String request_url; + String fragment ; + String query_string; + byte [] body; + int body_size; + int num_headers; + LastHeader last_header_element; + Map header; + List
headers; + boolean should_keep_alive; + + byte[] upgrade; + boolean upgrade() { + return null != upgrade; + } + + int http_major; + int http_minor; + + boolean message_begin_called; + boolean headers_complete_called; + boolean message_complete_called; + boolean message_complete_on_eof; + + + Map parsed_header; + String currHField; + String currHValue; + byte [] pbody; + int num_called; + + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("NAME: "); b.append(name);b.append("\n"); + b.append("type: "); b.append(type);b.append("\n"); + b.append("method: "); b.append(method);b.append("\n"); + b.append("status_code: "); b.append(status_code);b.append("\n"); + b.append("request_path: "); b.append(request_path);b.append("\n"); + b.append("request_url: "); b.append(request_url);b.append("\n"); + b.append("fragment: "); b.append(fragment);b.append("\n"); + b.append("query_string: "); b.append(query_string);b.append("\n"); + b.append("body:\n"); b.append(new String(body));b.append("\n"); + b.append("should_keep_alive: "); b.append(should_keep_alive);b.append("\n"); + b.append("upgrade: "); b.append(upgrade);b.append("\n"); + b.append("http_major: "); b.append(http_major);b.append("\n"); + b.append("http_minor: "); b.append(http_minor);b.append("\n"); + b.append("message_complete_called: "); b.append(message_complete_called);b.append("\n"); + return b.toString(); + } + + Message () { + this.header = new HashMap(); + this.headers = new LinkedList
(); + reset(); + } + /* + *prepare this Test Instance for reuse. + * */ + void reset () { + this.parsed_header = new HashMap(); + this.pbody = null; + this.num_called = 0; + + } + void check (boolean val, String mes) { + if (!val) { + //p(name+" : "+mes); + throw new RuntimeException(name+" : "+mes); + } + } + + + HTTPDataCallback getCB (final String value, final String mes, final TestSettings settings) { + return new HTTPDataCallback() { + public int cb (HTTPParser p, ByteBuffer b, int pos, int len){ + // if ("url".equals(mes)){ + // p("pos"+pos); + // p("len"+len); + // if (8==pos && 5 == len && "connect request".equals(name)) { + // //throw new RuntimeException(name); + // } + // } + //String str = str(b, pos, len); + ByteList list = settings.map.get(mes); + for (int i=0; i!=len; ++i) { + list.add(b.get(pos+i)); + } + //settings.map.put(mes, prev_val + str); + //check(value.equals(str), "incorrect "+mes+": "+str); + if (-1 == pos) { + throw new RuntimeException("he?"); + } + return 0; + } + }; + } + + void execute () { + p(name); + ByteBuffer buf = ByteBuffer.wrap(raw); + HTTPParser p = new HTTPParser(); + TestSettings s = settings(); + + + + p.execute(s, buf); + if (!p.upgrade) { + // call execute again, else parser can't know message is done + // if no content length is set. + p.execute(s, buf); + } + if (!s.success) { + throw new RuntimeException("Test: "+name+" failed"); + } + } // execute + + void execute_permutations() { + /* + |-|---------------| + |--|--------------| + |---|-------------| + (...) + |---------------|-| + |-----------------| + */ + p(name); + for (int i = 2; i != raw.length; ++i) { + // p(i); + HTTPParser p = new HTTPParser(); + TestSettings s = settings(); + ByteBuffer buf = ByteBuffer.wrap(raw); + int olimit = buf.limit(); + buf.limit(i); + + parse(p,s,buf); + if (!p.upgrade) { + buf.position(i); + buf.limit(olimit); + + parse(p,s,buf); + if (!p.upgrade) { + parse(p,s,buf); + } else { + if (!upgrade()) { + throw new RuntimeException("Test:"+name+"parsed as upgrade, is not"); + } + } + + } else { + if (!upgrade()) { + throw new RuntimeException("Test:"+name+"parsed as upgrade, is not"); + } + } + if (!s.success) { + p(this); + throw new RuntimeException("Test: "+name+" failed"); + } + reset(); + } + //System.exit(0); + } // execute_permutations + void parse(HTTPParser p, ParserSettings s, ByteBuffer b) { + //p("About to parse: "+b.position() + "->" + b.limit()); + p.execute(s, b); + } + + TestSettings settings() { + final TestSettings s = new TestSettings(); + s.on_url = getCB(request_url, "url", s); + s.on_message_begin = new HTTPCallback() { + public int cb (HTTPParser p) { + message_begin_called = true; + return -1; + } + }; + s.on_header_field = new HTTPDataCallback() { + public int cb (HTTPParser p, ByteBuffer b, int pos, int len){ + if (null != currHValue && null == currHField) { + throw new RuntimeException(name+": shouldn't happen"); + } + if (null != currHField) { + if (null == currHValue) { + currHField += str(b,pos,len); + return 0; + } else { + parsed_header.put(currHField, currHValue); + currHField = null; + currHValue = null; + } + } + currHField = str(b,pos,len); + return 0; + } + }; + s.on_header_value = new HTTPDataCallback() { + public int cb (HTTPParser p, ByteBuffer b, int pos, int len){ + if (null == currHField) { + throw new RuntimeException(name+" :shouldn't happen field"); + } + if (null == currHValue) { + currHValue = str(b,pos,len); + } else { + currHValue += str(b, pos, len); + } + return 0; + } + }; + s.on_headers_complete = new HTTPCallback() { + public int cb (HTTPParser p) { + headers_complete_called = true; + String parsed_path = null; + String parsed_query = null; + String parsed_url = null; + String parsed_frag = null; + + try { + parsed_url = new String(s.map.get("url").toArray(), "UTF8"); + + HTTPParserUrl u = new HTTPParserUrl(); + HTTPParser pp = new HTTPParser(); + ByteBuffer data = Util.buffer(parsed_url); + pp.parse_url(data,false, u); + + parsed_path = u.getFieldValue(HTTPParser.UrlFields.UF_PATH, data); + parsed_query = u.getFieldValue(HTTPParser.UrlFields.UF_QUERY, data); + parsed_frag = u.getFieldValue(HTTPParser.UrlFields.UF_FRAGMENT, data); + + } catch (java.io.UnsupportedEncodingException uee) { + throw new RuntimeException(uee); + } + + if (!request_path.equals(parsed_path)) { + throw new RuntimeException(name+": invalid path: "+parsed_path+" should be: "+request_path); + } + if (!query_string.equals(parsed_query)) { + throw new RuntimeException(name+": invalid query: "+parsed_query+" should be: "+query_string); + } + if (!request_url.equals(parsed_url)) { + throw new RuntimeException(">"+name+"<: invalid url: >"+parsed_url+"< should be: >"+request_url+"<"); + } + if (!fragment.equals(parsed_frag)) { + throw new RuntimeException(name+": invalid fragement: "+parsed_frag+" should be: "+fragment); + } + if (null != currHValue || null != currHField) { + if (null == currHField || null == currHValue) { + throw new RuntimeException("shouldn't happen"); + } + } + if (null != currHField) { + //p(currHField); + //p(">"+currHValue+"<"); + parsed_header.put(currHField, currHValue); + currHField = null; + currHValue = null; + } + + + return 0; + } + }; + // s.on_headers_complete = new HTTPCallback() { + // public int cb (HTTPParser p) { + // p("Complete:"+name); + // return 0; + // } + // }; + + s.on_body = new HTTPDataCallback() { + public int cb (HTTPParser p, ByteBuffer b, int pos, int len){ + int l = pbody == null ? len : len + pbody.length; + int off = pbody == null ? 0 : pbody.length; + byte [] nbody = new byte[l]; + + if (null != pbody) { + System.arraycopy(pbody, 0, nbody, 0, pbody.length); + } + + int saved = b.position(); + b.position(pos); + b.get(nbody, off, len); + b.position(saved); + pbody = nbody; + return 0; + } + }; + + s.on_message_complete = new HTTPCallback() { + public int cb(HTTPParser p) { + message_complete_called = true; + num_called += 1; + if ( p.http_minor != http_minor + || p.http_major != http_major + || p.status_code != status_code ) { + + throw new RuntimeException("major/minor/status_code mismatch"); + } + + //check headers + + if (header.keySet().size() != parsed_header.keySet().size()) { + p(parsed_header); + throw new RuntimeException(name+": different amount of headers"); + } + for (String key : header.keySet()) { + String pvalue = parsed_header.get(key); + if (!header.get(key).equals(pvalue)) { + throw new RuntimeException(name+" : different values for :"+key+" is >"+pvalue+"< should: >"+header.get(key)+"<"); + } + } + //check body + if (null == pbody && (null == body || body.length == 0 || body.length == 1)) { + s.success = true; + return 0; + } + if (null == pbody) { + throw new RuntimeException(name+": no body, should be: "+new String(body)); + } + if (pbody.length != body.length) { + p(pbody.length); + p(body.length); + p(new String(pbody)); + p(new String(body)); + throw new RuntimeException(name+": incorrect body length"); + } + for (int i = 0 ; i!= body.length; ++i) { + if (pbody[i] != body[i]) { + throw new RuntimeException("different body"); + } + } + s.success = true; + return 0; + } + }; + return s; + } // settings + static void p(Object o) { + System.out.println(o); + } + + static class TestSettings extends ParserSettings { + public boolean success; + Map map; + TestSettings () { + map = new HashMap(); + map.put("path", new ByteList()); + map.put("query_string", new ByteList()); + map.put("url", new ByteList()); + map.put("fragment", new ByteList()); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/ParseUrl.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/ParseUrl.java new file mode 100644 index 0000000..0e74021 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/ParseUrl.java @@ -0,0 +1,51 @@ +package http_parser.lolevel; + +import http_parser.HTTPParserUrl; +import static http_parser.lolevel.Util.*; + +public class ParseUrl { + public static void test(int i) { + HTTPParserUrl u = new HTTPParserUrl(); + HTTPParser p = new HTTPParser(); + Url test = Url.URL_TESTS[i]; +// System.out.println(":: " + test.name); + int rv = p.parse_url(Util.buffer(test.url),test.is_connect,u); + UnitTest.check_equals(rv, test.rv); + if(test.rv == 0){ + UnitTest.check_equals(u, test.u); + } + + } + public static void test() { + p(ParseUrl.class); + + for (int i = 0; i < Url.URL_TESTS.length; i++) { + test(i); + } + } + + static void usage() { + p("usage: [jre] http_parser.lolevel.ParseUrl [i]"); + p(" i : optional test case id"); + p("---------------------------------------------"); + p("Test Cases:"); + for (int i =0; i!= Url.URL_TESTS.length; ++i) { + p(" "+i+": "+Url.URL_TESTS[i].name); + } + } + + public static void main (String [] args) { + if (0 == args.length) { + test(); + } else { + try { + int i = Integer.parseInt(args[0]); + test(i); + } catch (Throwable t) { + t.printStackTrace(); + usage(); + } + + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java new file mode 100644 index 0000000..4367bbb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Requests.java @@ -0,0 +1,69 @@ +package http_parser.lolevel; + +import java.nio.*; +import java.util.*; + +import static http_parser.lolevel.Util.*; +import http_parser.*; + +import primitive.collection.ByteList; + +public class Requests { + + static void test_simple(String req, boolean should_pass) { + HTTPParser parser = new HTTPParser(ParserType.HTTP_REQUEST); + ByteBuffer buf = buffer(req); + boolean passed = false; + int read = 0; + try { + parser.execute(Util.SETTINGS_NULL, buf); + passed = (read == req.length()); + read = parser.execute(Util.SETTINGS_NULL, Util.empty()); + passed &= (0 == read); + } catch (Throwable t) { + passed = false; + } + check(passed == should_pass); + } + static void simple_tests() { + test_simple("hello world", false); + test_simple("GET / HTP/1.1\r\n\r\n", false); + + test_simple("ASDF / HTTP/1.1\r\n\r\n", false); + test_simple("PROPPATCHA / HTTP/1.1\r\n\r\n", false); + test_simple("GETA / HTTP/1.1\r\n\r\n", false); + } + + public static void test () { + p(Requests.class); + simple_tests(); + + List all = TestLoaderNG.load("tests.dumped"); + List requests = new LinkedList(); + for (Message m : all) { + if (ParserType.HTTP_REQUEST == m.type) { + requests.add(m); + } + } + for (Message m : requests) { + test_message(m); + } + + for (int i = 0; i!= requests.size(); ++i) { + if (!requests.get(i).should_keep_alive) continue; + for (int j = 0; j!=requests.size(); ++j) { + if (!requests.get(j).should_keep_alive) continue; + for (int k = 0; k!= requests.size(); ++k) { + test_multiple3(requests.get(i), requests.get(j), requests.get(k)); + } + } + } + + // postpone test_scan + + } + + + + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java new file mode 100644 index 0000000..1cb71dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Responses.java @@ -0,0 +1,52 @@ +package http_parser.lolevel; + +import java.nio.*; +import java.util.*; + +import static http_parser.lolevel.Util.*; +import http_parser.*; + +import primitive.collection.ByteList; + +public class Responses { + + + + public static void test () { + p(Responses.class); + List all = TestLoaderNG.load("tests.dumped"); + List responses = new LinkedList(); + for (Message m : all) { + if (ParserType.HTTP_RESPONSE == m.type) { + responses.add(m); + } + } + for (Message m : responses) { + test_message(m); + } + + for (int i = 0; i!= responses.size(); ++i) { + if (!responses.get(i).should_keep_alive) continue; + for (int j = 0; j!=responses.size(); ++j) { + if (!responses.get(j).should_keep_alive) continue; + for (int k = 0; k!= responses.size(); ++k) { + test_multiple3(responses.get(i), responses.get(j), responses.get(k)); + } + } + } + + // not sure what test_message_count_body does that test_message doesn't... + // Message m = find(responses, "404 no headers no body"); + // test_message_count_body(m); + // m = find(responses, "200 trailing space on chunked body"); + // test_message_count_body(m); + + // TODO test very large chunked response + + // test_scan is more or less the same as test_permutations, will implement later... + } + + + + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java new file mode 100644 index 0000000..6c35898 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Test.java @@ -0,0 +1,16 @@ +package http_parser.lolevel; + + +public class Test { + public static void main (String [] args) { + UnitTest.test(); + TestHeaderOverflowError.test(); + TestNoOverflowLongBody.test(); + Responses.test(); + ParseUrl.test(); + Requests.test(); + Upgrade.test(); + WrongContentLength.test(); + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java new file mode 100644 index 0000000..ee47903 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestHeaderOverflowError.java @@ -0,0 +1,48 @@ +package http_parser.lolevel; + +import java.nio.*; + +import static http_parser.lolevel.Util.*; + +public class TestHeaderOverflowError { + + public static void test (http_parser.ParserType type) { + HTTPParser parser = new HTTPParser(type); + ByteBuffer buf = getBytes(type); + + int numbytes = buf.limit(); + + parser.execute(Util.SETTINGS_NULL, buf); + + check(numbytes == buf.position()); + + buf = buffer("header-key: header-value\r\n"); + numbytes = buf.limit(); + for (int i = 0; i!= 1000; ++i) { + parser.execute(Util.SETTINGS_NULL, buf); + check(numbytes == buf.position()); + + buf.rewind(); + + } + } + + static ByteBuffer getBytes (http_parser.ParserType type) { + if (http_parser.ParserType.HTTP_BOTH == type) { + throw new RuntimeException("only HTTP_REQUEST and HTTP_RESPONSE"); + } + + if (http_parser.ParserType.HTTP_REQUEST == type) { + return buffer("GET / HTTP/1.1\r\n"); + } + return buffer("HTTP/1.0 200 OK\r\n"); + } + + public static void test () { + p(TestHeaderOverflowError.class); + test(http_parser.ParserType.HTTP_REQUEST); + test(http_parser.ParserType.HTTP_RESPONSE); + } + + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java new file mode 100644 index 0000000..329485d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java @@ -0,0 +1,212 @@ +package http_parser.lolevel; +// name : 200 trailing space on chunked body +// raw : "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n25 \r\nThis is the data in the first chunk\r\n\r\n1C\r\nand this is the second one\r\n\r\n0 \r\n\r\n" +// type : HTTP_RESPONSE +// method: HTTP_DELETE +// status code :200 +// request_path: +// request_url : +// fragment : +// query_string: +// body :"This is the data in the first chunk\r\nand this is the second one\r\n" +// body_size :65 +// header_0 :{ "Content-Type": "text/plain"} +// header_1 :{ "Transfer-Encoding": "chunked"} +// should_keep_alive :1 +// upgrade :0 +// http_major :1 +// http_minor :1 + + +import java.io.FileReader; +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.Reader; +import java.io.Reader; +import java.io.IOException; + +import java.util.*; +import java.util.regex.*; + +import java.nio.ByteBuffer; + +import http_parser.HTTPMethod; +import http_parser.ParserType; + +public class TestLoaderNG { + String fn; + public TestLoaderNG(String filename) { + this.fn = filename; + } + static void p(Object o) { + System.out.println(o); + } + public static List load (String fn) { + List list = null; + try { + BufferedReader buf = new BufferedReader(new FileReader(fn)); + list = load(buf); + } catch (Throwable t) { + throw new RuntimeException(t); + } + return list; + + } + public static Message parse (String message) { + List list = load(new BufferedReader(new StringReader(message))); + if (null == list || 0 == list.size() ) { + return null; + } + return list.get(0); + } + + public static List load (BufferedReader buf) { + List list = new LinkedList(); + String line = null; + Message curr = new Message(); + Pattern pattern = Pattern.compile("(\\S+)\\s*:(.*)"); + try { + while (null != (line = buf.readLine()) ){ + if ("".equals(line.trim())) { + list.add (curr); + curr = new Message(); + continue; + } + Matcher m = pattern.matcher(line); + if (m.matches()) { + // you can not be fucking serious!? + // this has got to be the most retarded regex + // interface in the history of the world ... + // (though I'm sure there's worse c++ regexp libs...) + MatchResult r = m.toMatchResult(); + String key = r.group(1).trim(); + String value = r.group(2).trim(); + if ("name".equals(key)) {curr.name = value;} + else if ("raw".equals(key)) {curr.raw = toByteArray(value);} //! + else if ("type".equals(key)) {curr.type = ParserType.parse(value);} + else if ("method".equals(key)) {curr.method = HTTPMethod.parse(value);} + else if ("status_code".equals(key)) {curr.status_code = Integer.parseInt(value);} + else if ("request_path".equals(key)) {curr.request_path = value;} + else if ("request_url".equals(key)) {curr.request_url = value;} + + else if ("fragment".equals(key)) {curr.fragment = value;} + else if ("query_string".equals(key)) {curr.query_string = value;} + else if ("body".equals(key)) {curr.body = toByteArray(value);} //! + else if ("body_size".equals(key)) {curr.body_size = Integer.parseInt(value);} + else if (key.startsWith("header")) { + String [] h = getHeader(value); + curr.header.put(h[0], h[1]); + } + else if ("should_keep_alive".equals(key)) + {curr.should_keep_alive = (1 == Integer.parseInt(value));} + else if ("upgrade".equals(key)) { curr.upgrade = toByteArray(value);} + else if ("http_major".equals(key)) {curr.http_major = Integer.parseInt(value);} + else if ("http_minor".equals(key)) {curr.http_minor = Integer.parseInt(value);} + } else { + p("WTF?"+line); + } + + } + } catch (Throwable t) { + throw new RuntimeException(t); + } + return list; + } + + static String [] getHeader(String value) { + // { "Host": "0.0.0.0=5000"} + Pattern p = Pattern.compile("\\{ ?\"([^\"]*)\": ?\"(.*)\"}"); + Matcher m = p.matcher(value); + if (!m.matches()) { + p(value); + throw new RuntimeException("something wrong"); + } + String [] result = new String[2]; + MatchResult r = m.toMatchResult(); + result[0] = r.group(1).trim(); + result[1] = r.group(2); //.trim(); + return result; + } + + static final byte BSLASH = 0x5c; + static final byte QUOT = 0x22; + static final byte CR = 0x0d; + static final byte LF = 0x0a; + static final byte n = 0x6e; + static final byte r = 0x72; + + static final Byte[] JAVA_GENERICS_ROCK_HARD = new Byte[0]; + + + static byte [] toByteArray (String quotedString) { + ArrayList bytes = new ArrayList(); + String s = quotedString.substring(1, quotedString.length()-1); + byte [] byts = s.getBytes(java.nio.charset.Charset.forName("UTF8")); + boolean escaped = false; + for (byte b : byts) { + switch (b) { + case BSLASH: + escaped = true; + break; + case n: + if (escaped) { + bytes.add(LF); + escaped = false; + } else { + bytes.add(b); + } + break; + case r: + if (escaped) { + escaped = false; + bytes.add(CR); + } else { + bytes.add(b); + } + break; + case QUOT: + escaped = false; + bytes.add(QUOT); + break; + default: + bytes.add(b); + } + + } + + byts = new byte[bytes.size()]; + int i = 0; + for (Byte b : bytes) { + byts[i++]=b; + } + return byts; + } + + public static void main(String [] args) throws Throwable { + //TestLoaderNG l = new TestLoaderNG(args[0]); + List ts = load(args[0]); + for (Message t : ts) { +// for (int i =0; i!= t.raw.length; ++i) { +// p(i+":"+t.raw[i]); +// } +// try { + t.execute_permutations(); +// } catch (Throwable th) { +// p("failed: "+t.name); +// } + t.execute(); + // System.exit(0); + } + } + + class Header { + String field; + String value; + } + enum LastHeader { + NONE + ,FIELD + ,VALUE + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java new file mode 100644 index 0000000..13d8ea0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestNoOverflowLongBody.java @@ -0,0 +1,62 @@ +package http_parser.lolevel; + +import java.nio.*; + +import static http_parser.lolevel.Util.*; + +public class TestNoOverflowLongBody { + + public static void test (http_parser.ParserType type, int len) { + HTTPParser parser = new HTTPParser(type); + ByteBuffer buf = getBytes(type, len); + + int buflen = buf.limit(); + + parser.execute(Util.SETTINGS_NULL, buf); + + check(buflen == buf.position()); + + buf = buffer("a"); + buflen = buf.limit(); + + for (int i = 0; i!= len; ++i) { + parser.execute(Util.SETTINGS_NULL, buf); + check(buflen == buf.position()); + buf.rewind(); + } + + buf = getBytes(type, len); + buflen = buf.limit(); + + parser.execute(Util.SETTINGS_NULL, buf); + + check(buflen == buf.position()); + + } + + static ByteBuffer getBytes (http_parser.ParserType type, int length) { + if (http_parser.ParserType.HTTP_BOTH == type) { + throw new RuntimeException("only HTTP_REQUEST and HTTP_RESPONSE"); + } + + String template = "%s\r\nConnection: Keep-Alive\r\nContent-Length: %d\r\n\r\n"; + String str = null; + if (http_parser.ParserType.HTTP_REQUEST == type) { + str = String.format(template, "GET / HTTP/1.1", length); + } else { + str = String.format(template, "HTTP/1.0 200 OK", length); + } + return buffer(str); + } + + public static void test () { + p(TestNoOverflowLongBody.class); + test(http_parser.ParserType.HTTP_REQUEST, 1000); + test(http_parser.ParserType.HTTP_REQUEST, 100000); + test(http_parser.ParserType.HTTP_RESPONSE, 1000); + test(http_parser.ParserType.HTTP_RESPONSE, 100000); + } + + + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java new file mode 100644 index 0000000..4159980 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java @@ -0,0 +1,117 @@ +package http_parser.lolevel; + +import java.nio.ByteBuffer; +import http_parser.HTTPException; +import http_parser.Util; + +public class UnitTest { + + static void p(Object o) {System.out.println(o);} + + public static void testErrorFormat() { + String bla = "This has an error in position 10 (the n in 'an')"; + ByteBuffer buf = ByteBuffer.wrap(bla.getBytes()); + buf.position(10); + + String mes = +"This has an error in position 10 (the n in 'an')\n" + +"..........^"; + + check_equals(mes, Util.error ("test error", buf, 0)); + + + bla = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J"; + buf = ByteBuffer.wrap(bla.getBytes()); + buf.position(50); + mes = +"56789B123456789C123456789D123456789E123456789F123456789G123456789H123456\n"+ +"....................................^"; + check_equals(mes, Util.error("test trim right and left", buf, 0)); + + + buf.position(5); + mes = +"123456789A123456789B123456789C123456789D123456789E123456789F123456789G12\n"+ +".....^"; + check_equals(mes, Util.error("test trim right", buf, 0)); + + + int limit = buf.limit(); + buf.limit(10); + mes = +"123456789A\n"+ +".....^"; + check_equals(mes, Util.error("all before, not enough after", buf, 0)); + + + + buf.limit(limit); + buf.position(90); + mes = +"9C123456789D123456789E123456789F123456789G123456789H123456789I123456789J\n"+ +"..............................................................^"; + check_equals(mes, Util.error("test trim left", buf, 10)); + } + + + // Test that the error callbacks are properly called. + public static void testErrorCallback () { + String nothttp = "THis is certainly not valid HTTP"; + ByteBuffer buf = ByteBuffer.wrap(nothttp.getBytes()); + + ParserSettings s = new ParserSettings(); + s.on_error = new HTTPErrorCallback() { + public void cb (HTTPParser p, String mes, ByteBuffer buf, int pos) { + throw new HTTPException(mes); + } + }; // err callback + + + HTTPParser p = new HTTPParser(); + try { + p.execute(s, buf); + } catch (HTTPException e) { + check_equals("Invalid HTTP method", e.getMessage()); + } + + buf = ByteBuffer.wrap("GET / HTTP 1.10000".getBytes()); + p = new HTTPParser(); + try { + p.execute(s, buf); + } catch (HTTPException e) { + check_equals("ridiculous http minor", e.getMessage()); + } + + // if no error handler is defined, behave just like the above... + ParserSettings s0 = new ParserSettings(); + + buf = ByteBuffer.wrap("THis is certainly not valid HTTP".getBytes()); + p = new HTTPParser(); + try { + p.execute(s0, buf); + } catch (HTTPException e) { + check_equals("Invalid HTTP method", e.getMessage()); + } + + buf = ByteBuffer.wrap("GET / HTTP 1.10000".getBytes()); + p = new HTTPParser(); + try { + p.execute(s0, buf); + } catch (HTTPException e) { + check_equals("ridiculous http minor", e.getMessage()); + } + } + + static void check_equals(Object supposed2be, Object is) { + if (!supposed2be.equals(is)) { + throw new RuntimeException(is + " is supposed to be "+supposed2be); + } + } + + + public static void test () { + p(UnitTest.class); + testErrorFormat(); + testErrorCallback(); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java new file mode 100644 index 0000000..9af3d4a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Upgrade.java @@ -0,0 +1,27 @@ +package http_parser.lolevel; + +import java.nio.*; +import java.util.*; + +import http_parser.ParserType; + +import static http_parser.lolevel.Util.*; + +public class Upgrade { + static final String upgrade = "GET /demo HTTP/1.1\r\n" + + "Connection: Upgrade\r\n" + + "Upgrade: WebSocket\r\n\r\n" + + "third key data"; + static void test () { + p(Upgrade.class); + HTTPParser parser = new HTTPParser(ParserType.HTTP_REQUEST); + ByteBuffer buf = buffer(upgrade); + + int read = parser.execute(Util.SETTINGS_NULL, buf); + check (63 == read); + String s = str(buf); + check ("third key data".equals(str(buf))); + + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Url.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Url.java new file mode 100644 index 0000000..35469d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Url.java @@ -0,0 +1,127 @@ +package http_parser.lolevel; + +import http_parser.FieldData; +import http_parser.HTTPParserUrl; + +import static http_parser.HTTPParserUrl.*; +import static http_parser.lolevel.HTTPParser.*; + +/** + */ +public class Url { + + public static Url[] URL_TESTS = new Url[]{ + new Url("proxy request", "http://hostname/", false, + new HTTPParserUrl( + (1 << UrlFields.UF_SCHEMA.getIndex()) | (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PATH.getIndex()), + 0, + new FieldData[]{ + new FieldData(0,4), + new FieldData(7,8), + new FieldData(0,0), + new FieldData(15,1), + new FieldData(0,0), + new FieldData(0,0) + }), + 0), + new Url("CONNECT request", "hostname:443", true, + new HTTPParserUrl( + (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PORT.getIndex()), + 443, + new FieldData[]{ + new FieldData(0,0), + new FieldData(0,8), + new FieldData(9,3), + new FieldData(0,0), + new FieldData(0,0), + new FieldData(0,0) + }), + 0), + new Url("proxy ipv6 request", "http://[1:2::3:4]/", false, + new HTTPParserUrl( + (1 << UrlFields.UF_SCHEMA.getIndex()) | (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PATH.getIndex()), + 0, + new FieldData[]{ + new FieldData(0,4), + new FieldData(8,8), + new FieldData(0,0), + new FieldData(17,1), + new FieldData(0,0), + new FieldData(0,0) + }), + 0), + new Url("CONNECT ipv6 address", "[1:2::3:4]:443", true, + new HTTPParserUrl( + (1 << UrlFields.UF_HOST.getIndex()) | (1 << UrlFields.UF_PORT.getIndex()), + 443, + new FieldData[]{ + new FieldData(0,0), + new FieldData(1,8), + new FieldData(11,3), + new FieldData(0,0), + new FieldData(0,0), + new FieldData(0,0) + }), + 0), + new Url("extra ? in query string", + "http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css,fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css,fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css", + false, + new HTTPParserUrl( + (1 << UrlFields.UF_SCHEMA.getIndex()) | + (1 << UrlFields.UF_HOST.getIndex()) | + (1 << UrlFields.UF_PATH.getIndex()) | + (1 << UrlFields.UF_QUERY.getIndex()), + 0, + new FieldData[]{ + new FieldData(0,4), + new FieldData(7,10), + new FieldData(0,0), + new FieldData(17,12), + new FieldData(30,187), + new FieldData(0,0) + }), + 0), + new Url("proxy empty host", + "http://:443/", + false, + null, + 1), + new Url("proxy empty port", + "http://hostname:/", + false, + null, + 1), + new Url("CONNECT empty host", + ":443", + true, + null, + 1), + new Url("CONNECT empty port", + "hostname:", + true, + null, + 1), + new Url("CONNECT with extra bits", + "hostname:443/", + true, + null, + 1), + + }; + + String name; + String url; + boolean is_connect; + HTTPParserUrl u; + int rv; + + public Url(String name, String url, boolean is_connect, HTTPParserUrl u, int rv) { + this.name = name; + this.url = url; + this.is_connect = is_connect; + this.u = u; + this.rv = rv; + } + + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java new file mode 100644 index 0000000..c73d9e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/Util.java @@ -0,0 +1,236 @@ +package http_parser.lolevel; + +import java.nio.*; +import java.util.*; + +import primitive.collection.ByteList; + +import http_parser.*; + +public class Util { + + static final ParserSettings SETTINGS_NULL = new ParserSettings(); + + static String str (ByteBuffer b, int pos, int len) { + byte [] by = new byte[len]; + int saved = b.position(); + b.position(pos); + b.get(by); + b.position(saved); + return new String(by); + } + static String str (ByteBuffer b) { + int len = b.limit() - b.position(); + byte [] by = new byte[len]; + int saved = b.position(); + b.get(by); + b.position(saved); + return new String(by); + } + + static ByteBuffer buffer(String str) { + return ByteBuffer.wrap(str.getBytes()); + } + + static ByteBuffer empty() { + return ByteBuffer.wrap(new byte[0]); + } + + static void check(boolean betterBtrue) { + if (!betterBtrue) { + throw new RuntimeException("!"); + } + } + static void check (int should, int is) { + if (should != is) { + throw new RuntimeException("should be: "+should+" is:"+is); + } + } + + static void test_message(Message mes) { + int raw_len = mes.raw.length; + for (int msg1len = 0; msg1len != raw_len; ++msg1len) { + mes.reset(); + ByteBuffer msg1 = ByteBuffer.wrap(mes.raw, 0, msg1len); + ByteBuffer msg2 = ByteBuffer.wrap(mes.raw, msg1len, mes.raw.length - msg1len); + + HTTPParser parser = new HTTPParser(mes.type); + ParserSettings settings = mes.settings(); + + int read = 0; + if (msg1len !=0) { + read = parser.execute(settings, msg1); + if (mes.upgrade() && parser.upgrade) { + // Messages have a settings() that checks itself... + check(1 == mes.num_called); + continue; + } + check(read == msg1len); + } + + read = parser.execute(settings, msg2); + if (mes.upgrade() && parser.upgrade) { + check(1 == mes.num_called); + continue; + } + + check( mes.raw.length - msg1len, read); + + ByteBuffer empty = Util.empty(); + read = parser.execute(settings, empty); + + if (mes.upgrade() && parser.upgrade) { + check(1 == mes.num_called); + continue; + } + check(empty.position() == empty.limit()); + check(0 == read); + check(1 == mes.num_called); + + } + } + + static void test_multiple3(Message r1, Message r2, Message r3) { + int message_count = 1; + if (!r1.upgrade()) { + message_count++; + if (!r2.upgrade()) { + message_count++; + } + } + boolean has_upgrade = (message_count < 3 || r3.upgrade()); + + ByteList blist = new ByteList(); + blist.addAll(r1.raw); + blist.addAll(r2.raw); + blist.addAll(r3.raw); + + byte [] raw = blist.toArray(); + ByteBuffer buf = ByteBuffer.wrap(raw); + + Util.Settings settings = Util.settings(); + HTTPParser parser = new HTTPParser(r1.type); + + int read = parser.execute(settings, buf); + if (has_upgrade && parser.upgrade) { + raw = upgrade_message_fix(raw, read, r1,r2,r3); + check(settings.numCalled == message_count); + return; + } + + check(read == raw.length); + + buf = Util.empty(); + read = parser.execute(settings, buf); + if (has_upgrade && parser.upgrade) { + check(settings.numCalled == message_count); + return; + } + + check(0 == read); + check(settings.numCalled == message_count); + } + + /* Given a sequence of bytes and the number of these that we were able to + * parse, verify that upgrade bodies are correct. + */ + static byte [] upgrade_message_fix(byte[] body, int nread, Message... msgs) { + int off = 0; + for (Message m : msgs) { + off += m.raw.length; + if (m.upgrade()) { + off -= m.upgrade.length; + // Original C: + // Check the portion of the response after its specified upgrade + // if (!check_str_eq(m, "upgrade", body + off, body + nread)) { + // abort(); + // } + // to me, this seems to be equivalent to comparing off and nread ... + check (off, nread); + + // Original C: + // Fix up the response so that message_eq() will verify the beginning + // of the upgrade */ + // + // *(body + nread + strlen(m->upgrade)) = '\0'; + // This only shortens body so the strlen check passes. + return new byte[off]; + + } + } + return null; + } +//upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) { +// va_list ap; +// size_t i; +// size_t off = 0; +// +// va_start(ap, nmsgs); +// +// for (i = 0; i < nmsgs; i++) { +// struct message *m = va_arg(ap, struct message *); +// +// off += strlen(m->raw); +// +// if (m->upgrade) { +// off -= strlen(m->upgrade); +// +// /* Check the portion of the response after its specified upgrade */ +// if (!check_str_eq(m, "upgrade", body + off, body + nread)) { +// abort(); +// } +// +// /* Fix up the response so that message_eq() will verify the beginning +// * of the upgrade */ +// *(body + nread + strlen(m->upgrade)) = '\0'; +// messages[num_messages -1 ].upgrade = body + nread; +// +// va_end(ap); +// return; +// } +// } +// +// va_end(ap); +// printf("\n\n*** Error: expected a message with upgrade ***\n"); +// +// abort(); +//} + static void p (Object o) { + System.out.println(o); + } + + static Settings settings() { + return new Settings(); + } + static Message find(List list, String name) { + for (Message m : list) { + if (name.equals(m.name)) { + return m; + } + } + return null; + } + + static class Settings extends ParserSettings { + public int numCalled; + public int bodyCount; + Settings() { + this.on_message_complete = new HTTPCallback() { + public int cb (HTTPParser parser) { + numCalled++; + return 0; + } + }; + this.on_body = new HTTPDataCallback() { + public int cb (HTTPParser p, ByteBuffer b, int pos, int len) { + bodyCount += len; + return 0; + } + }; + } + + int numCalled () { + return this.numCalled; + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java new file mode 100644 index 0000000..fc8f081 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/WrongContentLength.java @@ -0,0 +1,59 @@ +package http_parser.lolevel; + +import java.nio.*; +import java.util.*; + +import http_parser.ParserType; + +import static http_parser.lolevel.Util.*; + +public class WrongContentLength { + static final String contentLength = "GET / HTTP/1.0\r\n" + + "Content-Length: 5\r\n" + + "\r\n" + + "hello" + + "hello_again"; + static void test () { + p(WrongContentLength.class); + HTTPParser parser = new HTTPParser(ParserType.HTTP_REQUEST); + ByteBuffer buf = buffer(contentLength); + + Settings settings = new Settings(); + + int read = parser.execute(settings, buf); + check (settings.msg_cmplt_called); + check ("invalid method".equals(settings.err)); + + } + public static void main(String [] args) { + test(); + } + + static class Settings extends ParserSettings { + public int bodyCount; + public boolean msg_cmplt_called; + public String err; + Settings () { + this.on_message_complete = new HTTPCallback () { + public int cb (HTTPParser p) { + check (5 == bodyCount); + msg_cmplt_called = true; + return 0; + } + }; + this.on_body = new HTTPDataCallback() { + public int cb (HTTPParser p, ByteBuffer b, int pos, int len) { + bodyCount += len; + check ("hello".equals(str(b, pos, len))); + return 0; + } + }; + this.on_error = new HTTPErrorCallback() { + public void cb (HTTPParser p, String mes, ByteBuffer b, int i) { + err = mes; + } + }; + } + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/test.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/test.c new file mode 100644 index 0000000..3840747 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/test.c @@ -0,0 +1,3425 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "http_parser.h" +#include +#include +#include +#include /* rand */ +#include +#include + +#undef TRUE +#define TRUE 1 +#undef FALSE +#define FALSE 0 + +#define MAX_HEADERS 13 +#define MAX_ELEMENT_SIZE 2048 + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +static http_parser *parser; + +struct message { + const char *name; // for debugging purposes + const char *raw; + enum http_parser_type type; + enum http_method method; + int status_code; + char request_path[MAX_ELEMENT_SIZE]; + char request_url[MAX_ELEMENT_SIZE]; + char fragment[MAX_ELEMENT_SIZE]; + char query_string[MAX_ELEMENT_SIZE]; + char body[MAX_ELEMENT_SIZE]; + size_t body_size; + const char *host; + const char *userinfo; + uint16_t port; + int num_headers; + enum { NONE=0, FIELD, VALUE } last_header_element; + char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE]; + int should_keep_alive; + + const char *upgrade; // upgraded body + + unsigned short http_major; + unsigned short http_minor; + + int message_begin_cb_called; + int headers_complete_cb_called; + int message_complete_cb_called; + int message_complete_on_eof; + int body_is_final; +}; + +static int currently_parsing_eof; + +static struct message messages[5]; +static int num_messages; +static http_parser_settings *current_pause_parser; + +/* * R E Q U E S T S * */ +const struct message requests[] = +#define CURL_GET 0 +{ {.name= "curl get" + ,.type= HTTP_REQUEST + ,.raw= "GET /test HTTP/1.1\r\n" + "User-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\n" + "Host: 0.0.0.0=5000\r\n" + "Accept: */*\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 3 + ,.headers= + { { "User-Agent", "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1" } + , { "Host", "0.0.0.0=5000" } + , { "Accept", "*/*" } + } + ,.body= "" + } + +#define FIREFOX_GET 1 +, {.name= "firefox get" + ,.type= HTTP_REQUEST + ,.raw= "GET /favicon.ico HTTP/1.1\r\n" + "Host: 0.0.0.0=5000\r\n" + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + "Accept-Language: en-us,en;q=0.5\r\n" + "Accept-Encoding: gzip,deflate\r\n" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" + "Keep-Alive: 300\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/favicon.ico" + ,.request_url= "/favicon.ico" + ,.num_headers= 8 + ,.headers= + { { "Host", "0.0.0.0=5000" } + , { "User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0" } + , { "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } + , { "Accept-Language", "en-us,en;q=0.5" } + , { "Accept-Encoding", "gzip,deflate" } + , { "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7" } + , { "Keep-Alive", "300" } + , { "Connection", "keep-alive" } + } + ,.body= "" + } + +#define DUMBFUCK 2 +, {.name= "dumbfuck" + ,.type= HTTP_REQUEST + ,.raw= "GET /dumbfuck HTTP/1.1\r\n" + "aaaaaaaaaaaaa:++++++++++\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/dumbfuck" + ,.request_url= "/dumbfuck" + ,.num_headers= 1 + ,.headers= + { { "aaaaaaaaaaaaa", "++++++++++" } + } + ,.body= "" + } + +#define FRAGMENT_IN_URI 3 +, {.name= "fragment in url" + ,.type= HTTP_REQUEST + ,.raw= "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "page=1" + ,.fragment= "posts-17408" + ,.request_path= "/forums/1/topics/2375" + /* XXX request url does include fragment? */ + ,.request_url= "/forums/1/topics/2375?page=1#posts-17408" + ,.num_headers= 0 + ,.body= "" + } + +#define GET_NO_HEADERS_NO_BODY 4 +, {.name= "get no headers no body" + ,.type= HTTP_REQUEST + ,.raw= "GET /get_no_headers_no_body/world HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE /* would need Connection: close */ + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/get_no_headers_no_body/world" + ,.request_url= "/get_no_headers_no_body/world" + ,.num_headers= 0 + ,.body= "" + } + +#define GET_ONE_HEADER_NO_BODY 5 +, {.name= "get one header no body" + ,.type= HTTP_REQUEST + ,.raw= "GET /get_one_header_no_body HTTP/1.1\r\n" + "Accept: */*\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE /* would need Connection: close */ + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/get_one_header_no_body" + ,.request_url= "/get_one_header_no_body" + ,.num_headers= 1 + ,.headers= + { { "Accept" , "*/*" } + } + ,.body= "" + } + +#define GET_FUNKY_CONTENT_LENGTH 6 +, {.name= "get funky content length body hello" + ,.type= HTTP_REQUEST + ,.raw= "GET /get_funky_content_length_body_hello HTTP/1.0\r\n" + "conTENT-Length: 5\r\n" + "\r\n" + "HELLO" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/get_funky_content_length_body_hello" + ,.request_url= "/get_funky_content_length_body_hello" + ,.num_headers= 1 + ,.headers= + { { "conTENT-Length" , "5" } + } + ,.body= "HELLO" + } + +#define POST_IDENTITY_BODY_WORLD 7 +, {.name= "post identity body world" + ,.type= HTTP_REQUEST + ,.raw= "POST /post_identity_body_world?q=search#hey HTTP/1.1\r\n" + "Accept: */*\r\n" + "Transfer-Encoding: identity\r\n" + "Content-Length: 5\r\n" + "\r\n" + "World" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "q=search" + ,.fragment= "hey" + ,.request_path= "/post_identity_body_world" + ,.request_url= "/post_identity_body_world?q=search#hey" + ,.num_headers= 3 + ,.headers= + { { "Accept", "*/*" } + , { "Transfer-Encoding", "identity" } + , { "Content-Length", "5" } + } + ,.body= "World" + } + +#define POST_CHUNKED_ALL_YOUR_BASE 8 +, {.name= "post - chunked body: all your base are belong to us" + ,.type= HTTP_REQUEST + ,.raw= "POST /post_chunked_all_your_base HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "1e\r\nall your base are belong to us\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/post_chunked_all_your_base" + ,.request_url= "/post_chunked_all_your_base" + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding" , "chunked" } + } + ,.body= "all your base are belong to us" + } + +#define TWO_CHUNKS_MULT_ZERO_END 9 +, {.name= "two chunks ; triple zero ending" + ,.type= HTTP_REQUEST + ,.raw= "POST /two_chunks_mult_zero_end HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "5\r\nhello\r\n" + "6\r\n world\r\n" + "000\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/two_chunks_mult_zero_end" + ,.request_url= "/two_chunks_mult_zero_end" + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding", "chunked" } + } + ,.body= "hello world" + } + +#define CHUNKED_W_TRAILING_HEADERS 10 +, {.name= "chunked with trailing headers. blech." + ,.type= HTTP_REQUEST + ,.raw= "POST /chunked_w_trailing_headers HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "5\r\nhello\r\n" + "6\r\n world\r\n" + "0\r\n" + "Vary: *\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/chunked_w_trailing_headers" + ,.request_url= "/chunked_w_trailing_headers" + ,.num_headers= 3 + ,.headers= + { { "Transfer-Encoding", "chunked" } + , { "Vary", "*" } + , { "Content-Type", "text/plain" } + } + ,.body= "hello world" + } + +#define CHUNKED_W_BULLSHIT_AFTER_LENGTH 11 +, {.name= "with bullshit after the length" + ,.type= HTTP_REQUEST + ,.raw= "POST /chunked_w_bullshit_after_length HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n" + "6; blahblah; blah\r\n world\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/chunked_w_bullshit_after_length" + ,.request_url= "/chunked_w_bullshit_after_length" + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding", "chunked" } + } + ,.body= "hello world" + } + +#define WITH_QUOTES 12 +, {.name= "with quotes" + ,.type= HTTP_REQUEST + ,.raw= "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "foo=\"bar\"" + ,.fragment= "" + ,.request_path= "/with_\"stupid\"_quotes" + ,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\"" + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define APACHEBENCH_GET 13 +/* The server receiving this request SHOULD NOT wait for EOF + * to know that content-length == 0. + * How to represent this in a unit test? message_complete_on_eof + * Compare with NO_CONTENT_LENGTH_RESPONSE. + */ +, {.name = "apachebench get" + ,.type= HTTP_REQUEST + ,.raw= "GET /test HTTP/1.0\r\n" + "Host: 0.0.0.0:5000\r\n" + "User-Agent: ApacheBench/2.3\r\n" + "Accept: */*\r\n\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 3 + ,.headers= { { "Host", "0.0.0.0:5000" } + , { "User-Agent", "ApacheBench/2.3" } + , { "Accept", "*/*" } + } + ,.body= "" + } + +#define QUERY_URL_WITH_QUESTION_MARK_GET 14 +/* Some clients include '?' characters in query strings. + */ +, {.name = "query url with question mark" + ,.type= HTTP_REQUEST + ,.raw= "GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "foo=bar?baz" + ,.fragment= "" + ,.request_path= "/test.cgi" + ,.request_url= "/test.cgi?foo=bar?baz" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define PREFIX_NEWLINE_GET 15 +/* Some clients, especially after a POST in a keep-alive connection, + * will send an extra CRLF before the next request + */ +, {.name = "newline prefix get" + ,.type= HTTP_REQUEST + ,.raw= "\r\nGET /test HTTP/1.1\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define UPGRADE_REQUEST 16 +, {.name = "upgrade request" + ,.type= HTTP_REQUEST + ,.raw= "GET /demo HTTP/1.1\r\n" + "Host: example.com\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" + "Sec-WebSocket-Protocol: sample\r\n" + "Upgrade: WebSocket\r\n" + "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" + "Origin: http://example.com\r\n" + "\r\n" + "Hot diggity dogg" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/demo" + ,.request_url= "/demo" + ,.num_headers= 7 + ,.upgrade="Hot diggity dogg" + ,.headers= { { "Host", "example.com" } + , { "Connection", "Upgrade" } + , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" } + , { "Sec-WebSocket-Protocol", "sample" } + , { "Upgrade", "WebSocket" } + , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" } + , { "Origin", "http://example.com" } + } + ,.body= "" + } + +#define CONNECT_REQUEST 17 +, {.name = "connect request" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "\r\n" + "some data\r\n" + "and yet even more data" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "0-home0.netscape.com:443" + ,.num_headers= 2 + ,.upgrade="some data\r\nand yet even more data" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + } + ,.body= "" + } + +#define REPORT_REQ 18 +, {.name= "report request" + ,.type= HTTP_REQUEST + ,.raw= "REPORT /test HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_REPORT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define NO_HTTP_VERSION 19 +, {.name= "request with no http version" + ,.type= HTTP_REQUEST + ,.raw= "GET /\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 0 + ,.http_minor= 9 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define MSEARCH_REQ 20 +, {.name= "m-search request" + ,.type= HTTP_REQUEST + ,.raw= "M-SEARCH * HTTP/1.1\r\n" + "HOST: 239.255.255.250:1900\r\n" + "MAN: \"ssdp:discover\"\r\n" + "ST: \"ssdp:all\"\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_MSEARCH + ,.query_string= "" + ,.fragment= "" + ,.request_path= "*" + ,.request_url= "*" + ,.num_headers= 3 + ,.headers= { { "HOST", "239.255.255.250:1900" } + , { "MAN", "\"ssdp:discover\"" } + , { "ST", "\"ssdp:all\"" } + } + ,.body= "" + } + +#define LINE_FOLDING_IN_HEADER 21 +, {.name= "line folding in header value" + ,.type= HTTP_REQUEST + ,.raw= "GET / HTTP/1.1\r\n" + "Line1: abc\r\n" + "\tdef\r\n" + " ghi\r\n" + "\t\tjkl\r\n" + " mno \r\n" + "\t \tqrs\r\n" + "Line2: \t line2\t\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 2 + ,.headers= { { "Line1", "abcdefghijklmno qrs" } + , { "Line2", "line2\t" } + } + ,.body= "" + } + + +#define QUERY_TERMINATED_HOST 22 +, {.name= "host terminated by a query string" + ,.type= HTTP_REQUEST + ,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "hail=all" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "http://hypnotoad.org?hail=all" + ,.host= "hypnotoad.org" + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define QUERY_TERMINATED_HOSTPORT 23 +, {.name= "host:port terminated by a query string" + ,.type= HTTP_REQUEST + ,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "hail=all" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "http://hypnotoad.org:1234?hail=all" + ,.host= "hypnotoad.org" + ,.port= 1234 + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define SPACE_TERMINATED_HOSTPORT 24 +, {.name= "host:port terminated by a space" + ,.type= HTTP_REQUEST + ,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "http://hypnotoad.org:1234" + ,.host= "hypnotoad.org" + ,.port= 1234 + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define PATCH_REQ 25 +, {.name = "PATCH request" + ,.type= HTTP_REQUEST + ,.raw= "PATCH /file.txt HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Content-Type: application/example\r\n" + "If-Match: \"e0023aa4e\"\r\n" + "Content-Length: 10\r\n" + "\r\n" + "cccccccccc" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_PATCH + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/file.txt" + ,.request_url= "/file.txt" + ,.num_headers= 4 + ,.headers= { { "Host", "www.example.com" } + , { "Content-Type", "application/example" } + , { "If-Match", "\"e0023aa4e\"" } + , { "Content-Length", "10" } + } + ,.body= "cccccccccc" + } + +#define CONNECT_CAPS_REQUEST 26 +, {.name = "connect caps request" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "HOME0.NETSCAPE.COM:443" + ,.num_headers= 2 + ,.upgrade="" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + } + ,.body= "" + } + +#if !HTTP_PARSER_STRICT +#define UTF8_PATH_REQ 27 +, {.name= "utf-8 path request" + ,.type= HTTP_REQUEST + ,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n" + "Host: github.com\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "q=1" + ,.fragment= "narf" + ,.request_path= "/δ¶/δt/pope" + ,.request_url= "/δ¶/δt/pope?q=1#narf" + ,.num_headers= 1 + ,.headers= { {"Host", "github.com" } + } + ,.body= "" + } + +#define HOSTNAME_UNDERSCORE 28 +, {.name = "hostname underscore" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "home_0.netscape.com:443" + ,.num_headers= 2 + ,.upgrade="" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + } + ,.body= "" + } +#endif /* !HTTP_PARSER_STRICT */ + +/* see https://github.com/ry/http-parser/issues/47 */ +#define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29 +, {.name = "eat CRLF between requests, no \"Connection: close\" header" + ,.raw= "POST / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: 4\r\n" + "\r\n" + "q=42\r\n" /* note the trailing CRLF */ + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 3 + ,.upgrade= 0 + ,.headers= { { "Host", "www.example.com" } + , { "Content-Type", "application/x-www-form-urlencoded" } + , { "Content-Length", "4" } + } + ,.body= "q=42" + } + +/* see https://github.com/ry/http-parser/issues/47 */ +#define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30 +, {.name = "eat CRLF between requests even if \"Connection: close\" is set" + ,.raw= "POST / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: 4\r\n" + "Connection: close\r\n" + "\r\n" + "q=42\r\n" /* note the trailing CRLF */ + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE /* input buffer isn't empty when on_message_complete is called */ + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 4 + ,.upgrade= 0 + ,.headers= { { "Host", "www.example.com" } + , { "Content-Type", "application/x-www-form-urlencoded" } + , { "Content-Length", "4" } + , { "Connection", "close" } + } + ,.body= "q=42" + } + +#define PURGE_REQ 31 +, {.name = "PURGE request" + ,.type= HTTP_REQUEST + ,.raw= "PURGE /file.txt HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_PURGE + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/file.txt" + ,.request_url= "/file.txt" + ,.num_headers= 1 + ,.headers= { { "Host", "www.example.com" } } + ,.body= "" + } + +#define SEARCH_REQ 32 +, {.name = "SEARCH request" + ,.type= HTTP_REQUEST + ,.raw= "SEARCH / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_SEARCH + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 1 + ,.headers= { { "Host", "www.example.com" } } + ,.body= "" + } + +#define PROXY_WITH_BASIC_AUTH 33 +, {.name= "host:port and basic_auth" + ,.type= HTTP_REQUEST + ,.raw= "GET http://a%12:b!&*$@hypnotoad.org:1234/toto HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.fragment= "" + ,.request_path= "/toto" + ,.request_url= "http://a%12:b!&*$@hypnotoad.org:1234/toto" + ,.host= "hypnotoad.org" + ,.userinfo= "a%12:b!&*$" + ,.port= 1234 + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + + +, {.name= NULL } /* sentinel */ +}; + +/* * R E S P O N S E S * */ +const struct message responses[] = +#define GOOGLE_301 0 +{ {.name= "google 301" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 301 Moved Permanently\r\n" + "Location: http://www.google.com/\r\n" + "Content-Type: text/html; charset=UTF-8\r\n" + "Date: Sun, 26 Apr 2009 11:11:49 GMT\r\n" + "Expires: Tue, 26 May 2009 11:11:49 GMT\r\n" + "X-$PrototypeBI-Version: 1.6.0.3\r\n" /* $ char in header field */ + "Cache-Control: public, max-age=2592000\r\n" + "Server: gws\r\n" + "Content-Length: 219 \r\n" + "\r\n" + "\n" + "301 Moved\n" + "

301 Moved

\n" + "The document has moved\n" + "here.\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 301 + ,.num_headers= 8 + ,.headers= + { { "Location", "http://www.google.com/" } + , { "Content-Type", "text/html; charset=UTF-8" } + , { "Date", "Sun, 26 Apr 2009 11:11:49 GMT" } + , { "Expires", "Tue, 26 May 2009 11:11:49 GMT" } + , { "X-$PrototypeBI-Version", "1.6.0.3" } + , { "Cache-Control", "public, max-age=2592000" } + , { "Server", "gws" } + , { "Content-Length", "219 " } + } + ,.body= "\n" + "301 Moved\n" + "

301 Moved

\n" + "The document has moved\n" + "here.\r\n" + "\r\n" + } + +#define NO_CONTENT_LENGTH_RESPONSE 1 +/* The client should wait for the server's EOF. That is, when content-length + * is not specified, and "Connection: close", the end of body is specified + * by the EOF. + * Compare with APACHEBENCH_GET + */ +, {.name= "no content-length response" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Date: Tue, 04 Aug 2009 07:59:32 GMT\r\n" + "Server: Apache\r\n" + "X-Powered-By: Servlet/2.5 JSP/2.1\r\n" + "Content-Type: text/xml; charset=utf-8\r\n" + "Connection: close\r\n" + "\r\n" + "\n" + "\n" + " \n" + " \n" + " SOAP-ENV:Client\n" + " Client Error\n" + " \n" + " \n" + "" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 5 + ,.headers= + { { "Date", "Tue, 04 Aug 2009 07:59:32 GMT" } + , { "Server", "Apache" } + , { "X-Powered-By", "Servlet/2.5 JSP/2.1" } + , { "Content-Type", "text/xml; charset=utf-8" } + , { "Connection", "close" } + } + ,.body= "\n" + "\n" + " \n" + " \n" + " SOAP-ENV:Client\n" + " Client Error\n" + " \n" + " \n" + "" + } + +#define NO_HEADERS_NO_BODY_404 2 +, {.name= "404 no headers no body" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 404 Not Found\r\n\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 404 + ,.num_headers= 0 + ,.headers= {} + ,.body_size= 0 + ,.body= "" + } + +#define NO_REASON_PHRASE 3 +, {.name= "301 no response phrase" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 301\r\n\r\n" + ,.should_keep_alive = FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 301 + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define TRAILING_SPACE_ON_CHUNKED_BODY 4 +, {.name="200 trailing space on chunked body" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "25 \r\n" + "This is the data in the first chunk\r\n" + "\r\n" + "1C\r\n" + "and this is the second one\r\n" + "\r\n" + "0 \r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 2 + ,.headers= + { {"Content-Type", "text/plain" } + , {"Transfer-Encoding", "chunked" } + } + ,.body_size = 37+28 + ,.body = + "This is the data in the first chunk\r\n" + "and this is the second one\r\n" + + } + +#define NO_CARRIAGE_RET 5 +, {.name="no carriage ret" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\n" + "Content-Type: text/html; charset=utf-8\n" + "Connection: close\n" + "\n" + "these headers are from http://news.ycombinator.com/" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 2 + ,.headers= + { {"Content-Type", "text/html; charset=utf-8" } + , {"Connection", "close" } + } + ,.body= "these headers are from http://news.ycombinator.com/" + } + +#define PROXY_CONNECTION 6 +, {.name="proxy connection" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html; charset=UTF-8\r\n" + "Content-Length: 11\r\n" + "Proxy-Connection: close\r\n" + "Date: Thu, 31 Dec 2009 20:55:48 +0000\r\n" + "\r\n" + "hello world" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 4 + ,.headers= + { {"Content-Type", "text/html; charset=UTF-8" } + , {"Content-Length", "11" } + , {"Proxy-Connection", "close" } + , {"Date", "Thu, 31 Dec 2009 20:55:48 +0000"} + } + ,.body= "hello world" + } + +#define UNDERSTORE_HEADER_KEY 7 + // shown by + // curl -o /dev/null -v "http://ad.doubleclick.net/pfadx/DARTSHELLCONFIGXML;dcmt=text/xml;" +, {.name="underscore header key" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Server: DCLK-AdSvr\r\n" + "Content-Type: text/xml\r\n" + "Content-Length: 0\r\n" + "DCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 4 + ,.headers= + { {"Server", "DCLK-AdSvr" } + , {"Content-Type", "text/xml" } + , {"Content-Length", "0" } + , {"DCLK_imp", "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o" } + } + ,.body= "" + } + +#define BONJOUR_MADAME_FR 8 +/* The client should not merge two headers fields when the first one doesn't + * have a value. + */ +, {.name= "bonjourmadame.fr" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.0 301 Moved Permanently\r\n" + "Date: Thu, 03 Jun 2010 09:56:32 GMT\r\n" + "Server: Apache/2.2.3 (Red Hat)\r\n" + "Cache-Control: public\r\n" + "Pragma: \r\n" + "Location: http://www.bonjourmadame.fr/\r\n" + "Vary: Accept-Encoding\r\n" + "Content-Length: 0\r\n" + "Content-Type: text/html; charset=UTF-8\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 301 + ,.num_headers= 9 + ,.headers= + { { "Date", "Thu, 03 Jun 2010 09:56:32 GMT" } + , { "Server", "Apache/2.2.3 (Red Hat)" } + , { "Cache-Control", "public" } + , { "Pragma", "" } + , { "Location", "http://www.bonjourmadame.fr/" } + , { "Vary", "Accept-Encoding" } + , { "Content-Length", "0" } + , { "Content-Type", "text/html; charset=UTF-8" } + , { "Connection", "keep-alive" } + } + ,.body= "" + } + +#define RES_FIELD_UNDERSCORE 9 +/* Should handle spaces in header fields */ +, {.name= "field underscore" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Date: Tue, 28 Sep 2010 01:14:13 GMT\r\n" + "Server: Apache\r\n" + "Cache-Control: no-cache, must-revalidate\r\n" + "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n" + ".et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\n" + "Vary: Accept-Encoding\r\n" + "_eep-Alive: timeout=45\r\n" /* semantic value ignored */ + "_onnection: Keep-Alive\r\n" /* semantic value ignored */ + "Transfer-Encoding: chunked\r\n" + "Content-Type: text/html\r\n" + "Connection: close\r\n" + "\r\n" + "0\r\n\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 11 + ,.headers= + { { "Date", "Tue, 28 Sep 2010 01:14:13 GMT" } + , { "Server", "Apache" } + , { "Cache-Control", "no-cache, must-revalidate" } + , { "Expires", "Mon, 26 Jul 1997 05:00:00 GMT" } + , { ".et-Cookie", "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com" } + , { "Vary", "Accept-Encoding" } + , { "_eep-Alive", "timeout=45" } + , { "_onnection", "Keep-Alive" } + , { "Transfer-Encoding", "chunked" } + , { "Content-Type", "text/html" } + , { "Connection", "close" } + } + ,.body= "" + } + +#define NON_ASCII_IN_STATUS_LINE 10 +/* Should handle non-ASCII in status line */ +, {.name= "non-ASCII in status line" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 500 Oriëntatieprobleem\r\n" + "Date: Fri, 5 Nov 2010 23:07:12 GMT+2\r\n" + "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 500 + ,.num_headers= 3 + ,.headers= + { { "Date", "Fri, 5 Nov 2010 23:07:12 GMT+2" } + , { "Content-Length", "0" } + , { "Connection", "close" } + } + ,.body= "" + } + +#define HTTP_VERSION_0_9 11 +/* Should handle HTTP/0.9 */ +, {.name= "http version 0.9" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/0.9 200 OK\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 0 + ,.http_minor= 9 + ,.status_code= 200 + ,.num_headers= 0 + ,.headers= + {} + ,.body= "" + } + +#define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12 +/* The client should wait for the server's EOF. That is, when neither + * content-length nor transfer-encoding is specified, the end of body + * is specified by the EOF. + */ +, {.name= "neither content-length nor transfer-encoding response" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "hello world" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 1 + ,.headers= + { { "Content-Type", "text/plain" } + } + ,.body= "hello world" + } + +#define NO_BODY_HTTP10_KA_200 13 +, {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.0 200 OK\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 200 + ,.num_headers= 1 + ,.headers= + { { "Connection", "keep-alive" } + } + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP10_KA_204 14 +, {.name= "HTTP/1.0 with keep-alive and a 204 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.0 204 No content\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 204 + ,.num_headers= 1 + ,.headers= + { { "Connection", "keep-alive" } + } + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_KA_200 15 +, {.name= "HTTP/1.1 with an EOF-terminated 200 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 0 + ,.headers={} + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_KA_204 16 +, {.name= "HTTP/1.1 with a 204 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 204 No content\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 204 + ,.num_headers= 0 + ,.headers={} + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_NOKA_204 17 +, {.name= "HTTP/1.1 with a 204 status and keep-alive disabled" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 204 No content\r\n" + "Connection: close\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 204 + ,.num_headers= 1 + ,.headers= + { { "Connection", "close" } + } + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_KA_CHUNKED_200 18 +, {.name= "HTTP/1.1 with chunked endocing and a 200 response" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding", "chunked" } + } + ,.body_size= 0 + ,.body= "" + } + +#if !HTTP_PARSER_STRICT +#define SPACE_IN_FIELD_RES 19 +/* Should handle spaces in header fields */ +, {.name= "field space" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Server: Microsoft-IIS/6.0\r\n" + "X-Powered-By: ASP.NET\r\n" + "en-US Content-Type: text/xml\r\n" /* this is the problem */ + "Content-Type: text/xml\r\n" + "Content-Length: 16\r\n" + "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n" + "Connection: keep-alive\r\n" + "\r\n" + "hello" /* fake body */ + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.num_headers= 7 + ,.headers= + { { "Server", "Microsoft-IIS/6.0" } + , { "X-Powered-By", "ASP.NET" } + , { "en-US Content-Type", "text/xml" } + , { "Content-Type", "text/xml" } + , { "Content-Length", "16" } + , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" } + , { "Connection", "keep-alive" } + } + ,.body= "hello" + } +#endif /* !HTTP_PARSER_STRICT */ + +, {.name= NULL } /* sentinel */ +}; + +/* strnlen() is a POSIX.2008 addition. Can't rely on it being available so + * define it ourselves. + */ +size_t +strnlen(const char *s, size_t maxlen) +{ + const char *p; + + p = memchr(s, '\0', maxlen); + if (p == NULL) + return maxlen; + + return p - s; +} + +size_t +strlncat(char *dst, size_t len, const char *src, size_t n) +{ + size_t slen; + size_t dlen; + size_t rlen; + size_t ncpy; + + slen = strnlen(src, n); + dlen = strnlen(dst, len); + + if (dlen < len) { + rlen = len - dlen; + ncpy = slen < rlen ? slen : (rlen - 1); + memcpy(dst + dlen, src, ncpy); + dst[dlen + ncpy] = '\0'; + } + + assert(len > slen + dlen); + return slen + dlen; +} + +size_t +strlcat(char *dst, const char *src, size_t len) +{ + return strlncat(dst, len, src, (size_t) -1); +} + +size_t +strlncpy(char *dst, size_t len, const char *src, size_t n) +{ + size_t slen; + size_t ncpy; + + slen = strnlen(src, n); + + if (len > 0) { + ncpy = slen < len ? slen : (len - 1); + memcpy(dst, src, ncpy); + dst[ncpy] = '\0'; + } + + assert(len > slen); + return slen; +} + +size_t +strlcpy(char *dst, const char *src, size_t len) +{ + return strlncpy(dst, len, src, (size_t) -1); +} + +int +request_url_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + strlncat(messages[num_messages].request_url, + sizeof(messages[num_messages].request_url), + buf, + len); + return 0; +} + +int +status_complete_cb (http_parser *p) { + assert(p == parser); + p->data++; + return 0; +} + +int +header_field_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + struct message *m = &messages[num_messages]; + + if (m->last_header_element != FIELD) + m->num_headers++; + + strlncat(m->headers[m->num_headers-1][0], + sizeof(m->headers[m->num_headers-1][0]), + buf, + len); + + m->last_header_element = FIELD; + + return 0; +} + +int +header_value_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + struct message *m = &messages[num_messages]; + + strlncat(m->headers[m->num_headers-1][1], + sizeof(m->headers[m->num_headers-1][1]), + buf, + len); + + m->last_header_element = VALUE; + + return 0; +} + +void +check_body_is_final (const http_parser *p) +{ + if (messages[num_messages].body_is_final) { + fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " + "on last on_body callback call " + "but it doesn't! ***\n\n"); + assert(0); + abort(); + } + messages[num_messages].body_is_final = http_body_is_final(p); +} + +int +body_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + strlncat(messages[num_messages].body, + sizeof(messages[num_messages].body), + buf, + len); + messages[num_messages].body_size += len; + check_body_is_final(p); + // printf("body_cb: '%s'\n", requests[num_messages].body); + return 0; +} + +int +count_body_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + assert(buf); + messages[num_messages].body_size += len; + check_body_is_final(p); + return 0; +} + +int +message_begin_cb (http_parser *p) +{ + assert(p == parser); + messages[num_messages].message_begin_cb_called = TRUE; + return 0; +} + +int +headers_complete_cb (http_parser *p) +{ + assert(p == parser); + messages[num_messages].method = parser->method; + messages[num_messages].status_code = parser->status_code; + messages[num_messages].http_major = parser->http_major; + messages[num_messages].http_minor = parser->http_minor; + messages[num_messages].headers_complete_cb_called = TRUE; + messages[num_messages].should_keep_alive = http_should_keep_alive(parser); + return 0; +} + +int +message_complete_cb (http_parser *p) +{ + assert(p == parser); + if (messages[num_messages].should_keep_alive != http_should_keep_alive(parser)) + { + fprintf(stderr, "\n\n *** Error http_should_keep_alive() should have same " + "value in both on_message_complete and on_headers_complete " + "but it doesn't! ***\n\n"); + assert(0); + abort(); + } + + if (messages[num_messages].body_size && + http_body_is_final(p) && + !messages[num_messages].body_is_final) + { + fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " + "on last on_body callback call " + "but it doesn't! ***\n\n"); + assert(0); + abort(); + } + + messages[num_messages].message_complete_cb_called = TRUE; + + messages[num_messages].message_complete_on_eof = currently_parsing_eof; + + num_messages++; + return 0; +} + +/* These dontcall_* callbacks exist so that we can verify that when we're + * paused, no additional callbacks are invoked */ +int +dontcall_message_begin_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_message_begin() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_header_field_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_header_field() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_header_value_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_header_value() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_request_url_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_request_url() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_body_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_body_cb() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_headers_complete_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_headers_complete() called on paused " + "parser ***\n\n"); + abort(); +} + +int +dontcall_message_complete_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_message_complete() called on paused " + "parser ***\n\n"); + abort(); +} + +static http_parser_settings settings_dontcall = + {.on_message_begin = dontcall_message_begin_cb + ,.on_header_field = dontcall_header_field_cb + ,.on_header_value = dontcall_header_value_cb + ,.on_url = dontcall_request_url_cb + ,.on_body = dontcall_body_cb + ,.on_headers_complete = dontcall_headers_complete_cb + ,.on_message_complete = dontcall_message_complete_cb + }; + +/* These pause_* callbacks always pause the parser and just invoke the regular + * callback that tracks content. Before returning, we overwrite the parser + * settings to point to the _dontcall variety so that we can verify that + * the pause actually did, you know, pause. */ +int +pause_message_begin_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return message_begin_cb(p); +} + +int +pause_header_field_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return header_field_cb(p, buf, len); +} + +int +pause_header_value_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return header_value_cb(p, buf, len); +} + +int +pause_request_url_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return request_url_cb(p, buf, len); +} + +int +pause_body_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return body_cb(p, buf, len); +} + +int +pause_headers_complete_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return headers_complete_cb(p); +} + +int +pause_message_complete_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return message_complete_cb(p); +} + +static http_parser_settings settings_pause = + {.on_message_begin = pause_message_begin_cb + ,.on_header_field = pause_header_field_cb + ,.on_header_value = pause_header_value_cb + ,.on_url = pause_request_url_cb + ,.on_body = pause_body_cb + ,.on_headers_complete = pause_headers_complete_cb + ,.on_message_complete = pause_message_complete_cb + }; + +static http_parser_settings settings = + {.on_message_begin = message_begin_cb + ,.on_header_field = header_field_cb + ,.on_header_value = header_value_cb + ,.on_url = request_url_cb + ,.on_body = body_cb + ,.on_headers_complete = headers_complete_cb + ,.on_message_complete = message_complete_cb + }; + +static http_parser_settings settings_count_body = + {.on_message_begin = message_begin_cb + ,.on_header_field = header_field_cb + ,.on_header_value = header_value_cb + ,.on_url = request_url_cb + ,.on_body = count_body_cb + ,.on_headers_complete = headers_complete_cb + ,.on_message_complete = message_complete_cb + }; + +static http_parser_settings settings_null = + {.on_message_begin = 0 + ,.on_header_field = 0 + ,.on_header_value = 0 + ,.on_url = 0 + ,.on_body = 0 + ,.on_headers_complete = 0 + ,.on_message_complete = 0 + }; + +void +parser_init (enum http_parser_type type) +{ + num_messages = 0; + + assert(parser == NULL); + + parser = malloc(sizeof(http_parser)); + + http_parser_init(parser, type); + + memset(&messages, 0, sizeof messages); + +} + +void +parser_free () +{ + assert(parser); + free(parser); + parser = NULL; +} + +size_t parse (const char *buf, size_t len) +{ + size_t nparsed; + currently_parsing_eof = (len == 0); + nparsed = http_parser_execute(parser, &settings, buf, len); + return nparsed; +} + +size_t parse_count_body (const char *buf, size_t len) +{ + size_t nparsed; + currently_parsing_eof = (len == 0); + nparsed = http_parser_execute(parser, &settings_count_body, buf, len); + return nparsed; +} + +size_t parse_pause (const char *buf, size_t len) +{ + size_t nparsed; + http_parser_settings s = settings_pause; + + currently_parsing_eof = (len == 0); + current_pause_parser = &s; + nparsed = http_parser_execute(parser, current_pause_parser, buf, len); + return nparsed; +} + +static inline int +check_str_eq (const struct message *m, + const char *prop, + const char *expected, + const char *found) { + if ((expected == NULL) != (found == NULL)) { + printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); + printf("expected %s\n", (expected == NULL) ? "NULL" : expected); + printf(" found %s\n", (found == NULL) ? "NULL" : found); + return 0; + } + if (expected != NULL && 0 != strcmp(expected, found)) { + printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); + printf("expected '%s'\n", expected); + printf(" found '%s'\n", found); + return 0; + } + return 1; +} + +static inline int +check_num_eq (const struct message *m, + const char *prop, + int expected, + int found) { + if (expected != found) { + printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); + printf("expected %d\n", expected); + printf(" found %d\n", found); + return 0; + } + return 1; +} + +#define MESSAGE_CHECK_STR_EQ(expected, found, prop) \ + if (!check_str_eq(expected, #prop, expected->prop, found->prop)) return 0 + +#define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \ + if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0 + +#define MESSAGE_CHECK_URL_EQ(u, expected, found, prop, fn) \ +do { \ + char ubuf[256]; \ + \ + if ((u)->field_set & (1 << (fn))) { \ + memcpy(ubuf, (found)->request_url + (u)->field_data[(fn)].off, \ + (u)->field_data[(fn)].len); \ + ubuf[(u)->field_data[(fn)].len] = '\0'; \ + } else { \ + ubuf[0] = '\0'; \ + } \ + \ + check_str_eq(expected, #prop, expected->prop, ubuf); \ +} while(0) + +int +message_eq (int index, const struct message *expected) +{ + int i; + struct message *m = &messages[index]; + + MESSAGE_CHECK_NUM_EQ(expected, m, http_major); + MESSAGE_CHECK_NUM_EQ(expected, m, http_minor); + + if (expected->type == HTTP_REQUEST) { + MESSAGE_CHECK_NUM_EQ(expected, m, method); + } else { + MESSAGE_CHECK_NUM_EQ(expected, m, status_code); + } + + MESSAGE_CHECK_NUM_EQ(expected, m, should_keep_alive); + MESSAGE_CHECK_NUM_EQ(expected, m, message_complete_on_eof); + + assert(m->message_begin_cb_called); + assert(m->headers_complete_cb_called); + assert(m->message_complete_cb_called); + + + MESSAGE_CHECK_STR_EQ(expected, m, request_url); + + /* Check URL components; we can't do this w/ CONNECT since it doesn't + * send us a well-formed URL. + */ + if (*m->request_url && m->method != HTTP_CONNECT) { + struct http_parser_url u; + + if (http_parser_parse_url(m->request_url, strlen(m->request_url), 0, &u)) { + fprintf(stderr, "\n\n*** failed to parse URL %s ***\n\n", + m->request_url); + abort(); + } + + if (expected->host) { + MESSAGE_CHECK_URL_EQ(&u, expected, m, host, UF_HOST); + } + + if (expected->userinfo) { + MESSAGE_CHECK_URL_EQ(&u, expected, m, userinfo, UF_USERINFO); + } + + m->port = (u.field_set & (1 << UF_PORT)) ? + u.port : 0; + + MESSAGE_CHECK_URL_EQ(&u, expected, m, query_string, UF_QUERY); + MESSAGE_CHECK_URL_EQ(&u, expected, m, fragment, UF_FRAGMENT); + MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH); + MESSAGE_CHECK_NUM_EQ(expected, m, port); + } + + if (expected->body_size) { + MESSAGE_CHECK_NUM_EQ(expected, m, body_size); + } else { + MESSAGE_CHECK_STR_EQ(expected, m, body); + } + + MESSAGE_CHECK_NUM_EQ(expected, m, num_headers); + + int r; + for (i = 0; i < m->num_headers; i++) { + r = check_str_eq(expected, "header field", expected->headers[i][0], m->headers[i][0]); + if (!r) return 0; + r = check_str_eq(expected, "header value", expected->headers[i][1], m->headers[i][1]); + if (!r) return 0; + } + + MESSAGE_CHECK_STR_EQ(expected, m, upgrade); + + return 1; +} + +/* Given a sequence of varargs messages, return the number of them that the + * parser should successfully parse, taking into account that upgraded + * messages prevent all subsequent messages from being parsed. + */ +size_t +count_parsed_messages(const size_t nmsgs, ...) { + size_t i; + va_list ap; + + va_start(ap, nmsgs); + + for (i = 0; i < nmsgs; i++) { + struct message *m = va_arg(ap, struct message *); + + if (m->upgrade) { + va_end(ap); + return i + 1; + } + } + + va_end(ap); + return nmsgs; +} + +/* Given a sequence of bytes and the number of these that we were able to + * parse, verify that upgrade bodies are correct. + */ +void +upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) { + va_list ap; + size_t i; + size_t off = 0; + + va_start(ap, nmsgs); + + for (i = 0; i < nmsgs; i++) { + struct message *m = va_arg(ap, struct message *); + + off += strlen(m->raw); + + if (m->upgrade) { + off -= strlen(m->upgrade); + + /* Check the portion of the response after its specified upgrade */ + if (!check_str_eq(m, "upgrade", body + off, body + nread)) { + abort(); + } + + /* Fix up the response so that message_eq() will verify the beginning + * of the upgrade */ + *(body + nread + strlen(m->upgrade)) = '\0'; + messages[num_messages -1 ].upgrade = body + nread; + + va_end(ap); + return; + } + } + + va_end(ap); + printf("\n\n*** Error: expected a message with upgrade ***\n"); + + abort(); +} + +static void +print_error (const char *raw, size_t error_location) +{ + fprintf(stderr, "\n*** %s ***\n\n", + http_errno_description(HTTP_PARSER_ERRNO(parser))); + + int this_line = 0, char_len = 0; + size_t i, j, len = strlen(raw), error_location_line = 0; + for (i = 0; i < len; i++) { + if (i == error_location) this_line = 1; + switch (raw[i]) { + case '\r': + char_len = 2; + fprintf(stderr, "\\r"); + break; + + case '\n': + char_len = 2; + fprintf(stderr, "\\n\n"); + + if (this_line) goto print; + + error_location_line = 0; + continue; + + default: + char_len = 1; + fputc(raw[i], stderr); + break; + } + if (!this_line) error_location_line += char_len; + } + + fprintf(stderr, "[eof]\n"); + + print: + for (j = 0; j < error_location_line; j++) { + fputc(' ', stderr); + } + fprintf(stderr, "^\n\nerror location: %u\n", (unsigned int)error_location); +} + +void +test_preserve_data (void) +{ + char my_data[] = "application-specific data"; + http_parser parser; + parser.data = my_data; + http_parser_init(&parser, HTTP_REQUEST); + if (parser.data != my_data) { + printf("\n*** parser.data not preserved accross http_parser_init ***\n\n"); + abort(); + } +} + +struct url_test { + const char *name; + const char *url; + int is_connect; + struct http_parser_url u; + int rv; +}; + +const struct url_test url_tests[] = +{ {.name="proxy request" + ,.url="http://hostname/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) + ,.port=0 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 7, 8 } /* UF_HOST */ + ,{ 0, 0 } /* UF_PORT */ + ,{ 15, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="proxy request with port" + ,.url="http://hostname:444/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) + ,.port=444 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 7, 8 } /* UF_HOST */ + ,{ 16, 3 } /* UF_PORT */ + ,{ 19, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="CONNECT request" + ,.url="hostname:443" + ,.is_connect=1 + ,.u= + {.field_set=(1 << UF_HOST) | (1 << UF_PORT) + ,.port=443 + ,.field_data= + {{ 0, 0 } /* UF_SCHEMA */ + ,{ 0, 8 } /* UF_HOST */ + ,{ 9, 3 } /* UF_PORT */ + ,{ 0, 0 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="CONNECT request but not connect" + ,.url="hostname:443" + ,.is_connect=0 + ,.rv=1 + } + +, {.name="proxy ipv6 request" + ,.url="http://[1:2::3:4]/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) + ,.port=0 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 8, 8 } /* UF_HOST */ + ,{ 0, 0 } /* UF_PORT */ + ,{ 17, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="proxy ipv6 request with port" + ,.url="http://[1:2::3:4]:67/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) + ,.port=67 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 8, 8 } /* UF_HOST */ + ,{ 18, 2 } /* UF_PORT */ + ,{ 20, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="CONNECT ipv6 address" + ,.url="[1:2::3:4]:443" + ,.is_connect=1 + ,.u= + {.field_set=(1 << UF_HOST) | (1 << UF_PORT) + ,.port=443 + ,.field_data= + {{ 0, 0 } /* UF_SCHEMA */ + ,{ 1, 8 } /* UF_HOST */ + ,{ 11, 3 } /* UF_PORT */ + ,{ 0, 0 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="ipv4 in ipv6 address" + ,.url="http://[2001:0000:0000:0000:0000:0000:1.9.1.1]/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) + ,.port=0 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 8, 37 } /* UF_HOST */ + ,{ 0, 0 } /* UF_PORT */ + ,{ 46, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="extra ? in query string" + ,.url="http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css," + "fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css," + "fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css" + ,.is_connect=0 + ,.u= + {.field_set=(1<field_set, u->port); + for (i = 0; i < UF_MAX; i++) { + if ((u->field_set & (1 << i)) == 0) { + printf("\tfield_data[%u]: unset\n", i); + continue; + } + + printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n\"", + i, + u->field_data[i].off, + u->field_data[i].len, + u->field_data[i].len, + url + u->field_data[i].off); + } +} + +void +test_parse_url (void) +{ + struct http_parser_url u; + const struct url_test *test; + unsigned int i; + int rv; + + for (i = 0; i < (sizeof(url_tests) / sizeof(url_tests[0])); i++) { + test = &url_tests[i]; + memset(&u, 0, sizeof(u)); + + rv = http_parser_parse_url(test->url, + strlen(test->url), + test->is_connect, + &u); + + if (test->rv == 0) { + if (rv != 0) { + printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " + "unexpected rv %d ***\n\n", test->url, test->name, rv); + abort(); + } + + if (memcmp(&u, &test->u, sizeof(u)) != 0) { + printf("\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n", + test->url, test->name); + + printf("target http_parser_url:\n"); + dump_url(test->url, &test->u); + printf("result http_parser_url:\n"); + dump_url(test->url, &u); + + abort(); + } + } else { + /* test->rv != 0 */ + if (rv == 0) { + printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " + "unexpected rv %d ***\n\n", test->url, test->name, rv); + abort(); + } + } + } +} + +void +test_method_str (void) +{ + assert(0 == strcmp("GET", http_method_str(HTTP_GET))); + assert(0 == strcmp("", http_method_str(1337))); +} + +void +test_message (const struct message *message) +{ + size_t raw_len = strlen(message->raw); + size_t msg1len; + for (msg1len = 0; msg1len < raw_len; msg1len++) { + parser_init(message->type); + + size_t read; + const char *msg1 = message->raw; + const char *msg2 = msg1 + msg1len; + size_t msg2len = raw_len - msg1len; + + if (msg1len) { + read = parse(msg1, msg1len); + + if (message->upgrade && parser->upgrade) { + messages[num_messages - 1].upgrade = msg1 + read; + goto test; + } + + if (read != msg1len) { + print_error(msg1, read); + abort(); + } + } + + + read = parse(msg2, msg2len); + + if (message->upgrade && parser->upgrade) { + messages[num_messages - 1].upgrade = msg2 + read; + goto test; + } + + if (read != msg2len) { + print_error(msg2, read); + abort(); + } + + read = parse(NULL, 0); + + if (read != 0) { + print_error(message->raw, read); + abort(); + } + + test: + + if (num_messages != 1) { + printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); + abort(); + } + + if(!message_eq(0, message)) abort(); + + parser_free(); + } +} + +void +test_message_count_body (const struct message *message) +{ + parser_init(message->type); + + size_t read; + size_t l = strlen(message->raw); + size_t i, toread; + size_t chunk = 4024; + + for (i = 0; i < l; i+= chunk) { + toread = MIN(l-i, chunk); + read = parse_count_body(message->raw + i, toread); + if (read != toread) { + print_error(message->raw, read); + abort(); + } + } + + + read = parse_count_body(NULL, 0); + if (read != 0) { + print_error(message->raw, read); + abort(); + } + + if (num_messages != 1) { + printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); + abort(); + } + + if(!message_eq(0, message)) abort(); + + parser_free(); +} + +void +test_simple (const char *buf, enum http_errno err_expected) +{ + parser_init(HTTP_REQUEST); + + size_t parsed; + int pass; + enum http_errno err; + + parsed = parse(buf, strlen(buf)); + pass = (parsed == strlen(buf)); + err = HTTP_PARSER_ERRNO(parser); + parsed = parse(NULL, 0); + pass &= (parsed == 0); + + parser_free(); + + /* In strict mode, allow us to pass with an unexpected HPE_STRICT as + * long as the caller isn't expecting success. + */ +#if HTTP_PARSER_STRICT + if (err_expected != err && err_expected != HPE_OK && err != HPE_STRICT) { +#else + if (err_expected != err) { +#endif + fprintf(stderr, "\n*** test_simple expected %s, but saw %s ***\n\n%s\n", + http_errno_name(err_expected), http_errno_name(err), buf); + abort(); + } +} + +void +test_header_overflow_error (int req) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + const char *buf; + buf = req ? "GET / HTTP/1.1\r\n" : "HTTP/1.0 200 OK\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + buf = "header-key: header-value\r\n"; + size_t buflen = strlen(buf); + + int i; + for (i = 0; i < 10000; i++) { + parsed = http_parser_execute(&parser, &settings_null, buf, buflen); + if (parsed != buflen) { + //fprintf(stderr, "error found on iter %d\n", i); + assert(HTTP_PARSER_ERRNO(&parser) == HPE_HEADER_OVERFLOW); + return; + } + } + + fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n"); + abort(); +} + +static void +test_content_length_overflow (const char *buf, size_t buflen, int expect_ok) +{ + http_parser parser; + http_parser_init(&parser, HTTP_RESPONSE); + http_parser_execute(&parser, &settings_null, buf, buflen); + + if (expect_ok) + assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK); + else + assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CONTENT_LENGTH); +} + +void +test_header_content_length_overflow_error (void) +{ +#define X(size) \ + "HTTP/1.1 200 OK\r\n" \ + "Content-Length: " #size "\r\n" \ + "\r\n" + const char a[] = X(18446744073709551614); /* 2^64-2 */ + const char b[] = X(18446744073709551615); /* 2^64-1 */ + const char c[] = X(18446744073709551616); /* 2^64 */ +#undef X + test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ + test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ + test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ +} + +void +test_chunk_content_length_overflow_error (void) +{ +#define X(size) \ + "HTTP/1.1 200 OK\r\n" \ + "Transfer-Encoding: chunked\r\n" \ + "\r\n" \ + #size "\r\n" \ + "..." + const char a[] = X(FFFFFFFFFFFFFFFE); /* 2^64-2 */ + const char b[] = X(FFFFFFFFFFFFFFFF); /* 2^64-1 */ + const char c[] = X(10000000000000000); /* 2^64 */ +#undef X + test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ + test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ + test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ +} + +void +test_no_overflow_long_body (int req, size_t length) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + size_t i; + char buf1[3000]; + size_t buf1len = sprintf(buf1, "%s\r\nConnection: Keep-Alive\r\nContent-Length: %lu\r\n\r\n", + req ? "POST / HTTP/1.0" : "HTTP/1.0 200 OK", (unsigned long)length); + parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); + if (parsed != buf1len) + goto err; + + for (i = 0; i < length; i++) { + char foo = 'a'; + parsed = http_parser_execute(&parser, &settings_null, &foo, 1); + if (parsed != 1) + goto err; + } + + parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); + if (parsed != buf1len) goto err; + return; + + err: + fprintf(stderr, + "\n*** error in test_no_overflow_long_body %s of length %lu ***\n", + req ? "REQUEST" : "RESPONSE", + (unsigned long)length); + abort(); +} + +void +test_multiple3 (const struct message *r1, const struct message *r2, const struct message *r3) +{ + int message_count = count_parsed_messages(3, r1, r2, r3); + + char total[ strlen(r1->raw) + + strlen(r2->raw) + + strlen(r3->raw) + + 1 + ]; + total[0] = '\0'; + + strcat(total, r1->raw); + strcat(total, r2->raw); + strcat(total, r3->raw); + + parser_init(r1->type); + + size_t read; + + read = parse(total, strlen(total)); + + if (parser->upgrade) { + upgrade_message_fix(total, read, 3, r1, r2, r3); + goto test; + } + + if (read != strlen(total)) { + print_error(total, read); + abort(); + } + + read = parse(NULL, 0); + + if (read != 0) { + print_error(total, read); + abort(); + } + +test: + + if (message_count != num_messages) { + fprintf(stderr, "\n\n*** Parser didn't see 3 messages only %d *** \n", num_messages); + abort(); + } + + if (!message_eq(0, r1)) abort(); + if (message_count > 1 && !message_eq(1, r2)) abort(); + if (message_count > 2 && !message_eq(2, r3)) abort(); + + parser_free(); +} + +/* SCAN through every possible breaking to make sure the + * parser can handle getting the content in any chunks that + * might come from the socket + */ +void +test_scan (const struct message *r1, const struct message *r2, const struct message *r3) +{ + char total[80*1024] = "\0"; + char buf1[80*1024] = "\0"; + char buf2[80*1024] = "\0"; + char buf3[80*1024] = "\0"; + + strcat(total, r1->raw); + strcat(total, r2->raw); + strcat(total, r3->raw); + + size_t read; + + int total_len = strlen(total); + + int total_ops = 2 * (total_len - 1) * (total_len - 2) / 2; + int ops = 0 ; + + size_t buf1_len, buf2_len, buf3_len; + int message_count = count_parsed_messages(3, r1, r2, r3); + + int i,j,type_both; + for (type_both = 0; type_both < 2; type_both ++ ) { + for (j = 2; j < total_len; j ++ ) { + for (i = 1; i < j; i ++ ) { + + if (ops % 1000 == 0) { + printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops); + fflush(stdout); + } + ops += 1; + + parser_init(type_both ? HTTP_BOTH : r1->type); + + buf1_len = i; + strlncpy(buf1, sizeof(buf1), total, buf1_len); + buf1[buf1_len] = 0; + + buf2_len = j - i; + strlncpy(buf2, sizeof(buf1), total+i, buf2_len); + buf2[buf2_len] = 0; + + buf3_len = total_len - j; + strlncpy(buf3, sizeof(buf1), total+j, buf3_len); + buf3[buf3_len] = 0; + + read = parse(buf1, buf1_len); + + if (parser->upgrade) goto test; + + if (read != buf1_len) { + print_error(buf1, read); + goto error; + } + + read += parse(buf2, buf2_len); + + if (parser->upgrade) goto test; + + if (read != buf1_len + buf2_len) { + print_error(buf2, read); + goto error; + } + + read += parse(buf3, buf3_len); + + if (parser->upgrade) goto test; + + if (read != buf1_len + buf2_len + buf3_len) { + print_error(buf3, read); + goto error; + } + + parse(NULL, 0); + +test: + if (parser->upgrade) { + upgrade_message_fix(total, read, 3, r1, r2, r3); + } + + if (message_count != num_messages) { + fprintf(stderr, "\n\nParser didn't see %d messages only %d\n", + message_count, num_messages); + goto error; + } + + if (!message_eq(0, r1)) { + fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n"); + goto error; + } + + if (message_count > 1 && !message_eq(1, r2)) { + fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n"); + goto error; + } + + if (message_count > 2 && !message_eq(2, r3)) { + fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n"); + goto error; + } + + parser_free(); + } + } + } + puts("\b\b\b\b100%"); + return; + + error: + fprintf(stderr, "i=%d j=%d\n", i, j); + fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1); + fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2); + fprintf(stderr, "buf3 (%u) %s\n", (unsigned int)buf3_len, buf3); + abort(); +} + +// user required to free the result +// string terminated by \0 +char * +create_large_chunked_message (int body_size_in_kb, const char* headers) +{ + int i; + size_t wrote = 0; + size_t headers_len = strlen(headers); + size_t bufsize = headers_len + (5+1024+2)*body_size_in_kb + 6; + char * buf = malloc(bufsize); + + memcpy(buf, headers, headers_len); + wrote += headers_len; + + for (i = 0; i < body_size_in_kb; i++) { + // write 1kb chunk into the body. + memcpy(buf + wrote, "400\r\n", 5); + wrote += 5; + memset(buf + wrote, 'C', 1024); + wrote += 1024; + strcpy(buf + wrote, "\r\n"); + wrote += 2; + } + + memcpy(buf + wrote, "0\r\n\r\n", 6); + wrote += 6; + assert(wrote == bufsize); + + return buf; +} + +void +test_status_complete (void) +{ + parser_init(HTTP_RESPONSE); + parser->data = 0; + http_parser_settings settings = settings_null; + settings.on_status_complete = status_complete_cb; + + char *response = "don't mind me, just a simple response"; + http_parser_execute(parser, &settings, response, strlen(response)); + assert(parser->data == (void*)0); // the status_complete callback was never called + assert(parser->http_errno == HPE_INVALID_CONSTANT); // the errno for an invalid status line +} + +/* Verify that we can pause parsing at any of the bytes in the + * message and still get the result that we're expecting. */ +void +test_message_pause (const struct message *msg) +{ + char *buf = (char*) msg->raw; + size_t buflen = strlen(msg->raw); + size_t nread; + + parser_init(msg->type); + + do { + nread = parse_pause(buf, buflen); + + // We can only set the upgrade buffer once we've gotten our message + // completion callback. + if (messages[0].message_complete_cb_called && + msg->upgrade && + parser->upgrade) { + messages[0].upgrade = buf + nread; + goto test; + } + + if (nread < buflen) { + + // Not much do to if we failed a strict-mode check + if (HTTP_PARSER_ERRNO(parser) == HPE_STRICT) { + parser_free(); + return; + } + + assert (HTTP_PARSER_ERRNO(parser) == HPE_PAUSED); + } + + buf += nread; + buflen -= nread; + http_parser_pause(parser, 0); + } while (buflen > 0); + + nread = parse_pause(NULL, 0); + assert (nread == 0); + +test: + if (num_messages != 1) { + printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name); + abort(); + } + + if(!message_eq(0, msg)) abort(); + + parser_free(); +} + +int +main (void) +{ + parser = NULL; + int i, j, k; + int request_count; + int response_count; + + printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser)); + + for (request_count = 0; requests[request_count].name; request_count++); + for (response_count = 0; responses[response_count].name; response_count++); + + //// API + test_preserve_data(); + test_parse_url(); + test_method_str(); + + //// OVERFLOW CONDITIONS + + test_header_overflow_error(HTTP_REQUEST); + test_no_overflow_long_body(HTTP_REQUEST, 1000); + test_no_overflow_long_body(HTTP_REQUEST, 100000); + + test_header_overflow_error(HTTP_RESPONSE); + test_no_overflow_long_body(HTTP_RESPONSE, 1000); + test_no_overflow_long_body(HTTP_RESPONSE, 100000); + + test_header_content_length_overflow_error(); + test_chunk_content_length_overflow_error(); + + //// RESPONSES + + for (i = 0; i < response_count; i++) { + test_message(&responses[i]); + } + + for (i = 0; i < response_count; i++) { + test_message_pause(&responses[i]); + } + + for (i = 0; i < response_count; i++) { + if (!responses[i].should_keep_alive) continue; + for (j = 0; j < response_count; j++) { + if (!responses[j].should_keep_alive) continue; + for (k = 0; k < response_count; k++) { + test_multiple3(&responses[i], &responses[j], &responses[k]); + } + } + } + + test_message_count_body(&responses[NO_HEADERS_NO_BODY_404]); + test_message_count_body(&responses[TRAILING_SPACE_ON_CHUNKED_BODY]); + + // test very large chunked response + { + char * msg = create_large_chunked_message(31337, + "HTTP/1.0 200 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "Content-Type: text/plain\r\n" + "\r\n"); + struct message large_chunked = + {.name= "large chunked" + ,.type= HTTP_RESPONSE + ,.raw= msg + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 200 + ,.num_headers= 2 + ,.headers= + { { "Transfer-Encoding", "chunked" } + , { "Content-Type", "text/plain" } + } + ,.body_size= 31337*1024 + }; + test_message_count_body(&large_chunked); + free(msg); + } + + + + printf("response scan 1/2 "); + test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] + , &responses[NO_BODY_HTTP10_KA_204] + , &responses[NO_REASON_PHRASE] + ); + + printf("response scan 2/2 "); + test_scan( &responses[BONJOUR_MADAME_FR] + , &responses[UNDERSTORE_HEADER_KEY] + , &responses[NO_CARRIAGE_RET] + ); + + puts("responses okay"); + + + /// REQUESTS + + test_simple("hello world", HPE_INVALID_METHOD); + test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION); + + + test_simple("ASDF / HTTP/1.1\r\n\r\n", HPE_INVALID_METHOD); + test_simple("PROPPATCHA / HTTP/1.1\r\n\r\n", HPE_INVALID_METHOD); + test_simple("GETA / HTTP/1.1\r\n\r\n", HPE_INVALID_METHOD); + + // Well-formed but incomplete + test_simple("GET / HTTP/1.1\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 6\r\n" + "\r\n" + "fooba", + HPE_OK); + + static const char *all_methods[] = { + "DELETE", + "GET", + "HEAD", + "POST", + "PUT", + //"CONNECT", //CONNECT can't be tested like other methods, it's a tunnel + "OPTIONS", + "TRACE", + "COPY", + "LOCK", + "MKCOL", + "MOVE", + "PROPFIND", + "PROPPATCH", + "UNLOCK", + "REPORT", + "MKACTIVITY", + "CHECKOUT", + "MERGE", + "M-SEARCH", + "NOTIFY", + "SUBSCRIBE", + "UNSUBSCRIBE", + "PATCH", + 0 }; + const char **this_method; + for (this_method = all_methods; *this_method; this_method++) { + char buf[200]; + sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); + test_simple(buf, HPE_OK); + } + + static const char *bad_methods[] = { + "C******", + "M****", + 0 }; + for (this_method = bad_methods; *this_method; this_method++) { + char buf[200]; + sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); + test_simple(buf, HPE_UNKNOWN); + } + + const char *dumbfuck2 = + "GET / HTTP/1.1\r\n" + "X-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n" + "\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n" + "\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n" + "\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n" + "\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n" + "\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n" + "\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n" + "\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n" + "\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n" + "\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n" + "\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n" + "\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n" + "\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n" + "\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgHTTPAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n" + "\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n" + "\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n" + "\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n" + "\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n" + "\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n" + "\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n" + "\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n" + "\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n" + "\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n" + "\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n" + "\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n" + "\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n" + "\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n" + "\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n" + "\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n" + "\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n" + "\tRA==\r\n" + "\t-----END CERTIFICATE-----\r\n" + "\r\n"; + test_simple(dumbfuck2, HPE_OK); + +#if 0 + // NOTE(Wed Nov 18 11:57:27 CET 2009) this seems okay. we just read body + // until EOF. + // + // no content-length + // error if there is a body without content length + const char *bad_get_no_headers_no_body = "GET /bad_get_no_headers_no_body/world HTTP/1.1\r\n" + "Accept: */*\r\n" + "\r\n" + "HELLO"; + test_simple(bad_get_no_headers_no_body, 0); +#endif + /* TODO sending junk and large headers gets rejected */ + + + /* check to make sure our predefined requests are okay */ + for (i = 0; requests[i].name; i++) { + test_message(&requests[i]); + } + + for (i = 0; i < request_count; i++) { + test_message_pause(&requests[i]); + } + + for (i = 0; i < request_count; i++) { + if (!requests[i].should_keep_alive) continue; + for (j = 0; j < request_count; j++) { + if (!requests[j].should_keep_alive) continue; + for (k = 0; k < request_count; k++) { + test_multiple3(&requests[i], &requests[j], &requests[k]); + } + } + } + + printf("request scan 1/4 "); + test_scan( &requests[GET_NO_HEADERS_NO_BODY] + , &requests[GET_ONE_HEADER_NO_BODY] + , &requests[GET_NO_HEADERS_NO_BODY] + ); + + printf("request scan 2/4 "); + test_scan( &requests[POST_CHUNKED_ALL_YOUR_BASE] + , &requests[POST_IDENTITY_BODY_WORLD] + , &requests[GET_FUNKY_CONTENT_LENGTH] + ); + + printf("request scan 3/4 "); + test_scan( &requests[TWO_CHUNKS_MULT_ZERO_END] + , &requests[CHUNKED_W_TRAILING_HEADERS] + , &requests[CHUNKED_W_BULLSHIT_AFTER_LENGTH] + ); + + printf("request scan 4/4 "); + test_scan( &requests[QUERY_URL_WITH_QUESTION_MARK_GET] + , &requests[PREFIX_NEWLINE_GET ] + , &requests[CONNECT_REQUEST] + ); + + test_status_complete(); + + puts("requests okay"); + + return 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped new file mode 100644 index 0000000..038bb52 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped @@ -0,0 +1,845 @@ +name :curl get +raw :"GET /test HTTP/1.1\r\nUser-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\nHost: 0.0.0.0=5000\r\nAccept: */*\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/test +request_url :/test +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "User-Agent": "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1"} +header_1 :{ "Host": "0.0.0.0=5000"} +header_2 :{ "Accept": "*/*"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :firefox get +raw :"GET /favicon.ico HTTP/1.1\r\nHost: 0.0.0.0=5000\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 300\r\nConnection: keep-alive\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/favicon.ico +request_url :/favicon.ico +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Host": "0.0.0.0=5000"} +header_1 :{ "User-Agent": "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0"} +header_2 :{ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"} +header_3 :{ "Accept-Language": "en-us,en;q=0.5"} +header_4 :{ "Accept-Encoding": "gzip,deflate"} +header_5 :{ "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7"} +header_6 :{ "Keep-Alive": "300"} +header_7 :{ "Connection": "keep-alive"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :dumbfuck +raw :"GET /dumbfuck HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/dumbfuck +request_url :/dumbfuck +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "aaaaaaaaaaaaa": "++++++++++"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :fragment in url +raw :"GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/forums/1/topics/2375 +request_url :/forums/1/topics/2375?page=1#posts-17408 +fragment :posts-17408 +query_string:page=1 +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :get no headers no body +raw :"GET /get_no_headers_no_body/world HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/get_no_headers_no_body/world +request_url :/get_no_headers_no_body/world +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :get one header no body +raw :"GET /get_one_header_no_body HTTP/1.1\r\nAccept: */*\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/get_one_header_no_body +request_url :/get_one_header_no_body +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Accept": "*/*"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :get funky content length body hello +raw :"GET /get_funky_content_length_body_hello HTTP/1.0\r\nconTENT-Length: 5\r\n\r\nHELLO" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/get_funky_content_length_body_hello +request_url :/get_funky_content_length_body_hello +fragment : +query_string: +body :"HELLO" +body_size :0 +header_0 :{ "conTENT-Length": "5"} +should_keep_alive :0 +http_major :1 +http_minor :0 + +name :post identity body world +raw :"POST /post_identity_body_world?q=search#hey HTTP/1.1\r\nAccept: */*\r\nTransfer-Encoding: identity\r\nContent-Length: 5\r\n\r\nWorld" +type :HTTP_REQUEST +method: HTTP_POST +status_code :0 +request_path:/post_identity_body_world +request_url :/post_identity_body_world?q=search#hey +fragment :hey +query_string:q=search +body :"World" +body_size :0 +header_0 :{ "Accept": "*/*"} +header_1 :{ "Transfer-Encoding": "identity"} +header_2 :{ "Content-Length": "5"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :post - chunked body: all your base are belong to us +raw :"POST /post_chunked_all_your_base HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n1e\r\nall your base are belong to us\r\n0\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_POST +status_code :0 +request_path:/post_chunked_all_your_base +request_url :/post_chunked_all_your_base +fragment : +query_string: +body :"all your base are belong to us" +body_size :0 +header_0 :{ "Transfer-Encoding": "chunked"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :two chunks ; triple zero ending +raw :"POST /two_chunks_mult_zero_end HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n6\r\n world\r\n000\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_POST +status_code :0 +request_path:/two_chunks_mult_zero_end +request_url :/two_chunks_mult_zero_end +fragment : +query_string: +body :"hello world" +body_size :0 +header_0 :{ "Transfer-Encoding": "chunked"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :chunked with trailing headers. blech. +raw :"POST /chunked_w_trailing_headers HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n6\r\n world\r\n0\r\nVary: *\r\nContent-Type: text/plain\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_POST +status_code :0 +request_path:/chunked_w_trailing_headers +request_url :/chunked_w_trailing_headers +fragment : +query_string: +body :"hello world" +body_size :0 +header_0 :{ "Transfer-Encoding": "chunked"} +header_1 :{ "Vary": "*"} +header_2 :{ "Content-Type": "text/plain"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :with bullshit after the length +raw :"POST /chunked_w_bullshit_after_length HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n6; blahblah; blah\r\n world\r\n0\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_POST +status_code :0 +request_path:/chunked_w_bullshit_after_length +request_url :/chunked_w_bullshit_after_length +fragment : +query_string: +body :"hello world" +body_size :0 +header_0 :{ "Transfer-Encoding": "chunked"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :with quotes +raw :"GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/with_"stupid"_quotes +request_url :/with_"stupid"_quotes?foo="bar" +fragment : +query_string:foo="bar" +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :apachebench get +raw :"GET /test HTTP/1.0\r\nHost: 0.0.0.0:5000\r\nUser-Agent: ApacheBench/2.3\r\nAccept: */*\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/test +request_url :/test +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Host": "0.0.0.0:5000"} +header_1 :{ "User-Agent": "ApacheBench/2.3"} +header_2 :{ "Accept": "*/*"} +should_keep_alive :0 +http_major :1 +http_minor :0 + +name :query url with question mark +raw :"GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/test.cgi +request_url :/test.cgi?foo=bar?baz +fragment : +query_string:foo=bar?baz +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :newline prefix get +raw :"\r\nGET /test HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/test +request_url :/test +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :upgrade request +raw :"GET /demo HTTP/1.1\r\nHost: example.com\r\nConnection: Upgrade\r\nSec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\nSec-WebSocket-Protocol: sample\r\nUpgrade: WebSocket\r\nSec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\nOrigin: http://example.com\r\n\r\nHot diggity dogg" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/demo +request_url :/demo +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Host": "example.com"} +header_1 :{ "Connection": "Upgrade"} +header_2 :{ "Sec-WebSocket-Key2": "12998 5 Y3 1 .P00"} +header_3 :{ "Sec-WebSocket-Protocol": "sample"} +header_4 :{ "Upgrade": "WebSocket"} +header_5 :{ "Sec-WebSocket-Key1": "4 @1 46546xW%0l 1 5"} +header_6 :{ "Origin": "http://example.com"} +should_keep_alive :1 +upgrade :"Hot diggity dogg" +http_major :1 +http_minor :1 + +name :connect request +raw :"CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\nsome data\r\nand yet even more data" +type :HTTP_REQUEST +method: HTTP_CONNECT +status_code :0 +request_path: +request_url :0-home0.netscape.com:443 +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "User-agent": "Mozilla/1.1N"} +header_1 :{ "Proxy-authorization": "basic aGVsbG86d29ybGQ="} +should_keep_alive :0 +upgrade :"some data\r\nand yet even more data" +http_major :1 +http_minor :0 + +name :report request +raw :"REPORT /test HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_REPORT +status_code :0 +request_path:/test +request_url :/test +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :request with no http version +raw :"GET /\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/ +request_url :/ +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :0 +http_major :0 +http_minor :9 + +name :m-search request +raw :"M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nST: \"ssdp:all\"\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_MSEARCH +status_code :0 +request_path:* +request_url :* +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "HOST": "239.255.255.250:1900"} +header_1 :{ "MAN": ""ssdp:discover""} +header_2 :{ "ST": ""ssdp:all""} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :line folding in header value +raw :"GET / HTTP/1.1\r\nLine1: abc\r\n def\r\n ghi\r\n jkl\r\n mno \r\n qrs\r\nLine2: line2 \r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/ +request_url :/ +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Line1": "abcdefghijklmno qrs"} +header_1 :{ "Line2": "line2 "} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :host terminated by a query string +raw :"GET http://hypnotoad.org?hail=all HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path: +request_url :http://hypnotoad.org?hail=all +fragment : +query_string:hail=all +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :host:port terminated by a query string +raw :"GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path: +request_url :http://hypnotoad.org:1234?hail=all +fragment : +query_string:hail=all +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :host:port terminated by a space +raw :"GET http://hypnotoad.org:1234 HTTP/1.1\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path: +request_url :http://hypnotoad.org:1234 +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :PATCH request +raw :"PATCH /file.txt HTTP/1.1\r\nHost: www.example.com\r\nContent-Type: application/example\r\nIf-Match: \"e0023aa4e\"\r\nContent-Length: 10\r\n\r\ncccccccccc" +type :HTTP_REQUEST +method: UNKNOWN +status_code :0 +request_path:/file.txt +request_url :/file.txt +fragment : +query_string: +body :"cccccccccc" +body_size :0 +header_0 :{ "Host": "www.example.com"} +header_1 :{ "Content-Type": "application/example"} +header_2 :{ "If-Match": ""e0023aa4e""} +header_3 :{ "Content-Length": "10"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :connect caps request +raw :"CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\nUser-agent: Mozilla/1.1N\r\nProxy-authorization: basic aGVsbG86d29ybGQ=\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_CONNECT +status_code :0 +request_path: +request_url :HOME0.NETSCAPE.COM:443 +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "User-agent": "Mozilla/1.1N"} +header_1 :{ "Proxy-authorization": "basic aGVsbG86d29ybGQ="} +should_keep_alive :0 +upgrade :"" +http_major :1 +http_minor :0 + +name :eat CRLF between requests, no "Connection: close" header +raw :"POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 4\r\n\r\nq=42\r\n" +type :HTTP_REQUEST +method: HTTP_POST +status_code :0 +request_path:/ +request_url :/ +fragment : +query_string: +body :"q=42" +body_size :0 +header_0 :{ "Host": "www.example.com"} +header_1 :{ "Content-Type": "application/x-www-form-urlencoded"} +header_2 :{ "Content-Length": "4"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :eat CRLF between requests even if "Connection: close" is set +raw :"POST / HTTP/1.1\r\nHost: www.example.com\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 4\r\nConnection: close\r\n\r\nq=42\r\n" +type :HTTP_REQUEST +method: HTTP_POST +status_code :0 +request_path:/ +request_url :/ +fragment : +query_string: +body :"q=42" +body_size :0 +header_0 :{ "Host": "www.example.com"} +header_1 :{ "Content-Type": "application/x-www-form-urlencoded"} +header_2 :{ "Content-Length": "4"} +header_3 :{ "Connection": "close"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :PURGE request +raw :"PURGE /file.txt HTTP/1.1\r\nHost: www.example.com\r\n\r\n" +type :HTTP_REQUEST +method: UNKNOWN +status_code :0 +request_path:/file.txt +request_url :/file.txt +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Host": "www.example.com"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :google 301 +raw :"HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Sun, 26 Apr 2009 11:11:49 GMT\r\nExpires: Tue, 26 May 2009 11:11:49 GMT\r\nX-$PrototypeBI-Version: 1.6.0.3\r\nCache-Control: public, max-age=2592000\r\nServer: gws\r\nContent-Length: 219 \r\n\r\n\n301 Moved\n

301 Moved

\nThe document has moved\nhere.\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :301 +request_path: +request_url : +fragment : +query_string: +body :"\n301 Moved\n

301 Moved

\nThe document has moved\nhere.\r\n\r\n" +body_size :0 +header_0 :{ "Location": "http://www.google.com/"} +header_1 :{ "Content-Type": "text/html; charset=UTF-8"} +header_2 :{ "Date": "Sun, 26 Apr 2009 11:11:49 GMT"} +header_3 :{ "Expires": "Tue, 26 May 2009 11:11:49 GMT"} +header_4 :{ "X-$PrototypeBI-Version": "1.6.0.3"} +header_5 :{ "Cache-Control": "public, max-age=2592000"} +header_6 :{ "Server": "gws"} +header_7 :{ "Content-Length": "219 "} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :no content-length response +raw :"HTTP/1.1 200 OK\r\nDate: Tue, 04 Aug 2009 07:59:32 GMT\r\nServer: Apache\r\nX-Powered-By: Servlet/2.5 JSP/2.1\r\nContent-Type: text/xml; charset=utf-8\r\nConnection: close\r\n\r\n\n\n \n \n SOAP-ENV:Client\n Client Error\n \n \n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"\n\n \n \n SOAP-ENV:Client\n Client Error\n \n \n" +body_size :0 +header_0 :{ "Date": "Tue, 04 Aug 2009 07:59:32 GMT"} +header_1 :{ "Server": "Apache"} +header_2 :{ "X-Powered-By": "Servlet/2.5 JSP/2.1"} +header_3 :{ "Content-Type": "text/xml; charset=utf-8"} +header_4 :{ "Connection": "close"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :404 no headers no body +raw :"HTTP/1.1 404 Not Found\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :404 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :301 no response phrase +raw :"HTTP/1.1 301\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :301 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :200 trailing space on chunked body +raw :"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n25 \r\nThis is the data in the first chunk\r\n\r\n1C\r\nand this is the second one\r\n\r\n0 \r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"This is the data in the first chunk\r\nand this is the second one\r\n" +body_size :65 +header_0 :{ "Content-Type": "text/plain"} +header_1 :{ "Transfer-Encoding": "chunked"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :no carriage ret +raw :"HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\nConnection: close\n\nthese headers are from http://news.ycombinator.com/" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"these headers are from http://news.ycombinator.com/" +body_size :0 +header_0 :{ "Content-Type": "text/html; charset=utf-8"} +header_1 :{ "Connection": "close"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :proxy connection +raw :"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 11\r\nProxy-Connection: close\r\nDate: Thu, 31 Dec 2009 20:55:48 +0000\r\n\r\nhello world" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"hello world" +body_size :0 +header_0 :{ "Content-Type": "text/html; charset=UTF-8"} +header_1 :{ "Content-Length": "11"} +header_2 :{ "Proxy-Connection": "close"} +header_3 :{ "Date": "Thu, 31 Dec 2009 20:55:48 +0000"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :underscore header key +raw :"HTTP/1.1 200 OK\r\nServer: DCLK-AdSvr\r\nContent-Type: text/xml\r\nContent-Length: 0\r\nDCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Server": "DCLK-AdSvr"} +header_1 :{ "Content-Type": "text/xml"} +header_2 :{ "Content-Length": "0"} +header_3 :{ "DCLK_imp": "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o"} +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :bonjourmadame.fr +raw :"HTTP/1.0 301 Moved Permanently\r\nDate: Thu, 03 Jun 2010 09:56:32 GMT\r\nServer: Apache/2.2.3 (Red Hat)\r\nCache-Control: public\r\nPragma: \r\nLocation: http://www.bonjourmadame.fr/\r\nVary: Accept-Encoding\r\nContent-Length: 0\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: keep-alive\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :301 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Date": "Thu, 03 Jun 2010 09:56:32 GMT"} +header_1 :{ "Server": "Apache/2.2.3 (Red Hat)"} +header_2 :{ "Cache-Control": "public"} +header_3 :{ "Pragma": ""} +header_4 :{ "Location": "http://www.bonjourmadame.fr/"} +header_5 :{ "Vary": "Accept-Encoding"} +header_6 :{ "Content-Length": "0"} +header_7 :{ "Content-Type": "text/html; charset=UTF-8"} +header_8 :{ "Connection": "keep-alive"} +should_keep_alive :1 +http_major :1 +http_minor :0 + +name :field underscore +raw :"HTTP/1.1 200 OK\r\nDate: Tue, 28 Sep 2010 01:14:13 GMT\r\nServer: Apache\r\nCache-Control: no-cache, must-revalidate\r\nExpires: Mon, 26 Jul 1997 05:00:00 GMT\r\n.et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\nVary: Accept-Encoding\r\n_eep-Alive: timeout=45\r\n_onnection: Keep-Alive\r\nTransfer-Encoding: chunked\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n0\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Date": "Tue, 28 Sep 2010 01:14:13 GMT"} +header_1 :{ "Server": "Apache"} +header_2 :{ "Cache-Control": "no-cache, must-revalidate"} +header_3 :{ "Expires": "Mon, 26 Jul 1997 05:00:00 GMT"} +header_4 :{ ".et-Cookie": "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com"} +header_5 :{ "Vary": "Accept-Encoding"} +header_6 :{ "_eep-Alive": "timeout=45"} +header_7 :{ "_onnection": "Keep-Alive"} +header_8 :{ "Transfer-Encoding": "chunked"} +header_9 :{ "Content-Type": "text/html"} +header_10 :{ "Connection": "close"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :non-ASCII in status line +raw :"HTTP/1.1 500 Oriëntatieprobleem\r\nDate: Fri, 5 Nov 2010 23:07:12 GMT+2\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :500 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Date": "Fri, 5 Nov 2010 23:07:12 GMT+2"} +header_1 :{ "Content-Length": "0"} +header_2 :{ "Connection": "close"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :http version 0.9 +raw :"HTTP/0.9 200 OK\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :0 +http_major :0 +http_minor :9 + +name :neither content-length nor transfer-encoding response +raw :"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nhello world" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"hello world" +body_size :0 +header_0 :{ "Content-Type": "text/plain"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :HTTP/1.0 with keep-alive and EOF-terminated 200 status +raw :"HTTP/1.0 200 OK\r\nConnection: keep-alive\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Connection": "keep-alive"} +should_keep_alive :0 +http_major :1 +http_minor :0 + +name :HTTP/1.0 with keep-alive and a 204 status +raw :"HTTP/1.0 204 No content\r\nConnection: keep-alive\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :204 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Connection": "keep-alive"} +should_keep_alive :1 +http_major :1 +http_minor :0 + +name :HTTP/1.1 with an EOF-terminated 200 status +raw :"HTTP/1.1 200 OK\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :HTTP/1.1 with a 204 status +raw :"HTTP/1.1 204 No content\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :204 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +should_keep_alive :1 +http_major :1 +http_minor :1 + +name :HTTP/1.1 with a 204 status and keep-alive disabled +raw :"HTTP/1.1 204 No content\r\nConnection: close\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :204 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Connection": "close"} +should_keep_alive :0 +http_major :1 +http_minor :1 + +name :HTTP/1.1 with chunked endocing and a 200 response +raw :"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n" +type :HTTP_RESPONSE +method: HTTP_DELETE +status_code :200 +request_path: +request_url : +fragment : +query_string: +body :"" +body_size :0 +header_0 :{ "Transfer-Encoding": "chunked"} +should_keep_alive :1 +http_major :1 +http_minor :1 + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 new file mode 100644 index 0000000..5266159 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tests.utf8 @@ -0,0 +1,17 @@ +name :utf-8 path request +raw :"GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\nHost: github.com\r\n\r\n" +type :HTTP_REQUEST +method: HTTP_GET +status_code :0 +request_path:/δ¶/δt/pope +request_url :/δ¶/δt/pope?q=1#narf +fragment :narf +query_string:q=1 +body :"" +body_size :0 +header_0 :{ "Host": "github.com"} +should_keep_alive :1 +upgrade :0 +http_major :1 +http_minor :1 + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb new file mode 100644 index 0000000..1604890 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb @@ -0,0 +1,6 @@ + +"A".upto("Z") {|c| + puts "public static final byte #{c} = 0x#{c[0].to_s(16)};" +} + + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb new file mode 100644 index 0000000..84f9699 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb @@ -0,0 +1,13 @@ + + +def printbytes str +str.each_byte { |b| + print "0x#{b.to_s(16)}, " +} +end + +if $0 == __FILE__ + printf "static final byte [] #{ARGV[0]} = {\n" + printbytes ARGV[0] + printf "\n};\n" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb new file mode 100644 index 0000000..13960cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb @@ -0,0 +1,15 @@ + + +0.upto(255) { |i| + printf "\n" if i%16 == 0 + printf " " if i%8 == 0 + s = ("" << i) + if s =~ /[A-Z0-9\-_\/ ]/ + print "0x#{i.to_s(16)}," + elsif s =~ /[a-z]/ + print "0x#{s.upcase[0].to_s(16)}," + else + print "0x00," + end + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb new file mode 100644 index 0000000..683adb9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb @@ -0,0 +1,33 @@ + + + + +# name : 200 trailing space on chunked body +# raw : "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n25 \r\nThis is the data in the first chunk\r\n\r\n1C\r\nand this is the second one\r\n\r\n0 \r\n\r\n" +# type : HTTP_RESPONSE +# method: HTTP_DELETE +# status code :200 +# request_path: +# request_url : +# fragment : +# query_string: +# body :"This is the data in the first chunk\r\nand this is the second one\r\n" +# body_size :65 +# header_0 :{ "Content-Type": "text/plain"} +# header_1 :{ "Transfer-Encoding": "chunked"} +# should_keep_alive :1 +# upgrade :0 +# http_major :1 +# http_minor :1 + + +class ParserTest + attr_accessor :name + attr_accessor :raw + attr_accessor :type + attr_accessor :method + attr_accessor :status_code + attr_accessor :request_path + attr_accessor :method +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/AUTHORS b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/AUTHORS new file mode 100644 index 0000000..5323b68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/AUTHORS @@ -0,0 +1,68 @@ +# Authors ordered by first contribution. +Ryan Dahl +Jeremy Hinegardner +Sergey Shepelev +Joe Damato +tomika +Phoenix Sol +Cliff Frey +Ewen Cheslack-Postava +Santiago Gala +Tim Becker +Jeff Terrace +Ben Noordhuis +Nathan Rajlich +Mark Nottingham +Aman Gupta +Tim Becker +Sean Cunningham +Peter Griess +Salman Haq +Cliff Frey +Jon Kolb +Fouad Mardini +Paul Querna +Felix Geisendörfer +koichik +Andre Caron +Ivo Raisr +James McLaughlin +David Gwynne +Thomas LE ROUX +Randy Rizun +Andre Louis Caron +Simon Zimmermann +Erik Dubbelboer +Martell Malone +Bertrand Paquet +BogDan Vatra +Peter Faiman +Corey Richardson +Tóth Tamás +Cam Swords +Chris Dickinson +Uli Köhler +Charlie Somerville +Patrik Stutz +Fedor Indutny +runner +Alexis Campailla +David Wragg +Vinnie Falco +Alex Butum +Rex Feng +Alex Kocharin +Mark Koopman +Helge Heß +Alexis La Goutte +George Miroshnykov +Maciej Małecki +Marc O'Morain +Jeff Pinner +Timothy J Fontaine +Akagi201 +Romain Giraud +Jay Satiro +Arne Steen +Kjell Schubert +Olivier Mengué diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT new file mode 100644 index 0000000..1ec0ab4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/README.md b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/README.md new file mode 100644 index 0000000..b265d71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/README.md @@ -0,0 +1,246 @@ +HTTP Parser +=========== + +[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser) + +This is a parser for HTTP messages written in C. It parses both requests and +responses. The parser is designed to be used in performance HTTP +applications. It does not make any syscalls nor allocations, it does not +buffer data, it can be interrupted at anytime. Depending on your +architecture, it only requires about 40 bytes of data per message +stream (in a web server that is per connection). + +Features: + + * No dependencies + * Handles persistent streams (keep-alive). + * Decodes chunked encoding. + * Upgrade support + * Defends against buffer overflow attacks. + +The parser extracts the following information from HTTP messages: + + * Header fields and values + * Content-Length + * Request method + * Response status code + * Transfer-Encoding + * HTTP version + * Request URL + * Message body + + +Usage +----- + +One `http_parser` object is used per TCP connection. Initialize the struct +using `http_parser_init()` and set the callbacks. That might look something +like this for a request parser: +```c +http_parser_settings settings; +settings.on_url = my_url_callback; +settings.on_header_field = my_header_field_callback; +/* ... */ + +http_parser *parser = malloc(sizeof(http_parser)); +http_parser_init(parser, HTTP_REQUEST); +parser->data = my_socket; +``` + +When data is received on the socket execute the parser and check for errors. + +```c +size_t len = 80*1024, nparsed; +char buf[len]; +ssize_t recved; + +recved = recv(fd, buf, len, 0); + +if (recved < 0) { + /* Handle error. */ +} + +/* Start up / continue the parser. + * Note we pass recved==0 to signal that EOF has been received. + */ +nparsed = http_parser_execute(parser, &settings, buf, recved); + +if (parser->upgrade) { + /* handle new protocol */ +} else if (nparsed != recved) { + /* Handle error. Usually just close the connection. */ +} +``` + +`http_parser` needs to know where the end of the stream is. For example, sometimes +servers send responses without Content-Length and expect the client to +consume input (for the body) until EOF. To tell `http_parser` about EOF, give +`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors +can still be encountered during an EOF, so one must still be prepared +to receive them. + +Scalar valued message information such as `status_code`, `method`, and the +HTTP version are stored in the parser structure. This data is only +temporally stored in `http_parser` and gets reset on each new message. If +this information is needed later, copy it out of the structure during the +`headers_complete` callback. + +The parser decodes the transfer-encoding for both requests and responses +transparently. That is, a chunked encoding is decoded before being sent to +the on_body callback. + + +The Special Problem of Upgrade +------------------------------ + +`http_parser` supports upgrading the connection to a different protocol. An +increasingly common example of this is the WebSocket protocol which sends +a request like + + GET /demo HTTP/1.1 + Upgrade: WebSocket + Connection: Upgrade + Host: example.com + Origin: http://example.com + WebSocket-Protocol: sample + +followed by non-HTTP data. + +(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the +WebSocket protocol.) + +To support this, the parser will treat this as a normal HTTP message without a +body, issuing both on_headers_complete and on_message_complete callbacks. However +http_parser_execute() will stop parsing at the end of the headers and return. + +The user is expected to check if `parser->upgrade` has been set to 1 after +`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied +offset by the return value of `http_parser_execute()`. + + +Callbacks +--------- + +During the `http_parser_execute()` call, the callbacks set in +`http_parser_settings` will be executed. The parser maintains state and +never looks behind, so buffering the data is not necessary. If you need to +save certain data for later usage, you can do that from the callbacks. + +There are two types of callbacks: + +* notification `typedef int (*http_cb) (http_parser*);` + Callbacks: on_message_begin, on_headers_complete, on_message_complete. +* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);` + Callbacks: (requests only) on_url, + (common) on_header_field, on_header_value, on_body; + +Callbacks must return 0 on success. Returning a non-zero value indicates +error to the parser, making it exit immediately. + +For cases where it is necessary to pass local information to/from a callback, +the `http_parser` object's `data` field can be used. +An example of such a case is when using threads to handle a socket connection, +parse a request, and then give a response over that socket. By instantiation +of a thread-local struct containing relevant data (e.g. accepted socket, +allocated memory for callbacks to write into, etc), a parser's callbacks are +able to communicate data between the scope of the thread and the scope of the +callback in a threadsafe manner. This allows `http_parser` to be used in +multi-threaded contexts. + +Example: +```c + typedef struct { + socket_t sock; + void* buffer; + int buf_len; + } custom_data_t; + + +int my_url_callback(http_parser* parser, const char *at, size_t length) { + /* access to thread local custom_data_t struct. + Use this access save parsed data for later use into thread local + buffer, or communicate over socket + */ + parser->data; + ... + return 0; +} + +... + +void http_parser_thread(socket_t sock) { + int nparsed = 0; + /* allocate memory for user data */ + custom_data_t *my_data = malloc(sizeof(custom_data_t)); + + /* some information for use by callbacks. + * achieves thread -> callback information flow */ + my_data->sock = sock; + + /* instantiate a thread-local parser */ + http_parser *parser = malloc(sizeof(http_parser)); + http_parser_init(parser, HTTP_REQUEST); /* initialise parser */ + /* this custom data reference is accessible through the reference to the + parser supplied to callback functions */ + parser->data = my_data; + + http_parser_settings settings; /* set up callbacks */ + settings.on_url = my_url_callback; + + /* execute parser */ + nparsed = http_parser_execute(parser, &settings, buf, recved); + + ... + /* parsed information copied from callback. + can now perform action on data copied into thread-local memory from callbacks. + achieves callback -> thread information flow */ + my_data->buffer; + ... +} + +``` + +In case you parse HTTP message in chunks (i.e. `read()` request line +from socket, parse, read half headers, parse, etc) your data callbacks +may be called more than once. `http_parser` guarantees that data pointer is only +valid for the lifetime of callback. You can also `read()` into a heap allocated +buffer to avoid copying memory around if this fits your application. + +Reading headers may be a tricky task if you read/parse headers partially. +Basically, you need to remember whether last header callback was field or value +and apply the following logic: + + (on_header_field and on_header_value shortened to on_h_*) + ------------------------ ------------ -------------------------------------------- + | State (prev. callback) | Callback | Description/action | + ------------------------ ------------ -------------------------------------------- + | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | + | | | into it | + ------------------------ ------------ -------------------------------------------- + | value | on_h_field | New header started. | + | | | Copy current name,value buffers to headers | + | | | list and allocate new buffer for new name | + ------------------------ ------------ -------------------------------------------- + | field | on_h_field | Previous name continues. Reallocate name | + | | | buffer and append callback data to it | + ------------------------ ------------ -------------------------------------------- + | field | on_h_value | Value for current header started. Allocate | + | | | new buffer and copy callback data to it | + ------------------------ ------------ -------------------------------------------- + | value | on_h_value | Value continues. Reallocate value buffer | + | | | and append callback data to it | + ------------------------ ------------ -------------------------------------------- + + +Parsing URLs +------------ + +A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`. +Users of this library may wish to use it to parse URLs constructed from +consecutive `on_url` callbacks. + +See examples of reading in headers: + +* [partial example](http://gist.github.com/155877) in C +* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C +* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/bench.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/bench.c new file mode 100644 index 0000000..678f555 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/bench.c @@ -0,0 +1,128 @@ +/* Copyright Fedor Indutny. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "http_parser.h" +#include +#include +#include +#include +#include + +/* 8 gb */ +static const int64_t kBytes = 8LL << 30; + +static const char data[] = + "POST /joyent/http-parser HTTP/1.1\r\n" + "Host: github.com\r\n" + "DNT: 1\r\n" + "Accept-Encoding: gzip, deflate, sdch\r\n" + "Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n" + "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/39.0.2171.65 Safari/537.36\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9," + "image/webp,*/*;q=0.8\r\n" + "Referer: https://github.com/joyent/http-parser\r\n" + "Connection: keep-alive\r\n" + "Transfer-Encoding: chunked\r\n" + "Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n"; +static const size_t data_len = sizeof(data) - 1; + +static int on_info(http_parser* p) { + return 0; +} + + +static int on_data(http_parser* p, const char *at, size_t length) { + return 0; +} + +static http_parser_settings settings = { + .on_message_begin = on_info, + .on_headers_complete = on_info, + .on_message_complete = on_info, + .on_header_field = on_data, + .on_header_value = on_data, + .on_url = on_data, + .on_status = on_data, + .on_body = on_data +}; + +int bench(int iter_count, int silent) { + struct http_parser parser; + int i; + int err; + struct timeval start; + struct timeval end; + + if (!silent) { + err = gettimeofday(&start, NULL); + assert(err == 0); + } + + fprintf(stderr, "req_len=%d\n", (int) data_len); + for (i = 0; i < iter_count; i++) { + size_t parsed; + http_parser_init(&parser, HTTP_REQUEST); + + parsed = http_parser_execute(&parser, &settings, data, data_len); + assert(parsed == data_len); + } + + if (!silent) { + double elapsed; + double bw; + double total; + + err = gettimeofday(&end, NULL); + assert(err == 0); + + fprintf(stdout, "Benchmark result:\n"); + + elapsed = (double) (end.tv_sec - start.tv_sec) + + (end.tv_usec - start.tv_usec) * 1e-6f; + + total = (double) iter_count * data_len; + bw = (double) total / elapsed; + + fprintf(stdout, "%.2f mb | %.2f mb/s | %.2f req/sec | %.2f s\n", + (double) total / (1024 * 1024), + bw / (1024 * 1024), + (double) iter_count / elapsed, + elapsed); + + fflush(stdout); + } + + return 0; +} + +int main(int argc, char** argv) { + int64_t iterations; + + iterations = kBytes / (int64_t) data_len; + if (argc == 2 && strcmp(argv[1], "infinite") == 0) { + for (;;) + bench(iterations, 1); + return 0; + } else { + return bench(iterations, 0); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/parsertrace.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/parsertrace.c new file mode 100644 index 0000000..3daa7f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/parsertrace.c @@ -0,0 +1,157 @@ +/* Copyright Joyent, Inc. and other Node contributors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Dump what the parser finds to stdout as it happen */ + +#include "http_parser.h" +#include +#include +#include + +int on_message_begin(http_parser* _) { + (void)_; + printf("\n***MESSAGE BEGIN***\n\n"); + return 0; +} + +int on_headers_complete(http_parser* _) { + (void)_; + printf("\n***HEADERS COMPLETE***\n\n"); + return 0; +} + +int on_message_complete(http_parser* _) { + (void)_; + printf("\n***MESSAGE COMPLETE***\n\n"); + return 0; +} + +int on_url(http_parser* _, const char* at, size_t length) { + (void)_; + printf("Url: %.*s\n", (int)length, at); + return 0; +} + +int on_header_field(http_parser* _, const char* at, size_t length) { + (void)_; + printf("Header field: %.*s\n", (int)length, at); + return 0; +} + +int on_header_value(http_parser* _, const char* at, size_t length) { + (void)_; + printf("Header value: %.*s\n", (int)length, at); + return 0; +} + +int on_body(http_parser* _, const char* at, size_t length) { + (void)_; + printf("Body: %.*s\n", (int)length, at); + return 0; +} + +void usage(const char* name) { + fprintf(stderr, + "Usage: %s $type $filename\n" + " type: -x, where x is one of {r,b,q}\n" + " parses file as a Response, reQuest, or Both\n", + name); + exit(EXIT_FAILURE); +} + +int main(int argc, char* argv[]) { + enum http_parser_type file_type; + + if (argc != 3) { + usage(argv[0]); + } + + char* type = argv[1]; + if (type[0] != '-') { + usage(argv[0]); + } + + switch (type[1]) { + /* in the case of "-", type[1] will be NUL */ + case 'r': + file_type = HTTP_RESPONSE; + break; + case 'q': + file_type = HTTP_REQUEST; + break; + case 'b': + file_type = HTTP_BOTH; + break; + default: + usage(argv[0]); + } + + char* filename = argv[2]; + FILE* file = fopen(filename, "r"); + if (file == NULL) { + perror("fopen"); + goto fail; + } + + fseek(file, 0, SEEK_END); + long file_length = ftell(file); + if (file_length == -1) { + perror("ftell"); + goto fail; + } + fseek(file, 0, SEEK_SET); + + char* data = malloc(file_length); + if (fread(data, 1, file_length, file) != (size_t)file_length) { + fprintf(stderr, "couldn't read entire file\n"); + free(data); + goto fail; + } + + http_parser_settings settings; + memset(&settings, 0, sizeof(settings)); + settings.on_message_begin = on_message_begin; + settings.on_url = on_url; + settings.on_header_field = on_header_field; + settings.on_header_value = on_header_value; + settings.on_headers_complete = on_headers_complete; + settings.on_body = on_body; + settings.on_message_complete = on_message_complete; + + http_parser parser; + http_parser_init(&parser, file_type); + size_t nparsed = http_parser_execute(&parser, &settings, data, file_length); + free(data); + + if (nparsed != (size_t)file_length) { + fprintf(stderr, + "Error: %s (%s)\n", + http_errno_description(HTTP_PARSER_ERRNO(&parser)), + http_errno_name(HTTP_PARSER_ERRNO(&parser))); + goto fail; + } + + return EXIT_SUCCESS; + +fail: + fclose(file); + return EXIT_FAILURE; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/url_parser.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/url_parser.c new file mode 100644 index 0000000..f235bed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/contrib/url_parser.c @@ -0,0 +1,47 @@ +#include "http_parser.h" +#include +#include + +void +dump_url (const char *url, const struct http_parser_url *u) +{ + unsigned int i; + + printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port); + for (i = 0; i < UF_MAX; i++) { + if ((u->field_set & (1 << i)) == 0) { + printf("\tfield_data[%u]: unset\n", i); + continue; + } + + printf("\tfield_data[%u]: off: %u, len: %u, part: %.*s\n", + i, + u->field_data[i].off, + u->field_data[i].len, + u->field_data[i].len, + url + u->field_data[i].off); + } +} + +int main(int argc, char ** argv) { + struct http_parser_url u; + int len, connect, result; + + if (argc != 3) { + printf("Syntax : %s connect|get url\n", argv[0]); + return 1; + } + len = strlen(argv[2]); + connect = strcmp("connect", argv[1]) == 0 ? 1 : 0; + printf("Parsing %s, connect %d\n", argv[2], connect); + + http_parser_url_init(&u); + result = http_parser_parse_url(argv[2], len, connect, &u); + if (result != 0) { + printf("Parse error : %d\n", result); + return result; + } + printf("Parse ok, result : \n"); + dump_url(argv[2], &u); + return 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.c new file mode 100644 index 0000000..f9991c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.c @@ -0,0 +1,2440 @@ +/* Copyright Joyent, Inc. and other Node contributors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "http_parser.h" +#include +#include +#include +#include +#include + +#ifndef ULLONG_MAX +# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ +#endif + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifndef BIT_AT +# define BIT_AT(a, i) \ + (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ + (1 << ((unsigned int) (i) & 7)))) +#endif + +#ifndef ELEM_AT +# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) +#endif + +#define SET_ERRNO(e) \ +do { \ + parser->http_errno = (e); \ +} while(0) + +#define CURRENT_STATE() p_state +#define UPDATE_STATE(V) p_state = (enum state) (V); +#define RETURN(V) \ +do { \ + parser->state = CURRENT_STATE(); \ + return (V); \ +} while (0); +#define REEXECUTE() \ + goto reexecute; \ + + +#ifdef __GNUC__ +# define LIKELY(X) __builtin_expect(!!(X), 1) +# define UNLIKELY(X) __builtin_expect(!!(X), 0) +#else +# define LIKELY(X) (X) +# define UNLIKELY(X) (X) +#endif + + +/* Run the notify callback FOR, returning ER if it fails */ +#define CALLBACK_NOTIFY_(FOR, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ +} while (0) + +/* Run the notify callback FOR and consume the current byte */ +#define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) + +/* Run the notify callback FOR and don't consume the current byte */ +#define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) + +/* Run data callback FOR with LEN bytes, returning ER if it fails */ +#define CALLBACK_DATA_(FOR, LEN, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (FOR##_mark) { \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != \ + settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ + FOR##_mark = NULL; \ + } \ +} while (0) + +/* Run the data callback FOR and consume the current byte */ +#define CALLBACK_DATA(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) + +/* Run the data callback FOR and don't consume the current byte */ +#define CALLBACK_DATA_NOADVANCE(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) + +/* Set the mark FOR; non-destructive if mark is already set */ +#define MARK(FOR) \ +do { \ + if (!FOR##_mark) { \ + FOR##_mark = p; \ + } \ +} while (0) + +/* Don't allow the total size of the HTTP headers (including the status + * line) to exceed HTTP_MAX_HEADER_SIZE. This check is here to protect + * embedders against denial-of-service attacks where the attacker feeds + * us a never-ending header that the embedder keeps buffering. + * + * This check is arguably the responsibility of embedders but we're doing + * it on the embedder's behalf because most won't bother and this way we + * make the web a little safer. HTTP_MAX_HEADER_SIZE is still far bigger + * than any reasonable request or response so this should never affect + * day-to-day operation. + */ +#define COUNT_HEADER_SIZE(V) \ +do { \ + parser->nread += (V); \ + if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \ + SET_ERRNO(HPE_HEADER_OVERFLOW); \ + goto error; \ + } \ +} while (0) + + +#define PROXY_CONNECTION "proxy-connection" +#define CONNECTION "connection" +#define CONTENT_LENGTH "content-length" +#define TRANSFER_ENCODING "transfer-encoding" +#define UPGRADE "upgrade" +#define CHUNKED "chunked" +#define KEEP_ALIVE "keep-alive" +#define CLOSE "close" + + +static const char *method_strings[] = + { +#define XX(num, name, string) #string, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +static const char tokens[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, '!', 0, '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', 0, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'x', 'y', 'z', 0, 0, 0, '^', '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'x', 'y', 'z', 0, '|', 0, '~', 0 }; + + +static const int8_t unhex[256] = + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + + +#if HTTP_PARSER_STRICT +# define T(v) 0 +#else +# define T(v) v +#endif + + +static const uint8_t normal_url_char[32] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; + +#undef T + +enum state + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_http_major + , s_res_http_dot + , s_res_http_minor + , s_res_http_end + , s_res_first_status_code + , s_res_status_code + , s_res_status_start + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_server_start + , s_req_server + , s_req_server_with_at + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_http_major + , s_req_http_dot + , s_req_http_minor + , s_req_http_end + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_discard_ws + , s_header_value_discard_ws_almost_done + , s_header_value_discard_lws + , s_header_value_start + , s_header_value + , s_header_value_lws + + , s_header_almost_done + + , s_chunk_size_start + , s_chunk_size + , s_chunk_parameters + , s_chunk_size_almost_done + + , s_headers_almost_done + , s_headers_done + + /* Important: 's_headers_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + + , s_message_done + }; + + +#define PARSING_HEADER(state) (state <= s_headers_done) + + +enum header_states + { h_general = 0 + , h_C + , h_CO + , h_CON + + , h_matching_connection + , h_matching_proxy_connection + , h_matching_content_length + , h_matching_transfer_encoding + , h_matching_upgrade + + , h_connection + , h_content_length + , h_content_length_num + , h_content_length_ws + , h_transfer_encoding + , h_upgrade + + , h_matching_transfer_encoding_chunked + , h_matching_connection_token_start + , h_matching_connection_keep_alive + , h_matching_connection_close + , h_matching_connection_upgrade + , h_matching_connection_token + + , h_transfer_encoding_chunked + , h_connection_keep_alive + , h_connection_close + , h_connection_upgrade + }; + +enum http_host_state + { + s_http_host_dead = 1 + , s_http_userinfo_start + , s_http_userinfo + , s_http_host_start + , s_http_host_v6_start + , s_http_host + , s_http_host_v6 + , s_http_host_v6_end + , s_http_host_v6_zone_start + , s_http_host_v6_zone + , s_http_host_port_start + , s_http_host_port +}; + +/* Macros for character classes; depends on strict-mode */ +#define CR '\r' +#define LF '\n' +#define LOWER(c) (unsigned char)(c | 0x20) +#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') +#define IS_NUM(c) ((c) >= '0' && (c) <= '9') +#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) +#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) +#define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ + (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ + (c) == ')') +#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ + (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ + (c) == '$' || (c) == ',') + +#define STRICT_TOKEN(c) (tokens[(unsigned char)c]) + +#if HTTP_PARSER_STRICT +#define TOKEN(c) (tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) +#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') +#else +#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) \ + (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) +#define IS_HOST_CHAR(c) \ + (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') +#endif + +/** + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + **/ +#define IS_HEADER_CHAR(ch) \ + (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127)) + +#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) + + +#if HTTP_PARSER_STRICT +# define STRICT_CHECK(cond) \ +do { \ + if (cond) { \ + SET_ERRNO(HPE_STRICT); \ + goto error; \ + } \ +} while (0) +# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) +#else +# define STRICT_CHECK(cond) +# define NEW_MESSAGE() start_state +#endif + + +/* Map errno values to strings for human-readable output */ +#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, +static struct { + const char *name; + const char *description; +} http_strerror_tab[] = { + HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) +}; +#undef HTTP_STRERROR_GEN + +int http_message_needs_eof(const http_parser *parser); + +/* Our URL parser. + * + * This is designed to be shared by http_parser_execute() for URL validation, + * hence it has a state transition + byte-for-byte interface. In addition, it + * is meant to be embedded in http_parser_parse_url(), which does the dirty + * work of turning state transitions URL components for its API. + * + * This function should only be invoked with non-space characters. It is + * assumed that the caller cares about (and can detect) the transition between + * URL and non-URL states by looking for these. + */ +static enum state +parse_url_char(enum state s, const char ch) +{ + if (ch == ' ' || ch == '\r' || ch == '\n') { + return s_dead; + } + +#if HTTP_PARSER_STRICT + if (ch == '\t' || ch == '\f') { + return s_dead; + } +#endif + + switch (s) { + case s_req_spaces_before_url: + /* Proxied requests are followed by scheme of an absolute URI (alpha). + * All methods except CONNECT are followed by '/' or '*'. + */ + + if (ch == '/' || ch == '*') { + return s_req_path; + } + + if (IS_ALPHA(ch)) { + return s_req_schema; + } + + break; + + case s_req_schema: + if (IS_ALPHA(ch)) { + return s; + } + + if (ch == ':') { + return s_req_schema_slash; + } + + break; + + case s_req_schema_slash: + if (ch == '/') { + return s_req_schema_slash_slash; + } + + break; + + case s_req_schema_slash_slash: + if (ch == '/') { + return s_req_server_start; + } + + break; + + case s_req_server_with_at: + if (ch == '@') { + return s_dead; + } + + /* FALLTHROUGH */ + case s_req_server_start: + case s_req_server: + if (ch == '/') { + return s_req_path; + } + + if (ch == '?') { + return s_req_query_string_start; + } + + if (ch == '@') { + return s_req_server_with_at; + } + + if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { + return s_req_server; + } + + break; + + case s_req_path: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + return s_req_query_string_start; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_query_string_start: + case s_req_query_string: + if (IS_URL_CHAR(ch)) { + return s_req_query_string; + } + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + return s_req_query_string; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_fragment_start: + if (IS_URL_CHAR(ch)) { + return s_req_fragment; + } + + switch (ch) { + case '?': + return s_req_fragment; + + case '#': + return s; + } + + break; + + case s_req_fragment: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + case '#': + return s; + } + + break; + + default: + break; + } + + /* We should never fall out of the switch above unless there's an error */ + return s_dead; +} + +size_t http_parser_execute (http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len) +{ + char c, ch; + int8_t unhex_val; + const char *p = data; + const char *header_field_mark = 0; + const char *header_value_mark = 0; + const char *url_mark = 0; + const char *body_mark = 0; + const char *status_mark = 0; + enum state p_state = (enum state) parser->state; + const unsigned int lenient = parser->lenient_http_headers; + + /* We're in an error state. Don't bother doing anything. */ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return 0; + } + + if (len == 0) { + switch (CURRENT_STATE()) { + case s_body_identity_eof: + /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if + * we got paused. + */ + CALLBACK_NOTIFY_NOADVANCE(message_complete); + return 0; + + case s_dead: + case s_start_req_or_res: + case s_start_res: + case s_start_req: + return 0; + + default: + SET_ERRNO(HPE_INVALID_EOF_STATE); + return 1; + } + } + + + if (CURRENT_STATE() == s_header_field) + header_field_mark = data; + if (CURRENT_STATE() == s_header_value) + header_value_mark = data; + switch (CURRENT_STATE()) { + case s_req_path: + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_server: + case s_req_server_with_at: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + url_mark = data; + break; + case s_res_status: + status_mark = data; + break; + default: + break; + } + + for (p=data; p != data + len; p++) { + ch = *p; + + if (PARSING_HEADER(CURRENT_STATE())) + COUNT_HEADER_SIZE(1); + +reexecute: + switch (CURRENT_STATE()) { + + case s_dead: + /* this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + if (LIKELY(ch == CR || ch == LF)) + break; + + SET_ERRNO(HPE_CLOSED_CONNECTION); + goto error; + + case s_start_req_or_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (ch == 'H') { + UPDATE_STATE(s_res_or_resp_H); + + CALLBACK_NOTIFY(message_begin); + } else { + parser->type = HTTP_REQUEST; + UPDATE_STATE(s_start_req); + REEXECUTE(); + } + + break; + } + + case s_res_or_resp_H: + if (ch == 'T') { + parser->type = HTTP_RESPONSE; + UPDATE_STATE(s_res_HT); + } else { + if (UNLIKELY(ch != 'E')) { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + parser->type = HTTP_REQUEST; + parser->method = HTTP_HEAD; + parser->index = 2; + UPDATE_STATE(s_req_method); + } + break; + + case s_start_res: + { + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + switch (ch) { + case 'H': + UPDATE_STATE(s_res_H); + break; + + case CR: + case LF: + break; + + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + CALLBACK_NOTIFY(message_begin); + break; + } + + case s_res_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HT); + break; + + case s_res_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HTT); + break; + + case s_res_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_res_HTTP); + break; + + case s_res_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_res_http_major); + break; + + case s_res_http_major: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_res_http_dot); + break; + + case s_res_http_dot: + { + if (UNLIKELY(ch != '.')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + UPDATE_STATE(s_res_http_minor); + break; + } + + case s_res_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_res_http_end); + break; + + case s_res_http_end: + { + if (UNLIKELY(ch != ' ')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + UPDATE_STATE(s_res_first_status_code); + break; + } + + case s_res_first_status_code: + { + if (!IS_NUM(ch)) { + if (ch == ' ') { + break; + } + + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + parser->status_code = ch - '0'; + UPDATE_STATE(s_res_status_code); + break; + } + + case s_res_status_code: + { + if (!IS_NUM(ch)) { + switch (ch) { + case ' ': + UPDATE_STATE(s_res_status_start); + break; + case CR: + case LF: + UPDATE_STATE(s_res_status_start); + REEXECUTE(); + break; + default: + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + break; + } + + parser->status_code *= 10; + parser->status_code += ch - '0'; + + if (UNLIKELY(parser->status_code > 999)) { + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + + break; + } + + case s_res_status_start: + { + MARK(status); + UPDATE_STATE(s_res_status); + parser->index = 0; + + if (ch == CR || ch == LF) + REEXECUTE(); + + break; + } + + case s_res_status: + if (ch == CR) { + UPDATE_STATE(s_res_line_almost_done); + CALLBACK_DATA(status); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA(status); + break; + } + + break; + + case s_res_line_almost_done: + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_field_start); + break; + + case s_start_req: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (UNLIKELY(!IS_ALPHA(ch))) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + parser->method = (enum http_method) 0; + parser->index = 1; + switch (ch) { + case 'A': parser->method = HTTP_ACL; break; + case 'B': parser->method = HTTP_BIND; break; + case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; + case 'D': parser->method = HTTP_DELETE; break; + case 'G': parser->method = HTTP_GET; break; + case 'H': parser->method = HTTP_HEAD; break; + case 'L': parser->method = HTTP_LOCK; /* or LINK */ break; + case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; + case 'N': parser->method = HTTP_NOTIFY; break; + case 'O': parser->method = HTTP_OPTIONS; break; + case 'P': parser->method = HTTP_POST; + /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ + break; + case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break; + case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH, SOURCE */ break; + case 'T': parser->method = HTTP_TRACE; break; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break; + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + UPDATE_STATE(s_req_method); + + CALLBACK_NOTIFY(message_begin); + + break; + } + + case s_req_method: + { + const char *matcher; + if (UNLIKELY(ch == '\0')) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + matcher = method_strings[parser->method]; + if (ch == ' ' && matcher[parser->index] == '\0') { + UPDATE_STATE(s_req_spaces_before_url); + } else if (ch == matcher[parser->index]) { + ; /* nada */ + } else if ((ch >= 'A' && ch <= 'Z') || ch == '-') { + + switch (parser->method << 16 | parser->index << 8 | ch) { +#define XX(meth, pos, ch, new_meth) \ + case (HTTP_##meth << 16 | pos << 8 | ch): \ + parser->method = HTTP_##new_meth; break; + + XX(POST, 1, 'U', PUT) + XX(POST, 1, 'A', PATCH) + XX(POST, 1, 'R', PROPFIND) + XX(PUT, 2, 'R', PURGE) + XX(CONNECT, 1, 'H', CHECKOUT) + XX(CONNECT, 2, 'P', COPY) + XX(MKCOL, 1, 'O', MOVE) + XX(MKCOL, 1, 'E', MERGE) + XX(MKCOL, 1, '-', MSEARCH) + XX(MKCOL, 2, 'A', MKACTIVITY) + XX(MKCOL, 3, 'A', MKCALENDAR) + XX(SUBSCRIBE, 1, 'E', SEARCH) + XX(SUBSCRIBE, 1, 'O', SOURCE) + XX(REPORT, 2, 'B', REBIND) + XX(PROPFIND, 4, 'P', PROPPATCH) + XX(LOCK, 1, 'I', LINK) + XX(UNLOCK, 2, 'S', UNSUBSCRIBE) + XX(UNLOCK, 2, 'B', UNBIND) + XX(UNLOCK, 3, 'I', UNLINK) +#undef XX + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + ++parser->index; + break; + } + + case s_req_spaces_before_url: + { + if (ch == ' ') break; + + MARK(url); + if (parser->method == HTTP_CONNECT) { + UPDATE_STATE(s_req_server_start); + } + + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + + break; + } + + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + { + switch (ch) { + /* No whitespace allowed here */ + case ' ': + case CR: + case LF: + SET_ERRNO(HPE_INVALID_URL); + goto error; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + + break; + } + + case s_req_server: + case s_req_server_with_at: + case s_req_path: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + { + switch (ch) { + case ' ': + UPDATE_STATE(s_req_http_start); + CALLBACK_DATA(url); + break; + case CR: + case LF: + parser->http_major = 0; + parser->http_minor = 9; + UPDATE_STATE((ch == CR) ? + s_req_line_almost_done : + s_header_field_start); + CALLBACK_DATA(url); + break; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + break; + } + + case s_req_http_start: + switch (ch) { + case 'H': + UPDATE_STATE(s_req_http_H); + break; + case ' ': + break; + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + break; + + case s_req_http_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HT); + break; + + case s_req_http_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HTT); + break; + + case s_req_http_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_req_http_HTTP); + break; + + case s_req_http_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_req_http_major); + break; + + case s_req_http_major: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_req_http_dot); + break; + + case s_req_http_dot: + { + if (UNLIKELY(ch != '.')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + UPDATE_STATE(s_req_http_minor); + break; + } + + case s_req_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_req_http_end); + break; + + case s_req_http_end: + { + if (ch == CR) { + UPDATE_STATE(s_req_line_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + break; + } + + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + break; + } + + /* end of request line */ + case s_req_line_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_field_start); + break; + } + + case s_header_field_start: + { + if (ch == CR) { + UPDATE_STATE(s_headers_almost_done); + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + UPDATE_STATE(s_headers_almost_done); + REEXECUTE(); + } + + c = TOKEN(ch); + + if (UNLIKELY(!c)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + MARK(header_field); + + parser->index = 0; + UPDATE_STATE(s_header_field); + + switch (c) { + case 'c': + parser->header_state = h_C; + break; + + case 'p': + parser->header_state = h_matching_proxy_connection; + break; + + case 't': + parser->header_state = h_matching_transfer_encoding; + break; + + case 'u': + parser->header_state = h_matching_upgrade; + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_field: + { + const char* start = p; + for (; p != data + len; p++) { + ch = *p; + c = TOKEN(ch); + + if (!c) + break; + + switch (parser->header_state) { + case h_general: + break; + + case h_C: + parser->index++; + parser->header_state = (c == 'o' ? h_CO : h_general); + break; + + case h_CO: + parser->index++; + parser->header_state = (c == 'n' ? h_CON : h_general); + break; + + case h_CON: + parser->index++; + switch (c) { + case 'n': + parser->header_state = h_matching_connection; + break; + case 't': + parser->header_state = h_matching_content_length; + break; + default: + parser->header_state = h_general; + break; + } + break; + + /* connection */ + + case h_matching_connection: + parser->index++; + if (parser->index > sizeof(CONNECTION)-1 + || c != CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* proxy-connection */ + + case h_matching_proxy_connection: + parser->index++; + if (parser->index > sizeof(PROXY_CONNECTION)-1 + || c != PROXY_CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* content-length */ + + case h_matching_content_length: + parser->index++; + if (parser->index > sizeof(CONTENT_LENGTH)-1 + || c != CONTENT_LENGTH[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { + parser->header_state = h_content_length; + } + break; + + /* transfer-encoding */ + + case h_matching_transfer_encoding: + parser->index++; + if (parser->index > sizeof(TRANSFER_ENCODING)-1 + || c != TRANSFER_ENCODING[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { + parser->header_state = h_transfer_encoding; + } + break; + + /* upgrade */ + + case h_matching_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE)-1 + || c != UPGRADE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(UPGRADE)-2) { + parser->header_state = h_upgrade; + } + break; + + case h_connection: + case h_content_length: + case h_transfer_encoding: + case h_upgrade: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + assert(0 && "Unknown header_state"); + break; + } + } + + COUNT_HEADER_SIZE(p - start); + + if (p == data + len) { + --p; + break; + } + + if (ch == ':') { + UPDATE_STATE(s_header_value_discard_ws); + CALLBACK_DATA(header_field); + break; + } + + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + case s_header_value_discard_ws: + if (ch == ' ' || ch == '\t') break; + + if (ch == CR) { + UPDATE_STATE(s_header_value_discard_ws_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + /* FALLTHROUGH */ + + case s_header_value_start: + { + MARK(header_value); + + UPDATE_STATE(s_header_value); + parser->index = 0; + + c = LOWER(ch); + + switch (parser->header_state) { + case h_upgrade: + parser->flags |= F_UPGRADE; + parser->header_state = h_general; + break; + + case h_transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + parser->header_state = h_matching_transfer_encoding_chunked; + } else { + parser->header_state = h_general; + } + break; + + case h_content_length: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + if (parser->flags & F_CONTENTLENGTH) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + parser->flags |= F_CONTENTLENGTH; + parser->content_length = ch - '0'; + parser->header_state = h_content_length_num; + break; + + case h_connection: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + parser->header_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + parser->header_state = h_matching_connection_close; + } else if (c == 'u') { + parser->header_state = h_matching_connection_upgrade; + } else { + parser->header_state = h_matching_connection_token; + } + break; + + /* Multi-value `Connection` header */ + case h_matching_connection_token_start: + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_value: + { + const char* start = p; + enum header_states h_state = (enum header_states) parser->header_state; + for (; p != data + len; p++) { + ch = *p; + if (ch == CR) { + UPDATE_STATE(s_header_almost_done); + parser->header_state = h_state; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_almost_done); + COUNT_HEADER_SIZE(p - start); + parser->header_state = h_state; + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + + if (!lenient && !IS_HEADER_CHAR(ch)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + c = LOWER(ch); + + switch (h_state) { + case h_general: + { + const char* p_cr; + const char* p_lf; + size_t limit = data + len - p; + + limit = MIN(limit, HTTP_MAX_HEADER_SIZE); + + p_cr = (const char*) memchr(p, CR, limit); + p_lf = (const char*) memchr(p, LF, limit); + if (p_cr != NULL) { + if (p_lf != NULL && p_cr >= p_lf) + p = p_lf; + else + p = p_cr; + } else if (UNLIKELY(p_lf != NULL)) { + p = p_lf; + } else { + p = data + len; + } + --p; + + break; + } + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + if (ch == ' ') break; + h_state = h_content_length_num; + /* FALLTHROUGH */ + + case h_content_length_num: + { + uint64_t t; + + if (ch == ' ') { + h_state = h_content_length_ws; + break; + } + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + t = parser->content_length; + t *= 10; + t += ch - '0'; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + parser->content_length = t; + break; + } + + case h_content_length_ws: + if (ch == ' ') break; + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_chunked: + parser->index++; + if (parser->index > sizeof(CHUNKED)-1 + || c != CHUNKED[parser->index]) { + h_state = h_general; + } else if (parser->index == sizeof(CHUNKED)-2) { + h_state = h_transfer_encoding_chunked; + } + break; + + case h_matching_connection_token_start: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + h_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + h_state = h_matching_connection_close; + } else if (c == 'u') { + h_state = h_matching_connection_upgrade; + } else if (STRICT_TOKEN(c)) { + h_state = h_matching_connection_token; + } else if (c == ' ' || c == '\t') { + /* Skip lws */ + } else { + h_state = h_general; + } + break; + + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + parser->index++; + if (parser->index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(KEEP_ALIVE)-2) { + h_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + parser->index++; + if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(CLOSE)-2) { + h_state = h_connection_close; + } + break; + + /* looking for 'Connection: upgrade' */ + case h_matching_connection_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE) - 1 || + c != UPGRADE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(UPGRADE)-2) { + h_state = h_connection_upgrade; + } + break; + + case h_matching_connection_token: + if (ch == ',') { + h_state = h_matching_connection_token_start; + parser->index = 0; + } + break; + + case h_transfer_encoding_chunked: + if (ch != ' ') h_state = h_general; + break; + + case h_connection_keep_alive: + case h_connection_close: + case h_connection_upgrade: + if (ch == ',') { + if (h_state == h_connection_keep_alive) { + parser->flags |= F_CONNECTION_KEEP_ALIVE; + } else if (h_state == h_connection_close) { + parser->flags |= F_CONNECTION_CLOSE; + } else if (h_state == h_connection_upgrade) { + parser->flags |= F_CONNECTION_UPGRADE; + } + h_state = h_matching_connection_token_start; + parser->index = 0; + } else if (ch != ' ') { + h_state = h_matching_connection_token; + } + break; + + default: + UPDATE_STATE(s_header_value); + h_state = h_general; + break; + } + } + parser->header_state = h_state; + + COUNT_HEADER_SIZE(p - start); + + if (p == data + len) + --p; + break; + } + + case s_header_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_value_lws); + break; + } + + case s_header_value_lws: + { + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_start); + REEXECUTE(); + } + + /* finished the header */ + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + default: + break; + } + + UPDATE_STATE(s_header_field_start); + REEXECUTE(); + } + + case s_header_value_discard_ws_almost_done: + { + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + case s_header_value_discard_lws: + { + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_discard_ws); + break; + } else { + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + default: + break; + } + + /* header value was empty */ + MARK(header_value); + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + } + + case s_headers_almost_done: + { + STRICT_CHECK(ch != LF); + + if (parser->flags & F_TRAILING) { + /* End of a chunked request */ + UPDATE_STATE(s_message_done); + CALLBACK_NOTIFY_NOADVANCE(chunk_complete); + REEXECUTE(); + } + + /* Cannot use chunked encoding and a content-length header together + per the HTTP specification. */ + if ((parser->flags & F_CHUNKED) && + (parser->flags & F_CONTENTLENGTH)) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + UPDATE_STATE(s_headers_done); + + /* Set this here so that on_headers_complete() callbacks can see it */ + if ((parser->flags & F_UPGRADE) && + (parser->flags & F_CONNECTION_UPGRADE)) { + /* For responses, "Upgrade: foo" and "Connection: upgrade" are + * mandatory only when it is a 101 Switching Protocols response, + * otherwise it is purely informational, to announce support. + */ + parser->upgrade = + (parser->type == HTTP_REQUEST || parser->status_code == 101); + } else { + parser->upgrade = (parser->method == HTTP_CONNECT); + } + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + * + * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so + * we have to simulate it by handling a change in errno below. + */ + if (settings->on_headers_complete) { + switch (settings->on_headers_complete(parser)) { + case 0: + break; + + case 2: + parser->upgrade = 1; + + /* FALLTHROUGH */ + case 1: + parser->flags |= F_SKIPBODY; + break; + + default: + SET_ERRNO(HPE_CB_headers_complete); + RETURN(p - data); /* Error */ + } + } + + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + RETURN(p - data); + } + + REEXECUTE(); + } + + case s_headers_done: + { + int hasBody; + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + hasBody = parser->flags & F_CHUNKED || + (parser->content_length > 0 && parser->content_length != ULLONG_MAX); + if (parser->upgrade && (parser->method == HTTP_CONNECT || + (parser->flags & F_SKIPBODY) || !hasBody)) { + /* Exit, the rest of the message is in a different protocol. */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + RETURN((p - data) + 1); + } + + if (parser->flags & F_SKIPBODY) { + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header */ + UPDATE_STATE(s_chunk_size_start); + } else { + if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->content_length != ULLONG_MAX) { + /* Content-Length header given and non-zero */ + UPDATE_STATE(s_body_identity); + } else { + if (!http_message_needs_eof(parser)) { + /* Assume content-length 0 - read the next */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else { + /* Read body until EOF */ + UPDATE_STATE(s_body_identity_eof); + } + } + } + + break; + } + + case s_body_identity: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* The difference between advancing content_length and p is because + * the latter will automaticaly advance on the next loop iteration. + * Further, if content_length ends up at 0, we want to see the last + * byte again for our message complete callback. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_message_done); + + /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. + * + * The alternative to doing this is to wait for the next byte to + * trigger the data callback, just as in every other case. The + * problem with this is that this makes it difficult for the test + * harness to distinguish between complete-on-EOF and + * complete-on-length. It's not clear that this distinction is + * important for applications, but let's keep it for now. + */ + CALLBACK_DATA_(body, p - body_mark + 1, p - data); + REEXECUTE(); + } + + break; + } + + /* read until EOF */ + case s_body_identity_eof: + MARK(body); + p = data + len - 1; + + break; + + case s_message_done: + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + if (parser->upgrade) { + /* Exit, the rest of the message is in a different protocol. */ + RETURN((p - data) + 1); + } + break; + + case s_chunk_size_start: + { + assert(parser->nread == 1); + assert(parser->flags & F_CHUNKED); + + unhex_val = unhex[(unsigned char)ch]; + if (UNLIKELY(unhex_val == -1)) { + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + parser->content_length = unhex_val; + UPDATE_STATE(s_chunk_size); + break; + } + + case s_chunk_size: + { + uint64_t t; + + assert(parser->flags & F_CHUNKED); + + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + + unhex_val = unhex[(unsigned char)ch]; + + if (unhex_val == -1) { + if (ch == ';' || ch == ' ') { + UPDATE_STATE(s_chunk_parameters); + break; + } + + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + t = parser->content_length; + t *= 16; + t += unhex_val; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + case s_chunk_parameters: + { + assert(parser->flags & F_CHUNKED); + /* just ignore this shit. TODO check for overflow */ + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + break; + } + + case s_chunk_size_almost_done: + { + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + if (parser->content_length == 0) { + parser->flags |= F_TRAILING; + UPDATE_STATE(s_header_field_start); + } else { + UPDATE_STATE(s_chunk_data); + } + CALLBACK_NOTIFY(chunk_header); + break; + } + + case s_chunk_data: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->flags & F_CHUNKED); + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* See the explanation in s_body_identity for why the content + * length and data pointers are managed this way. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_chunk_data_almost_done); + } + + break; + } + + case s_chunk_data_almost_done: + assert(parser->flags & F_CHUNKED); + assert(parser->content_length == 0); + STRICT_CHECK(ch != CR); + UPDATE_STATE(s_chunk_data_done); + CALLBACK_DATA(body); + break; + + case s_chunk_data_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + parser->nread = 0; + UPDATE_STATE(s_chunk_size_start); + CALLBACK_NOTIFY(chunk_complete); + break; + + default: + assert(0 && "unhandled state"); + SET_ERRNO(HPE_INVALID_INTERNAL_STATE); + goto error; + } + } + + /* Run callbacks for any marks that we have leftover after we ran our of + * bytes. There should be at most one of these set, so it's OK to invoke + * them in series (unset marks will not result in callbacks). + * + * We use the NOADVANCE() variety of callbacks here because 'p' has already + * overflowed 'data' and this allows us to correct for the off-by-one that + * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' + * value that's in-bounds). + */ + + assert(((header_field_mark ? 1 : 0) + + (header_value_mark ? 1 : 0) + + (url_mark ? 1 : 0) + + (body_mark ? 1 : 0) + + (status_mark ? 1 : 0)) <= 1); + + CALLBACK_DATA_NOADVANCE(header_field); + CALLBACK_DATA_NOADVANCE(header_value); + CALLBACK_DATA_NOADVANCE(url); + CALLBACK_DATA_NOADVANCE(body); + CALLBACK_DATA_NOADVANCE(status); + + RETURN(len); + +error: + if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { + SET_ERRNO(HPE_UNKNOWN); + } + + RETURN(p - data); +} + + +/* Does the parser need to see an EOF to find the end of the message? */ +int +http_message_needs_eof (const http_parser *parser) +{ + if (parser->type == HTTP_REQUEST) { + return 0; + } + + /* See RFC 2616 section 4.4 */ + if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ + parser->status_code == 204 || /* No Content */ + parser->status_code == 304 || /* Not Modified */ + parser->flags & F_SKIPBODY) { /* response to a HEAD request */ + return 0; + } + + if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { + return 0; + } + + return 1; +} + + +int +http_should_keep_alive (const http_parser *parser) +{ + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; + } + } else { + /* HTTP/1.0 or earlier */ + if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { + return 0; + } + } + + return !http_message_needs_eof(parser); +} + + +const char * +http_method_str (enum http_method m) +{ + return ELEM_AT(method_strings, m, ""); +} + + +void +http_parser_init (http_parser *parser, enum http_parser_type t) +{ + void *data = parser->data; /* preserve application data */ + memset(parser, 0, sizeof(*parser)); + parser->data = data; + parser->type = t; + parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); + parser->http_errno = HPE_OK; +} + +void +http_parser_settings_init(http_parser_settings *settings) +{ + memset(settings, 0, sizeof(*settings)); +} + +const char * +http_errno_name(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].name; +} + +const char * +http_errno_description(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].description; +} + +static enum http_host_state +http_parse_host_char(enum http_host_state s, const char ch) { + switch(s) { + case s_http_userinfo: + case s_http_userinfo_start: + if (ch == '@') { + return s_http_host_start; + } + + if (IS_USERINFO_CHAR(ch)) { + return s_http_userinfo; + } + break; + + case s_http_host_start: + if (ch == '[') { + return s_http_host_v6_start; + } + + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + break; + + case s_http_host: + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + /* FALLTHROUGH */ + case s_http_host_v6_end: + if (ch == ':') { + return s_http_host_port_start; + } + + break; + + case s_http_host_v6: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_start: + if (IS_HEX(ch) || ch == ':' || ch == '.') { + return s_http_host_v6; + } + + if (s == s_http_host_v6 && ch == '%') { + return s_http_host_v6_zone_start; + } + break; + + case s_http_host_v6_zone: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_zone_start: + /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */ + if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' || + ch == '~') { + return s_http_host_v6_zone; + } + break; + + case s_http_host_port: + case s_http_host_port_start: + if (IS_NUM(ch)) { + return s_http_host_port; + } + + break; + + default: + break; + } + return s_http_host_dead; +} + +static int +http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { + enum http_host_state s; + + const char *p; + size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; + + assert(u->field_set & (1 << UF_HOST)); + + u->field_data[UF_HOST].len = 0; + + s = found_at ? s_http_userinfo_start : s_http_host_start; + + for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { + enum http_host_state new_s = http_parse_host_char(s, *p); + + if (new_s == s_http_host_dead) { + return 1; + } + + switch(new_s) { + case s_http_host: + if (s != s_http_host) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6: + if (s != s_http_host_v6) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + u->field_data[UF_HOST].len++; + break; + + case s_http_host_port: + if (s != s_http_host_port) { + u->field_data[UF_PORT].off = p - buf; + u->field_data[UF_PORT].len = 0; + u->field_set |= (1 << UF_PORT); + } + u->field_data[UF_PORT].len++; + break; + + case s_http_userinfo: + if (s != s_http_userinfo) { + u->field_data[UF_USERINFO].off = p - buf ; + u->field_data[UF_USERINFO].len = 0; + u->field_set |= (1 << UF_USERINFO); + } + u->field_data[UF_USERINFO].len++; + break; + + default: + break; + } + s = new_s; + } + + /* Make sure we don't end somewhere unexpected */ + switch (s) { + case s_http_host_start: + case s_http_host_v6_start: + case s_http_host_v6: + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + case s_http_host_port_start: + case s_http_userinfo: + case s_http_userinfo_start: + return 1; + default: + break; + } + + return 0; +} + +void +http_parser_url_init(struct http_parser_url *u) { + memset(u, 0, sizeof(*u)); +} + +int +http_parser_parse_url(const char *buf, size_t buflen, int is_connect, + struct http_parser_url *u) +{ + enum state s; + const char *p; + enum http_parser_url_fields uf, old_uf; + int found_at = 0; + + u->port = u->field_set = 0; + s = is_connect ? s_req_server_start : s_req_spaces_before_url; + old_uf = UF_MAX; + + for (p = buf; p < buf + buflen; p++) { + s = parse_url_char(s, *p); + + /* Figure out the next field that we're operating on */ + switch (s) { + case s_dead: + return 1; + + /* Skip delimeters */ + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_query_string_start: + case s_req_fragment_start: + continue; + + case s_req_schema: + uf = UF_SCHEMA; + break; + + case s_req_server_with_at: + found_at = 1; + + /* FALLTHROUGH */ + case s_req_server: + uf = UF_HOST; + break; + + case s_req_path: + uf = UF_PATH; + break; + + case s_req_query_string: + uf = UF_QUERY; + break; + + case s_req_fragment: + uf = UF_FRAGMENT; + break; + + default: + assert(!"Unexpected state"); + return 1; + } + + /* Nothing's changed; soldier on */ + if (uf == old_uf) { + u->field_data[uf].len++; + continue; + } + + u->field_data[uf].off = p - buf; + u->field_data[uf].len = 1; + + u->field_set |= (1 << uf); + old_uf = uf; + } + + /* host must be present if there is a schema */ + /* parsing http:///toto will fail */ + if ((u->field_set & (1 << UF_SCHEMA)) && + (u->field_set & (1 << UF_HOST)) == 0) { + return 1; + } + + if (u->field_set & (1 << UF_HOST)) { + if (http_parse_host(buf, u, found_at) != 0) { + return 1; + } + } + + /* CONNECT requests can only contain "hostname:port" */ + if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { + return 1; + } + + if (u->field_set & (1 << UF_PORT)) { + uint16_t off; + uint16_t len; + const char* p; + const char* end; + unsigned long v; + + off = u->field_data[UF_PORT].off; + len = u->field_data[UF_PORT].len; + end = buf + off + len; + + /* NOTE: The characters are already validated and are in the [0-9] range */ + assert(off + len <= buflen && "Port number overflow"); + v = 0; + for (p = buf + off; p < end; p++) { + v *= 10; + v += *p - '0'; + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } + } + + u->port = (uint16_t) v; + } + + return 0; +} + +void +http_parser_pause(http_parser *parser, int paused) { + /* Users should only be pausing/unpausing a parser that is not in an error + * state. In non-debug builds, there's not much that we can do about this + * other than ignore it. + */ + if (HTTP_PARSER_ERRNO(parser) == HPE_OK || + HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { + SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); + } else { + assert(0 && "Attempting to pause parser in error state"); + } +} + +int +http_body_is_final(const struct http_parser *parser) { + return parser->state == s_message_done; +} + +unsigned long +http_parser_version(void) { + return HTTP_PARSER_VERSION_MAJOR * 0x10000 | + HTTP_PARSER_VERSION_MINOR * 0x00100 | + HTTP_PARSER_VERSION_PATCH * 0x00001; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.gyp b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.gyp new file mode 100644 index 0000000..ef34eca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.gyp @@ -0,0 +1,111 @@ +# This file is used with the GYP meta build system. +# http://code.google.com/p/gyp/ +# To build try this: +# svn co http://gyp.googlecode.com/svn/trunk gyp +# ./gyp/gyp -f make --depth=`pwd` http_parser.gyp +# ./out/Debug/test +{ + 'target_defaults': { + 'default_configuration': 'Debug', + 'configurations': { + # TODO: hoist these out and put them somewhere common, because + # RuntimeLibrary MUST MATCH across the entire project + 'Debug': { + 'defines': [ 'DEBUG', '_DEBUG' ], + 'cflags': [ '-Wall', '-Wextra', '-O0', '-g', '-ftrapv' ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 1, # static debug + }, + }, + }, + 'Release': { + 'defines': [ 'NDEBUG' ], + 'cflags': [ '-Wall', '-Wextra', '-O3' ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 0, # static release + }, + }, + } + }, + 'msvs_settings': { + 'VCCLCompilerTool': { + }, + 'VCLibrarianTool': { + }, + 'VCLinkerTool': { + 'GenerateDebugInformation': 'true', + }, + }, + 'conditions': [ + ['OS == "win"', { + 'defines': [ + 'WIN32' + ], + }] + ], + }, + + 'targets': [ + { + 'target_name': 'http_parser', + 'type': 'static_library', + 'include_dirs': [ '.' ], + 'direct_dependent_settings': { + 'defines': [ 'HTTP_PARSER_STRICT=0' ], + 'include_dirs': [ '.' ], + }, + 'defines': [ 'HTTP_PARSER_STRICT=0' ], + 'sources': [ './http_parser.c', ], + 'conditions': [ + ['OS=="win"', { + 'msvs_settings': { + 'VCCLCompilerTool': { + # Compile as C++. http_parser.c is actually C99, but C++ is + # close enough in this case. + 'CompileAs': 2, + }, + }, + }] + ], + }, + + { + 'target_name': 'http_parser_strict', + 'type': 'static_library', + 'include_dirs': [ '.' ], + 'direct_dependent_settings': { + 'defines': [ 'HTTP_PARSER_STRICT=1' ], + 'include_dirs': [ '.' ], + }, + 'defines': [ 'HTTP_PARSER_STRICT=1' ], + 'sources': [ './http_parser.c', ], + 'conditions': [ + ['OS=="win"', { + 'msvs_settings': { + 'VCCLCompilerTool': { + # Compile as C++. http_parser.c is actually C99, but C++ is + # close enough in this case. + 'CompileAs': 2, + }, + }, + }] + ], + }, + + { + 'target_name': 'test-nonstrict', + 'type': 'executable', + 'dependencies': [ 'http_parser' ], + 'sources': [ 'test.c' ] + }, + + { + 'target_name': 'test-strict', + 'type': 'executable', + 'dependencies': [ 'http_parser_strict' ], + 'sources': [ 'test.c' ] + } + ] +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.h b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.h new file mode 100644 index 0000000..a0de71e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/http_parser.h @@ -0,0 +1,433 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef http_parser_h +#define http_parser_h +#ifdef __cplusplus +extern "C" { +#endif + +/* Also update SONAME in the Makefile whenever you change these. */ +#define HTTP_PARSER_VERSION_MAJOR 2 +#define HTTP_PARSER_VERSION_MINOR 8 +#define HTTP_PARSER_VERSION_PATCH 1 + +#include +#if defined(_WIN32) && !defined(__MINGW32__) && \ + (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) +#include +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run + * faster + */ +#ifndef HTTP_PARSER_STRICT +# define HTTP_PARSER_STRICT 1 +#endif + +/* Maximium header size allowed. If the macro is not defined + * before including this header then the default is used. To + * change the maximum header size, define the macro in the build + * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove + * the effective limit on the size of the header, define the macro + * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) + */ +#ifndef HTTP_MAX_HEADER_SIZE +# define HTTP_MAX_HEADER_SIZE (80*1024) +#endif + +typedef struct http_parser http_parser; +typedef struct http_parser_settings http_parser_settings; + + +/* Callbacks should return non-zero to indicate an error. The parser will + * then halt execution. + * + * The one exception is on_headers_complete. In a HTTP_RESPONSE parser + * returning '1' from on_headers_complete will tell the parser that it + * should not expect a body. This is used when receiving a response to a + * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + * chunked' headers that indicate the presence of a body. + * + * Returning `2` from on_headers_complete will tell parser that it should not + * expect neither a body nor any futher responses on this connection. This is + * useful for handling responses to a CONNECT request which may not contain + * `Upgrade` or `Connection: upgrade` headers. + * + * http_data_cb does not return data chunks. It will be called arbitrarily + * many times for each string. E.G. you might get 10 callbacks for "on_url" + * each providing just a few characters more data. + */ +typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); +typedef int (*http_cb) (http_parser*); + + +/* Status Codes */ +#define HTTP_STATUS_MAP(XX) \ + XX(100, CONTINUE, Continue) \ + XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \ + XX(102, PROCESSING, Processing) \ + XX(200, OK, OK) \ + XX(201, CREATED, Created) \ + XX(202, ACCEPTED, Accepted) \ + XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \ + XX(204, NO_CONTENT, No Content) \ + XX(205, RESET_CONTENT, Reset Content) \ + XX(206, PARTIAL_CONTENT, Partial Content) \ + XX(207, MULTI_STATUS, Multi-Status) \ + XX(208, ALREADY_REPORTED, Already Reported) \ + XX(226, IM_USED, IM Used) \ + XX(300, MULTIPLE_CHOICES, Multiple Choices) \ + XX(301, MOVED_PERMANENTLY, Moved Permanently) \ + XX(302, FOUND, Found) \ + XX(303, SEE_OTHER, See Other) \ + XX(304, NOT_MODIFIED, Not Modified) \ + XX(305, USE_PROXY, Use Proxy) \ + XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \ + XX(308, PERMANENT_REDIRECT, Permanent Redirect) \ + XX(400, BAD_REQUEST, Bad Request) \ + XX(401, UNAUTHORIZED, Unauthorized) \ + XX(402, PAYMENT_REQUIRED, Payment Required) \ + XX(403, FORBIDDEN, Forbidden) \ + XX(404, NOT_FOUND, Not Found) \ + XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \ + XX(406, NOT_ACCEPTABLE, Not Acceptable) \ + XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \ + XX(408, REQUEST_TIMEOUT, Request Timeout) \ + XX(409, CONFLICT, Conflict) \ + XX(410, GONE, Gone) \ + XX(411, LENGTH_REQUIRED, Length Required) \ + XX(412, PRECONDITION_FAILED, Precondition Failed) \ + XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \ + XX(414, URI_TOO_LONG, URI Too Long) \ + XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \ + XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \ + XX(417, EXPECTATION_FAILED, Expectation Failed) \ + XX(421, MISDIRECTED_REQUEST, Misdirected Request) \ + XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \ + XX(423, LOCKED, Locked) \ + XX(424, FAILED_DEPENDENCY, Failed Dependency) \ + XX(426, UPGRADE_REQUIRED, Upgrade Required) \ + XX(428, PRECONDITION_REQUIRED, Precondition Required) \ + XX(429, TOO_MANY_REQUESTS, Too Many Requests) \ + XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \ + XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \ + XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \ + XX(501, NOT_IMPLEMENTED, Not Implemented) \ + XX(502, BAD_GATEWAY, Bad Gateway) \ + XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \ + XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \ + XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \ + XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \ + XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ + XX(508, LOOP_DETECTED, Loop Detected) \ + XX(510, NOT_EXTENDED, Not Extended) \ + XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \ + +enum http_status + { +#define XX(num, name, string) HTTP_STATUS_##name = num, + HTTP_STATUS_MAP(XX) +#undef XX + }; + + +/* Request Methods */ +#define HTTP_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + /* pathological */ \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + /* WebDAV */ \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + XX(16, BIND, BIND) \ + XX(17, REBIND, REBIND) \ + XX(18, UNBIND, UNBIND) \ + XX(19, ACL, ACL) \ + /* subversion */ \ + XX(20, REPORT, REPORT) \ + XX(21, MKACTIVITY, MKACTIVITY) \ + XX(22, CHECKOUT, CHECKOUT) \ + XX(23, MERGE, MERGE) \ + /* upnp */ \ + XX(24, MSEARCH, M-SEARCH) \ + XX(25, NOTIFY, NOTIFY) \ + XX(26, SUBSCRIBE, SUBSCRIBE) \ + XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ + /* RFC-5789 */ \ + XX(28, PATCH, PATCH) \ + XX(29, PURGE, PURGE) \ + /* CalDAV */ \ + XX(30, MKCALENDAR, MKCALENDAR) \ + /* RFC-2068, section 19.6.1.2 */ \ + XX(31, LINK, LINK) \ + XX(32, UNLINK, UNLINK) \ + /* icecast */ \ + XX(33, SOURCE, SOURCE) \ + +enum http_method + { +#define XX(num, name, string) HTTP_##name = num, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; + + +/* Flag values for http_parser.flags field */ +enum flags + { F_CHUNKED = 1 << 0 + , F_CONNECTION_KEEP_ALIVE = 1 << 1 + , F_CONNECTION_CLOSE = 1 << 2 + , F_CONNECTION_UPGRADE = 1 << 3 + , F_TRAILING = 1 << 4 + , F_UPGRADE = 1 << 5 + , F_SKIPBODY = 1 << 6 + , F_CONTENTLENGTH = 1 << 7 + }; + + +/* Map for errno-related constants + * + * The provided argument should be a macro that takes 2 arguments. + */ +#define HTTP_ERRNO_MAP(XX) \ + /* No error */ \ + XX(OK, "success") \ + \ + /* Callback-related errors */ \ + XX(CB_message_begin, "the on_message_begin callback failed") \ + XX(CB_url, "the on_url callback failed") \ + XX(CB_header_field, "the on_header_field callback failed") \ + XX(CB_header_value, "the on_header_value callback failed") \ + XX(CB_headers_complete, "the on_headers_complete callback failed") \ + XX(CB_body, "the on_body callback failed") \ + XX(CB_message_complete, "the on_message_complete callback failed") \ + XX(CB_status, "the on_status callback failed") \ + XX(CB_chunk_header, "the on_chunk_header callback failed") \ + XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ + \ + /* Parsing-related errors */ \ + XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ + XX(HEADER_OVERFLOW, \ + "too many header bytes seen; overflow detected") \ + XX(CLOSED_CONNECTION, \ + "data received after completed connection: close message") \ + XX(INVALID_VERSION, "invalid HTTP version") \ + XX(INVALID_STATUS, "invalid HTTP status code") \ + XX(INVALID_METHOD, "invalid HTTP method") \ + XX(INVALID_URL, "invalid URL") \ + XX(INVALID_HOST, "invalid host") \ + XX(INVALID_PORT, "invalid port") \ + XX(INVALID_PATH, "invalid path") \ + XX(INVALID_QUERY_STRING, "invalid query string") \ + XX(INVALID_FRAGMENT, "invalid fragment") \ + XX(LF_EXPECTED, "LF character expected") \ + XX(INVALID_HEADER_TOKEN, "invalid character in header") \ + XX(INVALID_CONTENT_LENGTH, \ + "invalid character in content-length header") \ + XX(UNEXPECTED_CONTENT_LENGTH, \ + "unexpected content-length header") \ + XX(INVALID_CHUNK_SIZE, \ + "invalid character in chunk size header") \ + XX(INVALID_CONSTANT, "invalid constant string") \ + XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ + XX(STRICT, "strict mode assertion failed") \ + XX(PAUSED, "parser is paused") \ + XX(UNKNOWN, "an unknown error occurred") + + +/* Define HPE_* values for each errno value above */ +#define HTTP_ERRNO_GEN(n, s) HPE_##n, +enum http_errno { + HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) +}; +#undef HTTP_ERRNO_GEN + + +/* Get an http_errno value from an http_parser */ +#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) + + +struct http_parser { + /** PRIVATE **/ + unsigned int type : 2; /* enum http_parser_type */ + unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */ + unsigned int state : 7; /* enum state from http_parser.c */ + unsigned int header_state : 7; /* enum header_state from http_parser.c */ + unsigned int index : 7; /* index into current matcher */ + unsigned int lenient_http_headers : 1; + + uint32_t nread; /* # bytes read in various scenarios */ + uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ + + /** READ-ONLY **/ + unsigned short http_major; + unsigned short http_minor; + unsigned int status_code : 16; /* responses only */ + unsigned int method : 8; /* requests only */ + unsigned int http_errno : 7; + + /* 1 = Upgrade header was present and the parser has exited because of that. + * 0 = No upgrade header present. + * Should be checked when http_parser_execute() returns in addition to + * error checking. + */ + unsigned int upgrade : 1; + + /** PUBLIC **/ + void *data; /* A pointer to get hook to the "connection" or "socket" object */ +}; + + +struct http_parser_settings { + http_cb on_message_begin; + http_data_cb on_url; + http_data_cb on_status; + http_data_cb on_header_field; + http_data_cb on_header_value; + http_cb on_headers_complete; + http_data_cb on_body; + http_cb on_message_complete; + /* When on_chunk_header is called, the current chunk length is stored + * in parser->content_length. + */ + http_cb on_chunk_header; + http_cb on_chunk_complete; +}; + + +enum http_parser_url_fields + { UF_SCHEMA = 0 + , UF_HOST = 1 + , UF_PORT = 2 + , UF_PATH = 3 + , UF_QUERY = 4 + , UF_FRAGMENT = 5 + , UF_USERINFO = 6 + , UF_MAX = 7 + }; + + +/* Result structure for http_parser_parse_url(). + * + * Callers should index into field_data[] with UF_* values iff field_set + * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and + * because we probably have padding left over), we convert any port to + * a uint16_t. + */ +struct http_parser_url { + uint16_t field_set; /* Bitmask of (1 << UF_*) values */ + uint16_t port; /* Converted UF_PORT string */ + + struct { + uint16_t off; /* Offset into buffer in which field starts */ + uint16_t len; /* Length of run in buffer */ + } field_data[UF_MAX]; +}; + + +/* Returns the library version. Bits 16-23 contain the major version number, + * bits 8-15 the minor version number and bits 0-7 the patch level. + * Usage example: + * + * unsigned long version = http_parser_version(); + * unsigned major = (version >> 16) & 255; + * unsigned minor = (version >> 8) & 255; + * unsigned patch = version & 255; + * printf("http_parser v%u.%u.%u\n", major, minor, patch); + */ +unsigned long http_parser_version(void); + +void http_parser_init(http_parser *parser, enum http_parser_type type); + + +/* Initialize http_parser_settings members to 0 + */ +void http_parser_settings_init(http_parser_settings *settings); + + +/* Executes the parser. Returns number of parsed bytes. Sets + * `parser->http_errno` on error. */ +size_t http_parser_execute(http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len); + + +/* If http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns 0, then this should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ +int http_should_keep_alive(const http_parser *parser); + +/* Returns a string version of the HTTP method. */ +const char *http_method_str(enum http_method m); + +/* Return a string name of the given error */ +const char *http_errno_name(enum http_errno err); + +/* Return a string description of the given error */ +const char *http_errno_description(enum http_errno err); + +/* Initialize all http_parser_url members to 0 */ +void http_parser_url_init(struct http_parser_url *u); + +/* Parse a URL; return nonzero on failure */ +int http_parser_parse_url(const char *buf, size_t buflen, + int is_connect, + struct http_parser_url *u); + +/* Pause or un-pause the parser; a nonzero value pauses */ +void http_parser_pause(http_parser *parser, int paused); + +/* Checks if this is the final chunk of the body. */ +int http_body_is_final(const http_parser *parser); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/test.c b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/test.c new file mode 100644 index 0000000..df170e4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/ext/ruby_http_parser/vendor/http-parser/test.c @@ -0,0 +1,4456 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "http_parser.h" +#include +#include +#include +#include /* rand */ +#include +#include + +#if defined(__APPLE__) +# undef strlncpy +#endif /* defined(__APPLE__) */ + +#undef TRUE +#define TRUE 1 +#undef FALSE +#define FALSE 0 + +#define MAX_HEADERS 13 +#define MAX_ELEMENT_SIZE 2048 +#define MAX_CHUNKS 16 + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) + +static http_parser *parser; + +struct message { + const char *name; // for debugging purposes + const char *raw; + enum http_parser_type type; + enum http_method method; + int status_code; + char response_status[MAX_ELEMENT_SIZE]; + char request_path[MAX_ELEMENT_SIZE]; + char request_url[MAX_ELEMENT_SIZE]; + char fragment[MAX_ELEMENT_SIZE]; + char query_string[MAX_ELEMENT_SIZE]; + char body[MAX_ELEMENT_SIZE]; + size_t body_size; + const char *host; + const char *userinfo; + uint16_t port; + int num_headers; + enum { NONE=0, FIELD, VALUE } last_header_element; + char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE]; + int should_keep_alive; + + int num_chunks; + int num_chunks_complete; + int chunk_lengths[MAX_CHUNKS]; + + const char *upgrade; // upgraded body + + unsigned short http_major; + unsigned short http_minor; + + int message_begin_cb_called; + int headers_complete_cb_called; + int message_complete_cb_called; + int status_cb_called; + int message_complete_on_eof; + int body_is_final; +}; + +static int currently_parsing_eof; + +static struct message messages[5]; +static int num_messages; +static http_parser_settings *current_pause_parser; + +/* * R E Q U E S T S * */ +const struct message requests[] = +#define CURL_GET 0 +{ {.name= "curl get" + ,.type= HTTP_REQUEST + ,.raw= "GET /test HTTP/1.1\r\n" + "User-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\n" + "Host: 0.0.0.0=5000\r\n" + "Accept: */*\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 3 + ,.headers= + { { "User-Agent", "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1" } + , { "Host", "0.0.0.0=5000" } + , { "Accept", "*/*" } + } + ,.body= "" + } + +#define FIREFOX_GET 1 +, {.name= "firefox get" + ,.type= HTTP_REQUEST + ,.raw= "GET /favicon.ico HTTP/1.1\r\n" + "Host: 0.0.0.0=5000\r\n" + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + "Accept-Language: en-us,en;q=0.5\r\n" + "Accept-Encoding: gzip,deflate\r\n" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" + "Keep-Alive: 300\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/favicon.ico" + ,.request_url= "/favicon.ico" + ,.num_headers= 8 + ,.headers= + { { "Host", "0.0.0.0=5000" } + , { "User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0" } + , { "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } + , { "Accept-Language", "en-us,en;q=0.5" } + , { "Accept-Encoding", "gzip,deflate" } + , { "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7" } + , { "Keep-Alive", "300" } + , { "Connection", "keep-alive" } + } + ,.body= "" + } + +#define DUMBFUCK 2 +, {.name= "dumbfuck" + ,.type= HTTP_REQUEST + ,.raw= "GET /dumbfuck HTTP/1.1\r\n" + "aaaaaaaaaaaaa:++++++++++\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/dumbfuck" + ,.request_url= "/dumbfuck" + ,.num_headers= 1 + ,.headers= + { { "aaaaaaaaaaaaa", "++++++++++" } + } + ,.body= "" + } + +#define FRAGMENT_IN_URI 3 +, {.name= "fragment in url" + ,.type= HTTP_REQUEST + ,.raw= "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "page=1" + ,.fragment= "posts-17408" + ,.request_path= "/forums/1/topics/2375" + /* XXX request url does include fragment? */ + ,.request_url= "/forums/1/topics/2375?page=1#posts-17408" + ,.num_headers= 0 + ,.body= "" + } + +#define GET_NO_HEADERS_NO_BODY 4 +, {.name= "get no headers no body" + ,.type= HTTP_REQUEST + ,.raw= "GET /get_no_headers_no_body/world HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE /* would need Connection: close */ + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/get_no_headers_no_body/world" + ,.request_url= "/get_no_headers_no_body/world" + ,.num_headers= 0 + ,.body= "" + } + +#define GET_ONE_HEADER_NO_BODY 5 +, {.name= "get one header no body" + ,.type= HTTP_REQUEST + ,.raw= "GET /get_one_header_no_body HTTP/1.1\r\n" + "Accept: */*\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE /* would need Connection: close */ + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/get_one_header_no_body" + ,.request_url= "/get_one_header_no_body" + ,.num_headers= 1 + ,.headers= + { { "Accept" , "*/*" } + } + ,.body= "" + } + +#define GET_FUNKY_CONTENT_LENGTH 6 +, {.name= "get funky content length body hello" + ,.type= HTTP_REQUEST + ,.raw= "GET /get_funky_content_length_body_hello HTTP/1.0\r\n" + "conTENT-Length: 5\r\n" + "\r\n" + "HELLO" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/get_funky_content_length_body_hello" + ,.request_url= "/get_funky_content_length_body_hello" + ,.num_headers= 1 + ,.headers= + { { "conTENT-Length" , "5" } + } + ,.body= "HELLO" + } + +#define POST_IDENTITY_BODY_WORLD 7 +, {.name= "post identity body world" + ,.type= HTTP_REQUEST + ,.raw= "POST /post_identity_body_world?q=search#hey HTTP/1.1\r\n" + "Accept: */*\r\n" + "Transfer-Encoding: identity\r\n" + "Content-Length: 5\r\n" + "\r\n" + "World" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "q=search" + ,.fragment= "hey" + ,.request_path= "/post_identity_body_world" + ,.request_url= "/post_identity_body_world?q=search#hey" + ,.num_headers= 3 + ,.headers= + { { "Accept", "*/*" } + , { "Transfer-Encoding", "identity" } + , { "Content-Length", "5" } + } + ,.body= "World" + } + +#define POST_CHUNKED_ALL_YOUR_BASE 8 +, {.name= "post - chunked body: all your base are belong to us" + ,.type= HTTP_REQUEST + ,.raw= "POST /post_chunked_all_your_base HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "1e\r\nall your base are belong to us\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/post_chunked_all_your_base" + ,.request_url= "/post_chunked_all_your_base" + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding" , "chunked" } + } + ,.body= "all your base are belong to us" + ,.num_chunks_complete= 2 + ,.chunk_lengths= { 0x1e } + } + +#define TWO_CHUNKS_MULT_ZERO_END 9 +, {.name= "two chunks ; triple zero ending" + ,.type= HTTP_REQUEST + ,.raw= "POST /two_chunks_mult_zero_end HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "5\r\nhello\r\n" + "6\r\n world\r\n" + "000\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/two_chunks_mult_zero_end" + ,.request_url= "/two_chunks_mult_zero_end" + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding", "chunked" } + } + ,.body= "hello world" + ,.num_chunks_complete= 3 + ,.chunk_lengths= { 5, 6 } + } + +#define CHUNKED_W_TRAILING_HEADERS 10 +, {.name= "chunked with trailing headers. blech." + ,.type= HTTP_REQUEST + ,.raw= "POST /chunked_w_trailing_headers HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "5\r\nhello\r\n" + "6\r\n world\r\n" + "0\r\n" + "Vary: *\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/chunked_w_trailing_headers" + ,.request_url= "/chunked_w_trailing_headers" + ,.num_headers= 3 + ,.headers= + { { "Transfer-Encoding", "chunked" } + , { "Vary", "*" } + , { "Content-Type", "text/plain" } + } + ,.body= "hello world" + ,.num_chunks_complete= 3 + ,.chunk_lengths= { 5, 6 } + } + +#define CHUNKED_W_BULLSHIT_AFTER_LENGTH 11 +, {.name= "with bullshit after the length" + ,.type= HTTP_REQUEST + ,.raw= "POST /chunked_w_bullshit_after_length HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n" + "6; blahblah; blah\r\n world\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/chunked_w_bullshit_after_length" + ,.request_url= "/chunked_w_bullshit_after_length" + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding", "chunked" } + } + ,.body= "hello world" + ,.num_chunks_complete= 3 + ,.chunk_lengths= { 5, 6 } + } + +#define WITH_QUOTES 12 +, {.name= "with quotes" + ,.type= HTTP_REQUEST + ,.raw= "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "foo=\"bar\"" + ,.fragment= "" + ,.request_path= "/with_\"stupid\"_quotes" + ,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\"" + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define APACHEBENCH_GET 13 +/* The server receiving this request SHOULD NOT wait for EOF + * to know that content-length == 0. + * How to represent this in a unit test? message_complete_on_eof + * Compare with NO_CONTENT_LENGTH_RESPONSE. + */ +, {.name = "apachebench get" + ,.type= HTTP_REQUEST + ,.raw= "GET /test HTTP/1.0\r\n" + "Host: 0.0.0.0:5000\r\n" + "User-Agent: ApacheBench/2.3\r\n" + "Accept: */*\r\n\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 3 + ,.headers= { { "Host", "0.0.0.0:5000" } + , { "User-Agent", "ApacheBench/2.3" } + , { "Accept", "*/*" } + } + ,.body= "" + } + +#define QUERY_URL_WITH_QUESTION_MARK_GET 14 +/* Some clients include '?' characters in query strings. + */ +, {.name = "query url with question mark" + ,.type= HTTP_REQUEST + ,.raw= "GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "foo=bar?baz" + ,.fragment= "" + ,.request_path= "/test.cgi" + ,.request_url= "/test.cgi?foo=bar?baz" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define PREFIX_NEWLINE_GET 15 +/* Some clients, especially after a POST in a keep-alive connection, + * will send an extra CRLF before the next request + */ +, {.name = "newline prefix get" + ,.type= HTTP_REQUEST + ,.raw= "\r\nGET /test HTTP/1.1\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define UPGRADE_REQUEST 16 +, {.name = "upgrade request" + ,.type= HTTP_REQUEST + ,.raw= "GET /demo HTTP/1.1\r\n" + "Host: example.com\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" + "Sec-WebSocket-Protocol: sample\r\n" + "Upgrade: WebSocket\r\n" + "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" + "Origin: http://example.com\r\n" + "\r\n" + "Hot diggity dogg" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/demo" + ,.request_url= "/demo" + ,.num_headers= 7 + ,.upgrade="Hot diggity dogg" + ,.headers= { { "Host", "example.com" } + , { "Connection", "Upgrade" } + , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" } + , { "Sec-WebSocket-Protocol", "sample" } + , { "Upgrade", "WebSocket" } + , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" } + , { "Origin", "http://example.com" } + } + ,.body= "" + } + +#define CONNECT_REQUEST 17 +, {.name = "connect request" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "\r\n" + "some data\r\n" + "and yet even more data" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "0-home0.netscape.com:443" + ,.num_headers= 2 + ,.upgrade="some data\r\nand yet even more data" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + } + ,.body= "" + } + +#define REPORT_REQ 18 +, {.name= "report request" + ,.type= HTTP_REQUEST + ,.raw= "REPORT /test HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_REPORT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/test" + ,.request_url= "/test" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define NO_HTTP_VERSION 19 +, {.name= "request with no http version" + ,.type= HTTP_REQUEST + ,.raw= "GET /\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 0 + ,.http_minor= 9 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define MSEARCH_REQ 20 +, {.name= "m-search request" + ,.type= HTTP_REQUEST + ,.raw= "M-SEARCH * HTTP/1.1\r\n" + "HOST: 239.255.255.250:1900\r\n" + "MAN: \"ssdp:discover\"\r\n" + "ST: \"ssdp:all\"\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_MSEARCH + ,.query_string= "" + ,.fragment= "" + ,.request_path= "*" + ,.request_url= "*" + ,.num_headers= 3 + ,.headers= { { "HOST", "239.255.255.250:1900" } + , { "MAN", "\"ssdp:discover\"" } + , { "ST", "\"ssdp:all\"" } + } + ,.body= "" + } + +#define LINE_FOLDING_IN_HEADER 21 +, {.name= "line folding in header value" + ,.type= HTTP_REQUEST + ,.raw= "GET / HTTP/1.1\r\n" + "Line1: abc\r\n" + "\tdef\r\n" + " ghi\r\n" + "\t\tjkl\r\n" + " mno \r\n" + "\t \tqrs\r\n" + "Line2: \t line2\t\r\n" + "Line3:\r\n" + " line3\r\n" + "Line4: \r\n" + " \r\n" + "Connection:\r\n" + " close\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 5 + ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" } + , { "Line2", "line2\t" } + , { "Line3", "line3" } + , { "Line4", "" } + , { "Connection", "close" }, + } + ,.body= "" + } + + +#define QUERY_TERMINATED_HOST 22 +, {.name= "host terminated by a query string" + ,.type= HTTP_REQUEST + ,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "hail=all" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "http://hypnotoad.org?hail=all" + ,.host= "hypnotoad.org" + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define QUERY_TERMINATED_HOSTPORT 23 +, {.name= "host:port terminated by a query string" + ,.type= HTTP_REQUEST + ,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "hail=all" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "http://hypnotoad.org:1234?hail=all" + ,.host= "hypnotoad.org" + ,.port= 1234 + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define SPACE_TERMINATED_HOSTPORT 24 +, {.name= "host:port terminated by a space" + ,.type= HTTP_REQUEST + ,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "http://hypnotoad.org:1234" + ,.host= "hypnotoad.org" + ,.port= 1234 + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define PATCH_REQ 25 +, {.name = "PATCH request" + ,.type= HTTP_REQUEST + ,.raw= "PATCH /file.txt HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Content-Type: application/example\r\n" + "If-Match: \"e0023aa4e\"\r\n" + "Content-Length: 10\r\n" + "\r\n" + "cccccccccc" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_PATCH + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/file.txt" + ,.request_url= "/file.txt" + ,.num_headers= 4 + ,.headers= { { "Host", "www.example.com" } + , { "Content-Type", "application/example" } + , { "If-Match", "\"e0023aa4e\"" } + , { "Content-Length", "10" } + } + ,.body= "cccccccccc" + } + +#define CONNECT_CAPS_REQUEST 26 +, {.name = "connect caps request" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "HOME0.NETSCAPE.COM:443" + ,.num_headers= 2 + ,.upgrade="" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + } + ,.body= "" + } + +#if !HTTP_PARSER_STRICT +#define UTF8_PATH_REQ 27 +, {.name= "utf-8 path request" + ,.type= HTTP_REQUEST + ,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n" + "Host: github.com\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "q=1" + ,.fragment= "narf" + ,.request_path= "/δ¶/δt/pope" + ,.request_url= "/δ¶/δt/pope?q=1#narf" + ,.num_headers= 1 + ,.headers= { {"Host", "github.com" } + } + ,.body= "" + } + +#define HOSTNAME_UNDERSCORE 28 +, {.name = "hostname underscore" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.query_string= "" + ,.fragment= "" + ,.request_path= "" + ,.request_url= "home_0.netscape.com:443" + ,.num_headers= 2 + ,.upgrade="" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + } + ,.body= "" + } +#endif /* !HTTP_PARSER_STRICT */ + +/* see https://github.com/ry/http-parser/issues/47 */ +#define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29 +, {.name = "eat CRLF between requests, no \"Connection: close\" header" + ,.raw= "POST / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: 4\r\n" + "\r\n" + "q=42\r\n" /* note the trailing CRLF */ + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 3 + ,.upgrade= 0 + ,.headers= { { "Host", "www.example.com" } + , { "Content-Type", "application/x-www-form-urlencoded" } + , { "Content-Length", "4" } + } + ,.body= "q=42" + } + +/* see https://github.com/ry/http-parser/issues/47 */ +#define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30 +, {.name = "eat CRLF between requests even if \"Connection: close\" is set" + ,.raw= "POST / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: 4\r\n" + "Connection: close\r\n" + "\r\n" + "q=42\r\n" /* note the trailing CRLF */ + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE /* input buffer isn't empty when on_message_complete is called */ + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 4 + ,.upgrade= 0 + ,.headers= { { "Host", "www.example.com" } + , { "Content-Type", "application/x-www-form-urlencoded" } + , { "Content-Length", "4" } + , { "Connection", "close" } + } + ,.body= "q=42" + } + +#define PURGE_REQ 31 +, {.name = "PURGE request" + ,.type= HTTP_REQUEST + ,.raw= "PURGE /file.txt HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_PURGE + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/file.txt" + ,.request_url= "/file.txt" + ,.num_headers= 1 + ,.headers= { { "Host", "www.example.com" } } + ,.body= "" + } + +#define SEARCH_REQ 32 +, {.name = "SEARCH request" + ,.type= HTTP_REQUEST + ,.raw= "SEARCH / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_SEARCH + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 1 + ,.headers= { { "Host", "www.example.com" } } + ,.body= "" + } + +#define PROXY_WITH_BASIC_AUTH 33 +, {.name= "host:port and basic_auth" + ,.type= HTTP_REQUEST + ,.raw= "GET http://a%12:b!&*$@hypnotoad.org:1234/toto HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.fragment= "" + ,.request_path= "/toto" + ,.request_url= "http://a%12:b!&*$@hypnotoad.org:1234/toto" + ,.host= "hypnotoad.org" + ,.userinfo= "a%12:b!&*$" + ,.port= 1234 + ,.num_headers= 0 + ,.headers= { } + ,.body= "" + } + +#define LINE_FOLDING_IN_HEADER_WITH_LF 34 +, {.name= "line folding in header value" + ,.type= HTTP_REQUEST + ,.raw= "GET / HTTP/1.1\n" + "Line1: abc\n" + "\tdef\n" + " ghi\n" + "\t\tjkl\n" + " mno \n" + "\t \tqrs\n" + "Line2: \t line2\t\n" + "Line3:\n" + " line3\n" + "Line4: \n" + " \n" + "Connection:\n" + " close\n" + "\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/" + ,.request_url= "/" + ,.num_headers= 5 + ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" } + , { "Line2", "line2\t" } + , { "Line3", "line3" } + , { "Line4", "" } + , { "Connection", "close" }, + } + ,.body= "" + } + +#define CONNECTION_MULTI 35 +, {.name = "multiple connection header values with folding" + ,.type= HTTP_REQUEST + ,.raw= "GET /demo HTTP/1.1\r\n" + "Host: example.com\r\n" + "Connection: Something,\r\n" + " Upgrade, ,Keep-Alive\r\n" + "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" + "Sec-WebSocket-Protocol: sample\r\n" + "Upgrade: WebSocket\r\n" + "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" + "Origin: http://example.com\r\n" + "\r\n" + "Hot diggity dogg" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/demo" + ,.request_url= "/demo" + ,.num_headers= 7 + ,.upgrade="Hot diggity dogg" + ,.headers= { { "Host", "example.com" } + , { "Connection", "Something, Upgrade, ,Keep-Alive" } + , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" } + , { "Sec-WebSocket-Protocol", "sample" } + , { "Upgrade", "WebSocket" } + , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" } + , { "Origin", "http://example.com" } + } + ,.body= "" + } + +#define CONNECTION_MULTI_LWS 36 +, {.name = "multiple connection header values with folding and lws" + ,.type= HTTP_REQUEST + ,.raw= "GET /demo HTTP/1.1\r\n" + "Connection: keep-alive, upgrade\r\n" + "Upgrade: WebSocket\r\n" + "\r\n" + "Hot diggity dogg" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/demo" + ,.request_url= "/demo" + ,.num_headers= 2 + ,.upgrade="Hot diggity dogg" + ,.headers= { { "Connection", "keep-alive, upgrade" } + , { "Upgrade", "WebSocket" } + } + ,.body= "" + } + +#define CONNECTION_MULTI_LWS_CRLF 37 +, {.name = "multiple connection header values with folding and lws" + ,.type= HTTP_REQUEST + ,.raw= "GET /demo HTTP/1.1\r\n" + "Connection: keep-alive, \r\n upgrade\r\n" + "Upgrade: WebSocket\r\n" + "\r\n" + "Hot diggity dogg" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "" + ,.fragment= "" + ,.request_path= "/demo" + ,.request_url= "/demo" + ,.num_headers= 2 + ,.upgrade="Hot diggity dogg" + ,.headers= { { "Connection", "keep-alive, upgrade" } + , { "Upgrade", "WebSocket" } + } + ,.body= "" + } + +#define UPGRADE_POST_REQUEST 38 +, {.name = "upgrade post request" + ,.type= HTTP_REQUEST + ,.raw= "POST /demo HTTP/1.1\r\n" + "Host: example.com\r\n" + "Connection: Upgrade\r\n" + "Upgrade: HTTP/2.0\r\n" + "Content-Length: 15\r\n" + "\r\n" + "sweet post body" + "Hot diggity dogg" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.request_path= "/demo" + ,.request_url= "/demo" + ,.num_headers= 4 + ,.upgrade="Hot diggity dogg" + ,.headers= { { "Host", "example.com" } + , { "Connection", "Upgrade" } + , { "Upgrade", "HTTP/2.0" } + , { "Content-Length", "15" } + } + ,.body= "sweet post body" + } + +#define CONNECT_WITH_BODY_REQUEST 39 +, {.name = "connect with body request" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT foo.bar.com:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "Content-Length: 10\r\n" + "\r\n" + "blarfcicle" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.request_url= "foo.bar.com:443" + ,.num_headers= 3 + ,.upgrade="blarfcicle" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + , { "Content-Length", "10" } + } + ,.body= "" + } + +/* Examples from the Internet draft for LINK/UNLINK methods: + * https://tools.ietf.org/id/draft-snell-link-method-01.html#rfc.section.5 + */ + +#define LINK_REQUEST 40 +, {.name = "link request" + ,.type= HTTP_REQUEST + ,.raw= "LINK /images/my_dog.jpg HTTP/1.1\r\n" + "Host: example.com\r\n" + "Link: ; rel=\"tag\"\r\n" + "Link: ; rel=\"tag\"\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_LINK + ,.request_path= "/images/my_dog.jpg" + ,.request_url= "/images/my_dog.jpg" + ,.query_string= "" + ,.fragment= "" + ,.num_headers= 3 + ,.headers= { { "Host", "example.com" } + , { "Link", "; rel=\"tag\"" } + , { "Link", "; rel=\"tag\"" } + } + ,.body= "" + } + +#define UNLINK_REQUEST 41 +, {.name = "unlink request" + ,.type= HTTP_REQUEST + ,.raw= "UNLINK /images/my_dog.jpg HTTP/1.1\r\n" + "Host: example.com\r\n" + "Link: ; rel=\"tag\"\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_UNLINK + ,.request_path= "/images/my_dog.jpg" + ,.request_url= "/images/my_dog.jpg" + ,.query_string= "" + ,.fragment= "" + ,.num_headers= 2 + ,.headers= { { "Host", "example.com" } + , { "Link", "; rel=\"tag\"" } + } + ,.body= "" + } + +#define SOURCE_REQUEST 42 +, {.name = "source request" + ,.type= HTTP_REQUEST + ,.raw= "SOURCE /music/sweet/music HTTP/1.1\r\n" + "Host: example.com\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_SOURCE + ,.request_path= "/music/sweet/music" + ,.request_url= "/music/sweet/music" + ,.query_string= "" + ,.fragment= "" + ,.num_headers= 1 + ,.headers= { { "Host", "example.com" } } + ,.body= "" + } +}; + +/* * R E S P O N S E S * */ +const struct message responses[] = +#define GOOGLE_301 0 +{ {.name= "google 301" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 301 Moved Permanently\r\n" + "Location: http://www.google.com/\r\n" + "Content-Type: text/html; charset=UTF-8\r\n" + "Date: Sun, 26 Apr 2009 11:11:49 GMT\r\n" + "Expires: Tue, 26 May 2009 11:11:49 GMT\r\n" + "X-$PrototypeBI-Version: 1.6.0.3\r\n" /* $ char in header field */ + "Cache-Control: public, max-age=2592000\r\n" + "Server: gws\r\n" + "Content-Length: 219 \r\n" + "\r\n" + "\n" + "301 Moved\n" + "

301 Moved

\n" + "The document has moved\n" + "here.\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 301 + ,.response_status= "Moved Permanently" + ,.num_headers= 8 + ,.headers= + { { "Location", "http://www.google.com/" } + , { "Content-Type", "text/html; charset=UTF-8" } + , { "Date", "Sun, 26 Apr 2009 11:11:49 GMT" } + , { "Expires", "Tue, 26 May 2009 11:11:49 GMT" } + , { "X-$PrototypeBI-Version", "1.6.0.3" } + , { "Cache-Control", "public, max-age=2592000" } + , { "Server", "gws" } + , { "Content-Length", "219 " } + } + ,.body= "\n" + "301 Moved\n" + "

301 Moved

\n" + "The document has moved\n" + "here.\r\n" + "\r\n" + } + +#define NO_CONTENT_LENGTH_RESPONSE 1 +/* The client should wait for the server's EOF. That is, when content-length + * is not specified, and "Connection: close", the end of body is specified + * by the EOF. + * Compare with APACHEBENCH_GET + */ +, {.name= "no content-length response" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Date: Tue, 04 Aug 2009 07:59:32 GMT\r\n" + "Server: Apache\r\n" + "X-Powered-By: Servlet/2.5 JSP/2.1\r\n" + "Content-Type: text/xml; charset=utf-8\r\n" + "Connection: close\r\n" + "\r\n" + "\n" + "\n" + " \n" + " \n" + " SOAP-ENV:Client\n" + " Client Error\n" + " \n" + " \n" + "" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 5 + ,.headers= + { { "Date", "Tue, 04 Aug 2009 07:59:32 GMT" } + , { "Server", "Apache" } + , { "X-Powered-By", "Servlet/2.5 JSP/2.1" } + , { "Content-Type", "text/xml; charset=utf-8" } + , { "Connection", "close" } + } + ,.body= "\n" + "\n" + " \n" + " \n" + " SOAP-ENV:Client\n" + " Client Error\n" + " \n" + " \n" + "" + } + +#define NO_HEADERS_NO_BODY_404 2 +, {.name= "404 no headers no body" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 404 Not Found\r\n\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 404 + ,.response_status= "Not Found" + ,.num_headers= 0 + ,.headers= {} + ,.body_size= 0 + ,.body= "" + } + +#define NO_REASON_PHRASE 3 +, {.name= "301 no response phrase" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 301\r\n\r\n" + ,.should_keep_alive = FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 301 + ,.response_status= "" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define TRAILING_SPACE_ON_CHUNKED_BODY 4 +, {.name="200 trailing space on chunked body" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "25 \r\n" + "This is the data in the first chunk\r\n" + "\r\n" + "1C\r\n" + "and this is the second one\r\n" + "\r\n" + "0 \r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 2 + ,.headers= + { {"Content-Type", "text/plain" } + , {"Transfer-Encoding", "chunked" } + } + ,.body_size = 37+28 + ,.body = + "This is the data in the first chunk\r\n" + "and this is the second one\r\n" + ,.num_chunks_complete= 3 + ,.chunk_lengths= { 0x25, 0x1c } + } + +#define NO_CARRIAGE_RET 5 +, {.name="no carriage ret" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\n" + "Content-Type: text/html; charset=utf-8\n" + "Connection: close\n" + "\n" + "these headers are from http://news.ycombinator.com/" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 2 + ,.headers= + { {"Content-Type", "text/html; charset=utf-8" } + , {"Connection", "close" } + } + ,.body= "these headers are from http://news.ycombinator.com/" + } + +#define PROXY_CONNECTION 6 +, {.name="proxy connection" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html; charset=UTF-8\r\n" + "Content-Length: 11\r\n" + "Proxy-Connection: close\r\n" + "Date: Thu, 31 Dec 2009 20:55:48 +0000\r\n" + "\r\n" + "hello world" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 4 + ,.headers= + { {"Content-Type", "text/html; charset=UTF-8" } + , {"Content-Length", "11" } + , {"Proxy-Connection", "close" } + , {"Date", "Thu, 31 Dec 2009 20:55:48 +0000"} + } + ,.body= "hello world" + } + +#define UNDERSTORE_HEADER_KEY 7 + // shown by + // curl -o /dev/null -v "http://ad.doubleclick.net/pfadx/DARTSHELLCONFIGXML;dcmt=text/xml;" +, {.name="underscore header key" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Server: DCLK-AdSvr\r\n" + "Content-Type: text/xml\r\n" + "Content-Length: 0\r\n" + "DCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 4 + ,.headers= + { {"Server", "DCLK-AdSvr" } + , {"Content-Type", "text/xml" } + , {"Content-Length", "0" } + , {"DCLK_imp", "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o" } + } + ,.body= "" + } + +#define BONJOUR_MADAME_FR 8 +/* The client should not merge two headers fields when the first one doesn't + * have a value. + */ +, {.name= "bonjourmadame.fr" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.0 301 Moved Permanently\r\n" + "Date: Thu, 03 Jun 2010 09:56:32 GMT\r\n" + "Server: Apache/2.2.3 (Red Hat)\r\n" + "Cache-Control: public\r\n" + "Pragma: \r\n" + "Location: http://www.bonjourmadame.fr/\r\n" + "Vary: Accept-Encoding\r\n" + "Content-Length: 0\r\n" + "Content-Type: text/html; charset=UTF-8\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 301 + ,.response_status= "Moved Permanently" + ,.num_headers= 9 + ,.headers= + { { "Date", "Thu, 03 Jun 2010 09:56:32 GMT" } + , { "Server", "Apache/2.2.3 (Red Hat)" } + , { "Cache-Control", "public" } + , { "Pragma", "" } + , { "Location", "http://www.bonjourmadame.fr/" } + , { "Vary", "Accept-Encoding" } + , { "Content-Length", "0" } + , { "Content-Type", "text/html; charset=UTF-8" } + , { "Connection", "keep-alive" } + } + ,.body= "" + } + +#define RES_FIELD_UNDERSCORE 9 +/* Should handle spaces in header fields */ +, {.name= "field underscore" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Date: Tue, 28 Sep 2010 01:14:13 GMT\r\n" + "Server: Apache\r\n" + "Cache-Control: no-cache, must-revalidate\r\n" + "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n" + ".et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\n" + "Vary: Accept-Encoding\r\n" + "_eep-Alive: timeout=45\r\n" /* semantic value ignored */ + "_onnection: Keep-Alive\r\n" /* semantic value ignored */ + "Transfer-Encoding: chunked\r\n" + "Content-Type: text/html\r\n" + "Connection: close\r\n" + "\r\n" + "0\r\n\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 11 + ,.headers= + { { "Date", "Tue, 28 Sep 2010 01:14:13 GMT" } + , { "Server", "Apache" } + , { "Cache-Control", "no-cache, must-revalidate" } + , { "Expires", "Mon, 26 Jul 1997 05:00:00 GMT" } + , { ".et-Cookie", "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com" } + , { "Vary", "Accept-Encoding" } + , { "_eep-Alive", "timeout=45" } + , { "_onnection", "Keep-Alive" } + , { "Transfer-Encoding", "chunked" } + , { "Content-Type", "text/html" } + , { "Connection", "close" } + } + ,.body= "" + ,.num_chunks_complete= 1 + ,.chunk_lengths= {} + } + +#define NON_ASCII_IN_STATUS_LINE 10 +/* Should handle non-ASCII in status line */ +, {.name= "non-ASCII in status line" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 500 Oriëntatieprobleem\r\n" + "Date: Fri, 5 Nov 2010 23:07:12 GMT+2\r\n" + "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 500 + ,.response_status= "Oriëntatieprobleem" + ,.num_headers= 3 + ,.headers= + { { "Date", "Fri, 5 Nov 2010 23:07:12 GMT+2" } + , { "Content-Length", "0" } + , { "Connection", "close" } + } + ,.body= "" + } + +#define HTTP_VERSION_0_9 11 +/* Should handle HTTP/0.9 */ +, {.name= "http version 0.9" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/0.9 200 OK\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 0 + ,.http_minor= 9 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 0 + ,.headers= + {} + ,.body= "" + } + +#define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12 +/* The client should wait for the server's EOF. That is, when neither + * content-length nor transfer-encoding is specified, the end of body + * is specified by the EOF. + */ +, {.name= "neither content-length nor transfer-encoding response" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "hello world" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 1 + ,.headers= + { { "Content-Type", "text/plain" } + } + ,.body= "hello world" + } + +#define NO_BODY_HTTP10_KA_200 13 +, {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.0 200 OK\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 1 + ,.headers= + { { "Connection", "keep-alive" } + } + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP10_KA_204 14 +, {.name= "HTTP/1.0 with keep-alive and a 204 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.0 204 No content\r\n" + "Connection: keep-alive\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 204 + ,.response_status= "No content" + ,.num_headers= 1 + ,.headers= + { { "Connection", "keep-alive" } + } + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_KA_200 15 +, {.name= "HTTP/1.1 with an EOF-terminated 200 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 0 + ,.headers={} + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_KA_204 16 +, {.name= "HTTP/1.1 with a 204 status" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 204 No content\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 204 + ,.response_status= "No content" + ,.num_headers= 0 + ,.headers={} + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_NOKA_204 17 +, {.name= "HTTP/1.1 with a 204 status and keep-alive disabled" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 204 No content\r\n" + "Connection: close\r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 204 + ,.response_status= "No content" + ,.num_headers= 1 + ,.headers= + { { "Connection", "close" } + } + ,.body_size= 0 + ,.body= "" + } + +#define NO_BODY_HTTP11_KA_CHUNKED_200 18 +, {.name= "HTTP/1.1 with chunked endocing and a 200 response" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 1 + ,.headers= + { { "Transfer-Encoding", "chunked" } + } + ,.body_size= 0 + ,.body= "" + ,.num_chunks_complete= 1 + } + +#if !HTTP_PARSER_STRICT +#define SPACE_IN_FIELD_RES 19 +/* Should handle spaces in header fields */ +, {.name= "field space" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Server: Microsoft-IIS/6.0\r\n" + "X-Powered-By: ASP.NET\r\n" + "en-US Content-Type: text/xml\r\n" /* this is the problem */ + "Content-Type: text/xml\r\n" + "Content-Length: 16\r\n" + "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n" + "Connection: keep-alive\r\n" + "\r\n" + "hello" /* fake body */ + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 7 + ,.headers= + { { "Server", "Microsoft-IIS/6.0" } + , { "X-Powered-By", "ASP.NET" } + , { "en-US Content-Type", "text/xml" } + , { "Content-Type", "text/xml" } + , { "Content-Length", "16" } + , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" } + , { "Connection", "keep-alive" } + } + ,.body= "hello" + } +#endif /* !HTTP_PARSER_STRICT */ + +#define AMAZON_COM 20 +, {.name= "amazon.com" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 301 MovedPermanently\r\n" + "Date: Wed, 15 May 2013 17:06:33 GMT\r\n" + "Server: Server\r\n" + "x-amz-id-1: 0GPHKXSJQ826RK7GZEB2\r\n" + "p3p: policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"\r\n" + "x-amz-id-2: STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD\r\n" + "Location: http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846\r\n" + "Vary: Accept-Encoding,User-Agent\r\n" + "Content-Type: text/html; charset=ISO-8859-1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "1\r\n" + "\n\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 301 + ,.response_status= "MovedPermanently" + ,.num_headers= 9 + ,.headers= { { "Date", "Wed, 15 May 2013 17:06:33 GMT" } + , { "Server", "Server" } + , { "x-amz-id-1", "0GPHKXSJQ826RK7GZEB2" } + , { "p3p", "policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"" } + , { "x-amz-id-2", "STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD" } + , { "Location", "http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846" } + , { "Vary", "Accept-Encoding,User-Agent" } + , { "Content-Type", "text/html; charset=ISO-8859-1" } + , { "Transfer-Encoding", "chunked" } + } + ,.body= "\n" + ,.num_chunks_complete= 2 + ,.chunk_lengths= { 1 } + } + +#define EMPTY_REASON_PHRASE_AFTER_SPACE 20 +, {.name= "empty reason phrase after space" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 \r\n" + "\r\n" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "" + ,.num_headers= 0 + ,.headers= {} + ,.body= "" + } + +#define CONTENT_LENGTH_X 21 +, {.name= "Content-Length-X" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Content-Length-X: 0\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "2\r\n" + "OK\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 2 + ,.headers= { { "Content-Length-X", "0" } + , { "Transfer-Encoding", "chunked" } + } + ,.body= "OK" + ,.num_chunks_complete= 2 + ,.chunk_lengths= { 2 } + } + +#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER 22 +, {.name= "HTTP 101 response with Upgrade header" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 101 Switching Protocols\r\n" + "Connection: upgrade\r\n" + "Upgrade: h2c\r\n" + "\r\n" + "proto" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 101 + ,.response_status= "Switching Protocols" + ,.upgrade= "proto" + ,.num_headers= 2 + ,.headers= + { { "Connection", "upgrade" } + , { "Upgrade", "h2c" } + } + } + +#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 23 +, {.name= "HTTP 101 response with Upgrade and Content-Length header" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 101 Switching Protocols\r\n" + "Connection: upgrade\r\n" + "Upgrade: h2c\r\n" + "Content-Length: 4\r\n" + "\r\n" + "body" + "proto" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 101 + ,.response_status= "Switching Protocols" + ,.body= "body" + ,.upgrade= "proto" + ,.num_headers= 3 + ,.headers= + { { "Connection", "upgrade" } + , { "Upgrade", "h2c" } + , { "Content-Length", "4" } + } + } + +#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 24 +, {.name= "HTTP 101 response with Upgrade and Transfer-Encoding header" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 101 Switching Protocols\r\n" + "Connection: upgrade\r\n" + "Upgrade: h2c\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "2\r\n" + "bo\r\n" + "2\r\n" + "dy\r\n" + "0\r\n" + "\r\n" + "proto" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 101 + ,.response_status= "Switching Protocols" + ,.body= "body" + ,.upgrade= "proto" + ,.num_headers= 3 + ,.headers= + { { "Connection", "upgrade" } + , { "Upgrade", "h2c" } + , { "Transfer-Encoding", "chunked" } + } + ,.num_chunks_complete= 3 + ,.chunk_lengths= { 2, 2 } + } + +#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER 25 +, {.name= "HTTP 200 response with Upgrade header" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Connection: upgrade\r\n" + "Upgrade: h2c\r\n" + "\r\n" + "body" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.body= "body" + ,.upgrade= NULL + ,.num_headers= 2 + ,.headers= + { { "Connection", "upgrade" } + , { "Upgrade", "h2c" } + } + } + +#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 26 +, {.name= "HTTP 200 response with Upgrade and Content-Length header" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Connection: upgrade\r\n" + "Upgrade: h2c\r\n" + "Content-Length: 4\r\n" + "\r\n" + "body" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 3 + ,.body= "body" + ,.upgrade= NULL + ,.headers= + { { "Connection", "upgrade" } + , { "Upgrade", "h2c" } + , { "Content-Length", "4" } + } + } + +#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 27 +, {.name= "HTTP 200 response with Upgrade and Transfer-Encoding header" + ,.type= HTTP_RESPONSE + ,.raw= "HTTP/1.1 200 OK\r\n" + "Connection: upgrade\r\n" + "Upgrade: h2c\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "2\r\n" + "bo\r\n" + "2\r\n" + "dy\r\n" + "0\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 3 + ,.body= "body" + ,.upgrade= NULL + ,.headers= + { { "Connection", "upgrade" } + , { "Upgrade", "h2c" } + , { "Transfer-Encoding", "chunked" } + } + ,.num_chunks_complete= 3 + ,.chunk_lengths= { 2, 2 } + } +}; + +/* strnlen() is a POSIX.2008 addition. Can't rely on it being available so + * define it ourselves. + */ +size_t +strnlen(const char *s, size_t maxlen) +{ + const char *p; + + p = memchr(s, '\0', maxlen); + if (p == NULL) + return maxlen; + + return p - s; +} + +size_t +strlncat(char *dst, size_t len, const char *src, size_t n) +{ + size_t slen; + size_t dlen; + size_t rlen; + size_t ncpy; + + slen = strnlen(src, n); + dlen = strnlen(dst, len); + + if (dlen < len) { + rlen = len - dlen; + ncpy = slen < rlen ? slen : (rlen - 1); + memcpy(dst + dlen, src, ncpy); + dst[dlen + ncpy] = '\0'; + } + + assert(len > slen + dlen); + return slen + dlen; +} + +size_t +strlncpy(char *dst, size_t len, const char *src, size_t n) +{ + size_t slen; + size_t ncpy; + + slen = strnlen(src, n); + + if (len > 0) { + ncpy = slen < len ? slen : (len - 1); + memcpy(dst, src, ncpy); + dst[ncpy] = '\0'; + } + + assert(len > slen); + return slen; +} + +int +request_url_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + strlncat(messages[num_messages].request_url, + sizeof(messages[num_messages].request_url), + buf, + len); + return 0; +} + +int +header_field_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + struct message *m = &messages[num_messages]; + + if (m->last_header_element != FIELD) + m->num_headers++; + + strlncat(m->headers[m->num_headers-1][0], + sizeof(m->headers[m->num_headers-1][0]), + buf, + len); + + m->last_header_element = FIELD; + + return 0; +} + +int +header_value_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + struct message *m = &messages[num_messages]; + + strlncat(m->headers[m->num_headers-1][1], + sizeof(m->headers[m->num_headers-1][1]), + buf, + len); + + m->last_header_element = VALUE; + + return 0; +} + +void +check_body_is_final (const http_parser *p) +{ + if (messages[num_messages].body_is_final) { + fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " + "on last on_body callback call " + "but it doesn't! ***\n\n"); + assert(0); + abort(); + } + messages[num_messages].body_is_final = http_body_is_final(p); +} + +int +body_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + strlncat(messages[num_messages].body, + sizeof(messages[num_messages].body), + buf, + len); + messages[num_messages].body_size += len; + check_body_is_final(p); + // printf("body_cb: '%s'\n", requests[num_messages].body); + return 0; +} + +int +count_body_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + assert(buf); + messages[num_messages].body_size += len; + check_body_is_final(p); + return 0; +} + +int +message_begin_cb (http_parser *p) +{ + assert(p == parser); + messages[num_messages].message_begin_cb_called = TRUE; + return 0; +} + +int +headers_complete_cb (http_parser *p) +{ + assert(p == parser); + messages[num_messages].method = parser->method; + messages[num_messages].status_code = parser->status_code; + messages[num_messages].http_major = parser->http_major; + messages[num_messages].http_minor = parser->http_minor; + messages[num_messages].headers_complete_cb_called = TRUE; + messages[num_messages].should_keep_alive = http_should_keep_alive(parser); + return 0; +} + +int +message_complete_cb (http_parser *p) +{ + assert(p == parser); + if (messages[num_messages].should_keep_alive != http_should_keep_alive(parser)) + { + fprintf(stderr, "\n\n *** Error http_should_keep_alive() should have same " + "value in both on_message_complete and on_headers_complete " + "but it doesn't! ***\n\n"); + assert(0); + abort(); + } + + if (messages[num_messages].body_size && + http_body_is_final(p) && + !messages[num_messages].body_is_final) + { + fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " + "on last on_body callback call " + "but it doesn't! ***\n\n"); + assert(0); + abort(); + } + + messages[num_messages].message_complete_cb_called = TRUE; + + messages[num_messages].message_complete_on_eof = currently_parsing_eof; + + num_messages++; + return 0; +} + +int +response_status_cb (http_parser *p, const char *buf, size_t len) +{ + assert(p == parser); + + messages[num_messages].status_cb_called = TRUE; + + strlncat(messages[num_messages].response_status, + sizeof(messages[num_messages].response_status), + buf, + len); + return 0; +} + +int +chunk_header_cb (http_parser *p) +{ + assert(p == parser); + int chunk_idx = messages[num_messages].num_chunks; + messages[num_messages].num_chunks++; + if (chunk_idx < MAX_CHUNKS) { + messages[num_messages].chunk_lengths[chunk_idx] = p->content_length; + } + + return 0; +} + +int +chunk_complete_cb (http_parser *p) +{ + assert(p == parser); + + /* Here we want to verify that each chunk_header_cb is matched by a + * chunk_complete_cb, so not only should the total number of calls to + * both callbacks be the same, but they also should be interleaved + * properly */ + assert(messages[num_messages].num_chunks == + messages[num_messages].num_chunks_complete + 1); + + messages[num_messages].num_chunks_complete++; + return 0; +} + +/* These dontcall_* callbacks exist so that we can verify that when we're + * paused, no additional callbacks are invoked */ +int +dontcall_message_begin_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_message_begin() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_header_field_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_header_field() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_header_value_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_header_value() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_request_url_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_request_url() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_body_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_body_cb() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_headers_complete_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_headers_complete() called on paused " + "parser ***\n\n"); + abort(); +} + +int +dontcall_message_complete_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_message_complete() called on paused " + "parser ***\n\n"); + abort(); +} + +int +dontcall_response_status_cb (http_parser *p, const char *buf, size_t len) +{ + if (p || buf || len) { } // gcc + fprintf(stderr, "\n\n*** on_status() called on paused parser ***\n\n"); + abort(); +} + +int +dontcall_chunk_header_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_chunk_header() called on paused parser ***\n\n"); + exit(1); +} + +int +dontcall_chunk_complete_cb (http_parser *p) +{ + if (p) { } // gcc + fprintf(stderr, "\n\n*** on_chunk_complete() " + "called on paused parser ***\n\n"); + exit(1); +} + +static http_parser_settings settings_dontcall = + {.on_message_begin = dontcall_message_begin_cb + ,.on_header_field = dontcall_header_field_cb + ,.on_header_value = dontcall_header_value_cb + ,.on_url = dontcall_request_url_cb + ,.on_status = dontcall_response_status_cb + ,.on_body = dontcall_body_cb + ,.on_headers_complete = dontcall_headers_complete_cb + ,.on_message_complete = dontcall_message_complete_cb + ,.on_chunk_header = dontcall_chunk_header_cb + ,.on_chunk_complete = dontcall_chunk_complete_cb + }; + +/* These pause_* callbacks always pause the parser and just invoke the regular + * callback that tracks content. Before returning, we overwrite the parser + * settings to point to the _dontcall variety so that we can verify that + * the pause actually did, you know, pause. */ +int +pause_message_begin_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return message_begin_cb(p); +} + +int +pause_header_field_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return header_field_cb(p, buf, len); +} + +int +pause_header_value_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return header_value_cb(p, buf, len); +} + +int +pause_request_url_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return request_url_cb(p, buf, len); +} + +int +pause_body_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return body_cb(p, buf, len); +} + +int +pause_headers_complete_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return headers_complete_cb(p); +} + +int +pause_message_complete_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return message_complete_cb(p); +} + +int +pause_response_status_cb (http_parser *p, const char *buf, size_t len) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return response_status_cb(p, buf, len); +} + +int +pause_chunk_header_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return chunk_header_cb(p); +} + +int +pause_chunk_complete_cb (http_parser *p) +{ + http_parser_pause(p, 1); + *current_pause_parser = settings_dontcall; + return chunk_complete_cb(p); +} + +int +connect_headers_complete_cb (http_parser *p) +{ + headers_complete_cb(p); + return 1; +} + +int +connect_message_complete_cb (http_parser *p) +{ + messages[num_messages].should_keep_alive = http_should_keep_alive(parser); + return message_complete_cb(p); +} + +static http_parser_settings settings_pause = + {.on_message_begin = pause_message_begin_cb + ,.on_header_field = pause_header_field_cb + ,.on_header_value = pause_header_value_cb + ,.on_url = pause_request_url_cb + ,.on_status = pause_response_status_cb + ,.on_body = pause_body_cb + ,.on_headers_complete = pause_headers_complete_cb + ,.on_message_complete = pause_message_complete_cb + ,.on_chunk_header = pause_chunk_header_cb + ,.on_chunk_complete = pause_chunk_complete_cb + }; + +static http_parser_settings settings = + {.on_message_begin = message_begin_cb + ,.on_header_field = header_field_cb + ,.on_header_value = header_value_cb + ,.on_url = request_url_cb + ,.on_status = response_status_cb + ,.on_body = body_cb + ,.on_headers_complete = headers_complete_cb + ,.on_message_complete = message_complete_cb + ,.on_chunk_header = chunk_header_cb + ,.on_chunk_complete = chunk_complete_cb + }; + +static http_parser_settings settings_count_body = + {.on_message_begin = message_begin_cb + ,.on_header_field = header_field_cb + ,.on_header_value = header_value_cb + ,.on_url = request_url_cb + ,.on_status = response_status_cb + ,.on_body = count_body_cb + ,.on_headers_complete = headers_complete_cb + ,.on_message_complete = message_complete_cb + ,.on_chunk_header = chunk_header_cb + ,.on_chunk_complete = chunk_complete_cb + }; + +static http_parser_settings settings_connect = + {.on_message_begin = message_begin_cb + ,.on_header_field = header_field_cb + ,.on_header_value = header_value_cb + ,.on_url = request_url_cb + ,.on_status = response_status_cb + ,.on_body = dontcall_body_cb + ,.on_headers_complete = connect_headers_complete_cb + ,.on_message_complete = connect_message_complete_cb + ,.on_chunk_header = chunk_header_cb + ,.on_chunk_complete = chunk_complete_cb + }; + +static http_parser_settings settings_null = + {.on_message_begin = 0 + ,.on_header_field = 0 + ,.on_header_value = 0 + ,.on_url = 0 + ,.on_status = 0 + ,.on_body = 0 + ,.on_headers_complete = 0 + ,.on_message_complete = 0 + ,.on_chunk_header = 0 + ,.on_chunk_complete = 0 + }; + +void +parser_init (enum http_parser_type type) +{ + num_messages = 0; + + assert(parser == NULL); + + parser = malloc(sizeof(http_parser)); + + http_parser_init(parser, type); + + memset(&messages, 0, sizeof messages); + +} + +void +parser_free () +{ + assert(parser); + free(parser); + parser = NULL; +} + +size_t parse (const char *buf, size_t len) +{ + size_t nparsed; + currently_parsing_eof = (len == 0); + nparsed = http_parser_execute(parser, &settings, buf, len); + return nparsed; +} + +size_t parse_count_body (const char *buf, size_t len) +{ + size_t nparsed; + currently_parsing_eof = (len == 0); + nparsed = http_parser_execute(parser, &settings_count_body, buf, len); + return nparsed; +} + +size_t parse_pause (const char *buf, size_t len) +{ + size_t nparsed; + http_parser_settings s = settings_pause; + + currently_parsing_eof = (len == 0); + current_pause_parser = &s; + nparsed = http_parser_execute(parser, current_pause_parser, buf, len); + return nparsed; +} + +size_t parse_connect (const char *buf, size_t len) +{ + size_t nparsed; + currently_parsing_eof = (len == 0); + nparsed = http_parser_execute(parser, &settings_connect, buf, len); + return nparsed; +} + +static inline int +check_str_eq (const struct message *m, + const char *prop, + const char *expected, + const char *found) { + if ((expected == NULL) != (found == NULL)) { + printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); + printf("expected %s\n", (expected == NULL) ? "NULL" : expected); + printf(" found %s\n", (found == NULL) ? "NULL" : found); + return 0; + } + if (expected != NULL && 0 != strcmp(expected, found)) { + printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); + printf("expected '%s'\n", expected); + printf(" found '%s'\n", found); + return 0; + } + return 1; +} + +static inline int +check_num_eq (const struct message *m, + const char *prop, + int expected, + int found) { + if (expected != found) { + printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); + printf("expected %d\n", expected); + printf(" found %d\n", found); + return 0; + } + return 1; +} + +#define MESSAGE_CHECK_STR_EQ(expected, found, prop) \ + if (!check_str_eq(expected, #prop, expected->prop, found->prop)) return 0 + +#define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \ + if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0 + +#define MESSAGE_CHECK_URL_EQ(u, expected, found, prop, fn) \ +do { \ + char ubuf[256]; \ + \ + if ((u)->field_set & (1 << (fn))) { \ + memcpy(ubuf, (found)->request_url + (u)->field_data[(fn)].off, \ + (u)->field_data[(fn)].len); \ + ubuf[(u)->field_data[(fn)].len] = '\0'; \ + } else { \ + ubuf[0] = '\0'; \ + } \ + \ + check_str_eq(expected, #prop, expected->prop, ubuf); \ +} while(0) + +int +message_eq (int index, int connect, const struct message *expected) +{ + int i; + struct message *m = &messages[index]; + + MESSAGE_CHECK_NUM_EQ(expected, m, http_major); + MESSAGE_CHECK_NUM_EQ(expected, m, http_minor); + + if (expected->type == HTTP_REQUEST) { + MESSAGE_CHECK_NUM_EQ(expected, m, method); + } else { + MESSAGE_CHECK_NUM_EQ(expected, m, status_code); + MESSAGE_CHECK_STR_EQ(expected, m, response_status); + assert(m->status_cb_called); + } + + if (!connect) { + MESSAGE_CHECK_NUM_EQ(expected, m, should_keep_alive); + MESSAGE_CHECK_NUM_EQ(expected, m, message_complete_on_eof); + } + + assert(m->message_begin_cb_called); + assert(m->headers_complete_cb_called); + assert(m->message_complete_cb_called); + + + MESSAGE_CHECK_STR_EQ(expected, m, request_url); + + /* Check URL components; we can't do this w/ CONNECT since it doesn't + * send us a well-formed URL. + */ + if (*m->request_url && m->method != HTTP_CONNECT) { + struct http_parser_url u; + + if (http_parser_parse_url(m->request_url, strlen(m->request_url), 0, &u)) { + fprintf(stderr, "\n\n*** failed to parse URL %s ***\n\n", + m->request_url); + abort(); + } + + if (expected->host) { + MESSAGE_CHECK_URL_EQ(&u, expected, m, host, UF_HOST); + } + + if (expected->userinfo) { + MESSAGE_CHECK_URL_EQ(&u, expected, m, userinfo, UF_USERINFO); + } + + m->port = (u.field_set & (1 << UF_PORT)) ? + u.port : 0; + + MESSAGE_CHECK_URL_EQ(&u, expected, m, query_string, UF_QUERY); + MESSAGE_CHECK_URL_EQ(&u, expected, m, fragment, UF_FRAGMENT); + MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH); + MESSAGE_CHECK_NUM_EQ(expected, m, port); + } + + if (connect) { + check_num_eq(m, "body_size", 0, m->body_size); + } else if (expected->body_size) { + MESSAGE_CHECK_NUM_EQ(expected, m, body_size); + } else { + MESSAGE_CHECK_STR_EQ(expected, m, body); + } + + if (connect) { + check_num_eq(m, "num_chunks_complete", 0, m->num_chunks_complete); + } else { + assert(m->num_chunks == m->num_chunks_complete); + MESSAGE_CHECK_NUM_EQ(expected, m, num_chunks_complete); + for (i = 0; i < m->num_chunks && i < MAX_CHUNKS; i++) { + MESSAGE_CHECK_NUM_EQ(expected, m, chunk_lengths[i]); + } + } + + MESSAGE_CHECK_NUM_EQ(expected, m, num_headers); + + int r; + for (i = 0; i < m->num_headers; i++) { + r = check_str_eq(expected, "header field", expected->headers[i][0], m->headers[i][0]); + if (!r) return 0; + r = check_str_eq(expected, "header value", expected->headers[i][1], m->headers[i][1]); + if (!r) return 0; + } + + if (!connect) { + MESSAGE_CHECK_STR_EQ(expected, m, upgrade); + } + + return 1; +} + +/* Given a sequence of varargs messages, return the number of them that the + * parser should successfully parse, taking into account that upgraded + * messages prevent all subsequent messages from being parsed. + */ +size_t +count_parsed_messages(const size_t nmsgs, ...) { + size_t i; + va_list ap; + + va_start(ap, nmsgs); + + for (i = 0; i < nmsgs; i++) { + struct message *m = va_arg(ap, struct message *); + + if (m->upgrade) { + va_end(ap); + return i + 1; + } + } + + va_end(ap); + return nmsgs; +} + +/* Given a sequence of bytes and the number of these that we were able to + * parse, verify that upgrade bodies are correct. + */ +void +upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) { + va_list ap; + size_t i; + size_t off = 0; + + va_start(ap, nmsgs); + + for (i = 0; i < nmsgs; i++) { + struct message *m = va_arg(ap, struct message *); + + off += strlen(m->raw); + + if (m->upgrade) { + off -= strlen(m->upgrade); + + /* Check the portion of the response after its specified upgrade */ + if (!check_str_eq(m, "upgrade", body + off, body + nread)) { + abort(); + } + + /* Fix up the response so that message_eq() will verify the beginning + * of the upgrade */ + *(body + nread + strlen(m->upgrade)) = '\0'; + messages[num_messages -1 ].upgrade = body + nread; + + va_end(ap); + return; + } + } + + va_end(ap); + printf("\n\n*** Error: expected a message with upgrade ***\n"); + + abort(); +} + +static void +print_error (const char *raw, size_t error_location) +{ + fprintf(stderr, "\n*** %s ***\n\n", + http_errno_description(HTTP_PARSER_ERRNO(parser))); + + int this_line = 0, char_len = 0; + size_t i, j, len = strlen(raw), error_location_line = 0; + for (i = 0; i < len; i++) { + if (i == error_location) this_line = 1; + switch (raw[i]) { + case '\r': + char_len = 2; + fprintf(stderr, "\\r"); + break; + + case '\n': + fprintf(stderr, "\\n\n"); + + if (this_line) goto print; + + error_location_line = 0; + continue; + + default: + char_len = 1; + fputc(raw[i], stderr); + break; + } + if (!this_line) error_location_line += char_len; + } + + fprintf(stderr, "[eof]\n"); + + print: + for (j = 0; j < error_location_line; j++) { + fputc(' ', stderr); + } + fprintf(stderr, "^\n\nerror location: %u\n", (unsigned int)error_location); +} + +void +test_preserve_data (void) +{ + char my_data[] = "application-specific data"; + http_parser parser; + parser.data = my_data; + http_parser_init(&parser, HTTP_REQUEST); + if (parser.data != my_data) { + printf("\n*** parser.data not preserved accross http_parser_init ***\n\n"); + abort(); + } +} + +struct url_test { + const char *name; + const char *url; + int is_connect; + struct http_parser_url u; + int rv; +}; + +const struct url_test url_tests[] = +{ {.name="proxy request" + ,.url="http://hostname/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) + ,.port=0 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 7, 8 } /* UF_HOST */ + ,{ 0, 0 } /* UF_PORT */ + ,{ 15, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="proxy request with port" + ,.url="http://hostname:444/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) + ,.port=444 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 7, 8 } /* UF_HOST */ + ,{ 16, 3 } /* UF_PORT */ + ,{ 19, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="CONNECT request" + ,.url="hostname:443" + ,.is_connect=1 + ,.u= + {.field_set=(1 << UF_HOST) | (1 << UF_PORT) + ,.port=443 + ,.field_data= + {{ 0, 0 } /* UF_SCHEMA */ + ,{ 0, 8 } /* UF_HOST */ + ,{ 9, 3 } /* UF_PORT */ + ,{ 0, 0 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="CONNECT request but not connect" + ,.url="hostname:443" + ,.is_connect=0 + ,.rv=1 + } + +, {.name="proxy ipv6 request" + ,.url="http://[1:2::3:4]/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) + ,.port=0 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 8, 8 } /* UF_HOST */ + ,{ 0, 0 } /* UF_PORT */ + ,{ 17, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="proxy ipv6 request with port" + ,.url="http://[1:2::3:4]:67/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) + ,.port=67 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 8, 8 } /* UF_HOST */ + ,{ 18, 2 } /* UF_PORT */ + ,{ 20, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="CONNECT ipv6 address" + ,.url="[1:2::3:4]:443" + ,.is_connect=1 + ,.u= + {.field_set=(1 << UF_HOST) | (1 << UF_PORT) + ,.port=443 + ,.field_data= + {{ 0, 0 } /* UF_SCHEMA */ + ,{ 1, 8 } /* UF_HOST */ + ,{ 11, 3 } /* UF_PORT */ + ,{ 0, 0 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="ipv4 in ipv6 address" + ,.url="http://[2001:0000:0000:0000:0000:0000:1.9.1.1]/" + ,.is_connect=0 + ,.u= + {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) + ,.port=0 + ,.field_data= + {{ 0, 4 } /* UF_SCHEMA */ + ,{ 8, 37 } /* UF_HOST */ + ,{ 0, 0 } /* UF_PORT */ + ,{ 46, 1 } /* UF_PATH */ + ,{ 0, 0 } /* UF_QUERY */ + ,{ 0, 0 } /* UF_FRAGMENT */ + ,{ 0, 0 } /* UF_USERINFO */ + } + } + ,.rv=0 + } + +, {.name="extra ? in query string" + ,.url="http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css," + "fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css," + "fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css" + ,.is_connect=0 + ,.u= + {.field_set=(1<field_set, u->port); + for (i = 0; i < UF_MAX; i++) { + if ((u->field_set & (1 << i)) == 0) { + printf("\tfield_data[%u]: unset\n", i); + continue; + } + + printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n\"", + i, + u->field_data[i].off, + u->field_data[i].len, + u->field_data[i].len, + url + u->field_data[i].off); + } +} + +void +test_parse_url (void) +{ + struct http_parser_url u; + const struct url_test *test; + unsigned int i; + int rv; + + for (i = 0; i < (sizeof(url_tests) / sizeof(url_tests[0])); i++) { + test = &url_tests[i]; + memset(&u, 0, sizeof(u)); + + rv = http_parser_parse_url(test->url, + strlen(test->url), + test->is_connect, + &u); + + if (test->rv == 0) { + if (rv != 0) { + printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " + "unexpected rv %d ***\n\n", test->url, test->name, rv); + abort(); + } + + if (memcmp(&u, &test->u, sizeof(u)) != 0) { + printf("\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n", + test->url, test->name); + + printf("target http_parser_url:\n"); + dump_url(test->url, &test->u); + printf("result http_parser_url:\n"); + dump_url(test->url, &u); + + abort(); + } + } else { + /* test->rv != 0 */ + if (rv == 0) { + printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " + "unexpected rv %d ***\n\n", test->url, test->name, rv); + abort(); + } + } + } +} + +void +test_method_str (void) +{ + assert(0 == strcmp("GET", http_method_str(HTTP_GET))); + assert(0 == strcmp("", http_method_str(1337))); +} + +void +test_message (const struct message *message) +{ + size_t raw_len = strlen(message->raw); + size_t msg1len; + for (msg1len = 0; msg1len < raw_len; msg1len++) { + parser_init(message->type); + + size_t read; + const char *msg1 = message->raw; + const char *msg2 = msg1 + msg1len; + size_t msg2len = raw_len - msg1len; + + if (msg1len) { + read = parse(msg1, msg1len); + + if (message->upgrade && parser->upgrade && num_messages > 0) { + messages[num_messages - 1].upgrade = msg1 + read; + goto test; + } + + if (read != msg1len) { + print_error(msg1, read); + abort(); + } + } + + + read = parse(msg2, msg2len); + + if (message->upgrade && parser->upgrade) { + messages[num_messages - 1].upgrade = msg2 + read; + goto test; + } + + if (read != msg2len) { + print_error(msg2, read); + abort(); + } + + read = parse(NULL, 0); + + if (read != 0) { + print_error(message->raw, read); + abort(); + } + + test: + + if (num_messages != 1) { + printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); + abort(); + } + + if(!message_eq(0, 0, message)) abort(); + + parser_free(); + } +} + +void +test_message_count_body (const struct message *message) +{ + parser_init(message->type); + + size_t read; + size_t l = strlen(message->raw); + size_t i, toread; + size_t chunk = 4024; + + for (i = 0; i < l; i+= chunk) { + toread = MIN(l-i, chunk); + read = parse_count_body(message->raw + i, toread); + if (read != toread) { + print_error(message->raw, read); + abort(); + } + } + + + read = parse_count_body(NULL, 0); + if (read != 0) { + print_error(message->raw, read); + abort(); + } + + if (num_messages != 1) { + printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); + abort(); + } + + if(!message_eq(0, 0, message)) abort(); + + parser_free(); +} + +void +test_simple_type (const char *buf, + enum http_errno err_expected, + enum http_parser_type type) +{ + parser_init(type); + + enum http_errno err; + + parse(buf, strlen(buf)); + err = HTTP_PARSER_ERRNO(parser); + parse(NULL, 0); + + parser_free(); + + /* In strict mode, allow us to pass with an unexpected HPE_STRICT as + * long as the caller isn't expecting success. + */ +#if HTTP_PARSER_STRICT + if (err_expected != err && err_expected != HPE_OK && err != HPE_STRICT) { +#else + if (err_expected != err) { +#endif + fprintf(stderr, "\n*** test_simple expected %s, but saw %s ***\n\n%s\n", + http_errno_name(err_expected), http_errno_name(err), buf); + abort(); + } +} + +void +test_simple (const char *buf, enum http_errno err_expected) +{ + test_simple_type(buf, err_expected, HTTP_REQUEST); +} + +void +test_invalid_header_content (int req, const char* str) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + const char *buf; + buf = req ? + "GET / HTTP/1.1\r\n" : + "HTTP/1.1 200 OK\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + buf = str; + size_t buflen = strlen(buf); + + parsed = http_parser_execute(&parser, &settings_null, buf, buflen); + if (parsed != buflen) { + assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_HEADER_TOKEN); + return; + } + + fprintf(stderr, + "\n*** Error expected but none in invalid header content test ***\n"); + abort(); +} + +void +test_invalid_header_field_content_error (int req) +{ + test_invalid_header_content(req, "Foo: F\01ailure"); + test_invalid_header_content(req, "Foo: B\02ar"); +} + +void +test_invalid_header_field (int req, const char* str) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + const char *buf; + buf = req ? + "GET / HTTP/1.1\r\n" : + "HTTP/1.1 200 OK\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + buf = str; + size_t buflen = strlen(buf); + + parsed = http_parser_execute(&parser, &settings_null, buf, buflen); + if (parsed != buflen) { + assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_HEADER_TOKEN); + return; + } + + fprintf(stderr, + "\n*** Error expected but none in invalid header token test ***\n"); + abort(); +} + +void +test_invalid_header_field_token_error (int req) +{ + test_invalid_header_field(req, "Fo@: Failure"); + test_invalid_header_field(req, "Foo\01\test: Bar"); +} + +void +test_double_content_length_error (int req) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + const char *buf; + buf = req ? + "GET / HTTP/1.1\r\n" : + "HTTP/1.1 200 OK\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + buf = "Content-Length: 0\r\nContent-Length: 1\r\n\r\n"; + size_t buflen = strlen(buf); + + parsed = http_parser_execute(&parser, &settings_null, buf, buflen); + if (parsed != buflen) { + assert(HTTP_PARSER_ERRNO(&parser) == HPE_UNEXPECTED_CONTENT_LENGTH); + return; + } + + fprintf(stderr, + "\n*** Error expected but none in double content-length test ***\n"); + abort(); +} + +void +test_chunked_content_length_error (int req) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + const char *buf; + buf = req ? + "GET / HTTP/1.1\r\n" : + "HTTP/1.1 200 OK\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + buf = "Transfer-Encoding: chunked\r\nContent-Length: 1\r\n\r\n"; + size_t buflen = strlen(buf); + + parsed = http_parser_execute(&parser, &settings_null, buf, buflen); + if (parsed != buflen) { + assert(HTTP_PARSER_ERRNO(&parser) == HPE_UNEXPECTED_CONTENT_LENGTH); + return; + } + + fprintf(stderr, + "\n*** Error expected but none in chunked content-length test ***\n"); + abort(); +} + +void +test_header_cr_no_lf_error (int req) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + const char *buf; + buf = req ? + "GET / HTTP/1.1\r\n" : + "HTTP/1.1 200 OK\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + buf = "Foo: 1\rBar: 1\r\n\r\n"; + size_t buflen = strlen(buf); + + parsed = http_parser_execute(&parser, &settings_null, buf, buflen); + if (parsed != buflen) { + assert(HTTP_PARSER_ERRNO(&parser) == HPE_LF_EXPECTED); + return; + } + + fprintf(stderr, + "\n*** Error expected but none in header whitespace test ***\n"); + abort(); +} + +void +test_no_overflow_parse_url (void) +{ + int rv; + struct http_parser_url u; + + http_parser_url_init(&u); + rv = http_parser_parse_url("http://example.com:8001", 22, 0, &u); + + if (rv != 0) { + fprintf(stderr, + "\n*** test_no_overflow_parse_url invalid return value=%d\n", + rv); + abort(); + } + + if (u.port != 800) { + fprintf(stderr, + "\n*** test_no_overflow_parse_url invalid port number=%d\n", + u.port); + abort(); + } +} + +void +test_header_overflow_error (int req) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + const char *buf; + buf = req ? "GET / HTTP/1.1\r\n" : "HTTP/1.0 200 OK\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + buf = "header-key: header-value\r\n"; + size_t buflen = strlen(buf); + + int i; + for (i = 0; i < 10000; i++) { + parsed = http_parser_execute(&parser, &settings_null, buf, buflen); + if (parsed != buflen) { + //fprintf(stderr, "error found on iter %d\n", i); + assert(HTTP_PARSER_ERRNO(&parser) == HPE_HEADER_OVERFLOW); + return; + } + } + + fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n"); + abort(); +} + + +void +test_header_nread_value () +{ + http_parser parser; + http_parser_init(&parser, HTTP_REQUEST); + size_t parsed; + const char *buf; + buf = "GET / HTTP/1.1\r\nheader: value\nhdr: value\r\n"; + parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); + assert(parsed == strlen(buf)); + + assert(parser.nread == strlen(buf)); +} + + +static void +test_content_length_overflow (const char *buf, size_t buflen, int expect_ok) +{ + http_parser parser; + http_parser_init(&parser, HTTP_RESPONSE); + http_parser_execute(&parser, &settings_null, buf, buflen); + + if (expect_ok) + assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK); + else + assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CONTENT_LENGTH); +} + +void +test_header_content_length_overflow_error (void) +{ +#define X(size) \ + "HTTP/1.1 200 OK\r\n" \ + "Content-Length: " #size "\r\n" \ + "\r\n" + const char a[] = X(1844674407370955160); /* 2^64 / 10 - 1 */ + const char b[] = X(18446744073709551615); /* 2^64-1 */ + const char c[] = X(18446744073709551616); /* 2^64 */ +#undef X + test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ + test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ + test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ +} + +void +test_chunk_content_length_overflow_error (void) +{ +#define X(size) \ + "HTTP/1.1 200 OK\r\n" \ + "Transfer-Encoding: chunked\r\n" \ + "\r\n" \ + #size "\r\n" \ + "..." + const char a[] = X(FFFFFFFFFFFFFFE); /* 2^64 / 16 - 1 */ + const char b[] = X(FFFFFFFFFFFFFFFF); /* 2^64-1 */ + const char c[] = X(10000000000000000); /* 2^64 */ +#undef X + test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ + test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ + test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ +} + +void +test_no_overflow_long_body (int req, size_t length) +{ + http_parser parser; + http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); + size_t parsed; + size_t i; + char buf1[3000]; + size_t buf1len = sprintf(buf1, "%s\r\nConnection: Keep-Alive\r\nContent-Length: %lu\r\n\r\n", + req ? "POST / HTTP/1.0" : "HTTP/1.0 200 OK", (unsigned long)length); + parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); + if (parsed != buf1len) + goto err; + + for (i = 0; i < length; i++) { + char foo = 'a'; + parsed = http_parser_execute(&parser, &settings_null, &foo, 1); + if (parsed != 1) + goto err; + } + + parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); + if (parsed != buf1len) goto err; + return; + + err: + fprintf(stderr, + "\n*** error in test_no_overflow_long_body %s of length %lu ***\n", + req ? "REQUEST" : "RESPONSE", + (unsigned long)length); + abort(); +} + +void +test_multiple3 (const struct message *r1, const struct message *r2, const struct message *r3) +{ + int message_count = count_parsed_messages(3, r1, r2, r3); + + char total[ strlen(r1->raw) + + strlen(r2->raw) + + strlen(r3->raw) + + 1 + ]; + total[0] = '\0'; + + strcat(total, r1->raw); + strcat(total, r2->raw); + strcat(total, r3->raw); + + parser_init(r1->type); + + size_t read; + + read = parse(total, strlen(total)); + + if (parser->upgrade) { + upgrade_message_fix(total, read, 3, r1, r2, r3); + goto test; + } + + if (read != strlen(total)) { + print_error(total, read); + abort(); + } + + read = parse(NULL, 0); + + if (read != 0) { + print_error(total, read); + abort(); + } + +test: + + if (message_count != num_messages) { + fprintf(stderr, "\n\n*** Parser didn't see 3 messages only %d *** \n", num_messages); + abort(); + } + + if (!message_eq(0, 0, r1)) abort(); + if (message_count > 1 && !message_eq(1, 0, r2)) abort(); + if (message_count > 2 && !message_eq(2, 0, r3)) abort(); + + parser_free(); +} + +/* SCAN through every possible breaking to make sure the + * parser can handle getting the content in any chunks that + * might come from the socket + */ +void +test_scan (const struct message *r1, const struct message *r2, const struct message *r3) +{ + char total[80*1024] = "\0"; + char buf1[80*1024] = "\0"; + char buf2[80*1024] = "\0"; + char buf3[80*1024] = "\0"; + + strcat(total, r1->raw); + strcat(total, r2->raw); + strcat(total, r3->raw); + + size_t read; + + int total_len = strlen(total); + + int total_ops = 2 * (total_len - 1) * (total_len - 2) / 2; + int ops = 0 ; + + size_t buf1_len, buf2_len, buf3_len; + int message_count = count_parsed_messages(3, r1, r2, r3); + + int i,j,type_both; + for (type_both = 0; type_both < 2; type_both ++ ) { + for (j = 2; j < total_len; j ++ ) { + for (i = 1; i < j; i ++ ) { + + if (ops % 1000 == 0) { + printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops); + fflush(stdout); + } + ops += 1; + + parser_init(type_both ? HTTP_BOTH : r1->type); + + buf1_len = i; + strlncpy(buf1, sizeof(buf1), total, buf1_len); + buf1[buf1_len] = 0; + + buf2_len = j - i; + strlncpy(buf2, sizeof(buf1), total+i, buf2_len); + buf2[buf2_len] = 0; + + buf3_len = total_len - j; + strlncpy(buf3, sizeof(buf1), total+j, buf3_len); + buf3[buf3_len] = 0; + + read = parse(buf1, buf1_len); + + if (parser->upgrade) goto test; + + if (read != buf1_len) { + print_error(buf1, read); + goto error; + } + + read += parse(buf2, buf2_len); + + if (parser->upgrade) goto test; + + if (read != buf1_len + buf2_len) { + print_error(buf2, read); + goto error; + } + + read += parse(buf3, buf3_len); + + if (parser->upgrade) goto test; + + if (read != buf1_len + buf2_len + buf3_len) { + print_error(buf3, read); + goto error; + } + + parse(NULL, 0); + +test: + if (parser->upgrade) { + upgrade_message_fix(total, read, 3, r1, r2, r3); + } + + if (message_count != num_messages) { + fprintf(stderr, "\n\nParser didn't see %d messages only %d\n", + message_count, num_messages); + goto error; + } + + if (!message_eq(0, 0, r1)) { + fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n"); + goto error; + } + + if (message_count > 1 && !message_eq(1, 0, r2)) { + fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n"); + goto error; + } + + if (message_count > 2 && !message_eq(2, 0, r3)) { + fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n"); + goto error; + } + + parser_free(); + } + } + } + puts("\b\b\b\b100%"); + return; + + error: + fprintf(stderr, "i=%d j=%d\n", i, j); + fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1); + fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2); + fprintf(stderr, "buf3 (%u) %s\n", (unsigned int)buf3_len, buf3); + abort(); +} + +// user required to free the result +// string terminated by \0 +char * +create_large_chunked_message (int body_size_in_kb, const char* headers) +{ + int i; + size_t wrote = 0; + size_t headers_len = strlen(headers); + size_t bufsize = headers_len + (5+1024+2)*body_size_in_kb + 6; + char * buf = malloc(bufsize); + + memcpy(buf, headers, headers_len); + wrote += headers_len; + + for (i = 0; i < body_size_in_kb; i++) { + // write 1kb chunk into the body. + memcpy(buf + wrote, "400\r\n", 5); + wrote += 5; + memset(buf + wrote, 'C', 1024); + wrote += 1024; + strcpy(buf + wrote, "\r\n"); + wrote += 2; + } + + memcpy(buf + wrote, "0\r\n\r\n", 6); + wrote += 6; + assert(wrote == bufsize); + + return buf; +} + +/* Verify that we can pause parsing at any of the bytes in the + * message and still get the result that we're expecting. */ +void +test_message_pause (const struct message *msg) +{ + char *buf = (char*) msg->raw; + size_t buflen = strlen(msg->raw); + size_t nread; + + parser_init(msg->type); + + do { + nread = parse_pause(buf, buflen); + + // We can only set the upgrade buffer once we've gotten our message + // completion callback. + if (messages[0].message_complete_cb_called && + msg->upgrade && + parser->upgrade) { + messages[0].upgrade = buf + nread; + goto test; + } + + if (nread < buflen) { + + // Not much do to if we failed a strict-mode check + if (HTTP_PARSER_ERRNO(parser) == HPE_STRICT) { + parser_free(); + return; + } + + assert (HTTP_PARSER_ERRNO(parser) == HPE_PAUSED); + } + + buf += nread; + buflen -= nread; + http_parser_pause(parser, 0); + } while (buflen > 0); + + nread = parse_pause(NULL, 0); + assert (nread == 0); + +test: + if (num_messages != 1) { + printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name); + abort(); + } + + if(!message_eq(0, 0, msg)) abort(); + + parser_free(); +} + +/* Verify that body and next message won't be parsed in responses to CONNECT */ +void +test_message_connect (const struct message *msg) +{ + char *buf = (char*) msg->raw; + size_t buflen = strlen(msg->raw); + + parser_init(msg->type); + + parse_connect(buf, buflen); + + if (num_messages != 1) { + printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name); + abort(); + } + + if(!message_eq(0, 1, msg)) abort(); + + parser_free(); +} + +int +main (void) +{ + parser = NULL; + unsigned i, j, k; + unsigned long version; + unsigned major; + unsigned minor; + unsigned patch; + + version = http_parser_version(); + major = (version >> 16) & 255; + minor = (version >> 8) & 255; + patch = version & 255; + printf("http_parser v%u.%u.%u (0x%06lx)\n", major, minor, patch, version); + + printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser)); + + //// API + test_preserve_data(); + test_parse_url(); + test_method_str(); + + //// NREAD + test_header_nread_value(); + + //// OVERFLOW CONDITIONS + test_no_overflow_parse_url(); + + test_header_overflow_error(HTTP_REQUEST); + test_no_overflow_long_body(HTTP_REQUEST, 1000); + test_no_overflow_long_body(HTTP_REQUEST, 100000); + + test_header_overflow_error(HTTP_RESPONSE); + test_no_overflow_long_body(HTTP_RESPONSE, 1000); + test_no_overflow_long_body(HTTP_RESPONSE, 100000); + + test_header_content_length_overflow_error(); + test_chunk_content_length_overflow_error(); + + //// HEADER FIELD CONDITIONS + test_double_content_length_error(HTTP_REQUEST); + test_chunked_content_length_error(HTTP_REQUEST); + test_header_cr_no_lf_error(HTTP_REQUEST); + test_invalid_header_field_token_error(HTTP_REQUEST); + test_invalid_header_field_content_error(HTTP_REQUEST); + test_double_content_length_error(HTTP_RESPONSE); + test_chunked_content_length_error(HTTP_RESPONSE); + test_header_cr_no_lf_error(HTTP_RESPONSE); + test_invalid_header_field_token_error(HTTP_RESPONSE); + test_invalid_header_field_content_error(HTTP_RESPONSE); + + test_simple_type( + "POST / HTTP/1.1\r\n" + "Content-Length: 42 \r\n" // Note the surrounding whitespace. + "\r\n", + HPE_OK, + HTTP_REQUEST); + + test_simple_type( + "POST / HTTP/1.1\r\n" + "Content-Length: 4 2\r\n" + "\r\n", + HPE_INVALID_CONTENT_LENGTH, + HTTP_REQUEST); + + test_simple_type( + "POST / HTTP/1.1\r\n" + "Content-Length: 13 37\r\n" + "\r\n", + HPE_INVALID_CONTENT_LENGTH, + HTTP_REQUEST); + + //// RESPONSES + + test_simple_type("HTP/1.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); + test_simple_type("HTTP/01.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); + test_simple_type("HTTP/11.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); + test_simple_type("HTTP/1.01 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); + test_simple_type("HTTP/1.1\t200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); + + for (i = 0; i < ARRAY_SIZE(responses); i++) { + test_message(&responses[i]); + } + + for (i = 0; i < ARRAY_SIZE(responses); i++) { + test_message_pause(&responses[i]); + } + + for (i = 0; i < ARRAY_SIZE(responses); i++) { + test_message_connect(&responses[i]); + } + + for (i = 0; i < ARRAY_SIZE(responses); i++) { + if (!responses[i].should_keep_alive) continue; + for (j = 0; j < ARRAY_SIZE(responses); j++) { + if (!responses[j].should_keep_alive) continue; + for (k = 0; k < ARRAY_SIZE(responses); k++) { + test_multiple3(&responses[i], &responses[j], &responses[k]); + } + } + } + + test_message_count_body(&responses[NO_HEADERS_NO_BODY_404]); + test_message_count_body(&responses[TRAILING_SPACE_ON_CHUNKED_BODY]); + + // test very large chunked response + { + char * msg = create_large_chunked_message(31337, + "HTTP/1.0 200 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "Content-Type: text/plain\r\n" + "\r\n"); + struct message large_chunked = + {.name= "large chunked" + ,.type= HTTP_RESPONSE + ,.raw= msg + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.status_code= 200 + ,.response_status= "OK" + ,.num_headers= 2 + ,.headers= + { { "Transfer-Encoding", "chunked" } + , { "Content-Type", "text/plain" } + } + ,.body_size= 31337*1024 + ,.num_chunks_complete= 31338 + }; + for (i = 0; i < MAX_CHUNKS; i++) { + large_chunked.chunk_lengths[i] = 1024; + } + test_message_count_body(&large_chunked); + free(msg); + } + + + + printf("response scan 1/2 "); + test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] + , &responses[NO_BODY_HTTP10_KA_204] + , &responses[NO_REASON_PHRASE] + ); + + printf("response scan 2/2 "); + test_scan( &responses[BONJOUR_MADAME_FR] + , &responses[UNDERSTORE_HEADER_KEY] + , &responses[NO_CARRIAGE_RET] + ); + + puts("responses okay"); + + + /// REQUESTS + + test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION); + test_simple("GET / HTTP/01.1\r\n\r\n", HPE_INVALID_VERSION); + test_simple("GET / HTTP/11.1\r\n\r\n", HPE_INVALID_VERSION); + test_simple("GET / HTTP/1.01\r\n\r\n", HPE_INVALID_VERSION); + + // Extended characters - see nodejs/test/parallel/test-http-headers-obstext.js + test_simple("GET / HTTP/1.1\r\n" + "Test: Düsseldorf\r\n", + HPE_OK); + + // Well-formed but incomplete + test_simple("GET / HTTP/1.1\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 6\r\n" + "\r\n" + "fooba", + HPE_OK); + + static const char *all_methods[] = { + "DELETE", + "GET", + "HEAD", + "POST", + "PUT", + //"CONNECT", //CONNECT can't be tested like other methods, it's a tunnel + "OPTIONS", + "TRACE", + "COPY", + "LOCK", + "MKCOL", + "MOVE", + "PROPFIND", + "PROPPATCH", + "SEARCH", + "UNLOCK", + "BIND", + "REBIND", + "UNBIND", + "ACL", + "REPORT", + "MKACTIVITY", + "CHECKOUT", + "MERGE", + "M-SEARCH", + "NOTIFY", + "SUBSCRIBE", + "UNSUBSCRIBE", + "PATCH", + "PURGE", + "MKCALENDAR", + "LINK", + "UNLINK", + 0 }; + const char **this_method; + for (this_method = all_methods; *this_method; this_method++) { + char buf[200]; + sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); + test_simple(buf, HPE_OK); + } + + static const char *bad_methods[] = { + "ASDF", + "C******", + "COLA", + "GEM", + "GETA", + "M****", + "MKCOLA", + "PROPPATCHA", + "PUN", + "PX", + "SA", + "hello world", + 0 }; + for (this_method = bad_methods; *this_method; this_method++) { + char buf[200]; + sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); + test_simple(buf, HPE_INVALID_METHOD); + } + + // illegal header field name line folding + test_simple("GET / HTTP/1.1\r\n" + "name\r\n" + " : value\r\n" + "\r\n", + HPE_INVALID_HEADER_TOKEN); + + const char *dumbfuck2 = + "GET / HTTP/1.1\r\n" + "X-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n" + "\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n" + "\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n" + "\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n" + "\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n" + "\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n" + "\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n" + "\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n" + "\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n" + "\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n" + "\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n" + "\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n" + "\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n" + "\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgHTTPAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n" + "\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n" + "\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n" + "\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n" + "\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n" + "\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n" + "\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n" + "\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n" + "\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n" + "\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n" + "\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n" + "\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n" + "\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n" + "\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n" + "\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n" + "\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n" + "\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n" + "\tRA==\r\n" + "\t-----END CERTIFICATE-----\r\n" + "\r\n"; + test_simple(dumbfuck2, HPE_OK); + + const char *corrupted_connection = + "GET / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Connection\r\033\065\325eep-Alive\r\n" + "Accept-Encoding: gzip\r\n" + "\r\n"; + test_simple(corrupted_connection, HPE_INVALID_HEADER_TOKEN); + + const char *corrupted_header_name = + "GET / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "X-Some-Header\r\033\065\325eep-Alive\r\n" + "Accept-Encoding: gzip\r\n" + "\r\n"; + test_simple(corrupted_header_name, HPE_INVALID_HEADER_TOKEN); + +#if 0 + // NOTE(Wed Nov 18 11:57:27 CET 2009) this seems okay. we just read body + // until EOF. + // + // no content-length + // error if there is a body without content length + const char *bad_get_no_headers_no_body = "GET /bad_get_no_headers_no_body/world HTTP/1.1\r\n" + "Accept: */*\r\n" + "\r\n" + "HELLO"; + test_simple(bad_get_no_headers_no_body, 0); +#endif + /* TODO sending junk and large headers gets rejected */ + + + /* check to make sure our predefined requests are okay */ + for (i = 0; i < ARRAY_SIZE(requests); i++) { + test_message(&requests[i]); + } + + for (i = 0; i < ARRAY_SIZE(requests); i++) { + test_message_pause(&requests[i]); + } + + for (i = 0; i < ARRAY_SIZE(requests); i++) { + if (!requests[i].should_keep_alive) continue; + for (j = 0; j < ARRAY_SIZE(requests); j++) { + if (!requests[j].should_keep_alive) continue; + for (k = 0; k < ARRAY_SIZE(requests); k++) { + test_multiple3(&requests[i], &requests[j], &requests[k]); + } + } + } + + printf("request scan 1/4 "); + test_scan( &requests[GET_NO_HEADERS_NO_BODY] + , &requests[GET_ONE_HEADER_NO_BODY] + , &requests[GET_NO_HEADERS_NO_BODY] + ); + + printf("request scan 2/4 "); + test_scan( &requests[POST_CHUNKED_ALL_YOUR_BASE] + , &requests[POST_IDENTITY_BODY_WORLD] + , &requests[GET_FUNKY_CONTENT_LENGTH] + ); + + printf("request scan 3/4 "); + test_scan( &requests[TWO_CHUNKS_MULT_ZERO_END] + , &requests[CHUNKED_W_TRAILING_HEADERS] + , &requests[CHUNKED_W_BULLSHIT_AFTER_LENGTH] + ); + + printf("request scan 4/4 "); + test_scan( &requests[QUERY_URL_WITH_QUESTION_MARK_GET] + , &requests[PREFIX_NEWLINE_GET ] + , &requests[CONNECT_REQUEST] + ); + + puts("requests okay"); + + return 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/http_parser.rb.gemspec b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/http_parser.rb.gemspec new file mode 100644 index 0000000..2125a27 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/http_parser.rb.gemspec @@ -0,0 +1,32 @@ +Gem::Specification.new do |s| + s.name = "http_parser.rb" + s.version = "0.8.1" + s.summary = "Simple callback-based HTTP request/response parser" + s.description = "Ruby bindings to https://github.com/joyent/http-parser and https://github.com/http-parser/http-parser.java" + + s.authors = ["Marc-Andre Cournoyer", "Aman Gupta"] + s.email = ["macournoyer@gmail.com", "aman@tmm1.net"] + s.license = 'MIT' + + s.homepage = "https://github.com/tmm1/http_parser.rb" + s.files = `git ls-files`.split("\n").grep_v(%r{spec/}) + Dir['ext/ruby_http_parser/vendor/**/*'] + + s.require_paths = ["lib"] + s.extensions = ["ext/ruby_http_parser/extconf.rb"] + + s.add_development_dependency 'rake-compiler', '~> 1.0' + s.add_development_dependency 'rspec', '~> 3' + s.add_development_dependency 'json', '~> 2.1' + s.add_development_dependency 'benchmark_suite', '~> 1.0' + s.add_development_dependency 'ffi', '~> 1.9' + + if RUBY_PLATFORM =~ /java/ + s.add_development_dependency 'jruby-openssl' + else + if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0') + s.add_development_dependency 'yajl-ruby', '~> 1.3' + else + s.add_development_dependency 'yajl-ruby', '= 1.2.1' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http/parser.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http/parser.rb new file mode 100644 index 0000000..4881b03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http/parser.rb @@ -0,0 +1 @@ +require 'http_parser' diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http_parser.rb b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http_parser.rb new file mode 100644 index 0000000..c69f7a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/lib/http_parser.rb @@ -0,0 +1,21 @@ +$:.unshift File.expand_path('../', __FILE__) +require 'ruby_http_parser' + +Http = HTTP + +module HTTP + class Parser + class << self + attr_reader :default_header_value_type + + def default_header_value_type=(val) + if (val != :mixed && val != :strings && val != :arrays) + raise ArgumentError, "Invalid header value type" + end + @default_header_value_type = val + end + end + end +end + +HTTP::Parser.default_header_value_type = :mixed diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/compile.rake b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/compile.rake new file mode 100644 index 0000000..3345fbe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/compile.rake @@ -0,0 +1,42 @@ +require 'rubygems/package_task' +require 'rake/extensiontask' +require 'rake/javaextensiontask' + +def gemspec + @clean_gemspec ||= eval(File.read(File.expand_path('../../http_parser.rb.gemspec', __FILE__))) +end + +Gem::PackageTask.new(gemspec) do |pkg| +end + +if RUBY_PLATFORM =~ /java/ + Rake::JavaExtensionTask.new("ruby_http_parser", gemspec) do |ext| + ext.classpath = File.expand_path('../../ext/ruby_http_parser/vendor/http-parser-java/ext/primitives.jar', __FILE__) + end +else + Rake::ExtensionTask.new("ruby_http_parser", gemspec) do |ext| + unless RUBY_PLATFORM =~ /mswin|mingw/ + ext.cross_compile = true + ext.cross_platform = ['x86-mingw32', 'x86-mswin32-60'] + + # inject 1.8/1.9 pure-ruby entry point + ext.cross_compiling do |spec| + spec.files += ['lib/ruby_http_parser.rb'] + end + end + end +end + +file 'lib/ruby_http_parser.rb' do |t| + File.open(t.name, 'wb') do |f| + f.write <<-eoruby +RUBY_VERSION =~ /(\\d+.\\d+)/ +require "\#{$1}/ruby_http_parser" + eoruby + end + at_exit{ FileUtils.rm t.name if File.exist?(t.name) } +end + +if Rake::Task.task_defined?(:cross) + task :cross => 'lib/ruby_http_parser.rb' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/fixtures.rake b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/fixtures.rake new file mode 100644 index 0000000..b5d36ef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/fixtures.rake @@ -0,0 +1,71 @@ +desc "Generate test fixtures" +task :fixtures => :submodules do + require 'yajl' + data = File.read File.expand_path('../../ext/ruby_http_parser/vendor/http-parser/test.c', __FILE__) + + %w[ requests responses ].each do |type| + # find test definitions in between requests/responses[]= and .name=NULL + tmp = data[/#{type}\[\]\s*=(.+?),\s*\{\s*\.name=\s*NULL/m, 1] + + # replace first { with a [ (parsing an array of test cases) + tmp.sub!('{','[') + + # replace booleans + tmp.gsub!('TRUE', 'true') + tmp.gsub!('FALSE', 'false') + + # mark strict mode tests + tmp.gsub!(%r|#if\s+!HTTP_PARSER_STRICT(.+?)#endif\s*/\*\s*!HTTP_PARSER_STRICT.+\n|m){ + $1.gsub(/^(.+,\.type= .+)$/, "\\1\n, .strict= false") + } + + # remove macros and comments + tmp.gsub!(/^#(if|elif|endif|define).+$/,'') + tmp.gsub!(/\/\*(.+?)\*\/$/,'') + + # HTTP_* enums become strings + tmp.gsub!(/(= )(HTTP_\w+)/){ + "#{$1}#{$2.sub('MSEARCH','M-SEARCH').dump}" + } + + # join multiline strings for body and raw data + tmp.gsub!(/((body|raw)\s*=)(.+?)(\n\s+[\},])/m){ + before, after = $1, $4 + raw = $3.split("\n").map{ |l| l.strip[1..-2] }.join('') + "#{before} \"#{raw}\" #{after}" + } + + # make headers an array of array tuples + tmp.gsub!(/(\.headers\s*=)(.+?)(\s*,\.)/m){ + before, after = $1, $3 + raw = $2.gsub('{', '[').gsub('}', ']') + "#{before} #{raw} #{after}" + } + + # .name= becomes "name": + tmp.gsub!(/^(.{2,5})\.(\w+)\s*=/){ + "#{$1}#{$2.dump}: " + } + + # evaluate addition expressions + tmp.gsub!(/(body_size\":\s*)(\d+)\+(\d+)/){ + "#{$1}#{$2.to_i+$3.to_i}" + } + + # end result array + tmp << ']' + + # normalize data + results = Yajl.load(tmp, :symbolize_keys => true) + results.map{ |res| + res[:headers] and res[:headers] = Hash[*res[:headers].flatten] + res[:method] and res[:method].gsub!(/^HTTP_/, '') + res[:strict] = true unless res.has_key?(:strict) + } + + # write to a file + File.open("spec/support/#{type}.json", 'w'){ |f| + f.write Yajl.dump(results, :pretty => true) + } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/spec.rake b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/spec.rake new file mode 100644 index 0000000..3deb568 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/spec.rake @@ -0,0 +1,5 @@ +require "rspec/core/rake_task" + +RSpec::Core::RakeTask.new do |t| + t.rspec_opts = %w(--format documentation --color) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/submodules.rake b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/submodules.rake new file mode 100644 index 0000000..d978e9f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/http_parser.rb-0.8.1/tasks/submodules.rake @@ -0,0 +1,7 @@ +desc "Fetch upstream submodules" +task :submodules do + if Dir['ext/ruby_http_parser/vendor/http-parser/*'].empty? + sh 'git submodule init' + sh 'git submodule update' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/MIT-LICENSE b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/MIT-LICENSE new file mode 100644 index 0000000..ed8e9ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 The Ruby I18n team + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/README.md b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/README.md new file mode 100644 index 0000000..3547966 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/README.md @@ -0,0 +1,139 @@ +# Ruby I18n + +[![Gem Version](https://badge.fury.io/rb/i18n.svg)](https://badge.fury.io/rb/i18n) +[![Build Status](https://github.com/ruby-i18n/i18n/workflows/Ruby/badge.svg)](https://github.com/ruby-i18n/i18n/actions?query=workflow%3ARuby) + +Ruby internationalization and localization (i18n) solution. + +Currently maintained by @radar. + +## Usage + +### Rails + +You will most commonly use this library within a Rails app. + +We support Rails versions from 6.0 and up. + +[See the Rails Guide](https://guides.rubyonrails.org/i18n.html) for an example of its usage. + +### Ruby (without Rails) + +We support Ruby versions from 3.1 and up. + +If you want to use this library without Rails, you can simply add `i18n` to your `Gemfile`: + +```ruby +gem 'i18n' +``` + +Then configure I18n with some translations, and a default locale: + +```ruby +I18n.load_path += Dir[File.expand_path("config/locales") + "/*.yml"] +I18n.default_locale = :en # (note that `en` is already the default!) +``` + +A simple translation file in your project might live at `config/locales/en.yml` and look like: + +```yml +en: + test: "This is a test" +``` + +You can then access this translation by doing: + +```ruby +I18n.t(:test) +``` + +You can switch locales in your project by setting `I18n.locale` to a different value: + +```ruby +I18n.locale = :de +I18n.t(:test) # => "Dies ist ein Test" +``` + +### Fiber-safe config updates + +`Fiber[]` values are inherited by child fibers. +To avoid sharing mutable config objects across fibers, prefer creating updated configs and setting them with `set!`: + +```ruby +I18n.config.with(locale: :ja).set! +``` + +`set!` stores a frozen config in the current execution context. +This keeps inherited state safe and lets updates happen by replacing config objects. + +## Features + +* Translation and localization +* Interpolation of values to translations +* Pluralization (CLDR compatible) +* Customizable transliteration to ASCII +* Flexible defaults +* Bulk lookup +* Lambdas as translation data +* Custom key/scope separator +* Custom exception handlers +* Extensible architecture with a swappable backend + +## Pluggable Features + +* Cache +* Pluralization: lambda pluralizers stored as translation data +* Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation) +* [Gettext support](https://github.com/ruby-i18n/i18n/wiki/Gettext) +* Translation metadata + +## Alternative Backend + +* Chain +* ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs) +* KeyValue (uses active_support/json and cannot store procs) + +For more information and lots of resources see [the 'Resources' page on the wiki](https://github.com/ruby-i18n/i18n/wiki/Resources). + +## Tests + +You can run tests both with + +* `rake test` or just `rake` +* run any test file directly, e.g. `ruby -Ilib:test test/api/simple_test.rb` + +You can run all tests against all Gemfiles with + +* `ruby test/run_all.rb` + +The structure of the test suite is a bit unusual as it uses modules to reuse +particular tests in different test cases. + +The reason for this is that we need to enforce the I18n API across various +combinations of extensions. E.g. the Simple backend alone needs to support +the same API as any combination of feature and/or optimization modules included +to the Simple backend. We test this by reusing the same API definition (implemented +as test methods) in test cases with different setups. + +You can find the test cases that enforce the API in test/api. And you can find +the API definition test methods in test/api/tests. + +All other test cases (e.g. as defined in test/backend, test/core_ext) etc. +follow the usual test setup and should be easy to grok. + +## More Documentation + +Additional documentation can be found here: https://github.com/ruby-i18n/i18n/wiki + +## Contributors + +* @radar +* @carlosantoniodasilva +* @josevalim +* @knapo +* @tigrish +* [and many more](https://github.com/ruby-i18n/i18n/graphs/contributors) + +## License + +MIT License. See the included MIT-LICENSE file. diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n.rb new file mode 100644 index 0000000..429ce46 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n.rb @@ -0,0 +1,507 @@ +# frozen_string_literal: true + +require 'concurrent/map' +require 'concurrent/hash' + +require 'i18n/version' +require 'i18n/utils' +require 'i18n/exceptions' +require 'i18n/interpolate/ruby' + +module I18n + autoload :Backend, 'i18n/backend' + autoload :Config, 'i18n/config' + autoload :Gettext, 'i18n/gettext' + autoload :Locale, 'i18n/locale' + autoload :Tests, 'i18n/tests' + autoload :Middleware, 'i18n/middleware' + + RESERVED_KEYS = %i[ + cascade + deep_interpolation + skip_interpolation + default + exception_handler + fallback + fallback_in_progress + fallback_original_locale + format + object + raise + resolve + scope + separator + throw + ] + EMPTY_HASH = {}.freeze + + def self.new_double_nested_cache # :nodoc: + Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new } + end + + # Marks a key as reserved. Reserved keys are used internally, + # and can't also be used for interpolation. If you are using any + # extra keys as I18n options, you should call I18n.reserve_key + # before any I18n.translate (etc) calls are made. + def self.reserve_key(key) + RESERVED_KEYS << key.to_sym + @reserved_keys_pattern = nil + end + + def self.reserved_keys_pattern # :nodoc: + @reserved_keys_pattern ||= /(?E.g., ActionView ships with the translation: + # :date => {:formats => {:short => "%b %d"}}. + # + # Translations can be looked up at any level of this hash using the key argument + # and the scope option. E.g., in this example I18n.t :date + # returns the whole translations hash {:formats => {:short => "%b %d"}}. + # + # Key can be either a single key or a dot-separated key (both Strings and Symbols + # work). E.g., the short format can be looked up using both: + # I18n.t 'date.formats.short' + # I18n.t :'date.formats.short' + # + # Scope can be either a single key, a dot-separated key or an array of keys + # or dot-separated keys. Keys and scopes can be combined freely. So these + # examples will all look up the same short date format: + # I18n.t 'date.formats.short' + # I18n.t 'formats.short', :scope => 'date' + # I18n.t 'short', :scope => 'date.formats' + # I18n.t 'short', :scope => %w(date formats) + # + # *INTERPOLATION* + # + # Translations can contain interpolation variables which will be replaced by + # values passed to #translate as part of the options hash, with the keys matching + # the interpolation variable names. + # + # E.g., with a translation :foo => "foo %{bar}" the option + # value for the key +bar+ will be interpolated into the translation: + # I18n.t :foo, :bar => 'baz' # => 'foo baz' + # + # *PLURALIZATION* + # + # Translation data can contain pluralized translations. Pluralized translations + # are arrays of singular/plural versions of translations like ['Foo', 'Foos']. + # + # Note that I18n::Backend::Simple only supports an algorithm for English + # pluralization rules. Other algorithms can be supported by custom backends. + # + # This returns the singular version of a pluralized translation: + # I18n.t :foo, :count => 1 # => 'Foo' + # + # These both return the plural version of a pluralized translation: + # I18n.t :foo, :count => 0 # => 'Foos' + # I18n.t :foo, :count => 2 # => 'Foos' + # + # The :count option can be used both for pluralization and interpolation. + # E.g., with the translation + # :foo => ['%{count} foo', '%{count} foos'], count will + # be interpolated to the pluralized translation: + # I18n.t :foo, :count => 1 # => '1 foo' + # + # *DEFAULTS* + # + # This returns the translation for :foo or default if no translation was found: + # I18n.t :foo, :default => 'default' + # + # This returns the translation for :foo or the translation for :bar if no + # translation for :foo was found: + # I18n.t :foo, :default => :bar + # + # Returns the translation for :foo or the translation for :bar + # or default if no translations for :foo and :bar were found. + # I18n.t :foo, :default => [:bar, 'default'] + # + # BULK LOOKUP + # + # This returns an array with the translations for :foo and :bar. + # I18n.t [:foo, :bar] + # + # Can be used with dot-separated nested keys: + # I18n.t [:'baz.foo', :'baz.bar'] + # + # Which is the same as using a scope option: + # I18n.t [:foo, :bar], :scope => :baz + # + # *LAMBDAS* + # + # Both translations and defaults can be given as Ruby lambdas. Lambdas will be + # called and passed the key and options. + # + # E.g. assuming the key :salutation resolves to: + # lambda { |key, options| options[:gender] == 'm' ? "Mr. #{options[:name]}" : "Mrs. #{options[:name]}" } + # + # Then I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith". + # + # Note that the string returned by lambda will go through string interpolation too, + # so the following lambda would give the same result: + # lambda { |key, options| options[:gender] == 'm' ? "Mr. %{name}" : "Mrs. %{name}" } + # + # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when + # a cache layer is put in front of I18n.translate it will generate a cache key + # from the argument values passed to #translate. Therefore your lambdas should + # always return the same translations/values per unique combination of argument + # values. + # + # Ruby 2.7+ keyword arguments warning + # + # This method uses keyword arguments. + # There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0 + # The "hash" parameter must be passed as keyword argument. + # + # Good: + # I18n.t(:salutation, :gender => 'w', :name => 'Smith') + # I18n.t(:salutation, **{ :gender => 'w', :name => 'Smith' }) + # I18n.t(:salutation, **any_hash) + # + # Bad: + # I18n.t(:salutation, { :gender => 'w', :name => 'Smith' }) + # I18n.t(:salutation, any_hash) + # + def translate(key = nil, throw: false, raise: false, locale: nil, **options) # TODO deprecate :raise + locale ||= config.locale + raise Disabled.new('t') if locale == false + enforce_available_locales!(locale) + + backend = config.backend + + if key.is_a?(Array) + key.map do |k| + translate_key(k, throw, raise, locale, backend, options) + end + else + translate_key(key, throw, raise, locale, backend, options) + end + end + alias :t :translate + + # Wrapper for translate that adds :raise => true. With + # this option, if no translation is found, it will raise I18n::MissingTranslationData + def translate!(key, **options) + translate(key, **options, raise: true) + end + alias :t! :translate! + + # Returns an array of interpolation keys for the given translation key + # + # *Examples* + # + # Suppose we have the following: + # I18n.t 'example.zero' == 'Zero interpolations' + # I18n.t 'example.one' == 'One interpolation %{foo}' + # I18n.t 'example.two' == 'Two interpolations %{foo} %{bar}' + # I18n.t 'example.three' == ['One %{foo}', 'Two %{bar}', 'Three %{baz}'] + # I18n.t 'example.one', locale: :other == 'One interpolation %{baz}' + # + # Then we can expect the following results: + # I18n.interpolation_keys('example.zero') #=> [] + # I18n.interpolation_keys('example.one') #=> ['foo'] + # I18n.interpolation_keys('example.two') #=> ['foo', 'bar'] + # I18n.interpolation_keys('example.three') #=> ['foo', 'bar', 'baz'] + # I18n.interpolation_keys('one', scope: 'example', locale: :other) #=> ['baz'] + # I18n.interpolation_keys('does-not-exist') #=> [] + # I18n.interpolation_keys('example') #=> [] + def interpolation_keys(key, **options) + raise I18n::ArgumentError if !key.is_a?(String) || key.empty? + + return [] unless exists?(key, **options.slice(:locale, :scope)) + + translation = translate(key, **options.slice(:locale, :scope)) + interpolation_keys_from_translation(translation) + .flatten.compact + end + + # Returns true if a translation exists for a given key, otherwise returns false. + def exists?(key, _locale = nil, locale: _locale, **options) + locale ||= config.locale + raise Disabled.new('exists?') if locale == false + raise I18n::ArgumentError if (key.is_a?(String) && key.empty?) || key.nil? + + config.backend.exists?(locale, key, options) + end + + # Transliterates UTF-8 characters to ASCII. By default this method will + # transliterate only Latin strings to an ASCII approximation: + # + # I18n.transliterate("Ærøskøbing") + # # => "AEroskobing" + # + # I18n.transliterate("日本語") + # # => "???" + # + # It's also possible to add support for per-locale transliterations. I18n + # expects transliteration rules to be stored at + # i18n.transliterate.rule. + # + # Transliteration rules can either be a Hash or a Proc. Procs must accept a + # single string argument. Hash rules inherit the default transliteration + # rules, while Procs do not. + # + # *Examples* + # + # Setting a Hash in .yml: + # + # i18n: + # transliterate: + # rule: + # ü: "ue" + # ö: "oe" + # + # Setting a Hash using Ruby: + # + # store_translations(:de, i18n: { + # transliterate: { + # rule: { + # 'ü' => 'ue', + # 'ö' => 'oe' + # } + # } + # }) + # + # Setting a Proc: + # + # translit = lambda {|string| MyTransliterator.transliterate(string) } + # store_translations(:xx, :i18n => {:transliterate => {:rule => translit}) + # + # Transliterating strings: + # + # I18n.locale = :en + # I18n.transliterate("Jürgen") # => "Jurgen" + # I18n.locale = :de + # I18n.transliterate("Jürgen") # => "Juergen" + # I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen" + # I18n.transliterate("Jürgen", :locale => :de) # => "Juergen" + def transliterate(key, throw: false, raise: false, locale: nil, replacement: nil, **options) + locale ||= config.locale + raise Disabled.new('transliterate') if locale == false + enforce_available_locales!(locale) + + config.backend.transliterate(locale, key, replacement) + rescue I18n::ArgumentError => exception + handle_exception((throw && :throw || raise && :raise), exception, locale, key, options) + end + + # Localizes certain objects, such as dates and numbers to local formatting. + def localize(object, locale: nil, format: nil, **options) + locale ||= config.locale + raise Disabled.new('l') if locale == false + enforce_available_locales!(locale) + + format ||= :default + config.backend.localize(locale, object, format, options) + end + alias :l :localize + + # Executes block with given I18n.locale set. + def with_locale(tmp_locale = nil) + if tmp_locale == nil + yield + else + current_locale = self.locale + self.locale = tmp_locale + begin + yield + ensure + self.locale = current_locale + end + end + end + + # Merges the given locale, key and scope into a single array of keys. + # Splits keys that contain dots into multiple keys. Makes sure all + # keys are Symbols. + def normalize_keys(locale, key, scope, separator = nil) + separator ||= I18n.default_separator + + [ + *normalize_key(locale, separator), + *normalize_key(scope, separator), + *normalize_key(key, separator) + ] + end + + # Returns true when the passed locale, which can be either a String or a + # Symbol, is in the list of available locales. Returns false otherwise. + def locale_available?(locale) + I18n.config.available_locales_set.include?(locale) + end + + # Raises an InvalidLocale exception when the passed locale is not available. + def enforce_available_locales!(locale) + if locale != false && config.enforce_available_locales + raise I18n::InvalidLocale.new(locale) if !locale_available?(locale) + end + end + + def available_locales_initialized? + config.available_locales_initialized? + end + + private + + def translate_key(key, throw, raise, locale, backend, options) + result = catch(:exception) do + backend.translate(locale, key, options) + end + + if result.is_a?(MissingTranslation) + handle_exception((throw && :throw || raise && :raise), result, locale, key, options) + else + result + end + end + + # Any exceptions thrown in translate will be sent to the @@exception_handler + # which can be a Symbol, a Proc or any other Object unless they're forced to + # be raised or thrown (MissingTranslation). + # + # If exception_handler is a Symbol then it will simply be sent to I18n as + # a method call. A Proc will simply be called. In any other case the + # method #call will be called on the exception_handler object. + # + # Examples: + # + # I18n.exception_handler = :custom_exception_handler # this is the default + # I18n.custom_exception_handler(exception, locale, key, options) # will be called like this + # + # I18n.exception_handler = lambda { |*args| ... } # a lambda + # I18n.exception_handler.call(exception, locale, key, options) # will be called like this + # + # I18n.exception_handler = I18nExceptionHandler.new # an object + # I18n.exception_handler.call(exception, locale, key, options) # will be called like this + def handle_exception(handling, exception, locale, key, options) + case handling + when :raise + raise exception.respond_to?(:to_exception) ? exception.to_exception : exception + when :throw + throw :exception, exception + else + case handler = options[:exception_handler] || config.exception_handler + when Symbol + send(handler, exception, locale, key, options) + else + handler.call(exception, locale, key, options) + end + end + end + + @@normalized_key_cache = I18n.new_double_nested_cache + + def normalize_key(key, separator) + @@normalized_key_cache[separator][key] ||= + case key + when Array + key.flat_map { |k| normalize_key(k, separator) } + else + keys = key.to_s.split(separator) + keys.delete('') + keys.map! do |k| + case k + when /\A[-+]?([1-9]\d*|0)\z/ # integer + k.to_i + when 'true' + true + when 'false' + false + else + k.to_sym + end + end + keys + end + end + + def interpolation_keys_from_translation(translation) + case translation + when ::String + translation.scan(Regexp.union(I18n.config.interpolation_patterns)) + when ::Array + translation.map { |element| interpolation_keys_from_translation(element) } + else + [] + end + end + end + + extend Base +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend.rb new file mode 100644 index 0000000..863d618 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module I18n + module Backend + autoload :Base, 'i18n/backend/base' + autoload :Cache, 'i18n/backend/cache' + autoload :CacheFile, 'i18n/backend/cache_file' + autoload :Cascade, 'i18n/backend/cascade' + autoload :Chain, 'i18n/backend/chain' + autoload :Fallbacks, 'i18n/backend/fallbacks' + autoload :Flatten, 'i18n/backend/flatten' + autoload :Gettext, 'i18n/backend/gettext' + autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler' + autoload :KeyValue, 'i18n/backend/key_value' + autoload :LazyLoadable, 'i18n/backend/lazy_loadable' + autoload :Memoize, 'i18n/backend/memoize' + autoload :Metadata, 'i18n/backend/metadata' + autoload :Pluralization, 'i18n/backend/pluralization' + autoload :Simple, 'i18n/backend/simple' + autoload :Transliterator, 'i18n/backend/transliterator' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/base.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/base.rb new file mode 100644 index 0000000..0c59cd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/base.rb @@ -0,0 +1,314 @@ +# frozen_string_literal: true + +require 'yaml' +require 'json' + +module I18n + module Backend + module Base + include I18n::Backend::Transliterator + + # Accepts a list of paths to translation files. Loads translations from + # plain Ruby (*.rb), YAML files (*.yml), or JSON files (*.json). See #load_rb, #load_yml, and #load_json + # for details. + def load_translations(*filenames) + filenames = I18n.load_path if filenames.empty? + filenames.flatten.each do |filename| + loaded_translations = load_file(filename) + yield filename, loaded_translations if block_given? + end + end + + # This method receives a locale, a data hash and options for storing translations. + # Should be implemented + def store_translations(locale, data, options = EMPTY_HASH) + raise NotImplementedError + end + + def translate(locale, key, options = EMPTY_HASH) + raise I18n::ArgumentError if (key.is_a?(String) || key.is_a?(Symbol)) && key.empty? + raise InvalidLocale.new(locale) unless locale + return nil if key.nil? && !options.key?(:default) + + entry = lookup(locale, key, options[:scope], options) unless key.nil? + + if entry.nil? && options.key?(:default) + entry = default(locale, key, options[:default], options) + else + entry = resolve_entry(locale, key, entry, options) + end + + count = options[:count] + + if entry.nil? && (subtrees? || !count) + if (options.key?(:default) && !options[:default].nil?) || !options.key?(:default) + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + end + + entry = entry.dup if entry.is_a?(String) + entry = pluralize(locale, entry, count) if count + + if entry.nil? && !subtrees? + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + + deep_interpolation = options[:deep_interpolation] + skip_interpolation = options[:skip_interpolation] + values = Utils.except(options, *RESERVED_KEYS) unless options.empty? + if !skip_interpolation && values && !values.empty? + entry = if deep_interpolation + deep_interpolate(locale, entry, values) + else + interpolate(locale, entry, values) + end + elsif entry.is_a?(String) && entry =~ I18n.reserved_keys_pattern + raise ReservedInterpolationKey.new($1.to_sym, entry) + end + entry + end + + def exists?(locale, key, options = EMPTY_HASH) + lookup(locale, key, options[:scope]) != nil + end + + # Acts the same as +strftime+, but uses a localized version of the + # format string. Takes a key from the date/time formats translations as + # a format argument (e.g., :short in :'date.formats'). + def localize(locale, object, format = :default, options = EMPTY_HASH) + if object.nil? && options.include?(:default) + return options[:default] + end + raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime) + + if Symbol === format + key = format + type = object.respond_to?(:sec) ? 'time' : 'date' + options = options.merge(:raise => true, :object => object, :locale => locale) + format = I18n.t(:"#{type}.formats.#{key}", **options) + end + + format = translate_localization_format(locale, object, format, options) + object.strftime(format) + end + + # Returns an array of locales for which translations are available + # ignoring the reserved translation meta data key :i18n. + def available_locales + raise NotImplementedError + end + + def reload! + eager_load! if eager_loaded? + end + + def eager_load! + @eager_loaded = true + end + + protected + + def eager_loaded? + @eager_loaded ||= false + end + + # The method which actually looks up for the translation in the store. + def lookup(locale, key, scope = [], options = EMPTY_HASH) + raise NotImplementedError + end + + def subtrees? + true + end + + # Evaluates defaults. + # If given subject is an Array, it walks the array and returns the + # first translation that can be resolved. Otherwise it tries to resolve + # the translation directly. + def default(locale, object, subject, options = EMPTY_HASH) + if options.size == 1 && options.has_key?(:default) + options = {} + else + options = Utils.except(options, :default) + end + + case subject + when Array + subject.each do |item| + result = resolve(locale, object, item, options) + return result unless result.nil? + end and nil + else + resolve(locale, object, subject, options) + end + end + + # Resolves a translation. + # If the given subject is a Symbol, it will be translated with the + # given options. If it is a Proc then it will be evaluated. All other + # subjects will be returned directly. + def resolve(locale, object, subject, options = EMPTY_HASH) + return subject if options[:resolve] == false + result = catch(:exception) do + case subject + when Symbol + I18n.translate( + subject, + **options.merge( + :locale => locale, + :throw => true, + :skip_interpolation => true + ) + ) + when Proc + date_or_time = options.delete(:object) || object + resolve(locale, object, subject.call(date_or_time, **options)) + else + subject + end + end + result unless result.is_a?(MissingTranslation) + end + alias_method :resolve_entry, :resolve + + # Picks a translation from a pluralized mnemonic subkey according to English + # pluralization rules : + # - It will pick the :one subkey if count is equal to 1. + # - It will pick the :other subkey otherwise. + # - It will pick the :zero subkey in the special case where count is + # equal to 0 and there is a :zero subkey present. This behaviour is + # not standard with regards to the CLDR pluralization rules. + # Other backends can implement more flexible or complex pluralization rules. + def pluralize(locale, entry, count) + entry = entry.reject { |k, _v| k == :attributes } if entry.is_a?(Hash) + return entry unless entry.is_a?(Hash) && count + + key = pluralization_key(entry, count) + raise InvalidPluralizationData.new(entry, count, key) unless entry.has_key?(key) + entry[key] + end + + # Interpolates values into a given subject. + # + # if the given subject is a string then: + # method interpolates "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X' + # # => "file test.txt opened by %{user}" + # + # if the given subject is an array then: + # each element of the array is recursively interpolated (until it finds a string) + # method interpolates ["yes, %{user}", ["maybe no, %{user}", "no, %{user}"]], :user => "bartuz" + # # => ["yes, bartuz", ["maybe no, bartuz", "no, bartuz"]] + def interpolate(locale, subject, values = EMPTY_HASH) + return subject if values.empty? + + case subject + when ::String then I18n.interpolate(subject, values) + when ::Array then subject.map { |element| interpolate(locale, element, values) } + else + subject + end + end + + # Deep interpolation + # + # deep_interpolate { people: { ann: "Ann is %{ann}", john: "John is %{john}" } }, + # ann: 'good', john: 'big' + # #=> { people: { ann: "Ann is good", john: "John is big" } } + def deep_interpolate(locale, data, values = EMPTY_HASH) + return data if values.empty? + + case data + when ::String + I18n.interpolate(data, values) + when ::Hash + data.each_with_object({}) do |(k, v), result| + result[k] = deep_interpolate(locale, v, values) + end + when ::Array + data.map do |v| + deep_interpolate(locale, v, values) + end + else + data + end + end + + # Loads a single translations file by delegating to #load_rb or + # #load_yml depending on the file extension and directly merges the + # data to the existing translations. Raises I18n::UnknownFileType + # for all other file extensions. + def load_file(filename) + type = File.extname(filename).tr('.', '').downcase + raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true) + data, keys_symbolized = send(:"load_#{type}", filename) + unless data.is_a?(Hash) + raise InvalidLocaleData.new(filename, 'expects it to return a hash, but does not') + end + data.each { |locale, d| store_translations(locale, d || {}, skip_symbolize_keys: keys_symbolized) } + + data + end + + # Loads a plain Ruby translations file. eval'ing the file must yield + # a Hash containing translation data with locales as toplevel keys. + def load_rb(filename) + translations = eval(IO.read(filename), binding, filename.to_s) + [translations, false] + end + + # Loads a YAML translations file. The data must have locales as + # toplevel keys. + def load_yml(filename) + begin + if YAML.respond_to?(:unsafe_load_file) # Psych 4.0 way + [YAML.unsafe_load_file(filename, symbolize_names: true, freeze: true), true] + else + [YAML.load_file(filename), false] + end + rescue TypeError, ScriptError, StandardError => e + raise InvalidLocaleData.new(filename, e.inspect) + end + end + alias_method :load_yaml, :load_yml + + # Loads a JSON translations file. The data must have locales as + # toplevel keys. + def load_json(filename) + begin + # Use #load_file as a proxy for a version of JSON where symbolize_names and freeze are supported. + if ::JSON.respond_to?(:load_file) + [::JSON.load_file(filename, symbolize_names: true, freeze: true), true] + else + [::JSON.parse(File.read(filename)), false] + end + rescue TypeError, StandardError => e + raise InvalidLocaleData.new(filename, e.inspect) + end + end + + def translate_localization_format(locale, object, format, options) + format.to_s.gsub(/%(|\^)[aAbBpP]/) do |match| + case match + when '%a' then I18n.t!(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday] + when '%^a' then I18n.t!(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday].upcase + when '%A' then I18n.t!(:"date.day_names", :locale => locale, :format => format)[object.wday] + when '%^A' then I18n.t!(:"date.day_names", :locale => locale, :format => format)[object.wday].upcase + when '%b' then I18n.t!(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon] + when '%^b' then I18n.t!(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon].upcase + when '%B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon] + when '%^B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon].upcase + when '%p' then I18n.t!(:"time.#{(object.respond_to?(:hour) ? object.hour : 0) < 12 ? :am : :pm}", :locale => locale, :format => format).upcase + when '%P' then I18n.t!(:"time.#{(object.respond_to?(:hour) ? object.hour : 0) < 12 ? :am : :pm}", :locale => locale, :format => format).downcase + end + end + rescue MissingTranslationData => e + e.message + end + + def pluralization_key(entry, count) + key = :zero if count == 0 && entry.has_key?(:zero) + key ||= count == 1 ? :one : :other + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache.rb new file mode 100644 index 0000000..40c18d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +# This module allows you to easily cache all responses from the backend - thus +# speeding up the I18n aspects of your application quite a bit. +# +# To enable caching you can simply include the Cache module to the Simple +# backend - or whatever other backend you are using: +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Cache) +# +# You will also need to set a cache store implementation that you want to use: +# +# I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store) +# +# You can use any cache implementation you want that provides the same API as +# ActiveSupport::Cache (only the methods #fetch and #write are being used). +# +# The cache_key implementation by default assumes you pass values that return +# a valid key from #hash (see +# https://www.ruby-doc.org/core/classes/Object.html#M000337). However, you can +# configure your own digest method via which responds to #hexdigest (see +# https://ruby-doc.org/stdlib/libdoc/openssl/rdoc/OpenSSL/Digest.html): +# +# I18n.cache_key_digest = OpenSSL::Digest::SHA256.new +# +# If you use a lambda as a default value in your translation like this: +# +# I18n.t(:"date.order", :default => lambda {[:month, :day, :year]}) +# +# Then you will always have a cache miss, because each time this method +# is called the lambda will have a different hash value. If you know +# the result of the lambda is a constant as in the example above, then +# to cache this you can make the lambda a constant, like this: +# +# DEFAULT_DATE_ORDER = lambda {[:month, :day, :year]} +# ... +# I18n.t(:"date.order", :default => DEFAULT_DATE_ORDER) +# +# If the lambda may result in different values for each call then consider +# also using the Memoize backend. +# +module I18n + class << self + @@cache_store = nil + @@cache_namespace = nil + @@cache_key_digest = nil + + def cache_store + @@cache_store + end + + def cache_store=(store) + @@cache_store = store + end + + def cache_namespace + @@cache_namespace + end + + def cache_namespace=(namespace) + @@cache_namespace = namespace + end + + def cache_key_digest + @@cache_key_digest + end + + def cache_key_digest=(key_digest) + @@cache_key_digest = key_digest + end + + def perform_caching? + !cache_store.nil? + end + end + + module Backend + # TODO Should the cache be cleared if new translations are stored? + module Cache + def translate(locale, key, options = EMPTY_HASH) + I18n.perform_caching? ? fetch(cache_key(locale, key, options)) { super } : super + end + + protected + + def fetch(cache_key, &block) + result = _fetch(cache_key, &block) + throw(:exception, result) if result.is_a?(MissingTranslation) + result = result.dup if result.frozen? rescue result + result + end + + def _fetch(cache_key, &block) + result = I18n.cache_store.read(cache_key) + return result unless result.nil? + result = catch(:exception, &block) + I18n.cache_store.write(cache_key, result) unless result.is_a?(Proc) + result + end + + def cache_key(locale, key, options) + # This assumes that only simple, native Ruby values are passed to I18n.translate. + "i18n/#{I18n.cache_namespace}/#{locale}/#{digest_item(key)}/#{digest_item(options)}" + end + + private + + def digest_item(key) + I18n.cache_key_digest ? I18n.cache_key_digest.hexdigest(key.to_s) : key.to_s.hash + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache_file.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache_file.rb new file mode 100644 index 0000000..0c5e192 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cache_file.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'openssl' + +module I18n + module Backend + # Overwrites the Base load_file method to cache loaded file contents. + module CacheFile + # Optionally provide path_roots array to normalize filename paths, + # to make the cached i18n data portable across environments. + attr_accessor :path_roots + + protected + + # Track loaded translation files in the `i18n.load_file` scope, + # and skip loading the file if its contents are still up-to-date. + def load_file(filename) + initialized = !respond_to?(:initialized?) || initialized? + key = I18n::Backend::Flatten.escape_default_separator(normalized_path(filename)) + old_mtime, old_digest = initialized && lookup(:i18n, key, :load_file) + return if (mtime = File.mtime(filename).to_i) == old_mtime || + (digest = OpenSSL::Digest::SHA256.file(filename).hexdigest) == old_digest + super + store_translations(:i18n, load_file: { key => [mtime, digest] }) + end + + # Translate absolute filename to relative path for i18n key. + def normalized_path(file) + return file unless path_roots + path = path_roots.find(&file.method(:start_with?)) || + raise(InvalidLocaleData.new(file, 'outside expected path roots')) + file.sub(path, path_roots.index(path).to_s) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cascade.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cascade.rb new file mode 100644 index 0000000..782b07b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/cascade.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# The Cascade module adds the ability to do cascading lookups to backends that +# are compatible to the Simple backend. +# +# By cascading lookups we mean that for any key that can not be found the +# Cascade module strips one segment off the scope part of the key and then +# tries to look up the key in that scope. +# +# E.g. when a lookup for the key :"foo.bar.baz" does not yield a result then +# the segment :bar will be stripped off the scope part :"foo.bar" and the new +# scope :foo will be used to look up the key :baz. If that does not succeed +# then the remaining scope segment :foo will be omitted, too, and again the +# key :baz will be looked up (now with no scope). +# +# To enable a cascading lookup one passes the :cascade option: +# +# I18n.t(:'foo.bar.baz', :cascade => true) +# +# This will return the first translation found for :"foo.bar.baz", :"foo.baz" +# or :baz in this order. +# +# The cascading lookup takes precedence over resolving any given defaults. +# I.e. defaults will kick in after the cascading lookups haven't succeeded. +# +# This behavior is useful for libraries like ActiveRecord validations where +# the library wants to give users a bunch of more or less fine-grained options +# of scopes for a particular key. +# +# Thanks to Clemens Kofler for the initial idea and implementation! See +# http://github.com/clemens/i18n-cascading-backend + +module I18n + module Backend + module Cascade + def lookup(locale, key, scope = [], options = EMPTY_HASH) + return super unless cascade = options[:cascade] + + cascade = { :step => 1 } unless cascade.is_a?(Hash) + step = cascade[:step] || 1 + offset = cascade[:offset] || 1 + separator = options[:separator] || I18n.default_separator + skip_root = cascade.has_key?(:skip_root) ? cascade[:skip_root] : true + + scope = I18n.normalize_keys(nil, key, scope, separator) + key = (scope.slice!(-offset, offset) || []).join(separator) + + begin + result = super + return result unless result.nil? + scope = scope.dup + end while (!scope.empty? || !skip_root) && scope.slice!(-step, step) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/chain.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/chain.rb new file mode 100644 index 0000000..e081a91 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/chain.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +module I18n + module Backend + # Backend that chains multiple other backends and checks each of them when + # a translation needs to be looked up. This is useful when you want to use + # standard translations with a Simple backend but store custom application + # translations in a database or other backends. + # + # To use the Chain backend instantiate it and set it to the I18n module. + # You can add chained backends through the initializer or backends + # accessor: + # + # # preserves the existing Simple backend set to I18n.backend + # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend) + # + # The implementation assumes that all backends added to the Chain implement + # a lookup method with the same API as Simple backend does. + # + # Fallback translations using the :default option are only used by the last backend of a chain. + class Chain + module Implementation + include Base + + attr_accessor :backends + + def initialize(*backends) + self.backends = backends + end + + def initialized? + backends.all? do |backend| + backend.instance_eval do + return false unless initialized? + end + end + true + end + + def reload! + backends.each { |backend| backend.reload! } + end + + def eager_load! + backends.each { |backend| backend.eager_load! } + end + + def store_translations(locale, data, options = EMPTY_HASH) + backends.first.store_translations(locale, data, options) + end + + def available_locales + backends.map { |backend| backend.available_locales }.flatten.uniq + end + + def translate(locale, key, default_options = EMPTY_HASH) + namespace = nil + options = Utils.except(default_options, :default) + + backends.each do |backend| + catch(:exception) do + options = default_options if backend == backends.last + translation = backend.translate(locale, key, options) + if namespace_lookup?(translation, options) + namespace = _deep_merge(translation, namespace || {}) + elsif !translation.nil? || (options.key?(:default) && options[:default].nil?) + return translation + end + end + end + + return namespace if namespace + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + + def exists?(locale, key, options = EMPTY_HASH) + backends.any? do |backend| + backend.exists?(locale, key, options) + end + end + + def localize(locale, object, format = :default, options = EMPTY_HASH) + backends.each do |backend| + catch(:exception) do + result = backend.localize(locale, object, format, options) and return result + end + end + throw(:exception, I18n::MissingTranslation.new(locale, format, options)) + end + + protected + def init_translations + backends.each do |backend| + backend.send(:init_translations) + end + end + + def translations + backends.reverse.each_with_object({}) do |backend, memo| + partial_translations = backend.instance_eval do + init_translations unless initialized? + translations + end + Utils.deep_merge!(memo, partial_translations) { |_, a, b| b || a } + end + end + + def namespace_lookup?(result, options) + result.is_a?(Hash) && !options.has_key?(:count) + end + + private + # This is approximately what gets used in ActiveSupport. + # However since we are not guaranteed to run in an ActiveSupport context + # it is wise to have our own copy. We underscore it + # to not pollute the namespace of the including class. + def _deep_merge(hash, other_hash) + copy = hash.dup + other_hash.each_pair do |k,v| + value_from_other = hash[k] + copy[k] = value_from_other.is_a?(Hash) && v.is_a?(Hash) ? _deep_merge(value_from_other, v) : v + end + copy + end + end + + include Implementation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/fallbacks.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/fallbacks.rb new file mode 100644 index 0000000..0ab50a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/fallbacks.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +# I18n locale fallbacks are useful when you want your application to use +# translations from other locales when translations for the current locale are +# missing. E.g. you might want to use :en translations when translations in +# your applications main locale :de are missing. +# +# To enable locale fallbacks you can simply include the Fallbacks module to +# the Simple backend - or whatever other backend you are using: +# +# I18n::Backend::Simple.include(I18n::Backend::Fallbacks) +module I18n + @@fallbacks = nil + + class << self + # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+. + def fallbacks + @@fallbacks ||= I18n::Locale::Fallbacks.new + if Fiber.respond_to?(:[]) + Fiber[:i18n_fallbacks] || @@fallbacks + else + Thread.current[:i18n_fallbacks] || @@fallbacks + end + end + + # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation. + def fallbacks=(fallbacks) + @@fallbacks = fallbacks.is_a?(Array) ? I18n::Locale::Fallbacks.new(fallbacks) : fallbacks + if Fiber.respond_to?(:[]) + Fiber[:i18n_fallbacks] = @@fallbacks + else + Thread.current[:i18n_fallbacks] = @@fallbacks + end + end + end + + module Backend + module Fallbacks + # Overwrites the Base backend translate method so that it will try each + # locale given by I18n.fallbacks for the given locale. E.g. for the + # locale :"de-DE" it might try the locales :"de-DE", :de and :en + # (depends on the fallbacks implementation) until it finds a result with + # the given options. If it does not find any result for any of the + # locales it will then throw MissingTranslation as usual. + # + # The default option takes precedence over fallback locales only when + # it's a Symbol. When the default contains a String, Proc or Hash + # it is evaluated last after all the fallback locales have been tried. + def translate(locale, key, options = EMPTY_HASH) + return super unless options.fetch(:fallback, true) + return super if options[:fallback_in_progress] + default = extract_non_symbol_default!(options) if options[:default] + + fallback_options = options.merge(:fallback_in_progress => true, fallback_original_locale: locale) + I18n.fallbacks[locale].each do |fallback| + begin + catch(:exception) do + result = super(fallback, key, fallback_options) + unless result.nil? + on_fallback(locale, fallback, key, options) if locale.to_s != fallback.to_s + return result + end + end + rescue I18n::InvalidLocale + # we do nothing when the locale is invalid, as this is a fallback anyways. + end + end + + return if options.key?(:default) && options[:default].nil? + + return super(locale, nil, options.merge(:default => default)) if default + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + + def resolve_entry(locale, object, subject, options = EMPTY_HASH) + return subject if options[:resolve] == false + result = catch(:exception) do + options.delete(:fallback_in_progress) if options.key?(:fallback_in_progress) + + case subject + when Symbol + I18n.translate(subject, **options.merge( + :locale => options[:fallback_original_locale], + :throw => true, + :skip_interpolation => true + )) + when Proc + date_or_time = options.delete(:object) || object + resolve_entry(options[:fallback_original_locale], object, subject.call(date_or_time, **options)) + else + subject + end + end + result unless result.is_a?(MissingTranslation) + end + + def extract_non_symbol_default!(options) + defaults = [options[:default]].flatten + first_non_symbol_default = defaults.detect{|default| !default.is_a?(Symbol)} + if first_non_symbol_default + options[:default] = defaults[0, defaults.index(first_non_symbol_default)] + end + return first_non_symbol_default + end + + def exists?(locale, key, options = EMPTY_HASH) + return super unless options.fetch(:fallback, true) + I18n.fallbacks[locale].each do |fallback| + begin + return true if super(fallback, key, options) + rescue I18n::InvalidLocale + # we do nothing when the locale is invalid, as this is a fallback anyways. + end + end + + false + end + + private + + # Overwrite on_fallback to add specified logic when the fallback succeeds. + def on_fallback(_original_locale, _fallback_locale, _key, _options) + nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/flatten.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/flatten.rb new file mode 100644 index 0000000..e9bd9d5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/flatten.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +module I18n + module Backend + # This module contains several helpers to assist flattening translations. + # You may want to flatten translations for: + # + # 1) speed up lookups, as in the Memoize backend; + # 2) In case you want to store translations in a data store, as in ActiveRecord backend; + # + # You can check both backends above for some examples. + # This module also keeps all links in a hash so they can be properly resolved when flattened. + module Flatten + SEPARATOR_ESCAPE_CHAR = "\001" + FLATTEN_SEPARATOR = "." + + # normalize_keys the flatten way. This method is significantly faster + # and creates way less objects than the one at I18n.normalize_keys. + # It also handles escaping the translation keys. + def self.normalize_flat_keys(locale, key, scope, separator) + keys = [scope, key] + keys.flatten! + keys.compact! + + separator ||= I18n.default_separator + + if separator != FLATTEN_SEPARATOR + from_str = "#{FLATTEN_SEPARATOR}#{separator}" + to_str = "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}" + + keys.map! { |k| k.to_s.tr from_str, to_str } + end + + keys.join(".") + end + + # Receives a string and escape the default separator. + def self.escape_default_separator(key) #:nodoc: + key.to_s.tr(FLATTEN_SEPARATOR, SEPARATOR_ESCAPE_CHAR) + end + + # Shortcut to I18n::Backend::Flatten.normalize_flat_keys + # and then resolve_links. + def normalize_flat_keys(locale, key, scope, separator) + key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, separator) + resolve_link(locale, key) + end + + # Store flattened links. + def links + @links ||= I18n.new_double_nested_cache + end + + # Flatten keys for nested Hashes by chaining up keys: + # + # >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind + # => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" } + # + def flatten_keys(hash, escape, prev_key=nil, &block) + hash.each_pair do |key, value| + key = escape_default_separator(key) if escape + curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym + yield curr_key, value + flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash) + end + end + + # Receives a hash of translations (where the key is a locale and + # the value is another hash) and return a hash with all + # translations flattened. + # + # Nested hashes are included in the flattened hash just if subtree + # is true and Symbols are automatically stored as links. + def flatten_translations(locale, data, escape, subtree) + hash = {} + flatten_keys(data, escape) do |key, value| + if value.is_a?(Hash) + hash[key] = value if subtree + else + store_link(locale, key, value) if value.is_a?(Symbol) + hash[key] = value + end + end + hash + end + + protected + + def store_link(locale, key, link) + links[locale.to_sym][key.to_s] = link.to_s + end + + def resolve_link(locale, key) + key, locale = key.to_s, locale.to_sym + links = self.links[locale] + + if links.key?(key) + links[key] + elsif link = find_link(locale, key) + store_link(locale, key, key.gsub(*link)) + else + key + end + end + + def find_link(locale, key) #:nodoc: + links[locale].each_pair do |from, to| + return [from, to] if key[0, from.length] == from + end && nil + end + + def escape_default_separator(key) #:nodoc: + I18n::Backend::Flatten.escape_default_separator(key) + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/gettext.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/gettext.rb new file mode 100644 index 0000000..0769646 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/gettext.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'i18n/gettext' +require 'i18n/gettext/po_parser' + +module I18n + module Backend + # Experimental support for using Gettext po files to store translations. + # + # To use this you can simply include the module to the Simple backend - or + # whatever other backend you are using. + # + # I18n::Backend::Simple.include(I18n::Backend::Gettext) + # + # Now you should be able to include your Gettext translation (*.po) files to + # the +I18n.load_path+ so they're loaded to the backend and you can use them as + # usual: + # + # I18n.load_path += Dir["path/to/locales/*.po"] + # + # Following the Gettext convention this implementation expects that your + # translation files are named by their locales. E.g. the file en.po would + # contain the translations for the English locale. + # + # To translate text you must use one of the translate methods provided by + # I18n::Gettext::Helpers. + # + # include I18n::Gettext::Helpers + # puts _("some string") + # + # Without it strings containing periods (".") will not be translated. + + module Gettext + class PoData < Hash + def set_comment(msgid_or_sym, comment) + # ignore + end + end + + protected + def load_po(filename) + locale = ::File.basename(filename, '.po').to_sym + data = normalize(locale, parse(filename)) + [{ locale => data }, false] + end + + def parse(filename) + GetText::PoParser.new.parse(::File.read(filename), PoData.new) + end + + def normalize(locale, data) + data.inject({}) do |result, (key, value)| + unless key.nil? || key.empty? + key = key.gsub(I18n::Gettext::CONTEXT_SEPARATOR, '|') + key, value = normalize_pluralization(locale, key, value) if key.index("\000") + + parts = key.split('|').reverse + normalized = parts.inject({}) do |_normalized, part| + { part => _normalized.empty? ? value : _normalized } + end + + Utils.deep_merge!(result, normalized) + end + result + end + end + + def normalize_pluralization(locale, key, value) + # FIXME po_parser includes \000 chars that can not be turned into Symbols + key = key.gsub("\000", I18n::Gettext::PLURAL_SEPARATOR).split(I18n::Gettext::PLURAL_SEPARATOR).first + + keys = I18n::Gettext.plural_keys(locale) + values = value.split("\000") + raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect} on #{locale} locale for msgid #{key.inspect} with values #{values.inspect}" if values.size != keys.size + + result = {} + values.each_with_index { |_value, ix| result[keys[ix]] = _value } + [key, result] + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/interpolation_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/interpolation_compiler.rb new file mode 100644 index 0000000..0e5c872 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/interpolation_compiler.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +# The InterpolationCompiler module contains optimizations that can tremendously +# speed up the interpolation process on the Simple backend. +# +# It works by defining a pre-compiled method on stored translation Strings that +# already bring all the knowledge about contained interpolation variables etc. +# so that the actual recurring interpolation will be very fast. +# +# To enable pre-compiled interpolations you can simply include the +# InterpolationCompiler module to the Simple backend: +# +# I18n::Backend::Simple.include(I18n::Backend::InterpolationCompiler) +# +# Note that InterpolationCompiler does not yield meaningful results and consequently +# should not be used with Ruby 1.9 (YARV) but improves performance everywhere else +# (jRuby, Rubinius). +module I18n + module Backend + module InterpolationCompiler + module Compiler + extend self + + TOKENIZER = /(%%?\{[^}]+\})/ + + def compile_if_an_interpolation(string) + if interpolated_str?(string) + string = +string + string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + def i18n_interpolate(v = {}) + "#{compiled_interpolation_body(string)}" + end + RUBY_EVAL + end + + string + end + + def interpolated_str?(str) + str.kind_of?(::String) && str =~ TOKENIZER + end + + protected + # tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"] + def tokenize(str) + str.split(TOKENIZER) + end + + def compiled_interpolation_body(str) + tokenize(str).map do |token| + token.match(TOKENIZER) ? handle_interpolation_token(token) : escape_plain_str(token) + end.join + end + + def handle_interpolation_token(token) + token.start_with?('%%') ? token[1..] : compile_interpolation_token(token[2..-2]) + end + + def compile_interpolation_token(key) + "\#{#{interpolate_or_raise_missing(key)}}" + end + + def interpolate_or_raise_missing(key) + escaped_key = escape_key_sym(key) + RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key) + end + + def interpolate_key(key) + [direct_key(key), nil_key(key), missing_key(key)].join('||') + end + + def direct_key(key) + "((t = v[#{key}]) && t.respond_to?(:call) ? t.call : t)" + end + + def nil_key(key) + "(v.has_key?(#{key}) && '')" + end + + def missing_key(key) + "I18n.config.missing_interpolation_argument_handler.call(#{key}, v, self)" + end + + def reserved_key(key) + "raise(ReservedInterpolationKey.new(#{key}, self))" + end + + def escape_plain_str(str) + str.gsub(/"|\\|#/) {|x| "\\#{x}"} + end + + def escape_key_sym(key) + # rely on Ruby to do all the hard work :) + key.to_sym.inspect + end + end + + def interpolate(locale, string, values) + if string.respond_to?(:i18n_interpolate) + string.i18n_interpolate(values) + elsif values + super + else + string + end + end + + def store_translations(locale, data, options = EMPTY_HASH) + compile_all_strings_in(data) + super + end + + protected + def compile_all_strings_in(data) + data.each_value do |value| + Compiler.compile_if_an_interpolation(value) + compile_all_strings_in(value) if value.kind_of?(Hash) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/key_value.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/key_value.rb new file mode 100644 index 0000000..b937e25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/key_value.rb @@ -0,0 +1,204 @@ +# frozen_string_literal: true + +require 'i18n/backend/base' + +module I18n + + begin + require 'oj' + class JSON + class << self + def encode(value) + Oj::Rails.encode(value) + end + def decode(value) + Oj.load(value) + end + end + end + rescue LoadError + require 'active_support/json' + JSON = ActiveSupport::JSON + end + + module Backend + # This is a basic backend for key value stores. It receives on + # initialization the store, which should respond to three methods: + # + # * store#[](key) - Used to get a value + # * store#[]=(key, value) - Used to set a value + # * store#keys - Used to get all keys + # + # Since these stores only supports string, all values are converted + # to JSON before being stored, allowing it to also store booleans, + # hashes and arrays. However, this store does not support Procs. + # + # As the ActiveRecord backend, Symbols are just supported when loading + # translations from the filesystem or through explicit store translations. + # + # Also, avoid calling I18n.available_locales since it's a somehow + # expensive operation in most stores. + # + # == Example + # + # To setup I18n to use TokyoCabinet in memory is quite straightforward: + # + # require 'rufus/tokyo/cabinet' # gem install rufus-tokyo + # I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*')) + # + # == Performance + # + # You may make this backend even faster by including the Memoize module. + # However, notice that you should properly clear the cache if you change + # values directly in the key-store. + # + # == Subtrees + # + # In most backends, you are allowed to retrieve part of a translation tree: + # + # I18n.backend.store_translations :en, :foo => { :bar => :baz } + # I18n.t "foo" #=> { :bar => :baz } + # + # This backend supports this feature by default, but it slows down the storage + # of new data considerably and makes hard to delete entries. That said, you are + # allowed to disable the storage of subtrees on initialization: + # + # I18n::Backend::KeyValue.new(@store, false) + # + # This is useful if you are using a KeyValue backend chained to a Simple backend. + class KeyValue + module Implementation + attr_accessor :store + + include Base, Flatten + + def initialize(store, subtrees=true) + @store, @subtrees = store, subtrees + end + + def initialized? + !@store.nil? + end + + def store_translations(locale, data, options = EMPTY_HASH) + escape = options.fetch(:escape, true) + flatten_translations(locale, data, escape, @subtrees).each do |key, value| + key = "#{locale}.#{key}" + + case value + when Hash + if @subtrees && (old_value = @store[key]) + old_value = JSON.decode(old_value) + value = Utils.deep_merge!(Utils.deep_symbolize_keys(old_value), value) if old_value.is_a?(Hash) + end + when Proc + raise "Key-value stores cannot handle procs" + end + + @store[key] = JSON.encode(value) unless value.is_a?(Symbol) + end + end + + def available_locales + locales = @store.keys.map { |k| k =~ /\./; $` } + locales.uniq! + locales.compact! + locales.map! { |k| k.to_sym } + locales + end + + protected + + # Queries the translations from the key-value store and converts + # them into a hash such as the one returned from loading the + # haml files + def translations + @translations = Utils.deep_symbolize_keys(@store.keys.clone.map do |main_key| + main_value = JSON.decode(@store[main_key]) + main_key.to_s.split(".").reverse.inject(main_value) do |value, key| + {key.to_sym => value} + end + end.inject{|hash, elem| Utils.deep_merge!(hash, elem)}) + end + + def init_translations + # NO OP + # This call made also inside Simple Backend and accessed by + # other plugins like I18n-js and babilu and + # to use it along with the Chain backend we need to + # provide a uniform API even for protected methods :S + end + + def subtrees? + @subtrees + end + + def lookup(locale, key, scope = [], options = EMPTY_HASH) + key = normalize_flat_keys(locale, key, scope, options[:separator]) + value = @store["#{locale}.#{key}"] + value = JSON.decode(value) if value + + if value.is_a?(Hash) + Utils.deep_symbolize_keys(value) + elsif !value.nil? + value + elsif !@subtrees + SubtreeProxy.new("#{locale}.#{key}", @store) + end + end + + def pluralize(locale, entry, count) + if subtrees? + super + else + return entry unless entry.is_a?(Hash) + key = pluralization_key(entry, count) + entry[key] + end + end + end + + class SubtreeProxy + def initialize(master_key, store) + @master_key = master_key + @store = store + @subtree = nil + end + + def has_key?(key) + @subtree && @subtree.has_key?(key) || self[key] + end + + def [](key) + unless @subtree && value = @subtree[key] + value = @store["#{@master_key}.#{key}"] + if value + value = JSON.decode(value) + (@subtree ||= {})[key] = value + end + end + value + end + + def is_a?(klass) + Hash == klass || super + end + alias :kind_of? :is_a? + + def instance_of?(klass) + Hash == klass || super + end + + def nil? + @subtree.nil? + end + + def inspect + @subtree.inspect + end + end + + include Implementation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/lazy_loadable.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/lazy_loadable.rb new file mode 100644 index 0000000..575b32b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/lazy_loadable.rb @@ -0,0 +1,184 @@ +# frozen_string_literal: true + +module I18n + module Backend + # Backend that lazy loads translations based on the current locale. This + # implementation avoids loading all translations up front. Instead, it only + # loads the translations that belong to the current locale. This offers a + # performance incentive in local development and test environments for + # applications with many translations for many different locales. It's + # particularly useful when the application only refers to a single locales' + # translations at a time (ex. A Rails workload). The implementation + # identifies which translation files from the load path belong to the + # current locale by pattern matching against their path name. + # + # Specifically, a translation file is considered to belong to a locale if: + # a) the filename is in the I18n load path + # b) the filename ends in a supported extension (ie. .yml, .json, .po, .rb) + # c) the filename starts with the locale identifier + # d) the locale identifier and optional proceeding text is separated by an underscore, ie. "_". + # + # Examples: + # Valid files that will be selected by this backend: + # + # "files/locales/en_translation.yml" (Selected for locale "en") + # "files/locales/fr.po" (Selected for locale "fr") + # + # Invalid files that won't be selected by this backend: + # + # "files/locales/translation-file" + # "files/locales/en-translation.unsupported" + # "files/locales/french/translation.yml" + # "files/locales/fr/translation.yml" + # + # The implementation uses this assumption to defer the loading of + # translation files until the current locale actually requires them. + # + # The backend has two working modes: lazy_load and eager_load. + # + # Note: This backend should only be enabled in test environments! + # When the mode is set to false, the backend behaves exactly like the + # Simple backend, with an additional check that the paths being loaded + # abide by the format. If paths can't be matched to the format, an error is raised. + # + # You can configure lazy loaded backends through the initializer or backends + # accessor: + # + # # In test environments + # + # I18n.backend = I18n::Backend::LazyLoadable.new(lazy_load: true) + # + # # In other environments, such as production and CI + # + # I18n.backend = I18n::Backend::LazyLoadable.new(lazy_load: false) # default + # + class LocaleExtractor + class << self + def locale_from_path(path) + name = File.basename(path, ".*") + locale = name.split("_").first + locale.to_sym unless locale.nil? + end + end + end + + class LazyLoadable < Simple + def initialize(lazy_load: false) + @lazy_load = lazy_load + end + + # Returns whether the current locale is initialized. + def initialized? + if lazy_load? + initialized_locales[I18n.locale] + else + super + end + end + + # Clean up translations and uninitialize all locales. + def reload! + if lazy_load? + @initialized_locales = nil + @translations = nil + else + super + end + end + + # Eager loading is not supported in the lazy context. + def eager_load! + if lazy_load? + raise UnsupportedMethod.new(__method__, self.class, "Cannot eager load translations because backend was configured with lazy_load: true.") + else + super + end + end + + # Parse the load path and extract all locales. + def available_locales + if lazy_load? + I18n.load_path.map { |path| LocaleExtractor.locale_from_path(path) }.uniq + else + super + end + end + + def lookup(locale, key, scope = [], options = EMPTY_HASH) + if lazy_load? + I18n.with_locale(locale) do + super + end + else + super + end + end + + protected + + + # Load translations from files that belong to the current locale. + def init_translations + file_errors = if lazy_load? + initialized_locales[I18n.locale] = true + load_translations_and_collect_file_errors(filenames_for_current_locale) + else + @initialized = true + load_translations_and_collect_file_errors(I18n.load_path) + end + + raise InvalidFilenames.new(file_errors) unless file_errors.empty? + end + + def initialized_locales + @initialized_locales ||= Hash.new(false) + end + + private + + def lazy_load? + @lazy_load + end + + class FilenameIncorrect < StandardError + def initialize(file, expected_locale, unexpected_locales) + super "#{file} can only load translations for \"#{expected_locale}\". Found translations for: #{unexpected_locales}." + end + end + + # Loads each file supplied and asserts that the file only loads + # translations as expected by the name. The method returns a list of + # errors corresponding to offending files. + def load_translations_and_collect_file_errors(files) + errors = [] + + load_translations(files) do |file, loaded_translations| + assert_file_named_correctly!(file, loaded_translations) + rescue FilenameIncorrect => e + errors << e + end + + errors + end + + # Select all files from I18n load path that belong to current locale. + # These files must start with the locale identifier (ie. "en", "pt-BR"), + # followed by an "_" demarcation to separate proceeding text. + def filenames_for_current_locale + I18n.load_path.flatten.select do |path| + LocaleExtractor.locale_from_path(path) == I18n.locale + end + end + + # Checks if a filename is named in correspondence to the translations it loaded. + # The locale extracted from the path must be the single locale loaded in the translations. + def assert_file_named_correctly!(file, translations) + loaded_locales = translations.keys.map(&:to_sym) + expected_locale = LocaleExtractor.locale_from_path(file) + unexpected_locales = loaded_locales.reject { |locale| locale == expected_locale } + + raise FilenameIncorrect.new(file, expected_locale, unexpected_locales) unless unexpected_locales.empty? + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/memoize.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/memoize.rb new file mode 100644 index 0000000..3293d2b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/memoize.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# Memoize module simply memoizes the values returned by lookup using +# a flat hash and can tremendously speed up the lookup process in a backend. +# +# To enable it you can simply include the Memoize module to your backend: +# +# I18n::Backend::Simple.include(I18n::Backend::Memoize) +# +# Notice that it's the responsibility of the backend to define whenever the +# cache should be cleaned. +module I18n + module Backend + module Memoize + def available_locales + @memoized_locales ||= super + end + + def store_translations(locale, data, options = EMPTY_HASH) + reset_memoizations!(locale) + super + end + + def reload! + reset_memoizations! + super + end + + def eager_load! + memoized_lookup + available_locales + super + end + + protected + + def lookup(locale, key, scope = nil, options = EMPTY_HASH) + flat_key = I18n::Backend::Flatten.normalize_flat_keys(locale, + key, scope, options[:separator]).to_sym + flat_hash = memoized_lookup[locale.to_sym] + flat_hash.key?(flat_key) ? flat_hash[flat_key] : (flat_hash[flat_key] = super) + end + + def memoized_lookup + @memoized_lookup ||= I18n.new_double_nested_cache + end + + def reset_memoizations!(locale=nil) + @memoized_locales = nil + (locale ? memoized_lookup[locale.to_sym] : memoized_lookup).clear + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/metadata.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/metadata.rb new file mode 100644 index 0000000..51ea7a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/metadata.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +# I18n translation metadata is useful when you want to access information +# about how a translation was looked up, pluralized or interpolated in +# your application. +# +# msg = I18n.t(:message, :default => 'Hi!', :scope => :foo) +# msg.translation_metadata +# # => { :key => :message, :scope => :foo, :default => 'Hi!' } +# +# If a :count option was passed to #translate it will be set to the metadata. +# Likewise, if any interpolation variables were passed they will also be set. +# +# To enable translation metadata you can simply include the Metadata module +# into the Simple backend class - or whatever other backend you are using: +# +# I18n::Backend::Simple.include(I18n::Backend::Metadata) +# +module I18n + module Backend + module Metadata + class << self + def included(base) + Object.class_eval do + def translation_metadata + unless self.frozen? + @translation_metadata ||= {} + else + {} + end + end + + def translation_metadata=(translation_metadata) + @translation_metadata = translation_metadata unless self.frozen? + end + end unless Object.method_defined?(:translation_metadata) + end + end + + def translate(locale, key, options = EMPTY_HASH) + metadata = { + :locale => locale, + :key => key, + :scope => options[:scope], + :default => options[:default], + :separator => options[:separator], + :values => options.reject { |name, _value| RESERVED_KEYS.include?(name) } + } + with_metadata(metadata) { super } + end + + def interpolate(locale, entry, values = EMPTY_HASH) + metadata = entry.translation_metadata.merge(:original => entry) + with_metadata(metadata) { super } + end + + def pluralize(locale, entry, count) + with_metadata(:count => count) { super } + end + + protected + + def with_metadata(metadata, &block) + result = yield + result.translation_metadata = result.translation_metadata.merge(metadata) if result + result + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/pluralization.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/pluralization.rb new file mode 100644 index 0000000..1d3277b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/pluralization.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +# I18n Pluralization are useful when you want your application to +# customize pluralization rules. +# +# To enable locale specific pluralizations you can simply include the +# Pluralization module to the Simple backend - or whatever other backend you +# are using. +# +# I18n::Backend::Simple.include(I18n::Backend::Pluralization) +# +# You also need to make sure to provide pluralization algorithms to the +# backend, i.e. include them to your I18n.load_path accordingly. +module I18n + module Backend + module Pluralization + # Overwrites the Base backend translate method so that it will check the + # translation meta data space (:i18n) for a locale specific pluralization + # rule and use it to pluralize the given entry. I.e., the library expects + # pluralization rules to be stored at I18n.t(:'i18n.plural.rule') + # + # Pluralization rules are expected to respond to #call(count) and + # return a pluralization key. Valid keys depend on the pluralization + # rules for the locale, as defined in the CLDR. + # As of v41, 6 locale-specific plural categories are defined: + # :few, :many, :one, :other, :two, :zero + # + # n.b., The :one plural category does not imply the number 1. + # Instead, :one is a category for any number that behaves like 1 in + # that locale. For example, in some locales, :one is used for numbers + # that end in "1" (like 1, 21, 151) but that don't end in + # 11 (like 11, 111, 10311). + # Similar notes apply to the :two, and :zero plural categories. + # + # If you want to have different strings for the categories of count == 0 + # (e.g. "I don't have any cars") or count == 1 (e.g. "I have a single car") + # use the explicit `"0"` and `"1"` keys. + # https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#Explicit_0_1_rules + def pluralize(locale, entry, count) + return entry unless entry.is_a?(Hash) && count + + pluralizer = pluralizer(locale) + if pluralizer.respond_to?(:call) + # Deprecation: The use of the `zero` key in this way is incorrect. + # Users that want a different string for the case of `count == 0` should use the explicit "0" key instead. + # We keep this incorrect behaviour for now for backwards compatibility until we can remove it. + # Ref: https://github.com/ruby-i18n/i18n/issues/629 + return entry[:zero] if count == 0 && entry.has_key?(:zero) + + # "0" and "1" are special cases + # https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#Explicit_0_1_rules + if count == 0 || count == 1 + value = entry[symbolic_count(count)] + return value if value + end + + # Lateral Inheritance of "count" attribute (http://www.unicode.org/reports/tr35/#Lateral_Inheritance): + # > If there is no value for a path, and that path has a [@count="x"] attribute and value, then: + # > 1. If "x" is numeric, the path falls back to the path with [@count=«the plural rules category for x for that locale»], within that the same locale. + # > 2. If "x" is anything but "other", it falls back to a path [@count="other"], within that the same locale. + # > 3. If "x" is "other", it falls back to the path that is completely missing the count item, within that the same locale. + # Note: We don't yet implement #3 above, since we haven't decided how lateral inheritance attributes should be represented. + plural_rule_category = pluralizer.call(count) + + value = if entry.has_key?(plural_rule_category) || entry.has_key?(:other) + entry[plural_rule_category] || entry[:other] + else + raise InvalidPluralizationData.new(entry, count, plural_rule_category) + end + else + super + end + end + + protected + + def pluralizers + @pluralizers ||= {} + end + + def pluralizer(locale) + pluralizers[locale] ||= I18n.t(:'i18n.plural.rule', :locale => locale, :resolve => false) + end + + private + + # Normalizes categories of 0.0 and 1.0 + # and returns the symbolic version + def symbolic_count(count) + count = 0 if count == 0 + count = 1 if count == 1 + count.to_s.to_sym + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/simple.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/simple.rb new file mode 100644 index 0000000..7cef780 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/simple.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require 'i18n/backend/base' + +module I18n + module Backend + # A simple backend that reads translations from YAML files and stores them in + # an in-memory hash. Relies on the Base backend. + # + # The implementation is provided by a Implementation module allowing to easily + # extend Simple backend's behavior by including modules. E.g.: + # + # module I18n::Backend::Pluralization + # def pluralize(*args) + # # extended pluralization logic + # super + # end + # end + # + # I18n::Backend::Simple.include(I18n::Backend::Pluralization) + class Simple + module Implementation + include Base + + # Mutex to ensure that concurrent translations loading will be thread-safe + MUTEX = Mutex.new + + def initialized? + @initialized ||= false + end + + # Stores translations for the given locale in memory. + # This uses a deep merge for the translations hash, so existing + # translations will be overwritten by new ones only at the deepest + # level of the hash. + def store_translations(locale, data, options = EMPTY_HASH) + if I18n.enforce_available_locales && + I18n.available_locales_initialized? && + !I18n.locale_available?(locale) + return data + end + locale = locale.to_sym + translations[locale] ||= Concurrent::Hash.new + data = Utils.deep_symbolize_keys(data) unless options.fetch(:skip_symbolize_keys, false) + MUTEX.synchronize { Utils.deep_merge!(translations[locale], data) } + end + + # Get available locales from the translations hash + def available_locales + init_translations unless initialized? + translations.inject([]) do |locales, (locale, data)| + locales << locale unless data.size <= 1 && (data.empty? || data.has_key?(:i18n)) + locales + end + end + + # Clean up translations hash and set initialized to false on reload! + def reload! + @initialized = false + @translations = nil + super + end + + def eager_load! + init_translations unless initialized? + super + end + + def translations(do_init: false) + # To avoid returning empty translations, + # call `init_translations` + init_translations if do_init && !initialized? + + @translations ||= Concurrent::Hash.new do |h, k| + MUTEX.synchronize do + h[k] = Concurrent::Hash.new + end + end + end + + protected + + def init_translations + load_translations + @initialized = true + end + + # Looks up a translation from the translations hash. Returns nil if + # either key is nil, or locale, scope or key do not exist as a key in the + # nested translations hash. Splits keys or scopes containing dots + # into multiple keys, i.e. currency.format is regarded the same as + # %w(currency format). + def lookup(locale, key, scope = [], options = EMPTY_HASH) + init_translations unless initialized? + keys = I18n.normalize_keys(locale, key, scope, options[:separator]) + + keys.inject(translations) do |result, _key| + return nil unless result.is_a?(Hash) + unless result.has_key?(_key) + _key = _key.to_s.to_sym + return nil unless result.has_key?(_key) + end + result = result[_key] + result = resolve_entry(locale, _key, result, Utils.except(options.merge(:scope => nil), :count)) if result.is_a?(Symbol) + result + end + end + end + + include Implementation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/transliterator.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/transliterator.rb new file mode 100644 index 0000000..00679c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/backend/transliterator.rb @@ -0,0 +1,109 @@ +# encoding: utf-8 +# frozen_string_literal: true + +module I18n + module Backend + module Transliterator + DEFAULT_REPLACEMENT_CHAR = "?" + + # Given a locale and a UTF-8 string, return the locale's ASCII + # approximation for the string. + def transliterate(locale, string, replacement = nil) + @transliterators ||= {} + @transliterators[locale] ||= Transliterator.get I18n.t(:'i18n.transliterate.rule', + :locale => locale, :resolve => false, :default => {}) + @transliterators[locale].transliterate(string, replacement) + end + + # Get a transliterator instance. + def self.get(rule = nil) + if !rule || rule.kind_of?(Hash) + HashTransliterator.new(rule) + elsif rule.kind_of? Proc + ProcTransliterator.new(rule) + else + raise I18n::ArgumentError, "Transliteration rule must be a proc or a hash." + end + end + + # A transliterator which accepts a Proc as its transliteration rule. + class ProcTransliterator + def initialize(rule) + @rule = rule + end + + def transliterate(string, replacement = nil) + @rule.call(string) + end + end + + # A transliterator which accepts a Hash of characters as its translation + # rule. + class HashTransliterator + DEFAULT_APPROXIMATIONS = { + "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"AE", + "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I", + "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O", + "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U", + "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "ẞ"=>"SS", "à"=>"a", + "á"=>"a", "â"=>"a", "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", + "è"=>"e", "é"=>"e", "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", + "ï"=>"i", "ð"=>"d", "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", + "ö"=>"o", "ø"=>"o", "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", + "þ"=>"th", "ÿ"=>"y", "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", + "ą"=>"a", "Ć"=>"C", "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", + "Č"=>"C", "č"=>"c", "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", + "ē"=>"e", "Ĕ"=>"E", "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", + "Ě"=>"E", "ě"=>"e", "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", + "ġ"=>"g", "Ģ"=>"G", "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", + "Ĩ"=>"I", "ĩ"=>"i", "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", + "į"=>"i", "İ"=>"I", "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", + "Ķ"=>"K", "ķ"=>"k", "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", + "Ľ"=>"L", "ľ"=>"l", "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", + "ń"=>"n", "Ņ"=>"N", "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", + "ŋ"=>"ng", "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", + "Œ"=>"OE", "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", + "ř"=>"r", "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", + "Š"=>"S", "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", + "ŧ"=>"t", "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", + "Ů"=>"U", "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", + "ŵ"=>"w", "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", + "ż"=>"z", "Ž"=>"Z", "ž"=>"z", "Ǫ"=>"O", "ǫ"=>"o", "Ǭ"=>"O", + "ǭ"=>"o" + }.freeze + + def initialize(rule = nil) + @rule = rule + add_default_approximations + add rule if rule + end + + def transliterate(string, replacement = nil) + replacement ||= DEFAULT_REPLACEMENT_CHAR + string.gsub(/[^\x00-\x7f]/u) do |char| + approximations[char] || (replacement == :none ? char : replacement) + end + end + + private + + def approximations + @approximations ||= {} + end + + def add_default_approximations + DEFAULT_APPROXIMATIONS.each do |key, value| + approximations[key] = value + end + end + + # Add transliteration rules to the approximations hash. + def add(hash) + hash.each do |key, value| + approximations[key.to_s] = value.to_s + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/config.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/config.rb new file mode 100644 index 0000000..2424c27 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/config.rb @@ -0,0 +1,199 @@ +# frozen_string_literal: true + +require 'set' + +module I18n + class Config + # The only configuration value that is not global and scoped to thread is :locale. + # It defaults to the default_locale. + def locale + defined?(@locale) && @locale != nil ? @locale : default_locale + end + + def initialize + @owner = Fiber.current + end + + def owned_by?(fiber) + @owner == fiber + end + + def owner=(fiber) + @owner = fiber + end + + def initialize_copy(other) + @owner = Fiber.current + end + + # Returns a copied configuration with the provided attributes set. + def with(**attrs) + dup.tap do |copy| + attrs.each do |name, value| + copy.public_send("#{name}=", value) + end + end + end + + # Sets this configuration as the current one for the active execution context. + # The stored configuration is frozen to avoid sharing mutable state between fibers. + def set! + self.owner = Fiber.current unless frozen? + freeze + I18n.config = self + self + end + + # Sets the current locale pseudo-globally, i.e. in the Thread.current or Fiber local hash. + def locale=(locale) + I18n.enforce_available_locales!(locale) + @locale = locale && locale.to_sym + end + + # Returns the current backend. Defaults to +Backend::Simple+. + def backend + @@backend ||= Backend::Simple.new + end + + # Sets the current backend. Used to set a custom backend. + def backend=(backend) + @@backend = backend + end + + # Returns the current default locale. Defaults to :'en' + def default_locale + @@default_locale ||= :en + end + + # Sets the current default locale. Used to set a custom default locale. + def default_locale=(locale) + I18n.enforce_available_locales!(locale) + @@default_locale = locale && locale.to_sym + end + + # Returns an array of locales for which translations are available. + # Unless you explicitly set these through I18n.available_locales= + # the call will be delegated to the backend. + def available_locales + @@available_locales ||= nil + @@available_locales || backend.available_locales + end + + # Caches the available locales list as both strings and symbols in a Set, so + # that we can have faster lookups to do the available locales enforce check. + def available_locales_set #:nodoc: + @@available_locales_set ||= available_locales.inject(Set.new) do |set, locale| + set << locale.to_s << locale.to_sym + end + end + + # Sets the available locales. + def available_locales=(locales) + @@available_locales = Array(locales).map { |locale| locale.to_sym } + @@available_locales = nil if @@available_locales.empty? + @@available_locales_set = nil + end + + # Returns true if the available_locales have been initialized + def available_locales_initialized? + ( !!defined?(@@available_locales) && !!@@available_locales ) + end + + # Clears the available locales set so it can be recomputed again after I18n + # gets reloaded. + def clear_available_locales_set #:nodoc: + @@available_locales_set = nil + end + + # Returns the current default scope separator. Defaults to '.' + def default_separator + @@default_separator ||= '.' + end + + # Sets the current default scope separator. + def default_separator=(separator) + @@default_separator = separator + end + + # Returns the current exception handler. Defaults to an instance of + # I18n::ExceptionHandler. + def exception_handler + @@exception_handler ||= ExceptionHandler.new + end + + # Sets the exception handler. + def exception_handler=(exception_handler) + @@exception_handler = exception_handler + end + + # Returns the current handler for situations when interpolation argument + # is missing. MissingInterpolationArgument will be raised by default. + def missing_interpolation_argument_handler + @@missing_interpolation_argument_handler ||= lambda do |missing_key, provided_hash, string| + raise MissingInterpolationArgument.new(missing_key, provided_hash, string) + end + end + + # Sets the missing interpolation argument handler. It can be any + # object that responds to #call. The arguments that will be passed to #call + # are the same as for MissingInterpolationArgument initializer. Use +Proc.new+ + # if you don't care about arity. + # + # == Example: + # You can suppress raising an exception and return string instead: + # + # I18n.config.missing_interpolation_argument_handler = Proc.new do |key| + # "#{key} is missing" + # end + def missing_interpolation_argument_handler=(exception_handler) + @@missing_interpolation_argument_handler = exception_handler + end + + # Allow clients to register paths providing translation data sources. The + # backend defines acceptable sources. + # + # E.g. the provided SimpleBackend accepts a list of paths to translation + # files which are either named *.rb and contain plain Ruby Hashes or are + # named *.yml and contain YAML data. So for the SimpleBackend clients may + # register translation files like this: + # I18n.load_path << 'path/to/locale/en.yml' + def load_path + @@load_path ||= [] + end + + # Sets the load path instance. Custom implementations are expected to + # behave like a Ruby Array. + def load_path=(load_path) + @@load_path = load_path + @@available_locales_set = nil + backend.reload! + end + + # Whether or not to verify if locales are in the list of available locales. + # Defaults to true. + @@enforce_available_locales = true + def enforce_available_locales + @@enforce_available_locales + end + + def enforce_available_locales=(enforce_available_locales) + @@enforce_available_locales = enforce_available_locales + end + + # Returns the current interpolation patterns. Defaults to + # I18n::DEFAULT_INTERPOLATION_PATTERNS. + def interpolation_patterns + @@interpolation_patterns ||= I18n::DEFAULT_INTERPOLATION_PATTERNS.dup + end + + # Sets the current interpolation patterns. Used to set a interpolation + # patterns. + # + # E.g. using {{}} as a placeholder like "{{hello}}, world!": + # + # I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/ + def interpolation_patterns=(interpolation_patterns) + @@interpolation_patterns = interpolation_patterns + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/exceptions.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/exceptions.rb new file mode 100644 index 0000000..100055c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/exceptions.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +module I18n + class ExceptionHandler + def call(exception, _locale, _key, _options) + if exception.is_a?(MissingTranslation) + exception.message + else + raise exception + end + end + end + + class ArgumentError < ::ArgumentError; end + + class Disabled < ArgumentError + def initialize(method) + super(<<~MESSAGE) + I18n.#{method} is currently disabled, likely because your application is still in its loading phase. + + This method is meant to display text in the user locale, so calling it before the user locale has + been set is likely to display text from the wrong locale to some users. + + If you have a legitimate reason to access i18n data outside of the user flow, you can do so by passing + the desired locale explicitly with the `locale` argument, e.g. `I18n.#{method}(..., locale: :en)` + MESSAGE + end + end + + class InvalidLocale < ArgumentError + attr_reader :locale + def initialize(locale) + @locale = locale + super "#{locale.inspect} is not a valid locale" + end + end + + class InvalidLocaleData < ArgumentError + attr_reader :filename + def initialize(filename, exception_message) + @filename, @exception_message = filename, exception_message + super "can not load translations from #{filename}: #{exception_message}" + end + end + + class MissingTranslation < ArgumentError + module Base + PERMITTED_KEYS = [:scope, :default].freeze + + attr_reader :locale, :key, :options + + def initialize(locale, key, options = EMPTY_HASH) + @key, @locale, @options = key, locale, options.slice(*PERMITTED_KEYS) + options.each { |k, v| self.options[k] = v.inspect if v.is_a?(Proc) } + end + + def keys + @keys ||= I18n.normalize_keys(locale, key, options[:scope]).tap do |keys| + keys << 'no key' if keys.size < 2 + end + end + + def message + if (default = options[:default]).is_a?(Array) && default.any? + other_options = ([key, *default]).map { |k| normalized_option(k).prepend('- ') }.join("\n") + "Translation missing. Options considered were:\n#{other_options}" + else + "Translation missing: #{keys.join('.')}" + end + end + + def normalized_option(key) + I18n.normalize_keys(locale, key, options[:scope]).join('.') + end + + alias :to_s :message + + def to_exception + MissingTranslationData.new(locale, key, options) + end + end + + include Base + end + + class MissingTranslationData < ArgumentError + include MissingTranslation::Base + end + + class InvalidPluralizationData < ArgumentError + attr_reader :entry, :count, :key + def initialize(entry, count, key) + @entry, @count, @key = entry, count, key + super "translation data #{entry.inspect} can not be used with :count => #{count}. key '#{key}' is missing." + end + end + + class MissingInterpolationArgument < ArgumentError + attr_reader :key, :values, :string + def initialize(key, values, string) + @key, @values, @string = key, values, string + super "missing interpolation argument #{key.inspect} in #{string.inspect} (#{values.inspect} given)" + end + end + + class ReservedInterpolationKey < ArgumentError + attr_reader :key, :string + def initialize(key, string) + @key, @string = key, string + super "reserved key #{key.inspect} used in #{string.inspect}" + end + end + + class UnknownFileType < ArgumentError + attr_reader :type, :filename + def initialize(type, filename) + @type, @filename = type, filename + super "can not load translations from #{filename}, the file type #{type} is not known" + end + end + + class UnsupportedMethod < ArgumentError + attr_reader :method, :backend_klass, :msg + def initialize(method, backend_klass, msg) + @method = method + @backend_klass = backend_klass + @msg = msg + super "#{backend_klass} does not support the ##{method} method. #{msg}" + end + end + + class InvalidFilenames < ArgumentError + NUMBER_OF_ERRORS_SHOWN = 20 + def initialize(file_errors) + super <<~MSG + Found #{file_errors.count} error(s). + The first #{[file_errors.count, NUMBER_OF_ERRORS_SHOWN].min} error(s): + #{file_errors.map(&:message).first(NUMBER_OF_ERRORS_SHOWN).join("\n")} + + To use the LazyLoadable backend: + 1. Filenames must start with the locale. + 2. An underscore must separate the locale with any optional text that follows. + 3. The file must only contain translation data for the single locale. + + Example: + "/config/locales/fr.yml" which contains: + ```yml + fr: + dog: + chien + ``` + MSG + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext.rb new file mode 100644 index 0000000..858daff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module I18n + module Gettext + PLURAL_SEPARATOR = "\001" + CONTEXT_SEPARATOR = "\004" + + autoload :Helpers, 'i18n/gettext/helpers' + + @@plural_keys = { :en => [:one, :other] } + + class << self + # returns an array of plural keys for the given locale or the whole hash + # of locale mappings to plural keys so that we can convert from gettext's + # integer-index based style + # TODO move this information to the pluralization module + def plural_keys(*args) + args.empty? ? @@plural_keys : @@plural_keys[args.first] || @@plural_keys[:en] + end + + def extract_scope(msgid, separator) + scope = msgid.to_s.split(separator) + msgid = scope.pop + [scope, msgid] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/helpers.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/helpers.rb new file mode 100644 index 0000000..d077619 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/helpers.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'i18n/gettext' + +module I18n + module Gettext + # Implements classical Gettext style accessors. To use this include the + # module to the global namespace or wherever you want to use it. + # + # include I18n::Gettext::Helpers + module Helpers + # Makes dynamic translation messages readable for the gettext parser. + # _(fruit) cannot be understood by the gettext parser. To help the parser find all your translations, + # you can add fruit = N_("Apple") which does not translate, but tells the parser: "Apple" needs translation. + # * msgid: the message id. + # * Returns: msgid. + def N_(msgsid) + msgsid + end + + def gettext(msgid, options = EMPTY_HASH) + I18n.t(msgid, **{:default => msgid, :separator => '|'}.merge(options)) + end + alias _ gettext + + def sgettext(msgid, separator = '|') + scope, msgid = I18n::Gettext.extract_scope(msgid, separator) + I18n.t(msgid, :scope => scope, :default => msgid, :separator => separator) + end + alias s_ sgettext + + def pgettext(msgctxt, msgid) + separator = I18n::Gettext::CONTEXT_SEPARATOR + sgettext([msgctxt, msgid].join(separator), separator) + end + alias p_ pgettext + + def ngettext(msgid, msgid_plural, n = 1) + nsgettext(msgid, msgid_plural, n) + end + alias n_ ngettext + + # Method signatures: + # nsgettext('Fruits|apple', 'apples', 2) + # nsgettext(['Fruits|apple', 'apples'], 2) + def nsgettext(msgid, msgid_plural, n = 1, separator = '|') + if msgid.is_a?(Array) + msgid, msgid_plural, n, separator = msgid[0], msgid[1], msgid_plural, n + separator = '|' unless separator.is_a?(::String) + end + + scope, msgid = I18n::Gettext.extract_scope(msgid, separator) + default = { :one => msgid, :other => msgid_plural } + I18n.t(msgid, :default => default, :count => n, :scope => scope, :separator => separator) + end + alias ns_ nsgettext + + # Method signatures: + # npgettext('Fruits', 'apple', 'apples', 2) + # npgettext('Fruits', ['apple', 'apples'], 2) + def npgettext(msgctxt, msgid, msgid_plural, n = 1) + separator = I18n::Gettext::CONTEXT_SEPARATOR + + if msgid.is_a?(Array) + msgid_plural, msgid, n = msgid[1], [msgctxt, msgid[0]].join(separator), msgid_plural + else + msgid = [msgctxt, msgid].join(separator) + end + + nsgettext(msgid, msgid_plural, n, separator) + end + alias np_ npgettext + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/po_parser.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/po_parser.rb new file mode 100644 index 0000000..a07fdc5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/gettext/po_parser.rb @@ -0,0 +1,329 @@ +=begin + poparser.rb - Generate a .mo + + Copyright (C) 2003-2009 Masao Mutoh + + You may redistribute it and/or modify it under the same + license terms as Ruby. +=end + +#MODIFIED +# removed include GetText etc +# added stub translation method _(x) +require 'racc/parser' + +module GetText + + class PoParser < Racc::Parser + + def _(x) + x + end + +module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 108 + def unescape(orig) + ret = orig.gsub(/\\n/, "\n") + ret.gsub!(/\\t/, "\t") + ret.gsub!(/\\r/, "\r") + ret.gsub!(/\\"/, "\"") + ret + end + + def parse(str, data, ignore_fuzzy = true) + @comments = [] + @data = data + @fuzzy = false + @msgctxt = "" + $ignore_fuzzy = ignore_fuzzy + + str.strip! + @q = [] + until str.empty? do + case str + when /\A\s+/ + str = $' + when /\Amsgctxt/ + @q.push [:MSGCTXT, $&] + str = $' + when /\Amsgid_plural/ + @q.push [:MSGID_PLURAL, $&] + str = $' + when /\Amsgid/ + @q.push [:MSGID, $&] + str = $' + when /\Amsgstr/ + @q.push [:MSGSTR, $&] + str = $' + when /\A\[(\d+)\]/ + @q.push [:PLURAL_NUM, $1] + str = $' + when /\A\#~(.*)/ + $stderr.print _("Warning: obsolete msgid exists.\n") + $stderr.print " #{$&}\n" + @q.push [:COMMENT, $&] + str = $' + when /\A\#(.*)/ + @q.push [:COMMENT, $&] + str = $' + when /\A\"(.*)\"/ + @q.push [:STRING, $1] + str = $' + else + #c = str[0,1] + #@q.push [:STRING, c] + str = str[1..-1] + end + end + @q.push [false, '$end'] + if $DEBUG + @q.each do |a,b| + puts "[#{a}, #{b}]" + end + end + @yydebug = true if $DEBUG + do_parse + + if @comments.size > 0 + @data.set_comment(:last, @comments.join("\n")) + end + @data + end + + def next_token + @q.shift + end + + def on_message(msgid, msgstr) + if msgstr.size > 0 + @data[msgid] = msgstr + @data.set_comment(msgid, @comments.join("\n")) + end + @comments.clear + @msgctxt = "" + end + + def on_comment(comment) + @fuzzy = true if (/fuzzy/ =~ comment) + @comments << comment + end + + +..end src/poparser.ry modeval..id7a99570e05 + +##### racc 1.4.5 generates ### + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 12, :_reduce_5, + 1, 13, :_reduce_none, + 1, 13, :_reduce_none, + 4, 15, :_reduce_8, + 5, 16, :_reduce_9, + 2, 17, :_reduce_10, + 1, 17, :_reduce_none, + 3, 18, :_reduce_12, + 1, 11, :_reduce_13, + 2, 14, :_reduce_14, + 1, 14, :_reduce_15 ] + +racc_reduce_n = 16 + +racc_shift_n = 26 + +racc_action_table = [ + 3, 13, 5, 7, 9, 15, 16, 17, 20, 17, + 13, 17, 13, 13, 11, 17, 23, 20, 13, 17 ] + +racc_action_check = [ + 1, 16, 1, 1, 1, 12, 12, 12, 18, 18, + 7, 14, 15, 9, 3, 19, 20, 21, 23, 25 ] + +racc_action_pointer = [ + nil, 0, nil, 14, nil, nil, nil, 3, nil, 6, + nil, nil, 0, nil, 4, 5, -6, nil, 2, 8, + 8, 11, nil, 11, nil, 12 ] + +racc_action_default = [ + -1, -16, -2, -16, -3, -13, -4, -16, -6, -16, + -7, 26, -16, -15, -5, -16, -16, -14, -16, -8, + -16, -9, -11, -16, -10, -12 ] + +racc_goto_table = [ + 12, 22, 14, 4, 24, 6, 2, 8, 18, 19, + 10, 21, 1, nil, nil, nil, 25 ] + +racc_goto_check = [ + 5, 9, 5, 3, 9, 4, 2, 6, 5, 5, + 7, 8, 1, nil, nil, nil, 5 ] + +racc_goto_pointer = [ + nil, 12, 5, 2, 4, -7, 6, 9, -7, -17 ] + +racc_goto_default = [ + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ] + +racc_token_table = { + false => 0, + Object.new => 1, + :COMMENT => 2, + :MSGID => 3, + :MSGCTXT => 4, + :MSGID_PLURAL => 5, + :MSGSTR => 6, + :STRING => 7, + :PLURAL_NUM => 8 } + +racc_use_result_var = true + +racc_nt_base = 9 + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] + +Racc_token_to_s_table = [ +'$end', +'error', +'COMMENT', +'MSGID', +'MSGCTXT', +'MSGID_PLURAL', +'MSGSTR', +'STRING', +'PLURAL_NUM', +'$start', +'msgfmt', +'comment', +'msgctxt', +'message', +'string_list', +'single_message', +'plural_message', +'msgstr_plural', +'msgstr_plural_line'] + +Racc_debug_parser = true + +##### racc system variables end ##### + + # reduce 0 omitted + + # reduce 1 omitted + + # reduce 2 omitted + + # reduce 3 omitted + + # reduce 4 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 25 + def _reduce_5( val, _values, result ) + @msgctxt = unescape(val[1]) + "\004" + result + end +.,., + + # reduce 6 omitted + + # reduce 7 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 48 + def _reduce_8( val, _values, result ) + if @fuzzy and $ignore_fuzzy + if val[1] != "" + $stderr.print _("Warning: fuzzy message was ignored.\n") + $stderr.print " msgid '#{val[1]}'\n" + else + on_message('', unescape(val[3])) + end + @fuzzy = false + else + on_message(@msgctxt + unescape(val[1]), unescape(val[3])) + end + result = "" + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 65 + def _reduce_9( val, _values, result ) + if @fuzzy and $ignore_fuzzy + if val[1] != "" + $stderr.print _("Warning: fuzzy message was ignored.\n") + $stderr.print "msgid = '#{val[1]}\n" + else + on_message('', unescape(val[3])) + end + @fuzzy = false + else + on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4])) + end + result = "" + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 76 + def _reduce_10( val, _values, result ) + if val[0].size > 0 + result = val[0] + "\000" + val[1] + else + result = "" + end + result + end +.,., + + # reduce 11 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 84 + def _reduce_12( val, _values, result ) + result = val[2] + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 91 + def _reduce_13( val, _values, result ) + on_comment(val[0]) + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 99 + def _reduce_14( val, _values, result ) + result = val.delete_if{|item| item == ""}.join + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 103 + def _reduce_15( val, _values, result ) + result = val[0] + result + end +.,., + + def _reduce_none( val, _values, result ) + result + end + + end # class PoParser + +end # module GetText diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/interpolate/ruby.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/interpolate/ruby.rb new file mode 100644 index 0000000..5b50593 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/interpolate/ruby.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# heavily based on Masao Mutoh's gettext String interpolation extension +# http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb + +module I18n + DEFAULT_INTERPOLATION_PATTERNS = [ + /%%/, + /%\{([\w|]+)\}/, # matches placeholders like "%{foo} or %{foo|word}" + /%<(\w+)>([^\d]*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%.d" + ].freeze + INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS) + deprecate_constant :INTERPOLATION_PATTERN + + INTERPOLATION_PATTERNS_CACHE = Hash.new do |hash, patterns| + hash[patterns] = Regexp.union(patterns) + end + private_constant :INTERPOLATION_PATTERNS_CACHE + + class << self + # Return String or raises MissingInterpolationArgument exception. + # Missing argument's logic is handled by I18n.config.missing_interpolation_argument_handler. + def interpolate(string, values) + raise ReservedInterpolationKey.new($1.to_sym, string) if string =~ I18n.reserved_keys_pattern + raise ArgumentError.new('Interpolation values must be a Hash.') unless values.kind_of?(Hash) + interpolate_hash(string, values) + end + + def interpolate_hash(string, values) + pattern = INTERPOLATION_PATTERNS_CACHE[config.interpolation_patterns] + interpolated = false + + interpolated_string = string.gsub(pattern) do |match| + interpolated = true + + if match == '%%' + '%' + else + key = ($1 || $2 || match.tr("%{}", "")).to_sym + value = if values.key?(key) + values[key] + else + config.missing_interpolation_argument_handler.call(key, values, string) + end + value = value.call(values) if value.respond_to?(:call) + $3 ? sprintf("%#{$3}", value) : value + end + end + + interpolated ? interpolated_string : string + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale.rb new file mode 100644 index 0000000..c4078e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module I18n + module Locale + autoload :Fallbacks, 'i18n/locale/fallbacks' + autoload :Tag, 'i18n/locale/tag' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/fallbacks.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/fallbacks.rb new file mode 100644 index 0000000..56d08d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/fallbacks.rb @@ -0,0 +1,107 @@ +# Locale Fallbacks +# +# Extends the I18n module to hold a fallbacks instance which is set to an +# instance of I18n::Locale::Fallbacks by default but can be swapped with a +# different implementation. +# +# Locale fallbacks will compute a number of fallback locales for a given locale. +# For example: +# +#

+# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] 
+# +# Locale fallbacks always fall back to +# +# * all parent locales of a given locale (e.g. :es for :"es-MX") first, +# * the current default locales and all of their parents second +# +# The default locales are set to [] by default but can be set to something else. +# +# One can additionally add any number of additional fallback locales manually. +# These will be added before the default locales to the fallback chain. For +# example: +# +# # using a custom locale as default fallback locale +# +# I18n.fallbacks = I18n::Locale::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de) +# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en] +# I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en] +# +# # mapping fallbacks to an existing instance +# +# # people speaking Catalan also speak Spanish as spoken in Spain +# fallbacks = I18n.fallbacks +# fallbacks.map(:ca => :"es-ES") +# fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en] +# +# # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel +# fallbacks.map(:"ar-PS" => :"he-IL") +# fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en] +# fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en] +# +# # people speaking Sami as spoken in Finland also speak Swedish and Finnish as spoken in Finland +# fallbacks.map(:sms => [:"se-FI", :"fi-FI"]) +# fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en] + +module I18n + module Locale + class Fallbacks < Hash + def initialize(*mappings) + @map = {} + map(mappings.pop) if mappings.last.is_a?(Hash) + self.defaults = mappings.empty? ? [] : mappings + end + + def defaults=(defaults) + @defaults = defaults.flat_map { |default| compute(default, false) } + end + attr_reader :defaults + + def [](locale) + raise InvalidLocale.new(locale) if locale.nil? + raise Disabled.new('fallback#[]') if locale == false + locale = locale.to_sym + super || store(locale, compute(locale)) + end + + def map(*args, &block) + if args.count == 1 && !block_given? + mappings = args.first + mappings.each do |from, to| + from, to = from.to_sym, Array(to) + to.each do |_to| + @map[from] ||= [] + @map[from] << _to.to_sym + end + end + else + @map.map(*args, &block) + end + end + + def empty? + @map.empty? && @defaults.empty? + end + + def inspect + "#<#{self.class.name} @map=#{@map.inspect} @defaults=#{@defaults.inspect}>" + end + + protected + + def compute(tags, include_defaults = true, exclude = []) + result = [] + Array(tags).each do |tag| + tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } - exclude + result += tags + tags.each { |_tag| result += compute(@map[_tag], false, exclude + result) if @map[_tag] } + end + + result.push(*defaults) if include_defaults + result.uniq! + result.compact! + result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag.rb new file mode 100644 index 0000000..a640b44 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag.rb @@ -0,0 +1,28 @@ +# encoding: utf-8 + +module I18n + module Locale + module Tag + autoload :Parents, 'i18n/locale/tag/parents' + autoload :Rfc4646, 'i18n/locale/tag/rfc4646' + autoload :Simple, 'i18n/locale/tag/simple' + + class << self + # Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+. + def implementation + @@implementation ||= Simple + end + + # Sets the current locale tag implementation. Use this to set a different locale tag implementation. + def implementation=(implementation) + @@implementation = implementation + end + + # Factory method for locale tags. Delegates to the current locale tag implementation. + def tag(tag) + implementation.tag(tag) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/parents.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/parents.rb new file mode 100644 index 0000000..6283e66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/parents.rb @@ -0,0 +1,24 @@ +module I18n + module Locale + module Tag + module Parents + def parent + @parent ||= + begin + segs = to_a + segs.compact! + segs.length > 1 ? self.class.tag(*segs[0..(segs.length - 2)].join('-')) : nil + end + end + + def self_and_parents + @self_and_parents ||= [self].concat parents + end + + def parents + @parents ||= parent ? [parent].concat(parent.parents) : [] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/rfc4646.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/rfc4646.rb new file mode 100644 index 0000000..4ce4c75 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/rfc4646.rb @@ -0,0 +1,74 @@ +# RFC 4646/47 compliant Locale tag implementation that parses locale tags to +# subtags such as language, script, region, variant etc. +# +# For more information see by http://en.wikipedia.org/wiki/IETF_language_tag +# +# Rfc4646::Parser does not implement grandfathered tags. + +module I18n + module Locale + module Tag + RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ] + RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase } + + class Rfc4646 < Struct.new(*RFC4646_SUBTAGS) + class << self + # Parses the given tag and returns a Tag instance if it is valid. + # Returns false if the given tag is not valid according to RFC 4646. + def tag(tag) + matches = parser.match(tag) + new(*matches) if matches + end + + def parser + @@parser ||= Rfc4646::Parser + end + + def parser=(parser) + @@parser = parser + end + end + + include Parents + + RFC4646_FORMATS.each do |name, format| + define_method(name) { self[name].send(format) unless self[name].nil? } + end + + def to_sym + to_s.to_sym + end + + def to_s + @tag ||= to_a.compact.join("-") + end + + def to_a + members.collect { |attr| self.send(attr) } + end + + module Parser + PATTERN = %r{\A(?: + ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language + (?:-([a-z]{4}))? # script + (?:-([a-z]{2}|\d{3}))? # region + (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant + (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension + (?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag + (x(?:-[0-9a-z]{1,8})+)| # privateuse tag + /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered + )\z}xi + + class << self + def match(tag) + c = PATTERN.match(tag.to_s).captures + c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here? + rescue + false + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/simple.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/simple.rb new file mode 100644 index 0000000..18d55c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/locale/tag/simple.rb @@ -0,0 +1,39 @@ +# Simple Locale tag implementation that computes subtags by simply splitting +# the locale tag at '-' occurrences. +module I18n + module Locale + module Tag + class Simple + class << self + def tag(tag) + new(tag) + end + end + + include Parents + + attr_reader :tag + + def initialize(*tag) + @tag = tag.join('-').to_sym + end + + def subtags + @subtags = tag.to_s.split('-').map!(&:to_s) + end + + def to_sym + tag + end + + def to_s + tag.to_s + end + + def to_a + subtags + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/middleware.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/middleware.rb new file mode 100644 index 0000000..8999834 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/middleware.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module I18n + class Middleware + + def initialize(app) + @app = app + end + + def call(env) + @app.call(env) + ensure + if Fiber.respond_to?(:[]) + Fiber[:i18n_config] = I18n::Config.new + else + Thread.current.thread_variable_set(:i18n_config, I18n::Config.new) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests.rb new file mode 100644 index 0000000..30d0ed5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module I18n + module Tests + autoload :Basics, 'i18n/tests/basics' + autoload :Defaults, 'i18n/tests/defaults' + autoload :Interpolation, 'i18n/tests/interpolation' + autoload :Link, 'i18n/tests/link' + autoload :Localization, 'i18n/tests/localization' + autoload :Lookup, 'i18n/tests/lookup' + autoload :Pluralization, 'i18n/tests/pluralization' + autoload :Procs, 'i18n/tests/procs' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/basics.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/basics.rb new file mode 100644 index 0000000..833762b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/basics.rb @@ -0,0 +1,58 @@ +module I18n + module Tests + module Basics + def teardown + I18n.available_locales = nil + end + + test "available_locales returns the available_locales produced by the backend, by default" do + I18n.backend.store_translations('de', :foo => 'bar') + I18n.backend.store_translations('en', :foo => 'foo') + + assert_equal I18n.available_locales, I18n.backend.available_locales + end + + test "available_locales can be set to something else independently from the actual locale data" do + I18n.backend.store_translations('de', :foo => 'bar') + I18n.backend.store_translations('en', :foo => 'foo') + + I18n.available_locales = :foo + assert_equal [:foo], I18n.available_locales + + I18n.available_locales = [:foo, 'bar'] + assert_equal [:foo, :bar], I18n.available_locales + + I18n.available_locales = nil + assert_equal I18n.available_locales, I18n.backend.available_locales + end + + test "available_locales memoizes when set explicitly" do + I18n.backend.expects(:available_locales).never + I18n.available_locales = [:foo] + I18n.backend.store_translations('de', :bar => 'baz') + I18n.reload! + assert_equal [:foo], I18n.available_locales + end + + test "available_locales delegates to the backend when not set explicitly" do + original_available_locales_value = I18n.backend.available_locales + I18n.backend.expects(:available_locales).returns(original_available_locales_value).twice + assert_equal I18n.backend.available_locales, I18n.available_locales + end + + test "exists? is implemented by the backend" do + I18n.backend.store_translations(:foo, :bar => 'baz') + assert I18n.exists?(:bar, :foo) + end + + test "storing a nil value as a translation removes it from the available locale data" do + I18n.backend.store_translations(:en, :to_be_deleted => 'bar') + assert_equal 'bar', I18n.t(:to_be_deleted, :default => 'baz') + + I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store + I18n.backend.store_translations(:en, :to_be_deleted => nil) + assert_equal 'baz', I18n.t(:to_be_deleted, :default => 'baz') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/defaults.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/defaults.rb new file mode 100644 index 0000000..e5db336 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/defaults.rb @@ -0,0 +1,59 @@ +# encoding: utf-8 + +module I18n + module Tests + module Defaults + def setup + super + I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }) + end + + test "defaults: given nil as a key it returns the given default" do + assert_equal 'default', I18n.t(nil, :default => 'default') + end + + test "defaults: given a symbol as a default it translates the symbol" do + assert_equal 'bar', I18n.t(nil, :default => :'foo.bar') + end + + test "defaults: given a symbol as a default and a scope it stays inside the scope when looking up the symbol" do + assert_equal 'bar', I18n.t(:missing, :default => :bar, :scope => :foo) + end + + test "defaults: given an array as a default it returns the first match" do + assert_equal 'bar', I18n.t(:does_not_exist, :default => [:does_not_exist_2, :'foo.bar']) + end + + test "defaults: given an array as a default with false it returns false" do + assert_equal false, I18n.t(:does_not_exist, :default => [false]) + end + + test "defaults: given false it returns false" do + assert_equal false, I18n.t(:does_not_exist, :default => false) + end + + test "defaults: given nil it returns nil" do + assert_nil I18n.t(:does_not_exist, :default => nil) + end + + test "defaults: given an array of missing keys it raises a MissingTranslationData exception" do + assert_raises I18n::MissingTranslationData do + I18n.t(:does_not_exist, :default => [:does_not_exist_2, :does_not_exist_3], :raise => true) + end + end + + test "defaults: using a custom scope separator" do + # data must have been stored using the custom separator when using the ActiveRecord backend + I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' }) + assert_equal 'bar', I18n.t(nil, :default => :'foo|bar', :separator => '|') + end + + # Addresses issue: #599 + test "defaults: only interpolates once when resolving defaults" do + I18n.backend.store_translations(:en, :greeting => 'hey %{name}') + assert_equal 'hey %{dont_interpolate_me}', + I18n.t(:does_not_exist, :name => '%{dont_interpolate_me}', default: [:greeting]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/interpolation.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/interpolation.rb new file mode 100644 index 0000000..991c4ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/interpolation.rb @@ -0,0 +1,185 @@ +# encoding: utf-8 + +module I18n + module Tests + module Interpolation + # If no interpolation parameter is not given, I18n should not alter the string. + # This behavior is due to three reasons: + # + # * Checking interpolation keys in all strings hits performance, badly; + # + # * This allows us to retrieve untouched values through I18n. For example + # I could have a middleware that returns I18n lookup results in JSON + # to be processed through Javascript. Leaving the keys untouched allows + # the interpolation to happen at the javascript level; + # + # * Security concerns: if I allow users to translate a web site, they can + # insert %{} in messages causing the I18n lookup to fail in every request. + # + test "interpolation: given no values it does not alter the string" do + assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!') + end + + test "interpolation: given values it interpolates them into the string" do + assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David') + end + + test "interpolation: works with a pipe" do + assert_equal 'Hi david!', interpolate(:default => 'Hi %{name|lowercase}!', :'name|lowercase' => 'david') + end + + test "interpolation: given a nil value it still interpolates it into the string" do + assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil) + end + + test "interpolation: given a lambda as a value it calls it if the string contains the key" do + assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => lambda { |*args| 'David' }) + end + + test "interpolation: given a lambda as a value it does not call it if the string does not contain the key" do + assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) } + end + + test "interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do + assert_raises(I18n::MissingInterpolationArgument) do + interpolate(:default => '%{foo}', :bar => 'bar') + end + end + + test "interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do + assert_nothing_raised do + assert_equal 'Barr %{foo}', interpolate(:default => '%{bar} %%{foo}', :bar => 'Barr') + end + end + + test "interpolation: it does not change the original, stored translation string" do + I18n.backend.store_translations(:en, :interpolate => 'Hi %{name}!') + assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David') + assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda') + end + + test "interpolation: given an array interpolates each element" do + I18n.backend.store_translations(:en, :array_interpolate => ['Hi', 'Mr. %{name}', 'or sir %{name}']) + assert_equal ['Hi', 'Mr. Bartuz', 'or sir Bartuz'], interpolate(:array_interpolate, :name => 'Bartuz') + end + + test "interpolation: given the translation is in utf-8 it still works" do + assert_equal 'Häi David!', interpolate(:default => 'Häi %{name}!', :name => 'David') + end + + test "interpolation: given the value is in utf-8 it still works" do + assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi %{name}!', :name => 'ゆきひろ') + end + + test "interpolation: given the translation and the value are in utf-8 it still works" do + assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、%{name}さん!', :name => 'ゆきひろ') + end + + if Object.const_defined?(:Encoding) + test "interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do + assert_raises(Encoding::CompatibilityError) do + interpolate(:default => euc_jp('こんにちは、%{name}さん!'), :name => 'ゆきひろ') + end + end + + test "interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do + assert_raises(Encoding::CompatibilityError) do + interpolate(:default => 'こんにちは、%{name}さん!', :name => euc_jp('ゆきひろ')) + end + end + + test "interpolation: ASCII strings in the backend should be encoded to UTF8 if interpolation options are in UTF8" do + I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.dup.force_encoding(Encoding::US_ASCII)) + result = I18n.t 'encoding', :who => "måmmå miå" + assert_equal Encoding::UTF_8, result.encoding + end + + test "interpolation: UTF8 strings in the backend are still returned as UTF8 with ASCII interpolation" do + I18n.backend.store_translations 'en', 'encoding' => 'måmmå miå %{what}' + result = I18n.t 'encoding', :what => 'let me go'.dup.force_encoding(Encoding::US_ASCII) + assert_equal Encoding::UTF_8, result.encoding + end + + test "interpolation: UTF8 strings in the backend are still returned as UTF8 even with numbers interpolation" do + I18n.backend.store_translations 'en', 'encoding' => '%{count} times: måmmå miå' + result = I18n.t 'encoding', :count => 3 + assert_equal Encoding::UTF_8, result.encoding + end + end + + test "interpolation: given a translations containing a reserved key it raises I18n::ReservedInterpolationKey" do + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{exception_handler}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{default}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{separator}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{scope}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '%{scope}') } + + I18n.backend.store_translations(:en, :interpolate => 'Hi %{scope}!') + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:interpolate) } + end + + test "interpolation: it does not raise I18n::ReservedInterpolationKey for escaped variables" do + assert_nothing_raised do + assert_equal '%{separator}', interpolate(:foo => :bar, :default => '%%{separator}') + end + + # Note: The two interpolations below do not remove the escape character (%) because + # I18n should not alter the strings when no interpolation parameters are given, + # see the comment at the top of this file. + assert_nothing_raised do + assert_equal '%%{scope}', interpolate(:default => '%%{scope}') + end + + I18n.backend.store_translations(:en, :interpolate => 'Hi %%{scope}!') + assert_nothing_raised do + assert_equal 'Hi %%{scope}!', interpolate(:interpolate) + end + end + + test "interpolation: deep interpolation for default string" do + assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!', :deep_interpolation => true) + end + + test "interpolation: deep interpolation for interpolated string" do + assert_equal 'Hi Ann!', interpolate(:default => 'Hi %{name}!', :name => 'Ann', :deep_interpolation => true) + end + + test "interpolation: deep interpolation for Hash" do + people = { :people => { :ann => 'Ann is %{ann}', :john => 'John is %{john}' } } + interpolated_people = { :people => { :ann => 'Ann is good', :john => 'John is big' } } + assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true) + end + + test "interpolation: deep interpolation for Array" do + people = { :people => ['Ann is %{ann}', 'John is %{john}'] } + interpolated_people = { :people => ['Ann is good', 'John is big'] } + assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true) + end + + protected + + def capture(stream) + begin + stream = stream.to_s + eval "$#{stream} = StringIO.new" + yield + result = eval("$#{stream}").string + ensure + eval("$#{stream} = #{stream.upcase}") + end + + result + end + + def euc_jp(string) + string.encode(Encoding::EUC_JP) + end + + def interpolate(*args) + options = args.last.is_a?(Hash) ? args.pop : {} + key = args.pop + I18n.backend.translate('en', key, options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/link.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/link.rb new file mode 100644 index 0000000..d2f20e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/link.rb @@ -0,0 +1,66 @@ +# encoding: utf-8 + +module I18n + module Tests + module Link + test "linked lookup: if a key resolves to a symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :link => :linked, + :linked => 'linked' + } + assert_equal 'linked', I18n.backend.translate('en', :link) + end + + test "linked lookup: if a key resolves to a dot-separated symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :link => :"foo.linked", + :foo => { :linked => 'linked' } + } + assert_equal('linked', I18n.backend.translate('en', :link)) + end + + test "linked lookup: if a dot-separated key resolves to a symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :foo => { :link => :linked }, + :linked => 'linked' + } + assert_equal('linked', I18n.backend.translate('en', :'foo.link')) + end + + test "linked lookup: if a dot-separated key resolves to a dot-separated symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :foo => { :link => :"bar.linked" }, + :bar => { :linked => 'linked' } + } + assert_equal('linked', I18n.backend.translate('en', :'foo.link')) + end + + test "linked lookup: links always refer to the absolute key" do + I18n.backend.store_translations 'en', { + :foo => { :link => :linked, :linked => 'linked in foo' }, + :linked => 'linked absolutely' + } + assert_equal 'linked absolutely', I18n.backend.translate('en', :link, :scope => :foo) + end + + test "linked lookup: a link can resolve to a namespace in the middle of a dot-separated key" do + I18n.backend.store_translations 'en', { + :activemodel => { :errors => { :messages => { :blank => "can't be blank" } } }, + :activerecord => { :errors => { :messages => :"activemodel.errors.messages" } } + } + assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank") + assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank") + end + + test "linked lookup: a link can resolve with option :count" do + I18n.backend.store_translations 'en', { + :counter => :counted, + :counted => { :foo => { :one => "one", :other => "other" }, :bar => "bar" } + } + assert_equal "one", I18n.t(:'counter.foo', count: 1) + assert_equal "other", I18n.t(:'counter.foo', count: 2) + assert_equal "bar", I18n.t(:'counter.bar', count: 3) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization.rb new file mode 100644 index 0000000..53b1502 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization.rb @@ -0,0 +1,19 @@ +module I18n + module Tests + module Localization + autoload :Date, 'i18n/tests/localization/date' + autoload :DateTime, 'i18n/tests/localization/date_time' + autoload :Time, 'i18n/tests/localization/time' + autoload :Procs, 'i18n/tests/localization/procs' + + def self.included(base) + base.class_eval do + include I18n::Tests::Localization::Date + include I18n::Tests::Localization::DateTime + include I18n::Tests::Localization::Procs + include I18n::Tests::Localization::Time + end + end + end + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date.rb new file mode 100644 index 0000000..c21fbbf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date.rb @@ -0,0 +1,122 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module Date + def setup + super + setup_date_translations + @date = ::Date.new(2008, 3, 1) + end + + test "localize Date: given the short format it uses it" do + assert_equal '01. Mär', I18n.l(@date, :format => :short, :locale => :de) + end + + test "localize Date: given the long format it uses it" do + assert_equal '01. März 2008', I18n.l(@date, :format => :long, :locale => :de) + end + + test "localize Date: given the default format it uses it" do + assert_equal '01.03.2008', I18n.l(@date, :format => :default, :locale => :de) + end + + test "localize Date: given a day name format it returns the correct day name" do + assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de) + end + + test "localize Date: given a uppercased day name format it returns the correct day name in upcase" do + assert_equal 'samstag'.upcase, I18n.l(@date, :format => '%^A', :locale => :de) + end + + test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do + assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de) + end + + test "localize Date: given an meridian indicator format it returns the correct meridian indicator" do + assert_equal 'AM', I18n.l(@date, :format => '%p', :locale => :de) + assert_equal 'am', I18n.l(@date, :format => '%P', :locale => :de) + end + + test "localize Date: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do + assert_equal 'sa'.upcase, I18n.l(@date, :format => '%^a', :locale => :de) + end + + test "localize Date: given a month name format it returns the correct month name" do + assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de) + end + + test "localize Date: given a uppercased month name format it returns the correct month name in upcase" do + assert_equal 'märz'.upcase, I18n.l(@date, :format => '%^B', :locale => :de) + end + + test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do + assert_equal 'Mär', I18n.l(@date, :format => '%b', :locale => :de) + end + + test "localize Date: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do + assert_equal 'mär'.upcase, I18n.l(@date, :format => '%^b', :locale => :de) + end + + test "localize Date: given a date format with the month name upcased it returns the correct value" do + assert_equal '1. FEBRUAR 2008', I18n.l(::Date.new(2008, 2, 1), :format => "%-d. %^B %Y", :locale => :de) + end + + test "localize Date: given missing translations it returns the correct error message" do + assert_equal 'Translation missing: fr.date.abbr_month_names', I18n.l(@date, :format => '%b', :locale => :fr) + end + + test "localize Date: given an unknown format it does not fail" do + assert_nothing_raised { I18n.l(@date, :format => '%x') } + end + + test "localize Date: does not modify the options hash" do + options = { :format => '%b', :locale => :de } + assert_equal 'Mär', I18n.l(@date, **options) + assert_equal({ :format => '%b', :locale => :de }, options) + assert_nothing_raised { I18n.l(@date, **options.freeze) } + end + + test "localize Date: given nil with default value it returns default" do + assert_equal 'default', I18n.l(nil, :default => 'default') + end + + test "localize Date: given nil it raises I18n::ArgumentError" do + assert_raises(I18n::ArgumentError) { I18n.l(nil) } + end + + test "localize Date: given a plain Object it raises I18n::ArgumentError" do + assert_raises(I18n::ArgumentError) { I18n.l(Object.new) } + end + + test "localize Date: given a format is missing it raises I18n::MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.l(@date, :format => :missing) } + end + + test "localize Date: it does not alter the format string" do + assert_equal '01. Februar 2009', I18n.l(::Date.parse('2009-02-01'), :format => :long, :locale => :de) + assert_equal '01. Oktober 2009', I18n.l(::Date.parse('2009-10-01'), :format => :long, :locale => :de) + end + + protected + + def setup_date_translations + I18n.backend.store_translations :de, { + :date => { + :formats => { + :default => "%d.%m.%Y", + :short => "%d. %b", + :long => "%d. %B %Y", + }, + :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag), + :abbr_day_names => %w(So Mo Di Mi Do Fr Sa), + :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil), + :abbr_month_names => %w(Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil) + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date_time.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date_time.rb new file mode 100644 index 0000000..b5d3527 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/date_time.rb @@ -0,0 +1,103 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module DateTime + def setup + super + setup_datetime_translations + @datetime = ::DateTime.new(2008, 3, 1, 6) + @other_datetime = ::DateTime.new(2008, 3, 1, 18) + end + + test "localize DateTime: given the short format it uses it" do + assert_equal '01. Mär 06:00', I18n.l(@datetime, :format => :short, :locale => :de) + end + + test "localize DateTime: given the long format it uses it" do + assert_equal '01. März 2008 06:00', I18n.l(@datetime, :format => :long, :locale => :de) + end + + test "localize DateTime: given the default format it uses it" do + assert_equal 'Sa, 01. Mär 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de) + end + + test "localize DateTime: given a day name format it returns the correct day name" do + assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de) + end + + test "localize DateTime: given a uppercased day name format it returns the correct day name in upcase" do + assert_equal 'samstag'.upcase, I18n.l(@datetime, :format => '%^A', :locale => :de) + end + + test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do + assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de) + end + + test "localize DateTime: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do + assert_equal 'sa'.upcase, I18n.l(@datetime, :format => '%^a', :locale => :de) + end + + test "localize DateTime: given a month name format it returns the correct month name" do + assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de) + end + + test "localize DateTime: given a uppercased month name format it returns the correct month name in upcase" do + assert_equal 'märz'.upcase, I18n.l(@datetime, :format => '%^B', :locale => :de) + end + + test "localize DateTime: given an abbreviated month name format it returns the correct abbreviated month name" do + assert_equal 'Mär', I18n.l(@datetime, :format => '%b', :locale => :de) + end + + test "localize DateTime: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do + assert_equal 'mär'.upcase, I18n.l(@datetime, :format => '%^b', :locale => :de) + end + + test "localize DateTime: given a date format with the month name upcased it returns the correct value" do + assert_equal '1. FEBRUAR 2008', I18n.l(::DateTime.new(2008, 2, 1, 6), :format => "%-d. %^B %Y", :locale => :de) + end + + test "localize DateTime: given missing translations it returns the correct error message" do + assert_equal 'Translation missing: fr.date.abbr_month_names', I18n.l(@datetime, :format => '%b', :locale => :fr) + end + + test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do + assert_equal 'AM', I18n.l(@datetime, :format => '%p', :locale => :de) + assert_equal 'PM', I18n.l(@other_datetime, :format => '%p', :locale => :de) + end + + test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator in downcase" do + assert_equal 'am', I18n.l(@datetime, :format => '%P', :locale => :de) + assert_equal 'pm', I18n.l(@other_datetime, :format => '%P', :locale => :de) + end + + test "localize DateTime: given an unknown format it does not fail" do + assert_nothing_raised { I18n.l(@datetime, :format => '%x') } + end + + test "localize DateTime: given a format is missing it raises I18n::MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.l(@datetime, :format => :missing) } + end + + protected + + def setup_datetime_translations + # time translations might have been set up in Tests::Api::Localization::Time + I18n.backend.store_translations :de, { + :time => { + :formats => { + :default => "%a, %d. %b %Y %H:%M:%S %z", + :short => "%d. %b %H:%M", + :long => "%d. %B %Y %H:%M" + }, + :am => 'am', + :pm => 'pm' + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/procs.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/procs.rb new file mode 100644 index 0000000..2c5d8e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/procs.rb @@ -0,0 +1,118 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module Procs + test "localize: using day names from lambdas" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_match(/Суббота/, I18n.l(time, :format => "%A, %d %B", :locale => :ru)) + assert_match(/суббота/, I18n.l(time, :format => "%d %B (%A)", :locale => :ru)) + end + + test "localize: using month names from lambdas" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_match(/марта/, I18n.l(time, :format => "%d %B %Y", :locale => :ru)) + assert_match(/Март /, I18n.l(time, :format => "%B %Y", :locale => :ru)) + end + + test "localize: using abbreviated day names from lambdas" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_match(/марта/, I18n.l(time, :format => "%d %b %Y", :locale => :ru)) + assert_match(/март /, I18n.l(time, :format => "%b %Y", :locale => :ru)) + end + + test "localize Date: given a format that resolves to a Proc it calls the Proc with the object" do + setup_time_proc_translations + date = ::Date.new(2008, 3, 1) + assert_equal '[Sat, 01 Mar 2008, {}]', I18n.l(date, :format => :proc, :locale => :ru) + end + + test "localize Date: given a format that resolves to a Proc it calls the Proc with the object and extra options" do + setup_time_proc_translations + date = ::Date.new(2008, 3, 1) + assert_equal %|[Sat, 01 Mar 2008, #{{:foo=>"foo"}}]|, I18n.l(date, :format => :proc, :foo => 'foo', :locale => :ru) + end + + test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object" do + setup_time_proc_translations + datetime = ::DateTime.new(2008, 3, 1, 6) + assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {}]', I18n.l(datetime, :format => :proc, :locale => :ru) + end + + test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object and extra options" do + setup_time_proc_translations + datetime = ::DateTime.new(2008, 3, 1, 6) + assert_equal %|[Sat, 01 Mar 2008 06:00:00 +00:00, #{{:foo=>"foo"}}]|, I18n.l(datetime, :format => :proc, :foo => 'foo', :locale => :ru) + end + + test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_equal I18n::Tests::Localization::Procs.inspect_args([time], {}), I18n.l(time, :format => :proc, :locale => :ru) + end + + test "localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + options = { :foo => 'foo' } + assert_equal I18n::Tests::Localization::Procs.inspect_args([time], options), I18n.l(time, **options.merge(:format => :proc, :locale => :ru)) + end + + protected + + def self.inspect_args(args, kwargs) + args << kwargs + args = args.map do |arg| + case arg + when ::Time, ::DateTime + arg.strftime('%a, %d %b %Y %H:%M:%S %Z').sub('+0000', '+00:00') + when ::Date + arg.strftime('%a, %d %b %Y') + when Hash + arg.delete(:fallback_in_progress) + arg.delete(:fallback_original_locale) + arg.inspect + else + arg.inspect + end + end + "[#{args.join(', ')}]" + end + + def setup_time_proc_translations + I18n.backend.store_translations :ru, { + :time => { + :formats => { + :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) } + } + }, + :date => { + :formats => { + :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) } + }, + :'day_names' => lambda { |key, options| + (options[:format] =~ /^%A/) ? + %w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) : + %w(воскресенье понедельник вторник среда четверг пятница суббота) + }, + :'month_names' => lambda { |key, options| + (options[:format] =~ /(%d|%e)(\s*)?(%B)/) ? + %w(января февраля марта апреля мая июня июля августа сентября октября ноября декабря).unshift(nil) : + %w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil) + }, + :'abbr_month_names' => lambda { |key, options| + (options[:format] =~ /(%d|%e)(\s*)(%b)/) ? + %w(янв. февр. марта апр. мая июня июля авг. сент. окт. нояб. дек.).unshift(nil) : + %w(янв. февр. март апр. май июнь июль авг. сент. окт. нояб. дек.).unshift(nil) + }, + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/time.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/time.rb new file mode 100644 index 0000000..456a760 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/localization/time.rb @@ -0,0 +1,103 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module Time + def setup + super + setup_time_translations + @time = ::Time.utc(2008, 3, 1, 6, 0) + @other_time = ::Time.utc(2008, 3, 1, 18, 0) + end + + test "localize Time: given the short format it uses it" do + assert_equal '01. Mär 06:00', I18n.l(@time, :format => :short, :locale => :de) + end + + test "localize Time: given the long format it uses it" do + assert_equal '01. März 2008 06:00', I18n.l(@time, :format => :long, :locale => :de) + end + + # TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this? + # def test_localize_given_the_default_format_it_uses_it + # assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@time, :format => :default, :locale => :de) + # end + + test "localize Time: given a day name format it returns the correct day name" do + assert_equal 'Samstag', I18n.l(@time, :format => '%A', :locale => :de) + end + + test "localize Time: given a uppercased day name format it returns the correct day name in upcase" do + assert_equal 'samstag'.upcase, I18n.l(@time, :format => '%^A', :locale => :de) + end + + test "localize Time: given an abbreviated day name format it returns the correct abbreviated day name" do + assert_equal 'Sa', I18n.l(@time, :format => '%a', :locale => :de) + end + + test "localize Time: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do + assert_equal 'sa'.upcase, I18n.l(@time, :format => '%^a', :locale => :de) + end + + test "localize Time: given a month name format it returns the correct month name" do + assert_equal 'März', I18n.l(@time, :format => '%B', :locale => :de) + end + + test "localize Time: given a uppercased month name format it returns the correct month name in upcase" do + assert_equal 'märz'.upcase, I18n.l(@time, :format => '%^B', :locale => :de) + end + + test "localize Time: given an abbreviated month name format it returns the correct abbreviated month name" do + assert_equal 'Mär', I18n.l(@time, :format => '%b', :locale => :de) + end + + test "localize Time: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do + assert_equal 'mär'.upcase, I18n.l(@time, :format => '%^b', :locale => :de) + end + + test "localize Time: given a date format with the month name upcased it returns the correct value" do + assert_equal '1. FEBRUAR 2008', I18n.l(::Time.utc(2008, 2, 1, 6, 0), :format => "%-d. %^B %Y", :locale => :de) + end + + test "localize Time: given missing translations it returns the correct error message" do + assert_equal 'Translation missing: fr.date.abbr_month_names', I18n.l(@time, :format => '%b', :locale => :fr) + end + + test "localize Time: given a meridian indicator format it returns the correct meridian indicator" do + assert_equal 'AM', I18n.l(@time, :format => '%p', :locale => :de) + assert_equal 'PM', I18n.l(@other_time, :format => '%p', :locale => :de) + end + + test "localize Time: given a meridian indicator format it returns the correct meridian indicator in upcase" do + assert_equal 'am', I18n.l(@time, :format => '%P', :locale => :de) + assert_equal 'pm', I18n.l(@other_time, :format => '%P', :locale => :de) + end + + test "localize Time: given an unknown format it does not fail" do + assert_nothing_raised { I18n.l(@time, :format => '%x') } + end + + test "localize Time: given a format is missing it raises I18n::MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.l(@time, :format => :missing) } + end + + protected + + def setup_time_translations + I18n.backend.store_translations :de, { + :time => { + :formats => { + :default => "%a, %d. %b %Y %H:%M:%S %z", + :short => "%d. %b %H:%M", + :long => "%d. %B %Y %H:%M", + }, + :am => 'am', + :pm => 'pm' + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/lookup.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/lookup.rb new file mode 100644 index 0000000..f1bee79 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/lookup.rb @@ -0,0 +1,87 @@ +# encoding: utf-8 + +module I18n + module Tests + module Lookup + def setup + super + I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }, :falsy => false, :truthy => true, + :string => "a", :array => %w(a b c), :hash => { "a" => "b" }) + end + + test "lookup: it returns a string" do + assert_equal("a", I18n.t(:string)) + end + + test "lookup: it returns hash" do + assert_equal({ :a => "b" }, I18n.t(:hash)) + end + + test "lookup: it returns an array" do + assert_equal(%w(a b c), I18n.t(:array)) + end + + test "lookup: it returns a native true" do + assert I18n.t(:truthy) === true + end + + test "lookup: it returns a native false" do + assert I18n.t(:falsy) === false + end + + test "lookup: given a missing key, no default and no raise option it returns an error message" do + assert_equal "Translation missing: en.missing", I18n.t(:missing) + end + + test "lookup: given a missing key, no default and the raise option it raises MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) } + end + + test "lookup: does not raise an exception if no translation data is present for the given locale" do + assert_nothing_raised { I18n.t(:foo, :locale => :xx) } + end + + test "lookup: does not modify the options hash" do + options = {} + assert_equal "a", I18n.t(:string, **options) + assert_equal({}, options) + assert_nothing_raised { I18n.t(:string, **options.freeze) } + end + + test "lookup: given an array of keys it translates all of them" do + assert_equal %w(bar baz), I18n.t([:bar, :baz], :scope => [:foo]) + end + + test "lookup: using a custom scope separator" do + # data must have been stored using the custom separator when using the ActiveRecord backend + I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' }) + assert_equal 'bar', I18n.t('foo|bar', :separator => '|') + end + + # In fact it probably *should* fail but Rails currently relies on using the default locale instead. + # So we'll stick to this for now until we get it fixed in Rails. + test "lookup: given nil as a locale it does not raise but use the default locale" do + # assert_raises(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) } + assert_nothing_raised { I18n.t(:bar, :locale => nil) } + end + + test "lookup: a resulting String is not frozen" do + assert !I18n.t(:string).frozen? + end + + test "lookup: a resulting Array is not frozen" do + assert !I18n.t(:array).frozen? + end + + test "lookup: a resulting Hash is not frozen" do + assert !I18n.t(:hash).frozen? + end + + # Addresses issue: #599 + test "lookup: only interpolates once when resolving symbols" do + I18n.backend.store_translations(:en, foo: :bar, bar: '%{value}') + assert_equal '%{dont_interpolate_me}', I18n.t(:foo, value: '%{dont_interpolate_me}') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/pluralization.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/pluralization.rb new file mode 100644 index 0000000..19e73f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/pluralization.rb @@ -0,0 +1,35 @@ +# encoding: utf-8 + +module I18n + module Tests + module Pluralization + test "pluralization: given 0 it returns the :zero translation if it is defined" do + assert_equal 'zero', I18n.t(:default => { :zero => 'zero' }, :count => 0) + end + + test "pluralization: given 0 it returns the :other translation if :zero is not defined" do + assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 0) + end + + test "pluralization: given 1 it returns the singular translation" do + assert_equal 'bar', I18n.t(:default => { :one => 'bar' }, :count => 1) + end + + test "pluralization: given 2 it returns the :other translation" do + assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 2) + end + + test "pluralization: given 3 it returns the :other translation" do + assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 3) + end + + test "pluralization: given nil it returns the whole entry" do + assert_equal({ :one => 'bar' }, I18n.t(:default => { :one => 'bar' }, :count => nil)) + end + + test "pluralization: given incomplete pluralization data it raises I18n::InvalidPluralizationData" do + assert_raises(I18n::InvalidPluralizationData) { I18n.t(:default => { :one => 'bar' }, :count => 2) } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/procs.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/procs.rb new file mode 100644 index 0000000..d377117 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/tests/procs.rb @@ -0,0 +1,71 @@ +# encoding: utf-8 + +module I18n + module Tests + module Procs + test "lookup: given a translation is a proc it calls the proc with the key and interpolation values" do + I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| I18n::Tests::Procs.filter_args(*args) }) + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(:a_lambda, :foo => 'foo') + end + + test "lookup: given a translation is a proc it passes the interpolation values as keyword arguments" do + I18n.backend.store_translations(:en, :a_lambda => lambda { |key, foo:, **| I18n::Tests::Procs.filter_args(key, foo: foo) }) + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(:a_lambda, :foo => 'foo') + end + + test "defaults: given a default is a Proc it calls it with the key and interpolation values" do + proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) } + assert_equal %|[nil, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => proc, :foo => 'foo') + end + + test "defaults: given a default is a key that resolves to a Proc it calls it with the key and interpolation values" do + the_lambda = lambda { |*args| I18n::Tests::Procs.filter_args(*args) } + I18n.backend.store_translations(:en, :a_lambda => the_lambda) + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => :a_lambda, :foo => 'foo') + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => [nil, :a_lambda], :foo => 'foo') + end + + test "interpolation: given an interpolation value is a lambda it calls it with key and values before interpolating it" do + proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) } + if RUBY_VERSION < "3.4" + assert_match %r(\[\{:foo=>#\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc) + else + assert_match %r(\[\{foo: #\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc) + end + end + + test "interpolation: given a key resolves to a Proc that returns a string then interpolation still works" do + proc = lambda { |*args| "%{foo}: " + I18n::Tests::Procs.filter_args(*args) } + assert_equal %|foo: [nil, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => proc, :foo => 'foo') + end + + test "pluralization: given a key resolves to a Proc that returns valid data then pluralization still works" do + proc = lambda { |*args| { :zero => 'zero', :one => 'one', :other => 'other' } } + assert_equal 'zero', I18n.t(:default => proc, :count => 0) + assert_equal 'one', I18n.t(:default => proc, :count => 1) + assert_equal 'other', I18n.t(:default => proc, :count => 2) + end + + test "lookup: given the option :resolve => false was passed it does not resolve proc translations" do + I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| I18n::Tests::Procs.filter_args(*args) }) + assert_equal Proc, I18n.t(:a_lambda, :resolve => false).class + end + + test "lookup: given the option :resolve => false was passed it does not resolve proc default" do + assert_equal Proc, I18n.t(nil, :default => lambda { |*args| I18n::Tests::Procs.filter_args(*args) }, :resolve => false).class + end + + + def self.filter_args(*args) + args.map do |arg| + if arg.is_a?(Hash) + arg.delete(:fallback_in_progress) + arg.delete(:fallback_original_locale) + arg.delete(:skip_interpolation) + end + arg + end.inspect + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/utils.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/utils.rb new file mode 100644 index 0000000..8841561 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/utils.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module I18n + module Utils + class << self + if Hash.method_defined?(:except) + def except(hash, *keys) + hash.except(*keys) + end + else + def except(hash, *keys) + hash = hash.dup + keys.each { |k| hash.delete(k) } + hash + end + end + + def deep_merge(hash, other_hash, &block) + deep_merge!(hash.dup, other_hash, &block) + end + + def deep_merge!(hash, other_hash, &block) + hash.merge!(other_hash) do |key, this_val, other_val| + if this_val.is_a?(Hash) && other_val.is_a?(Hash) + deep_merge(this_val, other_val, &block) + elsif block_given? + yield key, this_val, other_val + else + other_val + end + end + end + + def deep_symbolize_keys(hash) + hash.each_with_object({}) do |(key, value), result| + result[key.respond_to?(:to_sym) ? key.to_sym : key] = deep_symbolize_keys_in_object(value) + result + end + end + + private + + def deep_symbolize_keys_in_object(value) + case value + when Hash + deep_symbolize_keys(value) + when Array + value.map { |e| deep_symbolize_keys_in_object(e) } + else + value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/version.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/version.rb new file mode 100644 index 0000000..3d937a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.15.2/lib/i18n/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module I18n + VERSION = "1.15.2" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/ci.yml b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/ci.yml new file mode 100644 index 0000000..7bcf219 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/ci.yml @@ -0,0 +1,103 @@ +name: Continuous Integration + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + j4: + if: "!contains(github.event.commits[0].message, '[ci skip]')" + name: "Jekyll ${{ matrix.jekyll_version }} (Ruby ${{ matrix.ruby_version }})" + runs-on: 'ubuntu-latest' + env: + JEKYLL_VERSION: ${{ matrix.jekyll_version }} + strategy: + fail-fast: false + matrix: + ruby_version: + - 2.7 + - 3.3 + - 3.4 + jekyll_version: + - "~> 4.0" + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 5 + - name: "Set up Ruby ${{ matrix.ruby_version }}" + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + bundler-cache: true + - name: Execute tests + run: bundle exec rspec + j3: + if: "!contains(github.event.commits[0].message, '[ci skip]')" + name: "Jekyll ${{ matrix.jekyll_version }} (Ruby ${{ matrix.ruby_version }})" + runs-on: 'ubuntu-latest' + env: + JEKYLL_VERSION: ${{ matrix.jekyll_version }} + strategy: + fail-fast: false + matrix: + ruby_version: + - 2.7 + jekyll_version: + - "~> 3.9" + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 5 + - name: "Set up Ruby ${{ matrix.ruby_version }}" + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + bundler-cache: true + - name: Execute tests + run: bundle exec rspec + + style_check: + if: "!contains(github.event.commits[0].message, '[ci skip]')" + name: "Code Style Check (Ruby ${{ matrix.ruby_version }})" + runs-on: 'ubuntu-latest' + strategy: + fail-fast: false + matrix: + ruby_version: + - 2.7 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 5 + - name: "Set up Ruby ${{ matrix.ruby_version }}" + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + bundler-cache: true + - name: Check Style Offenses + run: bundle exec rubocop -S -D + + gem_build: + if: "!contains(github.event.commits[0].message, '[ci skip]')" + name: "Test Gem build (Ruby ${{ matrix.ruby_version }})" + runs-on: 'ubuntu-latest' + strategy: + fail-fast: false + matrix: + ruby_version: + - 2.7 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 5 + - name: "Set up Ruby ${{ matrix.ruby_version }}" + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + bundler-cache: true + - name: Test Gem build + run: bundle exec gem build jekyll-seo-tag.gemspec diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/release.yml b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/release.yml new file mode 100644 index 0000000..e3b723c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/release.yml @@ -0,0 +1,33 @@ +name: Release Gem + +on: + push: + branches: + - master + paths: + - "lib/**/version.rb" + +jobs: + release: + if: "github.repository_owner == 'jekyll'" + name: "Release Gem (Ruby ${{ matrix.ruby_version }})" + runs-on: "ubuntu-latest" + strategy: + fail-fast: true + matrix: + ruby_version: + - 2.7 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: "Set up Ruby ${{ matrix.ruby_version }}" + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + bundler-cache: true + - name: Build and Publish Gem + uses: ashmaroli/release-gem@dist + with: + gemspec_name: jekyll-seo-tag + env: + GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_GEM_PUSH_API_KEY }} diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof new file mode 100644 index 0000000..2f06786 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +bundle exec ruby jekyll-seo-tag/.github/workflows/scripts/memprof.rb sandbox +exit 0 diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof.rb new file mode 100644 index 0000000..45143d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/scripts/memprof.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'jekyll' +require 'memory_profiler' + +MemoryProfiler.report(allow_files: 'lib/jekyll-seo-tag') do + Jekyll::PluginManager.require_from_bundler + Jekyll::Commands::Build.process({ + "source" => File.expand_path(ARGV[0]), + "destination" => File.expand_path("#{ARGV[0]}/_site"), + "disable_disk_cache" => true, + }) + puts '' +end.pretty_print(scale_bytes: true, normalize_paths: true) diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/third-party.yml b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/third-party.yml new file mode 100644 index 0000000..23d0a06 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.github/workflows/third-party.yml @@ -0,0 +1,63 @@ +name: Third-Party Repository Profiling + +on: + push: + branches: + - master + pull_request: + branches: + - master +jobs: + build_n_profile: + name: "Third-Party Repo Profile (Jekyll ${{ matrix.jekyll_version }}, Ruby ${{ matrix.ruby_version }})" + runs-on: "ubuntu-latest" + strategy: + fail-fast: false + matrix: + ruby_version: + - 2.7 + jekyll_version: + - "~> 4.0" + - "~> 3.9" + env: + BUNDLE_GEMFILE: "sandbox/Gemfile" + BUNDLE_PATH: "vendor/bundle" + BUNDLE_JOBS: 4 + BUNDLE_RETRY: 3 + JEKYLL_VERSION: ${{ matrix.jekyll_version }} + steps: + - name: Checkout Jekyll SEO Tag + uses: actions/checkout@v4 + with: + fetch-depth: 5 + path: jekyll-seo-tag + - name: Checkout Third-Party Repository (WITHOUT SEO Tag) + uses: actions/checkout@v4 + with: + repository: ashmaroli/tomjoht.github.io + ref: "no-seo-tag" + path: alpha-sandbox + - name: Checkout Same Third-Party Repository (WITH SEO Tag) + uses: actions/checkout@v4 + with: + repository: ashmaroli/tomjoht.github.io + ref: "seo-tag" + path: sandbox + - name: "Set up Ruby ${{ matrix.ruby_version }}" + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby_version }} + bundler-cache: true + - name: Run Jekyll Build (WITHOUT SEO Tag) 3 times + run: | + bundle exec jekyll build -s alpha-sandbox -d alpha-sandbox/_site --trace + bundle exec jekyll build -s alpha-sandbox -d alpha-sandbox/_site --trace + bundle exec jekyll build -s alpha-sandbox -d alpha-sandbox/_site --trace + - name: Run Jekyll Build (WITH SEO Tag) 3 times + run: | + bundle exec jekyll build -s sandbox -d sandbox/_site --trace + bundle exec jekyll build -s sandbox -d sandbox/_site --trace + bundle exec jekyll build -s sandbox -d sandbox/_site --trace + - name: Memory Analysis of Jekyll Build (WITH SEO Tag) + run: bash jekyll-seo-tag/.github/workflows/scripts/memprof + if: "!contains(matrix.jekyll_version, '3.')" diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.gitignore b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.gitignore new file mode 100644 index 0000000..6256dfa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.gitignore @@ -0,0 +1,9 @@ +*.gem +.bundle +.yardoc +Gemfile.lock +pkg +spec/reports/ +spec/fixtures/.jekyll-cache +tmp/ +vendor/bundle diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rspec b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rspec new file mode 100644 index 0000000..83e16f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop.yml b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop.yml new file mode 100644 index 0000000..6688e6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop.yml @@ -0,0 +1,42 @@ +inherit_from: .rubocop_todo.yml + +require: rubocop-jekyll +inherit_gem: + rubocop-jekyll: .rubocop.yml + +AllCops: + TargetRubyVersion: 2.5 + SuggestExtensions: false + Exclude: + - vendor/**/* + +Layout/LineEndStringConcatenationIndentation: + Enabled: true +Layout/LineLength: + Exclude: + - spec/**/* + - jekyll-seo-tag.gemspec + +Lint/EmptyInPattern: + Enabled: false + +Metrics/BlockLength: + Exclude: + - spec/**/* + +Naming/InclusiveLanguage: + Enabled: false + +Performance/MapCompact: + Enabled: true +Performance/RedundantEqualityComparisonBlock: + Enabled: true +Performance/RedundantSplitRegexpArgument: + Enabled: true + +Style/InPatternThen: + Enabled: false +Style/MultilineInPatternThen: + Enabled: false +Style/QuotedSymbols: + Enabled: true diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop_todo.yml b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop_todo.yml new file mode 100644 index 0000000..59fd59b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/.rubocop_todo.yml @@ -0,0 +1,46 @@ +# This configuration was generated by +# `rubocop --auto-gen-config --auto-gen-only-exclude` +# on 2021-09-17 06:40:32 UTC using RuboCop version 1.18.4. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# Configuration parameters: AllowComments. +Lint/EmptyClass: + Exclude: + - 'lib/jekyll-seo-tag/version.rb' + +# Offense count: 3 +Lint/NoReturnInBeginEndBlocks: + Exclude: + - 'lib/jekyll-seo-tag/author_drop.rb' + - 'lib/jekyll-seo-tag/drop.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Lint/ToJSON: + Exclude: + - 'lib/jekyll-seo-tag/json_ld_drop.rb' + +# Offense count: 1 +# Configuration parameters: IgnoredMethods, Max. +Metrics/PerceivedComplexity: + Exclude: + - 'lib/jekyll-seo-tag/drop.rb' + +# Offense count: 1 +# Configuration parameters: MinSize. +Performance/CollectionLiteralInLoop: + Exclude: + - 'spec/jekyll_seo_tag/author_drop_spec.rb' + +# Offense count: 9 +# Cop supports --auto-correct. +Style/RedundantBegin: + Exclude: + - 'lib/jekyll-seo-tag.rb' + - 'lib/jekyll-seo-tag/author_drop.rb' + - 'lib/jekyll-seo-tag/drop.rb' + - 'lib/jekyll-seo-tag/image_drop.rb' diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/Gemfile b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/Gemfile new file mode 100644 index 0000000..40f83de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gemspec + +gem "jekyll", ENV["JEKYLL_VERSION"] if ENV["JEKYLL_VERSION"] +gem "kramdown-parser-gfm" if ENV["JEKYLL_VERSION"] == "~> 3.9" diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/History.markdown b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/History.markdown new file mode 100644 index 0000000..d93e8e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/History.markdown @@ -0,0 +1,242 @@ +## 2.9.0 / 2026-05-08 + +### Minor Enhancements + + * Added the `twitter:description` tag (#464) + * Support for image paths relative to the page's directory (#466) + * Truncate the description value to 100 words (#492) + * Add support for title_category (#517) + * feat: Add canonical=false option to disable canonical URL output (#521) + * Add a article:modified_time property for articles (#515) + +### Bug Fixes + + * Use attribute `name` consistently for metadata under `twitter` namespace (#437) + +### Documentation + + * Migrate build badge to GH Actions (#499) + +### Development Fixes + + * Add Ruby 3.1 to CI matrix (#459) + * chore: remove git.io (#462) + * Bump versions in workflows (#516) + * fix: Fix rubocop offenses (#518) + + +## 2.8.0 / 2022-02-04 + +### Minor Enhancements + + * Allow to set type for author (#427) + * Allow setting `author.url` (#453) + * Implement Facebook domain verification (#455) + * Add `og:image:alt` and `twitter:image:alt` (#438) + * Sort JSON-LD data by key (#458) + +### Bug Fixes + + * Set the default `og:type` to 'website' (#391) + * Template: Remove double new line (#454) + +### Development Fixes + + * Fix typo in source code comment (#449) + * Set up Continuous Integration via GH Actions (#450) + * Bump RuboCop to v1.18.x (#452) + * Add workflow to release gem via GH Actions + +## 2.7.1 / 2020-10-18 + +### Development Fixes + + * refactor: mutate site payload instead of duplicating it (#419) + +## 2.7.0 / 2020-10-18 + +### Minor Enhancements + + * Change pagination message with `seo_paginator_message` option (#324) + * Make Twitter Summary Card without having Twitter account (#284) + * Prefer site.tagline to site.description for page title (#356) + * Render og:locale meta only when defined explicitly (#388) + +### Bug Fixes + + * Ensure a single leading `@` for twitter usernames (#367) + +### Development Fixes + + * chore(deps): require Ruby > 2.4.0 EOL + * test: fix locale specs that use the fallback locale (#360) + * refactor: Replace read-only empty hash with private constant (#418) + * refactor: Mutate hash literals instead of duplicating them (#417) + * refactor: Reduce allocations of instance-agnostic objects (#376) + * refactor: Memoize #author_hash in SeoTag::AuthorDrop (#342) + * refactor: simplify conditional in SeoTag::Drop#date_modified (#343) + * chore(ci): profile seo-tag plugin on a third-party repository (#414) + * chore(ci): Jekyll v4.0 (#372) + * chore(ci): test against current stable Ruby 2.5 and 2.7 (#385) + * style: align with latest jekyll-rubocop (#382) + * fix: Travis builds for Jekyll 3.x (#415) + +### Documentation + + * Structured Data Testing Tool is deprecated (#409) + * Rename Google webmaster tools to Google Search Console (#403) + * Improve documentation on plugin usage (#399) + * remove Google+ from example snippet (#358) + * HTTPS link to https://ogp.me/ (#359) + * HTTPS links to schema.org (#350) + * use example.com for example URL (#351) + +## 2.6.1 / 2019-05-17 + +### Development Fixes + + * Test against Jekyll 4.x (#336) + +## 2.6.0 / 2019-03-16 + +### Minor Enhancements + + * Twitter Image and Title (#330) + +### Bug Fixes + + * Do not cache the drop payload for SeoTag (#306) + * Update url of schema website (#296) + +### Development Fixes + + * Relax version constraint on Bundler (#325) + * chore(ci): Add Ruby 2.6, drop Ruby 2.3 (#326) + * chore (ci): remove deprecated `sudo: false` in .travis.yml (#333) + * Lint Ruby code with rubocop-jekyll gem (#302) + * chore(deps): bump rubocop-jekyll to v0.4 (#320) + * chore(deps): bump rubocop-jekyll to v0.3 (#316) + * Correct RuboCop offenses in spec files (#319) + +### Documentation + + * Rectify error in Usage documentation (#328) + +## 2.5.0 / 2018-05-18 + + * Docs: Prevent GitHub Pages from processing Liquid raw tag (#276) + +### Documentation + + * Use gems config key for Jekyll < 3.5.0 (#255) + * docs/usage - replace "below" with correct link (#280) + +### Development Fixes + + * Test against Ruby 2.5 (#260) + * add tests for twitter.card types (#289) + * Target Ruby 2.3 and Rubocop 0.56.0 (#292) + +### Minor Enhancements + + * Add webmaster_verifications for baidu (#263) + * Include page number in title (#250) + * Configure default Twitter summary card type (V2) (#225) + +## 2.4.0 / 2017-12-04 + +### Minor + + * Add meta generator (#236) + * Consistently use self-closing tags (#246) + * Strip null values from JSON-LD hash (#249) + +### Documentation + + * Avoid deprecation warning when building docs (#243) + +### Development Fixes + + * Test against latest Rubies (#242) + * Use Nokigiri on CI (#181) + +## 2.3.0 + +### Minor Enhancements + + * Use canonical_url specified in page if present #211 + * Fix for image.path causing an invalid url error #228 + * Ensure `site.data.authors` is properly formatted before attempting to retrieve author meta #227 + * Convert author, image, and JSON-LD to dedicated drops #229 + * Cache parsed template #231 + * Define path with `__dir__` #232 + +### Documentation + + * gems: is deprecated in current Jekyll version of github-pages #230 + +## 2.2.3 + + * Guard against the author's Twitter handle being Nil when stripping @'s #203 + * Guard against empty title or description strings #206 + +## 2.2.2 + +### Minor Enhancements + + * Guard against arrays in subhashes #197 + * Guard against invalid or missing URLs #199 + +### Development fixes + + * Remove dynamic GitHub Pages logic from Gemfile #194 + +## 2.2.1 + + * Convert template logic to a Liquid Drop (significant performance improvement) (#184) + * Fix for JSON-LD validation warning for images missing required properties (#183) + +## 2.2.0 + +### Major Enhancements + + * Add author meta (#103) + * Add og:locale support #166 + * Add support for Bing and Yandex webmaster tools. Closes #147 (#148) + * Add SEO author and date modified to validate JSON-LD output (#151) + +### Minor Enhancements + + * Use `|` for title separator (#162) + * Use `og:image` for twitter image (#174) + +### Development Fixes + + * Style fixes (#170, #157, #149) + * Test against latest version of Jekyll (#171) + * Bump dev dependencies (#172) + * Remove Rake dependency (#180) + +## 2.1.0 + +### Major Enhancement + + * Use new URL filters (#123) + +### Minor Enhancements + + * Wraps logo image json data in a publisher property (#133) + * Fix duplicated `escape_once` (#93) + * Simplify minify regex (#125) + * Don't mangle text with newlines #126 + +### Documentation + + * Add front matter default example for image (#132) + * Fix tiny typo (#106) + * add example usage of social profiles (#139) + +### Development + + * Inherit Jekyll's rubocop config for consistency (#109) + * Correct spelling in .travis.yml (#112) diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/LICENSE.txt new file mode 100644 index 0000000..3b5c0a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present Ben Balter and the jekyll-seo-tag contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/README.md b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/README.md new file mode 100644 index 0000000..c2d3b3e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/README.md @@ -0,0 +1,33 @@ +## About Jekyll SEO Tag + +A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content. + +[![Gem Version](https://badge.fury.io/rb/jekyll-seo-tag.svg)](https://badge.fury.io/rb/jekyll-seo-tag) [![Build Status](https://github.com/jekyll/jekyll-seo-tag/actions/workflows/ci.yml/badge.svg)](https://github.com/jekyll/jekyll-seo-tag/actions/workflows/ci.yml) + +## What it does + +Jekyll SEO Tag adds the following meta tags to your site: + +* Page title, with site title or description appended +* Page description +* Canonical URL +* Next and previous URLs on paginated pages +* [JSON-LD Site and post metadata](https://developers.google.com/search/docs/guides/intro-structured-data) for richer indexing +* [Open Graph](https://ogp.me/) title, description, site title, and URL (for Facebook, LinkedIn, etc.) +* [Twitter Summary Card](https://dev.twitter.com/cards/overview) metadata + +While you could theoretically add the necessary metadata tags yourself, Jekyll SEO Tag provides a battle-tested template of crowdsourced best-practices. + +## What it doesn't do + +Jekyll SEO tag is designed to output machine-readable metadata for search engines and social networks to index and display. If you're looking for something to analyze your Jekyll site's structure and content (e.g., more traditional SEO optimization), take a look at [The Jekyll SEO Gem](https://github.com/pmarsceill/jekyll-seo-gem). + +Jekyll SEO tag isn't designed to accommodate every possible use case. It should work for most site out of the box and without a laundry list of configuration options that serve only to confuse most users. + +## Documentation + +For more information, see: + +* [Installation](installation.md) +* [Usage](usage.md) +* [Advanced usage](advanced-usage.md) diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_config.yml b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_config.yml new file mode 100644 index 0000000..286cdd0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_config.yml @@ -0,0 +1,10 @@ +title: Jekyll SEO Tag +description: A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content. + +permalink: pretty + +plugins: + - jekyll-seo-tag + - jekyll-sitemap + +theme: jekyll-theme-primer diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_layouts/default.html b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_layouts/default.html new file mode 100644 index 0000000..da8eec8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/_layouts/default.html @@ -0,0 +1,18 @@ + + + + + + + {% seo %} + + +
+

{{ site.title }}

+ + {{ content }} +
+ + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/advanced-usage.md b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/advanced-usage.md new file mode 100644 index 0000000..bc24a66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/advanced-usage.md @@ -0,0 +1,224 @@ +## Advanced usage + +Jekyll SEO Tag is designed to implement SEO best practices by default and to be the right fit for most sites right out of the box. If for some reason, you need more control over the output, read on: + +### Disabling `` output + +If for some reason, you don't want the plugin to output `<title>` tags on each page, simply invoke the plugin within your template like so: + +<!-- {% raw %} --> +``` +{% seo title=false %} +``` +<!-- {% endraw %} --> + +### Disabling `<link rel="canonical">` output + +If you're using another plugin to generate canonical URLs (such as [jekyll-polyglot](https://github.com/untra/polyglot) for multilingual sites), you can disable the canonical URL output: + +<!-- {% raw %} --> +``` +{% seo canonical=false %} +``` +<!-- {% endraw %} --> + +This will prevent the plugin from outputting the `<link rel="canonical">` tag, while still outputting all other SEO tags including the `<meta property="og:url">` tag. + +### Author information + +Author information is used to propagate the `creator` field of Twitter summary cards. This should be an author-specific, not site-wide Twitter handle (the site-wide username be stored as `site.twitter.username`). + +*TL;DR: In most cases, put `author: [your Twitter handle]` in the document's front matter, for sites with multiple authors. If you need something more complicated, read on.* + +There are several ways to convey this author-specific information. Author information is found in the following order of priority: + +1. An `author` object, in the documents's front matter, e.g.: + + ```yml + author: + twitter: benbalter + ``` + +2. An `author` object, in the site's `_config.yml`, e.g.: + + ```yml + author: + twitter: benbalter + ``` + +3. `site.data.authors[author]`, if an author is specified in the document's front matter, and a corresponding key exists in `site.data.authors`. E.g., you have the following in the document's front matter: + + ```yml + author: benbalter + ``` + + And you have the following in `_data/authors.yml`: + + ```yml + benbalter: + picture: /img/benbalter.png + twitter: jekyllrb + + potus: + picture: /img/potus.png + twitter: whitehouse + ``` + + In the above example, the author `benbalter`'s Twitter handle will be resolved to `@jekyllrb`. This allows you to centralize author information in a single `_data/authors` file for site with many authors that require more than just the author's username. + + *Pro-tip: If `authors` is present in the document's front matter as an array (and `author` is not), the plugin will use the first author listed, as Twitter supports only one author.* + +4. An author in the document's front matter (the simplest way), e.g.: + + ```yml + author: benbalter + ``` + +5. An author in the site's `_config.yml`, e.g.: + + ```yml + author: benbalter + ``` + +#### Setting author url + +Starting from August 6, 2021 [Google recommends](https://developers.google.com/search/updates) to set the `author.url` property. This property helps Google to disambiguate the correct author of the article. + +You can set it the same way as the other author properties. For example, you can put it in an `author` object, in the site's `_config.yml`, e.g.: + + ```yml + author: + name: My Name + url: https://example.com/ + ``` + +### Customizing description length + +By default, the description is limited to the first 100 words of the full content. + +You can adjust this limit at the page level, by using the `seo_description_max_words` page property: + +```yml + seo_description_max_words: 200 +``` + +You can also set a default site-wide value for all pages using [Front Matter defaults](https://jekyllrb.com/docs/configuration/front-matter-defaults/) in your `_config.yml` file: + +```yml +defaults: + - scope: + path: "" + values: + seo_description_max_words: 200 +``` + + +### Customizing JSON-LD output + +The following options can be set for any particular page. While the default options are meant to serve most users in the most common circumstances, there may be situations where more precise control is necessary. + +* `seo` + * `name` - If the name of the thing that the page represents is different from the page title. (i.e.: "Frank's Café" vs "Welcome to Frank's Café") + * `type` - The type of things that the page represents. This must be a [Schema.org type](https://schema.org/docs/schemas.html), and will probably usually be something like [`BlogPosting`](https://schema.org/BlogPosting), [`NewsArticle`](https://schema.org/NewsArticle), [`Person`](https://schema.org/Person), [`Organization`](https://schema.org/Organization), etc. + * `links` - An array of other URLs that represent the same thing that this page represents. For instance, Jane's bio page might include links to Jane's GitHub and Twitter profiles. + * `date_modified` - Manually specify the `dateModified` field in the JSON-LD output to override Jekyll's own `dateModified`. + This field will take **first priority** for the `dateModified` JSON-LD output and the article modification time for Open Graph (`article:modified_time`). This is useful when the file timestamp does not match the true time that the content was modified. A user may also install [Last Modified At](https://github.com/gjtorikian/jekyll-last-modified-at) which will offer an alternative way of providing for the `dateModified` field. + +### Customizing image output + +For most users, setting `image: [path-to-image]` on a per-page basis should be enough. If you need more control over how images are represented, the `image` property can also be an object, with the following options: + +* `path` - The relative path to the image. Same as `image: [path-to-image]` +* `height` - The height of the Open Graph (`og:image`) image +* `width` - The width of the Open Graph (`og:image`) image +* `alt` - The alternative image text for Open Graph (`og:image:alt`) and Twitter (`twitter:image:alt`) + +You can use any of the above, optional properties, like so: + +```yml +image: + path: /img/twitter.png + height: 100 + width: 100 + alt: Twitter Logo +``` + +### Setting a default image + +You can define a default image using [Front Matter defaults](https://jekyllrb.com/docs/configuration/front-matter-defaults/), to provide a default Twitter Card or OGP image to all of your posts and pages. + +Here is a very basic example, that you are encouraged to adapt to your needs: + +```yml +defaults: + - scope: + path: "" + values: + image: /assets/images/default-card.png +``` + +### SmartyPants Titles + +Titles will be processed using [Jekyll's `smartify` filter](https://jekyllrb.com/docs/liquid/filters/). This will use SmartyPants to translate plain ASCII punctuation into "smart" typographic punctuation. This will not render or strip any Markdown you may be using in a page title. + +### Setting customized Canonical URL + +You can set custom Canonical URL for a page by specifying canonical_url option in page front matter. +E.g., you have the following in the page's front matter: +```yml +layout: post +title: Title of Your Post +canonical_url: 'https://github.com/jekyll/jekyll-seo-tag/' +``` + +Which will generate canonical_url with specified link in canonical_url. +```html +<link rel="canonical" href="https://github.com/jekyll/jekyll-seo-tag/" /> +``` + +If no canonical_url option was specified, then uses page url for generating canonical_url. +E.g., you have not specified canonical_url in front matter: +```yml +layout: post +title: Title of Your Post +``` + +Which will generate following canonical_url: +```html +<link rel="canonical" href="https://example.com/title-of-your-post" /> +``` + +### Customizing title modifier for paginated pages + +You can override the default title modifier for paginated pages from `Page %{current} of %{total} for ` to a string of your +choice by setting a `seo_paginator_message` key in your `_config.yml`. + +For example: + +```yml +seo_paginator_message: "%<current>s / %<total>s | " +``` + +While the value can be any string text, we recommend using a Ruby string-template containing the variables `current` and `total` +similar to the example above, to incorporate the current page-number and total number of paginated pages in the title. + +### Adding a page title category + +You can optionally add a page category to its title. +This is useful for indicating to the users that some pages are logically grouped or are of a specific kind. + +For example page front matter including: + +```yml +title: "my page" +title_category: "category" +``` + +And `_config.yml` including: + +```yml +title: "my site" +``` + +Will generate `my page | category | my site` as the page's main `<title>` tag +and `my page | category` as all other page's title declarations like `og:title`. diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/installation.md b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/installation.md new file mode 100644 index 0000000..4a91340 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/installation.md @@ -0,0 +1,24 @@ +# Installing Jekyll SEO Tag + +1. Add the following to your site's `Gemfile`: + + ```ruby + gem 'jekyll-seo-tag' + ``` + +2. Add the following to your site's `_config.yml`: + + ```yml + plugins: + - jekyll-seo-tag + ``` + +If you are using a Jekyll version less than `3.5.0`, use the `gems` key instead of `plugins`. + +3. Add the following right before `</head>` in your site's template(s): + +<!-- {% raw %} --> + ```liquid + {% seo %} + ``` +<!-- {% endraw %} --> diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/usage.md b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/usage.md new file mode 100644 index 0000000..20dbd41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/docs/usage.md @@ -0,0 +1,81 @@ +## Usage + +The SEO tag will respect any of the following if included in your site's `_config.yml` (and simply not include them if +they're not defined): + +* `title` - Your site's title (e.g., *Ben's Awesome Site*, *The GitHub Blog*, etc.), used as part of the title tag like +`Home | Ben's Awesome Site`. +* `tagline` - A short description (e.g., *A blog dedicated to reviewing cat gifs*), used as part of the title tag like +`Ben's Awesome Site | A blog dedicated to reviewing cat gifs` instead of `Ben's Awesome Site | Long description about a +blog dedicated to reviewing cat gifs` that would be used when `page.title` is not defined. +* `description` - A longer description used for the description meta tag. Also used as fallback for pages that don't +provide their own `description`, and also as part of the page's title tag if neither `page.title` nor `site.tagline` +has been defined. +* `url` - The full URL to your site. Note: `site.github.url` will be used by default. +* `author` - global author information (see [Advanced usage](advanced-usage.md#author-information)) +* `twitter` - The following properties are available: + * `twitter:card` - The site's default card type + * `twitter:username` - The site's Twitter handle. + + You'll want to describe them like so: + + ```yml + twitter: + username: benbalter + card: summary + ``` +* `facebook` - The following properties are available: + * `facebook:app_id` - a Facebook app ID for Facebook insights + * `facebook:publisher` - a Facebook page URL or ID of the publishing entity + * `facebook:admins` - a Facebook user ID for domain insights linked to a personal account + + You'll want to describe one or more like so: + + ```yml + facebook: + app_id: 1234 + publisher: 1234 + admins: 1234 + ``` +* `logo` - URL to a site-wide logo (e.g., `/assets/your-company-logo.png`) - If you would like the "publisher" property +to be present, you must add this field to your site's configuration, during the validation of the structured data by +Google Search Console, if the `logo` field is not validated, you will find errors inherent to the publisher in the +[Rich Results Testing Tool](https://search.google.com/test/rich-results) +* `social` - For [specifying social profiles](https://developers.google.com/search/docs/guides/enhance-site#add-your-sites-name-logo-and-social-links). +The following properties are available: + * `name` - If the user or organization name differs from the site's name + * `links` - An array of links to social media profiles. + + ```yml + social: + name: Ben Balter + links: + - https://twitter.com/BenBalter + - https://www.facebook.com/ben.balter + - https://www.linkedin.com/in/BenBalter + - https://github.com/benbalter + - https://keybase.io/benbalter + ``` +* `google_site_verification` for verifying ownership via Google Search Console +* Alternatively, verify ownership with several services at once using the following format: + ```yml + webmaster_verifications: + google: 1234 + bing: 1234 + alexa: 1234 + yandex: 1234 + baidu: 1234 + facebook: 1234 + ``` +* `locale` - The locale these tags are marked up in. Of the format `language_TERRITORY`. Default is `en_US`. Takes priority +over existing config key `lang`. + +The SEO tag will respect the following YAML front matter if included in a post, page, or document: + +* `title` - The title of the post, page, or document +* `description` - A short description of the page's content +* `image` - URL to an image associated with the post, page, or document (e.g., `/assets/page-pic.jpg`) +* `author` - Page-, post-, or document-specific author information (see [Advanced usage](advanced-usage.md#author-information)) +* `locale` - Page-, post-, or document-specific locale information. Takes priority over existing front matter attribute `lang`. + +*Note:* Front matter defaults can be used for any of the above values as described in advanced usage with an image example. diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/jekyll-seo-tag.gemspec b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/jekyll-seo-tag.gemspec new file mode 100644 index 0000000..487444b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/jekyll-seo-tag.gemspec @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative "lib/jekyll-seo-tag/version" + +Gem::Specification.new do |spec| + spec.name = "jekyll-seo-tag" + spec.version = Jekyll::SeoTag::VERSION + spec.authors = ["Ben Balter"] + spec.email = ["ben.balter@github.com"] + spec.summary = "A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content." + spec.homepage = "https://github.com/jekyll/jekyll-seo-tag" + spec.license = "MIT" + + # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or + # delete this section to allow pushing this gem to any host. + if spec.respond_to?(:metadata) + spec.metadata["allowed_push_host"] = "https://rubygems.org" + else + raise "RubyGems 2.0 or newer is required to protect against public gem pushes." + end + + spec.required_ruby_version = ">= 2.5.0" + + spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|spec|features)/!) } + spec.bindir = "exe" + spec.executables = spec.files.grep(%r!^exe/!) { |f| File.basename(f) } + spec.require_paths = ["lib"] + + spec.add_dependency "jekyll", ">= 3.8", "< 5.0" + spec.add_development_dependency "bundler", ">= 1.15" + spec.add_development_dependency "html-proofer", "~> 3.7" + spec.add_development_dependency "rspec", "~> 3.5" + spec.add_development_dependency "rubocop-jekyll", "~> 0.12.0" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag.rb new file mode 100644 index 0000000..a7f69a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require "jekyll" +require "jekyll-seo-tag/version" + +module Jekyll + class SeoTag < Liquid::Tag + autoload :JSONLD, "jekyll-seo-tag/json_ld" + autoload :AuthorDrop, "jekyll-seo-tag/author_drop" + autoload :ImageDrop, "jekyll-seo-tag/image_drop" + autoload :JSONLDDrop, "jekyll-seo-tag/json_ld_drop" + autoload :UrlHelper, "jekyll-seo-tag/url_helper" + autoload :Drop, "jekyll-seo-tag/drop" + autoload :Filters, "jekyll-seo-tag/filters" + + attr_accessor :context + + # Matches all whitespace that follows either + # 1. A '}', which closes a Liquid tag + # 2. A '{', which opens a JSON block + # 3. A '>' followed by a newline, which closes an XML tag or + # 4. A ',' followed by a newline, which ends a JSON line + # We will strip all of this whitespace to minify the template + # We will not strip any whitespace if the next character is a '-' + # so that we do not interfere with the HTML comment at the + # very begining + MINIFY_REGEX = %r!(?<=[{}]|[>,]\n)\s+(?\!-)!.freeze + + def initialize(_tag_name, text, _tokens) + super + @text = text + end + + def render(context) + @context = context + SeoTag.template.render!(payload, info) + end + + private + + def options + { + "version" => Jekyll::SeoTag::VERSION, + "title" => title?, + } + end + + def payload + # site_payload is an instance of UnifiedPayloadDrop. See https://github.com/jekyll/jekyll/blob/22f2724a1f117a94cc16d18c499a93d5915ede4f/lib/jekyll/site.rb#L261-L276 + context.registers[:site].site_payload.tap do |site_payload| + site_payload["page"] = context.registers[:page] + site_payload["paginator"] = context["paginator"] + site_payload["seo_tag"] = drop + end + end + + def drop + if context.registers[:site].liquid_renderer.respond_to?(:cache) + Jekyll::SeoTag::Drop.new(@text, @context) + else + @drop ||= Jekyll::SeoTag::Drop.new(@text, @context) + end + end + + def info + { + :registers => context.registers, + :filters => [Jekyll::Filters], + } + end + + class << self + def template + @template ||= Liquid::Template.parse template_contents + end + + private + + def template_contents + @template_contents ||= begin + File.read(template_path).gsub(MINIFY_REGEX, "") + end + end + + def template_path + @template_path ||= begin + File.expand_path "./template.html", File.dirname(__FILE__) + end + end + end + end +end + +Liquid::Template.register_tag("seo", Jekyll::SeoTag) diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/author_drop.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/author_drop.rb new file mode 100644 index 0000000..9d534cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/author_drop.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +module Jekyll + class SeoTag + # A drop representing the current page's author + # + # Author name will be pulled from: + # + # 1. The page's `author` key + # 2. The first author in the page's `authors` key + # 3. The `author` key in the site config + # + # If the result from the name search is a string, we'll also check + # for additional author metadata in `site.data.authors` + class AuthorDrop < Jekyll::Drops::Drop + # Initialize a new AuthorDrop + # + # page - The page hash (e.g., Page#to_liquid) + # site - The Jekyll::Drops::SiteDrop + def initialize(page: nil, site: nil) + raise ArgumentError unless page && site + + @mutations = {} + @page = page + @site = site + end + + # AuthorDrop#to_s should return name, allowing the author drop to safely + # replace `page.author`, if necessary, and remain backwards compatible + def name + author_hash["name"] + end + alias_method :to_s, :name + + def twitter + return @twitter if defined? @twitter + + twitter = author_hash["twitter"] || author_hash["name"] + @twitter = twitter.is_a?(String) ? twitter.sub(%r!^@!, "") : nil + end + + private + + attr_reader :site, :page + + # Finds the page author in the page.author, page.authors, or site.author + # + # Returns a string or hash representing the author + def resolved_author + return @resolved_author if defined? @resolved_author + + sources = [page["author"]] + sources << page["authors"].first if page["authors"].is_a?(Array) + sources << site["author"] + @resolved_author = sources.find { |s| !s.to_s.empty? } + end + + # If resolved_author is a string, attempts to find coresponding author + # metadata in `site.data.authors` + # + # Returns a hash representing additional metadata or an empty hash + def site_data_hash + @site_data_hash ||= begin + return {} unless resolved_author.is_a?(String) + return {} unless site.data["authors"].is_a?(Hash) + + author_hash = site.data["authors"][resolved_author] + author_hash.is_a?(Hash) ? author_hash : {} + end + end + + # Returns the normalized author hash representing the page author, + # including site-wide metadata if the author is provided as a string, + # or an empty hash, if the author cannot be resolved + def author_hash + @author_hash ||= begin + case resolved_author + when Hash + resolved_author + when String + { "name" => resolved_author }.merge!(site_data_hash) + else + {} + end + end + end + + # Since author_hash is aliased to fallback_data, any values in the hash + # will be exposed via the drop, allowing support for arbitrary metadata + alias_method :fallback_data, :author_hash + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/drop.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/drop.rb new file mode 100644 index 0000000..e3bc6a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/drop.rb @@ -0,0 +1,274 @@ +# frozen_string_literal: true + +module Jekyll + class SeoTag + class Drop < Jekyll::Drops::Drop + include Jekyll::SeoTag::UrlHelper + + TITLE_SEPARATOR = " | " + FORMAT_STRING_METHODS = [ + :markdownify, :strip_html, :normalize_whitespace, :escape_once, + ].freeze + HOMEPAGE_OR_ABOUT_REGEX = %r!^/(about/)?(index.html?)?$!.freeze + + EMPTY_READ_ONLY_HASH = {}.freeze + private_constant :EMPTY_READ_ONLY_HASH + + def initialize(text, context) + @obj = EMPTY_READ_ONLY_HASH + @mutations = {} + @text = text + @context = context + end + + def version + Jekyll::SeoTag::VERSION + end + + # Should the `<title>` tag be generated for this page? + def title? + return false unless title + return @display_title if defined?(@display_title) + + @display_title = (@text !~ %r!title=false!i) + end + + # Should the `<link rel="canonical">` tag be generated for this page? + def canonical? + return @canonical if defined?(@canonical) + + @canonical = (@text !~ %r!canonical=false!i) + end + + def site_title + @site_title ||= format_string(site["title"] || site["name"]) + end + + def site_tagline + @site_tagline ||= format_string site["tagline"] + end + + def site_description + @site_description ||= format_string site["description"] + end + + # Page title without site title or description appended + def page_title + return @page_title if defined?(@page_title) + + title = format_string(page["title"]) + title_category = format_string(page["title_category"]) + @page_title = if title && title_category && title != title_category + title + TITLE_SEPARATOR + title_category + else + title || title_category || site_title + end + end + + def site_tagline_or_description + site_tagline || site_description + end + + # Page title with site title or description appended + # rubocop:disable Metrics/CyclomaticComplexity + def title + @title ||= begin + if site_title && page_title != site_title + page_title + TITLE_SEPARATOR + site_title + elsif site_description && site_title + site_title + TITLE_SEPARATOR + site_tagline_or_description + else + page_title || site_title + end + end + + return page_number + @title if page_number + + @title + end + # rubocop:enable Metrics/CyclomaticComplexity + + def name + return @name if defined?(@name) + + @name = if seo_name + seo_name + elsif !homepage_or_about? + nil + elsif site_social["name"] + format_string site_social["name"] + elsif site_title + site_title + end + end + + def description + @description ||= begin + value = format_string(page["description"] || page["excerpt"]) || site_description + snippet(value, description_max_words) + end + end + + # A drop representing the page author + def author + @author ||= AuthorDrop.new(:page => page, :site => site) + end + + # A drop representing the JSON-LD output + def json_ld + @json_ld ||= JSONLDDrop.new(self) + end + + # Returns a Drop representing the page's image + # Returns nil if the image has no path, to preserve backwards compatability + def image + @image ||= ImageDrop.new(:page => page, :context => @context) + @image if @image.path + end + + def date_modified + @date_modified ||= begin + date = page_seo["date_modified"] || page["last_modified_at"].to_liquid || page["date"] + filters.date_to_xmlschema(date) if date + end + end + + def date_published + @date_published ||= filters.date_to_xmlschema(page["date"]) if page["date"] + end + + def type + @type ||= begin + if page_seo["type"] + page_seo["type"] + elsif homepage_or_about? + "WebSite" + elsif page["date"] + "BlogPosting" + else + "WebPage" + end + end + end + + def links + @links ||= begin + if page_seo["links"] + page_seo["links"] + elsif homepage_or_about? && site_social["links"] + site_social["links"] + end + end + end + + def logo + @logo ||= begin + return unless site["logo"] + + if absolute_url? site["logo"] + filters.uri_escape site["logo"] + else + filters.uri_escape filters.absolute_url site["logo"] + end + end + end + + def page_lang + @page_lang ||= page["lang"] || site["lang"] || "en_US" + end + + def page_locale + @page_locale ||= (page["locale"] || site["locale"] || page_lang).tr("-", "_") + end + + def canonical_url + @canonical_url ||= begin + if page["canonical_url"].to_s.empty? + filters.absolute_url(page["url"]).to_s.gsub(%r!/index\.html$!, "/") + else + page["canonical_url"] + end + end + end + + def description_max_words + @description_max_words ||= page["seo_description_max_words"] || 100 + end + + private + + def filters + @filters ||= Jekyll::SeoTag::Filters.new(@context) + end + + def page + @page ||= @context.registers[:page].to_liquid + end + + def site + @site ||= @context.registers[:site].site_payload["site"].to_liquid + end + + def homepage_or_about? + page["url"] =~ HOMEPAGE_OR_ABOUT_REGEX + end + + def page_number + return unless @context["paginator"] && @context["paginator"]["page"] + + current = @context["paginator"]["page"] + total = @context["paginator"]["total_pages"] + paginator_message = site["seo_paginator_message"] || "Page %<current>s of %<total>s for " + + format(paginator_message, :current => current, :total => total) if current > 1 + end + + attr_reader :context + + def fallback_data + @fallback_data ||= {} + end + + def format_string(string) + string = FORMAT_STRING_METHODS.reduce(string) do |memo, method| + filters.public_send(method, memo) + end + + string unless string.empty? + end + + def snippet(string, max_words) + return string if string.nil? + + result = string.split(%r!\s+!, max_words + 1)[0...max_words].join(" ") + result.length < string.length ? result.concat("…") : result + end + + def seo_name + @seo_name ||= format_string(page_seo["name"]) if page_seo["name"] + end + + def page_seo + @page_seo ||= sub_hash(page, "seo") + end + + def site_social + @site_social ||= sub_hash(site, "social") + end + + # Safely returns a sub hash + # + # hash - the parent hash + # key - the key in the parent hash + # + # Returns the sub hash or an empty hash, if it does not exist + def sub_hash(hash, key) + if hash[key].is_a?(Hash) + hash[key] + else + EMPTY_READ_ONLY_HASH + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/filters.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/filters.rb new file mode 100644 index 0000000..6cbdf81 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/filters.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Jekyll + class SeoTag + class Filters + include Jekyll::Filters + include Liquid::StandardFilters + + def initialize(context) + @context = context + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/image_drop.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/image_drop.rb new file mode 100644 index 0000000..01de9b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/image_drop.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +module Jekyll + class SeoTag + # A drop representing the page image + # The image path will be pulled from: + # + # 1. The `image` key if it's a string + # 2. The `image.path` key if it's a hash + # 3. The `image.facebook` key + # 4. The `image.twitter` key + class ImageDrop < Jekyll::Drops::Drop + include Jekyll::SeoTag::UrlHelper + + # Initialize a new ImageDrop + # + # page - The page hash (e.g., Page#to_liquid) + # context - the Liquid::Context + def initialize(page: nil, context: nil) + raise ArgumentError unless page && context + + @mutations = {} + @page = page + @context = context + end + + # Called path for backwards compatability, this is really + # the escaped, absolute URL representing the page's image + # Returns nil if no image path can be determined + def path + @path ||= filters.uri_escape(absolute_url) if absolute_url + end + alias_method :to_s, :path + + private + + attr_accessor :page, :context + + # The normalized image hash with a `path` key (which may be nil) + def image_hash + @image_hash ||= begin + image_meta = page["image"] + + case image_meta + when Hash + { "path" => nil }.merge!(image_meta) + when String + { "path" => image_meta } + else + { "path" => nil } + end + end + end + alias_method :fallback_data, :image_hash + + def raw_path + @raw_path ||= begin + image_hash["path"] || image_hash["facebook"] || image_hash["twitter"] + end + end + + def absolute_url + return unless raw_path + + @absolute_url ||= build_absolute_path + end + + def build_absolute_path + return raw_path unless raw_path.is_a?(String) && absolute_url?(raw_path) == false + return filters.absolute_url(raw_path) if raw_path.start_with?("/") + + page_dir = @page["url"] + page_dir = File.dirname(page_dir) unless page_dir.end_with?("/") + + filters.absolute_url File.join(page_dir, raw_path) + end + + def filters + @filters ||= Jekyll::SeoTag::Filters.new(context) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld.rb new file mode 100644 index 0000000..34d424a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Jekyll + class SeoTag + # This module is deprecated, but is included in the Gem to avoid a breaking + # change and should be removed at the next major version bump + module JSONLD + METHODS_KEYS = { + :json_context => "@context", + :type => "@type", + :name => "name", + :page_title => "headline", + :json_author => "author", + :json_image => "image", + :date_published => "datePublished", + :date_modified => "dateModified", + :description => "description", + :publisher => "publisher", + :main_entity => "mainEntityOfPage", + :links => "sameAs", + :canonical_url => "url", + }.freeze + + # Self should be a Jekyll::SeoTag::Drop instance (when extending the module) + def json_ld + Jekyll.logger.warn "Jekyll::SeoTag::JSONLD is deprecated" + @json_ld ||= JSONLDDrop.new(self) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld_drop.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld_drop.rb new file mode 100644 index 0000000..d51404f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/json_ld_drop.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +module Jekyll + class SeoTag + class JSONLDDrop < Jekyll::Drops::Drop + extend Forwardable + + def_delegator :page_drop, :name, :name + def_delegator :page_drop, :description, :description + def_delegator :page_drop, :canonical_url, :url + def_delegator :page_drop, :page_title, :headline + def_delegator :page_drop, :date_modified, :dateModified + def_delegator :page_drop, :date_published, :datePublished + def_delegator :page_drop, :links, :sameAs + def_delegator :page_drop, :logo, :logo + def_delegator :page_drop, :type, :type + + # Expose #type and #logo as private methods and #@type as a public method + alias_method :@type, :type + private :type, :logo + + VALID_ENTITY_TYPES = %w(BlogPosting CreativeWork).freeze + VALID_AUTHOR_TYPES = %w(Organization Person).freeze + private_constant :VALID_ENTITY_TYPES, :VALID_AUTHOR_TYPES + + # page_drop should be an instance of Jekyll::SeoTag::Drop + def initialize(page_drop) + @mutations = {} + @page_drop = page_drop + end + + def fallback_data + @fallback_data ||= { + "@context" => "https://schema.org", + } + end + + def author + return unless page_drop.author["name"] + + author_type = page_drop.author["type"] + return if author_type && !VALID_AUTHOR_TYPES.include?(author_type) + + hash = { + "@type" => author_type || "Person", + "name" => page_drop.author["name"], + } + + author_url = page_drop.author["url"] + hash["url"] = author_url if author_url + + hash + end + + def image + return unless page_drop.image + return page_drop.image.path if page_drop.image.keys.length == 1 + + hash = page_drop.image.to_h + hash["url"] = hash.delete("path") + hash["@type"] = "imageObject" + hash + end + + def publisher + return unless logo + + output = { + "@type" => "Organization", + "logo" => { + "@type" => "ImageObject", + "url" => logo, + }, + } + output["name"] = page_drop.author.name if page_drop.author.name + output + end + + def main_entity + return unless VALID_ENTITY_TYPES.include?(type) + + { + "@type" => "WebPage", + "@id" => page_drop.canonical_url, + } + end + alias_method :mainEntityOfPage, :main_entity + private :main_entity + + # Returns a JSON-encoded object containing the JSON-LD data. + # Keys are sorted. + def to_json(state = nil) + keys.sort.each_with_object({}) do |(key, _), result| + v = self[key] + result[key] = v unless v.nil? + end.to_json(state) + end + + private + + attr_reader :page_drop + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/url_helper.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/url_helper.rb new file mode 100644 index 0000000..42bc803 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/url_helper.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Jekyll + class SeoTag + # Mixin to share common URL-related methods between class + module UrlHelper + private + + # Determines if the given string is an absolute URL + # + # Returns true if an absolute URL + # Returns false if it's a relative URL + # Returns nil if it is not a string or can't be parsed as a URL + def absolute_url?(string) + return unless string + + Addressable::URI.parse(string).absolute? + rescue Addressable::URI::InvalidURIError + nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/version.rb b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/version.rb new file mode 100644 index 0000000..02c98e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/jekyll-seo-tag/version.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# Prevent bundler errors +module Liquid; class Tag; end; end + +module Jekyll + class SeoTag < Liquid::Tag + VERSION = "2.9.0" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/template.html b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/template.html new file mode 100755 index 0000000..ac733ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/lib/template.html @@ -0,0 +1,131 @@ +<!-- Begin Jekyll SEO tag v{{ seo_tag.version }} --> +{% if seo_tag.title? %} + <title>{{ seo_tag.title }} +{% endif %} + + + +{% if seo_tag.page_title %} + +{% endif %} + +{% if seo_tag.author.name %} + +{% endif %} + + + +{% if seo_tag.description %} + + +{% endif %} + +{% if site.url %} + {% if seo_tag.canonical? %} + {% endif %} +{% endif %} + +{% if seo_tag.site_title %} + +{% endif %} + +{% if seo_tag.image %} + + {% if seo_tag.image.height %} + + {% endif %} + {% if seo_tag.image.width %} + + {% endif %} + {% if seo_tag.image.alt %} + + {% endif %} +{% endif %} + +{% if seo_tag.date_published %} + + + {% if seo_tag.date_modified %} + + {% endif %} +{% else %} + +{% endif %} + +{% if paginator.previous_page %} + +{% endif %} +{% if paginator.next_page %} + +{% endif %} + +{% if seo_tag.image %} + + +{% else %} + +{% endif %} + +{% if seo_tag.image.alt %} + +{% endif %} + +{% if seo_tag.page_title %} + +{% endif %} + +{% if site.twitter %} + + + {% if seo_tag.author.twitter %} + + {% endif %} +{% endif %} + +{% if site.facebook %} + {% if site.facebook.admins %} + + {% endif %} + + {% if site.facebook.publisher %} + + {% endif %} + + {% if site.facebook.app_id %} + + {% endif %} +{% endif %} + +{% if site.webmaster_verifications %} + {% if site.webmaster_verifications.google %} + + {% endif %} + + {% if site.webmaster_verifications.bing %} + + {% endif %} + + {% if site.webmaster_verifications.alexa %} + + {% endif %} + + {% if site.webmaster_verifications.yandex %} + + {% endif %} + + {% if site.webmaster_verifications.baidu %} + + {% endif %} + + {% if site.webmaster_verifications.facebook %} + + {% endif %} +{% elsif site.google_site_verification %} + +{% endif %} + + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/bootstrap b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/bootstrap new file mode 100755 index 0000000..654265e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/bootstrap @@ -0,0 +1,5 @@ +#!/bin/sh + +set -ex + +bundle install diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/cibuild b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/cibuild new file mode 100755 index 0000000..dec4aa6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/cibuild @@ -0,0 +1,7 @@ +#!/bin/sh + +set -ex + +bundle exec rspec +bundle exec rubocop -S -D +bundle exec gem build jekyll-seo-tag.gemspec diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/release b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/release new file mode 100755 index 0000000..1458842 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/release @@ -0,0 +1,38 @@ +#!/bin/sh +# Tag and push a release. + +set -e + +# Make sure we're in the project root. + +cd $(dirname "$0")/.. + +# Build a new gem archive. + +rm -rf jekyll-seo-tag-*.gem +gem build -q jekyll-seo-tag.gemspec + +# Make sure we're on the master branch. + +(git branch | grep -q '* master') || { + echo "Only release from the master branch." + exit 1 +} + +# Figure out what version we're releasing. + +tag=v`ls jekyll-seo-tag-*.gem | sed 's/^jekyll-seo-tag-\(.*\)\.gem$/\1/'` + +# Make sure we haven't released this version before. + +git fetch -t origin + +(git tag -l | grep -q "$tag") && { + echo "Whoops, there's already a '${tag}' tag." + exit 1 +} + +# Tag it and bag it. + +gem push jekyll-seo-tag-*.gem && git tag "$tag" && + git push origin master && git push origin "$tag" diff --git a/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/site b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/site new file mode 100755 index 0000000..9e4f56f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/jekyll-seo-tag-2.9.0/script/site @@ -0,0 +1,3 @@ +#!/bin/sh + +bundle exec jekyll serve --source docs diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/BSDL b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/BSDL new file mode 100644 index 0000000..66d9359 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/CHANGES.md b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/CHANGES.md new file mode 100644 index 0000000..b13642a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/CHANGES.md @@ -0,0 +1,810 @@ +# Changes + +### Unreleased + +### 2026-07-13 (2.21.1) + +* Fix a compilation issue on Window and Microsoft Visual C++. + +### 2026-07-12 (2.21.0) + +* `JSON.generate` now accept a `sort_keys` option, which takes either a boolean or a block. +* Added `#empty?` and `#partial_value?` methods on `JSON::ResumableParser`. +* Numerous correctness and performance fixes for `JSON::ResumableParser`. +* Avoid triggering Ruby's `float out of range` warning when parsing out of range numbers. +* Declare C types with Ruby 4.1 `RUBY_TYPED_THREAD_SAFE_FREE`. + +### 2026-06-23 (2.20.0) + +* Both C and Java parsers are no longer recursive, so parsing very deep documents with `max_nesting: false` will no longer + result in `SystemStackError stack level too deep` errors. + * The `:max_nesting` option still defaults to `100`. +* Optimized floating point number parsing further by replacing the ryu algorithm by a port of Eisel-Lemire Fast Float. +* Added `JSON::ResumableParser` to parse streams of JSON documents. Not yet available on JRuby. +* Deprecate default support of JavaScript comments in the parser and add `allow_comments: true` parsing option. +* Integrate with Ruby 4.1 `ruby_sized_xfree`. + +### 2026-06-11 (2.19.9) + +* Fix buffer overflow that could lead to a crash when writing JSON directly into an IO + with `JSON.generate(object, io)`. [CVE-2026-54696]. + +### 2026-06-03 (2.19.8) + +* Fix 1-byte buffer overread on EOS errors. +* Handle invalid types passed as `max_nesting` option. + +### 2026-05-28 (2.19.7) + +* Fix some more edge cases with out of range floats. +* Ensure the string provided to `JSON.parse` can't be mutated during parsing. +* Add missing write barriers in `State#dup`. +* Further validate generator `depth` config. + +### 2026-05-28 (2.19.6) + +* Cleanly handle overly large `depth` generator argument. +* Add missing write barrier in `ParserConfig`. + +### 2026-05-04 (2.19.5) + +* Cap the parser to emit a maximum of 5 deprecation warnings per document. Emitting more is not helpful. + +### 2026-04-19 (2.19.4) + +* Fix parsing of out of range floats (very large exponents that lead to either `0.0` or `Inf`). + +### 2026-03-25 (2.19.3) + +* Fix handling of unescaped control characters preceeded by a backslash. + +### 2026-03-18 (2.19.2) + +* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`. + +### 2026-03-08 (2.19.1) + +* Fix a compiler dependent GC bug introduced in `2.18.0`. + +### 2026-03-06 (2.19.0) + +* Fix `allow_blank` parsing option to no longer allow invalid types (e.g. `load([], allow_blank: true)` now raise a type error). +* Add `allow_invalid_escape` parsing option to ignore backslashes that aren't followed by one of the valid escape characters. + +### 2026-02-03 (2.18.1) + +* Fix a potential crash in very specific circumstance if GC triggers during a call to `to_json` + without first invoking a user defined `#to_json` method. + +### 2025-12-11 (2.18.0) + +* Add `:allow_control_characters` parser options, to allow JSON strings containing unescaped ASCII control characters (e.g. newlines). + +### 2026-03-18 (2.17.1.2) - Security Backport + +* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`. + +### 2025-12-04 (2.17.1) + +* Fix a regression in parsing of unicode surogate pairs (`\uXX\uXX`) that could cause an invalid string to be returned. + +### 2025-12-03 (2.17.0) + +* Improve `JSON.load` and `JSON.unsafe_load` to allow passing options as second argument. +* Fix the parser to no longer ignore invalid escapes in strings. + Only `\"`, `\\`, `\b`, `\f`, `\n`, `\r`, `\t` and `\u` are valid JSON escapes. +* Fixed `JSON::Coder` to use the depth it was initialized with. +* On TruffleRuby, fix the generator to not call `to_json` on the return value of `as_json` for `Float::NAN`. +* Fixed handling of `state.depth`: when `to_json` changes `state.depth` but does not restore it, it is reset + automatically to its initial value. + In particular, when a `NestingError` is raised, `depth` is no longer equal to `max_nesting` after the call to + generate, and is reset to its initial value. Similarly when `to_json` raises an exception. + +### 2025-11-07 (2.16.0) + +* Deprecate `JSON::State#[]` and `JSON::State#[]=`. Consider using `JSON::Coder` instead. +* `JSON::Coder` now also yields to the block when encountering strings with invalid encoding. +* Fix GeneratorError messages to be UTF-8 encoded. +* Fix memory leak when `Exception` is raised, or `throw` is used during JSON generation. +* Optimized floating point number parsing by integrating the ryu algorithm (thanks to Josef Šimánek). +* Optimized numbers parsing using SWAR (thanks to Scott Myron). +* Optimized parsing of pretty printed documents using SWAR (thanks to Scott Myron). + +### 2026-03-18 (2.15.2.1) - Security Backport + +* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`. + +### 2025-10-25 (2.15.2) + +* Fix `JSON::Coder` to have one dedicated depth counter per invocation. + After encountering a circular reference in `JSON::Coder#dump`, any further `#dump` call would raise `JSON::NestingError`. + +### 2025-10-07 (2.15.1) + +* Fix incorrect escaping in the JRuby extension when encoding shared strings. + +### 2025-09-22 (2.15.0) + +* `JSON::Coder` callback now receive a second argument to convey whether the object is a hash key. +* Tuned the floating point number generator to not use scientific notation as aggressively. + +### 2025-09-18 (2.14.1) + +* Fix `IndexOutOfBoundsException` in the JRuby extension when encoding shared strings. + +### 2025-09-18 (2.14.0) + +* Add new `allow_duplicate_key` generator options. By default a warning is now emitted when a duplicated key is encountered. + In `json 3.0` an error will be raised. + ```ruby + >> Warning[:deprecated] = true + >> puts JSON.generate({ foo: 1, "foo" => 2 }) + (irb):2: warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}. + This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true` + {"foo":1,"foo":2} + >> JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false) + detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError) + ``` +* Fix `JSON.generate` `strict: true` mode to also restrict hash keys. +* Fix `JSON::Coder` to also invoke block for hash keys that aren't strings nor symbols. +* Fix `JSON.unsafe_load` usage with proc +* Fix the parser to more consistently reject invalid UTF-16 surogate pairs. +* Stop defining `String.json_create`, `String#to_json_raw`, `String#to_json_raw_object` when `json/add` isn't loaded. + +### 2025-07-28 (2.13.2) + +* Improve duplicate key warning and errors to include the key name and point to the right caller. + +### 2025-07-24 (2.13.1) + +* Fix support for older compilers without `__builtin_cpu_supports`. + +### 2025-07-17 (2.13.0) + +* Add new `allow_duplicate_key` parsing options. By default a warning is now emitted when a duplicated key is encountered. + In `json 3.0` an error will be raised. +* Optimize parsing further using SIMD to scan strings. + +### 2025-05-23 (2.12.2) + +* Fix compiler optimization level. + +### 2025-05-23 (2.12.1) + +* Fix a potential crash in large negative floating point number generation. +* Fix for JSON.pretty_generate to use passed state object's generate instead of state class as the required parameters aren't available. + +### 2025-05-12 (2.12.0) + +* Improve floating point generation to not use scientific notation as much. +* Include line and column in parser errors. Both in the message and as exception attributes. +* Handle non-string hash keys with broken `to_s` implementations. +* `JSON.generate` now uses SSE2 (x86) or NEON (arm64) instructions when available to escape strings. + +### 2025-04-25 (2.11.3) + +* Fix a regression in `JSON.pretty_generate` that could cause indentation to be off once some `#to_json` has been called. + +### 2025-04-24 (2.11.2) + +* Add back `JSON::PRETTY_STATE_PROTOTYPE`. This constant was private API but is used by popular gems like `multi_json`. + It now emits a deprecation warning. + +### 2025-04-24 (2.11.1) + +* Add back `JSON.restore`, `JSON.unparse`, `JSON.fast_unparse` and `JSON.pretty_unparse`. + These were deprecated 16 years ago, but never emitted warnings, only undocumented, so are + still used by a few gems. + +### 2025-04-24 (2.11.0) + +* Optimize Integer generation to be ~1.8x faster. +* Optimize Float generation to be ~10x faster. +* Fix `JSON.load` proc argument to substitute the parsed object with the return value. + This better match `Marshal.load` behavior. +* Deprecate `JSON.fast_generate` (it's not any faster, so pointless). +* Deprecate `JSON.load_default_options`. +* Deprecate `JSON.unsafe_load_default_options`. +* Deprecate `JSON.dump_default_options`. +* Deprecate `Kernel#j` +* Deprecate `Kernel#jj` +* Remove outdated `JSON.iconv`. +* Remove `Class#json_creatable?` monkey patch. +* Remove deprecated `JSON.restore` method. +* Remove deprecated `JSON.unparse` method. +* Remove deprecated `JSON.fast_unparse` method. +* Remove deprecated `JSON.pretty_unparse` method. +* Remove deprecated `JSON::UnparserError` constant. +* Remove outdated `JSON::MissingUnicodeSupport` constant. + +### 2025-03-12 (2.10.2) + +* Fix a potential crash in the C extension parser. +* Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0` inadvertently changed it. +* Ensure document snippets that are included in parser errors don't include truncated multibyte characters. +* Ensure parser error snippets are valid UTF-8. +* Fix `JSON::GeneratorError#detailed_message` on Ruby < 3.2 + +### 2025-02-10 (2.10.1) + +* Fix a compatibility issue with `MultiJson.dump(obj, pretty: true)`: `no implicit conversion of false into Proc (TypeError)`. + +### 2025-02-10 (2.10.0) + +* `strict: true` now accept symbols as values. Previously they'd only be accepted as hash keys. +* The C extension Parser has been entirely reimplemented from scratch. +* Introduced `JSON::Coder` as a new API allowing to customize how non native types are serialized in a non-global way. +* Introduced `JSON::Fragment` to allow assembling cached fragments in a safe way. +* The Java implementation of the generator received many optimizations. + +### 2024-12-18 (2.9.1) + +* Fix support for Solaris 10. + +### 2024-12-03 (2.9.0) + +* Fix C implementation of `script_safe` escaping to not confuse some other 3 wide characters with `\u2028` and `\u2029`. + e.g. `JSON.generate(["倩", "瀨"], script_safe: true)` would generate the wrong JSON. +* `JSON.dump(object, some_io)` now write into the IO in chunks while previously it would buffer the entire JSON before writing. +* `JSON::GeneratorError` now has a `#invalid_object` attribute, making it easier to understand why an object tree cannot be serialized. +* Numerous improvements to the JRuby extension. + +### 2024-11-14 (2.8.2) + +* `JSON.load_file` explicitly read the file as UTF-8. + +### 2024-11-06 (2.8.1) + +* Fix the java packages to include the extension. + +### 2024-11-06 (2.8.0) + +* Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explicitly enabled. + * Prefer to use `JSON.unsafe_load(string)` or `JSON.load(string, create_additions: true)`. +* Emit a deprecation warning when serializing valid UTF-8 strings encoded in `ASCII_8BIT` aka `BINARY`. +* Bump required Ruby version to 2.7. +* Add support for optionally parsing trailing commas, via `allow_trailing_comma: true`, which in cunjunction with the + pre-existing support for comments, make it suitable to parse `jsonc` documents. +* Many performance improvements to `JSON.parse` and `JSON.load`, up to `1.7x` faster on real world documents. +* Some minor performance improvements to `JSON.dump` and `JSON.generate`. +* `JSON.pretty_generate` no longer includes newlines inside empty object and arrays. + +### 2024-11-04 (2.7.6) + +* Fix a regression in JSON.generate when dealing with Hash keys that are string subclasses, call `to_json` on them. + +### 2024-10-25 (2.7.5) + +* Fix a memory leak when `#to_json` methods raise an exception. +* Gracefully handle formatting configs being set to `nil` instead of `""`. +* Workaround another issue caused by conflicting versions of both `json_pure` and `json` being loaded. + +### 2024-10-25 (2.7.4) + +* Workaround a bug in 3.4.8 and older https://github.com/rubygems/rubygems/pull/6490. + This bug would cause some gems with native extension to fail during compilation. +* Workaround different versions of `json` and `json_pure` being loaded (not officially supported). +* Make `json_pure` Ractor compatible. + +### 2024-10-24 (2.7.3) + +* Numerous performance optimizations in `JSON.generate` and `JSON.dump` (up to 2 times faster). +* Limit the size of ParserError exception messages, only include up to 32 bytes of the unparsable source. +* Fix json-pure's `Object#to_json` to accept non-state arguments. +* Fix multiline comment support in `json-pure`. +* Fix `JSON.parse` to no longer mutate the argument encoding when passed an ASCII-8BIT string. +* Fix `String#to_json` to raise on invalid encoding in `json-pure`. +* Delete code that was based on CVTUTF. +* Use the pure-Ruby generator on TruffleRuby. +* Fix `strict` mode in `json-pure` to not break on Integer. + +### 2024-04-04 (2.7.2) + +* Use rb_sym2str instead of SYM2ID #561 +* Fix memory leak when exception is raised during JSON generation #574 +* Remove references to "19" methods in JRuby #576 +* Make OpenStruct support as optional by @hsbt in #565 +* Autoload JSON::GenericObject to avoid require ostruct warning in Ruby 3.4 #577 +* Warn to install ostruct if json couldn't load it by @hsbt #578 + +### 2023-12-05 (2.7.1) + +* JSON.dump: handle unenclosed hashes regression #554 +* Overload kwargs in JSON.dump #556 +* [DOC] RDoc for additions #557 +* Fix JSON.dump overload combination #558 + +### 2023-12-01 (2.7.0) + +* Add a strict option to Generator #519 +* `escape_slash` option was renamed as `script_safe` and now also escape U+2028 and U+2029. `escape_slash` is now an alias of `script_safe` #525 +* Remove unnecessary initialization of create_id in JSON.parse() #454 +* Improvements to Hash#to_json in pure implementation generator #203 +* Use ruby_xfree to free buffers #518 +* Fix "unexpected token" offset for Infinity #507 +* Avoid using deprecated BigDecimal.new on JRuby #546 +* Removed code for Ruby 1.8 #540 +* Rename JSON::ParseError to JSON:ParserError #530 +* Call super in included hook #486 +* JRuby requires a minimum of Java 8 #516 +* Always indent even if empty #517 + +### 2022-11-30 (2.6.3) + +* bugfix json/pure mixing escaped with literal unicode raises Encoding::CompatibilityError #483 +* Stop including the parser source __LINE__ in exceptions #470 + +### 2022-11-17 (2.6.2) + +* Remove unknown keyword arg from DateTime.parse #488 +* Ignore java artifacts by @hsbt #489 +* Fix parser bug for empty string allocation #496 + +### 2021-10-24 (2.6.1) + +* Restore version.rb with 2.6.1 + +### 2021-10-14 (2.6.0) + +* Use `rb_enc_interned_str` if available to reduce allocations in `freeze: true` mode. #451. +* Bump required_ruby_version to 2.3. +* Fix compatibility with `GC.compact`. +* Fix some compilation warnings. #469 + +## 2020-12-22 (2.5.1) + +* Restore the compatibility for constants of JSON class. + +## 2020-12-22 (2.5.0) + +* Ready to Ractor-safe at Ruby 3.0. + +## 2020-12-17 (2.4.1) + +* Restore version.rb with 2.4.1 + +## 2020-12-15 (2.4.0) + +* Implement a freeze: parser option #447 +* Fix an issue with generate_pretty and empty objects in the Ruby and Java implementations #449 +* Fix JSON.load_file doc #448 +* Fix pure parser with unclosed arrays / objects #425 +* bundle the LICENSE file in the gem #444 +* Add an option to escape forward slash character #405 +* RDoc for JSON #439 #446 #442 #434 #433 #430 + +## 2020-06-30 (2.3.1) + +* Spelling and grammar fixes for comments. Pull request #191 by Josh + Kline. +* Enhance generic JSON and #generate docs. Pull request #347 by Victor + Shepelev. +* Add :nodoc: for GeneratorMethods. Pull request #349 by Victor Shepelev. +* Baseline changes to help (JRuby) development. Pull request #371 by Karol + Bucek. +* Add metadata for rubygems.org. Pull request #379 by Alexandre ZANNI. +* Remove invalid JSON.generate description from JSON module rdoc. Pull + request #384 by Jeremy Evans. +* Test with TruffleRuby in CI. Pull request #402 by Benoit Daloze. +* Rdoc enhancements. Pull request #413 by Burdette Lamar. +* Fixtures/ are not being tested... Pull request #416 by Marc-André + Lafortune. +* Use frozen string for hash key. Pull request #420 by Marc-André + Lafortune. +* Added :call-seq: to RDoc for some methods. Pull request #422 by Burdette + Lamar. +* Small typo fix. Pull request #423 by Marc-André Lafortune. + +## 2019-12-11 (2.3.0) + * Fix default of `create_additions` to always be `false` for `JSON(user_input)` + and `JSON.parse(user_input, nil)`. + Note that `JSON.load` remains with default `true` and is meant for internal + serialization of trusted data. [CVE-2020-10663] + * Fix passing args all #to_json in json/add/*. + * Fix encoding issues + * Fix issues of keyword vs positional parameter + * Fix JSON::Parser against bigdecimal updates + * Bug fixes to JRuby port + +## 2019-02-21 (2.2.0) + * Adds support for 2.6 BigDecimal and ruby standard library Set datetype. + +## 2017-04-18 (2.1.0) + * Allow passing of `decimal_class` option to specify a class as which to parse + JSON float numbers. +## 2017-03-23 (2.0.4) + * Raise exception for incomplete unicode surrogates/character escape + sequences. This problem was reported by Daniel Gollahon (dgollahon). + * Fix arbitrary heap exposure problem. This problem was reported by Ahmad + Sherif (ahmadsherif). + +## 2017-01-12 (2.0.3) + * Set `required_ruby_version` to 1.9 + * Some small fixes + +## 2016-07-26 (2.0.2) + * Specify `required_ruby_version` for json\_pure. + * Fix issue #295 failure when parsing frozen strings. + +## 2016-07-01 (2.0.1) + * Fix problem when requiring json\_pure and Parser constant was defined top + level. + * Add `RB_GC_GUARD` to avoid possible GC problem via Pete Johns. + * Store `current_nesting` on stack by Aaron Patterson. + +## 2015-09-11 (2.0.0) + * Now complies to newest JSON RFC 7159. + * Implements compatibility to ruby 2.4 integer unification. + * Removed support for `quirks_mode` option. + * Drops support for old rubies whose life has ended, that is rubies < 2.0. + Also see https://www.ruby-lang.org/en/news/2014/07/01/eol-for-1-8-7-and-1-9-2/ + * There were still some mentions of dual GPL licensing in the source, but JSON + has just the Ruby license that itself includes an explicit dual-licensing + clause that allows covered software to be distributed under the terms of + the Simplified BSD License instead for all ruby versions >= 1.9.3. This is + however a GPL compatible license according to the Free Software Foundation. + I changed these mentions to be consistent with the Ruby license setting in + the gemspec files which were already correct now. + +## 2017-01-13 (1.8.6) + * Be compatible with ancient ruby 1.8 (maybe?) + +## 2015-09-11 (1.8.5) + * Be compatible with ruby 2.4.0 + * There were still some mentions of dual GPL licensing in the source, but JSON + has just the Ruby license that itself includes an explicit dual-licensing + clause that allows covered software to be distributed under the terms of + the Simplified BSD License instead for all ruby versions >= 1.9.3. This is + however a GPL compatible license according to the Free Software Foundation. + I changed these mentions to be consistent with the Ruby license setting in + the gemspec files which were already correct now. + +## 2015-06-01 (1.8.3) + * Fix potential memory leak, thx to nobu. + +## 2015-01-08 (1.8.2) + * Some performance improvements by Vipul A M . + * Fix by Jason R. Clark to avoid mutation of + `JSON.dump_default_options`. + * More tests by Michael Mac-Vicar and fixing + `space_before` accessor in generator. + * Performance on Jruby improved by Ben Browning . + * Some fixes to be compatible with the new Ruby 2.2 by Zachary Scott + and SHIBATA Hiroshi . + +## 2013-05-13 (1.8.1) + * Remove Rubinius exception since transcoding should be working now. + +## 2013-05-13 (1.8.0) + * Fix https://github.com/ruby/json/issues/162 reported by Marc-Andre + Lafortune . Thanks! + * Applied patches by Yui NARUSE to suppress warning with + -Wchar-subscripts and better validate UTF-8 strings. + * Applied patch by ginriki@github to remove unnecessary if. + * Add load/dump interface to `JSON::GenericObject` to make + serialize :some_attribute, `JSON::GenericObject` + work in Rails active models for convenient `SomeModel#some_attribute.foo.bar` + access to serialised JSON data. + +## 2013-02-04 (1.7.7) + * Security fix for JSON create_additions default value and + `JSON::GenericObject`. It should not be possible to create additions unless + explicitly requested by setting the create_additions argument to true or + using the JSON.load/dump interface. If `JSON::GenericObject` is supposed to + be automatically deserialised, this has to be explicitly enabled by + setting + JSON::GenericObject.json_creatable = true + as well. + * Remove useless assert in fbuffer implementation. + * Apply patch attached to https://github.com/ruby/json/issues#issue/155 + provided by John Shahid , Thx! + * Add license information to rubygems spec data, reported by Jordi Massaguer Pla . + * Improve documentation, thx to Zachary Scott . + +## 2012-11-29 (1.7.6) + * Add `GeneratorState#merge` alias for JRuby, fix state accessor methods. Thx to + jvshahid@github. + * Increase hash likeness of state objects. + +## 2012-08-17 (1.7.5) + * Fix compilation of extension on older rubies. + +## 2012-07-26 (1.7.4) + * Fix compilation problem on AIX, see https://github.com/ruby/json/issues/142 + +## 2012-05-12 (1.7.3) + * Work around Rubinius encoding issues using iconv for conversion instead. + +## 2012-05-11 (1.7.2) + * Fix some encoding issues, that cause problems for the pure and the + extension variant in jruby 1.9 mode. + +## 2012-04-28 (1.7.1) + * Some small fixes for building + +## 2012-04-28 (1.7.0) + * Add `JSON::GenericObject` for method access to objects transmitted via JSON. + +## 2012-04-27 (1.6.7) + * Fix possible crash when trying to parse nil value. + +## 2012-02-11 (1.6.6) + * Propagate src encoding to values made from it (fixes 1.9 mode converting + everything to ascii-8bit; harmless for 1.8 mode too) (Thomas E. Enebo + ), should fix + https://github.com/ruby/json/issues#issue/119. + * Fix https://github.com/ruby/json/issues#issue/124 Thx to Jason Hutchens. + * Fix https://github.com/ruby/json/issues#issue/117 + +## 2012-01-15 (1.6.5) + * Vit Ondruch reported a bug that shows up when using + optimisation under GCC 4.7. Thx to him, Bohuslav Kabrda + and Yui NARUSE for debugging and + developing a patch fix. + +## 2011-12-24 (1.6.4) + * Patches that improve speed on JRuby contributed by Charles Oliver Nutter + . + * Support `object_class`/`array_class` with duck typed hash/array. + +## 2011-12-01 (1.6.3) + * Let `JSON.load('')` return nil as well to make mysql text columns (default to + `''`) work better for serialization. + +## 2011-11-21 (1.6.2) + * Add support for OpenStruct and BigDecimal. + * Fix bug when parsing nil in `quirks_mode`. + * Make JSON.dump and JSON.load methods better cooperate with Rails' serialize + method. Just use: + serialize :value, JSON + * Fix bug with time serialization concerning nanoseconds. Thanks for the + patch go to Josh Partlow (jpartlow@github). + * Improve parsing speed for JSON numbers (integers and floats) in a similar way to + what Evan Phoenix suggested in: + https://github.com/ruby/json/pull/103 + +## 2011-09-18 (1.6.1) + * Using -target 1.5 to force Java bits to compile with 1.5. + +## 2011-09-12 (1.6.0) + * Extract utilities (prettifier and GUI-editor) in its own gem json-utils. + * Split json/add/core into different files for classes to be serialised. + +## 2011-08-31 (1.5.4) + * Fix memory leak when used from multiple JRuby. (Patch by + jfirebaugh@github). + * Apply patch by Eric Wong that fixes garbage collection problem + reported in https://github.com/ruby/json/issues/46. + * Add :quirks_mode option to parser and generator. + * Add support for Rational and Complex number additions via json/add/complex + and json/add/rational requires. + +## 2011-06-20 (1.5.3) + * Alias State#configure method as State#merge to increase duck type synonymy with Hash. + * Add `as_json` methods in json/add/core, so rails can create its json objects the new way. + +## 2011-05-11 (1.5.2) + * Apply documentation patch by Cory Monty . + * Add gemspecs for json and json\_pure. + * Fix bug in jruby pretty printing. + * Fix bug in `object_class` and `array_class` when inheriting from Hash or + Array. + +## 2011-01-24 (1.5.1) + * Made rake-compiler build a fat binary gem. This should fix issue + https://github.com/ruby/json/issues#issue/54. + +## 2011-01-22 (1.5.0) + * Included Java source codes for the Jruby extension made by Daniel Luz + . + * Output full exception message of `deep_const_get` to aid debugging. + * Fixed an issue with ruby 1.9 `Module#const_defined?` method, that was + reported by Riley Goodside. + +## 2010-08-09 (1.4.6) + * Fixed oversight reported in http://github.com/ruby/json/issues/closed#issue/23, + always create a new object from the state prototype. + * Made pure and ext api more similar again. + +## 2010-08-07 (1.4.5) + * Manage data structure nesting depth in state object during generation. This + should reduce problems with `to_json` method definіtions that only have one + argument. + * Some fixes in the state objects and additional tests. +## 2010-08-06 (1.4.4) + * Fixes build problem for rubinius under OS X, http://github.com/ruby/json/issues/closed#issue/25 + * Fixes crashes described in http://github.com/ruby/json/issues/closed#issue/21 and + http://github.com/ruby/json/issues/closed#issue/23 +## 2010-05-05 (1.4.3) + * Fixed some test assertions, from Ruby r27587 and r27590, patch by nobu. + * Fixed issue http://github.com/ruby/json/issues/#issue/20 reported by + electronicwhisper@github. Thx! + +## 2010-04-26 (1.4.2) + * Applied patch from naruse Yui NARUSE to make building with + Microsoft Visual C possible again. + * Applied patch from devrandom in order to allow building of + json_pure if extensiontask is not present. + * Thanks to Dustin Schneider , who reported a memory + leak, which is fixed in this release. + * Applied 993f261ccb8f911d2ae57e9db48ec7acd0187283 patch from josh@github. + +## 2010-04-25 (1.4.1) + * Fix for a bug reported by Dan DeLeo , caused by T_FIXNUM + being different on 32bit/64bit architectures. + +## 2010-04-23 (1.4.0) + * Major speed improvements and building with simplified + directory/file-structure. + * Extension should at least be compatible with MRI, YARV and Rubinius. + +## 2010-04-07 (1.2.4) + * Trigger const_missing callback to make Rails' dynamic class loading work. + +## 2010-03-11 (1.2.3) + * Added a `State#[]` method which returns an attribute's value in order to + increase duck type compatibility to Hash. + +## 2010-02-27 (1.2.2) + * Made some changes to make the building of the parser/generator compatible + to Rubinius. + +## 2009-11-25 (1.2.1) + * Added `:symbolize_names` option to Parser, which returns symbols instead of + strings in object names/keys. + +## 2009-10-01 (1.2.0) + * `fast_generate` now raises an exception for nan and infinite floats. + * On Ruby 1.8 json supports parsing of UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, + and UTF-32LE JSON documents now. Under Ruby 1.9 the M17n conversion + functions are used to convert from all supported encodings. ASCII-8BIT + encoded strings are handled like all strings under Ruby 1.8 were. + * Better documentation + +## 2009-08-23 (1.1.9) + * Added forgotten main doc file `extra_rdoc_files`. + +## 2009-08-23 (1.1.8) + * Applied a patch by OZAWA Sakuro to make json/pure + work in environments that don't provide iconv. + * Applied patch by okkez_ in order to fix Ruby Bug #1768: + http://redmine.ruby-lang.org/issues/show/1768. + * Finally got around to avoid the rather paranoid escaping of ?/ characters + in the generator's output. The parsers aren't affected by this change. + Thanks to Rich Apodaca for the suggestion. + +## 2009-06-29 (1.1.7) + * Security Fix for JSON::Pure::Parser. A specially designed string could + cause catastrophic backtracking in one of the parser's regular expressions + in earlier 1.1.x versions. JSON::Ext::Parser isn't affected by this issue. + Thanks to Bartosz Blimke for reporting this + problem. + * This release also uses a less strict ruby version requirement for the + creation of the mswin32 native gem. + +## 2009-05-10 (1.1.6) + * No changes. І tested native linux gems in the last release and they don't + play well with different ruby versions other than the one the gem was built + with. This release is just to bump the version number in order to skip the + native gem on rubyforge. + +## 2009-05-10 (1.1.5) + * Started to build gems with rake-compiler gem. + * Applied patch object/array class patch from Brian Candler + and fixes. + +## 2009-04-01 (1.1.4) + * Fixed a bug in the creation of serialized generic rails objects reported by + Friedrich Graeter . + * Deleted tests/runner.rb, we're using testrb instead. + * Editor supports Infinity in numbers now. + * Made some changes in order to get the library to compile/run under Ruby + 1.9. + * Improved speed of the code path for the fast_generate method in the pure + variant. + +## 2008-07-10 (1.1.3) + * Wesley Beary reported a bug in json/add/core's DateTime + handling: If the nominator and denominator of the offset were divisible by + each other Ruby's Rational#to_s returns them as an integer not a fraction + with '/'. This caused a ZeroDivisionError during parsing. + * Use Date#start and DateTime#start instead of sg method, while + remaining backwards compatible. + * Supports ragel >= 6.0 now. + * Corrected some tests. + * Some minor changes. + +## 2007-11-27 (1.1.2) + * Remember default dir (last used directory) in editor. + * JSON::Editor.edit method added, the editor can now receive json texts from + the clipboard via C-v. + * Load json texts from an URL pasted via middle button press. + * Added :create_additions option to Parser. This makes it possible to disable + the creation of additions by force, in order to treat json texts as data + while having additions loaded. + * Jacob Maine reported, that JSON(:foo) outputs a JSON + object if the rails addition is enabled, which is wrong. It now outputs a + JSON string "foo" instead, like suggested by Jacob Maine. + * Discovered a bug in the Ruby Bugs Tracker on rubyforge, that was reported + by John Evans lgastako@gmail.com. He could produce a crash in the JSON + generator by returning something other than a String instance from a + to_json method. I now guard against this by doing a rather crude type + check, which raises an exception instead of crashing. + +## 2007-07-06 (1.1.1) + * Yui NARUSE sent some patches to fix tests for Ruby + 1.9. I applied them and adapted some of them a bit to run both on 1.8 and + 1.9. + * Introduced a `JSON.parse!` method without depth checking for people who + like danger. + * Made generate and `pretty_generate` methods configurable by an options hash. + * Added :allow_nan option to parser and generator in order to handle NaN, + Infinity, and -Infinity correctly - if requested. Floats, which aren't numbers, + aren't valid JSON according to RFC4627, so by default an exception will be + raised if any of these symbols are encountered. Thanks to Andrea Censi + for his hint about this. + * Fixed some more tests for Ruby 1.9. + * Implemented dump/load interface of Marshal as suggested in ruby-core:11405 + by murphy . + * Implemented the `max_nesting` feature for generate methods, too. + * Added some implementations for ruby core's custom objects for + serialisation/deserialisation purposes. + +## 2007-05-21 (1.1.0) + * Implemented max_nesting feature for parser to avoid stack overflows for + data from untrusted sources. If you trust the source, you can disable it + with the option max_nesting => false. + * Piers Cawley reported a bug, that not every + character can be escaped by `\` as required by RFC4627. There's a + contradiction between David Crockford's JSON checker test vectors (in + tests/fixtures) and RFC4627, though. I decided to stick to the RFC, because + the JSON checker seems to be a bit older than the RFC. + * Extended license to Ruby License, which includes the GPL. + * Added keyboard shortcuts, and 'Open location' menu item to edit_json.rb. + +## 2007-05-09 (1.0.4) + * Applied a patch from Yui NARUSE to make JSON compile + under Ruby 1.9. Thank you very much for mailing it to me! + * Made binary variants of JSON fail early, instead of falling back to the + pure version. This should avoid overshadowing of eventual problems while + loading of the binary. + +## 2007-03-24 (1.0.3) + * Improved performance of pure variant a bit. + * The ext variant of this release supports the mswin32 platform. Ugh! + +## 2007-03-24 (1.0.2) + * Ext Parser didn't parse 0e0 correctly into 0.0: Fixed! + +## 2007-03-24 (1.0.1) + * Forgot some object files in the build dir. I really like that - not! + +## 2007-03-24 (1.0.0) + * Added C implementations for the JSON generator and a ragel based JSON + parser in C. + * Much more tests, especially fixtures from json.org. + * Further improved conformance to RFC4627. + +## 2007-02-09 (0.4.3) + * Conform more to RFC4627 for JSON: This means JSON strings + now always must contain exactly one object `"{ ... }"` or array `"[ ... ]"` in + order to be parsed without raising an exception. The definition of what + constitutes a whitespace is narrower in JSON than in Ruby ([ \t\r\n]), and + there are differences in floats and integers (no octals or hexadecimals) as + well. + * Added aliases generate and `pretty_generate` of unparse and `pretty_unparse`. + * Fixed a test case. + * Catch an `Iconv::InvalidEncoding` exception, that seems to occur on some Sun + boxes with SunOS 5.8, if iconv doesn't support utf16 conversions. This was + reported by Andrew R Jackson , thanks a bunch! + +## 2006-08-25 (0.4.2) + * Fixed a bug in handling solidi (/-characters), that was reported by + Kevin Gilpin . + +## 2006-02-06 (0.4.1) + * Fixed a bug related to escaping with backslashes. Thanks for the report go + to Florian Munz . + +## 2005-09-23 (0.4.0) + * Initial Rubyforge Version diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/COPYING b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/COPYING new file mode 100644 index 0000000..426810a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/LEGAL b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/LEGAL new file mode 100644 index 0000000..3d3e093 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/LEGAL @@ -0,0 +1,20 @@ +# -*- rdoc -*- + += LEGAL NOTICE INFORMATION +-------------------------- + +All the files in this distribution are covered under either the Ruby's +license (see the file COPYING) or public-domain except some files +mentioned below. + +ext/json/ext/vendor/fpconv.h:: + This file is adapted from https://github.com/night-shift/fpconv + It is licensed under Boost Software License 1.0. + +ext/json/ext/vendor/jeaiii-ltoa.h:: + This file is adapted from https://github.com/jeaiii/itoa + It is licensed under the MIT License + +ext/json/ext/vendor/fast_float_parser.h:: + This file is adapted from the Fast Float C++ library by The fast_float authors https://github.com/fastfloat/fast_float + It is licensed under the MIT License diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/README.md b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/README.md new file mode 100644 index 0000000..5e6ffe4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/README.md @@ -0,0 +1,308 @@ +# JSON implementation for Ruby + +[![CI](https://github.com/ruby/json/actions/workflows/ci.yml/badge.svg)](https://github.com/ruby/json/actions/workflows/ci.yml) + +## Description + +This is an implementation of the JSON specification according to RFC 7159 +http://www.ietf.org/rfc/rfc7159.txt . + +The JSON generator generate UTF-8 character sequences by default. +If an :ascii\_only option with a true value is given, they escape all +non-ASCII and control characters with \uXXXX escape sequences, and support +UTF-16 surrogate pairs in order to be able to generate the whole range of +unicode code points. + +All strings, that are to be encoded as JSON strings, should be UTF-8 byte +sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8 +encoded, please use the to\_json\_raw\_object method of String (which produces +an object, that contains a byte array) and decode the result on the receiving +endpoint. + +## Installation + +Install the gem and add to the application's Gemfile by executing: + + $ bundle add json + +If bundler is not being used to manage dependencies, install the gem by executing: + + $ gem install json + +## Basic Usage + +To use JSON you can + +```ruby +require 'json' +``` + +Now you can parse a JSON document into a ruby data structure by calling + +```ruby +JSON.parse(document) +``` + +If you want to generate a JSON document from a ruby data structure call +```ruby +JSON.generate(data) +``` + +You can also use the `pretty_generate` method (which formats the output more +verbosely and nicely) or `fast_generate` (which doesn't do any of the security +checks generate performs, e. g. nesting deepness checks). + +## Casting non native types + +JSON documents can only support Hashes, Arrays, Strings, Integers and Floats. + +By default if you attempt to serialize something else, `JSON.generate` will +search for a `#to_json` method on that object: + +```ruby +Position = Struct.new(:latitude, :longitude) do + def to_json(state = nil, *) + JSON::State.from_state(state).generate({ + latitude: latitude, + longitude: longitude, + }) + end +end + +JSON.generate([ + Position.new(12323.234, 435345.233), + Position.new(23434.676, 159435.324), +]) # => [{"latitude":12323.234,"longitude":435345.233},{"latitude":23434.676,"longitude":159435.324}] +``` + +If a `#to_json` method isn't defined on the object, `JSON.generate` will fallback to call `#to_s`: + +```ruby +JSON.generate(Object.new) # => "#" +``` + +Both of these behavior can be disabled using the `strict: true` option: + +```ruby +JSON.generate(Object.new, strict: true) # => Object not allowed in JSON (JSON::GeneratorError) +JSON.generate(Position.new(1, 2), strict: true) # => Position not allowed in JSON (JSON::GeneratorError) +``` + +## JSON::Coder + +Since `#to_json` methods are global, it can sometimes be problematic if you need a given type to be +serialized in different ways in different locations. + +Instead it is recommended to use the newer `JSON::Coder` API: + +```ruby +module MyApp + API_JSON_CODER = JSON::Coder.new do |object, is_object_key| + case object + when Time + object.iso8601(3) + else + object + end + end +end + +puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z" +``` + +The provided block is called for all objects that don't have a native JSON equivalent, and +must return a Ruby object that has a native JSON equivalent. + +It is also called for objects that do have a JSON equivalent, but are used as Hash keys, for instance `{ 1 => 2}`, +as well as for strings that aren't valid UTF-8: + +```ruby +coder = JSON::Coder.new do |object, is_object_key| + case object + when String + if !object.valid_encoding? || object.encoding != Encoding::UTF_8 + Base64.encode64(object) + else + object + end + else + object + end +end +``` + +## Combining JSON fragments + +To combine JSON fragments into a bigger JSON document, you can use `JSON::Fragment`: + +```ruby +posts_json = cache.fetch_multi(post_ids) do |post_id| + JSON.generate(Post.find(post_id)) +end +posts_json.map! { |post_json| JSON::Fragment.new(post_json) } +JSON.generate({ posts: posts_json, count: posts_json.count }) +``` + +## Round-tripping arbitrary types + +> [!CAUTION] +> You should never use `JSON.unsafe_load` nor `JSON.parse(str, create_additions: true)` to parse untrusted user input, +> as it can lead to remote code execution vulnerabilities. + +To create a JSON document from a ruby data structure, you can call +`JSON.generate` like that: + +```ruby +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]" +``` + +To get back a ruby data structure from a JSON document, you have to call +JSON.parse on it: + +```ruby +JSON.parse json +# => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"] +``` + +Note, that the range from the original data structure is a simple +string now. The reason for this is, that JSON doesn't support ranges +or arbitrary classes. In this case the json library falls back to call +`Object#to_json`, which is the same as `#to_s.to_json`. + +It's possible to add JSON support serialization to arbitrary classes by +simply implementing a more specialized version of the `#to_json method`, that +should return a JSON object (a hash converted to JSON with `#to_json`) like +this (don't forget the `*a` for all the arguments): + +```ruby +class Range + def to_json(*a) + { + 'json_class' => self.class.name, # = 'Range' + 'data' => [ first, last, exclude_end? ] + }.to_json(*a) + end +end +``` + +The hash key `json_class` is the class, that will be asked to deserialise the +JSON representation later. In this case it's `Range`, but any namespace of +the form `A::B` or `::A::B` will do. All other keys are arbitrary and can be +used to store the necessary data to configure the object to be deserialised. + +If the key `json_class` is found in a JSON object, the JSON parser checks +if the given class responds to the `json_create` class method. If so, it is +called with the JSON object converted to a Ruby hash. So a range can +be deserialised by implementing `Range.json_create` like this: + +```ruby +class Range + def self.json_create(o) + new(*o['data']) + end +end +``` + +Now it possible to serialise/deserialise ranges as well: + +```ruby +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" +JSON.parse json +# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" +JSON.unsafe_load json +# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +``` + +`JSON.generate` always creates the shortest possible string representation of a +ruby data structure in one line. This is good for data storage or network +protocols, but not so good for humans to read. Fortunately there's also +`JSON.pretty_generate` (or `JSON.pretty_generate`) that creates a more readable +output: + +```ruby + puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10]) + [ + 1, + 2, + { + "a": 3.141 + }, + false, + true, + null, + { + "json_class": "Range", + "data": [ + 4, + 10, + false + ] + } + ] +``` + +There are also the methods `Kernel#j` for generate, and `Kernel#jj` for +`pretty_generate` output to the console, that work analogous to Core Ruby's `p` and +the `pp` library's `pp` methods. + +## Security + +When parsing or serializing untrusted input, parser and generator options should never be user controlled. + +```ruby +# Dangerous, DO NOT DO THIS. +JSON.generate(params[:data], params[:options]) +``` + +Security vulnerability reports relying on attacker controlled parsing or generator options will be handled as regular bug fixes. + +## Development + +### Prerequisites + +1. Clone the repository +2. Install dependencies with `bundle install` + +### Testing + +The full test suite can be run with: + +```bash +bundle exec rake test +``` + +### Release + +Update the `lib/json/version.rb` file. + +``` +rbenv shell 2.6.5 +rake build +gem push pkg/json-2.3.0.gem + +rbenv shell jruby-9.2.9.0 +rake build +gem push pkg/json-2.3.0-java.gem +``` + +## Author + +Florian Frank + +## License + +Ruby License, see https://www.ruby-lang.org/en/about/license.txt. + +## Download + +The latest version of this library can be downloaded at + +* https://rubygems.org/gems/json + +Online Documentation should be located at + +* https://www.rubydoc.info/gems/json diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/fbuffer/fbuffer.h b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/fbuffer/fbuffer.h new file mode 100644 index 0000000..cc44ea0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/fbuffer/fbuffer.h @@ -0,0 +1,259 @@ +#ifndef _FBUFFER_H_ +#define _FBUFFER_H_ + +#include "../json.h" +#include "../vendor/jeaiii-ltoa.h" + +enum fbuffer_type { + FBUFFER_HEAP_ALLOCATED = 0, + FBUFFER_STACK_ALLOCATED = 1, +}; + +typedef struct FBufferStruct { + enum fbuffer_type type; + size_t initial_length; + size_t len; + size_t capa; +#if JSON_DEBUG + size_t requested; +#endif + char *ptr; + VALUE io; +} FBuffer; + +#define FBUFFER_STACK_SIZE 512 +#define FBUFFER_IO_BUFFER_SIZE (16384 - 1) +#define FBUFFER_INITIAL_LENGTH_DEFAULT 1024 + +#define FBUFFER_PTR(fb) ((fb)->ptr) +#define FBUFFER_LEN(fb) ((fb)->len) +#define FBUFFER_CAPA(fb) ((fb)->capa) +#define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb) + +static void fbuffer_free(FBuffer *fb); +static void fbuffer_clear(FBuffer *fb); +static void fbuffer_append(FBuffer *fb, const char *newstr, size_t len); +static void fbuffer_append_long(FBuffer *fb, long number); +static inline void fbuffer_append_char(FBuffer *fb, char newchr); +static VALUE fbuffer_finalize(FBuffer *fb); + +static void fbuffer_init(FBuffer *fb, size_t initial_length, VALUE io, char *stack_buffer, size_t stack_buffer_size) +{ + if (RTEST(io)) { + JSON_ASSERT(fb->type == FBUFFER_HEAP_ALLOCATED); + fb->io = io; + fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_IO_BUFFER_SIZE; + } else { + fb->type = FBUFFER_STACK_ALLOCATED; + fb->ptr = stack_buffer; + fb->capa = stack_buffer_size; + fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT; + } +#if JSON_DEBUG + fb->requested = 0; +#endif +} + +static inline void fbuffer_consumed(FBuffer *fb, size_t consumed) +{ +#if JSON_DEBUG + if (consumed > fb->requested) { + rb_bug("fbuffer: Out of bound write"); + } + fb->requested = 0; +#endif + fb->len += consumed; +} + +static void fbuffer_free(FBuffer *fb) +{ + if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) { + JSON_SIZED_FREE_N(fb->ptr, fb->capa); + } +} + +static void fbuffer_clear(FBuffer *fb) +{ + fb->len = 0; +} + +static void fbuffer_flush(FBuffer *fb) +{ + rb_io_write(fb->io, rb_utf8_str_new(fb->ptr, fb->len)); + fbuffer_clear(fb); +} + +static void fbuffer_realloc(FBuffer *fb, size_t new_capa) +{ + if (new_capa > fb->capa) { + if (fb->type == FBUFFER_STACK_ALLOCATED) { + const char *old_buffer = fb->ptr; + fb->ptr = ALLOC_N(char, new_capa); + fb->type = FBUFFER_HEAP_ALLOCATED; + MEMCPY(fb->ptr, old_buffer, char, fb->len); + } else { + JSON_SIZED_REALLOC_N(fb->ptr, char, new_capa, fb->capa); + } + fb->capa = new_capa; + } +} + +static void fbuffer_do_inc_capa(FBuffer *fb, size_t requested) +{ + if (RB_UNLIKELY(fb->io)) { + if (fb->capa != 0) { + fbuffer_flush(fb); + if (RB_LIKELY(requested < fb->capa)) { + return; + } + } + } + + size_t new_capa = fb->capa ? fb->capa : fb->initial_length; + size_t needed_capa = requested + fb->len; + + while (new_capa < needed_capa) { + new_capa *= 2; + } + + fbuffer_realloc(fb, new_capa); +} + +static inline void fbuffer_inc_capa(FBuffer *fb, size_t requested) +{ +#if JSON_DEBUG + fb->requested = requested; +#endif + + if (RB_UNLIKELY(requested > fb->capa - fb->len)) { + fbuffer_do_inc_capa(fb, requested); + } +} + +static inline size_t fbuffer_size_mul_or_raise(size_t a, size_t b) +{ + size_t result = a * b; + if (RB_UNLIKELY(a != 0 && (result / a) != b)) { + rb_raise(rb_eArgError, "Buffer overflow, the resulting document is too large to be generated"); + } + return result; +} + +static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, size_t len) +{ + MEMCPY(fb->ptr + fb->len, newstr, char, len); + fbuffer_consumed(fb, len); +} + +static inline void fbuffer_append(FBuffer *fb, const char *newstr, size_t len) +{ + if (len > 0) { + fbuffer_inc_capa(fb, len); + fbuffer_append_reserved(fb, newstr, len); + } +} + +/* Appends a character into a buffer. The buffer needs to have sufficient capacity, via fbuffer_inc_capa(...). */ +static inline void fbuffer_append_reserved_char(FBuffer *fb, char chr) +{ +#if JSON_DEBUG + if (fb->requested < 1) { + rb_bug("fbuffer: unreserved write"); + } + fb->requested--; +#endif + + fb->ptr[fb->len] = chr; + fb->len++; +} + +static void fbuffer_append_str(FBuffer *fb, VALUE str) +{ + const char *ptr; + size_t len; + RSTRING_GETMEM(str, ptr, len); + + fbuffer_append(fb, ptr, len); + RB_GC_GUARD(str); +} + +static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat) +{ + const char *ptr; + size_t len; + RSTRING_GETMEM(str, ptr, len); + + fbuffer_inc_capa(fb, fbuffer_size_mul_or_raise(repeat, len)); + while (repeat) { +#if JSON_DEBUG + fb->requested = len; +#endif + fbuffer_append_reserved(fb, ptr, len); + repeat--; + } + RB_GC_GUARD(str); +} + +static inline void fbuffer_append_char(FBuffer *fb, char newchr) +{ + fbuffer_inc_capa(fb, 1); + *(fb->ptr + fb->len) = newchr; + fbuffer_consumed(fb, 1); +} + +static inline char *fbuffer_cursor(FBuffer *fb) +{ + return fb->ptr + fb->len; +} + +static inline void fbuffer_advance_to(FBuffer *fb, char *end) +{ + fbuffer_consumed(fb, (end - fb->ptr) - fb->len); +} + +/* + * Appends the decimal string representation of \a number into the buffer. + */ +static void fbuffer_append_long(FBuffer *fb, long number) +{ + /* + * The jeaiii_ultoa() function produces digits left-to-right, + * allowing us to write directly into the buffer, but we don't know + * the number of resulting characters. + * + * We do know, however, that the `number` argument is always in the + * range 0xc000000000000000 to 0x3fffffffffffffff, or, in decimal, + * -4611686018427387904 to 4611686018427387903. The max number of chars + * generated is therefore 20 (including a potential sign character). + */ + + static const int MAX_CHARS_FOR_LONG = 20; + + fbuffer_inc_capa(fb, MAX_CHARS_FOR_LONG); + + if (number < 0) { + fbuffer_append_reserved_char(fb, '-'); + + /* + * Since number is always > LONG_MIN, `-number` will not overflow + * and is always the positive abs() value. + */ + number = -number; + } + + char *end = jeaiii_ultoa(fbuffer_cursor(fb), number); + fbuffer_advance_to(fb, end); +} + +static VALUE fbuffer_finalize(FBuffer *fb) +{ + if (fb->io) { + fbuffer_flush(fb); + rb_io_flush(fb->io); + return fb->io; + } else { + return rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb)); + } +} + +#endif // _FBUFFER_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/Makefile b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/Makefile new file mode 100644 index 0000000..926cf71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /Users/ben/.rubies/ruby-3.4.1/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /Users/ben/.rubies/ruby-3.4.1/include/ruby-3.4.0/arm64-darwin24 +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/Users/ben/.rubies/ruby-3.4.1 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(SDKROOT)$(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = clang +CXX = clang++ -std=gnu++11 +LIBRUBY = $(LIBRUBY_A) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) -fdeclspec $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wextra-tokens -Wdeprecated-declarations -Wdivision-by-zero -Wdiv-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wold-style-definition -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fno-common +CFLAGS = $(CCDLFLAGS) $(cflags) -pipe $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_CONST_RUBY_TYPED_EMBEDDABLE -DJSON_GENERATOR -DHAVE_ARM_NEON_H -DJSON_ENABLE_SIMD -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/libyaml/include -I/opt/homebrew/opt/gdbm/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) -fdeclspec $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -L/opt/homebrew/Cellar/readline/8.2.13/lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -L/opt/homebrew/Cellar/gdbm/1.24/lib +dldflags = -L/opt/homebrew/Cellar/readline/8.2.13/lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -L/opt/homebrew/Cellar/gdbm/1.24/lib -Wl,-undefined,dynamic_lookup -bundle_loader '$(BUILTRUBY)' +ARCH_FLAG = -arch arm64 +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -dynamic -bundle +LDSHAREDXX = $(CXX) -dynamic -bundle +POSTLINK = dsymutil $@ 2>/dev/null; { test -z '$(RUBY_CODESIGN)' || codesign -s '$(RUBY_CODESIGN)' $@; } +AR = ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby.3.4 +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = arm64-darwin24 +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir -p +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) /opt/homebrew/opt/readline/lib /opt/homebrew/opt/libyaml/lib /opt/homebrew/opt/gdbm/lib +LIBPATH = -L. -L$(libdir) -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/libyaml/lib -L/opt/homebrew/opt/gdbm/lib +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /json/ext +LOCAL_LIBS = +LIBS = -lpthread +ORIG_SRCS = generator.c +SRCS = $(ORIG_SRCS) +OBJS = generator.o +HDRS = +LOCAL_HDRS = +TARGET = generator +TARGET_NAME = generator +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).bundle +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) $(TARGET_SO:=.dSYM) +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.json.-.ext.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object json/ext/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/extconf.rb new file mode 100644 index 0000000..33af03e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/extconf.rb @@ -0,0 +1,19 @@ +require 'mkmf' + +if RUBY_ENGINE == 'truffleruby' + # The pure-Ruby generator is faster on TruffleRuby, so skip compiling the generator extension + File.write('Makefile', dummy_makefile("").join) +else + append_cflags("-std=c99") + have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3 + have_func("ruby_xfree_sized", "ruby.h") # RUBY_VERSION >= 4.1 + + $defs << "-DJSON_GENERATOR" + $defs << "-DJSON_DEBUG" if ENV.fetch("JSON_DEBUG", "0") != "0" + + if enable_config('generator-use-simd', default=!ENV["JSON_DISABLE_SIMD"]) + load __dir__ + "/../simd/conf.rb" + end + + create_makefile 'json/ext/generator' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/generator.c b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/generator.c new file mode 100644 index 0000000..6f47332 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/generator/generator.c @@ -0,0 +1,2066 @@ +#include "../json.h" +#include "../fbuffer/fbuffer.h" +#include "../vendor/fpconv.c" + +#include +#include + +#include "../simd/simd.h" + +/* ruby api and some helpers */ + +enum duplicate_key_action { + JSON_DEPRECATED = 0, + JSON_IGNORE, + JSON_RAISE, +}; + +typedef struct JSON_Generator_StateStruct { + VALUE indent; + VALUE space; + VALUE space_before; + VALUE object_nl; + VALUE array_nl; + VALUE as_json; + + long max_nesting; + long depth; + long buffer_initial_length; + + enum duplicate_key_action on_duplicate_key; + + bool as_json_single_arg; + bool allow_nan; + bool ascii_only; + bool script_safe; + bool strict; + VALUE sort_keys; +} JSON_Generator_State; + +static VALUE mJSON, cState, cFragment, eGeneratorError, eNestingError, Encoding_UTF_8, default_sort_keys_proc; + +static ID i_to_s, i_to_json, i_new, i_encode; +static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan, sym_allow_duplicate_key, + sym_ascii_only, sym_depth, sym_buffer_initial_length, sym_script_safe, sym_escape_slash, sym_strict, sym_as_json, sym_sort_keys; + + +#define GET_STATE_TO(self, state) \ + TypedData_Get_Struct(self, JSON_Generator_State, &JSON_Generator_State_type, state) + +#define GET_STATE(self) \ + JSON_Generator_State *state; \ + GET_STATE_TO(self, state) + +struct generate_json_data; + +typedef void (*generator_func)(FBuffer *buffer, struct generate_json_data *data, VALUE obj); + +struct generate_json_data { + FBuffer *buffer; + VALUE vstate; + JSON_Generator_State *state; + VALUE obj; + generator_func func; + long depth; +}; + +static SIMD_Implementation simd_impl; + +static VALUE cState_from_state_s(VALUE self, VALUE opts); +static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func, VALUE io); +static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_object(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_array(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, VALUE obj); + +static int usascii_encindex, utf8_encindex, binary_encindex; + +NORETURN(static void) raise_generator_error_str(VALUE invalid_object, VALUE str) +{ + rb_enc_associate_index(str, utf8_encindex); + VALUE exc = rb_exc_new_str(eGeneratorError, str); + rb_ivar_set(exc, rb_intern("@invalid_object"), invalid_object); + rb_exc_raise(exc); +} + +#ifdef RBIMPL_ATTR_FORMAT +RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3) +#endif +NORETURN(static void) raise_generator_error(VALUE invalid_object, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + VALUE str = rb_vsprintf(fmt, args); + va_end(args); + raise_generator_error_str(invalid_object, str); +} + +// 0 - single byte char that don't need to be escaped. +// (x | 8) - char that needs to be escaped. +static const unsigned char CHAR_LENGTH_MASK = 7; +static const unsigned char ESCAPE_MASK = 8; + +typedef struct _search_state { + const char *ptr; + const char *end; + const char *cursor; + FBuffer *buffer; + +#ifdef HAVE_SIMD + const char *chunk_base; + const char *chunk_end; + bool has_matches; + +#if defined(HAVE_SIMD_NEON) + uint64_t matches_mask; +#elif defined(HAVE_SIMD_SSE2) + int matches_mask; +#else +#error "Unknown SIMD Implementation." +#endif /* HAVE_SIMD_NEON */ +#endif /* HAVE_SIMD */ +} search_state; + +ALWAYS_INLINE(static) void search_flush(search_state *search) +{ + // Do not remove this conditional without profiling, specifically escape-heavy text. + // escape_UTF8_char_basic will advance search->ptr and search->cursor (effectively a search_flush). + // For back-to-back characters that need to be escaped, specifically for the SIMD code paths, this method + // will be called just before calling escape_UTF8_char_basic. There will be no characters to append for the + // consecutive characters that need to be escaped. While the fbuffer_append is a no-op if + // nothing needs to be flushed, we can save a few memory references with this conditional. + if (search->ptr > search->cursor) { + fbuffer_append(search->buffer, search->cursor, search->ptr - search->cursor); + search->cursor = search->ptr; + } +} + +static const unsigned char escape_table_basic[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static inline unsigned char search_escape_basic(search_state *search) +{ + while (search->ptr < search->end) { + if (RB_UNLIKELY(escape_table_basic[(const unsigned char)*search->ptr])) { + search_flush(search); + return 1; + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +ALWAYS_INLINE(static) void escape_UTF8_char_basic(search_state *search) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + search->ptr++; + search->cursor = search->ptr; +} + +/* Converts in_string to a JSON string (without the wrapping '"' + * characters) in FBuffer out_buffer. + * + * Character are JSON-escaped according to: + * + * - Always: ASCII control characters (0x00-0x1F), dquote, and + * backslash. + * + * - If out_ascii_only: non-ASCII characters (>0x7F) + * + * - If script_safe: forwardslash (/), line separator (U+2028), and + * paragraph separator (U+2029) + * + * Everything else (should be UTF-8) is just passed through and + * appended to the result. + */ + + +#if defined(HAVE_SIMD_NEON) +static inline unsigned char search_escape_basic_neon(search_state *search); +#elif defined(HAVE_SIMD_SSE2) +static inline unsigned char search_escape_basic_sse2(search_state *search); +#endif + +static inline unsigned char search_escape_basic(search_state *search); + +static inline void convert_UTF8_to_JSON(search_state *search) +{ +#ifdef HAVE_SIMD +#if defined(HAVE_SIMD_NEON) + while (search_escape_basic_neon(search)) { + escape_UTF8_char_basic(search); + } +#elif defined(HAVE_SIMD_SSE2) + if (simd_impl == SIMD_SSE2) { + while (search_escape_basic_sse2(search)) { + escape_UTF8_char_basic(search); + } + return; + } + while (search_escape_basic(search)) { + escape_UTF8_char_basic(search); + } +#endif +#else + while (search_escape_basic(search)) { + escape_UTF8_char_basic(search); + } +#endif /* HAVE_SIMD */ +} + +static inline void escape_UTF8_char(search_state *search, unsigned char ch_len) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch_len) { + case 1: { + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + break; + } + case 3: { + if (search->ptr[2] & 1) { + fbuffer_append(search->buffer, "\\u2029", 6); + } else { + fbuffer_append(search->buffer, "\\u2028", 6); + } + break; + } + } + search->cursor = (search->ptr += ch_len); +} + +#ifdef HAVE_SIMD + +ALWAYS_INLINE(static) char *copy_remaining_bytes(search_state *search, unsigned long vec_len, unsigned long len) +{ + RBIMPL_ASSERT_OR_ASSUME(len < vec_len); + + // Flush the buffer so everything up until the last 'len' characters are unflushed. + search_flush(search); + + FBuffer *buf = search->buffer; + fbuffer_inc_capa(buf, vec_len); + + char *s = (buf->ptr + buf->len); + + // Pad the buffer with dummy characters that won't need escaping. + // This seem wasteful at first sight, but memset of vector length is very fast. + // This is a space as it can be directly represented as an immediate on AArch64. + memset(s, ' ', vec_len); + + // Optimistically copy the remaining 'len' characters to the output FBuffer. If there are no characters + // to escape, then everything ends up in the correct spot. Otherwise it was convenient temporary storage. + if (vec_len == 16) { + RBIMPL_ASSERT_OR_ASSUME(len >= SIMD_MINIMUM_THRESHOLD); + json_fast_memcpy16(s, search->ptr, len); + } else { + MEMCPY(s, search->ptr, char, len); + } + + return s; +} + +#ifdef HAVE_SIMD_NEON + +ALWAYS_INLINE(static) unsigned char neon_next_match(search_state *search) +{ + uint64_t mask = search->matches_mask; + uint32_t index = trailing_zeros64(mask) >> 2; + + // It is assumed escape_UTF8_char_basic will only ever increase search->ptr by at most one character. + // If we want to use a similar approach for full escaping we'll need to ensure: + // search->chunk_base + index >= search->ptr + // However, since we know escape_UTF8_char_basic only increases search->ptr by one, if the next match + // is one byte after the previous match then: + // search->chunk_base + index == search->ptr + search->ptr = search->chunk_base + index; + mask &= mask - 1; + search->matches_mask = mask; + search_flush(search); + return 1; +} + +static inline unsigned char search_escape_basic_neon(search_state *search) +{ + if (RB_UNLIKELY(search->has_matches)) { + // There are more matches if search->matches_mask > 0. + if (search->matches_mask > 0) { + return neon_next_match(search); + } else { + // neon_next_match will only advance search->ptr up to the last matching character. + // Skip over any characters in the last chunk that occur after the last match. + search->has_matches = false; + search->ptr = search->chunk_end; + } + } + + /* + * The code below implements an SIMD-based algorithm to determine if N bytes at a time + * need to be escaped. + * + * Assume the ptr = "Te\sting!" (the double quotes are included in the string) + * + * The explanation will be limited to the first 8 bytes of the string for simplicity. However + * the vector insructions may work on larger vectors. + * + * First, we load three constants 'lower_bound', 'backslash' and 'dblquote" in vector registers. + * + * lower_bound: [20 20 20 20 20 20 20 20] + * backslash: [5C 5C 5C 5C 5C 5C 5C 5C] + * dblquote: [22 22 22 22 22 22 22 22] + * + * Next we load the first chunk of the ptr: + * [22 54 65 5C 73 74 69 6E] (" T e \ s t i n) + * + * First we check if any byte in chunk is less than 32 (0x20). This returns the following vector + * as no bytes are less than 32 (0x20): + * [0 0 0 0 0 0 0 0] + * + * Next, we check if any byte in chunk is equal to a backslash: + * [0 0 0 FF 0 0 0 0] + * + * Finally we check if any byte in chunk is equal to a double quote: + * [FF 0 0 0 0 0 0 0] + * + * Now we have three vectors where each byte indicates if the corresponding byte in chunk + * needs to be escaped. We combine these vectors with a series of logical OR instructions. + * This is the needs_escape vector and it is equal to: + * [FF 0 0 FF 0 0 0 0] + * + * Next we compute the bitwise AND between each byte and 0x1 and compute the horizontal sum of + * the values in the vector. This computes how many bytes need to be escaped within this chunk. + * + * Finally we compute a mask that indicates which bytes need to be escaped. If the mask is 0 then, + * no bytes need to be escaped and we can continue to the next chunk. If the mask is not 0 then we + * have at least one byte that needs to be escaped. + */ + + if (string_scan_simd_neon(&search->ptr, search->end, &search->matches_mask)) { + search->has_matches = true; + search->chunk_base = search->ptr; + search->chunk_end = search->ptr + sizeof(uint8x16_t); + return neon_next_match(search); + } + + // There are fewer than 16 bytes left. + unsigned long remaining = (search->end - search->ptr); + if (remaining >= SIMD_MINIMUM_THRESHOLD) { + char *s = copy_remaining_bytes(search, sizeof(uint8x16_t), remaining); + + uint64_t mask = compute_chunk_mask_neon(s); + + if (!mask) { + // Nothing to escape, ensure search_flush doesn't do anything by setting + // search->cursor to search->ptr. + fbuffer_consumed(search->buffer, remaining); + search->ptr = search->end; + search->cursor = search->end; + return 0; + } + + search->matches_mask = mask; + search->has_matches = true; + search->chunk_end = search->end; + search->chunk_base = search->ptr; + return neon_next_match(search); + } + + if (search->ptr < search->end) { + return search_escape_basic(search); + } + + search_flush(search); + return 0; +} +#endif /* HAVE_SIMD_NEON */ + +#ifdef HAVE_SIMD_SSE2 + +ALWAYS_INLINE(static) unsigned char sse2_next_match(search_state *search) +{ + int mask = search->matches_mask; + int index = trailing_zeros(mask); + + // It is assumed escape_UTF8_char_basic will only ever increase search->ptr by at most one character. + // If we want to use a similar approach for full escaping we'll need to ensure: + // search->chunk_base + index >= search->ptr + // However, since we know escape_UTF8_char_basic only increases search->ptr by one, if the next match + // is one byte after the previous match then: + // search->chunk_base + index == search->ptr + search->ptr = search->chunk_base + index; + mask &= mask - 1; + search->matches_mask = mask; + search_flush(search); + return 1; +} + +#if defined(__clang__) || defined(__GNUC__) +#define TARGET_SSE2 __attribute__((target("sse2"))) +#else +#define TARGET_SSE2 +#endif + +ALWAYS_INLINE(static) TARGET_SSE2 unsigned char search_escape_basic_sse2(search_state *search) +{ + if (RB_UNLIKELY(search->has_matches)) { + // There are more matches if search->matches_mask > 0. + if (search->matches_mask > 0) { + return sse2_next_match(search); + } else { + // sse2_next_match will only advance search->ptr up to the last matching character. + // Skip over any characters in the last chunk that occur after the last match. + search->has_matches = false; + if (RB_UNLIKELY(search->chunk_base + sizeof(__m128i) >= search->end)) { + search->ptr = search->end; + } else { + search->ptr = search->chunk_base + sizeof(__m128i); + } + } + } + + if (string_scan_simd_sse2(&search->ptr, search->end, &search->matches_mask)) { + search->has_matches = true; + search->chunk_base = search->ptr; + search->chunk_end = search->ptr + sizeof(__m128i); + return sse2_next_match(search); + } + + // There are fewer than 16 bytes left. + unsigned long remaining = (search->end - search->ptr); + if (remaining >= SIMD_MINIMUM_THRESHOLD) { + char *s = copy_remaining_bytes(search, sizeof(__m128i), remaining); + + int needs_escape_mask = compute_chunk_mask_sse2(s); + + if (needs_escape_mask == 0) { + // Nothing to escape, ensure search_flush doesn't do anything by setting + // search->cursor to search->ptr. + fbuffer_consumed(search->buffer, remaining); + search->ptr = search->end; + search->cursor = search->end; + return 0; + } + + search->has_matches = true; + search->matches_mask = needs_escape_mask; + search->chunk_base = search->ptr; + return sse2_next_match(search); + } + + if (search->ptr < search->end) { + return search_escape_basic(search); + } + + search_flush(search); + return 0; +} + +#endif /* HAVE_SIMD_SSE2 */ + +#endif /* HAVE_SIMD */ + +static const unsigned char script_safe_escape_table[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, // '"' and '/' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // Continuation byte + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // First byte of a 2-byte code point + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + // First byte of a 3-byte code point + 3, 3,11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xE2 is the start of \u2028 and \u2029 + //First byte of a 4+ byte code point + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9, +}; + +static inline unsigned char search_script_safe_escape(search_state *search) +{ + while (search->ptr < search->end) { + unsigned char ch = (unsigned char)*search->ptr; + unsigned char ch_len = script_safe_escape_table[ch]; + + if (RB_UNLIKELY(ch_len)) { + if (ch_len & ESCAPE_MASK) { + if (RB_UNLIKELY(ch_len == 11)) { + const unsigned char *uptr = (const unsigned char *)search->ptr; + if (!(uptr[1] == 0x80 && (uptr[2] >> 1) == 0x54)) { + search->ptr += 3; + continue; + } + } + search_flush(search); + return ch_len & CHAR_LENGTH_MASK; + } else { + search->ptr += ch_len; + } + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +static void convert_UTF8_to_script_safe_JSON(search_state *search) +{ + unsigned char ch_len; + while ((ch_len = search_script_safe_escape(search))) { + escape_UTF8_char(search, ch_len); + } +} + +static const unsigned char ascii_only_escape_table[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // Continuation byte + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // First byte of a 2-byte code point + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + // First byte of a 3-byte code point + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + //First byte of a 4+ byte code point + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9, +}; + +static inline unsigned char search_ascii_only_escape(search_state *search, const unsigned char escape_table[256]) +{ + while (search->ptr < search->end) { + unsigned char ch = (unsigned char)*search->ptr; + unsigned char ch_len = escape_table[ch]; + + if (RB_UNLIKELY(ch_len)) { + search_flush(search); + return ch_len & CHAR_LENGTH_MASK; + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +static inline void full_escape_UTF8_char(search_state *search, unsigned char ch_len) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch_len) { + case 1: { + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + break; + } + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[12] = { '\\', 'u', 0, 0, 0, 0, '\\', 'u' }; + + uint32_t wchar = 0; + + switch (ch_len) { + case 2: + wchar = ch & 0x1F; + break; + case 3: + wchar = ch & 0x0F; + break; + case 4: + wchar = ch & 0x07; + break; + } + + for (short i = 1; i < ch_len; i++) { + wchar = (wchar << 6) | (search->ptr[i] & 0x3F); + } + + if (wchar <= 0xFFFF) { + scratch[2] = hexdig[wchar >> 12]; + scratch[3] = hexdig[(wchar >> 8) & 0xf]; + scratch[4] = hexdig[(wchar >> 4) & 0xf]; + scratch[5] = hexdig[wchar & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + } else { + uint16_t hi, lo; + wchar -= 0x10000; + hi = 0xD800 + (uint16_t)(wchar >> 10); + lo = 0xDC00 + (uint16_t)(wchar & 0x3FF); + + scratch[2] = hexdig[hi >> 12]; + scratch[3] = hexdig[(hi >> 8) & 0xf]; + scratch[4] = hexdig[(hi >> 4) & 0xf]; + scratch[5] = hexdig[hi & 0xf]; + + scratch[8] = hexdig[lo >> 12]; + scratch[9] = hexdig[(lo >> 8) & 0xf]; + scratch[10] = hexdig[(lo >> 4) & 0xf]; + scratch[11] = hexdig[lo & 0xf]; + + fbuffer_append(search->buffer, scratch, 12); + } + + break; + } + } + search->cursor = (search->ptr += ch_len); +} + +static void convert_UTF8_to_ASCII_only_JSON(search_state *search, const unsigned char escape_table[256]) +{ + unsigned char ch_len; + while ((ch_len = search_ascii_only_escape(search, escape_table))) { + full_escape_UTF8_char(search, ch_len); + } +} + +static void State_mark(void *ptr) +{ + JSON_Generator_State *state = ptr; + rb_gc_mark_movable(state->indent); + rb_gc_mark_movable(state->space); + rb_gc_mark_movable(state->space_before); + rb_gc_mark_movable(state->object_nl); + rb_gc_mark_movable(state->array_nl); + rb_gc_mark_movable(state->as_json); + rb_gc_mark_movable(state->sort_keys); +} + +static void State_compact(void *ptr) +{ + JSON_Generator_State *state = ptr; + state->indent = rb_gc_location(state->indent); + state->space = rb_gc_location(state->space); + state->space_before = rb_gc_location(state->space_before); + state->object_nl = rb_gc_location(state->object_nl); + state->array_nl = rb_gc_location(state->array_nl); + state->as_json = rb_gc_location(state->as_json); + state->sort_keys = rb_gc_location(state->sort_keys); +} + +static size_t State_memsize(const void *ptr) +{ +#ifdef HAVE_RUBY_TYPED_EMBEDDABLE + return 0; +#else + return sizeof(JSON_Generator_State); +#endif +} + +static const rb_data_type_t JSON_Generator_State_type = { + .wrap_struct_name = "JSON/Generator/State", + .function = { + .dmark = State_mark, + .dfree = RUBY_DEFAULT_FREE, + .dsize = State_memsize, + .dcompact = State_compact, + }, + .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE, +}; + +static void state_init(JSON_Generator_State *state) +{ + state->max_nesting = 100; + state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; +} + +static VALUE cState_s_allocate(VALUE klass) +{ + JSON_Generator_State *state; + VALUE obj = TypedData_Make_Struct(klass, JSON_Generator_State, &JSON_Generator_State_type, state); + state_init(state); + return obj; +} + +static void vstate_spill(struct generate_json_data *data) +{ + VALUE vstate = cState_s_allocate(cState); + GET_STATE(vstate); + MEMCPY(state, data->state, JSON_Generator_State, 1); + data->state = state; + data->vstate = vstate; + RB_OBJ_WRITTEN(vstate, Qundef, state->indent); + RB_OBJ_WRITTEN(vstate, Qundef, state->space); + RB_OBJ_WRITTEN(vstate, Qundef, state->space_before); + RB_OBJ_WRITTEN(vstate, Qundef, state->object_nl); + RB_OBJ_WRITTEN(vstate, Qundef, state->array_nl); + RB_OBJ_WRITTEN(vstate, Qundef, state->as_json); + RB_OBJ_WRITTEN(vstate, Qundef, state->sort_keys); +} + +static inline VALUE json_call_to_json(struct generate_json_data *data, VALUE obj) +{ + if (RB_UNLIKELY(!data->vstate)) { + vstate_spill(data); + } + GET_STATE(data->vstate); + state->depth = data->depth; + VALUE tmp = rb_funcall(obj, i_to_json, 1, data->vstate); + // no need to restore state->depth, vstate is just a temporary State + return tmp; +} + +static VALUE +json_call_as_json(JSON_Generator_State *state, VALUE object, VALUE is_key) +{ + VALUE proc_args[2] = {object, is_key}; + return rb_proc_call_with_block(state->as_json, 2, proc_args, Qnil); +} + +static VALUE +convert_string_subclass(VALUE key) +{ + VALUE key_to_s = rb_funcall(key, i_to_s, 0); + + if (RB_UNLIKELY(!RB_TYPE_P(key_to_s, T_STRING))) { + VALUE cname = rb_obj_class(key); + rb_raise(rb_eTypeError, + "can't convert %"PRIsVALUE" to %s (%"PRIsVALUE"#%s gives %"PRIsVALUE")", + cname, "String", cname, "to_s", rb_obj_class(key_to_s)); + } + + return key_to_s; +} + +static bool enc_utf8_compatible_p(int enc_idx) +{ + if (enc_idx == usascii_encindex) return true; + if (enc_idx == utf8_encindex) return true; + return false; +} + +static VALUE encode_json_string_try(VALUE str) +{ + return rb_funcall(str, i_encode, 1, Encoding_UTF_8); +} + +static VALUE encode_json_string_rescue(VALUE str, VALUE exception) +{ + raise_generator_error_str(str, rb_funcall(exception, rb_intern("message"), 0)); + return Qundef; +} + +static inline int json_str_coderange(VALUE str) { + int coderange = RB_ENC_CODERANGE(str); + if (coderange == RUBY_ENC_CODERANGE_UNKNOWN) { + coderange = rb_enc_str_coderange(str); + } + return coderange; +} + +static inline bool valid_json_string_p(VALUE str) +{ + int coderange = json_str_coderange(str); + + if (RB_LIKELY(coderange == ENC_CODERANGE_7BIT)) { + return true; + } + + if (RB_LIKELY(coderange == ENC_CODERANGE_VALID)) { + return enc_utf8_compatible_p(RB_ENCODING_GET_INLINED(str)); + } + + return false; +} + +NOINLINE(static) VALUE convert_invalid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key) +{ + if (!as_json_called && data->state->strict && RTEST(data->state->as_json)) { + VALUE coerced_str = json_call_as_json(data->state, str, Qfalse); + if (coerced_str != str) { + if (RB_TYPE_P(coerced_str, T_STRING)) { + if (!valid_json_string_p(coerced_str)) { + raise_generator_error(str, "source sequence is illegal/malformed utf-8"); + } + } else { + // as_json could return another type than T_STRING + if (is_key) { + raise_generator_error(coerced_str, "%"PRIsVALUE" not allowed as object key in JSON", CLASS_OF(coerced_str)); + } + } + + return coerced_str; + } + } + + if (RB_ENCODING_GET_INLINED(str) == binary_encindex) { + VALUE utf8_string = rb_enc_associate_index(rb_str_dup(str), utf8_encindex); + switch (rb_enc_str_coderange(utf8_string)) { + case ENC_CODERANGE_7BIT: + return utf8_string; + case ENC_CODERANGE_VALID: + // For historical reason, we silently reinterpret binary strings as UTF-8 if it would work. + // TODO: Raise in 3.0.0 + rb_warn("JSON.generate: UTF-8 string passed as BINARY, this will raise an encoding error in json 3.0"); + return utf8_string; + break; + } + } + + return rb_rescue(encode_json_string_try, str, encode_json_string_rescue, str); +} + +ALWAYS_INLINE(static) VALUE ensure_valid_encoding(struct generate_json_data *data, VALUE str, bool as_json_called, bool is_key) +{ + if (RB_LIKELY(valid_json_string_p(str))) { + return str; + } + else { + return convert_invalid_encoding(data, str, as_json_called, is_key); + } +} + +static void raw_generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append_char(buffer, '"'); + + long len; + search_state search; + search.buffer = buffer; + RSTRING_GETMEM(obj, search.ptr, len); + search.cursor = search.ptr; + search.end = search.ptr + len; + +#ifdef HAVE_SIMD + search.matches_mask = 0; + search.has_matches = false; + search.chunk_base = NULL; + search.chunk_end = NULL; +#endif /* HAVE_SIMD */ + + switch (json_str_coderange(obj)) { + case ENC_CODERANGE_7BIT: + case ENC_CODERANGE_VALID: + if (RB_UNLIKELY(data->state->ascii_only)) { + convert_UTF8_to_ASCII_only_JSON(&search, data->state->script_safe ? script_safe_escape_table : ascii_only_escape_table); + } else if (RB_UNLIKELY(data->state->script_safe)) { + convert_UTF8_to_script_safe_JSON(&search); + } else { + convert_UTF8_to_JSON(&search); + } + break; + default: + raise_generator_error(obj, "source sequence is illegal/malformed utf-8"); + break; + } + fbuffer_append_char(buffer, '"'); +} + +static void generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + obj = ensure_valid_encoding(data, obj, false, false); + raw_generate_json_string(buffer, data, obj); +} + +struct hash_foreach_arg { + VALUE hash; + struct generate_json_data *data; + int first_key_type; + bool first; + bool mixed_keys_encountered; +}; + +NOINLINE(static) void +json_inspect_hash_with_mixed_keys(struct hash_foreach_arg *arg) +{ + if (arg->mixed_keys_encountered) { + return; + } + arg->mixed_keys_encountered = true; + + JSON_Generator_State *state = arg->data->state; + if (state->on_duplicate_key != JSON_IGNORE) { + VALUE do_raise = state->on_duplicate_key == JSON_RAISE ? Qtrue : Qfalse; + rb_funcall(mJSON, rb_intern("on_mixed_keys_hash"), 2, arg->hash, do_raise); + } +} + +static int +json_object_i(VALUE key, VALUE val, VALUE _arg) +{ + struct hash_foreach_arg *arg = (struct hash_foreach_arg *)_arg; + struct generate_json_data *data = arg->data; + + FBuffer *buffer = data->buffer; + JSON_Generator_State *state = data->state; + + long depth = data->depth; + int key_type = rb_type(key); + + if (arg->first) { + arg->first = false; + arg->first_key_type = key_type; + } + else { + fbuffer_append_char(buffer, ','); + } + + if (RB_UNLIKELY(data->state->object_nl)) { + fbuffer_append_str(buffer, data->state->object_nl); + } + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); + } + + VALUE key_to_s; + bool as_json_called = false; + + start: + switch (key_type) { + case T_STRING: + if (RB_UNLIKELY(arg->first_key_type != T_STRING)) { + json_inspect_hash_with_mixed_keys(arg); + } + + if (RB_LIKELY(RBASIC_CLASS(key) == rb_cString)) { + key_to_s = key; + } else { + key_to_s = convert_string_subclass(key); + } + break; + case T_SYMBOL: + if (RB_UNLIKELY(arg->first_key_type != T_SYMBOL)) { + json_inspect_hash_with_mixed_keys(arg); + } + + key_to_s = rb_sym2str(key); + break; + default: + if (data->state->strict) { + if (RTEST(data->state->as_json) && !as_json_called) { + key = json_call_as_json(data->state, key, Qtrue); + key_type = rb_type(key); + as_json_called = true; + goto start; + } else { + raise_generator_error(key, "%"PRIsVALUE" not allowed as object key in JSON", CLASS_OF(key)); + } + } + key_to_s = rb_convert_type(key, T_STRING, "String", "to_s"); + break; + } + + key_to_s = ensure_valid_encoding(data, key_to_s, as_json_called, true); + + if (RB_LIKELY(RBASIC_CLASS(key_to_s) == rb_cString)) { + raw_generate_json_string(buffer, data, key_to_s); + } else { + generate_json(buffer, data, key_to_s); + } + if (RB_UNLIKELY(state->space_before)) fbuffer_append_str(buffer, data->state->space_before); + fbuffer_append_char(buffer, ':'); + if (RB_UNLIKELY(state->space)) fbuffer_append_str(buffer, data->state->space); + generate_json(buffer, data, val); + + return ST_CONTINUE; +} + +static inline long increase_depth(struct generate_json_data *data) +{ + JSON_Generator_State *state = data->state; + long depth = ++data->depth; + if (RB_UNLIKELY(depth > state->max_nesting && state->max_nesting)) { + rb_raise(eNestingError, "nesting of %ld is too deep. Did you try to serialize objects with circular references?", --data->depth); + } + return depth; +} + +static void generate_json_object(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + if (RB_UNLIKELY(data->state->sort_keys)) { + obj = rb_proc_call_with_block(data->state->sort_keys, 1, &obj, Qnil); + Check_Type(obj, T_HASH); + } + + long depth = increase_depth(data); + + if (RHASH_SIZE(obj) == 0) { + fbuffer_append(buffer, "{}", 2); + --data->depth; + return; + } + + fbuffer_append_char(buffer, '{'); + + struct hash_foreach_arg arg = { + .hash = obj, + .data = data, + .first = true, + }; + rb_hash_foreach(obj, json_object_i, (VALUE)&arg); + + depth = --data->depth; + if (RB_UNLIKELY(data->state->object_nl)) { + fbuffer_append_str(buffer, data->state->object_nl); + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); + } + } + fbuffer_append_char(buffer, '}'); +} + +static void generate_json_array(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + long depth = increase_depth(data); + + if (RARRAY_LEN(obj) == 0) { + fbuffer_append(buffer, "[]", 2); + --data->depth; + return; + } + + fbuffer_append_char(buffer, '['); + if (RB_UNLIKELY(data->state->array_nl)) fbuffer_append_str(buffer, data->state->array_nl); + for (int i = 0; i < RARRAY_LEN(obj); i++) { + if (i > 0) { + fbuffer_append_char(buffer, ','); + if (RB_UNLIKELY(data->state->array_nl)) fbuffer_append_str(buffer, data->state->array_nl); + } + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); + } + generate_json(buffer, data, RARRAY_AREF(obj, i)); + } + data->depth = --depth; + if (RB_UNLIKELY(data->state->array_nl)) { + fbuffer_append_str(buffer, data->state->array_nl); + if (RB_UNLIKELY(data->state->indent)) { + fbuffer_append_str_repeat(buffer, data->state->indent, depth); + } + } + fbuffer_append_char(buffer, ']'); +} + +static void generate_json_fallback(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + VALUE tmp; + if (rb_respond_to(obj, i_to_json)) { + tmp = json_call_to_json(data, obj); + Check_Type(tmp, T_STRING); + fbuffer_append_str(buffer, tmp); + } else { + tmp = rb_funcall(obj, i_to_s, 0); + Check_Type(tmp, T_STRING); + generate_json_string(buffer, data, tmp); + } +} + +static inline void generate_json_symbol(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + if (data->state->strict) { + generate_json_string(buffer, data, rb_sym2str(obj)); + } else { + generate_json_fallback(buffer, data, obj); + } +} + +static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append(buffer, "null", 4); +} + +static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append(buffer, "false", 5); +} + +static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append(buffer, "true", 4); +} + +static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append_long(buffer, FIX2LONG(obj)); +} + +static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + VALUE tmp = rb_funcall(obj, i_to_s, 0); + fbuffer_append_str(buffer, StringValue(tmp)); +} + +static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + double value = RFLOAT_VALUE(obj); + char allow_nan = data->state->allow_nan; + if (isinf(value) || isnan(value)) { + /* for NaN and Infinity values we either raise an error or rely on Float#to_s. */ + if (!allow_nan) { + if (data->state->strict && data->state->as_json) { + VALUE casted_obj = json_call_as_json(data->state, obj, Qfalse); + if (casted_obj != obj) { + increase_depth(data); + generate_json(buffer, data, casted_obj); + data->depth--; + return; + } + } + raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", rb_funcall(obj, i_to_s, 0)); + } + + VALUE tmp = rb_funcall(obj, i_to_s, 0); + fbuffer_append_str(buffer, tmp); + return; + } + + /* This implementation writes directly into the buffer. We reserve + * the 32 characters that fpconv_dtoa states as its maximum. + */ + fbuffer_inc_capa(buffer, 32); + char* d = buffer->ptr + buffer->len; + int len = fpconv_dtoa(value, d); + /* fpconv_dtoa converts a float to its shortest string representation, + * but it adds a ".0" if this is a plain integer. + */ + fbuffer_consumed(buffer, len); +} + +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + VALUE fragment = RSTRUCT_GET(obj, 0); + Check_Type(fragment, T_STRING); + fbuffer_append_str(buffer, fragment); +} + +static inline void generate_json_general(FBuffer *buffer, struct generate_json_data *data, VALUE obj, bool fallback) +{ + bool as_json_called = false; +start: + if (obj == Qnil) { + generate_json_null(buffer, data, obj); + } else if (obj == Qfalse) { + generate_json_false(buffer, data, obj); + } else if (obj == Qtrue) { + generate_json_true(buffer, data, obj); + } else if (RB_SPECIAL_CONST_P(obj)) { + if (RB_FIXNUM_P(obj)) { + generate_json_fixnum(buffer, data, obj); + } else if (RB_FLONUM_P(obj)) { + generate_json_float(buffer, data, obj); + } else if (RB_STATIC_SYM_P(obj)) { + generate_json_symbol(buffer, data, obj); + } else { + goto general; + } + } else { + VALUE klass = RBASIC_CLASS(obj); + switch (RB_BUILTIN_TYPE(obj)) { + case T_BIGNUM: + generate_json_bignum(buffer, data, obj); + break; + case T_HASH: + if (fallback && klass != rb_cHash) goto general; + generate_json_object(buffer, data, obj); + break; + case T_ARRAY: + if (fallback && klass != rb_cArray) goto general; + generate_json_array(buffer, data, obj); + break; + case T_STRING: + if (fallback && klass != rb_cString) goto general; + + if (RB_LIKELY(valid_json_string_p(obj))) { + raw_generate_json_string(buffer, data, obj); + } else if (as_json_called) { + raise_generator_error(obj, "source sequence is illegal/malformed utf-8"); + } else { + obj = ensure_valid_encoding(data, obj, false, false); + as_json_called = true; + goto start; + } + break; + case T_SYMBOL: + generate_json_symbol(buffer, data, obj); + break; + case T_FLOAT: + if (fallback && klass != rb_cFloat) goto general; + generate_json_float(buffer, data, obj); + break; + case T_STRUCT: + if (klass != cFragment) goto general; + generate_json_fragment(buffer, data, obj); + break; + default: + general: + if (data->state->strict) { + if (RTEST(data->state->as_json) && !as_json_called) { + obj = json_call_as_json(data->state, obj, Qfalse); + as_json_called = true; + goto start; + } else { + raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", CLASS_OF(obj)); + } + } else { + generate_json_fallback(buffer, data, obj); + } + } + } +} + +static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + generate_json_general(buffer, data, obj, true); +} + +static void generate_json_no_fallback(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + generate_json_general(buffer, data, obj, false); +} + +static VALUE generate_json_try(VALUE d) +{ + struct generate_json_data *data = (struct generate_json_data *)d; + + data->func(data->buffer, data, data->obj); + + return fbuffer_finalize(data->buffer); +} + +static VALUE generate_json_ensure(VALUE d) +{ + struct generate_json_data *data = (struct generate_json_data *)d; + fbuffer_free(data->buffer); + + return Qundef; +} + +static inline VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func, VALUE io) +{ + GET_STATE(self); + + char stack_buffer[FBUFFER_STACK_SIZE]; + FBuffer buffer = { 0 }; + fbuffer_init(&buffer, state->buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE); + + struct generate_json_data data = { + .buffer = &buffer, + .vstate = Qfalse, // don't use self as it may be frozen and its depth is mutated when calling to_json + .state = state, + .depth = state->depth, + .obj = obj, + .func = func + }; + return rb_ensure(generate_json_try, (VALUE)&data, generate_json_ensure, (VALUE)&data); +} + +/* call-seq: + * generate(obj) -> String + * generate(obj, anIO) -> anIO + * + * Generates a valid JSON document from object +obj+ and returns the + * result. If no valid JSON document can be created this method raises a + * GeneratorError exception. + */ +static VALUE cState_generate(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 1, 2); + VALUE obj = argv[0]; + VALUE io = argc > 1 ? argv[1] : Qnil; + return cState_partial_generate(self, obj, generate_json, io); +} + +/* :nodoc: */ +static VALUE cState_generate_no_fallback(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 1, 2); + VALUE obj = argv[0]; + VALUE io = argc > 1 ? argv[1] : Qnil; + return cState_partial_generate(self, obj, generate_json_no_fallback, io); +} + +static VALUE cState_initialize(int argc, VALUE *argv, VALUE self) +{ + rb_warn("The json gem extension was loaded with the stdlib ruby code. You should upgrade rubygems with `gem update --system`"); + return self; +} + +/* + * call-seq: initialize_copy(orig) + * + * Initializes this object from orig if it can be duplicated/cloned and returns + * it. +*/ +static VALUE cState_init_copy(VALUE obj, VALUE orig) +{ + JSON_Generator_State *objState, *origState; + + if (obj == orig) return obj; + GET_STATE_TO(obj, objState); + GET_STATE_TO(orig, origState); + if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State"); + + MEMCPY(objState, origState, JSON_Generator_State, 1); + + RB_OBJ_WRITTEN(obj, Qundef, objState->indent); + RB_OBJ_WRITTEN(obj, Qundef, objState->space); + RB_OBJ_WRITTEN(obj, Qundef, objState->space_before); + RB_OBJ_WRITTEN(obj, Qundef, objState->object_nl); + RB_OBJ_WRITTEN(obj, Qundef, objState->array_nl); + RB_OBJ_WRITTEN(obj, Qundef, objState->as_json); + RB_OBJ_WRITTEN(obj, Qundef, objState->sort_keys); + + return obj; +} + +/* + * call-seq: from_state(opts) + * + * Creates a State object from _opts_, which ought to be Hash to create a + * new State instance configured by _opts_, something else to create an + * unconfigured instance. If _opts_ is a State object, it is just returned. + */ +static VALUE cState_from_state_s(VALUE self, VALUE opts) +{ + if (rb_obj_is_kind_of(opts, self)) { + return opts; + } else if (rb_obj_is_kind_of(opts, rb_cHash)) { + return rb_funcall(self, i_new, 1, opts); + } else { + return rb_class_new_instance(0, NULL, cState); + } +} + +/* + * call-seq: indent() + * + * Returns the string that is used to indent levels in the JSON text. + */ +static VALUE cState_indent(VALUE self) +{ + GET_STATE(self); + return state->indent ? state->indent : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +static VALUE string_config(VALUE config) +{ + if (RTEST(config)) { + Check_Type(config, T_STRING); + if (RSTRING_LEN(config)) { + return rb_str_new_frozen(config); + } + } + return Qfalse; +} + +/* + * call-seq: indent=(indent) + * + * Sets the string that is used to indent levels in the JSON text. + */ +static VALUE cState_indent_set(VALUE self, VALUE indent) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->indent, string_config(indent)); + return Qnil; +} + +/* + * call-seq: space() + * + * Returns the string that is used to insert a space between the tokens in a JSON + * string. + */ +static VALUE cState_space(VALUE self) +{ + GET_STATE(self); + return state->space ? state->space : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: space=(space) + * + * Sets _space_ to the string that is used to insert a space between the tokens in a JSON + * string. + */ +static VALUE cState_space_set(VALUE self, VALUE space) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->space, string_config(space)); + return Qnil; +} + +/* + * call-seq: space_before() + * + * Returns the string that is used to insert a space before the ':' in JSON objects. + */ +static VALUE cState_space_before(VALUE self) +{ + GET_STATE(self); + return state->space_before ? state->space_before : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: space_before=(space_before) + * + * Sets the string that is used to insert a space before the ':' in JSON objects. + */ +static VALUE cState_space_before_set(VALUE self, VALUE space_before) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->space_before, string_config(space_before)); + return Qnil; +} + +/* + * call-seq: object_nl() + * + * This string is put at the end of a line that holds a JSON object (or + * Hash). + */ +static VALUE cState_object_nl(VALUE self) +{ + GET_STATE(self); + return state->object_nl ? state->object_nl : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: object_nl=(object_nl) + * + * This string is put at the end of a line that holds a JSON object (or + * Hash). + */ +static VALUE cState_object_nl_set(VALUE self, VALUE object_nl) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->object_nl, string_config(object_nl)); + return Qnil; +} + +/* + * call-seq: array_nl() + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_array_nl(VALUE self) +{ + GET_STATE(self); + return state->array_nl ? state->array_nl : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: array_nl=(array_nl) + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_array_nl_set(VALUE self, VALUE array_nl) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->array_nl, string_config(array_nl)); + return Qnil; +} + +/* + * call-seq: as_json() + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_as_json(VALUE self) +{ + GET_STATE(self); + return state->as_json; +} + +/* + * call-seq: as_json=(as_json) + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_as_json_set(VALUE self, VALUE as_json) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->as_json, rb_convert_type(as_json, T_DATA, "Proc", "to_proc")); + return Qnil; +} + +/* +* call-seq: check_circular? +* +* Returns true, if circular data structures should be checked, +* otherwise returns false. +*/ +static VALUE cState_check_circular_p(VALUE self) +{ + GET_STATE(self); + return state->max_nesting ? Qtrue : Qfalse; +} + +/* + * call-seq: max_nesting + * + * This integer returns the maximum level of data structure nesting in + * the generated JSON, max_nesting = 0 if no maximum is checked. + */ +static VALUE cState_max_nesting(VALUE self) +{ + GET_STATE(self); + return LONG2FIX(state->max_nesting); +} + +static long long_config(VALUE num) +{ + return RTEST(num) ? NUM2LONG(num) : 0; +} + +// depth must never be negative; reject early with a clear error. +static long depth_config(VALUE num) +{ + if (!RTEST(num)) return 0; + long d = NUM2LONG(num); + if (RB_UNLIKELY(d < 0)) { + rb_raise(rb_eArgError, "depth must be >= 0 (got %ld)", d); + } + if (RB_UNLIKELY(d > INT_MAX)) { + rb_raise(rb_eArgError, "depth is too large (got %ld)", d); + } + return d; +} + +/* + * call-seq: max_nesting=(depth) + * + * This sets the maximum level of data structure nesting in the generated JSON + * to the integer depth, max_nesting = 0 if no maximum should be checked. + */ +static VALUE cState_max_nesting_set(VALUE self, VALUE depth) +{ + rb_check_frozen(self); + GET_STATE(self); + state->max_nesting = long_config(depth); + return Qnil; +} + +/* + * call-seq: script_safe + * + * If this boolean is true, the forward slashes will be escaped in + * the json output. + */ +static VALUE cState_script_safe(VALUE self) +{ + GET_STATE(self); + return state->script_safe ? Qtrue : Qfalse; +} + +/* + * call-seq: script_safe=(enable) + * + * This sets whether or not the forward slashes will be escaped in + * the json output. + */ +static VALUE cState_script_safe_set(VALUE self, VALUE enable) +{ + rb_check_frozen(self); + GET_STATE(self); + state->script_safe = RTEST(enable); + return Qnil; +} + +/* + * call-seq: strict + * + * If this boolean is false, types unsupported by the JSON format will + * be serialized as strings. + * If this boolean is true, types unsupported by the JSON format will + * raise a JSON::GeneratorError. + */ +static VALUE cState_strict(VALUE self) +{ + GET_STATE(self); + return state->strict ? Qtrue : Qfalse; +} + +/* + * call-seq: strict=(enable) + * + * This sets whether or not to serialize types unsupported by the + * JSON format as strings. + * If this boolean is false, types unsupported by the JSON format will + * be serialized as strings. + * If this boolean is true, types unsupported by the JSON format will + * raise a JSON::GeneratorError. + */ +static VALUE cState_strict_set(VALUE self, VALUE enable) +{ + rb_check_frozen(self); + GET_STATE(self); + state->strict = RTEST(enable); + return Qnil; +} + +/* + * call-seq: allow_nan? + * + * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise + * returns false. + */ +static VALUE cState_allow_nan_p(VALUE self) +{ + GET_STATE(self); + return state->allow_nan ? Qtrue : Qfalse; +} + +/* + * call-seq: allow_nan=(enable) + * + * This sets whether or not to serialize NaN, Infinity, and -Infinity + */ +static VALUE cState_allow_nan_set(VALUE self, VALUE enable) +{ + rb_check_frozen(self); + GET_STATE(self); + state->allow_nan = RTEST(enable); + return Qnil; +} + +/* + * call-seq: ascii_only? + * + * Returns true, if only ASCII characters should be generated. Otherwise + * returns false. + */ +static VALUE cState_ascii_only_p(VALUE self) +{ + GET_STATE(self); + return state->ascii_only ? Qtrue : Qfalse; +} + +/* + * call-seq: ascii_only=(enable) + * + * This sets whether only ASCII characters should be generated. + */ +static VALUE cState_ascii_only_set(VALUE self, VALUE enable) +{ + rb_check_frozen(self); + GET_STATE(self); + state->ascii_only = RTEST(enable); + return Qnil; +} + +static VALUE cState_set_default_sort_keys_proc(VALUE self, VALUE proc) +{ + if (!rb_obj_is_proc(proc)) { + rb_raise(rb_eTypeError, "sort_key_proc must be a Proc"); + } + return default_sort_keys_proc = proc; +} + +static VALUE normalize_sort_keys(VALUE value) +{ + if (rb_obj_is_proc(value)) { + return value; + } else if (value == Qtrue) { + return default_sort_keys_proc; + } else if (RTEST(value)) { + rb_raise(rb_eTypeError, "The `sort_keys` argument must be a boolean or a Proc"); + } else { + return Qfalse; + } +} + +/* + * call-seq: sort_keys + * + * Get the value of sort_keys. + */ +static VALUE cState_sort_keys_p(VALUE self) +{ + GET_STATE(self); + return state->sort_keys; +} + +/* + * call-seq: sort_keys=(value) + * + * value is a boolean or a proc. If the value is the boolean true, object keys + * will be sorted lexicographically in ascending order. + * + * If the value is a proc, it receives the entire Hash and must return a Hash + * with its pairs in the desired order, allowing for arbitrary sorting. + */ +static VALUE cState_sort_keys_set(VALUE self, VALUE value) +{ + rb_check_frozen(self); + GET_STATE(self); + RB_OBJ_WRITE(self, &state->sort_keys, normalize_sort_keys(value)); + return Qnil; +} + +static VALUE cState_allow_duplicate_key_p(VALUE self) +{ + GET_STATE(self); + switch (state->on_duplicate_key) { + case JSON_IGNORE: + return Qtrue; + case JSON_DEPRECATED: + return Qnil; + default: + return Qfalse; + } +} + +/* + * call-seq: depth + * + * This integer returns the current depth of data structure nesting. + */ +static VALUE cState_depth(VALUE self) +{ + GET_STATE(self); + return LONG2FIX(state->depth); +} + +/* + * call-seq: depth=(depth) + * + * This sets the maximum level of data structure nesting in the generated JSON + * to the integer depth, max_nesting = 0 if no maximum should be checked. + */ +static VALUE cState_depth_set(VALUE self, VALUE depth) +{ + rb_check_frozen(self); + GET_STATE(self); + state->depth = depth_config(depth); + return Qnil; +} + +/* + * call-seq: buffer_initial_length + * + * This integer returns the current initial length of the buffer. + */ +static VALUE cState_buffer_initial_length(VALUE self) +{ + GET_STATE(self); + return LONG2FIX(state->buffer_initial_length); +} + +static void buffer_initial_length_set(JSON_Generator_State *state, VALUE buffer_initial_length) +{ + Check_Type(buffer_initial_length, T_FIXNUM); + long initial_length = FIX2LONG(buffer_initial_length); + if (initial_length > 0) { + state->buffer_initial_length = initial_length; + } +} + +/* + * call-seq: buffer_initial_length=(length) + * + * This sets the initial length of the buffer to +length+, if +length+ > 0, + * otherwise its value isn't changed. + */ +static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length) +{ + rb_check_frozen(self); + GET_STATE(self); + buffer_initial_length_set(state, buffer_initial_length); + return Qnil; +} + +struct configure_state_data { + JSON_Generator_State *state; + VALUE vstate; // Ruby object that owns the state, or Qfalse if stack-allocated +}; + +static inline void state_write_value(struct configure_state_data *data, VALUE *field, VALUE value) +{ + if (RTEST(data->vstate)) { + RB_OBJ_WRITE(data->vstate, field, value); + } else { + *field = value; + } +} + +static int configure_state_i(VALUE key, VALUE val, VALUE _arg) +{ + struct configure_state_data *data = (struct configure_state_data *)_arg; + JSON_Generator_State *state = data->state; + + if (key == sym_indent) { state_write_value(data, &state->indent, string_config(val)); } + else if (key == sym_space) { state_write_value(data, &state->space, string_config(val)); } + else if (key == sym_space_before) { state_write_value(data, &state->space_before, string_config(val)); } + else if (key == sym_object_nl) { state_write_value(data, &state->object_nl, string_config(val)); } + else if (key == sym_array_nl) { state_write_value(data, &state->array_nl, string_config(val)); } + else if (key == sym_max_nesting) { state->max_nesting = long_config(val); } + else if (key == sym_allow_nan) { state->allow_nan = RTEST(val); } + else if (key == sym_ascii_only) { state->ascii_only = RTEST(val); } + else if (key == sym_depth) { state->depth = depth_config(val); } + else if (key == sym_buffer_initial_length) { buffer_initial_length_set(state, val); } + else if (key == sym_script_safe) { state->script_safe = RTEST(val); } + else if (key == sym_escape_slash) { state->script_safe = RTEST(val); } + else if (key == sym_strict) { state->strict = RTEST(val); } + else if (key == sym_allow_duplicate_key) { state->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; } + else if (key == sym_as_json) { + VALUE proc = RTEST(val) ? rb_convert_type(val, T_DATA, "Proc", "to_proc") : Qfalse; + state->as_json_single_arg = proc && rb_proc_arity(proc) == 1; + state_write_value(data, &state->as_json, proc); + } + else if (key == sym_sort_keys) { + state_write_value(data, &state->sort_keys, normalize_sort_keys(val)); + } + return ST_CONTINUE; +} + +static void configure_state(JSON_Generator_State *state, VALUE vstate, VALUE config) +{ + if (!RTEST(config)) return; + + Check_Type(config, T_HASH); + + if (!RHASH_SIZE(config)) return; + + struct configure_state_data data = { + .state = state, + .vstate = vstate + }; + + // We assume in most cases few keys are set so it's faster to go over + // the provided keys than to check all possible keys. + rb_hash_foreach(config, configure_state_i, (VALUE)&data); +} + +static VALUE cState_configure(VALUE self, VALUE opts) +{ + rb_check_frozen(self); + GET_STATE(self); + configure_state(state, self, opts); + return self; +} + +static VALUE cState_m_do_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io, generator_func func) +{ + JSON_Generator_State state = {0}; + state_init(&state); + configure_state(&state, Qfalse, opts); + + char stack_buffer[FBUFFER_STACK_SIZE]; + FBuffer buffer = { 0 }; + fbuffer_init(&buffer, state.buffer_initial_length, io, stack_buffer, FBUFFER_STACK_SIZE); + + struct generate_json_data data = { + .buffer = &buffer, + .vstate = Qfalse, + .state = &state, + .depth = state.depth, + .obj = obj, + .func = func, + }; + return rb_ensure(generate_json_try, (VALUE)&data, generate_json_ensure, (VALUE)&data); +} + +static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io) +{ + return cState_m_do_generate(klass, obj, opts, io, generate_json); +} + +static VALUE cState_m_generate_no_fallback(VALUE klass, VALUE obj, VALUE opts, VALUE io) +{ + return cState_m_do_generate(klass, obj, opts, io, generate_json_no_fallback); +} + +void Init_generator(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + +#undef rb_intern + rb_require("json/common"); + + mJSON = rb_define_module("JSON"); + + rb_global_variable(&cFragment); + cFragment = rb_const_get(mJSON, rb_intern("Fragment")); + + VALUE mExt = rb_define_module_under(mJSON, "Ext"); + VALUE mGenerator = rb_define_module_under(mExt, "Generator"); + + rb_global_variable(&default_sort_keys_proc); + + rb_global_variable(&eGeneratorError); + eGeneratorError = rb_path2class("JSON::GeneratorError"); + + rb_global_variable(&eNestingError); + eNestingError = rb_path2class("JSON::NestingError"); + + cState = rb_define_class_under(mGenerator, "State", rb_cObject); + rb_define_alloc_func(cState, cState_s_allocate); + rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1); + rb_define_singleton_method(cState, "default_sort_keys_proc=", cState_set_default_sort_keys_proc, 1); + + rb_define_method(cState, "initialize", cState_initialize, -1); + rb_define_alias(cState, "initialize", "initialize"); // avoid method redefinition warnings + rb_define_private_method(cState, "_configure", cState_configure, 1); + + rb_define_method(cState, "initialize_copy", cState_init_copy, 1); + rb_define_method(cState, "indent", cState_indent, 0); + rb_define_method(cState, "indent=", cState_indent_set, 1); + rb_define_method(cState, "space", cState_space, 0); + rb_define_method(cState, "space=", cState_space_set, 1); + rb_define_method(cState, "space_before", cState_space_before, 0); + rb_define_method(cState, "space_before=", cState_space_before_set, 1); + rb_define_method(cState, "object_nl", cState_object_nl, 0); + rb_define_method(cState, "object_nl=", cState_object_nl_set, 1); + rb_define_method(cState, "array_nl", cState_array_nl, 0); + rb_define_method(cState, "array_nl=", cState_array_nl_set, 1); + rb_define_method(cState, "as_json", cState_as_json, 0); + rb_define_method(cState, "as_json=", cState_as_json_set, 1); + rb_define_method(cState, "max_nesting", cState_max_nesting, 0); + rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1); + rb_define_method(cState, "script_safe", cState_script_safe, 0); + rb_define_method(cState, "script_safe?", cState_script_safe, 0); + rb_define_method(cState, "script_safe=", cState_script_safe_set, 1); + rb_define_alias(cState, "escape_slash", "script_safe"); + rb_define_alias(cState, "escape_slash?", "script_safe?"); + rb_define_alias(cState, "escape_slash=", "script_safe="); + rb_define_method(cState, "strict", cState_strict, 0); + rb_define_method(cState, "strict?", cState_strict, 0); + rb_define_method(cState, "strict=", cState_strict_set, 1); + rb_define_method(cState, "check_circular?", cState_check_circular_p, 0); + rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0); + rb_define_method(cState, "allow_nan=", cState_allow_nan_set, 1); + rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0); + rb_define_method(cState, "ascii_only=", cState_ascii_only_set, 1); + rb_define_method(cState, "depth", cState_depth, 0); + rb_define_method(cState, "depth=", cState_depth_set, 1); + rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0); + rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1); + rb_define_method(cState, "generate", cState_generate, -1); + rb_define_method(cState, "_generate_no_fallback", cState_generate_no_fallback, -1); + rb_define_method(cState, "sort_keys", cState_sort_keys_p, 0); + rb_define_method(cState, "sort_keys=", cState_sort_keys_set, 1); + + rb_define_private_method(cState, "allow_duplicate_key?", cState_allow_duplicate_key_p, 0); + + rb_define_singleton_method(cState, "generate", cState_m_generate, 3); + rb_define_singleton_method(cState, "_generate_no_fallback", cState_m_generate_no_fallback, 3); + + rb_global_variable(&Encoding_UTF_8); + Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8")); + + i_to_s = rb_intern("to_s"); + i_to_json = rb_intern("to_json"); + i_new = rb_intern("new"); + i_encode = rb_intern("encode"); + + sym_indent = ID2SYM(rb_intern("indent")); + sym_space = ID2SYM(rb_intern("space")); + sym_space_before = ID2SYM(rb_intern("space_before")); + sym_object_nl = ID2SYM(rb_intern("object_nl")); + sym_array_nl = ID2SYM(rb_intern("array_nl")); + sym_max_nesting = ID2SYM(rb_intern("max_nesting")); + sym_allow_nan = ID2SYM(rb_intern("allow_nan")); + sym_ascii_only = ID2SYM(rb_intern("ascii_only")); + sym_depth = ID2SYM(rb_intern("depth")); + sym_buffer_initial_length = ID2SYM(rb_intern("buffer_initial_length")); + sym_script_safe = ID2SYM(rb_intern("script_safe")); + sym_escape_slash = ID2SYM(rb_intern("escape_slash")); + sym_strict = ID2SYM(rb_intern("strict")); + sym_as_json = ID2SYM(rb_intern("as_json")); + sym_allow_duplicate_key = ID2SYM(rb_intern("allow_duplicate_key")); + sym_sort_keys = ID2SYM(rb_intern("sort_keys")); + + usascii_encindex = rb_usascii_encindex(); + utf8_encindex = rb_utf8_encindex(); + binary_encindex = rb_ascii8bit_encindex(); + + rb_require("json/ext/generator/state"); + + simd_impl = find_simd_implementation(); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/json.h b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/json.h new file mode 100644 index 0000000..afddbe2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/json.h @@ -0,0 +1,183 @@ +#ifndef _JSON_H_ +#define _JSON_H_ + +#include "ruby.h" +#include "ruby/encoding.h" +#include + +#ifndef RBIMPL_ASSERT_OR_ASSUME +# define RBIMPL_ASSERT_OR_ASSUME(x) +#endif + +#if defined(RUBY_DEBUG) && RUBY_DEBUG +# define JSON_ASSERT RUBY_ASSERT +# ifndef JSON_DEBUG +# define JSON_DEBUG 1 +# endif +#else +# ifdef JSON_DEBUG +# include +# define JSON_ASSERT(x) assert(x) +# else +# define JSON_ASSERT(x) +# endif +#endif + +#ifdef JSON_DEBUG +# define JSON_UNREACHABLE_RETURN(val) rb_bug("Unreachable") +#else +# define JSON_UNREACHABLE_RETURN UNREACHABLE_RETURN +#endif + +/* shims */ + +#ifndef RUBY_TYPED_THREAD_SAFE_FREE +#define RUBY_TYPED_THREAD_SAFE_FREE RUBY_TYPED_FREE_IMMEDIATELY +#endif + +#ifndef UNDEF_P +#define UNDEF_P(val) (val == Qundef) +#endif + +#if SIZEOF_UINT64_T == SIZEOF_LONG_LONG +# define INT64T2NUM(x) LL2NUM(x) +# define UINT64T2NUM(x) ULL2NUM(x) +#elif SIZEOF_UINT64_T == SIZEOF_LONG +# define INT64T2NUM(x) LONG2NUM(x) +# define UINT64T2NUM(x) ULONG2NUM(x) +#else +# error No uint64_t conversion +#endif + +/* This is the fallback definition from Ruby 3.4 */ +#ifndef RBIMPL_STDBOOL_H +#if defined(__cplusplus) +# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L) +# include +# endif +#elif defined(HAVE_STDBOOL_H) +# include +#elif !defined(HAVE__BOOL) +typedef unsigned char _Bool; +# define bool _Bool +# define true ((_Bool)+1) +# define false ((_Bool)+0) +# define __bool_true_false_are_defined +#endif +#endif + +#ifndef HAVE_RUBY_XFREE_SIZED +static inline void ruby_xfree_sized(void *ptr, size_t oldsize) +{ + ruby_xfree(ptr); +} + +static inline void *ruby_xrealloc2_sized(void *ptr, size_t new_elems, size_t elem_size, size_t old_elems) +{ + return ruby_xrealloc2(ptr, new_elems, elem_size); +} +#endif + +# define JSON_SIZED_REALLOC_N(v, T, m, n) \ + ((v) = (T *)ruby_xrealloc2_sized((void *)(v), (m), sizeof(T), (n))) + +# define JSON_SIZED_FREE(v) ruby_xfree_sized((void *)(v), sizeof(*(v))) +# define JSON_SIZED_FREE_N(v, n) ruby_xfree_sized((void *)(v), sizeof(*(v)) * (n)) + +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# undef RUBY_TYPED_FROZEN_SHAREABLE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + +#ifdef RUBY_TYPED_EMBEDDABLE +# define HAVE_RUBY_TYPED_EMBEDDABLE 1 +#else +# ifdef HAVE_CONST_RUBY_TYPED_EMBEDDABLE +# define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE +# define HAVE_RUBY_TYPED_EMBEDDABLE 1 +# else +# define RUBY_TYPED_EMBEDDABLE 0 +# endif +#endif + +#ifndef NORETURN +#if defined(__has_attribute) && __has_attribute(noreturn) +#define NORETURN(x) __attribute__((noreturn)) x +#else +#define NORETURN(x) x +#endif +#endif + +#ifndef NOINLINE +#if defined(__has_attribute) && __has_attribute(noinline) +#define NOINLINE(x) __attribute__((noinline)) x +#else +#define NOINLINE(x) x +#endif +#endif + +#ifndef ALWAYS_INLINE +#if defined(__has_attribute) && __has_attribute(always_inline) +#define ALWAYS_INLINE(x) inline __attribute__((always_inline)) x +#else +#define ALWAYS_INLINE(x) inline x +#endif +#endif + +#ifndef RB_UNLIKELY +#define RB_UNLIKELY(expr) expr +#endif + +#ifndef RB_LIKELY +#define RB_LIKELY(expr) expr +#endif + +#ifndef MAYBE_UNUSED +# define MAYBE_UNUSED(x) x +#endif + +#ifdef RUBY_DEBUG +#ifndef JSON_DEBUG +#define JSON_DEBUG RUBY_DEBUG +#endif +#endif + +#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && INTPTR_MAX == INT64_MAX +#define JSON_CPU_LITTLE_ENDIAN_64BITS 1 +#else +#define JSON_CPU_LITTLE_ENDIAN_64BITS 0 +#endif + +#ifdef JSON_TRUFFLERUBY_RB_CATCH_BUG + +#undef RB_BLOCK_CALL_FUNC_ARGLIST +#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, func_args) VALUE func_args + +NORETURN(static inline) void json_rb_throw_obj(VALUE tag, VALUE obj) +{ + VALUE exc = rb_exc_new_str(rb_eException, rb_utf8_str_new_cstr("throw_workaround")); + rb_ivar_set(exc, rb_intern("@throw_tag"), tag); + rb_ivar_set(exc, rb_intern("@throw_obj"), obj); + rb_exc_raise(exc); +} +#define rb_throw_obj json_rb_throw_obj + +static inline VALUE json_rb_catch_obj(VALUE tag, VALUE (*func)(VALUE args), VALUE func_args) +{ + int status; + VALUE result = rb_protect(func, func_args, &status); + if (status) { + VALUE exc = rb_errinfo(); + if (tag == rb_ivar_get(exc, rb_intern("@throw_tag"))) { + rb_set_errinfo(Qnil); + return rb_ivar_get(exc, rb_intern("@throw_obj")); + } + rb_jump_tag(status); + } + return result; +} +#define rb_catch_obj json_rb_catch_obj + +#endif // JSON_TRUFFLERUBY_RB_CATCH_BUG + +#endif // _JSON_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/Makefile b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/Makefile new file mode 100644 index 0000000..ab8cb53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /Users/ben/.rubies/ruby-3.4.1/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /Users/ben/.rubies/ruby-3.4.1/include/ruby-3.4.0/arm64-darwin24 +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/Users/ben/.rubies/ruby-3.4.1 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(SDKROOT)$(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = clang +CXX = clang++ -std=gnu++11 +LIBRUBY = $(LIBRUBY_A) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework CoreFoundation $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) -fdeclspec $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wextra-tokens -Wdeprecated-declarations -Wdivision-by-zero -Wdiv-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wold-style-definition -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fno-common +CFLAGS = $(CCDLFLAGS) $(cflags) -pipe $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_RB_ENC_INTERNED_STR -DHAVE_RB_STR_TO_INTERNED_STR -DHAVE_RB_HASH_NEW_CAPA -DHAVE_RB_HASH_BULK_INSERT -DHAVE_CONST_RUBY_TYPED_EMBEDDABLE -DHAVE_ARM_NEON_H -DJSON_ENABLE_SIMD -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/libyaml/include -I/opt/homebrew/opt/gdbm/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) -fdeclspec $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -L/opt/homebrew/Cellar/readline/8.2.13/lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -L/opt/homebrew/Cellar/gdbm/1.24/lib +dldflags = -L/opt/homebrew/Cellar/readline/8.2.13/lib -L/opt/homebrew/Cellar/libyaml/0.2.5/lib -L/opt/homebrew/Cellar/gdbm/1.24/lib -Wl,-undefined,dynamic_lookup -bundle_loader '$(BUILTRUBY)' +ARCH_FLAG = -arch arm64 +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -dynamic -bundle +LDSHAREDXX = $(CXX) -dynamic -bundle +POSTLINK = dsymutil $@ 2>/dev/null; { test -z '$(RUBY_CODESIGN)' || codesign -s '$(RUBY_CODESIGN)' $@; } +AR = ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby.3.4 +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = arm64-darwin24 +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir -p +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) /opt/homebrew/opt/readline/lib /opt/homebrew/opt/libyaml/lib /opt/homebrew/opt/gdbm/lib +LIBPATH = -L. -L$(libdir) -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/libyaml/lib -L/opt/homebrew/opt/gdbm/lib +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /json/ext +LOCAL_LIBS = +LIBS = -lpthread +ORIG_SRCS = parser.c +SRCS = $(ORIG_SRCS) +OBJS = parser.o +HDRS = +LOCAL_HDRS = +TARGET = parser +TARGET_NAME = parser +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).bundle +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) $(TARGET_SO:=.dSYM) +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.json.-.ext.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object json/ext/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/extconf.rb new file mode 100644 index 0000000..a0358cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/extconf.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +require 'mkmf' + +$defs << "-DJSON_DEBUG" if ENV.fetch("JSON_DEBUG", "0") != "0" + +if RUBY_ENGINE == 'truffleruby' && RUBY_ENGINE_VERSION < '40.0' + # Ref: https://github.com/truffleruby/truffleruby/issues/4329 + # Ref: https://github.com/truffleruby/truffleruby/pull/4333 + $defs << "-DJSON_TRUFFLERUBY_RB_CATCH_BUG" +end + +have_func("rb_enc_interned_str", "ruby/encoding.h") # RUBY_VERSION >= 3.0 +have_func("rb_str_to_interned_str", "ruby.h") # RUBY_VERSION >= 3.0 +have_func("rb_hash_new_capa", "ruby.h") # RUBY_VERSION >= 3.2 +have_func("rb_hash_bulk_insert", "ruby.h") # Missing on TruffleRuby +have_func("ruby_xfree_sized", "ruby.h") # RUBY_VERSION >= 4.1 + +if have_header("x86intrin.h") + have_func("_lzcnt_u64", "x86intrin.h") +end + +if have_header("intrin.h") + have_func("__lzcnt64", "intrin.h") + have_func("_BitScanReverse64", "intrin.h") +end + +if RUBY_ENGINE == "ruby" + have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3 +end + +append_cflags("-std=c99") + +if enable_config('parser-use-simd', default=!ENV["JSON_DISABLE_SIMD"]) + load __dir__ + "/../simd/conf.rb" +end + +create_makefile 'json/ext/parser' diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/parser.c b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/parser.c new file mode 100644 index 0000000..d1c90ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/parser/parser.c @@ -0,0 +1,2917 @@ +#include "../json.h" +#include "../vendor/fast_float_parser.h" +#include "../simd/simd.h" + +static VALUE mJSON, eNestingError, eParserError, Encoding_UTF_8; +static VALUE CNaN, CInfinity, CMinusInfinity, JSON_empty_string; + +static ID i_new, i_try_convert, i_encode, i_at_line, i_at_column; +#ifndef HAVE_RB_STR_TO_INTERNED_STR +static ID i_uminus; +#endif + +static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_allow_comments, + sym_allow_control_characters, sym_allow_invalid_escape, sym_symbolize_names, + sym_freeze, sym_decimal_class, sym_on_load, sym_allow_duplicate_key; + +static int binary_encindex; +static int utf8_encindex; + +#ifndef HAVE_RB_HASH_BULK_INSERT +// For TruffleRuby +static void +rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash) +{ + long index = 0; + while (index < count) { + VALUE name = pairs[index++]; + VALUE value = pairs[index++]; + rb_hash_aset(hash, name, value); + } + RB_GC_GUARD(hash); +} +#endif + +#ifndef HAVE_RB_HASH_NEW_CAPA +#define rb_hash_new_capa(n) rb_hash_new() +#endif + +#ifndef HAVE_RB_STR_TO_INTERNED_STR +static VALUE rb_str_to_interned_str(VALUE str) +{ + return rb_funcall(rb_str_freeze(str), i_uminus, 0); +} +#endif + +/* name cache */ + +#include +#include + +// Object names are likely to be repeated, and are frozen. +// As such we can re-use them if we keep a cache of the ones we've seen so far, +// and save much more expensive lookups into the global fstring table. +// This cache implementation is deliberately simple, as we're optimizing for compactness, +// to be able to fit safely on the stack. +// As such, binary search into a sorted array gives a good tradeoff between compactness and +// performance. +#define JSON_RVALUE_CACHE_CAPA 63 +typedef struct rvalue_cache_struct { + int length; + VALUE entries[JSON_RVALUE_CACHE_CAPA]; +} rvalue_cache; + +static void rvalue_cache_mark(rvalue_cache *cache) +{ + for (int index = 0; index < cache->length; index++) { + rb_gc_mark_movable(cache->entries[index]); + } +} + +static void rvalue_cache_compact(rvalue_cache *cache) +{ + for (int index = 0; index < cache->length; index++) { + cache->entries[index] = rb_gc_location(cache->entries[index]); + } +} + +static rb_encoding *enc_utf8; + +#define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55 + +static inline VALUE build_interned_string(const char *str, const long length) +{ +# ifdef HAVE_RB_ENC_INTERNED_STR + return rb_enc_interned_str(str, length, enc_utf8); +# else + VALUE rstring = rb_utf8_str_new(str, length); + return rb_funcall(rb_str_freeze(rstring), i_uminus, 0); +# endif +} + +static inline VALUE build_symbol(const char *str, const long length) +{ + return rb_str_intern(build_interned_string(str, length)); +} + +static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring) +{ + MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index); + cache->length++; + cache->entries[index] = rstring; +} + +#define rstring_cache_memcmp memcmp + +#if JSON_CPU_LITTLE_ENDIAN_64BITS +#if __has_builtin(__builtin_bswap64) +#undef rstring_cache_memcmp +ALWAYS_INLINE(static) int rstring_cache_memcmp(const char *str, const char *rptr, const long length) +{ + // The libc memcmp has numerous complex optimizations, but in this particular case, + // we know the string is small (JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH), so being able to + // inline a simpler memcmp outperforms calling the libc version. + long i = 0; + + for (; i + 8 <= length; i += 8) { + uint64_t a, b; + memcpy(&a, str + i, 8); + memcpy(&b, rptr + i, 8); + if (a != b) { + a = __builtin_bswap64(a); + b = __builtin_bswap64(b); + return (a < b) ? -1 : 1; + } + } + + for (; i < length; i++) { + if (str[i] != rptr[i]) { + return (str[i] < rptr[i]) ? -1 : 1; + } + } + + return 0; +} +#endif +#endif + +ALWAYS_INLINE(static) int rstring_cache_cmp(const char *str, const long length, VALUE rstring) +{ + const char *rstring_ptr; + long rstring_length; + + RSTRING_GETMEM(rstring, rstring_ptr, rstring_length); + + if (length == rstring_length) { + return rstring_cache_memcmp(str, rstring_ptr, length); + } else { + return (int)(length - rstring_length); + } +} + +ALWAYS_INLINE(static) VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length) +{ + int low = 0; + int high = cache->length - 1; + + while (low <= high) { + int mid = (high + low) >> 1; + VALUE entry = cache->entries[mid]; + int cmp = rstring_cache_cmp(str, length, entry); + + if (cmp == 0) { + return entry; + } else if (cmp > 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + VALUE rstring = build_interned_string(str, length); + + if (cache->length < JSON_RVALUE_CACHE_CAPA) { + rvalue_cache_insert_at(cache, low, rstring); + } + return rstring; +} + +static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length) +{ + int low = 0; + int high = cache->length - 1; + + while (low <= high) { + int mid = (high + low) >> 1; + VALUE entry = cache->entries[mid]; + int cmp = rstring_cache_cmp(str, length, rb_sym2str(entry)); + + if (cmp == 0) { + return entry; + } else if (cmp > 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + VALUE rsymbol = build_symbol(str, length); + + if (cache->length < JSON_RVALUE_CACHE_CAPA) { + rvalue_cache_insert_at(cache, low, rsymbol); + } + return rsymbol; +} + +/* rvalue stack */ + +#define RVALUE_STACK_INITIAL_CAPA 128 + +enum rvalue_stack_type { + RVALUE_STACK_HEAP_ALLOCATED = 0, + RVALUE_STACK_STACK_ALLOCATED = 1, +}; + +typedef struct rvalue_stack_struct { + enum rvalue_stack_type type; + long capa; + long head; + VALUE *ptr; +} rvalue_stack; + +static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref); + +static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref) +{ + long required = stack->capa ? stack->capa * 2 : RVALUE_STACK_INITIAL_CAPA; + + if (stack->type == RVALUE_STACK_STACK_ALLOCATED) { + stack = rvalue_stack_spill(stack, handle, stack_ref); + } else { + JSON_SIZED_REALLOC_N(stack->ptr, VALUE, required, stack->capa); + stack->capa = required; + } + return stack; +} + +static VALUE rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref) +{ + JSON_ASSERT(stack->type != RVALUE_STACK_STACK_ALLOCATED || handle); + + if (RB_UNLIKELY(stack->head >= stack->capa)) { + stack = rvalue_stack_grow(stack, handle, stack_ref); + } + + stack->ptr[stack->head] = value; + stack->head++; + + return value; +} + +static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count) +{ + return stack->ptr + (stack->head - count); +} + +static inline void rvalue_stack_pop(rvalue_stack *stack, long count) +{ + stack->head -= count; +} + +static void rvalue_stack_mark(void *ptr) +{ + rvalue_stack *stack = (rvalue_stack *)ptr; + long index; + if (stack && stack->ptr) { + for (index = 0; index < stack->head; index++) { + rb_gc_mark_movable(stack->ptr[index]); + } + } +} + +static void rvalue_stack_free_buffer(rvalue_stack *stack) +{ + JSON_SIZED_FREE_N(stack->ptr, stack->capa); + stack->ptr = NULL; +} + +static void rvalue_stack_free(void *ptr) +{ + rvalue_stack *stack = (rvalue_stack *)ptr; + if (stack) { + rvalue_stack_free_buffer(stack); +#ifndef HAVE_RUBY_TYPED_EMBEDDABLE + JSON_SIZED_FREE(stack); +#endif + } +} + +static size_t rvalue_stack_memsize(const void *ptr) +{ + const rvalue_stack *stack = (const rvalue_stack *)ptr; + size_t memsize = sizeof(VALUE) * stack->capa; +#ifndef HAVE_RUBY_TYPED_EMBEDDABLE + memsize += sizeof(rvalue_stack); +#endif + return memsize; +} + +static void rvalue_stack_compact(void *ptr) +{ + rvalue_stack *stack = (rvalue_stack *)ptr; + long index; + if (stack && stack->ptr) { + for (index = 0; index < stack->head; index++) { + stack->ptr[index] = rb_gc_location(stack->ptr[index]); + } + } +} + +static const rb_data_type_t JSON_Parser_rvalue_stack_type = { + .wrap_struct_name = "JSON::Ext::Parser/rvalue_stack", + .function = { + .dmark = rvalue_stack_mark, + .dfree = rvalue_stack_free, + .dsize = rvalue_stack_memsize, + .dcompact = rvalue_stack_compact, + }, + // We deliberately don't declare rvalue_stack as RUBY_TYPED_WB_PROTECTED + // because it churns a lot of values so trigering write barriers every time is very costly. + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE, +}; + +static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref) +{ + rvalue_stack *stack; + *handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack); + *stack_ref = stack; + MEMCPY(stack, old_stack, rvalue_stack, 1); + + stack->capa = old_stack->capa << 1; + stack->ptr = ALLOC_N(VALUE, stack->capa); + stack->type = RVALUE_STACK_HEAP_ALLOCATED; + MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head); + return stack; +} + +static void rvalue_stack_eagerly_release(VALUE handle) +{ + if (handle) { + rvalue_stack *stack; + TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack); +#ifdef HAVE_RUBY_TYPED_EMBEDDABLE + rvalue_stack_free_buffer(stack); +#else + rvalue_stack_free(stack); + RTYPEDDATA_DATA(handle) = NULL; +#endif + } +} + +/* frame stack */ + +// Iterative (non-recursive) parsing keeps an explicit stack of the containers +// currently being built, instead of relying on the C call stack. Each frame +// only needs enough bookkeeping to close its container: which kind it is, the +// rvalue_stack position where its children start (so we know how many to pop), +// and the cursor at its opening brace (used to rewind for duplicate key +// errors). Frames hold no VALUEs, so this stack needs no GC marking; it reuses +// the same stack-allocated-with-heap-spill strategy as the rvalue_stack so that +// it's freed even if parsing raises. +// +// The lifecycle helpers below (grow/push/peek/pop/spill/free/eagerly_release +// and the rb_data_type_t) deliberately mirror their rvalue_stack counterparts +// -- the element type and the absence of a mark function are the only real +// differences. Keep the two in sync: a fix to the spill/release or +// HAVE_RUBY_TYPED_EMBEDDABLE handling in one almost certainly belongs in the +// other. +#define JSON_FRAME_STACK_INITIAL_CAPA 32 + +enum json_frame_type { + JSON_FRAME_ROOT, // == JSON_PHASE_DONE + JSON_FRAME_ARRAY, // == JSON_PHASE_ARRAY_COMMA + JSON_FRAME_OBJECT, // = JSON_PHASE_OBJECT_COMMA +}; + +// Where a frame is within its container's grammar. This is the entirety of the +// parser's "what to do next" state: json_parse_any dispatches on the top +// frame's phase and holds no resume state in C locals, so a parse can stop at +// any value boundary and be resumed purely from the (persistable) frame stack. +// +// The first three phases are deliberately equal to the corresponding json_frame_type +// to simplify the transition of phase in json_value_completed. +enum json_frame_phase { + JSON_PHASE_DONE = JSON_FRAME_ROOT, // root only: the document value has been parsed + JSON_PHASE_ARRAY_COMMA = JSON_FRAME_ARRAY, // after a value: expecting ',' or the closing ']' + JSON_PHASE_OBJECT_COMMA = JSON_FRAME_OBJECT, // after a value: expecting ',' or the closing '}' + JSON_PHASE_VALUE, // expecting a value (document root, array element, or object value after ':') + JSON_PHASE_OBJECT_KEY, // expecting a '"' key (after '{' or ',') + JSON_PHASE_OBJECT_COLON, // object only: after a key, expecting ':' +}; + +typedef struct json_frame_struct { + enum json_frame_type type; + enum json_frame_phase phase; + long value_stack_head; // rvalue_stack->head when this container opened + size_t start_offset; // object frames only (the '{'); NULL otherwise +} json_frame; + +typedef struct json_frame_stack_struct { + enum rvalue_stack_type type; // shared with rvalue_stack: is ptr stack- or heap-allocated + long capa; + long head; + json_frame *ptr; +} json_frame_stack; + +enum deprecatable_action { + JSON_DEPRECATED = 0, + JSON_IGNORE, + JSON_RAISE, +}; + +typedef struct JSON_ParserStruct { + VALUE on_load_proc; + VALUE decimal_class; + ID decimal_method_id; + enum deprecatable_action on_duplicate_key; + enum deprecatable_action on_comment; + int max_nesting; + bool allow_nan; + bool allow_trailing_comma; + bool allow_control_characters; + bool allow_invalid_escape; + bool symbolize_names; + bool freeze; +} JSON_ParserConfig; + +typedef struct JSON_ParserStateStruct { + VALUE *value_stack_handle; + VALUE *frame_stack_handle; + const char *start; + const char *cursor; + const char *end; + rvalue_stack *value_stack; + json_frame_stack *frames; + rvalue_cache name_cache; + int in_array; + int current_nesting; + unsigned int emitted_deprecations; + VALUE parser; +} JSON_ParserState; + +static json_frame_stack *json_frame_stack_spill(json_frame_stack *old_stack, VALUE *handle, json_frame_stack **stack_ref); + +static json_frame_stack *json_frame_stack_grow(json_frame_stack *stack, VALUE *handle, json_frame_stack **stack_ref) +{ + long required = stack->capa ? stack->capa * 2 : JSON_FRAME_STACK_INITIAL_CAPA; + + if (stack->type == RVALUE_STACK_STACK_ALLOCATED) { + stack = json_frame_stack_spill(stack, handle, stack_ref); + } else { + JSON_SIZED_REALLOC_N(stack->ptr, json_frame, required, stack->capa); + stack->capa = required; + } + return stack; +} + +static json_frame *json_frame_stack_push(JSON_ParserState *state, json_frame frame) +{ + json_frame_stack *stack = state->frames; + + JSON_ASSERT(stack->type != RVALUE_STACK_STACK_ALLOCATED || state->frame_stack_handle); + + if (RB_UNLIKELY(stack->head >= stack->capa)) { + stack = json_frame_stack_grow(stack, state->frame_stack_handle, &state->frames); + } + + json_frame *frame_ptr = &stack->ptr[stack->head++]; + *frame_ptr = frame; + return frame_ptr; +} + +static inline json_frame *json_frame_stack_peek(json_frame_stack *stack) +{ + return &stack->ptr[stack->head - 1]; +} + +static inline void json_frame_stack_pop(json_frame_stack *stack) +{ + stack->head--; +} + +static void json_frame_stack_free_buffer(json_frame_stack *stack) +{ + JSON_SIZED_FREE_N(stack->ptr, stack->capa); + stack->ptr = NULL; +} + +static void json_frame_stack_free(void *ptr) +{ + json_frame_stack *stack = (json_frame_stack *)ptr; + if (stack) { + json_frame_stack_free_buffer(stack); +#ifndef HAVE_RUBY_TYPED_EMBEDDABLE + JSON_SIZED_FREE(stack); +#endif + } +} + +static size_t json_frame_stack_memsize(const void *ptr) +{ + const json_frame_stack *stack = (const json_frame_stack *)ptr; + + size_t memsize = sizeof(json_frame) * stack->capa; +#ifndef HAVE_RUBY_TYPED_EMBEDDABLE + memsize += sizeof(json_frame_stack); +#endif + return memsize; +} + +static const rb_data_type_t JSON_Parser_frame_stack_type = { + .wrap_struct_name = "JSON::Ext::Parser/frame_stack", + .function = { + .dmark = NULL, + .dfree = json_frame_stack_free, + .dsize = json_frame_stack_memsize, + }, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, +}; + +static json_frame_stack *json_frame_stack_spill(json_frame_stack *old_stack, VALUE *handle, json_frame_stack **stack_ref) +{ + json_frame_stack *stack; + *handle = TypedData_Make_Struct(0, json_frame_stack, &JSON_Parser_frame_stack_type, stack); + *stack_ref = stack; + MEMCPY(stack, old_stack, json_frame_stack, 1); + + stack->capa = old_stack->capa << 1; + stack->ptr = ALLOC_N(json_frame, stack->capa); + stack->type = RVALUE_STACK_HEAP_ALLOCATED; + MEMCPY(stack->ptr, old_stack->ptr, json_frame, old_stack->head); + return stack; +} + +static void json_frame_stack_eagerly_release(VALUE handle) +{ + if (handle) { + json_frame_stack *stack; + TypedData_Get_Struct(handle, json_frame_stack, &JSON_Parser_frame_stack_type, stack); +#ifdef HAVE_RUBY_TYPED_EMBEDDABLE + json_frame_stack_free_buffer(stack); +#else + json_frame_stack_free(stack); + RTYPEDDATA_DATA(handle) = NULL; +#endif + } +} + +static int convert_UTF32_to_UTF8(char *buf, uint32_t ch) +{ + int len = 1; + if (ch <= 0x7F) { + buf[0] = (char) ch; + } else if (ch <= 0x07FF) { + buf[0] = (char) ((ch >> 6) | 0xC0); + buf[1] = (char) ((ch & 0x3F) | 0x80); + len++; + } else if (ch <= 0xFFFF) { + buf[0] = (char) ((ch >> 12) | 0xE0); + buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80); + buf[2] = (char) ((ch & 0x3F) | 0x80); + len += 2; + } else if (ch <= 0x1fffff) { + buf[0] =(char) ((ch >> 18) | 0xF0); + buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80); + buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80); + buf[3] =(char) ((ch & 0x3F) | 0x80); + len += 3; + } else { + buf[0] = '?'; + } + return len; +} + +static inline size_t rest(JSON_ParserState *state) { + return state->end - state->cursor; +} + +static inline bool eos(JSON_ParserState *state) { + return state->cursor >= state->end; +} + +static inline char peek(JSON_ParserState *state) +{ + if (RB_UNLIKELY(eos(state))) { + return 0; + } + return *state->cursor; +} + +static void cursor_position(JSON_ParserState *state, long *line_out, long *column_out) +{ + JSON_ASSERT(state->cursor <= state->end); + + // Redundant but helpful for hardening + if (RB_UNLIKELY(state->cursor > state->end)) { + state->cursor = state->end; + } + + const char *cursor = state->cursor; + long column = 0; + long line = 1; + + while (cursor >= state->start) { + if (*cursor-- == '\n') { + line++; + break; + } + column++; + } + + while (cursor >= state->start) { + if (*cursor-- == '\n') { + line++; + } + } + *line_out = line; + *column_out = column; +} + +static const unsigned int MAX_DEPRECATIONS = 5; + +static void emit_parse_warning(const char *message, JSON_ParserState *state) +{ + long line, column; + cursor_position(state, &line, &column); + + VALUE warning = rb_sprintf("%s at line %ld column %ld", message, line, column); + rb_funcall(mJSON, rb_intern("deprecation_warning"), 1, warning); +} + +#define PARSE_ERROR_FRAGMENT_LEN 32 + +static VALUE build_parse_error_message(const char *format, JSON_ParserState *state) +{ + unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3]; + + const char *ptr = "EOF"; + if (state->cursor && state->cursor < state->end) { + ptr = state->cursor; + size_t len = 0; + while (len < PARSE_ERROR_FRAGMENT_LEN) { + char ch = ptr[len]; + if (!ch || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\r') { + break; + } + len++; + } + + if (len) { + buffer[0] = '\''; + MEMCPY(buffer + 1, ptr, char, len); + + while (buffer[len] >= 0x80 && buffer[len] < 0xC0) { // Is continuation byte + len--; + } + + if (buffer[len] >= 0xC0) { // multibyte character start + len--; + } + + buffer[len + 1] = '\''; + buffer[len + 2] = '\0'; + ptr = (const char *)buffer; + } + } + + return rb_enc_sprintf(enc_utf8, format, ptr); +} + +static VALUE parse_error_new(JSON_ParserState *state, VALUE message, long line, long column, bool eos) +{ + VALUE exc = rb_exc_new_str(eParserError, message); + rb_ivar_set(exc, i_at_line, LONG2NUM(line)); + rb_ivar_set(exc, i_at_column, LONG2NUM(column)); + return exc; +} + +NORETURN(static) void raise_parse_error(const char *format, JSON_ParserState *state, bool eos) +{ + if (state->parser) { + if (eos) { + // the error will be swallowed by ResumableParser#parse, so no + // point building a message or backtrace. + rb_throw_obj(state->parser, state->parser); + } else { + // line and columns can't be accurate in resumable + rb_exc_raise(parse_error_new(state, build_parse_error_message(format, state), 0, 0, eos)); + } + } else { + VALUE message = build_parse_error_message(format, state); + long line, column; + cursor_position(state, &line, &column); + rb_str_catf(message, " at line %ld column %ld", line, column); + rb_exc_raise(parse_error_new(state, message, line, column, eos)); + } +} + +NORETURN(static) void raise_eos_error(const char *format, JSON_ParserState *state) +{ + raise_parse_error(format, state, true); +} + +NORETURN(static) void raise_syntax_error(const char *format, JSON_ParserState *state) +{ + raise_parse_error(format, state, false); +} + +NORETURN(static) void raise_parse_error_at(const char *format, JSON_ParserState *state, const char *at, bool eos) +{ + state->cursor = at; + raise_parse_error(format, state, eos); +} + +NORETURN(static) void raise_eos_error_at(const char *format, JSON_ParserState *state, const char *at) +{ + raise_parse_error_at(format, state, at, true); +} + +NORETURN(static) void raise_syntax_error_at(const char *format, JSON_ParserState *state, const char *at) +{ + raise_parse_error_at(format, state, at, false); +} + +/* unicode */ + +static const signed char digit_values[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, + -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1 +}; + +static uint32_t unescape_unicode(JSON_ParserState *state, const char *sp, const char *spe) +{ + if (RB_UNLIKELY(sp > spe - 4)) { + raise_eos_error_at("incomplete unicode character escape sequence at %s", state, sp - 2); + } + + const unsigned char *p = (const unsigned char *)sp; + + const signed char b0 = digit_values[p[0]]; + const signed char b1 = digit_values[p[1]]; + const signed char b2 = digit_values[p[2]]; + const signed char b3 = digit_values[p[3]]; + + if (RB_UNLIKELY((signed char)(b0 | b1 | b2 | b3) < 0)) { + raise_syntax_error_at("incomplete unicode character escape sequence at %s", state, sp - 2); + } + + return ((uint32_t)b0 << 12) | ((uint32_t)b1 << 8) | ((uint32_t)b2 << 4) | (uint32_t)b3; +} + +#define GET_PARSER_CONFIG \ + JSON_ParserConfig *config; \ + TypedData_Get_Struct(self, JSON_ParserConfig, &JSON_ParserConfig_type, config) + +static const rb_data_type_t JSON_ParserConfig_type; + +const char *COMMENT_DEPRECATION_MESSAGE = "Encountered comment in JSON. This will raise an error in json 3.0 unless enabled via `allow_comments: true`"; +NOINLINE(static) void +json_eat_comments(JSON_ParserState *state, JSON_ParserConfig *config, const char *resume_pos) +{ + if (config->on_comment == JSON_RAISE) { + raise_syntax_error("unexpected token %s", state); + } + + const char *start = state->cursor; + // An incomplete comment suspends a resumable parse by rewinding the cursor + // and throwing. Callers that already consumed a token not yet committed to + // the frame stack pass resume_pos so the rewind re-reads that token too. + // Non-resumable error positions keep pointing at the comment either way. + const char *rewind_pos = (state->parser && resume_pos) ? resume_pos : start; + state->cursor++; + + switch (peek(state)) { + case '/': { + const char *newline = memchr(state->cursor, '\n', state->end - state->cursor); + if (!newline) { + // state->parser marks resumable mode, where the buffer end is only a + // chunk boundary: the terminating newline may still arrive, so leave + // the comment unterminated instead of consuming to end as a one-shot + // parse would. + if (state->parser) { + raise_eos_error_at("unterminated comment, expected end of line", state, rewind_pos); + } + state->cursor = state->end; + } else { + state->cursor = newline + 1; + } + break; + } + case '*': { + state->cursor++; + + while (true) { + const char *next_match = memchr(state->cursor, '*', state->end - state->cursor); + if (!next_match) { + raise_eos_error_at("unterminated comment, expected closing '*/'", state, rewind_pos); + } + + state->cursor = next_match + 1; + if (peek(state) == '/') { + state->cursor++; + break; + } + } + break; + } + default: + raise_parse_error_at("unexpected token %s", state, eos(state) ? rewind_pos : start, eos(state)); + break; + } + + if (config->on_comment == JSON_DEPRECATED && state->emitted_deprecations < MAX_DEPRECATIONS) { + state->emitted_deprecations++; + emit_parse_warning(COMMENT_DEPRECATION_MESSAGE, state); + } +} + +ALWAYS_INLINE(static) void +json_eat_whitespace_resume_at(JSON_ParserState *state, JSON_ParserConfig *config, bool include_comments, const char *resume_pos) +{ + while (true) { + switch (peek(state)) { + case ' ': + state->cursor++; + break; + case '\n': + state->cursor++; + + // Heuristic: if we see a newline, there is likely consecutive spaces after it. +#if JSON_CPU_LITTLE_ENDIAN_64BITS + while (rest(state) > 8) { + uint64_t chunk; + memcpy(&chunk, state->cursor, sizeof(uint64_t)); + if (chunk == 0x2020202020202020) { + state->cursor += 8; + continue; + } + + uint32_t consecutive_spaces = trailing_zeros64(chunk ^ 0x2020202020202020) / CHAR_BIT; + state->cursor += consecutive_spaces; + break; + } +#endif + break; + case '\t': + case '\r': + state->cursor++; + break; + case '/': + if (!include_comments) { + return; + } + + json_eat_comments(state, config, resume_pos); + break; + + default: + return; + } + } +} + +ALWAYS_INLINE(static) void +json_eat_whitespace(JSON_ParserState *state, JSON_ParserConfig *config, bool include_comments) +{ + json_eat_whitespace_resume_at(state, config, include_comments, NULL); +} + +static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize) +{ + if (symbolize) { + intern = true; + } + VALUE result; +# ifdef HAVE_RB_ENC_INTERNED_STR + if (intern) { + result = rb_enc_interned_str(start, (long)(end - start), enc_utf8); + } else { + result = rb_utf8_str_new(start, (long)(end - start)); + } +# else + result = rb_utf8_str_new(start, (long)(end - start)); + if (intern) { + result = rb_funcall(rb_str_freeze(result), i_uminus, 0); + } +# endif + + if (symbolize) { + result = rb_str_intern(result); + } + + return result; +} + +static inline bool json_string_cacheable_p(const char *string, size_t length) +{ + // We mostly want to cache strings that are likely to be repeated. + // Simple heuristics: + // - Common names aren't likely to be very long. So we just don't cache names above an arbitrary threshold. + // - If the first character isn't a letter, we're much less likely to see this string again. + return length <= JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH && rb_isalpha(string[0]); +} + +static inline VALUE json_string_fastpath(JSON_ParserState *state, JSON_ParserConfig *config, const char *string, const char *stringEnd, bool is_name) +{ + bool intern = is_name || config->freeze; + bool symbolize = is_name && config->symbolize_names; + size_t bufferSize = stringEnd - string; + + if (is_name && state->in_array && RB_LIKELY(json_string_cacheable_p(string, bufferSize))) { + VALUE cached_key; + if (RB_UNLIKELY(symbolize)) { + cached_key = rsymbol_cache_fetch(&state->name_cache, string, bufferSize); + } else { + cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize); + } + + if (RB_LIKELY(cached_key)) { + return cached_key; + } + } + + return build_string(string, stringEnd, intern, symbolize); +} + +#define JSON_MAX_UNESCAPE_POSITIONS 16 +typedef struct _json_unescape_positions { + long size; + const char **positions; + unsigned long additional_backslashes; +} JSON_UnescapePositions; + +static inline const char *json_next_backslash(const char *pe, const char *stringEnd, JSON_UnescapePositions *positions) +{ + while (positions->size) { + positions->size--; + const char *next_position = positions->positions[0]; + positions->positions++; + if (next_position >= pe) { + return next_position; + } + } + + if (positions->additional_backslashes) { + positions->additional_backslashes--; + return memchr(pe, '\\', stringEnd - pe); + } + + return NULL; +} + +NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_ParserConfig *config, const char *string, const char *stringEnd, bool is_name, JSON_UnescapePositions *positions) +{ + bool intern = is_name || config->freeze; + bool symbolize = is_name && config->symbolize_names; + size_t bufferSize = stringEnd - string; + const char *p = string, *pe = string, *bufferStart; + char *buffer; + + VALUE result = rb_str_buf_new(bufferSize); + rb_enc_associate_index(result, utf8_encindex); + buffer = RSTRING_PTR(result); + bufferStart = buffer; + +#define APPEND_CHAR(chr) *buffer++ = chr; p = ++pe; + + while (pe < stringEnd && (pe = json_next_backslash(pe, stringEnd, positions))) { + if (pe > p) { + MEMCPY(buffer, p, char, pe - p); + buffer += pe - p; + } + switch (*++pe) { + case '"': + case '/': + p = pe; // nothing to unescape just need to skip the backslash + break; + case '\\': + APPEND_CHAR('\\'); + break; + case 'n': + APPEND_CHAR('\n'); + break; + case 'r': + APPEND_CHAR('\r'); + break; + case 't': + APPEND_CHAR('\t'); + break; + case 'b': + APPEND_CHAR('\b'); + break; + case 'f': + APPEND_CHAR('\f'); + break; + case 'u': { + uint32_t ch = unescape_unicode(state, ++pe, stringEnd); + pe += 3; + /* To handle values above U+FFFF, we take a sequence of + * \uXXXX escapes in the U+D800..U+DBFF then + * U+DC00..U+DFFF ranges, take the low 10 bits from each + * to make a 20-bit number, then add 0x10000 to get the + * final codepoint. + * + * See Unicode 15: 3.8 "Surrogates", 5.3 "Handling + * Surrogate Pairs in UTF-16", and 23.6 "Surrogates + * Area". + */ + if ((ch & 0xFC00) == 0xD800) { + pe++; + if (RB_LIKELY((pe <= stringEnd - 6) && memcmp(pe, "\\u", 2) == 0)) { + uint32_t sur = unescape_unicode(state, pe + 2, stringEnd); + + if (RB_UNLIKELY((sur & 0xFC00) != 0xDC00)) { + raise_syntax_error_at("invalid surrogate pair at %s", state, p); + } + + ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) | (sur & 0x3FF)); + pe += 5; + } else { + raise_syntax_error_at("incomplete surrogate pair at %s", state, p); + break; + } + } + + int unescape_len = convert_UTF32_to_UTF8(buffer, ch); + buffer += unescape_len; + p = ++pe; + break; + } + case 0: + return Qundef; + default: + if ((unsigned char)*pe < 0x20) { + if (!config->allow_control_characters) { + if (*pe == '\n') { + raise_syntax_error_at("Invalid unescaped newline character (\\n) in string: %s", state, pe - 1); + } + raise_syntax_error_at("invalid ASCII control character in string: %s", state, pe - 1); + } + } + + if (config->allow_invalid_escape) { + APPEND_CHAR(*pe); + } else { + raise_syntax_error_at("invalid escape character in string: %s", state, pe - 1); + } + break; + } + } +#undef APPEND_CHAR + + if (stringEnd > p) { + MEMCPY(buffer, p, char, stringEnd - p); + buffer += stringEnd - p; + } + rb_str_set_len(result, buffer - bufferStart); + + if (symbolize) { + result = rb_str_intern(result); + } else if (intern) { + result = rb_str_to_interned_str(result); + } + + return result; +} + +#define MAX_FAST_INTEGER_SIZE 18 +#define MAX_NUMBER_STACK_BUFFER 128 + +typedef VALUE (*json_number_decode_func_t)(const char *ptr); + +static inline VALUE json_decode_large_number(const char *start, long len, json_number_decode_func_t func) +{ + if (RB_LIKELY(len < MAX_NUMBER_STACK_BUFFER)) { + char buffer[MAX_NUMBER_STACK_BUFFER]; + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + return func(buffer); + } else { + VALUE buffer_v = rb_str_tmp_new(len); + char *buffer = RSTRING_PTR(buffer_v); + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + VALUE number = func(buffer); + RB_GC_GUARD(buffer_v); + return number; + } +} + +static VALUE json_decode_inum(const char *buffer) +{ + return rb_cstr2inum(buffer, 10); +} + +NOINLINE(static) VALUE json_decode_large_integer(const char *start, long len) +{ + return json_decode_large_number(start, len, json_decode_inum); +} + +static inline VALUE json_decode_integer(uint64_t mantissa, int mantissa_digits, bool negative, const char *start, const char *end) +{ + if (RB_LIKELY(mantissa_digits < MAX_FAST_INTEGER_SIZE)) { + if (negative) { + return INT64T2NUM(-((int64_t)mantissa)); + } + return UINT64T2NUM(mantissa); + } + + return json_decode_large_integer(start, end - start); +} + +static VALUE json_decode_dnum(const char *buffer) +{ + return DBL2NUM(rb_cstr_to_dbl(buffer, 1)); +} + +NOINLINE(static) VALUE json_decode_large_float(const char *start, long len) +{ + return json_decode_large_number(start, len, json_decode_dnum); +} + +/* Ruby JSON optimized float decoder using vendored Ryu algorithm + * Accepts pre-extracted mantissa and exponent from first-pass validation + */ +static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits, int64_t exponent, bool negative, + const char *start, const char *end) +{ + if (RB_UNLIKELY(config->decimal_class)) { + VALUE text = rb_str_new(start, end - start); + return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text); + } + + if (RB_UNLIKELY(exponent > INT32_MAX)) { + return negative ? CMinusInfinity : CInfinity; + } + + if (RB_UNLIKELY(exponent < INT32_MIN)) { + return rb_float_new(negative ? -0.0 : 0.0); + } + + if (RB_UNLIKELY(mantissa_digits > 18 || mantissa_digits + exponent < -307)) { + // If the value is so small that it definitely underflows to 0.0, return early + // to avoid triggering a "Float out of range" warning from rb_cstr_to_dbl. + // When mantissa_digits + exponent < -324, value < 10^(-324) < DBL_TRUE_MIN/2, + // so it rounds to 0 in IEEE 754 round-to-nearest. + if (RB_UNLIKELY(mantissa_digits + exponent < -324)) { + return rb_float_new(negative ? -0.0 : 0.0); + } + return json_decode_large_float(start, end - start); + } + + return DBL2NUM(ffp_s2d(exponent, mantissa, negative)); +} + +static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count) +{ + VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(state->value_stack, count)); + rvalue_stack_pop(state->value_stack, count); + + if (config->freeze) { + RB_OBJ_FREEZE(array); + } + + return array; +} + +static VALUE json_find_duplicated_key(size_t count, const VALUE *pairs) +{ + VALUE set = rb_hash_new_capa(count / 2); + for (size_t index = 0; index < count; index += 2) { + size_t before = RHASH_SIZE(set); + VALUE key = pairs[index]; + rb_hash_aset(set, key, Qtrue); + if (RHASH_SIZE(set) == before) { + if (RB_SYMBOL_P(key)) { + return rb_sym2str(key); + } + return key; + } + } + return Qfalse; +} + +NOINLINE(static) void emit_duplicate_key_warning(JSON_ParserState *state, VALUE duplicate_key) +{ + VALUE message = rb_sprintf( + "detected duplicate key %"PRIsVALUE" in JSON object. This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`", + rb_inspect(duplicate_key) + ); + + emit_parse_warning(RSTRING_PTR(message), state); + RB_GC_GUARD(message); +} + +NORETURN(static) void raise_duplicate_key_error(JSON_ParserState *state, VALUE duplicate_key) +{ + VALUE message = rb_sprintf( + "duplicate key %"PRIsVALUE, + rb_inspect(duplicate_key) + ); + + rb_str_concat(message, build_parse_error_message("", state)); + if (state->parser) { // line and columns can't be accurate in resumable + rb_exc_raise(parse_error_new(state, message, 0, 0, false)); + } else { + long line, column; + cursor_position(state, &line, &column); + rb_str_catf(message, " at line %ld column %ld", line, column); + rb_exc_raise(parse_error_new(state, message, line, column, false)); + } +} + +NOINLINE(static) void json_on_duplicate_key(JSON_ParserState *state, JSON_ParserConfig *config, size_t count, const VALUE *pairs) +{ + switch (config->on_duplicate_key) { + case JSON_IGNORE: + return; + + case JSON_DEPRECATED: + // Only emit the first few deprecations to avoid spamming. + if (state->emitted_deprecations < MAX_DEPRECATIONS) { + state->emitted_deprecations++; + emit_duplicate_key_warning(state, json_find_duplicated_key(count, pairs)); + } + return; + + case JSON_RAISE: + raise_duplicate_key_error(state, json_find_duplicated_key(count, pairs)); + return; + } + UNREACHABLE; +} + +static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, size_t count) +{ + size_t entries_count = count / 2; + VALUE object = rb_hash_new_capa(entries_count); + const VALUE *pairs = rvalue_stack_peek(state->value_stack, count); + rb_hash_bulk_insert(count, pairs, object); + + if (RB_UNLIKELY(RHASH_SIZE(object) < entries_count)) { + json_on_duplicate_key(state, config, count, pairs); + } + + rvalue_stack_pop(state->value_stack, count); + + if (config->freeze) { + RB_OBJ_FREEZE(object); + } + + return object; +} + +static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *config, VALUE value) +{ + if (RB_UNLIKELY(config->on_load_proc)) { + value = rb_proc_call_with_block(config->on_load_proc, 1, &value, Qnil); + } + rvalue_stack_push(state->value_stack, value, state->value_stack_handle, &state->value_stack); + return value; +} + +static const bool string_scan_table[256] = { + // ASCII Control Characters + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // ASCII Characters + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +#ifdef HAVE_SIMD +static SIMD_Implementation simd_impl = SIMD_NONE; +#endif /* HAVE_SIMD */ + +ALWAYS_INLINE(static) bool string_scan(JSON_ParserState *state) +{ +#ifdef HAVE_SIMD +#if defined(HAVE_SIMD_NEON) + + uint64_t mask = 0; + if (string_scan_simd_neon(&state->cursor, state->end, &mask)) { + state->cursor += trailing_zeros64(mask) >> 2; + return true; + } + +#elif defined(HAVE_SIMD_SSE2) + if (simd_impl == SIMD_SSE2) { + int mask = 0; + if (string_scan_simd_sse2(&state->cursor, state->end, &mask)) { + state->cursor += trailing_zeros(mask); + return true; + } + } +#endif /* HAVE_SIMD_NEON or HAVE_SIMD_SSE2 */ +#endif /* HAVE_SIMD */ + + while (!eos(state)) { + if (RB_UNLIKELY(string_scan_table[(unsigned char)*state->cursor])) { + return true; + } + state->cursor++; + } + + // If the string ended with an unterminated escape sequence, we might + // have gone past the end. + if (RB_UNLIKELY(state->cursor > state->end)) { + state->cursor = state->end; + } + + return false; +} + +static VALUE json_parse_escaped_string(JSON_ParserState *state, JSON_ParserConfig *config, bool is_name, const char *start) +{ + const char *backslashes[JSON_MAX_UNESCAPE_POSITIONS]; + JSON_UnescapePositions positions = { + .size = 0, + .positions = backslashes, + .additional_backslashes = 0, + }; + + do { + switch (*state->cursor) { + case '"': { + VALUE string = json_string_unescape(state, config, start, state->cursor, is_name, &positions); + state->cursor++; + return string; + } + case '\\': { + if (RB_LIKELY(positions.size < JSON_MAX_UNESCAPE_POSITIONS)) { + backslashes[positions.size] = state->cursor; + positions.size++; + } else { + positions.additional_backslashes++; + } + state->cursor++; + break; + } + default: + if (!config->allow_control_characters) { + raise_syntax_error("invalid ASCII control character in string: %s", state); + } + break; + } + + state->cursor++; + } while (string_scan(state)); + + return Qundef; +} + +ALWAYS_INLINE(static) VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig *config, bool is_name) +{ + state->cursor++; + const char *start = state->cursor; + + if (RB_UNLIKELY(!string_scan(state))) { + return Qundef; + } + + VALUE string; + if (RB_LIKELY(*state->cursor == '"')) { + string = json_string_fastpath(state, config, start, state->cursor, is_name); + state->cursor++; + } + else { + string = json_parse_escaped_string(state, config, is_name, start); + } + + return string; +} + +#if JSON_CPU_LITTLE_ENDIAN_64BITS +// From: https://lemire.me/blog/2022/01/21/swar-explained-parsing-eight-digits/ +// Additional References: +// https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ +// http://0x80.pl/notesen/2014-10-12-parsing-decimal-numbers-part-1-swar.html +static inline uint64_t decode_8digits_unrolled(uint64_t val) { + const uint64_t mask = 0x000000FF000000FF; + const uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32) + const uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32) + val -= 0x3030303030303030; + val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8; + val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32; + return val; +} + +static inline uint64_t decode_4digits_unrolled(uint32_t val) { + const uint32_t mask = 0x000000FF; + const uint32_t mul1 = 100; + val -= 0x30303030; + val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8; + val = ((val & mask) * mul1) + (((val >> 16) & mask)); + return val; +} +#endif + +static inline int json_parse_digits(JSON_ParserState *state, uint64_t *accumulator) +{ + const char *start = state->cursor; + +#if JSON_CPU_LITTLE_ENDIAN_64BITS + while (rest(state) >= sizeof(uint64_t)) { + uint64_t next_8bytes; + memcpy(&next_8bytes, state->cursor, sizeof(uint64_t)); + + // From: https://github.com/simdjson/simdjson/blob/32b301893c13d058095a07d9868edaaa42ee07aa/include/simdjson/generic/numberparsing.h#L333 + // Branchless version of: http://0x80.pl/articles/swar-digits-validate.html + uint64_t match = (next_8bytes & 0xF0F0F0F0F0F0F0F0) | (((next_8bytes + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4); + + if (match == 0x3333333333333333) { // 8 consecutive digits + *accumulator = (*accumulator * 100000000) + decode_8digits_unrolled(next_8bytes); + state->cursor += 8; + continue; + } + + uint32_t consecutive_digits = trailing_zeros64(match ^ 0x3333333333333333) / CHAR_BIT; + + if (consecutive_digits >= 4) { + *accumulator = (*accumulator * 10000) + decode_4digits_unrolled((uint32_t)next_8bytes); + state->cursor += 4; + consecutive_digits -= 4; + } + + while (consecutive_digits) { + *accumulator = *accumulator * 10 + (*state->cursor - '0'); + consecutive_digits--; + state->cursor++; + } + + return (int)(state->cursor - start); + } +#endif + + char next_char; + while (rb_isdigit(next_char = peek(state))) { + *accumulator = *accumulator * 10 + (next_char - '0'); + state->cursor++; + } + return (int)(state->cursor - start); +} + +static inline VALUE json_parse_number(JSON_ParserState *state, JSON_ParserConfig *config, bool negative, const char *start, bool resumable) +{ + bool integer = true; + const char first_digit = *state->cursor; + + // Variables for Ryu optimization - extract digits during parsing + int64_t exponent = 0; + int decimal_point_pos = -1; + uint64_t mantissa = 0; + + // Parse integer part and extract mantissa digits + int mantissa_digits = json_parse_digits(state, &mantissa); + + if (RB_UNLIKELY((first_digit == '0' && mantissa_digits > 1) || (negative && mantissa_digits == 0))) { + return Qundef; + } + + // Parse fractional part + if (peek(state) == '.') { + integer = false; + decimal_point_pos = mantissa_digits; // Remember position of decimal point + state->cursor++; + + int fractional_digits = json_parse_digits(state, &mantissa); + mantissa_digits += fractional_digits; + + if (RB_UNLIKELY(!fractional_digits)) { + return Qundef; + } + } + + // Parse exponent + if (rb_tolower(peek(state)) == 'e') { + integer = false; + state->cursor++; + + bool negative_exponent = false; + const char next_char = peek(state); + if (next_char == '-' || next_char == '+') { + negative_exponent = next_char == '-'; + state->cursor++; + } + + uint64_t abs_exponent = 0; + int exponent_digits = json_parse_digits(state, &abs_exponent); + + if (RB_UNLIKELY(!exponent_digits)) { + return Qundef; + } + + if (RB_UNLIKELY(exponent_digits >= 20 || abs_exponent > (uint64_t)INT64_MAX)) { + exponent = negative_exponent ? INT64_MIN : INT64_MAX; + } else { + exponent = negative_exponent ? -(int64_t)abs_exponent : (int64_t)abs_exponent; + } + } + + // A number touching the end of the buffer may still grow in a later chunk, + // so the caller will rewind and wait. Decoding it now would build a value + // -- for a long run of digits, an expensive bignum -- only to discard it, + // and repeating that on every resumed chunk is quadratic in the number's + // length. The digit scan above already advanced the cursor, which is all + // the caller needs to detect the incomplete number. + if (RB_UNLIKELY(resumable && eos(state))) { + return Qundef; + } + + if (integer) { + return json_decode_integer(mantissa, mantissa_digits, negative, start, state->cursor); + } + + // Adjust exponent based on decimal point position + if (decimal_point_pos >= 0) { + exponent -= (mantissa_digits - decimal_point_pos); + } + + return json_decode_float(config, mantissa, mantissa_digits, exponent, negative, start, state->cursor); +} + +// How many values (array elements, or interleaved object keys+values) have been +// pushed onto the rvalue stack since this container opened. Used to size the +// bulk decode on close, and to tell the first key/colon from later ones. +static inline long json_frame_entry_count(const json_frame *frame, const rvalue_stack *value_stack) +{ + return value_stack->head - frame->value_stack_head; +} + +// A complete value now sits on top of the rvalue stack. Advance the frame that +// was waiting for it: the root document is done, or the enclosing container +// moves on to expecting a ',' or its closing bracket. The caller passes the +// frame it already has in hand -- the one that was expecting the value -- which +// after a container close is the freshly re-exposed parent. +static inline enum json_frame_phase json_value_completed(json_frame *frame) +{ + JSON_ASSERT((int)JSON_PHASE_DONE == (int)JSON_FRAME_ROOT); + JSON_ASSERT((int)JSON_PHASE_ARRAY_COMMA == (int)JSON_FRAME_ARRAY); + JSON_ASSERT((int)JSON_PHASE_OBJECT_COMMA == (int)JSON_FRAME_OBJECT); + + return frame->phase = (enum json_frame_phase) frame->type; +} + +ALWAYS_INLINE(static) void json_match_keyword(JSON_ParserState *state, const char *keyword, size_t offset) +{ + // It is assumed that since `keyword` is always a literal, the compiler is able to constantize this + // `strlen` and several other computations in that routine. + + size_t len = strlen(keyword); + + // Note: memcmp with a small power of two and a literal string compile to an integer comparison / + // That's why we sometime compare starting from the first byte and sometimes from the second. + if (rest(state) >= len && (memcmp(state->cursor + offset, keyword + offset, len - offset) == 0)) { + state->cursor += len; + return; + } + + bool eos = rest(state) < len && memcmp(state->cursor, keyword, rest(state)) == 0; + raise_parse_error("unexpected token %s", state, eos); +} + +// Parse an arbitrary JSON value iteratively. This is a state machine driven +// entirely by the top frame's phase so it can stop at any value boundary and +// resume purely from the frame stack. A JSON_FRAME_ROOT frame sits at the +// bottom of the stack, so the stack is never empty mid-parse and the document +// itself is just another frame whose value, once parsed, leaves its phase DONE. +// When invoked in resumable mode, it returns true after parsing a complete document. +// If reaching EOS without having parsed a complete document, either returns false +// of raise a JSON::ParserError tagged with `@eos=true`. +ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config, bool resumable) +{ + json_frame *frame = json_frame_stack_peek(state->frames); + + switch (frame->phase) { + case JSON_PHASE_DONE: JSON_UNREACHABLE_RETURN(false); + case JSON_PHASE_ARRAY_COMMA: goto JSON_PHASE_ARRAY_COMMA; + case JSON_PHASE_OBJECT_COMMA: goto JSON_PHASE_OBJECT_COMMA; + case JSON_PHASE_VALUE: goto JSON_PHASE_VALUE; + case JSON_PHASE_OBJECT_KEY: goto JSON_PHASE_OBJECT_KEY; + case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON; + } + JSON_UNREACHABLE_RETURN(false); + + JSON_PHASE_VALUE: { + json_eat_whitespace(state, config, true); + + // A trailing comma lands us here expecting an element but finding the + // closing bracket; hand off to ARRAY_COMMA to close. An empty array + // closes inline at '[', so this position is only reached after a ','. + if (config->allow_trailing_comma && frame->type == JSON_FRAME_ARRAY && peek(state) == ']') { + goto JSON_PHASE_ARRAY_COMMA; + } + + VALUE value; + const char *value_start = state->cursor; + + switch (peek(state)) { + case 'n': + json_match_keyword(state, "null", 0); + value = Qnil; + break; + + case 't': + json_match_keyword(state, "true", 0); + value = Qtrue; + break; + + case 'f': + json_match_keyword(state, "false", 1); + value = Qfalse; + break; + + case 'N': + if (!config->allow_nan) { + raise_syntax_error("unexpected token %s", state); + } + + json_match_keyword(state, "NaN", 1); + value = CNaN; + break; + + case 'I': + if (!config->allow_nan) { + raise_syntax_error("unexpected token %s", state); + } + + json_match_keyword(state, "Infinity", 0); + value = CInfinity; + break; + + case '-': { + state->cursor++; + + value = json_parse_number(state, config, true, value_start, resumable); + + if (RB_UNLIKELY(UNDEF_P(value) && config->allow_nan && peek(state) == 'I')) { + state->cursor = value_start; + json_match_keyword(state, "-Infinity", 1); + value = CMinusInfinity; + break; + } + + // Top level numbers are ambiguous when parsing streams, we can't + // know if we parsed all the digits if we hit EOS. + if (RB_UNLIKELY(resumable && eos(state))) { + state->cursor = value_start; + return false; + } + + if (RB_UNLIKELY(UNDEF_P(value))) { + raise_syntax_error_at("invalid number: %s", state, value_start); + } + break; + } + + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { + value = json_parse_number(state, config, false, value_start, resumable); + + // Top level numbers are ambiguous when parsing streams, we can't + // know if we parsed all the digits if we hit EOS. + if (RB_UNLIKELY(resumable && eos(state))) { + state->cursor = value_start; + return false; + } + + if (RB_UNLIKELY(UNDEF_P(value))) { + raise_syntax_error_at("invalid number: %s", state, value_start); + } + break; + } + + case '"': { + // %r{\A"[^"\\\t\n\x00]*(?:\\[bfnrtu\\/"][^"\\]*)*"} + value = json_parse_string(state, config, false); + + if (RB_UNLIKELY(UNDEF_P(value))) { + bool is_eos = eos(state); + if (resumable && is_eos) { + state->cursor = value_start; + return false; + } + raise_parse_error("unexpected end of input, expected closing \"", state, is_eos); + } + break; + } + + case '[': { + state->cursor++; + // The '[' is consumed but its frame is only pushed below, so a + // comment suspending here must resume from the bracket. + json_eat_whitespace_resume_at(state, config, true, value_start); + + const char next = peek(state); + if (next == ']') { + state->cursor++; + value = json_decode_array(state, config, 0); + break; + } else if (resumable && eos(state)) { + state->cursor = value_start; + return false; + } + + state->current_nesting++; + if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) { + rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting); + } + state->in_array++; + + // Phase stays VALUE: the next iteration reads the first element. + frame = json_frame_stack_push(state, (json_frame){ + .type = JSON_FRAME_ARRAY, + .phase = JSON_PHASE_VALUE, + .value_stack_head = state->value_stack->head, + }); + goto JSON_PHASE_VALUE; + } + + case '{': { + state->cursor++; + // Same as '[': the frame is only pushed below. + json_eat_whitespace_resume_at(state, config, true, value_start); + + if (peek(state) == '}') { + state->cursor++; + value = json_decode_object(state, config, 0); + break; + } else if (resumable && eos(state)) { + state->cursor = value_start; + return false; + } + + state->current_nesting++; + if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) { + rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting); + } + + // Phase KEY: the next iteration reads the first key. + frame = json_frame_stack_push(state, (json_frame){ + .type = JSON_FRAME_OBJECT, + .phase = JSON_PHASE_OBJECT_KEY, + .value_stack_head = state->value_stack->head, + .start_offset = value_start - state->start, + }); + goto JSON_PHASE_OBJECT_KEY; + } + + case 0: + // peek() returns 0 both at end-of-stream and for a literal NUL byte in the + // buffer. Only a genuine EOS means "feed me more"; a NUL byte that is not at + // EOS is just an invalid character. + if (eos(state)) { + return false; + } else { + raise_syntax_error("unexpected NULL byte: %s", state); + } + default: + raise_syntax_error("unexpected character: %s", state); + } + + json_push_value(state, config, value); + json_value_completed(frame); + + switch (frame->phase) { + case JSON_PHASE_DONE: return true; + case JSON_PHASE_ARRAY_COMMA: goto JSON_PHASE_ARRAY_COMMA; + case JSON_PHASE_OBJECT_COMMA: goto JSON_PHASE_OBJECT_COMMA; + case JSON_PHASE_VALUE: goto JSON_PHASE_VALUE; + case JSON_PHASE_OBJECT_KEY: JSON_UNREACHABLE_RETURN(false); + case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON; + } + JSON_UNREACHABLE_RETURN(false); + } + + JSON_PHASE_OBJECT_KEY: { + JSON_ASSERT(frame->type == JSON_FRAME_OBJECT); + + json_eat_whitespace(state, config, true); + + // A trailing comma lands us here expecting a key but finding the closing + // brace; hand off to OBJECT_COMMA to close. An empty object closes inline + // at '{', so this position is only reached after a ','. + if (config->allow_trailing_comma && peek(state) == '}') { + goto JSON_PHASE_OBJECT_COMMA; + } + + const char *start = state->cursor; + + if (RB_LIKELY(peek(state) == '"')) { + VALUE string = json_parse_string(state, config, true); + if (UNDEF_P(string)) { + if (resumable) { + state->cursor = start; + return false; + } else { + raise_syntax_error("unexpected end of input, expected closing \"", state); + } + } + json_push_value(state, config, string); + frame->phase = JSON_PHASE_OBJECT_COLON; + goto JSON_PHASE_OBJECT_COLON; + } else if (resumable && eos(state)) { + return false; + } else { + // The message differs for the first key vs. a key after a + // ',': the first is the only one reached with nothing pushed + // for this object yet. + if (json_frame_entry_count(frame, state->value_stack) == 0) { + raise_syntax_error("expected object key, got %s", state); + } else { + raise_syntax_error("expected object key, got: %s", state); + } + } + JSON_UNREACHABLE_RETURN(false); + } + + JSON_PHASE_OBJECT_COLON: { + JSON_ASSERT(frame->type == JSON_FRAME_OBJECT); + + json_eat_whitespace(state, config, true); + + if (RB_LIKELY(peek(state) == ':')) { + state->cursor++; + frame->phase = JSON_PHASE_VALUE; + goto JSON_PHASE_VALUE; + } else if (resumable && eos(state)) { + return false; + } else { + // First colon (only the first pair's key is pushed, nothing + // else) vs. a later one. + if (json_frame_entry_count(frame, state->value_stack) == 1) { + raise_syntax_error("expected ':' after object key", state); + } else { + raise_syntax_error("expected ':' after object key, got: %s", state); + } + } + JSON_UNREACHABLE_RETURN(false); + } + + JSON_PHASE_ARRAY_COMMA: { + JSON_ASSERT(frame->type == JSON_FRAME_ARRAY); + + json_eat_whitespace(state, config, true); + + const char next_char = peek(state); + + if (RB_LIKELY(next_char == ',')) { + state->cursor++; + // Commit the phase before eating the whitespace that follows: an + // incomplete comment there would suspend the parse, and a phase not + // yet advanced past the ',' would drop it on resume. A trailing comma + // is recognized in JSON_PHASE_VALUE once the ']' is in the buffer. + frame->phase = JSON_PHASE_VALUE; + goto JSON_PHASE_VALUE; + } else if (next_char == ']') { + state->cursor++; + long count = json_frame_entry_count(frame, state->value_stack); + state->current_nesting--; + state->in_array--; + + json_push_value(state, config, json_decode_array(state, config, count)); + json_frame_stack_pop(state->frames); + frame = json_frame_stack_peek(state->frames); + + json_value_completed(frame); + + switch (frame->phase) { + case JSON_PHASE_DONE: return true; + case JSON_PHASE_ARRAY_COMMA: goto JSON_PHASE_ARRAY_COMMA; + case JSON_PHASE_OBJECT_COMMA: goto JSON_PHASE_OBJECT_COMMA; + case JSON_PHASE_VALUE: goto JSON_PHASE_VALUE; + case JSON_PHASE_OBJECT_KEY: JSON_UNREACHABLE_RETURN(false); + case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON; + } + } else if (resumable && eos(state)) { + return false; + } else { + raise_syntax_error("expected ',' or ']' after array value", state); + } + JSON_UNREACHABLE_RETURN(false); + } + + JSON_PHASE_OBJECT_COMMA: { + JSON_ASSERT(frame->type == JSON_FRAME_OBJECT); + + json_eat_whitespace(state, config, true); + const char next_char = peek(state); + + if (RB_LIKELY(next_char == ',')) { + state->cursor++; + // Commit the phase before eating the whitespace that follows: an + // incomplete comment there would suspend the parse, and a phase not + // yet advanced past the ',' would drop it on resume. A trailing comma + // is recognized in JSON_PHASE_OBJECT_KEY once the '}' is in the buffer. + frame->phase = JSON_PHASE_OBJECT_KEY; + goto JSON_PHASE_OBJECT_KEY; + } else if (next_char == '}') { + state->cursor++; + state->current_nesting--; + size_t count = json_frame_entry_count(frame, state->value_stack); + + // Temporary rewind cursor in case an error is raised + const char *final_cursor = state->cursor; + state->cursor = state->start + frame->start_offset; + VALUE object = json_decode_object(state, config, count); + state->cursor = final_cursor; + + json_push_value(state, config, object); + json_frame_stack_pop(state->frames); + frame = json_frame_stack_peek(state->frames); + json_value_completed(frame); + + switch (frame->phase) { + case JSON_PHASE_DONE: return true; + case JSON_PHASE_ARRAY_COMMA: goto JSON_PHASE_ARRAY_COMMA; + case JSON_PHASE_OBJECT_COMMA: goto JSON_PHASE_OBJECT_COMMA; + case JSON_PHASE_VALUE: goto JSON_PHASE_VALUE; + case JSON_PHASE_OBJECT_KEY: JSON_UNREACHABLE_RETURN(false); + case JSON_PHASE_OBJECT_COLON: goto JSON_PHASE_OBJECT_COLON; + } + } else if (resumable && eos(state)) { + return false; + } else { + raise_syntax_error("expected ',' or '}' after object value, got: %s", state); + } + JSON_UNREACHABLE_RETURN(false); + } + + JSON_UNREACHABLE_RETURN(false); +} + +static void json_ensure_eof(JSON_ParserState *state, JSON_ParserConfig *config) +{ + json_eat_whitespace(state, config, true); + if (!eos(state)) { + raise_syntax_error("unexpected token at end of stream %s", state); + } +} + +/* + * Document-class: JSON::Ext::Parser + * + * This is the JSON parser implemented as a C extension. It can be configured + * to be used by setting + * + * JSON.parser = JSON::Ext::Parser + * + * with the method parser= in JSON. + * + */ + +static VALUE convert_encoding(VALUE source) +{ + StringValue(source); + int encindex = RB_ENCODING_GET(source); + + if (RB_LIKELY(encindex == utf8_encindex)) { + return source; + } + + if (encindex == binary_encindex) { + // For historical reason, we silently reinterpret binary strings as UTF-8 + return rb_enc_associate_index(rb_str_dup(source), utf8_encindex); + } + + source = rb_funcall(source, i_encode, 1, Encoding_UTF_8); + StringValue(source); + return source; +} + +struct parser_config_init_args { + JSON_ParserConfig *config; + VALUE self; + VALUE unknown_keywords; + bool strict; +}; + +static void parser_config_wb_write(VALUE self, VALUE *dest, VALUE val) +{ + *dest = val; + if (self) RB_OBJ_WRITTEN(self, Qundef, val); +} + +static int parser_config_init_i(VALUE key, VALUE val, VALUE data) +{ + struct parser_config_init_args *args = (struct parser_config_init_args *)data; + JSON_ParserConfig *config = args->config; + VALUE self = args->self; + + if (key == sym_max_nesting) { config->max_nesting = RTEST(val) ? FIX2INT(val) : 0; } + else if (key == sym_allow_nan) { config->allow_nan = RTEST(val); } + else if (key == sym_allow_trailing_comma) { config->allow_trailing_comma = RTEST(val); } + else if (key == sym_allow_comments) { config->on_comment = RTEST(val) ? JSON_IGNORE : JSON_RAISE; } + else if (key == sym_allow_control_characters) { config->allow_control_characters = RTEST(val); } + else if (key == sym_allow_invalid_escape) { config->allow_invalid_escape = RTEST(val); } + else if (key == sym_symbolize_names) { config->symbolize_names = RTEST(val); } + else if (key == sym_freeze) { config->freeze = RTEST(val); } + else if (key == sym_on_load) { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); } + else if (key == sym_allow_duplicate_key) { config->on_duplicate_key = RTEST(val) ? JSON_IGNORE : JSON_RAISE; } + else if (key == sym_decimal_class) { + if (RTEST(val)) { + if (rb_respond_to(val, i_try_convert)) { + parser_config_wb_write(self, &config->decimal_class, val); + config->decimal_method_id = i_try_convert; + } else if (rb_respond_to(val, i_new)) { + parser_config_wb_write(self, &config->decimal_class, val); + config->decimal_method_id = i_new; + } else if (RB_TYPE_P(val, T_CLASS)) { + VALUE name = rb_class_name(val); + const char *name_cstr = RSTRING_PTR(name); + const char *last_colon = strrchr(name_cstr, ':'); + if (last_colon) { + const char *mod_path_end = last_colon - 1; + VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr); + parser_config_wb_write(self, &config->decimal_class, rb_path_to_class(mod_path)); + + const char *method_name_beg = last_colon + 1; + long before_len = method_name_beg - name_cstr; + long len = RSTRING_LEN(name) - before_len; + VALUE method_name = rb_str_substr(name, before_len, len); + config->decimal_method_id = SYM2ID(rb_str_intern(method_name)); + } else { + parser_config_wb_write(self, &config->decimal_class, rb_mKernel); + config->decimal_method_id = SYM2ID(rb_str_intern(name)); + } + } + } + } + else if (args->strict) { + if (!args->unknown_keywords) { + args->unknown_keywords = rb_obj_hide(rb_ary_new()); + } + rb_ary_push(args->unknown_keywords, key); + } + + return ST_CONTINUE; +} + +static void parser_config_init(JSON_ParserConfig *config, VALUE opts, VALUE self, bool strict) +{ + config->max_nesting = 100; + + struct parser_config_init_args args = { + .config = config, + .self = self, + .strict = strict, + }; + + if (NIL_P(opts)) return; + Check_Type(opts, T_HASH); + if (RHASH_SIZE(opts) == 0) return; + + // We assume in most cases few keys are set so it's faster to go over + // the provided keys than to check all possible keys. + rb_hash_foreach(opts, parser_config_init_i, (VALUE)&args); + + if (RB_UNLIKELY(args.unknown_keywords)) { + if (RARRAY_LEN(args.unknown_keywords) == 1) { + rb_raise(rb_eArgError, "unknown keyword: %" PRIsVALUE, RARRAY_AREF(args.unknown_keywords, 0)); + } + else { + VALUE keywords = rb_ary_join(args.unknown_keywords, rb_utf8_str_new_cstr(", ")); + rb_raise(rb_eArgError, "unknown keywords: %" PRIsVALUE, keywords); + } + } +} + +/* + * call-seq: new(opts => {}) + * + * Creates a new JSON::Ext::ParserConfig instance. + * + * Argument +opts+, if given, contains a \Hash of options for the parsing. + * See {Parsing Options}[#module-JSON-label-Parsing+Options]. + * + */ +static VALUE cParserConfig_initialize(VALUE self, VALUE opts) +{ + rb_check_frozen(self); + GET_PARSER_CONFIG; + + parser_config_init(config, opts, self, false); + + return self; +} + +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE src) +{ + VALUE Vsource = convert_encoding(src); + + // Ensure the string isn't mutated under us. + // The classic API to use is `rb_str_locktmp`, but then we'd + // need to use `rb_protect` to make sure we always unlock. + if (Vsource == src) { + Vsource = rb_str_new_frozen(Vsource); + } + + VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA]; + rvalue_stack value_stack = { + .type = RVALUE_STACK_STACK_ALLOCATED, + .ptr = rvalue_stack_buffer, + .capa = RVALUE_STACK_INITIAL_CAPA, + }; + + // Seed the frame stack with the root frame, establishing the invariant that + // json_parse_any always has a top frame to dispatch on (so the stack is never + // empty mid-parse). + json_frame frame_stack_buffer[JSON_FRAME_STACK_INITIAL_CAPA]; + frame_stack_buffer[0] = (json_frame){ + .type = JSON_FRAME_ROOT, + .phase = JSON_PHASE_VALUE, + }; + json_frame_stack frames = { + .type = RVALUE_STACK_STACK_ALLOCATED, + .ptr = frame_stack_buffer, + .capa = JSON_FRAME_STACK_INITIAL_CAPA, + .head = 1, + }; + + long len; + const char *start; + + RSTRING_GETMEM(Vsource, start, len); + + VALUE value_stack_handle = 0; + VALUE frame_stack_handle = 0; + JSON_ParserState _state = { + .start = start, + .cursor = start, + .end = start + len, + .value_stack = &value_stack, + .value_stack_handle = &value_stack_handle, + .frames = &frames, + .frame_stack_handle = &frame_stack_handle, + }; + JSON_ParserState *state = &_state; + + bool complete = json_parse_any(state, config, false); + + // The root document value is parsed; it is the lone survivor on + // the rvalue stack. + VALUE result = complete ? *rvalue_stack_peek(state->value_stack, 1) : Qundef; + + // This may be skipped in case of exception, but + // it won't cause a leak. + rvalue_stack_eagerly_release(value_stack_handle); + json_frame_stack_eagerly_release(frame_stack_handle); + RB_GC_GUARD(value_stack_handle); + RB_GC_GUARD(frame_stack_handle); + RB_GC_GUARD(Vsource); + + if (complete) { + json_ensure_eof(state, config); + } else { + raise_eos_error("unexpected end of input", state); + } + + return result; +} + +/* + * call-seq: parse(source) + * + * Parses the current JSON text _source_ and returns the complete data + * structure as a result. + * It raises JSON::ParserError if fail to parse. + */ +static VALUE cParserConfig_parse(VALUE self, VALUE Vsource) +{ + GET_PARSER_CONFIG; + return cParser_parse(config, Vsource); +} + +static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts) +{ + JSON_ParserConfig _config = {0}; + JSON_ParserConfig *config = &_config; + parser_config_init(config, opts, Qfalse, false); + + return cParser_parse(config, Vsource); +} + +static void JSON_ParserConfig_mark(void *ptr) +{ + JSON_ParserConfig *config = ptr; + rb_gc_mark_movable(config->on_load_proc); + rb_gc_mark_movable(config->decimal_class); +} + +static size_t JSON_ParserConfig_memsize(const void *ptr) +{ +#ifdef HAVE_RUBY_TYPED_EMBEDDABLE + return 0; +#else + return sizeof(JSON_ParserConfig); +#endif +} + +static void JSON_ParserConfig_compact(void *ptr) +{ + JSON_ParserConfig *config = ptr; + config->on_load_proc = rb_gc_location(config->on_load_proc); + config->decimal_class = rb_gc_location(config->decimal_class); +} + +static const rb_data_type_t JSON_ParserConfig_type = { + .wrap_struct_name = "JSON::Ext::Parser/ParserConfig", + .function = { + .dmark = JSON_ParserConfig_mark, + .dfree = RUBY_DEFAULT_FREE, + .dsize = JSON_ParserConfig_memsize, + .dcompact = JSON_ParserConfig_compact, + }, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE, +}; + +static VALUE cJSON_parser_s_allocate(VALUE klass) +{ + JSON_ParserConfig *config; + return TypedData_Make_Struct(klass, JSON_ParserConfig, &JSON_ParserConfig_type, config); +} + +static void json_str_clear(VALUE str) +{ + if (RB_OBJ_FROZEN_RAW(str)) { + return; + } + rb_str_replace(str, JSON_empty_string); +} + +typedef struct JSON_ResumableParserStruct { + JSON_ParserConfig config; + JSON_ParserState state; + rvalue_stack value_stack; + json_frame_stack frames; + VALUE buffer; + size_t parsed_bytes; + size_t incomplete_bytes; + bool complete; + bool in_use; +} JSON_ResumableParser; + +static void JSON_ResumableParser_mark(void *ptr) +{ + JSON_ResumableParser *parser = (JSON_ResumableParser *)ptr; + JSON_ParserConfig_mark(&parser->config); + rvalue_stack_mark(&parser->value_stack); + rvalue_cache_mark(&parser->state.name_cache); + rb_gc_mark(parser->buffer); // pin the buffer + rb_gc_mark_movable(parser->state.parser); +} + +static void JSON_ResumableParser_free(void *ptr) +{ + JSON_ResumableParser *parser = (JSON_ResumableParser *)ptr; + rvalue_stack_free_buffer(&parser->value_stack); + json_frame_stack_free_buffer(&parser->frames); +} + +static size_t JSON_ResumableParser_memsize(const void *ptr) +{ + const JSON_ResumableParser *parser = (const JSON_ResumableParser *)ptr; + size_t memsize = JSON_ParserConfig_memsize(&parser->config); + memsize += rvalue_stack_memsize(&parser->value_stack); + memsize += json_frame_stack_memsize(&parser->frames); +#ifndef HAVE_RUBY_TYPED_EMBEDDABLE + memsize += ( + sizeof(JSON_ResumableParser) + - sizeof(JSON_ParserState) + - sizeof(JSON_ParserConfig) + - sizeof(rvalue_stack) + - sizeof(json_frame_stack) + ); +#endif + return memsize; +} + +static void JSON_ResumableParser_compact(void *ptr) +{ + JSON_ResumableParser *parser = (JSON_ResumableParser *)ptr; + JSON_ParserConfig_compact(&parser->config); + rvalue_stack_compact(&parser->value_stack); + rvalue_cache_compact(&parser->state.name_cache); + parser->buffer = rb_gc_location(parser->buffer); + parser->state.parser = rb_gc_location(parser->state.parser); +} + +static const rb_data_type_t JSON_ResumableParser_type = { + .wrap_struct_name = "JSON::Ext::ResumableParser", + .function = { + JSON_ResumableParser_mark, + JSON_ResumableParser_free, + JSON_ResumableParser_memsize, + JSON_ResumableParser_compact, + }, + // RUBY_TYPED_WB_PROTECTED is deliberately not declared because + // this is a superset of JSON_Parser_rvalue_stack_type, so we'd need + // to trigger a lot of write barriers. + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE, +}; + +static VALUE cResumableParser_allocate(VALUE klass) +{ + JSON_ResumableParser *parser; + VALUE obj = TypedData_Make_Struct(klass, JSON_ResumableParser, &JSON_ResumableParser_type, parser); + parser->state.in_array++; + parser->state.parser = obj; + return obj; +} + +static inline JSON_ResumableParser *cResumableParser_get(VALUE self) +{ + JSON_ResumableParser *parser; + TypedData_Get_Struct(self, JSON_ResumableParser, &JSON_ResumableParser_type, parser); + return parser; +} + +/* + * call-seq: new(opts => {}) + * + * Creates a new JSON::ResumableParser instance. + * + * Argument +opts+, if given, contains a \Hash of options for the parsing. + * See {Parsing Options}[#module-JSON-label-Parsing+Options]. + * + * A ResumableParser is able to parse partial documents and resume parsing later + * when more of the document is provided: + * + * parser = JSON::ResumableParser.new + * parser << '{"user": "george", "role": "ad' + * parser.parse # => false + * parser.eos? # => true + * parser.partial_value # => { "user" => "george", "role" => nil } + * parser.rest # => '"ad' + * + * parser << 'min" }[1, 2, 3]' + * parser.parse # => true + * parser.value # => { "user" => "george", "role" => "admin" } + * + * parser.parse # => true + * parser.value # => [1, 2, 3] + * + * === Limitations + * + * While ResumableParser is able to parse streams of documents without any + * explicit separators between them, it is highly recommended to separate documents + * by either spaces or newlines, as otherwise the \JSON syntax for numbers may be ambiguous. + * When parsing a number, ResumableParser will not consider the number complete until something follows: + * + * parser << '123' + * parser.parse # => false + * parser << ' ' + * parser.parse # => true + * parser.value # => 123 + * + * === Security + * + * An incomplete document is buffered in full and there is no size limit, so when reading + * from an untrusted source the caller is responsible for bounding how much data is fed. + * For example: + * + * loop do + * if parser.parsed_bytes > DOCUMENT_MAX_SIZE + * raise "document too large" + * end + * + * parser << read_chunk + * while parser.parse + * process(parser.value) + * end + * end + */ +static VALUE cResumableParser_initialize(int argc, VALUE *argv, VALUE self) +{ + rb_check_frozen(self); + + VALUE opts = Qfalse; + rb_scan_args_kw(RB_SCAN_ARGS_LAST_HASH_KEYWORDS, argc, argv, "0:", &opts); + JSON_ResumableParser *parser = cResumableParser_get(self); + + opts = argc > 0 ? argv[0] : Qnil; + parser_config_init(&parser->config, opts, self, true); + + return self; +} + +static JSON_ResumableParser *ResumableParser_acquire(VALUE self, bool lock); + +/* + * call-seq: self << string -> self + * + * Appends the given string to the parser's buffer. + */ +static VALUE cResumableParser_feed(VALUE self, VALUE str) +{ + rb_check_frozen(self); + + JSON_ResumableParser *parser = ResumableParser_acquire(self, false); + + str = convert_encoding(str); + if (!RSTRING_LEN(str)) { + return self; + } + + size_t offset = parser->state.cursor - parser->state.start; + const size_t remaining = parser->state.end - parser->state.cursor; + + if (!remaining) { + if (parser->buffer) { + json_str_clear(parser->buffer); + } + parser->buffer = RB_OBJ_FROZEN_RAW(str) ? str : rb_obj_hide(rb_str_new_shared(str)); + offset = 0; + } else { + JSON_ASSERT(parser->buffer); + + const size_t size = parser->state.end - parser->state.start; + const size_t consumed = size - remaining; + + if (RB_OBJ_FROZEN_RAW(parser->buffer)) { + VALUE new_buffer = rb_obj_hide(rb_str_buf_new(remaining + RSTRING_LEN(str))); + rb_enc_associate_index(new_buffer, utf8_encindex); + + char *old_ptr = RSTRING_PTR(parser->buffer); + memcpy(RSTRING_PTR(new_buffer), old_ptr + consumed, remaining); + rb_str_set_len(new_buffer, remaining); + offset = 0; + parser->buffer = new_buffer; + } else if (consumed > (size / 2) && size >= 512) { + rb_str_modify(parser->buffer); + char *old_ptr = RSTRING_PTR(parser->buffer); + memmove(old_ptr, old_ptr + consumed, remaining); + rb_str_set_len(parser->buffer, remaining); + offset = 0; + } + rb_str_append(parser->buffer, str); + } + + long len; + const char *start; + RSTRING_GETMEM(parser->buffer, start, len); + parser->state.start = start; + parser->state.end = start + len; + parser->state.cursor = parser->state.start + offset; + + return self; +} + +struct json_parse_any_args { + JSON_ParserState *state; + JSON_ParserConfig *config; + VALUE parser; +}; + +static VALUE json_parse_any_resumable_safe0(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, _args)) +{ + struct json_parse_any_args *args = (struct json_parse_any_args *)_args; + return (VALUE)json_parse_any(args->state, args->config, true); +} + +static VALUE json_parse_any_resumable_safe(VALUE _args) +{ + struct json_parse_any_args *args = (struct json_parse_any_args *)_args; + VALUE result = rb_catch_obj(args->parser, json_parse_any_resumable_safe0, _args); + return result == args->parser ? Qfalse : result; +} + +static JSON_ResumableParser *ResumableParser_acquire(VALUE self, bool lock) +{ + JSON_ResumableParser *parser = cResumableParser_get(self); + + if (parser->in_use) { + rb_raise(rb_eArgError, "ResumableParser can't be used recursively"); + } + + if (lock) { + parser->in_use = true; + } + + // self may have moved, so we need to update all pointers + // Investigate: We might be better off keeping JSON_ParserState on the stack + // and only persist what we need. + parser->state.value_stack = &parser->value_stack; + parser->state.frames = &parser->frames; + + return parser; +} + +/* + * call-seq: parse -> true or false + * + * Attemps to parse a JSON document from the internal buffer. + * Returns whether a complete document could be parsed. + * + * It does raise +JSON::ParserError+ when encountering invalid \JSON syntax. + * + * The parsed object can be retrieved by calling #value + */ +static VALUE cResumableParser_parse(VALUE self) +{ + JSON_ResumableParser *parser = ResumableParser_acquire(self, true); + + if (parser->complete) { + parser->parsed_bytes = 0; + parser->incomplete_bytes = 0; + parser->complete = false; + } + + if (!parser->buffer) { + parser->in_use = false; + return Qfalse; + } + + if (parser->frames.head == 0) { + json_frame_stack_push(&parser->state, (json_frame){ + .type = JSON_FRAME_ROOT, + .phase = JSON_PHASE_VALUE, + }); + } + + VALUE Vsource = parser->buffer; // Prevent compaction + + json_frame *frame = json_frame_stack_peek(&parser->frames); + + if (frame->phase == JSON_PHASE_DONE) { + JSON_ASSERT(parser->value_stack.head == 1); + JSON_ASSERT(parser->frames.head == 1); + + frame->phase = JSON_PHASE_VALUE; + rvalue_stack_pop(parser->state.value_stack, 1); + } + + struct json_parse_any_args args = { + .state = &parser->state, + .config = &parser->config, + .parser = self, + }; + int status; + const char *initial_cursor = parser->state.cursor; + parser->complete = rb_protect(json_parse_any_resumable_safe, (VALUE)&args, &status); + + if (status) { + parser->complete = true; // a parse error is considered complete + } + + parser->parsed_bytes += parser->state.cursor - initial_cursor; + parser->incomplete_bytes = parser->complete ? 0 : parser->state.end - parser->state.cursor; + + json_eat_whitespace(&parser->state, &parser->config, false); + if (eos(&parser->state)) { + json_str_clear(parser->buffer); + parser->buffer = Qfalse; + } + parser->in_use = false; + + if (status) { + rb_jump_tag(status); // reraise + } + RB_GC_GUARD(Vsource); + return parser->complete ? Qtrue : Qfalse; +} + +/* + * call-seq: value? -> true or false + * + * Returns whether a parsed value is available. + */ +static VALUE cResumableParser_value_p(VALUE self) +{ + JSON_ResumableParser *parser = ResumableParser_acquire(self, false); + + if (parser->value_stack.head > 0) { + json_frame *frame = json_frame_stack_peek(&parser->frames); + if (frame->phase == JSON_PHASE_DONE) { + return Qtrue; + } + } + return Qfalse; +} + +/* + * call-seq: value -> object + * + * Returns and consume the last parsed value. + * Raises ArgumentError if there is no parsed value or if it was already retrieved: + * parser << '[1][2]' + * parser.value # ArgumentError no ready value + * parser.parse # => true + * parser.value # => [1] + * parser.value # ArgumentError no ready value + */ +static VALUE cResumableParser_value(VALUE self) +{ + JSON_ResumableParser *parser = ResumableParser_acquire(self, false); + + if (parser->frames.head > 0) { + json_frame *frame = json_frame_stack_peek(&parser->frames); + + if (frame->phase == JSON_PHASE_DONE) { + VALUE result = *rvalue_stack_peek(parser->state.value_stack, 1); + rvalue_stack_pop(parser->state.value_stack, 1); + json_frame_stack_pop(parser->state.frames); + return result; + } + } + rb_raise(rb_eArgError, "no ready value"); +} + +/* + * call-seq: clear -> self + * + * Entirely reset the parser state and buffer. + */ +static VALUE cResumableParser_clear(VALUE self) +{ + JSON_ResumableParser *parser = ResumableParser_acquire(self, false); + parser->buffer = 0; + parser->complete = true; + parser->parsed_bytes = 0; + parser->incomplete_bytes = 0; + parser->frames.head = 0; + parser->value_stack.head = 0; + parser->state.name_cache.length = 0; + parser->state.current_nesting = 0; + parser->state.in_array = 1; + parser->state.emitted_deprecations = 0; + parser->state.start = parser->state.cursor = parser->state.end = NULL; + return self; +} + +static VALUE cResumableParser_partial_value_body(VALUE self) +{ + JSON_ResumableParser *original_parser = cResumableParser_get(self); + JSON_ResumableParser parser = *original_parser; + + parser.state.frames = &parser.frames; + parser.state.value_stack = &parser.value_stack; + + if (parser.value_stack.head == 0) { + return Qnil; + } + + json_frame *frame = json_frame_stack_peek(parser.state.frames); + long missing_object_value = 0; + if (frame->type == JSON_FRAME_OBJECT && (frame->phase == JSON_PHASE_VALUE || frame->phase == JSON_PHASE_OBJECT_COLON)) { + missing_object_value = 1; + } + + // Copy the value stack as we need to mutate it. The collapse loop folds each + // open container by popping its entries and pushing the single result, so a + // parent always reclaims its child's slot; head exceeds its live size by at + // most one, either for the missing-value placeholder pushed below or for the + // result of folding an empty innermost container. That one spare slot keeps + // rvalue_stack_push from growing (reallocating) this ALLOCV buffer. + long capa = parser.value_stack.head; + parser.value_stack.capa = capa + 1; + VALUE tmpbuf, *value_stack_buffer = ALLOCV_N(VALUE, tmpbuf, parser.value_stack.capa); + MEMCPY(value_stack_buffer, parser.value_stack.ptr, VALUE, capa); + parser.value_stack.ptr = value_stack_buffer; + + JSON_ParserState *state = &parser.state; + JSON_ParserConfig *config = &parser.config; + + if (missing_object_value) { + rvalue_stack_push(state->value_stack, Qnil, NULL, &state->value_stack); + } + + VALUE partial_result = Qundef; + + while (UNDEF_P(partial_result)) { + frame = json_frame_stack_peek(state->frames); + + switch (frame->type) { + case JSON_FRAME_ROOT: { + partial_result = *rvalue_stack_peek(state->value_stack, 1); + break; + } + + case JSON_FRAME_ARRAY: { + long count = json_frame_entry_count(frame, state->value_stack); + json_push_value(state, config, json_decode_array(state, config, count)); + json_frame_stack_pop(state->frames); + + break; + } + + case JSON_FRAME_OBJECT: { + long count = json_frame_entry_count(frame, state->value_stack); + json_push_value(state, config, json_decode_object(state, config, count)); + json_frame_stack_pop(state->frames); + break; + } + + default: { + JSON_UNREACHABLE_RETURN(Qundef); + break; + } + } + } + + ALLOCV_END(tmpbuf); + return partial_result; +} + +/* + * call-seq: partial_value -> object + * + * Returns the Ruby objects parsed up to this point: + * parser << '[1, [2, 3,' + * parser.parse # => false + * parser.value # ArgumentError no ready value + * parser.partial_value # => [1, [2, 3]] + */ +static VALUE cResumableParser_partial_value(VALUE self) +{ + JSON_ResumableParser *parser = ResumableParser_acquire(self, true); + + int status; + VALUE result = rb_protect(cResumableParser_partial_value_body, self, &status); + parser->in_use = false; + if (status) { + rb_jump_tag(status); + } + return result; +} + +/* + * call-seq: rest -> string + * + * Returns a string containing what remains to be parsed in the buffer + * parser << '{ "message": "unterminated message' + * parser.parse # => false + * parser.rest # => '"unterminated message"' + */ +static VALUE cResumableParser_rest(VALUE self) +{ + JSON_ResumableParser *parser = cResumableParser_get(self); + + if (!parser->buffer) { + return rb_utf8_str_new("", 0); + } + + size_t offset = parser->state.cursor - parser->state.start; + const char *ptr; + long len; + RSTRING_GETMEM(parser->buffer, ptr, len); + return rb_utf8_str_new(ptr + offset, len - offset); +} + +/* + * call-seq: eos? -> true or false + * + * Returns whether the internal buffer has been entirely consumed. + */ +static VALUE cResumableParser_eos_p(VALUE self) +{ + JSON_ResumableParser *parser = cResumableParser_get(self); + return eos(&parser->state) ? Qtrue : Qfalse; +} + +/* + * call-seq: partial_value? -> true or false + * + * Returns whether a document is currently under construction: an unclosed + * container, a key awaiting its value, etc. + * + * It answers the same question as !partial_value.nil?, but as a + * cheap predicate on the parser's internal state, without materializing the + * partially parsed Ruby objects: + * parser << '{"a":1,' + * parser.parse # => false + * parser.partial_value? # => true + * + * A fully parsed document whose value hasn't been retrieved yet is not under + * construction: #value? returns true and #partial_value? returns false. + */ +static VALUE cResumableParser_partial_value_p(VALUE self) +{ + JSON_ResumableParser *parser = cResumableParser_get(self); + + // Mirror of #value?: values on the stack while the document isn't DONE + // belong to a partially built document. A container whose first key or + // element hasn't been parsed yet has no frame nor value registered (the + // tokenizer rewinds to the container start on EOS), so that state is + // observable through the buffer (#eos?/#rest) instead, keeping this + // predicate consistent with #partial_value returning nil. + if (parser->value_stack.head > 0) { + json_frame *frame = json_frame_stack_peek(&parser->frames); + if (frame->phase != JSON_PHASE_DONE) { + return Qtrue; + } + } + return Qfalse; +} + +/* + * call-seq: parsed_bytes -> integer + * + * Returns the number of bytes parsed since the start of the current partial value. + * This is intended to be used for securing against untrusted input: + * + * loop do + * if parser.parsed_bytes > DOCUMENT_MAX_SIZE + * raise "document too large" + * end + * + * parser << read_chunk + * while parser.parse + * process(parser.value) + * end + * end + */ +static VALUE cResumableParser_parsed_bytes(VALUE self) +{ + JSON_ResumableParser *parser = cResumableParser_get(self); + return ULL2NUM(parser->parsed_bytes + parser->incomplete_bytes); +} + +void Init_parser(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + +#undef rb_intern + rb_require("json/common"); + mJSON = rb_define_module("JSON"); + VALUE mExt = rb_define_module_under(mJSON, "Ext"); + VALUE cParserConfig = rb_define_class_under(mExt, "ParserConfig", rb_cObject); + + rb_global_variable(&eParserError); + eParserError = rb_path2class("JSON::ParserError"); + + rb_global_variable(&eNestingError); + eNestingError = rb_path2class("JSON::NestingError"); + + rb_define_alloc_func(cParserConfig, cJSON_parser_s_allocate); + rb_define_private_method(cParserConfig, "initialize", cParserConfig_initialize, 1); + rb_define_method(cParserConfig, "parse", cParserConfig_parse, 1); + + VALUE cParser = rb_define_class_under(mExt, "Parser", rb_cObject); + rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2); + + VALUE cResumableParser = rb_define_class_under(mJSON, "ResumableParser", rb_cObject); + rb_define_alloc_func(cResumableParser, cResumableParser_allocate); + rb_define_private_method(cResumableParser, "initialize", cResumableParser_initialize, -1); + rb_define_method(cResumableParser, "<<", cResumableParser_feed, 1); + rb_define_method(cResumableParser, "parse", cResumableParser_parse, 0); + rb_define_method(cResumableParser, "value", cResumableParser_value, 0); + rb_define_method(cResumableParser, "value?", cResumableParser_value_p, 0); + rb_define_method(cResumableParser, "partial_value", cResumableParser_partial_value, 0); + rb_define_method(cResumableParser, "partial_value?", cResumableParser_partial_value_p, 0); + rb_define_method(cResumableParser, "clear", cResumableParser_clear, 0); + rb_define_method(cResumableParser, "rest", cResumableParser_rest, 0); + rb_define_method(cResumableParser, "eos?", cResumableParser_eos_p, 0); + rb_define_method(cResumableParser, "parsed_bytes", cResumableParser_parsed_bytes, 0); + + rb_global_variable(&CNaN); + CNaN = rb_const_get(mJSON, rb_intern("NaN")); + + rb_global_variable(&CInfinity); + CInfinity = rb_const_get(mJSON, rb_intern("Infinity")); + + rb_global_variable(&CMinusInfinity); + CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity")); + + rb_global_variable(&Encoding_UTF_8); + Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8")); + + rb_global_variable(&JSON_empty_string); + JSON_empty_string = rb_obj_hide(rb_utf8_str_new("", 0)); + + sym_max_nesting = ID2SYM(rb_intern("max_nesting")); + sym_allow_nan = ID2SYM(rb_intern("allow_nan")); + sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma")); + sym_allow_comments = ID2SYM(rb_intern("allow_comments")); + sym_allow_control_characters = ID2SYM(rb_intern("allow_control_characters")); + sym_allow_invalid_escape = ID2SYM(rb_intern("allow_invalid_escape")); + sym_symbolize_names = ID2SYM(rb_intern("symbolize_names")); + sym_freeze = ID2SYM(rb_intern("freeze")); + sym_on_load = ID2SYM(rb_intern("on_load")); + sym_decimal_class = ID2SYM(rb_intern("decimal_class")); + sym_allow_duplicate_key = ID2SYM(rb_intern("allow_duplicate_key")); + + i_new = rb_intern("new"); + i_try_convert = rb_intern("try_convert"); +#ifndef HAVE_RB_STR_TO_INTERNED_STR + i_uminus = rb_intern("-@"); +#endif + i_encode = rb_intern("encode"); + i_at_line = rb_intern("@line"); + i_at_column = rb_intern("@column"); + + binary_encindex = rb_ascii8bit_encindex(); + utf8_encindex = rb_utf8_encindex(); + enc_utf8 = rb_utf8_encoding(); + +#ifdef HAVE_SIMD + simd_impl = find_simd_implementation(); +#endif +} diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/conf.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/conf.rb new file mode 100644 index 0000000..76f774b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/conf.rb @@ -0,0 +1,24 @@ +case RbConfig::CONFIG['host_cpu'] +when /^(arm|aarch64)/ + # Try to compile a small program using NEON instructions + header, type, init, extra = 'arm_neon.h', 'uint8x16_t', 'vdupq_n_u8(32)', nil +when /^(x86_64|x64)/ + header, type, init, extra = 'x86intrin.h', '__m128i', '_mm_set1_epi8(32)', 'if (__builtin_cpu_supports("sse2")) { printf("OK"); }' +end +if header + if have_header(header) && try_compile(<<~SRC, '-Werror=implicit-function-declaration') + #{cpp_include(header)} + int main(int argc, char **argv) { + #{type} test = #{init}; + #{extra} + if (argc > 100000) printf("%p", &test); + return 0; + } + SRC + $defs.push("-DJSON_ENABLE_SIMD") + else + puts "Disable SIMD" + end +end + +have_header('cpuid.h') diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/simd.h b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/simd.h new file mode 100644 index 0000000..611b41b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/simd/simd.h @@ -0,0 +1,208 @@ +#include "../json.h" + +typedef enum { + SIMD_NONE, + SIMD_NEON, + SIMD_SSE2 +} SIMD_Implementation; + +#ifndef __has_builtin // Optional of course. + #define __has_builtin(x) 0 // Compatibility with non-clang compilers. +#endif + +#ifdef __clang__ +# if __has_builtin(__builtin_ctzll) +# define HAVE_BUILTIN_CTZLL 1 +# else +# define HAVE_BUILTIN_CTZLL 0 +# endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define HAVE_BUILTIN_CTZLL 1 +#else +# define HAVE_BUILTIN_CTZLL 0 +#endif + +static inline uint32_t trailing_zeros64(uint64_t input) +{ + JSON_ASSERT(input > 0); // __builtin_ctz(0) is undefined behavior + +#if HAVE_BUILTIN_CTZLL + return __builtin_ctzll(input); +#else + uint32_t trailing_zeros = 0; + uint64_t temp = input; + while ((temp & 1) == 0 && temp > 0) { + trailing_zeros++; + temp >>= 1; + } + return trailing_zeros; +#endif +} + +static inline int trailing_zeros(int input) +{ + JSON_ASSERT(input > 0); // __builtin_ctz(0) is undefined behavior + +#if HAVE_BUILTIN_CTZLL + return __builtin_ctz(input); +#else + int trailing_zeros = 0; + int temp = input; + while ((temp & 1) == 0 && temp > 0) { + trailing_zeros++; + temp >>= 1; + } + return trailing_zeros; +#endif +} + +#ifdef JSON_ENABLE_SIMD + +#define SIMD_MINIMUM_THRESHOLD 4 + +ALWAYS_INLINE(static) void json_fast_memcpy16(char *dst, const char *src, size_t len) +{ + RBIMPL_ASSERT_OR_ASSUME(len < 16); + RBIMPL_ASSERT_OR_ASSUME(len >= SIMD_MINIMUM_THRESHOLD); // 4 +#if defined(__has_builtin) && __has_builtin(__builtin_memcpy) + // If __builtin_memcpy is available, use it to copy between SIMD_MINIMUM_THRESHOLD (4) and vec_len-1 (15) bytes. + // These copies overlap. The first copy will copy the first 8 (or 4) bytes. The second copy will copy + // the last 8 (or 4) bytes but overlap with the first copy. The overlapping bytes will be in the correct + // position in both copies. + + // Please do not attempt to replace __builtin_memcpy with memcpy without profiling and/or looking at the + // generated assembly. On clang-specifically (tested on Apple clang version 17.0.0 (clang-1700.0.13.3)), + // when using memcpy, the compiler will notice the only difference is a 4 or 8 and generate a conditional + // select instruction instead of direct loads and stores with a branch. This ends up slower than the branch + // plus two loads and stores generated when using __builtin_memcpy. + if (len >= 8) { + __builtin_memcpy(dst, src, 8); + __builtin_memcpy(dst + len - 8, src + len - 8, 8); + } else { + __builtin_memcpy(dst, src, 4); + __builtin_memcpy(dst + len - 4, src + len - 4, 4); + } +#else + MEMCPY(dst, src, char, len); +#endif +} + +#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__aarch64__) || defined(_M_ARM64) +#include + +#define FIND_SIMD_IMPLEMENTATION_DEFINED 1 +static inline SIMD_Implementation find_simd_implementation(void) +{ + return SIMD_NEON; +} + +#define HAVE_SIMD 1 +#define HAVE_SIMD_NEON 1 + +// See: https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon +ALWAYS_INLINE(static) uint64_t neon_match_mask(uint8x16_t matches) +{ + const uint8x8_t res = vshrn_n_u16(vreinterpretq_u16_u8(matches), 4); + const uint64_t mask = vget_lane_u64(vreinterpret_u64_u8(res), 0); + return mask & 0x8888888888888888ull; +} + +ALWAYS_INLINE(static) uint64_t compute_chunk_mask_neon(const char *ptr) +{ + uint8x16_t chunk = vld1q_u8((const unsigned char *)ptr); + + // Trick: c < 32 || c == 34 can be factored as c ^ 2 < 33 + // https://lemire.me/blog/2025/04/13/detect-control-characters-quotes-and-backslashes-efficiently-using-swar/ + const uint8x16_t too_low_or_dbl_quote = vcltq_u8(veorq_u8(chunk, vdupq_n_u8(2)), vdupq_n_u8(33)); + + uint8x16_t has_backslash = vceqq_u8(chunk, vdupq_n_u8('\\')); + uint8x16_t needs_escape = vorrq_u8(too_low_or_dbl_quote, has_backslash); + return neon_match_mask(needs_escape); +} + +ALWAYS_INLINE(static) int string_scan_simd_neon(const char **ptr, const char *end, uint64_t *mask) +{ + while (*ptr + sizeof(uint8x16_t) <= end) { + uint64_t chunk_mask = compute_chunk_mask_neon(*ptr); + if (chunk_mask) { + *mask = chunk_mask; + return 1; + } + *ptr += sizeof(uint8x16_t); + } + return 0; +} + +#endif /* ARM Neon Support.*/ + +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) + +#ifdef HAVE_X86INTRIN_H +#include + +#define HAVE_SIMD 1 +#define HAVE_SIMD_SSE2 1 + +#ifdef HAVE_CPUID_H +#define FIND_SIMD_IMPLEMENTATION_DEFINED 1 + +#if defined(__clang__) || defined(__GNUC__) +#define TARGET_SSE2 __attribute__((target("sse2"))) +#else +#define TARGET_SSE2 +#endif + +#define _mm_cmpge_epu8(a, b) _mm_cmpeq_epi8(_mm_max_epu8(a, b), a) +#define _mm_cmple_epu8(a, b) _mm_cmpge_epu8(b, a) +#define _mm_cmpgt_epu8(a, b) _mm_xor_si128(_mm_cmple_epu8(a, b), _mm_set1_epi8(-1)) +#define _mm_cmplt_epu8(a, b) _mm_cmpgt_epu8(b, a) + +ALWAYS_INLINE(static) TARGET_SSE2 int compute_chunk_mask_sse2(const char *ptr) +{ + __m128i chunk = _mm_loadu_si128((__m128i const*)ptr); + // Trick: c < 32 || c == 34 can be factored as c ^ 2 < 33 + // https://lemire.me/blog/2025/04/13/detect-control-characters-quotes-and-backslashes-efficiently-using-swar/ + __m128i too_low_or_dbl_quote = _mm_cmplt_epu8(_mm_xor_si128(chunk, _mm_set1_epi8(2)), _mm_set1_epi8(33)); + __m128i has_backslash = _mm_cmpeq_epi8(chunk, _mm_set1_epi8('\\')); + __m128i needs_escape = _mm_or_si128(too_low_or_dbl_quote, has_backslash); + return _mm_movemask_epi8(needs_escape); +} + +ALWAYS_INLINE(static) TARGET_SSE2 int string_scan_simd_sse2(const char **ptr, const char *end, int *mask) +{ + while (*ptr + sizeof(__m128i) <= end) { + int chunk_mask = compute_chunk_mask_sse2(*ptr); + if (chunk_mask) { + *mask = chunk_mask; + return 1; + } + *ptr += sizeof(__m128i); + } + + return 0; +} + +#include +#endif /* HAVE_CPUID_H */ + +static inline SIMD_Implementation find_simd_implementation(void) +{ + // TODO Revisit. I think the SSE version now only uses SSE2 instructions. + if (__builtin_cpu_supports("sse2")) { + return SIMD_SSE2; + } + + return SIMD_NONE; +} + +#endif /* HAVE_X86INTRIN_H */ +#endif /* X86_64 Support */ + +#endif /* JSON_ENABLE_SIMD */ + +#ifndef FIND_SIMD_IMPLEMENTATION_DEFINED +static inline SIMD_Implementation find_simd_implementation(void) +{ + return SIMD_NONE; +} +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fast_float_parser.h b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fast_float_parser.h new file mode 100644 index 0000000..6e43b25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fast_float_parser.h @@ -0,0 +1,814 @@ +/* Eisel-Lemire decimal->double, ported from fast_float: + * include/fast_float/decimal_to_binary.h, the compute_float> + * + compute_product_approximation routines. + * + * Algorithm authors: Michael Eisel (original approach) and Daniel Lemire + * (formalization, proof, and the fast_float implementation) — hence "Eisel-Lemire". + * + * Copyright (c) 2021 The fast_float authors. Tri-licensed Apache-2.0 / MIT / BSL-1.0; + * used here under MIT — see LICENSE-fast_float-MIT in this directory. + * + * C99 Port by Tilo Sloboda. + */ + +#ifndef FFP_H +#define FFP_H +#include +#include +#include + +#define FFP_SMALLEST_POWER_OF_FIVE (-342) +#define FFP_LARGEST_POWER_OF_FIVE (308) +static const uint64_t ffp_power_of_five_128[2 * (308 - (-342) + 1)] = { + 0xeef453d6923bd65a, 0x113faa2906a13b3f, + 0x9558b4661b6565f8, 0x4ac7ca59a424c507, + 0xbaaee17fa23ebf76, 0x5d79bcf00d2df649, + 0xe95a99df8ace6f53, 0xf4d82c2c107973dc, + 0x91d8a02bb6c10594, 0x79071b9b8a4be869, + 0xb64ec836a47146f9, 0x9748e2826cdee284, + 0xe3e27a444d8d98b7, 0xfd1b1b2308169b25, + 0x8e6d8c6ab0787f72, 0xfe30f0f5e50e20f7, + 0xb208ef855c969f4f, 0xbdbd2d335e51a935, + 0xde8b2b66b3bc4723, 0xad2c788035e61382, + 0x8b16fb203055ac76, 0x4c3bcb5021afcc31, + 0xaddcb9e83c6b1793, 0xdf4abe242a1bbf3d, + 0xd953e8624b85dd78, 0xd71d6dad34a2af0d, + 0x87d4713d6f33aa6b, 0x8672648c40e5ad68, + 0xa9c98d8ccb009506, 0x680efdaf511f18c2, + 0xd43bf0effdc0ba48, 0x212bd1b2566def2, + 0x84a57695fe98746d, 0x14bb630f7604b57, + 0xa5ced43b7e3e9188, 0x419ea3bd35385e2d, + 0xcf42894a5dce35ea, 0x52064cac828675b9, + 0x818995ce7aa0e1b2, 0x7343efebd1940993, + 0xa1ebfb4219491a1f, 0x1014ebe6c5f90bf8, + 0xca66fa129f9b60a6, 0xd41a26e077774ef6, + 0xfd00b897478238d0, 0x8920b098955522b4, + 0x9e20735e8cb16382, 0x55b46e5f5d5535b0, + 0xc5a890362fddbc62, 0xeb2189f734aa831d, + 0xf712b443bbd52b7b, 0xa5e9ec7501d523e4, + 0x9a6bb0aa55653b2d, 0x47b233c92125366e, + 0xc1069cd4eabe89f8, 0x999ec0bb696e840a, + 0xf148440a256e2c76, 0xc00670ea43ca250d, + 0x96cd2a865764dbca, 0x380406926a5e5728, + 0xbc807527ed3e12bc, 0xc605083704f5ecf2, + 0xeba09271e88d976b, 0xf7864a44c633682e, + 0x93445b8731587ea3, 0x7ab3ee6afbe0211d, + 0xb8157268fdae9e4c, 0x5960ea05bad82964, + 0xe61acf033d1a45df, 0x6fb92487298e33bd, + 0x8fd0c16206306bab, 0xa5d3b6d479f8e056, + 0xb3c4f1ba87bc8696, 0x8f48a4899877186c, + 0xe0b62e2929aba83c, 0x331acdabfe94de87, + 0x8c71dcd9ba0b4925, 0x9ff0c08b7f1d0b14, + 0xaf8e5410288e1b6f, 0x7ecf0ae5ee44dd9, + 0xdb71e91432b1a24a, 0xc9e82cd9f69d6150, + 0x892731ac9faf056e, 0xbe311c083a225cd2, + 0xab70fe17c79ac6ca, 0x6dbd630a48aaf406, + 0xd64d3d9db981787d, 0x92cbbccdad5b108, + 0x85f0468293f0eb4e, 0x25bbf56008c58ea5, + 0xa76c582338ed2621, 0xaf2af2b80af6f24e, + 0xd1476e2c07286faa, 0x1af5af660db4aee1, + 0x82cca4db847945ca, 0x50d98d9fc890ed4d, + 0xa37fce126597973c, 0xe50ff107bab528a0, + 0xcc5fc196fefd7d0c, 0x1e53ed49a96272c8, + 0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7a, + 0x9faacf3df73609b1, 0x77b191618c54e9ac, + 0xc795830d75038c1d, 0xd59df5b9ef6a2417, + 0xf97ae3d0d2446f25, 0x4b0573286b44ad1d, + 0x9becce62836ac577, 0x4ee367f9430aec32, + 0xc2e801fb244576d5, 0x229c41f793cda73f, + 0xf3a20279ed56d48a, 0x6b43527578c1110f, + 0x9845418c345644d6, 0x830a13896b78aaa9, + 0xbe5691ef416bd60c, 0x23cc986bc656d553, + 0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa8, + 0x94b3a202eb1c3f39, 0x7bf7d71432f3d6a9, + 0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc53, + 0xe858ad248f5c22c9, 0xd1b3400f8f9cff68, + 0x91376c36d99995be, 0x23100809b9c21fa1, + 0xb58547448ffffb2d, 0xabd40a0c2832a78a, + 0xe2e69915b3fff9f9, 0x16c90c8f323f516c, + 0x8dd01fad907ffc3b, 0xae3da7d97f6792e3, + 0xb1442798f49ffb4a, 0x99cd11cfdf41779c, + 0xdd95317f31c7fa1d, 0x40405643d711d583, + 0x8a7d3eef7f1cfc52, 0x482835ea666b2572, + 0xad1c8eab5ee43b66, 0xda3243650005eecf, + 0xd863b256369d4a40, 0x90bed43e40076a82, + 0x873e4f75e2224e68, 0x5a7744a6e804a291, + 0xa90de3535aaae202, 0x711515d0a205cb36, + 0xd3515c2831559a83, 0xd5a5b44ca873e03, + 0x8412d9991ed58091, 0xe858790afe9486c2, + 0xa5178fff668ae0b6, 0x626e974dbe39a872, + 0xce5d73ff402d98e3, 0xfb0a3d212dc8128f, + 0x80fa687f881c7f8e, 0x7ce66634bc9d0b99, + 0xa139029f6a239f72, 0x1c1fffc1ebc44e80, + 0xc987434744ac874e, 0xa327ffb266b56220, + 0xfbe9141915d7a922, 0x4bf1ff9f0062baa8, + 0x9d71ac8fada6c9b5, 0x6f773fc3603db4a9, + 0xc4ce17b399107c22, 0xcb550fb4384d21d3, + 0xf6019da07f549b2b, 0x7e2a53a146606a48, + 0x99c102844f94e0fb, 0x2eda7444cbfc426d, + 0xc0314325637a1939, 0xfa911155fefb5308, + 0xf03d93eebc589f88, 0x793555ab7eba27ca, + 0x96267c7535b763b5, 0x4bc1558b2f3458de, + 0xbbb01b9283253ca2, 0x9eb1aaedfb016f16, + 0xea9c227723ee8bcb, 0x465e15a979c1cadc, + 0x92a1958a7675175f, 0xbfacd89ec191ec9, + 0xb749faed14125d36, 0xcef980ec671f667b, + 0xe51c79a85916f484, 0x82b7e12780e7401a, + 0x8f31cc0937ae58d2, 0xd1b2ecb8b0908810, + 0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa15, + 0xdfbdcece67006ac9, 0x67a791e093e1d49a, + 0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e0, + 0xaecc49914078536d, 0x58fae9f773886e18, + 0xda7f5bf590966848, 0xaf39a475506a899e, + 0x888f99797a5e012d, 0x6d8406c952429603, + 0xaab37fd7d8f58178, 0xc8e5087ba6d33b83, + 0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a64, + 0x855c3be0a17fcd26, 0x5cf2eea09a55067f, + 0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481e, + 0xd0601d8efc57b08b, 0xf13b94daf124da26, + 0x823c12795db6ce57, 0x76c53d08d6b70858, + 0xa2cb1717b52481ed, 0x54768c4b0c64ca6e, + 0xcb7ddcdda26da268, 0xa9942f5dcf7dfd09, + 0xfe5d54150b090b02, 0xd3f93b35435d7c4c, + 0x9efa548d26e5a6e1, 0xc47bc5014a1a6daf, + 0xc6b8e9b0709f109a, 0x359ab6419ca1091b, + 0xf867241c8cc6d4c0, 0xc30163d203c94b62, + 0x9b407691d7fc44f8, 0x79e0de63425dcf1d, + 0xc21094364dfb5636, 0x985915fc12f542e4, + 0xf294b943e17a2bc4, 0x3e6f5b7b17b2939d, + 0x979cf3ca6cec5b5a, 0xa705992ceecf9c42, + 0xbd8430bd08277231, 0x50c6ff782a838353, + 0xece53cec4a314ebd, 0xa4f8bf5635246428, + 0x940f4613ae5ed136, 0x871b7795e136be99, + 0xb913179899f68584, 0x28e2557b59846e3f, + 0xe757dd7ec07426e5, 0x331aeada2fe589cf, + 0x9096ea6f3848984f, 0x3ff0d2c85def7621, + 0xb4bca50b065abe63, 0xfed077a756b53a9, + 0xe1ebce4dc7f16dfb, 0xd3e8495912c62894, + 0x8d3360f09cf6e4bd, 0x64712dd7abbbd95c, + 0xb080392cc4349dec, 0xbd8d794d96aacfb3, + 0xdca04777f541c567, 0xecf0d7a0fc5583a0, + 0x89e42caaf9491b60, 0xf41686c49db57244, + 0xac5d37d5b79b6239, 0x311c2875c522ced5, + 0xd77485cb25823ac7, 0x7d633293366b828b, + 0x86a8d39ef77164bc, 0xae5dff9c02033197, + 0xa8530886b54dbdeb, 0xd9f57f830283fdfc, + 0xd267caa862a12d66, 0xd072df63c324fd7b, + 0x8380dea93da4bc60, 0x4247cb9e59f71e6d, + 0xa46116538d0deb78, 0x52d9be85f074e608, + 0xcd795be870516656, 0x67902e276c921f8b, + 0x806bd9714632dff6, 0xba1cd8a3db53b6, + 0xa086cfcd97bf97f3, 0x80e8a40eccd228a4, + 0xc8a883c0fdaf7df0, 0x6122cd128006b2cd, + 0xfad2a4b13d1b5d6c, 0x796b805720085f81, + 0x9cc3a6eec6311a63, 0xcbe3303674053bb0, + 0xc3f490aa77bd60fc, 0xbedbfc4411068a9c, + 0xf4f1b4d515acb93b, 0xee92fb5515482d44, + 0x991711052d8bf3c5, 0x751bdd152d4d1c4a, + 0xbf5cd54678eef0b6, 0xd262d45a78a0635d, + 0xef340a98172aace4, 0x86fb897116c87c34, + 0x9580869f0e7aac0e, 0xd45d35e6ae3d4da0, + 0xbae0a846d2195712, 0x8974836059cca109, + 0xe998d258869facd7, 0x2bd1a438703fc94b, + 0x91ff83775423cc06, 0x7b6306a34627ddcf, + 0xb67f6455292cbf08, 0x1a3bc84c17b1d542, + 0xe41f3d6a7377eeca, 0x20caba5f1d9e4a93, + 0x8e938662882af53e, 0x547eb47b7282ee9c, + 0xb23867fb2a35b28d, 0xe99e619a4f23aa43, + 0xdec681f9f4c31f31, 0x6405fa00e2ec94d4, + 0x8b3c113c38f9f37e, 0xde83bc408dd3dd04, + 0xae0b158b4738705e, 0x9624ab50b148d445, + 0xd98ddaee19068c76, 0x3badd624dd9b0957, + 0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d6, + 0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4c, + 0xd47487cc8470652b, 0x7647c3200069671f, + 0x84c8d4dfd2c63f3b, 0x29ecd9f40041e073, + 0xa5fb0a17c777cf09, 0xf468107100525890, + 0xcf79cc9db955c2cc, 0x7182148d4066eeb4, + 0x81ac1fe293d599bf, 0xc6f14cd848405530, + 0xa21727db38cb002f, 0xb8ada00e5a506a7c, + 0xca9cf1d206fdc03b, 0xa6d90811f0e4851c, + 0xfd442e4688bd304a, 0x908f4a166d1da663, + 0x9e4a9cec15763e2e, 0x9a598e4e043287fe, + 0xc5dd44271ad3cdba, 0x40eff1e1853f29fd, + 0xf7549530e188c128, 0xd12bee59e68ef47c, + 0x9a94dd3e8cf578b9, 0x82bb74f8301958ce, + 0xc13a148e3032d6e7, 0xe36a52363c1faf01, + 0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac1, + 0x96f5600f15a7b7e5, 0x29ab103a5ef8c0b9, + 0xbcb2b812db11a5de, 0x7415d448f6b6f0e7, + 0xebdf661791d60f56, 0x111b495b3464ad21, + 0x936b9fcebb25c995, 0xcab10dd900beec34, + 0xb84687c269ef3bfb, 0x3d5d514f40eea742, + 0xe65829b3046b0afa, 0xcb4a5a3112a5112, + 0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ab, + 0xb3f4e093db73a093, 0x59ed216765690f56, + 0xe0f218b8d25088b8, 0x306869c13ec3532c, + 0x8c974f7383725573, 0x1e414218c73a13fb, + 0xafbd2350644eeacf, 0xe5d1929ef90898fa, + 0xdbac6c247d62a583, 0xdf45f746b74abf39, + 0x894bc396ce5da772, 0x6b8bba8c328eb783, + 0xab9eb47c81f5114f, 0x66ea92f3f326564, + 0xd686619ba27255a2, 0xc80a537b0efefebd, + 0x8613fd0145877585, 0xbd06742ce95f5f36, + 0xa798fc4196e952e7, 0x2c48113823b73704, + 0xd17f3b51fca3a7a0, 0xf75a15862ca504c5, + 0x82ef85133de648c4, 0x9a984d73dbe722fb, + 0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebba, + 0xcc963fee10b7d1b3, 0x318df905079926a8, + 0xffbbcfe994e5c61f, 0xfdf17746497f7052, + 0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa633, + 0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc0, + 0xf9bd690a1b68637b, 0x3dfdce7aa3c673b0, + 0x9c1661a651213e2d, 0x6bea10ca65c084e, + 0xc31bfa0fe5698db8, 0x486e494fcff30a62, + 0xf3e2f893dec3f126, 0x5a89dba3c3efccfa, + 0x986ddb5c6b3a76b7, 0xf89629465a75e01c, + 0xbe89523386091465, 0xf6bbb397f1135823, + 0xee2ba6c0678b597f, 0x746aa07ded582e2c, + 0x94db483840b717ef, 0xa8c2a44eb4571cdc, + 0xba121a4650e4ddeb, 0x92f34d62616ce413, + 0xe896a0d7e51e1566, 0x77b020baf9c81d17, + 0x915e2486ef32cd60, 0xace1474dc1d122e, + 0xb5b5ada8aaff80b8, 0xd819992132456ba, + 0xe3231912d5bf60e6, 0x10e1fff697ed6c69, + 0x8df5efabc5979c8f, 0xca8d3ffa1ef463c1, + 0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb2, + 0xddd0467c64bce4a0, 0xac7cb3f6d05ddbde, + 0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96b, + 0xad4ab7112eb3929d, 0x86c16c98d2c953c6, + 0xd89d64d57a607744, 0xe871c7bf077ba8b7, + 0x87625f056c7c4a8b, 0x11471cd764ad4972, + 0xa93af6c6c79b5d2d, 0xd598e40d3dd89bcf, + 0xd389b47879823479, 0x4aff1d108d4ec2c3, + 0x843610cb4bf160cb, 0xcedf722a585139ba, + 0xa54394fe1eedb8fe, 0xc2974eb4ee658828, + 0xce947a3da6a9273e, 0x733d226229feea32, + 0x811ccc668829b887, 0x806357d5a3f525f, + 0xa163ff802a3426a8, 0xca07c2dcb0cf26f7, + 0xc9bcff6034c13052, 0xfc89b393dd02f0b5, + 0xfc2c3f3841f17c67, 0xbbac2078d443ace2, + 0x9d9ba7832936edc0, 0xd54b944b84aa4c0d, + 0xc5029163f384a931, 0xa9e795e65d4df11, + 0xf64335bcf065d37d, 0x4d4617b5ff4a16d5, + 0x99ea0196163fa42e, 0x504bced1bf8e4e45, + 0xc06481fb9bcf8d39, 0xe45ec2862f71e1d6, + 0xf07da27a82c37088, 0x5d767327bb4e5a4c, + 0x964e858c91ba2655, 0x3a6a07f8d510f86f, + 0xbbe226efb628afea, 0x890489f70a55368b, + 0xeadab0aba3b2dbe5, 0x2b45ac74ccea842e, + 0x92c8ae6b464fc96f, 0x3b0b8bc90012929d, + 0xb77ada0617e3bbcb, 0x9ce6ebb40173744, + 0xe55990879ddcaabd, 0xcc420a6a101d0515, + 0x8f57fa54c2a9eab6, 0x9fa946824a12232d, + 0xb32df8e9f3546564, 0x47939822dc96abf9, + 0xdff9772470297ebd, 0x59787e2b93bc56f7, + 0x8bfbea76c619ef36, 0x57eb4edb3c55b65a, + 0xaefae51477a06b03, 0xede622920b6b23f1, + 0xdab99e59958885c4, 0xe95fab368e45eced, + 0x88b402f7fd75539b, 0x11dbcb0218ebb414, + 0xaae103b5fcd2a881, 0xd652bdc29f26a119, + 0xd59944a37c0752a2, 0x4be76d3346f0495f, + 0x857fcae62d8493a5, 0x6f70a4400c562ddb, + 0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb952, + 0xd097ad07a71f26b2, 0x7e2000a41346a7a7, + 0x825ecc24c873782f, 0x8ed400668c0c28c8, + 0xa2f67f2dfa90563b, 0x728900802f0f32fa, + 0xcbb41ef979346bca, 0x4f2b40a03ad2ffb9, + 0xfea126b7d78186bc, 0xe2f610c84987bfa8, + 0x9f24b832e6b0f436, 0xdd9ca7d2df4d7c9, + 0xc6ede63fa05d3143, 0x91503d1c79720dbb, + 0xf8a95fcf88747d94, 0x75a44c6397ce912a, + 0x9b69dbe1b548ce7c, 0xc986afbe3ee11aba, + 0xc24452da229b021b, 0xfbe85badce996168, + 0xf2d56790ab41c2a2, 0xfae27299423fb9c3, + 0x97c560ba6b0919a5, 0xdccd879fc967d41a, + 0xbdb6b8e905cb600f, 0x5400e987bbc1c920, + 0xed246723473e3813, 0x290123e9aab23b68, + 0x9436c0760c86e30b, 0xf9a0b6720aaf6521, + 0xb94470938fa89bce, 0xf808e40e8d5b3e69, + 0xe7958cb87392c2c2, 0xb60b1d1230b20e04, + 0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c2, + 0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af3, + 0xe2280b6c20dd5232, 0x25c6da63c38de1b0, + 0x8d590723948a535f, 0x579c487e5a38ad0e, + 0xb0af48ec79ace837, 0x2d835a9df0c6d851, + 0xdcdb1b2798182244, 0xf8e431456cf88e65, + 0x8a08f0f8bf0f156b, 0x1b8e9ecb641b58ff, + 0xac8b2d36eed2dac5, 0xe272467e3d222f3f, + 0xd7adf884aa879177, 0x5b0ed81dcc6abb0f, + 0x86ccbb52ea94baea, 0x98e947129fc2b4e9, + 0xa87fea27a539e9a5, 0x3f2398d747b36224, + 0xd29fe4b18e88640e, 0x8eec7f0d19a03aad, + 0x83a3eeeef9153e89, 0x1953cf68300424ac, + 0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd7, + 0xcdb02555653131b6, 0x3792f412cb06794d, + 0x808e17555f3ebf11, 0xe2bbd88bbee40bd0, + 0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec4, + 0xc8de047564d20a8b, 0xf245825a5a445275, + 0xfb158592be068d2e, 0xeed6e2f0f0d56712, + 0x9ced737bb6c4183d, 0x55464dd69685606b, + 0xc428d05aa4751e4c, 0xaa97e14c3c26b886, + 0xf53304714d9265df, 0xd53dd99f4b3066a8, + 0x993fe2c6d07b7fab, 0xe546a8038efe4029, + 0xbf8fdb78849a5f96, 0xde98520472bdd033, + 0xef73d256a5c0f77c, 0x963e66858f6d4440, + 0x95a8637627989aad, 0xdde7001379a44aa8, + 0xbb127c53b17ec159, 0x5560c018580d5d52, + 0xe9d71b689dde71af, 0xaab8f01e6e10b4a6, + 0x9226712162ab070d, 0xcab3961304ca70e8, + 0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d22, + 0xe45c10c42a2b3b05, 0x8cb89a7db77c506a, + 0x8eb98a7a9a5b04e3, 0x77f3608e92adb242, + 0xb267ed1940f1c61c, 0x55f038b237591ed3, + 0xdf01e85f912e37a3, 0x6b6c46dec52f6688, + 0x8b61313bbabce2c6, 0x2323ac4b3b3da015, + 0xae397d8aa96c1b77, 0xabec975e0a0d081a, + 0xd9c7dced53c72255, 0x96e7bd358c904a21, + 0x881cea14545c7575, 0x7e50d64177da2e54, + 0xaa242499697392d2, 0xdde50bd1d5d0b9e9, + 0xd4ad2dbfc3d07787, 0x955e4ec64b44e864, + 0x84ec3c97da624ab4, 0xbd5af13bef0b113e, + 0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58e, + 0xcfb11ead453994ba, 0x67de18eda5814af2, + 0x81ceb32c4b43fcf4, 0x80eacf948770ced7, + 0xa2425ff75e14fc31, 0xa1258379a94d028d, + 0xcad2f7f5359a3b3e, 0x96ee45813a04330, + 0xfd87b5f28300ca0d, 0x8bca9d6e188853fc, + 0x9e74d1b791e07e48, 0x775ea264cf55347e, + 0xc612062576589dda, 0x95364afe032a819e, + 0xf79687aed3eec551, 0x3a83ddbd83f52205, + 0x9abe14cd44753b52, 0xc4926a9672793543, + 0xc16d9a0095928a27, 0x75b7053c0f178294, + 0xf1c90080baf72cb1, 0x5324c68b12dd6339, + 0x971da05074da7bee, 0xd3f6fc16ebca5e04, + 0xbce5086492111aea, 0x88f4bb1ca6bcf585, + 0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6, + 0x9392ee8e921d5d07, 0x3aff322e62439fd0, + 0xb877aa3236a4b449, 0x9befeb9fad487c3, + 0xe69594bec44de15b, 0x4c2ebe687989a9b4, + 0x901d7cf73ab0acd9, 0xf9d37014bf60a11, + 0xb424dc35095cd80f, 0x538484c19ef38c95, + 0xe12e13424bb40e13, 0x2865a5f206b06fba, + 0x8cbccc096f5088cb, 0xf93f87b7442e45d4, + 0xafebff0bcb24aafe, 0xf78f69a51539d749, + 0xdbe6fecebdedd5be, 0xb573440e5a884d1c, + 0x89705f4136b4a597, 0x31680a88f8953031, + 0xabcc77118461cefc, 0xfdc20d2b36ba7c3e, + 0xd6bf94d5e57a42bc, 0x3d32907604691b4d, + 0x8637bd05af6c69b5, 0xa63f9a49c2c1b110, + 0xa7c5ac471b478423, 0xfcf80dc33721d54, + 0xd1b71758e219652b, 0xd3c36113404ea4a9, + 0x83126e978d4fdf3b, 0x645a1cac083126ea, + 0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4, + 0xcccccccccccccccc, 0xcccccccccccccccd, + 0x8000000000000000, 0x0, + 0xa000000000000000, 0x0, + 0xc800000000000000, 0x0, + 0xfa00000000000000, 0x0, + 0x9c40000000000000, 0x0, + 0xc350000000000000, 0x0, + 0xf424000000000000, 0x0, + 0x9896800000000000, 0x0, + 0xbebc200000000000, 0x0, + 0xee6b280000000000, 0x0, + 0x9502f90000000000, 0x0, + 0xba43b74000000000, 0x0, + 0xe8d4a51000000000, 0x0, + 0x9184e72a00000000, 0x0, + 0xb5e620f480000000, 0x0, + 0xe35fa931a0000000, 0x0, + 0x8e1bc9bf04000000, 0x0, + 0xb1a2bc2ec5000000, 0x0, + 0xde0b6b3a76400000, 0x0, + 0x8ac7230489e80000, 0x0, + 0xad78ebc5ac620000, 0x0, + 0xd8d726b7177a8000, 0x0, + 0x878678326eac9000, 0x0, + 0xa968163f0a57b400, 0x0, + 0xd3c21bcecceda100, 0x0, + 0x84595161401484a0, 0x0, + 0xa56fa5b99019a5c8, 0x0, + 0xcecb8f27f4200f3a, 0x0, + 0x813f3978f8940984, 0x4000000000000000, + 0xa18f07d736b90be5, 0x5000000000000000, + 0xc9f2c9cd04674ede, 0xa400000000000000, + 0xfc6f7c4045812296, 0x4d00000000000000, + 0x9dc5ada82b70b59d, 0xf020000000000000, + 0xc5371912364ce305, 0x6c28000000000000, + 0xf684df56c3e01bc6, 0xc732000000000000, + 0x9a130b963a6c115c, 0x3c7f400000000000, + 0xc097ce7bc90715b3, 0x4b9f100000000000, + 0xf0bdc21abb48db20, 0x1e86d40000000000, + 0x96769950b50d88f4, 0x1314448000000000, + 0xbc143fa4e250eb31, 0x17d955a000000000, + 0xeb194f8e1ae525fd, 0x5dcfab0800000000, + 0x92efd1b8d0cf37be, 0x5aa1cae500000000, + 0xb7abc627050305ad, 0xf14a3d9e40000000, + 0xe596b7b0c643c719, 0x6d9ccd05d0000000, + 0x8f7e32ce7bea5c6f, 0xe4820023a2000000, + 0xb35dbf821ae4f38b, 0xdda2802c8a800000, + 0xe0352f62a19e306e, 0xd50b2037ad200000, + 0x8c213d9da502de45, 0x4526f422cc340000, + 0xaf298d050e4395d6, 0x9670b12b7f410000, + 0xdaf3f04651d47b4c, 0x3c0cdd765f114000, + 0x88d8762bf324cd0f, 0xa5880a69fb6ac800, + 0xab0e93b6efee0053, 0x8eea0d047a457a00, + 0xd5d238a4abe98068, 0x72a4904598d6d880, + 0x85a36366eb71f041, 0x47a6da2b7f864750, + 0xa70c3c40a64e6c51, 0x999090b65f67d924, + 0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d, + 0x82818f1281ed449f, 0xbff8f10e7a8921a4, + 0xa321f2d7226895c7, 0xaff72d52192b6a0d, + 0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490, + 0xfee50b7025c36a08, 0x2f236d04753d5b4, + 0x9f4f2726179a2245, 0x1d762422c946590, + 0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5, + 0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2, + 0x9b934c3b330c8577, 0x63cc55f49f88eb2f, + 0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb, + 0xf316271c7fc3908a, 0x8bef464e3945ef7a, + 0x97edd871cfda3a56, 0x97758bf0e3cbb5ac, + 0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317, + 0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd, + 0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a, + 0xb975d6b6ee39e436, 0xb3e2fd538e122b44, + 0xe7d34c64a9c85d44, 0x60dbbca87196b616, + 0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd, + 0xb51d13aea4a488dd, 0x6babab6398bdbe41, + 0xe264589a4dcdab14, 0xc696963c7eed2dd1, + 0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2, + 0xb0de65388cc8ada8, 0x3b25a55f43294bcb, + 0xdd15fe86affad912, 0x49ef0eb713f39ebe, + 0x8a2dbf142dfcc7ab, 0x6e3569326c784337, + 0xacb92ed9397bf996, 0x49c2c37f07965404, + 0xd7e77a8f87daf7fb, 0xdc33745ec97be906, + 0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3, + 0xa8acd7c0222311bc, 0xc40832ea0d68ce0c, + 0xd2d80db02aabd62b, 0xf50a3fa490c30190, + 0x83c7088e1aab65db, 0x792667c6da79e0fa, + 0xa4b8cab1a1563f52, 0x577001b891185938, + 0xcde6fd5e09abcf26, 0xed4c0226b55e6f86, + 0x80b05e5ac60b6178, 0x544f8158315b05b4, + 0xa0dc75f1778e39d6, 0x696361ae3db1c721, + 0xc913936dd571c84c, 0x3bc3a19cd1e38e9, + 0xfb5878494ace3a5f, 0x4ab48a04065c723, + 0x9d174b2dcec0e47b, 0x62eb0d64283f9c76, + 0xc45d1df942711d9a, 0x3ba5d0bd324f8394, + 0xf5746577930d6500, 0xca8f44ec7ee36479, + 0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb, + 0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e, + 0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e, + 0x95d04aee3b80ece5, 0xbba1f1d158724a12, + 0xbb445da9ca61281f, 0x2a8a6e45ae8edc97, + 0xea1575143cf97226, 0xf52d09d71a3293bd, + 0x924d692ca61be758, 0x593c2626705f9c56, + 0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c, + 0xe498f455c38b997a, 0xb6dfb9c0f956447, + 0x8edf98b59a373fec, 0x4724bd4189bd5eac, + 0xb2977ee300c50fe7, 0x58edec91ec2cb657, + 0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed, + 0x8b865b215899f46c, 0xbd79e0d20082ee74, + 0xae67f1e9aec07187, 0xecd8590680a3aa11, + 0xda01ee641a708de9, 0xe80e6f4820cc9495, + 0x884134fe908658b2, 0x3109058d147fdcdd, + 0xaa51823e34a7eede, 0xbd4b46f0599fd415, + 0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a, + 0x850fadc09923329e, 0x3e2cf6bc604ddb0, + 0xa6539930bf6bff45, 0x84db8346b786151c, + 0xcfe87f7cef46ff16, 0xe612641865679a63, + 0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e, + 0xa26da3999aef7749, 0xe3be5e330f38f09d, + 0xcb090c8001ab551c, 0x5cadf5bfd3072cc5, + 0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6, + 0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa, + 0xc646d63501a1511d, 0xb281e1fd541501b8, + 0xf7d88bc24209a565, 0x1f225a7ca91a4226, + 0x9ae757596946075f, 0x3375788de9b06958, + 0xc1a12d2fc3978937, 0x52d6b1641c83ae, + 0xf209787bb47d6b84, 0xc0678c5dbd23a49a, + 0x9745eb4d50ce6332, 0xf840b7ba963646e0, + 0xbd176620a501fbff, 0xb650e5a93bc3d898, + 0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe, + 0x93ba47c980e98cdf, 0xc66f336c36b10137, + 0xb8a8d9bbe123f017, 0xb80b0047445d4184, + 0xe6d3102ad96cec1d, 0xa60dc059157491e5, + 0x9043ea1ac7e41392, 0x87c89837ad68db2f, + 0xb454e4a179dd1877, 0x29babe4598c311fb, + 0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a, + 0x8ce2529e2734bb1d, 0x1899e4a65f58660c, + 0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f, + 0xdc21a1171d42645d, 0x76707543f4fa1f73, + 0x899504ae72497eba, 0x6a06494a791c53a8, + 0xabfa45da0edbde69, 0x487db9d17636892, + 0xd6f8d7509292d603, 0x45a9d2845d3c42b6, + 0x865b86925b9bc5c2, 0xb8a2392ba45a9b2, + 0xa7f26836f282b732, 0x8e6cac7768d7141e, + 0xd1ef0244af2364ff, 0x3207d795430cd926, + 0x8335616aed761f1f, 0x7f44e6bd49e807b8, + 0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6, + 0xcd036837130890a1, 0x36dba887c37a8c0f, + 0x802221226be55a64, 0xc2494954da2c9789, + 0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c, + 0xc83553c5c8965d3d, 0x6f92829494e5acc7, + 0xfa42a8b73abbf48c, 0xcb772339ba1f17f9, + 0x9c69a97284b578d7, 0xff2a760414536efb, + 0xc38413cf25e2d70d, 0xfef5138519684aba, + 0xf46518c2ef5b8cd1, 0x7eb258665fc25d69, + 0x98bf2f79d5993802, 0xef2f773ffbd97a61, + 0xbeeefb584aff8603, 0xaafb550ffacfd8fa, + 0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38, + 0x952ab45cfa97a0b2, 0xdd945a747bf26183, + 0xba756174393d88df, 0x94f971119aeef9e4, + 0xe912b9d1478ceb17, 0x7a37cd5601aab85d, + 0x91abb422ccb812ee, 0xac62e055c10ab33a, + 0xb616a12b7fe617aa, 0x577b986b314d6009, + 0xe39c49765fdf9d94, 0xed5a7e85fda0b80b, + 0x8e41ade9fbebc27d, 0x14588f13be847307, + 0xb1d219647ae6b31c, 0x596eb2d8ae258fc8, + 0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb, + 0x8aec23d680043bee, 0x25de7bb9480d5854, + 0xada72ccc20054ae9, 0xaf561aa79a10ae6a, + 0xd910f7ff28069da4, 0x1b2ba1518094da04, + 0x87aa9aff79042286, 0x90fb44d2f05d0842, + 0xa99541bf57452b28, 0x353a1607ac744a53, + 0xd3fa922f2d1675f2, 0x42889b8997915ce8, + 0x847c9b5d7c2e09b7, 0x69956135febada11, + 0xa59bc234db398c25, 0x43fab9837e699095, + 0xcf02b2c21207ef2e, 0x94f967e45e03f4bb, + 0x8161afb94b44f57d, 0x1d1be0eebac278f5, + 0xa1ba1ba79e1632dc, 0x6462d92a69731732, + 0xca28a291859bbf93, 0x7d7b8f7503cfdcfe, + 0xfcb2cb35e702af78, 0x5cda735244c3d43e, + 0x9defbf01b061adab, 0x3a0888136afa64a7, + 0xc56baec21c7a1916, 0x88aaa1845b8fdd0, + 0xf6c69a72a3989f5b, 0x8aad549e57273d45, + 0x9a3c2087a63f6399, 0x36ac54e2f678864b, + 0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd, + 0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5, + 0x969eb7c47859e743, 0x9f644ae5a4b1b325, + 0xbc4665b596706114, 0x873d5d9f0dde1fee, + 0xeb57ff22fc0c7959, 0xa90cb506d155a7ea, + 0x9316ff75dd87cbd8, 0x9a7f12442d588f2, + 0xb7dcbf5354e9bece, 0xc11ed6d538aeb2f, + 0xe5d3ef282a242e81, 0x8f1668c8a86da5fa, + 0x8fa475791a569d10, 0xf96e017d694487bc, + 0xb38d92d760ec4455, 0x37c981dcc395a9ac, + 0xe070f78d3927556a, 0x85bbe253f47b1417, + 0x8c469ab843b89562, 0x93956d7478ccec8e, + 0xaf58416654a6babb, 0x387ac8d1970027b2, + 0xdb2e51bfe9d0696a, 0x6997b05fcc0319e, + 0x88fcf317f22241e2, 0x441fece3bdf81f03, + 0xab3c2fddeeaad25a, 0xd527e81cad7626c3, + 0xd60b3bd56a5586f1, 0x8a71e223d8d3b074, + 0x85c7056562757456, 0xf6872d5667844e49, + 0xa738c6bebb12d16c, 0xb428f8ac016561db, + 0xd106f86e69d785c7, 0xe13336d701beba52, + 0x82a45b450226b39c, 0xecc0024661173473, + 0xa34d721642b06084, 0x27f002d7f95d0190, + 0xcc20ce9bd35c78a5, 0x31ec038df7b441f4, + 0xff290242c83396ce, 0x7e67047175a15271, + 0x9f79a169bd203e41, 0xf0062c6e984d386, + 0xc75809c42c684dd1, 0x52c07b78a3e60868, + 0xf92e0c3537826145, 0xa7709a56ccdf8a82, + 0x9bbcc7a142b17ccb, 0x88a66076400bb691, + 0xc2abf989935ddbfe, 0x6acff893d00ea435, + 0xf356f7ebf83552fe, 0x583f6b8c4124d43, + 0x98165af37b2153de, 0xc3727a337a8b704a, + 0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c, + 0xeda2ee1c7064130c, 0x1162def06f79df73, + 0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8, + 0xb9a74a0637ce2ee1, 0x6d953e2bd7173692, + 0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437, + 0x910ab1d4db9914a0, 0x1d9c9892400a22a2, + 0xb54d5e4a127f59c8, 0x2503beb6d00cab4b, + 0xe2a0b5dc971f303a, 0x2e44ae64840fd61d, + 0x8da471a9de737e24, 0x5ceaecfed289e5d2, + 0xb10d8e1456105dad, 0x7425a83e872c5f47, + 0xdd50f1996b947518, 0xd12f124e28f77719, + 0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f, + 0xace73cbfdc0bfb7b, 0x636cc64d1001550b, + 0xd8210befd30efa5a, 0x3c47f7e05401aa4e, + 0x8714a775e3e95c78, 0x65acfaec34810a71, + 0xa8d9d1535ce3b396, 0x7f1839a741a14d0d, + 0xd31045a8341ca07c, 0x1ede48111209a050, + 0x83ea2b892091e44d, 0x934aed0aab460432, + 0xa4e4b66b68b65d60, 0xf81da84d5617853f, + 0xce1de40642e3f4b9, 0x36251260ab9d668e, + 0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019, + 0xa1075a24e4421730, 0xb24cf65b8612f81f, + 0xc94930ae1d529cfc, 0xdee033f26797b627, + 0xfb9b7cd9a4a7443c, 0x169840ef017da3b1, + 0x9d412e0806e88aa5, 0x8e1f289560ee864e, + 0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2, + 0xf5b5d7ec8acb58a2, 0xae10af696774b1db, + 0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29, + 0xbff610b0cc6edd3f, 0x17fd090a58d32af3, + 0xeff394dcff8a948e, 0xddfc4b4cef07f5b0, + 0x95f83d0a1fb69cd9, 0x4abdaf101564f98e, + 0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1, + 0xea53df5fd18d5513, 0x84c86189216dc5ed, + 0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4, + 0xb7118682dbb66a77, 0x3fbc8c33221dc2a1, + 0xe4d5e82392a40515, 0xfabaf3feaa5334a, + 0x8f05b1163ba6832d, 0x29cb4d87f2a7400e, + 0xb2c71d5bca9023f8, 0x743e20e9ef511012, + 0xdf78e4b2bd342cf6, 0x914da9246b255416, + 0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e, + 0xae9672aba3d0c320, 0xa184ac2473b529b1, + 0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e, + 0x8865899617fb1871, 0x7e2fa67c7a658892, + 0xaa7eebfb9df9de8d, 0xddbb901b98feeab7, + 0xd51ea6fa85785631, 0x552a74227f3ea565, + 0x8533285c936b35de, 0xd53a88958f87275f, + 0xa67ff273b8460356, 0x8a892abaf368f137, + 0xd01fef10a657842c, 0x2d2b7569b0432d85, + 0x8213f56a67f6b29b, 0x9c3b29620e29fc73, + 0xa298f2c501f45f42, 0x8349f3ba91b47b8f, + 0xcb3f2f7642717713, 0x241c70a936219a73, + 0xfe0efb53d30dd4d7, 0xed238cd383aa0110, + 0x9ec95d1463e8a506, 0xf4363804324a40aa, + 0xc67bb4597ce2ce48, 0xb143c6053edcd0d5, + 0xf81aa16fdc1b81da, 0xdd94b7868e94050a, + 0x9b10a4e5e9913128, 0xca7cf2b4191c8326, + 0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0, + 0xf24a01a73cf2dccf, 0xbc633b39673c8cec, + 0x976e41088617ca01, 0xd5be0503e085d813, + 0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18, + 0xec9c459d51852ba2, 0xddf8e7d60ed1219e, + 0x93e1ab8252f33b45, 0xcabb90e5c942b503, + 0xb8da1662e7b00a17, 0x3d6a751f3b936243, + 0xe7109bfba19c0c9d, 0xcc512670a783ad4, + 0x906a617d450187e2, 0x27fb2b80668b24c5, + 0xb484f9dc9641e9da, 0xb1f9f660802dedf6, + 0xe1a63853bbd26451, 0x5e7873f8a0396973, + 0x8d07e33455637eb2, 0xdb0b487b6423e1e8, + 0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62, + 0xdc5c5301c56b75f7, 0x7641a140cc7810fb, + 0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d, + 0xac2820d9623bf429, 0x546345fa9fbdcd44, + 0xd732290fbacaf133, 0xa97c177947ad4095, + 0x867f59a9d4bed6c0, 0x49ed8eabcccc485d, + 0xa81f301449ee8c70, 0x5c68f256bfff5a74, + 0xd226fc195c6a2f8c, 0x73832eec6fff3111, + 0x83585d8fd9c25db7, 0xc831fd53c5ff7eab, + 0xa42e74f3d032f525, 0xba3e7ca8b77f5e55, + 0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb, + 0x80444b5e7aa7cf85, 0x7980d163cf5b81b3, + 0xa0555e361951c366, 0xd7e105bcc332621f, + 0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7, + 0xfa856334878fc150, 0xb14f98f6f0feb951, + 0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3, + 0xc3b8358109e84f07, 0xa862f80ec4700c8, + 0xf4a642e14c6262c8, 0xcd27bb612758c0fa, + 0x98e7e9cccfbd7dbd, 0x8038d51cb897789c, + 0xbf21e44003acdd2c, 0xe0470a63e6bd56c3, + 0xeeea5d5004981478, 0x1858ccfce06cac74, + 0x95527a5202df0ccb, 0xf37801e0c43ebc8, + 0xbaa718e68396cffd, 0xd30560258f54e6ba, + 0xe950df20247c83fd, 0x47c6b82ef32a2069, + 0x91d28b7416cdd27e, 0x4cdc331d57fa5441, + 0xb6472e511c81471d, 0xe0133fe4adf8e952, + 0xe3d8f9e563a198e5, 0x58180fddd97723a6, + 0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648, +}; + +/* binary_format constants from fast_float. */ +#define FFP_MANTISSA_BITS 52 +#define FFP_MIN_EXPONENT (-1023) +#define FFP_INFINITE_POWER 0x7FF +#define FFP_SMALLEST_POW10 (-342) +#define FFP_LARGEST_POW10 308 +#define FFP_MIN_RTE (-4) /* min_exponent_round_to_even */ +#define FFP_MAX_RTE 23 /* max_exponent_round_to_even */ + +/* (((152170 + 65536) * q) >> 16) + 63 == floor(log2(10^q)) + q + 63, see paper. */ +static inline int32_t ffp_power(int32_t q) { + return (((152170 + 65536) * q) >> 16) + 63; +} + +static inline void ffp_mul128(uint64_t a, uint64_t b, uint64_t *hi, uint64_t *lo) { +#if defined(__SIZEOF_INT128__) + __uint128_t p = (__uint128_t)a * (__uint128_t)b; + *lo = (uint64_t)p; + *hi = (uint64_t)(p >> 64); +#else + uint64_t a0 = (uint32_t)a, a1 = a >> 32, b0 = (uint32_t)b, b1 = b >> 32; + uint64_t p00 = a0 * b0, p01 = a0 * b1, p10 = a1 * b0, p11 = a1 * b1; + uint64_t mid = p10 + (p00 >> 32) + (uint32_t)p01; + *hi = p11 + (mid >> 32) + (p01 >> 32); + *lo = (mid << 32) | (uint32_t)p00; +#endif +} + +static inline double ffp_bits2double(uint64_t bits) { + double d; + memcpy(&d, &bits, sizeof(d)); + return d; +} + +#if defined(__x86_64__) && defined(HAVE_X86INTRIN_H) +# include +#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H) +# include +#endif + +#if defined(_MSC_VER) && defined(__AVX2__) +# pragma intrinsic(__lzcnt64) +#endif + +static inline unsigned int +ffc_nlz_int64(uint64_t x) +{ +#if defined(HAVE_BUILTIN___BUILTIN_CLZLL) && !(defined(__sun) && defined(__sparc)) + return (unsigned int)__builtin_clzll((unsigned long long)x); + +#elif defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64) + return (unsigned int)__lzcnt64(x); + +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64) + return (unsigned int)_lzcnt_u64(x); + +#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64) + unsigned long r; + return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64; + +#else + uint64_t y; + unsigned int n = 64; + y = x >> 32; if (y) {n -= 32; x = y;} + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (unsigned int)(n - x); + +#endif +} + +/* q = power of ten, w = mantissa (exact, fits in uint64). neg = sign. */ +static inline double ffp_s2d(int64_t q, uint64_t w, bool neg) { + if (w == 0) { + return neg ? -0.0 : 0.0; + } + + const uint64_t sign = (uint64_t)(neg != 0) << 63; + uint64_t mantissa, prod_hi, prod_lo, sp_hi, sp_lo; + int32_t power2; + int upperbit, shift, index; + + if (q < FFP_SMALLEST_POW10) return ffp_bits2double(sign); /* underflow -> 0 */ + if (q > FFP_LARGEST_POW10) { + return ffp_bits2double(sign | ((uint64_t)FFP_INFINITE_POWER << FFP_MANTISSA_BITS)); + } + + unsigned int lz = ffc_nlz_int64(w); + w <<= lz; + + /* compute_product_approximation: precision_mask = 0x1FF. */ + index = 2 * (int)(q - FFP_SMALLEST_POWER_OF_FIVE); + ffp_mul128(w, ffp_power_of_five_128[index], &prod_hi, &prod_lo); + if ((prod_hi & 0x1FF) == 0x1FF) { + ffp_mul128(w, ffp_power_of_five_128[index + 1], &sp_hi, &sp_lo); + prod_lo += sp_hi; + if (sp_hi > prod_lo) { + prod_hi++; + } + } + + upperbit = (int)(prod_hi >> 63); + shift = upperbit + 64 - FFP_MANTISSA_BITS - 3; /* upperbit + 9 */ + mantissa = prod_hi >> shift; + power2 = (int32_t)(ffp_power((int32_t)q) + upperbit - lz - FFP_MIN_EXPONENT); + + if (power2 <= 0) { /* subnormal */ + if (-power2 + 1 >= 64) return ffp_bits2double(sign); /* far below min -> 0 */ + mantissa >>= (-power2 + 1); + mantissa += (mantissa & 1); + mantissa >>= 1; + power2 = (mantissa < ((uint64_t)1 << FFP_MANTISSA_BITS)) ? 0 : 1; + return ffp_bits2double(sign | ((uint64_t)power2 << FFP_MANTISSA_BITS) | mantissa); + } + + /* round-to-even: if we land exactly between two doubles, round down. */ + if ((prod_lo <= 1) && (q >= FFP_MIN_RTE) && (q <= FFP_MAX_RTE) && + ((mantissa & 3) == 1) && ((mantissa << shift) == prod_hi)) { + mantissa &= ~(uint64_t)1; + } + + mantissa += (mantissa & 1); + mantissa >>= 1; + if (mantissa >= ((uint64_t)2 << FFP_MANTISSA_BITS)) { + mantissa = (uint64_t)1 << FFP_MANTISSA_BITS; + power2++; + } + + mantissa &= ~((uint64_t)1 << FFP_MANTISSA_BITS); /* drop implicit bit */ + if (power2 >= FFP_INFINITE_POWER) { + return ffp_bits2double(sign | ((uint64_t)FFP_INFINITE_POWER << FFP_MANTISSA_BITS)); + } + return ffp_bits2double(sign | ((uint64_t)power2 << FFP_MANTISSA_BITS) | mantissa); +} + +#endif // FFP_H diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fpconv.c b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fpconv.c new file mode 100644 index 0000000..6c9bc2c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/fpconv.c @@ -0,0 +1,480 @@ +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// The contents of this file is extracted from https://github.com/night-shift/fpconv +// It was slightly modified to append ".0" to plain floats, for use with the https://github.com/ruby/json package. + +#include +#include +#include + +#if JSON_DEBUG +#include +#endif + +#define npowers 87 +#define steppowers 8 +#define firstpower -348 /* 10 ^ -348 */ + +#define expmax -32 +#define expmin -60 + +typedef struct Fp { + uint64_t frac; + int exp; +} Fp; + +static const Fp powers_ten[] = { + { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 }, + { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 }, + { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 }, + { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 }, + { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 }, + { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 }, + { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 }, + { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 }, + { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 }, + { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 }, + { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 }, + { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 }, + { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 }, + { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 }, + { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 }, + { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 }, + { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 }, + { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 }, + { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 }, + { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 }, + { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 }, + { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 }, + { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 }, + { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 }, + { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 }, + { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 }, + { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 }, + { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 }, + { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 }, + { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 }, + { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 }, + { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 }, + { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 }, + { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 }, + { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 }, + { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 }, + { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 }, + { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 }, + { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 }, + { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 }, + { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 }, + { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 }, + { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 }, + { 12648080533535911531U, 1066 } +}; + +static Fp find_cachedpow10(int exp, int* k) +{ + const double one_log_ten = 0.30102999566398114; + + int approx = (int)(-(exp + npowers) * one_log_ten); + int idx = (approx - firstpower) / steppowers; + + while(1) { + int current = exp + powers_ten[idx].exp + 64; + + if(current < expmin) { + idx++; + continue; + } + + if(current > expmax) { + idx--; + continue; + } + + *k = (firstpower + idx * steppowers); + + return powers_ten[idx]; + } +} + +#define fracmask 0x000FFFFFFFFFFFFFU +#define expmask 0x7FF0000000000000U +#define hiddenbit 0x0010000000000000U +#define signmask 0x8000000000000000U +#define expbias (1023 + 52) + +#define absv(n) ((n) < 0 ? -(n) : (n)) +#define minv(a, b) ((a) < (b) ? (a) : (b)) + +static const uint64_t tens[] = { + 10000000000000000000U, 1000000000000000000U, 100000000000000000U, + 10000000000000000U, 1000000000000000U, 100000000000000U, + 10000000000000U, 1000000000000U, 100000000000U, + 10000000000U, 1000000000U, 100000000U, + 10000000U, 1000000U, 100000U, + 10000U, 1000U, 100U, + 10U, 1U +}; + +static inline uint64_t get_dbits(double d) +{ + union { + double dbl; + uint64_t i; + } dbl_bits = { d }; + + return dbl_bits.i; +} + +static Fp build_fp(double d) +{ + uint64_t bits = get_dbits(d); + + Fp fp; + fp.frac = bits & fracmask; + fp.exp = (bits & expmask) >> 52; + + if(fp.exp) { + fp.frac += hiddenbit; + fp.exp -= expbias; + + } else { + fp.exp = -expbias + 1; + } + + return fp; +} + +static void normalize(Fp* fp) +{ + while ((fp->frac & hiddenbit) == 0) { + fp->frac <<= 1; + fp->exp--; + } + + int shift = 64 - 52 - 1; + fp->frac <<= shift; + fp->exp -= shift; +} + +static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper) +{ + upper->frac = (fp->frac << 1) + 1; + upper->exp = fp->exp - 1; + + while ((upper->frac & (hiddenbit << 1)) == 0) { + upper->frac <<= 1; + upper->exp--; + } + + int u_shift = 64 - 52 - 2; + + upper->frac <<= u_shift; + upper->exp = upper->exp - u_shift; + + + int l_shift = fp->frac == hiddenbit ? 2 : 1; + + lower->frac = (fp->frac << l_shift) - 1; + lower->exp = fp->exp - l_shift; + + + lower->frac <<= lower->exp - upper->exp; + lower->exp = upper->exp; +} + +static Fp multiply(Fp* a, Fp* b) +{ + const uint64_t lomask = 0x00000000FFFFFFFF; + + uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask); + uint64_t al_bh = (a->frac & lomask) * (b->frac >> 32); + uint64_t al_bl = (a->frac & lomask) * (b->frac & lomask); + uint64_t ah_bh = (a->frac >> 32) * (b->frac >> 32); + + uint64_t tmp = (ah_bl & lomask) + (al_bh & lomask) + (al_bl >> 32); + /* round up */ + tmp += 1U << 31; + + Fp fp = { + ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32), + a->exp + b->exp + 64 + }; + + return fp; +} + +static void round_digit(char* digits, int ndigits, uint64_t delta, uint64_t rem, uint64_t kappa, uint64_t frac) +{ + while (rem < frac && delta - rem >= kappa && + (rem + kappa < frac || frac - rem > rem + kappa - frac)) { + + digits[ndigits - 1]--; + rem += kappa; + } +} + +static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K) +{ + uint64_t wfrac = upper->frac - fp->frac; + uint64_t delta = upper->frac - lower->frac; + + Fp one; + one.frac = 1ULL << -upper->exp; + one.exp = upper->exp; + + uint64_t part1 = upper->frac >> -one.exp; + uint64_t part2 = upper->frac & (one.frac - 1); + + int idx = 0, kappa = 10; + const uint64_t* divp; + /* 1000000000 */ + for(divp = tens + 10; kappa > 0; divp++) { + + uint64_t div = *divp; + unsigned digit = (unsigned) (part1 / div); + + if (digit || idx) { + digits[idx++] = digit + '0'; + } + + part1 -= digit * div; + kappa--; + + uint64_t tmp = (part1 <<-one.exp) + part2; + if (tmp <= delta) { + *K += kappa; + round_digit(digits, idx, delta, tmp, div << -one.exp, wfrac); + + return idx; + } + } + + /* 10 */ + const uint64_t* unit = tens + 18; + + while(true) { + part2 *= 10; + delta *= 10; + kappa--; + + unsigned digit = (unsigned) (part2 >> -one.exp); + if (digit || idx) { + digits[idx++] = digit + '0'; + } + + part2 &= one.frac - 1; + if (part2 < delta) { + *K += kappa; + round_digit(digits, idx, delta, part2, one.frac, wfrac * *unit); + + return idx; + } + + unit--; + } +} + +static int grisu2(double d, char* digits, int* K) +{ + Fp w = build_fp(d); + + Fp lower, upper; + get_normalized_boundaries(&w, &lower, &upper); + + normalize(&w); + + int k; + Fp cp = find_cachedpow10(upper.exp, &k); + + w = multiply(&w, &cp); + upper = multiply(&upper, &cp); + lower = multiply(&lower, &cp); + + lower.frac++; + upper.frac--; + + *K = -k; + + return generate_digits(&w, &upper, &lower, digits, K); +} + +static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) +{ + int exp = absv(K + ndigits - 1); + + if(K >= 0 && exp < 15) { + memcpy(dest, digits, ndigits); + memset(dest + ndigits, '0', K); + + /* add a .0 to mark this as a float. */ + dest[ndigits + K] = '.'; + dest[ndigits + K + 1] = '0'; + + return ndigits + K + 2; + } + + /* write decimal w/o scientific notation */ + if(K < 0 && (K > -7 || exp < 10)) { + int offset = ndigits - absv(K); + /* fp < 1.0 -> write leading zero */ + if(offset <= 0) { + offset = -offset; + dest[0] = '0'; + dest[1] = '.'; + memset(dest + 2, '0', offset); + memcpy(dest + offset + 2, digits, ndigits); + + return ndigits + 2 + offset; + + /* fp > 1.0 */ + } else { + memcpy(dest, digits, offset); + dest[offset] = '.'; + memcpy(dest + offset + 1, digits + offset, ndigits - offset); + + return ndigits + 1; + } + } + + /* write decimal w/ scientific notation */ + ndigits = minv(ndigits, 18 - neg); + + int idx = 0; + dest[idx++] = digits[0]; + + if(ndigits > 1) { + dest[idx++] = '.'; + memcpy(dest + idx, digits + 1, ndigits - 1); + idx += ndigits - 1; + } + + dest[idx++] = 'e'; + + char sign = K + ndigits - 1 < 0 ? '-' : '+'; + dest[idx++] = sign; + + int cent = 0; + + if(exp > 99) { + cent = exp / 100; + dest[idx++] = cent + '0'; + exp -= cent * 100; + } + if(exp > 9) { + int dec = exp / 10; + dest[idx++] = dec + '0'; + exp -= dec * 10; + + } else if(cent) { + dest[idx++] = '0'; + } + + dest[idx++] = exp % 10 + '0'; + + return idx; +} + +static int filter_special(double fp, char* dest) +{ + if(fp == 0.0) { + dest[0] = '0'; + dest[1] = '.'; + dest[2] = '0'; + return 3; + } + + uint64_t bits = get_dbits(fp); + + bool nan = (bits & expmask) == expmask; + + if(!nan) { + return 0; + } + + if(bits & fracmask) { + dest[0] = 'n'; dest[1] = 'a'; dest[2] = 'n'; + + } else { + dest[0] = 'i'; dest[1] = 'n'; dest[2] = 'f'; + } + + return 3; +} + +/* Fast and accurate double to string conversion based on Florian Loitsch's + * Grisu-algorithm[1]. + * + * Input: + * fp -> the double to convert, dest -> destination buffer. + * The generated string will never be longer than 32 characters. + * Make sure to pass a pointer to at least 32 bytes of memory. + * The emitted string will not be null terminated. + * + * + * + * Output: + * The number of written characters. + * + * Exemplary usage: + * + * void print(double d) + * { + * char buf[28 + 1] // plus null terminator + * int str_len = fpconv_dtoa(d, buf); + * + * buf[str_len] = '\0'; + * printf("%s", buf); + * } + * + */ +static int fpconv_dtoa(double d, char dest[32]) +{ + char digits[18]; + + int str_len = 0; + bool neg = false; + + if(get_dbits(d) & signmask) { + dest[0] = '-'; + str_len++; + neg = true; + } + + int spec = filter_special(d, dest + str_len); + + if(spec) { + return str_len + spec; + } + + int K = 0; + int ndigits = grisu2(d, digits, &K); + + str_len += emit_digits(digits, ndigits, dest + str_len, K, neg); +#if JSON_DEBUG + assert(str_len <= 32); +#endif + + return str_len; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/jeaiii-ltoa.h b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/jeaiii-ltoa.h new file mode 100644 index 0000000..ba4f497 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/ext/json/ext/vendor/jeaiii-ltoa.h @@ -0,0 +1,267 @@ +/* + +This file is released under the terms of the MIT License. It is based on the +work of James Edward Anhalt III, with the original license listed below. + +MIT License + +Copyright (c) 2024,2025 Enrico Thierbach - https://github.com/radiospiel +Copyright (c) 2022 James Edward Anhalt III - https://github.com/jeaiii/itoa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef JEAIII_TO_TEXT_H_ +#define JEAIII_TO_TEXT_H_ + +#include + +typedef uint_fast32_t u32_t; +typedef uint_fast64_t u64_t; + +#define u32(x) ((u32_t)(x)) +#define u64(x) ((u64_t)(x)) + +struct digit_pair +{ + char dd[2]; +}; + +static const struct digit_pair *digits_dd = (struct digit_pair *)( + "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" + "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" + "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" + "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" + "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" + "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" + "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" +); + +static const struct digit_pair *digits_fd = (struct digit_pair *)( + "0_" "1_" "2_" "3_" "4_" "5_" "6_" "7_" "8_" "9_" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" + "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" + "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" + "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" + "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" + "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" + "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" +); + +static const u64_t mask24 = (u64(1) << 24) - 1; +static const u64_t mask32 = (u64(1) << 32) - 1; +static const u64_t mask57 = (u64(1) << 57) - 1; + +#define COPY(buffer, digits) memcpy(buffer, &(digits), sizeof(struct digit_pair)) + +static char * +jeaiii_ultoa(char *b, u64_t n) +{ + if (n < u32(1e2)) { + COPY(b, digits_fd[n]); + return n < 10 ? b + 1 : b + 2; + } + + if (n < u32(1e6)) { + if (n < u32(1e4)) { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * n); + COPY(b, digits_fd[f0 >> 24]); + + b -= n < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + + return b + 4; + } + + u64_t f0 = u64(10 * (1ull << 32ull)/ 1e5 + 1) * n; + COPY(b, digits_fd[f0 >> 32]); + + b -= n < u32(1e5); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + return b + 6; + } + + if (n < u64(1ull << 32ull)) { + if (n < u32(1e8)) { + u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * n >> 16; + COPY(b, digits_fd[f0 >> 32]); + + b -= n < u32(1e7); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + return b + 8; + } + + u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * n; + COPY(b, digits_fd[f0 >> 57]); + + b -= n < u32(1e9); + u64_t f2 = (f0 & mask57) * 100; + COPY(b + 2, digits_dd[f2 >> 57]); + + u64_t f4 = (f2 & mask57) * 100; + COPY(b + 4, digits_dd[f4 >> 57]); + + u64_t f6 = (f4 & mask57) * 100; + COPY(b + 6, digits_dd[f6 >> 57]); + + u64_t f8 = (f6 & mask57) * 100; + COPY(b + 8, digits_dd[f8 >> 57]); + + return b + 10; + } + + // if we get here U must be u64 but some compilers don't know that, so reassign n to a u64 to avoid warnings + u32_t z = n % u32(1e8); + u64_t u = n / u32(1e8); + + if (u < u32(1e2)) { + // u can't be 1 digit (if u < 10 it would have been handled above as a 9 digit 32bit number) + COPY(b, digits_dd[u]); + b += 2; + } + else if (u < u32(1e6)) { + if (u < u32(1e4)) { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * u); + COPY(b, digits_fd[f0 >> 24]); + + b -= u < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + b += 4; + } + else { + u64_t f0 = u64(10 * (1ull << 32ull) / 1e5 + 1) * u; + COPY(b, digits_fd[f0 >> 32]); + + b -= u < u32(1e5); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + b += 6; + } + } + else if (u < u32(1e8)) { + u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * u >> 16; + COPY(b, digits_fd[f0 >> 32]); + + b -= u < u32(1e7); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + b += 8; + } + else if (u < u64(1ull << 32ull)) { + u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * u; + COPY(b, digits_fd[f0 >> 57]); + + b -= u < u32(1e9); + u64_t f2 = (f0 & mask57) * 100; + COPY(b + 2, digits_dd[f2 >> 57]); + + u64_t f4 = (f2 & mask57) * 100; + COPY(b + 4, digits_dd[f4 >> 57]); + + u64_t f6 = (f4 & mask57) * 100; + COPY(b + 6, digits_dd[f6 >> 57]); + + u64_t f8 = (f6 & mask57) * 100; + COPY(b + 8, digits_dd[f8 >> 57]); + b += 10; + } + else { + u32_t y = u % u32(1e8); + u /= u32(1e8); + + // u is 2, 3, or 4 digits (if u < 10 it would have been handled above) + if (u < u32(1e2)) { + COPY(b, digits_dd[u]); + b += 2; + } + else { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * u); + COPY(b, digits_fd[f0 >> 24]); + + b -= u < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + + b += 4; + } + // do 8 digits + u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * y >> 16) + 1; + COPY(b, digits_dd[f0 >> 32]); + + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + b += 8; + } + + // do 8 digits + u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * z >> 16) + 1; + COPY(b, digits_dd[f0 >> 32]); + + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + return b + 8; +} + +#undef u32 +#undef u64 +#undef COPY + +#endif // JEAIII_TO_TEXT_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/json.gemspec b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/json.gemspec new file mode 100644 index 0000000..5575731 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/json.gemspec @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line| + /^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1 +end rescue nil + +spec = Gem::Specification.new do |s| + java_ext = Gem::Platform === s.platform && s.platform =~ 'java' || RUBY_ENGINE == 'jruby' + + s.name = "json" + s.version = version + + s.summary = "JSON Implementation for Ruby" + s.homepage = "https://github.com/ruby/json" + s.metadata = { + 'bug_tracker_uri' => 'https://github.com/ruby/json/issues', + 'changelog_uri' => 'https://github.com/ruby/json/blob/master/CHANGES.md', + 'documentation_uri' => 'https://docs.ruby-lang.org/en/master/JSON.html', + 'homepage_uri' => s.homepage, + 'source_code_uri' => 'https://github.com/ruby/json', + } + + s.required_ruby_version = Gem::Requirement.new(">= 2.7") + + if java_ext + s.description = "A JSON implementation as a JRuby extension." + s.author = "Daniel Luz" + s.email = "dev+ruby@mernen.com" + else + s.description = "This is a JSON implementation as a Ruby extension in C." + s.authors = ["Florian Frank"] + s.email = "flori@ping.de" + end + + s.licenses = ["Ruby"] + + s.extra_rdoc_files = ["README.md"] + s.rdoc_options = ["--title", "JSON implementation for Ruby", "--main", "README.md"] + + s.files = [ + "CHANGES.md", + "COPYING", + "BSDL", + "LEGAL", + "README.md", + "json.gemspec", + ] + Dir.glob("lib/**/*.rb", base: File.expand_path("..", __FILE__)) + + if java_ext + s.platform = 'java' + s.files += Dir["lib/json/ext/**/*.jar"] + else + s.extensions = Dir["ext/json/**/extconf.rb"] + s.files += Dir["ext/json/**/*.{c,h,rb}"] + end +end + +if RUBY_ENGINE == 'jruby' && $0 == __FILE__ + Gem::Builder.new(spec).build +else + spec +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json.rb new file mode 100644 index 0000000..d1e9414 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json.rb @@ -0,0 +1,693 @@ +# frozen_string_literal: true +require 'json/common' + +## +# = JavaScript \Object Notation (\JSON) +# +# \JSON is a lightweight data-interchange format. +# +# \JSON is easy for us humans to read and write, +# and equally simple for machines to read (parse) and write (generate). +# +# \JSON is language-independent, making it an ideal interchange format +# for applications in differing programming languages +# and on differing operating systems. +# +# == \JSON Values +# +# A \JSON value is one of the following: +# - Double-quoted text: "foo". +# - Number: +1+, +1.0+, +2.0e2+. +# - Boolean: +true+, +false+. +# - Null: +null+. +# - \Array: an ordered list of values, enclosed by square brackets: +# ["foo", 1, 1.0, 2.0e2, true, false, null] +# +# - \Object: a collection of name/value pairs, enclosed by curly braces; +# each name is double-quoted text; +# the values may be any \JSON values: +# {"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null} +# +# A \JSON array or object may contain nested arrays, objects, and scalars +# to any depth: +# {"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]} +# [{"foo": 0, "bar": 1}, ["baz", 2]] +# +# == Using \Module \JSON +# +# To make module \JSON available in your code, begin with: +# require 'json' +# +# All examples here assume that this has been done. +# +# === Parsing \JSON +# +# You can parse a \String containing \JSON data using +# either of two methods: +# - JSON.parse(source, opts) +# - JSON.parse!(source, opts) +# +# where +# - +source+ is a Ruby object. +# - +opts+ is a \Hash object containing options +# that control both input allowed and output formatting. +# +# The difference between the two methods +# is that JSON.parse! omits some checks +# and may not be safe for some +source+ data; +# use it only for data from trusted sources. +# Use the safer method JSON.parse for less trusted sources. +# +# ==== Parsing \JSON Arrays +# +# When +source+ is a \JSON array, JSON.parse by default returns a Ruby \Array: +# json = '["foo", 1, 1.0, 2.0e2, true, false, null]' +# ruby = JSON.parse(json) +# ruby # => ["foo", 1, 1.0, 200.0, true, false, nil] +# ruby.class # => Array +# +# The \JSON array may contain nested arrays, objects, and scalars +# to any depth: +# json = '[{"foo": 0, "bar": 1}, ["baz", 2]]' +# JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]] +# +# ==== Parsing \JSON \Objects +# +# When the source is a \JSON object, JSON.parse by default returns a Ruby \Hash: +# json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}' +# ruby = JSON.parse(json) +# ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil} +# ruby.class # => Hash +# +# The \JSON object may contain nested arrays, objects, and scalars +# to any depth: +# json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}' +# JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]} +# +# ==== Parsing \JSON Scalars +# +# When the source is a \JSON scalar (not an array or object), +# JSON.parse returns a Ruby scalar. +# +# \String: +# ruby = JSON.parse('"foo"') +# ruby # => 'foo' +# ruby.class # => String +# \Integer: +# ruby = JSON.parse('1') +# ruby # => 1 +# ruby.class # => Integer +# \Float: +# ruby = JSON.parse('1.0') +# ruby # => 1.0 +# ruby.class # => Float +# ruby = JSON.parse('2.0e2') +# ruby # => 200 +# ruby.class # => Float +# Boolean: +# ruby = JSON.parse('true') +# ruby # => true +# ruby.class # => TrueClass +# ruby = JSON.parse('false') +# ruby # => false +# ruby.class # => FalseClass +# Null: +# ruby = JSON.parse('null') +# ruby # => nil +# ruby.class # => NilClass +# +# ==== Parsing Options +# +# ====== Input Options +# +# Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed; +# defaults to +100+; specify +false+ to disable depth checking. +# +# With the default, +false+: +# source = '[0, [1, [2, [3]]]]' +# ruby = JSON.parse(source) +# ruby # => [0, [1, [2, [3]]]] +# Too deep: +# # Raises JSON::NestingError (nesting of 2 is too deep): +# JSON.parse(source, {max_nesting: 1}) +# Bad value: +# # Raises TypeError (wrong argument type Symbol (expected Fixnum)): +# JSON.parse(source, {max_nesting: :foo}) +# +# --- +# +# Option +allow_duplicate_key+ specifies whether duplicate keys in objects +# should be ignored or cause an error to be raised: +# +# When not specified: +# # The last value is used and a deprecation warning emitted. +# JSON.parse('{"a": 1, "a":2}') => {"a" => 2} +# # warning: detected duplicate keys in JSON object. +# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true` +# +# When set to +true+: +# # The last value is used. +# JSON.parse('{"a": 1, "a":2}') => {"a" => 2} +# +# When set to +false+, the future default: +# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError) +# +# --- +# +# Option +allow_nan+ (boolean) specifies whether to allow +# NaN, Infinity, and MinusInfinity in +source+; +# defaults to +false+. +# +# With the default, +false+: +# # Raises JSON::ParserError (225: unexpected token at '[NaN]'): +# JSON.parse('[NaN]') +# # Raises JSON::ParserError (232: unexpected token at '[Infinity]'): +# JSON.parse('[Infinity]') +# # Raises JSON::ParserError (248: unexpected token at '[-Infinity]'): +# JSON.parse('[-Infinity]') +# Allow: +# source = '[NaN, Infinity, -Infinity]' +# ruby = JSON.parse(source, {allow_nan: true}) +# ruby # => [NaN, Infinity, -Infinity] +# +# --- +# +# Option +allow_trailing_comma+ (boolean) specifies whether to allow +# trailing commas in objects and arrays; +# defaults to +false+. +# +# With the default, +false+: +# JSON.parse('[1,]') # unexpected character: ']' at line 1 column 4 (JSON::ParserError) +# +# When enabled: +# JSON.parse('[1,]', allow_trailing_comma: true) # => [1] +# +# --- +# +# Option +allow_comments+ (boolean) specifies whether to allow +# JavaScript style comments (either // comment or /* comment */); +# defaults to +false+. +# +# When not specified, a deprecation warning is emitted if a comment is encountered. +# +# When set to +true+, comments are ignored: +# JSON.parse('/* comment */ {"a": 1, "a":2}') # => {"a" => 2} +# +# When set to +false+, the future default: +# JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected character: '/' at line 1 column 1 (JSON::ParserError) +# +# --- +# +# Option +allow_control_characters+ (boolean) specifies whether to allow +# unescaped ASCII control characters, such as newlines, in strings; +# defaults to +false+. +# +# With the default, +false+: +# JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError) +# +# When enabled: +# JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld" +# +# --- +# +# Option +allow_invalid_escape+ (boolean) specifies whether to ignore backslahes that are followed +# by an invalid escape character in strings; +# defaults to +false+. +# +# With the default, +false+: +# JSON.parse('"Hell\o"') # invalid escape character in string (JSON::ParserError) +# +# When enabled: +# JSON.parse('"Hell\o"', allow_invalid_escape: true) # => "Hello" +# +# ====== Output Options +# +# Option +freeze+ (boolean) specifies whether the returned objects will be frozen; +# defaults to +false+. +# +# Option +symbolize_names+ (boolean) specifies whether returned \Hash keys +# should be Symbols; +# defaults to +false+ (use Strings). +# +# With the default, +false+: +# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}' +# ruby = JSON.parse(source) +# ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil} +# Use Symbols: +# ruby = JSON.parse(source, {symbolize_names: true}) +# ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil} +# +# --- +# +# Option +object_class+ (\Class) specifies the Ruby class to be used +# for each \JSON object; +# defaults to \Hash. +# +# With the default, \Hash: +# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}' +# ruby = JSON.parse(source) +# ruby.class # => Hash +# Use class \OpenStruct: +# ruby = JSON.parse(source, {object_class: OpenStruct}) +# ruby # => # +# +# --- +# +# Option +array_class+ (\Class) specifies the Ruby class to be used +# for each \JSON array; +# defaults to \Array. +# +# With the default, \Array: +# source = '["foo", 1.0, true, false, null]' +# ruby = JSON.parse(source) +# ruby.class # => Array +# Use class \Set: +# ruby = JSON.parse(source, {array_class: Set}) +# ruby # => # +# +# --- +# +# Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing. +# See {\JSON Additions}[#module-JSON-label-JSON+Additions]. +# +# === Generating \JSON +# +# To generate a Ruby \String containing \JSON data, +# use method JSON.generate(source, opts), where +# - +source+ is a Ruby object. +# - +opts+ is a \Hash object containing options +# that control both input allowed and output formatting. +# +# ==== Generating \JSON from Arrays +# +# When the source is a Ruby \Array, JSON.generate returns +# a \String containing a \JSON array: +# ruby = [0, 's', :foo] +# json = JSON.generate(ruby) +# json # => '[0,"s","foo"]' +# +# The Ruby \Array array may contain nested arrays, hashes, and scalars +# to any depth: +# ruby = [0, [1, 2], {foo: 3, bar: 4}] +# json = JSON.generate(ruby) +# json # => '[0,[1,2],{"foo":3,"bar":4}]' +# +# ==== Generating \JSON from Hashes +# +# When the source is a Ruby \Hash, JSON.generate returns +# a \String containing a \JSON object: +# ruby = {foo: 0, bar: 's', baz: :bat} +# json = JSON.generate(ruby) +# json # => '{"foo":0,"bar":"s","baz":"bat"}' +# +# The Ruby \Hash array may contain nested arrays, hashes, and scalars +# to any depth: +# ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad} +# json = JSON.generate(ruby) +# json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}' +# +# ==== Generating \JSON from Other Objects +# +# When the source is neither an \Array nor a \Hash, +# the generated \JSON data depends on the class of the source. +# +# When the source is a Ruby \Integer or \Float, JSON.generate returns +# a \String containing a \JSON number: +# JSON.generate(42) # => '42' +# JSON.generate(0.42) # => '0.42' +# +# When the source is a Ruby \String, JSON.generate returns +# a \String containing a \JSON string (with double-quotes): +# JSON.generate('A string') # => '"A string"' +# +# When the source is +true+, +false+ or +nil+, JSON.generate returns +# a \String containing the corresponding \JSON token: +# JSON.generate(true) # => 'true' +# JSON.generate(false) # => 'false' +# JSON.generate(nil) # => 'null' +# +# When the source is none of the above, JSON.generate returns +# a \String containing a \JSON string representation of the source: +# JSON.generate(:foo) # => '"foo"' +# JSON.generate(Complex(0, 0)) # => '"0+0i"' +# JSON.generate(Dir.new('.')) # => '"#"' +# +# ==== Generating Options +# +# ====== Input Options +# +# Option +allow_nan+ (boolean) specifies whether +# +NaN+, +Infinity+, and -Infinity may be generated; +# defaults to +false+. +# +# With the default, +false+: +# # Raises JSON::GeneratorError (920: NaN not allowed in JSON): +# JSON.generate(JSON::NaN) +# # Raises JSON::GeneratorError (917: Infinity not allowed in JSON): +# JSON.generate(JSON::Infinity) +# # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON): +# JSON.generate(JSON::MinusInfinity) +# +# Allow: +# ruby = [Float::NAN, Float::INFINITY, JSON::NaN, JSON::Infinity, JSON::MinusInfinity] +# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,NaN,Infinity,-Infinity]' +# +# --- +# +# Option +allow_duplicate_key+ (boolean) specifies whether +# hashes with duplicate keys should be allowed or produce an error. +# defaults to emit a deprecation warning. +# +# With the default, (not set): +# Warning[:deprecated] = true +# JSON.generate({ foo: 1, "foo" => 2 }) +# # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}. +# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true` +# # => '{"foo":1,"foo":2}' +# +# With false +# JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false) +# # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError) +# +# In version 3.0, false will become the default. +# +# --- +# +# Option +max_nesting+ (\Integer) specifies the maximum nesting depth +# in +obj+; defaults to +100+. +# +# With the default, +100+: +# obj = [[[[[[0]]]]]] +# JSON.generate(obj) # => '[[[[[[0]]]]]]' +# +# Too deep: +# # Raises JSON::NestingError (nesting of 2 is too deep): +# JSON.generate(obj, max_nesting: 2) +# +# ====== Escaping Options +# +# Options +script_safe+ (boolean) specifies wether '\u2028', '\u2029' +# and '/' should be escaped as to make the JSON object safe to interpolate in script +# tags. +# +# Options +ascii_only+ (boolean) specifies wether all characters outside the ASCII range +# should be escaped. +# +# ====== Output Options +# +# The default formatting options generate the most compact +# \JSON data, all on one line and with no whitespace. +# +# You can use these formatting options to generate +# \JSON data in a more open format, using whitespace. +# See also JSON.pretty_generate. +# +# - Option +array_nl+ (\String) specifies a string (usually a newline) +# to be inserted after each \JSON array; defaults to the empty \String, ''. +# - Option +object_nl+ (\String) specifies a string (usually a newline) +# to be inserted after each \JSON object; defaults to the empty \String, ''. +# - Option +indent+ (\String) specifies the string (usually spaces) to be +# used for indentation; defaults to the empty \String, ''; +# has no effect unless options +array_nl+ or +object_nl+ specify newlines. +# - Option +space+ (\String) specifies a string (usually a space) to be +# inserted after the colon in each \JSON object's pair; +# defaults to the empty \String, ''. +# - Option +space_before+ (\String) specifies a string (usually a space) to be +# inserted before the colon in each \JSON object's pair; +# defaults to the empty \String, ''. +# - Option +sort_keys+ (boolean or \Proc) controls whether and how the keys of a +# hash are sorted when generating the output; defaults to false. +# When +true+, keys are sorted lexicographically. When a \Proc, it receives +# the entire \Hash and must return a \Hash with its pairs in the desired +# order, allowing for arbitrary sort orders. +# +# In this example, +obj+ is used first to generate the shortest +# \JSON data (no whitespace), then again with all formatting options +# specified: +# +# obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}} +# json = JSON.generate(obj) +# puts 'Compact:', json +# opts = { +# array_nl: "\n", +# object_nl: "\n", +# indent: ' ', +# space_before: ' ', +# space: ' ' +# } +# puts 'Open:', JSON.generate(obj, opts) +# +# Output: +# Compact: +# {"foo":["bar","baz"],"bat":{"bam":0,"bad":1}} +# Open: +# { +# "foo" : [ +# "bar", +# "baz" +# ], +# "bat" : { +# "bam" : 0, +# "bad" : 1 +# } +# } +# +# == \JSON Additions +# +# Note that JSON Additions must only be used with trusted data, and is +# deprecated. +# +# When you "round trip" a non-\String object from Ruby to \JSON and back, +# you have a new \String, instead of the object you began with: +# ruby0 = Range.new(0, 2) +# json = JSON.generate(ruby0) +# json # => '0..2"' +# ruby1 = JSON.parse(json) +# ruby1 # => '0..2' +# ruby1.class # => String +# +# You can use \JSON _additions_ to preserve the original object. +# The addition is an extension of a ruby class, so that: +# - \JSON.generate stores more information in the \JSON string. +# - \JSON.parse, called with option +create_additions+, +# uses that information to create a proper Ruby object. +# +# This example shows a \Range being generated into \JSON +# and parsed back into Ruby, both without and with +# the addition for \Range: +# ruby = Range.new(0, 2) +# # This passage does not use the addition for Range. +# json0 = JSON.generate(ruby) +# ruby0 = JSON.parse(json0) +# # This passage uses the addition for Range. +# require 'json/add/range' +# json1 = JSON.generate(ruby) +# ruby1 = JSON.parse(json1, create_additions: true) +# # Make a nice display. +# display = <<~EOT +# Generated JSON: +# Without addition: #{json0} (#{json0.class}) +# With addition: #{json1} (#{json1.class}) +# Parsed JSON: +# Without addition: #{ruby0.inspect} (#{ruby0.class}) +# With addition: #{ruby1.inspect} (#{ruby1.class}) +# EOT +# puts display +# +# This output shows the different results: +# Generated JSON: +# Without addition: "0..2" (String) +# With addition: {"json_class":"Range","a":[0,2,false]} (String) +# Parsed JSON: +# Without addition: "0..2" (String) +# With addition: 0..2 (Range) +# +# The \JSON module includes additions for certain classes. +# You can also craft custom additions. +# See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions]. +# +# === Built-in Additions +# +# The \JSON module includes additions for certain classes. +# To use an addition, +require+ its source: +# - BigDecimal: require 'json/add/bigdecimal' +# - Complex: require 'json/add/complex' +# - Date: require 'json/add/date' +# - DateTime: require 'json/add/date_time' +# - Exception: require 'json/add/exception' +# - OpenStruct: require 'json/add/ostruct' +# - Range: require 'json/add/range' +# - Rational: require 'json/add/rational' +# - Regexp: require 'json/add/regexp' +# - Set: require 'json/add/set' +# - Struct: require 'json/add/struct' +# - Symbol: require 'json/add/symbol' +# - Time: require 'json/add/time' +# +# To reduce punctuation clutter, the examples below +# show the generated \JSON via +puts+, rather than the usual +inspect+, +# +# \BigDecimal: +# require 'json/add/bigdecimal' +# ruby0 = BigDecimal(0) # 0.0 +# json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"} +# ruby1 = JSON.parse(json, create_additions: true) # 0.0 +# ruby1.class # => BigDecimal +# +# \Complex: +# require 'json/add/complex' +# ruby0 = Complex(1+0i) # 1+0i +# json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0} +# ruby1 = JSON.parse(json, create_additions: true) # 1+0i +# ruby1.class # Complex +# +# \Date: +# require 'json/add/date' +# ruby0 = Date.today # 2020-05-02 +# json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0} +# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 +# ruby1.class # Date +# +# \DateTime: +# require 'json/add/date_time' +# ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00 +# json = JSON.generate(ruby0) # {"json_class":"DateTime","y":2020,"m":5,"d":2,"H":10,"M":38,"S":13,"of":"-5/24","sg":2299161.0} +# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00 +# ruby1.class # DateTime +# +# \Exception (and its subclasses including \RuntimeError): +# require 'json/add/exception' +# ruby0 = Exception.new('A message') # A message +# json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null} +# ruby1 = JSON.parse(json, create_additions: true) # A message +# ruby1.class # Exception +# ruby0 = RuntimeError.new('Another message') # Another message +# json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null} +# ruby1 = JSON.parse(json, create_additions: true) # Another message +# ruby1.class # RuntimeError +# +# \OpenStruct: +# require 'json/add/ostruct' +# ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # # +# json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}} +# ruby1 = JSON.parse(json, create_additions: true) # # +# ruby1.class # OpenStruct +# +# \Range: +# require 'json/add/range' +# ruby0 = Range.new(0, 2) # 0..2 +# json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]} +# ruby1 = JSON.parse(json, create_additions: true) # 0..2 +# ruby1.class # Range +# +# \Rational: +# require 'json/add/rational' +# ruby0 = Rational(1, 3) # 1/3 +# json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3} +# ruby1 = JSON.parse(json, create_additions: true) # 1/3 +# ruby1.class # Rational +# +# \Regexp: +# require 'json/add/regexp' +# ruby0 = Regexp.new('foo') # (?-mix:foo) +# json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"} +# ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo) +# ruby1.class # Regexp +# +# \Set: +# require 'json/add/set' +# ruby0 = Set.new([0, 1, 2]) # # +# json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]} +# ruby1 = JSON.parse(json, create_additions: true) # # +# ruby1.class # Set +# +# \Struct: +# require 'json/add/struct' +# Customer = Struct.new(:name, :address) # Customer +# ruby0 = Customer.new("Dave", "123 Main") # # +# json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]} +# ruby1 = JSON.parse(json, create_additions: true) # # +# ruby1.class # Customer +# +# \Symbol: +# require 'json/add/symbol' +# ruby0 = :foo # foo +# json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"} +# ruby1 = JSON.parse(json, create_additions: true) # foo +# ruby1.class # Symbol +# +# \Time: +# require 'json/add/time' +# ruby0 = Time.now # 2020-05-02 11:28:26 -0500 +# json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000} +# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500 +# ruby1.class # Time +# +# +# === Custom \JSON Additions +# +# In addition to the \JSON additions provided, +# you can craft \JSON additions of your own, +# either for Ruby built-in classes or for user-defined classes. +# +# Here's a user-defined class +Foo+: +# class Foo +# attr_accessor :bar, :baz +# def initialize(bar, baz) +# self.bar = bar +# self.baz = baz +# end +# end +# +# Here's the \JSON addition for it: +# # Extend class Foo with JSON addition. +# class Foo +# # Serialize Foo object with its class name and arguments +# def to_json(*args) +# { +# JSON.create_id => self.class.name, +# 'a' => [ bar, baz ] +# }.to_json(*args) +# end +# # Deserialize JSON string by constructing new Foo object with arguments. +# def self.json_create(object) +# new(*object['a']) +# end +# end +# +# Demonstration: +# require 'json' +# # This Foo object has no custom addition. +# foo0 = Foo.new(0, 1) +# json0 = JSON.generate(foo0) +# obj0 = JSON.parse(json0) +# # Lood the custom addition. +# require_relative 'foo_addition' +# # This foo has the custom addition. +# foo1 = Foo.new(0, 1) +# json1 = JSON.generate(foo1) +# obj1 = JSON.parse(json1, create_additions: true) +# # Make a nice display. +# display = <<~EOT +# Generated JSON: +# Without custom addition: #{json0} (#{json0.class}) +# With custom addition: #{json1} (#{json1.class}) +# Parsed JSON: +# Without custom addition: #{obj0.inspect} (#{obj0.class}) +# With custom addition: #{obj1.inspect} (#{obj1.class}) +# EOT +# puts display +# +# Output: +# +# Generated JSON: +# Without custom addition: "#" (String) +# With custom addition: {"json_class":"Foo","a":[0,1]} (String) +# Parsed JSON: +# Without custom addition: "#" (String) +# With custom addition: # (Foo) +# +module JSON + require 'json/version' + require 'json/ext' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/bigdecimal.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/bigdecimal.rb new file mode 100644 index 0000000..5dbc12c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/bigdecimal.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +begin + require 'bigdecimal' +rescue LoadError +end + +class BigDecimal + + # See #as_json. + def self.json_create(object) + BigDecimal._load object['b'] + end + + # Methods BigDecimal#as_json and +BigDecimal.json_create+ may be used + # to serialize and deserialize a \BigDecimal object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method BigDecimal#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/bigdecimal' + # x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"} + # z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object: + # + # BigDecimal.json_create(x) # => 0.2e1 + # BigDecimal.json_create(y) # => 0.2e1 + # BigDecimal.json_create(z) # => 0.2e1 + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'b' => _dump.force_encoding(Encoding::UTF_8), + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/bigdecimal' + # puts BigDecimal(2).to_json + # puts BigDecimal(2.0, 4).to_json + # puts BigDecimal(Complex(2, 0)).to_json + # + # Output: + # + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # {"json_class":"BigDecimal","b":"36:0.2e1"} + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # + def to_json(*args) + as_json.to_json(*args) + end +end if defined?(::BigDecimal) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/complex.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/complex.rb new file mode 100644 index 0000000..a69002e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/complex.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Complex + + # See #as_json. + def self.json_create(object) + Complex(object['r'], object['i']) + end + + # Methods Complex#as_json and +Complex.json_create+ may be used + # to serialize and deserialize a \Complex object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Complex#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/complex' + # x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0} + # y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Complex object: + # + # Complex.json_create(x) # => (2+0i) + # Complex.json_create(y) # => (2.0+4i) + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'r' => real, + 'i' => imag, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/complex' + # puts Complex(2).to_json + # puts Complex(2.0, 4).to_json + # + # Output: + # + # {"json_class":"Complex","r":2,"i":0} + # {"json_class":"Complex","r":2.0,"i":4} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/core.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/core.rb new file mode 100644 index 0000000..61ff454 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/core.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true +# This file requires the implementations of ruby core's custom objects for +# serialisation/deserialisation. + +require 'json/add/date' +require 'json/add/date_time' +require 'json/add/exception' +require 'json/add/range' +require 'json/add/regexp' +require 'json/add/string' +require 'json/add/struct' +require 'json/add/symbol' +require 'json/add/time' diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date.rb new file mode 100644 index 0000000..66965d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +require 'date' + +class Date + + # See #as_json. + def self.json_create(object) + civil(*object.values_at('y', 'm', 'd', 'sg')) + end + + alias start sg unless method_defined?(:start) + + # Methods Date#as_json and +Date.json_create+ may be used + # to serialize and deserialize a \Date object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Date#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/date' + # x = Date.today.as_json + # # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Date object: + # + # Date.json_create(x) + # # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'y' => year, + 'm' => month, + 'd' => day, + 'sg' => start, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/date' + # puts Date.today.to_json + # + # Output: + # + # {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date_time.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date_time.rb new file mode 100644 index 0000000..569f6ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/date_time.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +require 'date' + +class DateTime + + # See #as_json. + def self.json_create(object) + args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') + of_a, of_b = object['of'].split('/') + if of_b and of_b != '0' + args << Rational(of_a.to_i, of_b.to_i) + else + args << of_a + end + args << object['sg'] + civil(*args) + end + + alias start sg unless method_defined?(:start) + + # Methods DateTime#as_json and +DateTime.json_create+ may be used + # to serialize and deserialize a \DateTime object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method DateTime#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/datetime' + # x = DateTime.now.as_json + # # => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \DateTime object: + # + # DateTime.json_create(x) # BUG? Raises Date::Error "invalid date" + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'y' => year, + 'm' => month, + 'd' => day, + 'H' => hour, + 'M' => min, + 'S' => sec, + 'of' => offset.to_s, + 'sg' => start, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/datetime' + # puts DateTime.now.to_json + # + # Output: + # + # {"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0} + # + def to_json(*args) + as_json.to_json(*args) + end +end + + diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/exception.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/exception.rb new file mode 100644 index 0000000..5338ff8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/exception.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Exception + + # See #as_json. + def self.json_create(object) + result = new(object['m']) + result.set_backtrace object['b'] + result + end + + # Methods Exception#as_json and +Exception.json_create+ may be used + # to serialize and deserialize a \Exception object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Exception#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/exception' + # x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Exception object: + # + # Exception.json_create(x) # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'm' => message, + 'b' => backtrace, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/exception' + # puts Exception.new('Foo').to_json + # + # Output: + # + # {"json_class":"Exception","m":"Foo","b":null} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/ostruct.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/ostruct.rb new file mode 100644 index 0000000..534403b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/ostruct.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +begin + require 'ostruct' +rescue LoadError +end + +class OpenStruct + + # See #as_json. + def self.json_create(object) + new(object['t'] || object[:t]) + end + + # Methods OpenStruct#as_json and +OpenStruct.json_create+ may be used + # to serialize and deserialize a \OpenStruct object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method OpenStruct#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/ostruct' + # x = OpenStruct.new('name' => 'Rowdy', :age => nil).as_json + # # => {"json_class"=>"OpenStruct", "t"=>{:name=>'Rowdy', :age=>nil}} + # + # \Method +JSON.create+ deserializes such a hash, returning a \OpenStruct object: + # + # OpenStruct.json_create(x) + # # => # + # + def as_json(*) + klass = self.class.name + klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" + { + JSON.create_id => klass, + 't' => table, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/ostruct' + # puts OpenStruct.new('name' => 'Rowdy', :age => nil).to_json + # + # Output: + # + # {"json_class":"OpenStruct","t":{'name':'Rowdy',"age":null}} + # + def to_json(*args) + as_json.to_json(*args) + end +end if defined?(::OpenStruct) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/range.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/range.rb new file mode 100644 index 0000000..eb4b29a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/range.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Range + + # See #as_json. + def self.json_create(object) + new(*object['a']) + end + + # Methods Range#as_json and +Range.json_create+ may be used + # to serialize and deserialize a \Range object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Range#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/range' + # x = (1..4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, false]} + # y = (1...4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, true]} + # z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", false]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Range object: + # + # Range.json_create(x) # => 1..4 + # Range.json_create(y) # => 1...4 + # Range.json_create(z) # => "a".."d" + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'a' => [ first, last, exclude_end? ] + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/range' + # puts (1..4).to_json + # puts (1...4).to_json + # puts ('a'..'d').to_json + # + # Output: + # + # {"json_class":"Range","a":[1,4,false]} + # {"json_class":"Range","a":[1,4,true]} + # {"json_class":"Range","a":["a","d",false]} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/rational.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/rational.rb new file mode 100644 index 0000000..1eb2314 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/rational.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Rational + + # See #as_json. + def self.json_create(object) + Rational(object['n'], object['d']) + end + + # Methods Rational#as_json and +Rational.json_create+ may be used + # to serialize and deserialize a \Rational object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Rational#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/rational' + # x = Rational(2, 3).as_json + # # => {"json_class"=>"Rational", "n"=>2, "d"=>3} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Rational object: + # + # Rational.json_create(x) + # # => (2/3) + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'n' => numerator, + 'd' => denominator, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/rational' + # puts Rational(2, 3).to_json + # + # Output: + # + # {"json_class":"Rational","n":2,"d":3} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/regexp.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/regexp.rb new file mode 100644 index 0000000..f033dd1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/regexp.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Regexp + + # See #as_json. + def self.json_create(object) + new(object['s'], object['o']) + end + + # Methods Regexp#as_json and +Regexp.json_create+ may be used + # to serialize and deserialize a \Regexp object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Regexp#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/regexp' + # x = /foo/.as_json + # # => {"json_class"=>"Regexp", "o"=>0, "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Regexp object: + # + # Regexp.json_create(x) # => /foo/ + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'o' => options, + 's' => source, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/regexp' + # puts /foo/.to_json + # + # Output: + # + # {"json_class":"Regexp","o":0,"s":"foo"} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/set.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/set.rb new file mode 100644 index 0000000..c521d8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/set.rb @@ -0,0 +1,48 @@ +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +defined?(::Set) or require 'set' + +class Set + + # See #as_json. + def self.json_create(object) + new object['a'] + end + + # Methods Set#as_json and +Set.json_create+ may be used + # to serialize and deserialize a \Set object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Set#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/set' + # x = Set.new(%w/foo bar baz/).as_json + # # => {"json_class"=>"Set", "a"=>["foo", "bar", "baz"]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Set object: + # + # Set.json_create(x) # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'a' => to_a, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/set' + # puts Set.new(%w/foo bar baz/).to_json + # + # Output: + # + # {"json_class":"Set","a":["foo","bar","baz"]} + # + def to_json(*args) + as_json.to_json(*args) + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/string.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/string.rb new file mode 100644 index 0000000..9c3bde2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/string.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class String + # call-seq: json_create(o) + # + # Raw Strings are JSON Objects (the raw bytes are stored in an array for the + # key "raw"). The Ruby String can be created by this class method. + def self.json_create(object) + object["raw"].pack("C*") + end + + # call-seq: to_json_raw_object() + # + # This method creates a raw object hash, that can be nested into + # other data structures and will be generated as a raw string. This + # method should be used, if you want to convert raw strings to JSON + # instead of UTF-8 strings, e. g. binary data. + def to_json_raw_object + { + JSON.create_id => self.class.name, + "raw" => unpack("C*"), + } + end + + # call-seq: to_json_raw(*args) + # + # This method creates a JSON text from the result of a call to + # to_json_raw_object of this String. + def to_json_raw(...) + to_json_raw_object.to_json(...) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/struct.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/struct.rb new file mode 100644 index 0000000..98c38d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/struct.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Struct + + # See #as_json. + def self.json_create(object) + new(*object['v']) + end + + # Methods Struct#as_json and +Struct.json_create+ may be used + # to serialize and deserialize a \Struct object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Struct#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # x = Struct::Customer.new.as_json + # # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Struct object: + # + # Struct::Customer.json_create(x) + # # => # + # + def as_json(*) + klass = self.class.name + klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" + { + JSON.create_id => klass, + 'v' => values, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # puts Struct::Customer.new.to_json + # + # Output: + # + # {"json_class":"Struct","t":{'name':'Rowdy',"age":null}} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/symbol.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/symbol.rb new file mode 100644 index 0000000..20dd594 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/symbol.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Symbol + + # Methods Symbol#as_json and +Symbol.json_create+ may be used + # to serialize and deserialize a \Symbol object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Symbol#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/symbol' + # x = :foo.as_json + # # => {"json_class"=>"Symbol", "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Symbol object: + # + # Symbol.json_create(x) # => :foo + # + def as_json(*) + { + JSON.create_id => self.class.name, + 's' => to_s, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/symbol' + # puts :foo.to_json + # + # Output: + # + # # {"json_class":"Symbol","s":"foo"} + # + def to_json(state = nil, *a) + state = ::JSON::State.from_state(state) + if state.strict? + super + else + as_json.to_json(state, *a) + end + end + + # See #as_json. + def self.json_create(o) + o['s'].to_sym + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/time.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/time.rb new file mode 100644 index 0000000..05a1f24 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/add/time.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Time + + # See #as_json. + def self.json_create(object) + if usec = object.delete('u') # used to be tv_usec -> tv_nsec + object['n'] = usec * 1000 + end + at(object['s'], Rational(object['n'], 1000)) + end + + # Methods Time#as_json and +Time.json_create+ may be used + # to serialize and deserialize a \Time object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Time#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/time' + # x = Time.now.as_json + # # => {"json_class"=>"Time", "s"=>1700931656, "n"=>472846644} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Time object: + # + # Time.json_create(x) + # # => 2023-11-25 11:00:56.472846644 -0600 + # + def as_json(*) + { + JSON.create_id => self.class.name, + 's' => tv_sec, + 'n' => tv_nsec, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/time' + # puts Time.now.to_json + # + # Output: + # + # {"json_class":"Time","s":1700931678,"n":980650786} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/common.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/common.rb new file mode 100644 index 0000000..fdcb860 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/common.rb @@ -0,0 +1,1182 @@ +# frozen_string_literal: true + +require 'json/version' + +module JSON + autoload :GenericObject, 'json/generic_object' + + module ParserOptions # :nodoc: + class << self + def prepare(opts) + if opts[:object_class] || opts[:array_class] + opts = opts.dup + on_load = opts[:on_load] + + on_load = object_class_proc(opts[:object_class], on_load) if opts[:object_class] + on_load = array_class_proc(opts[:array_class], on_load) if opts[:array_class] + opts[:on_load] = on_load + end + + if opts.fetch(:create_additions, false) != false + opts = create_additions_proc(opts) + end + + opts + end + + private + + def object_class_proc(object_class, on_load) + ->(obj) do + if Hash === obj + object = object_class.new + obj.each { |k, v| object[k] = v } + obj = object + end + on_load.nil? ? obj : on_load.call(obj) + end + end + + def array_class_proc(array_class, on_load) + ->(obj) do + if Array === obj + array = array_class.new + obj.each { |v| array << v } + obj = array + end + on_load.nil? ? obj : on_load.call(obj) + end + end + + # TODO: extract :create_additions support to another gem for version 3.0 + def create_additions_proc(opts) + if opts[:symbolize_names] + raise ArgumentError, "options :symbolize_names and :create_additions cannot be used in conjunction" + end + + opts = opts.dup + create_additions = opts.fetch(:create_additions, false) + on_load = opts[:on_load] + object_class = opts[:object_class] || Hash + + opts[:on_load] = ->(object) do + case object + when String + opts[:match_string]&.each do |pattern, klass| + if match = pattern.match(object) + create_additions_warning if create_additions.nil? + object = klass.json_create(object) + break + end + end + when object_class + if opts[:create_additions] != false + if class_path = object[JSON.create_id] + klass = begin + Object.const_get(class_path) + rescue NameError => e + raise ArgumentError, "can't get const #{class_path}: #{e}" + end + + if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create) + create_additions_warning if create_additions.nil? + object = klass.json_create(object) + end + end + end + end + + on_load.nil? ? object : on_load.call(object) + end + + opts + end + + def create_additions_warning + JSON.deprecation_warning "JSON.load implicit support for `create_additions: true` is deprecated " \ + "and will be removed in 3.0, use JSON.unsafe_load or explicitly " \ + "pass `create_additions: true`" + end + end + end + + class << self + def deprecation_warning(message, uplevel = 3) # :nodoc: + gem_root = File.expand_path("..", __dir__) + "/" + caller_locations(uplevel, 10).each do |frame| + if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c") + uplevel += 1 + else + break + end + end + + if RUBY_VERSION >= "3.0" + warn(message, uplevel: uplevel, category: :deprecated) + else + warn(message, uplevel: uplevel) + end + end + + # :call-seq: + # JSON[object] -> new_array or new_string + # + # If +object+ is a \String, + # calls JSON.parse with +object+ and +opts+ (see method #parse): + # json = '[0, 1, null]' + # JSON[json]# => [0, 1, nil] + # + # Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate): + # ruby = [0, 1, nil] + # JSON[ruby] # => '[0,1,null]' + def [](object, opts = nil) + if object.is_a?(String) + return JSON.parse(object, opts) + elsif object.respond_to?(:to_str) + str = object.to_str + if str.is_a?(String) + return JSON.parse(str, opts) + end + end + + JSON.generate(object, opts) + end + + # Returns the JSON parser class that is used by JSON. + attr_reader :parser + + # Set the JSON parser class _parser_ to be used by JSON. + def parser=(parser) # :nodoc: + @parser = parser + remove_const :Parser if const_defined?(:Parser, false) + const_set :Parser, parser + end + + # Set the module _generator_ to be used by JSON. + def generator=(generator) # :nodoc: + old, $VERBOSE = $VERBOSE, nil + + # The default proc used when the +sort_keys+ generation option is +true+. + # It returns a new hash with the entries sorted by their keys. + sort_keys_proc = ->(hash) { hash.sort.to_h } + if defined?(::Ractor) && Ractor.respond_to?(:shareable_lambda) + sort_keys_proc = Ractor.shareable_lambda(&sort_keys_proc) + end + generator::State.default_sort_keys_proc = sort_keys_proc + + @generator = generator + if generator.const_defined?(:GeneratorMethods) + generator_methods = generator::GeneratorMethods + for const in generator_methods.constants + klass = const_get(const) + modul = generator_methods.const_get(const) + klass.class_eval do + instance_methods(false).each do |m| + m.to_s == 'to_json' and remove_method m + end + include modul + end + end + end + self.state = generator::State + const_set :State, state + ensure + $VERBOSE = old + end + + # Returns the JSON generator module that is used by JSON. + attr_reader :generator + + # Sets or Returns the JSON generator state class that is used by JSON. + attr_accessor :state + + private + + # Called from the extension when a hash has both string and symbol keys + def on_mixed_keys_hash(hash, do_raise) + set = {} + hash.each_key do |key| + key_str = key.to_s + + if set[key_str] + message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}" + if do_raise + raise GeneratorError, message + else + deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`") + end + else + set[key_str] = true + end + end + end + + def deprecated_singleton_attr_accessor(*attrs) + args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : "" + attrs.each do |attr| + singleton_class.class_eval <<~RUBY + def #{attr} + warn "JSON.#{attr} is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args} + @#{attr} + end + + def #{attr}=(val) + warn "JSON.#{attr}= is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args} + @#{attr} = val + end + + def _#{attr} + @#{attr} + end + RUBY + end + end + end + + # Sets create identifier, which is used to decide if the _json_create_ + # hook of a class should be called; initial value is +json_class+: + # JSON.create_id # => 'json_class' + def self.create_id=(new_value) + Thread.current[:"JSON.create_id"] = new_value.dup.freeze + end + + # Returns the current create identifier. + # See also JSON.create_id=. + def self.create_id + Thread.current[:"JSON.create_id"] || 'json_class' + end + + NaN = Float::NAN + + Infinity = Float::INFINITY + + MinusInfinity = -Infinity + + # The base exception for JSON errors. + class JSONError < StandardError; end + + # This exception is raised if a parser error occurs. + class ParserError < JSONError + attr_reader :line, :column + end + + # This exception is raised if the nesting of parsed data structures is too + # deep. + class NestingError < ParserError; end + + # This exception is raised if a generator or unparser error occurs. + class GeneratorError < JSONError + attr_reader :invalid_object + + def initialize(message, invalid_object = nil) + super(message) + @invalid_object = invalid_object + end + + def detailed_message(...) + # Exception#detailed_message doesn't exist until Ruby 3.2 + super_message = defined?(super) ? super : message + + if @invalid_object.nil? + super_message + else + "#{super_message}\nInvalid object: #{@invalid_object.inspect}" + end + end + end + + # Fragment of JSON document that is to be included as is: + # fragment = JSON::Fragment.new("[1, 2, 3]") + # JSON.generate({ count: 3, items: fragments }) + # + # This allows to easily assemble multiple JSON fragments that have + # been persisted somewhere without having to parse them nor resorting + # to string interpolation. + # + # Note: no validation is performed on the provided string. It is the + # responsibility of the caller to ensure the string contains valid JSON. + Fragment = Struct.new(:json) do + def initialize(json) + unless string = String.try_convert(json) + raise TypeError, " no implicit conversion of #{json.class} into String" + end + + super(string) + end + + def to_json(state = nil, *) + json + end + end + + module_function + + # :call-seq: + # JSON.parse(source, opts) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # Argument +source+ contains the \String to be parsed. + # + # Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # + # --- + # + # When +source+ is a \JSON array, returns a Ruby \Array: + # source = '["foo", 1.0, true, false, null]' + # ruby = JSON.parse(source) + # ruby # => ["foo", 1.0, true, false, nil] + # ruby.class # => Array + # + # When +source+ is a \JSON object, returns a Ruby \Hash: + # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}' + # ruby = JSON.parse(source) + # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil} + # ruby.class # => Hash + # + # For examples of parsing for all \JSON data types, see + # {Parsing \JSON}[#module-JSON-label-Parsing+JSON]. + # + # Parses nested JSON objects: + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON + # ruby = JSON.parse(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # Raises an exception if +source+ is not valid JSON: + # # Raises JSON::ParserError (783: unexpected token at ''): + # JSON.parse('') + # + def parse(source, opts = nil) + opts = ParserOptions.prepare(opts) unless opts.nil? + Parser.parse(source, opts) + end + + PARSE_L_OPTIONS = { + max_nesting: false, + allow_nan: true, + }.freeze + private_constant :PARSE_L_OPTIONS + + # :call-seq: + # JSON.parse!(source, opts) -> object + # + # Calls + # parse(source, opts) + # with +source+ and possibly modified +opts+. + # + # Differences from JSON.parse: + # - Option +max_nesting+, if not provided, defaults to +false+, + # which disables checking for nesting depth. + # - Option +allow_nan+, if not provided, defaults to +true+. + def parse!(source, opts = nil) + if opts.nil? + parse(source, PARSE_L_OPTIONS) + else + parse(source, PARSE_L_OPTIONS.merge(opts)) + end + end + + # :call-seq: + # JSON.load_file(path, opts={}) -> object + # + # Calls: + # parse(File.read(path), opts) + # + # See method #parse. + def load_file(filespec, opts = nil) + parse(File.read(filespec, encoding: Encoding::UTF_8), opts) + end + + # :call-seq: + # JSON.load_file!(path, opts = {}) + # + # Calls: + # JSON.parse!(File.read(path, opts)) + # + # See method #parse! + def load_file!(filespec, opts = nil) + parse!(File.read(filespec, encoding: Encoding::UTF_8), opts) + end + + # :call-seq: + # JSON.generate(obj, opts = nil) -> new_string + # + # Returns a \String containing the generated \JSON data. + # + # See also JSON.pretty_generate. + # + # Argument +obj+ is the Ruby object to be converted to \JSON. + # + # Argument +opts+, if given, contains a \Hash of options for the generation. + # See {Generating Options}[#module-JSON-label-Generating+Options]. + # + # --- + # + # When +obj+ is an \Array, returns a \String containing a \JSON array: + # obj = ["foo", 1.0, true, false, nil] + # json = JSON.generate(obj) + # json # => '["foo",1.0,true,false,null]' + # + # When +obj+ is a \Hash, returns a \String containing a \JSON object: + # obj = {foo: 0, bar: 's', baz: :bat} + # json = JSON.generate(obj) + # json # => '{"foo":0,"bar":"s","baz":"bat"}' + # + # For examples of generating from other Ruby objects, see + # {Generating \JSON from Other Objects}[#module-JSON-label-Generating+JSON+from+Other+Objects]. + # + # --- + # + # Raises an exception if any formatting option is not a \String. + # + # Raises an exception if +obj+ contains circular references: + # a = []; b = []; a.push(b); b.push(a) + # # Raises JSON::NestingError (nesting of 100 is too deep): + # JSON.generate(a) + # + def generate(obj, opts = nil) + if State === opts + opts.generate(obj) + else + State.generate(obj, opts, nil) + end + end + + # :call-seq: + # JSON.fast_generate(obj, opts) -> new_string + # + # Arguments +obj+ and +opts+ here are the same as + # arguments +obj+ and +opts+ in JSON.generate. + # + # By default, generates \JSON data without checking + # for circular references in +obj+ (option +max_nesting+ set to +false+, disabled). + # + # Raises an exception if +obj+ contains circular references: + # a = []; b = []; a.push(b); b.push(a) + # # Raises SystemStackError (stack level too deep): + # JSON.fast_generate(a) + def fast_generate(obj, opts = nil) + if RUBY_VERSION >= "3.0" + warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated + else + warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(obj, opts) + end + + PRETTY_GENERATE_OPTIONS = { + indent: ' ', + space: ' ', + object_nl: "\n", + array_nl: "\n", + }.freeze + private_constant :PRETTY_GENERATE_OPTIONS + + # :call-seq: + # JSON.pretty_generate(obj, opts = nil) -> new_string + # + # Arguments +obj+ and +opts+ here are the same as + # arguments +obj+ and +opts+ in JSON.generate. + # + # Default options are: + # { + # indent: ' ', # Two spaces + # space: ' ', # One space + # array_nl: "\n", # Newline + # object_nl: "\n" # Newline + # } + # + # Example: + # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}} + # json = JSON.pretty_generate(obj) + # puts json + # Output: + # { + # "foo": [ + # "bar", + # "baz" + # ], + # "bat": { + # "bam": 0, + # "bad": 1 + # } + # } + # + def pretty_generate(obj, opts = nil) + return opts.generate(obj) if State === opts + + options = PRETTY_GENERATE_OPTIONS + + if opts + unless opts.is_a?(Hash) + if opts.respond_to? :to_hash + opts = opts.to_hash + elsif opts.respond_to? :to_h + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + end + options = options.merge(opts) + end + + State.generate(obj, options, nil) + end + + # Sets or returns default options for the JSON.unsafe_load method. + # Initially: + # opts = JSON.load_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} + deprecated_singleton_attr_accessor :unsafe_load_default_options + + @unsafe_load_default_options = { + :max_nesting => false, + :allow_nan => true, + :allow_blank => true, + :create_additions => true, + } + + # Sets or returns default options for the JSON.load method. + # Initially: + # opts = JSON.load_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} + deprecated_singleton_attr_accessor :load_default_options + + @load_default_options = { + :allow_nan => true, + :allow_blank => true, + :create_additions => nil, + } + # :call-seq: + # JSON.unsafe_load(source, options = {}) -> object + # JSON.unsafe_load(source, proc = nil, options = {}) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # BEWARE: This method is meant to serialise data from trusted user input, + # like from your own database server or clients under your control, it could + # be dangerous to allow untrusted users to pass JSON sources into it. + # + # - Argument +source+ must be, or be convertible to, a \String: + # - If +source+ responds to instance method +to_str+, + # source.to_str becomes the source. + # - If +source+ responds to instance method +to_io+, + # source.to_io.read becomes the source. + # - If +source+ responds to instance method +read+, + # source.read becomes the source. + # - If both of the following are true, source becomes the \String 'null': + # - Option +allow_blank+ specifies a truthy value. + # - The source, as defined above, is +nil+ or the empty \String ''. + # - Otherwise, +source+ remains the source. + # - Argument +proc+, if given, must be a \Proc that accepts one argument. + # It will be called recursively with each result (depth-first order). + # See details below. + # - Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # The default options can be changed via method JSON.unsafe_load_default_options=. + # + # --- + # + # When no +proc+ is given, modifies +source+ as above and returns the result of + # parse(source, opts); see #parse. + # + # Source for following examples: + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON + # + # Load a \String: + # ruby = JSON.unsafe_load(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load an \IO object: + # require 'stringio' + # object = JSON.unsafe_load(StringIO.new(source)) + # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load a \File object: + # path = 't.json' + # File.write(path, source) + # File.open(path) do |file| + # JSON.unsafe_load(file) + # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # When +proc+ is given: + # - Modifies +source+ as above. + # - Gets the +result+ from calling parse(source, opts). + # - Recursively calls proc(result). + # - Returns the final result. + # + # Example: + # require 'json' + # + # # Some classes for the example. + # class Base + # def initialize(attributes) + # @attributes = attributes + # end + # end + # class User < Base; end + # class Account < Base; end + # class Admin < Base; end + # # The JSON source. + # json = <<-EOF + # { + # "users": [ + # {"type": "User", "username": "jane", "email": "jane@example.com"}, + # {"type": "User", "username": "john", "email": "john@example.com"} + # ], + # "accounts": [ + # {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, + # {"account": {"type": "Account", "paid": false, "account_id": "1235"}} + # ], + # "admins": {"type": "Admin", "password": "0wn3d"} + # } + # EOF + # # Deserializer method. + # def deserialize_obj(obj, safe_types = %w(User Account Admin)) + # type = obj.is_a?(Hash) && obj["type"] + # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj + # end + # # Call to JSON.unsafe_load + # ruby = JSON.unsafe_load(json, proc {|obj| + # case obj + # when Hash + # obj.each {|k, v| obj[k] = deserialize_obj v } + # when Array + # obj.map! {|v| deserialize_obj v } + # end + # obj + # }) + # pp ruby + # Output: + # {"users"=> + # [#"User", "username"=>"jane", "email"=>"jane@example.com"}>, + # #"User", "username"=>"john", "email"=>"john@example.com"}>], + # "accounts"=> + # [{"account"=> + # #"Account", "paid"=>true, "account_id"=>"1234"}>}, + # {"account"=> + # #"Account", "paid"=>false, "account_id"=>"1235"}>}], + # "admins"=> + # #"Admin", "password"=>"0wn3d"}>} + # + def unsafe_load(source, proc = nil, options = nil) + opts = if options.nil? + if proc && proc.is_a?(Hash) + options, proc = proc, nil + options + else + _unsafe_load_default_options + end + else + _unsafe_load_default_options.merge(options) + end + + unless source.is_a?(String) + if source.respond_to? :to_str + source = source.to_str + elsif source.respond_to? :to_io + source = source.to_io.read + elsif source.respond_to?(:read) + source = source.read + end + end + + if opts[:allow_blank] && (source.nil? || source.empty?) + source = 'null' + end + + if proc + opts = opts.dup + opts[:on_load] = proc.to_proc + end + + parse(source, opts) + end + + # :call-seq: + # JSON.load(source, options = {}) -> object + # JSON.load(source, proc = nil, options = {}) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # BEWARE: This method is meant to serialise data from trusted user input, + # like from your own database server or clients under your control, it could + # be dangerous to allow untrusted users to pass JSON sources into it. + # If you must use it, use JSON.unsafe_load instead to make it clear. + # + # Since JSON version 2.8.0, `load` emits a deprecation warning when a + # non native type is deserialized, without `create_additions` being explicitly + # enabled, and in JSON version 3.0, `load` will have `create_additions` disabled + # by default. + # + # - Argument +source+ must be, or be convertible to, a \String: + # - If +source+ responds to instance method +to_str+, + # source.to_str becomes the source. + # - If +source+ responds to instance method +to_io+, + # source.to_io.read becomes the source. + # - If +source+ responds to instance method +read+, + # source.read becomes the source. + # - If both of the following are true, source becomes the \String 'null': + # - Option +allow_blank+ specifies a truthy value. + # - The source, as defined above, is +nil+ or the empty \String ''. + # - Otherwise, +source+ remains the source. + # - Argument +proc+, if given, must be a \Proc that accepts one argument. + # It will be called recursively with each result (depth-first order). + # See details below. + # - Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # The default options can be changed via method JSON.load_default_options=. + # + # --- + # + # When no +proc+ is given, modifies +source+ as above and returns the result of + # parse(source, opts); see #parse. + # + # Source for following examples: + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON + # + # Load a \String: + # ruby = JSON.load(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load an \IO object: + # require 'stringio' + # object = JSON.load(StringIO.new(source)) + # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load a \File object: + # path = 't.json' + # File.write(path, source) + # File.open(path) do |file| + # JSON.load(file) + # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # When +proc+ is given: + # - Modifies +source+ as above. + # - Gets the +result+ from calling parse(source, opts). + # - Recursively calls proc(result). + # - Returns the final result. + # + # Example: + # require 'json' + # + # # Some classes for the example. + # class Base + # def initialize(attributes) + # @attributes = attributes + # end + # end + # class User < Base; end + # class Account < Base; end + # class Admin < Base; end + # # The JSON source. + # json = <<-EOF + # { + # "users": [ + # {"type": "User", "username": "jane", "email": "jane@example.com"}, + # {"type": "User", "username": "john", "email": "john@example.com"} + # ], + # "accounts": [ + # {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, + # {"account": {"type": "Account", "paid": false, "account_id": "1235"}} + # ], + # "admins": {"type": "Admin", "password": "0wn3d"} + # } + # EOF + # # Deserializer method. + # def deserialize_obj(obj, safe_types = %w(User Account Admin)) + # type = obj.is_a?(Hash) && obj["type"] + # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj + # end + # # Call to JSON.load + # ruby = JSON.load(json, proc {|obj| + # case obj + # when Hash + # obj.each {|k, v| obj[k] = deserialize_obj v } + # when Array + # obj.map! {|v| deserialize_obj v } + # end + # obj + # }) + # pp ruby + # Output: + # {"users"=> + # [#"User", "username"=>"jane", "email"=>"jane@example.com"}>, + # #"User", "username"=>"john", "email"=>"john@example.com"}>], + # "accounts"=> + # [{"account"=> + # #"Account", "paid"=>true, "account_id"=>"1234"}>}, + # {"account"=> + # #"Account", "paid"=>false, "account_id"=>"1235"}>}], + # "admins"=> + # #"Admin", "password"=>"0wn3d"}>} + # + def load(source, proc = nil, options = nil) + if proc && options.nil? && proc.is_a?(Hash) + options = proc + proc = nil + end + + opts = if options.nil? + if proc && proc.is_a?(Hash) + options, proc = proc, nil + options + else + _load_default_options + end + else + _load_default_options.merge(options) + end + + unless source.is_a?(String) + if source.respond_to? :to_str + source = source.to_str + elsif source.respond_to? :to_io + source = source.to_io.read + elsif source.respond_to?(:read) + source = source.read + end + end + + if opts[:allow_blank] && (source.nil? || (String === source && source.empty?)) + source = 'null' + end + + if proc + opts = opts.dup + opts[:on_load] = proc.to_proc + end + + parse(source, opts) + end + + # Sets or returns the default options for the JSON.dump method. + # Initially: + # opts = JSON.dump_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true} + deprecated_singleton_attr_accessor :dump_default_options + @dump_default_options = { + :max_nesting => false, + :allow_nan => true, + } + + # :call-seq: + # JSON.dump(obj, io = nil, limit = nil) + # + # Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result. + # + # The default options can be changed via method JSON.dump_default_options. + # + # - Argument +io+, if given, should respond to method +write+; + # the \JSON \String is written to +io+, and +io+ is returned. + # If +io+ is not given, the \JSON \String is returned. + # - Argument +limit+, if given, is passed to JSON.generate as option +max_nesting+. + # + # --- + # + # When argument +io+ is not given, returns the \JSON \String generated from +obj+: + # obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad} + # json = JSON.dump(obj) + # json # => "{\"foo\":[0,1],\"bar\":{\"baz\":2,\"bat\":3},\"bam\":\"bad\"}" + # + # When argument +io+ is given, writes the \JSON \String to +io+ and returns +io+: + # path = 't.json' + # File.open(path, 'w') do |file| + # JSON.dump(obj, file) + # end # => # + # puts File.read(path) + # Output: + # {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"} + def dump(obj, anIO = nil, limit = nil, kwargs = nil) + if kwargs.nil? + if limit.nil? + if anIO.is_a?(Hash) + kwargs = anIO + anIO = nil + end + elsif limit.is_a?(Hash) + kwargs = limit + limit = nil + end + end + + unless anIO.nil? + if anIO.respond_to?(:to_io) + anIO = anIO.to_io + elsif limit.nil? && !anIO.respond_to?(:write) + anIO, limit = nil, anIO + end + end + + opts = JSON._dump_default_options + opts = opts.merge(:max_nesting => limit) if limit + opts = opts.merge(kwargs) if kwargs + + begin + State.generate(obj, opts, anIO) + rescue JSON::NestingError + raise ArgumentError, "exceed depth limit" + end + end + + # :stopdoc: + # All these were meant to be deprecated circa 2009, but were just set as undocumented + # so usage still exist in the wild. + def unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated + else + warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(...) + end + module_function :unparse + + def fast_unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated + else + warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(...) + end + module_function :fast_unparse + + def pretty_unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated + else + warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1 + end + pretty_generate(...) + end + module_function :fast_unparse + + def restore(...) + if RUBY_VERSION >= "3.0" + warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1, category: :deprecated + else + warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1 + end + load(...) + end + module_function :restore + + class << self + private + + def const_missing(const_name) + case const_name + when :PRETTY_STATE_PROTOTYPE + if RUBY_VERSION >= "3.0" + warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated + else + warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1 + end + state.new(PRETTY_GENERATE_OPTIONS) + else + super + end + end + end + # :startdoc: + + # JSON::Coder holds a parser and generator configuration. + # + # module MyApp + # JSONC_CODER = JSON::Coder.new( + # allow_trailing_comma: true + # ) + # end + # + # MyApp::JSONC_CODER.load(document) + # + class Coder + # :call-seq: + # JSON.new(options = nil, &block) + # + # Argument +options+, if given, contains a \Hash of options for both parsing and generating. + # See {Parsing Options}[rdoc-ref:JSON@Parsing+Options], + # and {Generating Options}[rdoc-ref:JSON@Generating+Options]. + # + # For generation, the strict: true option is always set. When a Ruby object with no native \JSON counterpart is + # encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native + # \JSON counterpart: + # + # module MyApp + # API_JSON_CODER = JSON::Coder.new do |object| + # case object + # when Time + # object.iso8601(3) + # else + # object # Unknown type, will raise + # end + # end + # end + # + # puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z" + # + def initialize(options = nil, &as_json) + if options.nil? + options = { strict: true } + else + options = options.dup + options[:strict] = true + end + options[:as_json] = as_json if as_json + + @state = State.new(options).freeze + @parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options)).freeze + end + + # call-seq: + # dump(object) -> String + # dump(object, io) -> io + # + # Serialize the given object into a \JSON document. + def dump(object, io = nil) + @state.generate(object, io) + end + alias_method :generate, :dump + + # call-seq: + # load(string) -> Object + # + # Parse the given \JSON document and return an equivalent Ruby object. + def load(source) + @parser_config.parse(source) + end + alias_method :parse, :load + + # call-seq: + # load(path) -> Object + # + # Parse the given \JSON document and return an equivalent Ruby object. + def load_file(path) + load(File.read(path, encoding: Encoding::UTF_8)) + end + end + + module GeneratorMethods + # call-seq: to_json(*) + # + # Converts this object into a JSON string. + # If this object doesn't directly maps to a JSON native type, + # first convert it to a string (calling #to_s), then converts + # it to a JSON string, and returns the result. + # This is a fallback, if no special method #to_json was defined for some object. + def to_json(state = nil, *) + obj = case self + when nil, false, true, Integer, Float, Array, Hash + self + else + "#{self}" + end + + if state.nil? + JSON::State._generate_no_fallback(obj, nil, nil) + else + JSON::State.from_state(state)._generate_no_fallback(obj) + end + end + end +end + +module ::Kernel + private + + # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in + # one line. + def j(*objs) + if RUBY_VERSION >= "3.0" + warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated + else + warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1 + end + + objs.each do |obj| + puts JSON.generate(obj, :allow_nan => true, :max_nesting => false) + end + nil + end + + # Outputs _objs_ to STDOUT as JSON strings in a pretty format, with + # indentation and over many lines. + def jj(*objs) + if RUBY_VERSION >= "3.0" + warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated + else + warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1 + end + + objs.each do |obj| + puts JSON.pretty_generate(obj, :allow_nan => true, :max_nesting => false) + end + nil + end + + # If _object_ is string-like, parse the string and return the parsed result as + # a Ruby data structure. Otherwise, generate a JSON text from the Ruby data + # structure object and return it. + # + # The _opts_ argument is passed through to generate/parse respectively. See + # generate and parse for their documentation. + def JSON(object, opts = nil) + JSON[object, opts] + end +end + +class Object + include JSON::GeneratorMethods +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext.rb new file mode 100644 index 0000000..28500f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'json/common' + +module JSON + # This module holds all the modules/classes that implement JSON's + # functionality as C extensions. + module Ext + class Parser + class << self + def parse(...) + new(...).parse + end + alias_method :parse, :parse # Allow redefinition by extensions + end + + def initialize(source, opts = nil) + @source = source + @config = Config.new(opts) + end + + def source + @source.dup + end + + def parse + @config.parse(@source) + end + end + + require 'json/ext/parser' + Ext::Parser::Config = Ext::ParserConfig + JSON.parser = Ext::Parser + + if RUBY_ENGINE == 'truffleruby' + require 'json/truffle_ruby/generator' + JSON.generator = JSON::TruffleRuby::Generator + else + require 'json/ext/generator' + JSON.generator = Generator + end + end + + if defined?(ResumableParser) # Not yet available on JRuby + class ResumableParser + # Returns whether the parser is entirely done: no unconsumed bytes in + # the buffer, no document under construction and no parsed value + # awaiting retrieval. + # + # The main use case is detecting a truncated stream once the input is + # exhausted: + # + # loop do + # begin + # parser << socket.readpartial(4096) + # rescue EOFError + # break + # end + # while parser.parse + # process(parser.value) + # end + # end + # warn "stream was truncated" unless parser.empty? + def empty? + eos? && !partial_value? && !value? + end + end + end + + JSON_LOADED = true unless defined?(JSON::JSON_LOADED) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator.bundle b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator.bundle new file mode 100755 index 0000000..96b7040 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator/state.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator/state.rb new file mode 100644 index 0000000..3c1d2fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/generator/state.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +module JSON + module Ext + module Generator + class State + # call-seq: new(opts = {}) + # + # Instantiates a new State object, configured by _opts_. + # + # Argument +opts+, if given, contains a \Hash of options for the generation. + # See {Generating Options}[rdoc-ref:JSON@Generating+Options]. + def initialize(opts = nil) + if opts && !opts.empty? + configure(opts) + end + end + + # call-seq: configure(opts) + # + # Configure this State instance with the Hash _opts_, and return + # itself. + def configure(opts) + unless opts.is_a?(Hash) + if opts.respond_to?(:to_hash) + opts = opts.to_hash + elsif opts.respond_to?(:to_h) + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + end + _configure(opts) + end + + alias_method :merge, :configure + + # call-seq: to_h + # + # Returns the configuration instance variables as a hash, that can be + # passed to the configure method. + def to_h + result = { + indent: indent, + space: space, + space_before: space_before, + object_nl: object_nl, + array_nl: array_nl, + as_json: as_json, + allow_nan: allow_nan?, + ascii_only: ascii_only?, + max_nesting: max_nesting, + script_safe: script_safe?, + strict: strict?, + depth: depth, + buffer_initial_length: buffer_initial_length, + sort_keys: sort_keys + } + + allow_duplicate_key = allow_duplicate_key? + unless allow_duplicate_key.nil? + result[:allow_duplicate_key] = allow_duplicate_key + end + + instance_variables.each do |iv| + iv = iv.to_s[1..-1] + result[iv.to_sym] = self[iv] + end + + result + end + + alias_method :to_hash, :to_h + + # call-seq: [](name) + # + # Returns the value returned by method +name+. + def [](name) + ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0") + + if respond_to?(name) + __send__(name) + else + instance_variable_get("@#{name}") if + instance_variables.include?("@#{name}".to_sym) # avoid warning + end + end + + # call-seq: []=(name, value) + # + # Sets the attribute name to value. + def []=(name, value) + ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0") + + if respond_to?(name_writer = "#{name}=") + __send__ name_writer, value + else + instance_variable_set "@#{name}", value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/parser.bundle b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/parser.bundle new file mode 100755 index 0000000..432f107 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/ext/parser.bundle differ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/generic_object.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/generic_object.rb new file mode 100644 index 0000000..5c8ace3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/generic_object.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +begin + require 'ostruct' +rescue LoadError + warn "JSON::GenericObject requires 'ostruct'. Please install it with `gem install ostruct`." +end + +module JSON + class GenericObject < OpenStruct + class << self + alias [] new + + def json_creatable? + @json_creatable + end + + attr_writer :json_creatable + + def json_create(data) + data = data.dup + data.delete JSON.create_id + self[data] + end + + def from_hash(object) + case + when object.respond_to?(:to_hash) + result = new + object.to_hash.each do |key, value| + result[key] = from_hash(value) + end + result + when object.respond_to?(:to_ary) + object.to_ary.map { |a| from_hash(a) } + else + object + end + end + + def load(source, proc = nil, opts = {}) + result = ::JSON.load(source, proc, opts.merge(:object_class => self)) + result.nil? ? new : result + end + + def dump(obj, *args) + ::JSON.dump(obj, *args) + end + end + self.json_creatable = false + + def to_hash + table + end + + def |(other) + self.class[other.to_hash.merge(to_hash)] + end + + def as_json(*) + { JSON.create_id => self.class.name }.merge to_hash + end + + def to_json(*a) + as_json.to_json(*a) + end + end if defined?(::OpenStruct) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/truffle_ruby/generator.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/truffle_ruby/generator.rb new file mode 100644 index 0000000..ee6186f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/truffle_ruby/generator.rb @@ -0,0 +1,790 @@ +# frozen_string_literal: true +module JSON + module TruffleRuby + module Generator + MAP = { + "\x0" => '\u0000', + "\x1" => '\u0001', + "\x2" => '\u0002', + "\x3" => '\u0003', + "\x4" => '\u0004', + "\x5" => '\u0005', + "\x6" => '\u0006', + "\x7" => '\u0007', + "\b" => '\b', + "\t" => '\t', + "\n" => '\n', + "\xb" => '\u000b', + "\f" => '\f', + "\r" => '\r', + "\xe" => '\u000e', + "\xf" => '\u000f', + "\x10" => '\u0010', + "\x11" => '\u0011', + "\x12" => '\u0012', + "\x13" => '\u0013', + "\x14" => '\u0014', + "\x15" => '\u0015', + "\x16" => '\u0016', + "\x17" => '\u0017', + "\x18" => '\u0018', + "\x19" => '\u0019', + "\x1a" => '\u001a', + "\x1b" => '\u001b', + "\x1c" => '\u001c', + "\x1d" => '\u001d', + "\x1e" => '\u001e', + "\x1f" => '\u001f', + '"' => '\"', + '\\' => '\\\\', + }.freeze # :nodoc: + + SCRIPT_SAFE_MAP = MAP.merge( + '/' => '\\/', + "\u2028" => '\u2028', + "\u2029" => '\u2029', + ).freeze + + SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/ + + def self.native_type?(value) # :nodoc: + (false == value || true == value || nil == value || String === value || Symbol === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value) + end + + def self.native_key?(key) # :nodoc: + (Symbol === key || String === key) + end + + def self.valid_encoding?(string) # :nodoc: + return false unless string.encoding == ::Encoding::UTF_8 || string.encoding == ::Encoding::US_ASCII + string.is_a?(Symbol) || string.valid_encoding? + end + + # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with + # UTF16 big endian characters as \u????, and return it. + def self.utf8_to_json(string, script_safe = false) # :nodoc: + if script_safe + if SCRIPT_SAFE_ESCAPE_PATTERN.match?(string) + string.gsub(SCRIPT_SAFE_ESCAPE_PATTERN, SCRIPT_SAFE_MAP) + else + string + end + else + if /["\\\x0-\x1f]/.match?(string) + string.gsub(/["\\\x0-\x1f]/, MAP) + else + string + end + end + end + + def self.utf8_to_json_ascii(original_string, script_safe = false) # :nodoc: + string = original_string.b + map = script_safe ? SCRIPT_SAFE_MAP : MAP + string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& } + string.gsub!(/( + (?: + [\xc2-\xdf][\x80-\xbf] | + [\xe0-\xef][\x80-\xbf]{2} | + [\xf0-\xf4][\x80-\xbf]{3} + )+ | + [\x80-\xc1\xf5-\xff] # invalid + )/nx) { |c| + c.size == 1 and raise GeneratorError.new("invalid utf8 byte: '#{c}'", original_string) + s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0] + s.force_encoding(::Encoding::BINARY) + s.gsub!(/.{4}/n, '\\\\u\&') + s.force_encoding(::Encoding::UTF_8) + } + string.force_encoding(::Encoding::UTF_8) + string + rescue => e + raise GeneratorError.new(e.message, original_string) + end + + def self.valid_utf8?(string) + encoding = string.encoding + (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) && + string.valid_encoding? + end + + # This class is used to create State instances, that are use to hold data + # while generating a JSON text from a Ruby data structure. + class State + singleton_class.attr_accessor :default_sort_keys_proc # :nodoc: + + def self.generate(obj, opts = nil, io = nil) + new(opts).generate(obj, io) + end + + # Creates a State object from _opts_, which ought to be Hash to create + # a new State instance configured by _opts_, something else to create + # an unconfigured instance. If _opts_ is a State object, it is just + # returned. + def self.from_state(opts) + if opts + case + when self === opts + return opts + when opts.respond_to?(:to_hash) + return new(opts.to_hash) + when opts.respond_to?(:to_h) + return new(opts.to_h) + end + end + new + end + + # Instantiates a new State object, configured by _opts_. + # + # _opts_ can have the following keys: + # + # * *indent*: a string used to indent levels (default: ''), + # * *space*: a string that is put after, a : or , delimiter (default: ''), + # * *space_before*: a string that is put before a : pair delimiter (default: ''), + # * *object_nl*: a string that is put at the end of a JSON object (default: ''), + # * *array_nl*: a string that is put at the end of a JSON array (default: ''), + # * *script_safe*: true if U+2028, U+2029 and forward slash (/) should be escaped + # as to make the JSON object safe to interpolate in a script tag (default: false). + # * *check_circular*: is deprecated now, use the :max_nesting option instead, + # * *max_nesting*: sets the maximum level of data structure nesting in + # the generated JSON, max_nesting = 0 if no maximum should be checked. + # * *allow_nan*: true if NaN, Infinity, and -Infinity should be + # generated, otherwise an exception is thrown, if these values are + # encountered. This options defaults to false. + def initialize(opts = nil) + @indent = '' + @space = '' + @space_before = '' + @object_nl = '' + @array_nl = '' + @allow_nan = false + @ascii_only = false + @as_json = false + @depth = 0 + @buffer_initial_length = 1024 + @script_safe = false + @strict = false + @max_nesting = 100 + @sort_keys = false + configure(opts) if opts + end + + # This string is used to indent levels in the JSON text. + attr_accessor :indent + + # This string is used to insert a space between the tokens in a JSON + # string. + attr_accessor :space + + # This string is used to insert a space before the ':' in JSON objects. + attr_accessor :space_before + + # This string is put at the end of a line that holds a JSON object (or + # Hash). + attr_accessor :object_nl + + # This string is put at the end of a line that holds a JSON array. + attr_accessor :array_nl + + # This proc converts unsupported types into native JSON types. + attr_accessor :as_json + + # This integer returns the maximum level of data structure nesting in + # the generated JSON, max_nesting = 0 if no maximum is checked. + attr_accessor :max_nesting + + # If this attribute is set to true, forward slashes will be escaped in + # all json strings. + attr_accessor :script_safe + + # If this attribute is set to true, attempting to serialize types not + # supported by the JSON spec will raise a JSON::GeneratorError + attr_accessor :strict + + # Controls key sorting in the generated JSON. If set to +true+, object + # keys are sorted by key lexicographically. If set to a Proc, it + # receives the entire Hash and must return a Hash with its pairs in the + # desired order. + attr_reader :sort_keys + + def sort_keys=(value) # :nodoc: + type_error = false + @sort_keys = case value + when Proc + value + when true + State.default_sort_keys_proc + when nil, false + false + else + type_error = true + false + end + + if type_error + raise TypeError, "The `sort_keys` argument must be a boolean or a Proc" + end + + @sort_keys + end + + # :stopdoc: + attr_reader :buffer_initial_length + + def buffer_initial_length=(length) + if length > 0 + @buffer_initial_length = length + end + end + # :startdoc: + + # This integer returns the current depth data structure nesting in the + # generated JSON. + attr_reader :depth + + def depth=(depth) + if depth.negative? + raise ArgumentError, "depth must be >= 0 (got #{depth})" + end + @depth = depth + end + + def check_max_nesting # :nodoc: + return if @max_nesting.zero? + current_nesting = depth + 1 + current_nesting > @max_nesting and + raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?" + end + + # Returns true, if circular data structures are checked, + # otherwise returns false. + def check_circular? + !@max_nesting.zero? + end + + # Returns true if NaN, Infinity, and -Infinity should be considered as + # valid JSON and output. + def allow_nan? + @allow_nan + end + + # Returns true, if only ASCII characters should be generated. Otherwise + # returns false. + def ascii_only? + @ascii_only + end + + # Returns true, if forward slashes are escaped. Otherwise returns false. + def script_safe? + @script_safe + end + + # Returns true, if strict mode is enabled. Otherwise returns false. + # Strict mode only allow serializing JSON native types: Hash, Array, + # String, Integer, Float, true, false and nil. + def strict? + @strict + end + + # Configure this State instance with the Hash _opts_, and return + # itself. + def configure(opts) + if opts.respond_to?(:to_hash) + opts = opts.to_hash + elsif opts.respond_to?(:to_h) + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + + if opts[:depth]&.negative? + raise ArgumentError, "depth must be >= 0 (got #{opts[:depth]})" + end + + opts.each do |key, value| + instance_variable_set "@#{key}", value + end + + # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json + @indent = opts[:indent] || '' if opts.key?(:indent) + @space = opts[:space] || '' if opts.key?(:space) + @space_before = opts[:space_before] || '' if opts.key?(:space_before) + @object_nl = opts[:object_nl] || '' if opts.key?(:object_nl) + @array_nl = opts[:array_nl] || '' if opts.key?(:array_nl) + @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan) + @as_json = opts[:as_json].to_proc if opts[:as_json] + @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only) + self.sort_keys = opts[:sort_keys] if opts.key?(:sort_keys) + @depth = opts[:depth] || 0 + @buffer_initial_length ||= opts[:buffer_initial_length] + + @script_safe = if opts.key?(:script_safe) + !!opts[:script_safe] + elsif opts.key?(:escape_slash) + !!opts[:escape_slash] + else + false + end + + if opts.key?(:allow_duplicate_key) + @allow_duplicate_key = !!opts[:allow_duplicate_key] + else + @allow_duplicate_key = nil # nil is deprecation + end + + @strict = !!opts[:strict] if opts.key?(:strict) + + if !opts.key?(:max_nesting) # defaults to 100 + @max_nesting = 100 + elsif opts[:max_nesting] + unless opts[:max_nesting].is_a?(Integer) + raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}" + end + @max_nesting = opts[:max_nesting] + else + @max_nesting = 0 + end + self + end + alias merge configure + + def allow_duplicate_key? # :nodoc: + @allow_duplicate_key + end + + # Returns the configuration instance variables as a hash, that can be + # passed to the configure method. + def to_h + result = {} + instance_variables.each do |iv| + key = iv.to_s[1..-1] + result[key.to_sym] = instance_variable_get(iv) + end + + if result[:allow_duplicate_key].nil? + result.delete(:allow_duplicate_key) + end + + result + end + + alias to_hash to_h + + # Generates a valid JSON document from object +obj+ and + # returns the result. If no valid JSON document can be + # created this method raises a + # GeneratorError exception. + def generate(obj, anIO = nil) + return dup.generate(obj, anIO) if frozen? + + depth = @depth + if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and + !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj) and !@sort_keys + result = generate_json(obj, ''.dup) + else + if @sort_keys + obj = @sort_keys.call(obj) + end + + result = obj.to_json(self) + end + JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new( + "source sequence #{result.inspect} is illegal/malformed utf-8", + obj + ) + if anIO + anIO.write(result) + anIO + else + result + end + ensure + @depth = depth unless frozen? + end + + # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above) + private def generate_json(obj, buf) + case obj + when Hash + buf << '{' + first = true + key_type = nil + obj.each_pair do |k,v| + if first + key_type = k.class + else + if key_type && !@allow_duplicate_key && key_type != k.class + key_type = nil # stop checking + JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?) + end + buf << ',' + end + + key_str = k.to_s + if key_str.class == String + fast_serialize_string(key_str, buf) + elsif key_str.is_a?(String) + generate_json(key_str, buf) + else + raise TypeError, "#{k.class}#to_s returns an instance of #{key_str.class}, expected a String" + end + + buf << ':' + generate_json(v, buf) + first = false + end + buf << '}' + when Array + buf << '[' + first = true + obj.each do |e| + buf << ',' unless first + generate_json(e, buf) + first = false + end + buf << ']' + when String + if obj.class == String + fast_serialize_string(obj, buf) + else + buf << obj.to_json(self) + end + when Integer + buf << obj.to_s + when Symbol + if @strict + fast_serialize_string(obj.name, buf) + else + buf << obj.to_json(self) + end + else + # Note: Float is handled this way since Float#to_s is slow anyway + buf << obj.to_json(self) + end + end + + # Assumes !@ascii_only, !@script_safe + private def fast_serialize_string(string, buf) # :nodoc: + buf << '"' + unless string.encoding == ::Encoding::UTF_8 + begin + string = string.encode(::Encoding::UTF_8) + rescue Encoding::UndefinedConversionError => error + raise GeneratorError.new(error.message, string) + end + end + raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding? + + if /["\\\x0-\x1f]/.match?(string) + buf << string.gsub(/["\\\x0-\x1f]/, MAP) + else + buf << string + end + buf << '"' + end + + # Return the value returned by method +name+. + def [](name) + ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0") + + if respond_to?(name) + __send__(name) + else + instance_variable_get("@#{name}") if + instance_variables.include?("@#{name}".to_sym) # avoid warning + end + end + + def []=(name, value) + ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0") + + if respond_to?(name_writer = "#{name}=") + __send__ name_writer, value + else + instance_variable_set "@#{name}", value + end + end + end + + module GeneratorMethods + module Object + # Converts this object to a string (calling #to_s), converts + # it to a JSON string, and returns the result. This is a fallback, if no + # special method #to_json was defined for some object. + def to_json(state = nil, *) + state = State.from_state(state) if state + if state&.strict? + value = self + if state.strict? && !Generator.native_type?(value) + if state.as_json + value = state.as_json.call(value, false) + unless Generator.native_type?(value) + raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value) + end + value.to_json(state) + else + raise GeneratorError.new("#{value.class} not allowed in JSON", value) + end + end + else + to_s.to_json + end + end + end + + module Hash + # Returns a JSON string containing a JSON object, that is unparsed from + # this Hash instance. + # _state_ is a JSON::State object, that can also be used to configure the + # produced JSON string output further. + # _depth_ is used to find out nesting depth, to indent accordingly. + def to_json(state = nil, *) + state = State.from_state(state) + depth = state.depth + state.check_max_nesting + json_transform(state) + ensure + state.depth = depth + end + + private + + def json_transform(state) + depth = state.depth += 1 + + if empty? + state.depth -= 1 + return +'{}' + end + + delim = ",#{state.object_nl}" + result = "{#{state.object_nl}" + first = true + key_type = nil + indent = !state.object_nl.empty? + each { |key, value| + if first + key_type = key.class + else + if key_type && !state.allow_duplicate_key? && key_type != key.class + key_type = nil # stop checking + JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false) + end + result << delim + end + result << state.indent * depth if indent + + if state.strict? + if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key)) + key = state.as_json.call(key, true) + end + + unless Generator.native_key?(key) + raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key) + end + + unless Generator.valid_encoding?(key) + raise GeneratorError.new("source sequence is illegal/malformed utf-8", key) + end + end + + key_str = key.to_s + if key_str.is_a?(String) + key_json = key_str.to_json(state) + else + raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String" + end + + result = "#{result}#{key_json}#{state.space_before}:#{state.space}" + if state.strict? && !Generator.native_type?(value) + if state.as_json + value = state.as_json.call(value, false) + unless Generator.native_type?(value) + raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value) + end + result << value.to_json(state) + state.depth = depth + else + raise GeneratorError.new("#{value.class} not allowed in JSON", value) + end + elsif value.respond_to?(:to_json) + result << value.to_json(state) + state.depth = depth + else + result << %{"#{String(value)}"} + end + first = false + } + depth -= 1 + unless first + result << state.object_nl + result << state.indent * depth if indent + end + result << '}' + result + end + end + + module Array + # Returns a JSON string containing a JSON array, that is unparsed from + # this Array instance. + # _state_ is a JSON::State object, that can also be used to configure the + # produced JSON string output further. + def to_json(state = nil, *) + state = State.from_state(state) + depth = state.depth + state.check_max_nesting + json_transform(state) + ensure + state.depth = depth + end + + private + + def json_transform(state) + depth = state.depth += 1 + + if empty? + state.depth -= 1 + return +'[]' + end + + result = '['.dup + if state.array_nl.empty? + delim = "," + else + result << state.array_nl + delim = ",#{state.array_nl}" + end + + first = true + indent = !state.array_nl.empty? + each { |value| + result << delim unless first + result << state.indent * depth if indent + if state.strict? && !Generator.native_type?(value) + if state.as_json + value = state.as_json.call(value, false) + unless Generator.native_type?(value) + raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value) + end + result << value.to_json(state) + else + raise GeneratorError.new("#{value.class} not allowed in JSON", value) + end + elsif value.respond_to?(:to_json) + result << value.to_json(state) + state.depth = depth + else + result << %{"#{String(value)}"} + end + first = false + } + depth -= 1 + result << state.array_nl + result << state.indent * depth if indent + result << ']' + end + end + + module Integer + # Returns a JSON string representation for this Integer number. + def to_json(*) to_s end + end + + module Float + # Returns a JSON string representation for this Float number. + def to_json(state = nil, *args) + state = State.from_state(state) + if infinite? || nan? + if state.allow_nan? + to_s + elsif state.strict? && state.as_json + casted_value = state.as_json.call(self, false) + + if casted_value.equal?(self) + raise GeneratorError.new("#{self} not allowed in JSON", self) + end + unless Generator.native_type?(casted_value) + raise GeneratorError.new("#{casted_value.class} returned by #{state.as_json} not allowed in JSON", casted_value) + end + + state.check_max_nesting + state.depth += 1 + result = casted_value.to_json(state, *args) + state.depth -= 1 + result + else + raise GeneratorError.new("#{self} not allowed in JSON", self) + end + else + to_s + end + end + end + + module Symbol + def to_json(state = nil, *args) + state = State.from_state(state) + if state.strict? + name.to_json(state, *args) + else + super + end + end + end + + module String + # This string should be encoded with UTF-8 A call to this method + # returns a JSON string encoded with UTF16 big endian characters as + # \u????. + def to_json(state = nil, *args) + state = State.from_state(state) + string = self + + if state.strict? && state.as_json + unless Generator.valid_encoding?(string) + string = state.as_json.call(string, false) + unless string.is_a?(::String) + return string.to_json(state, *args) + end + end + end + + if string.encoding == ::Encoding::UTF_8 + unless string.valid_encoding? + raise GeneratorError.new("source sequence is illegal/malformed utf-8", self) + end + else + string = string.encode(::Encoding::UTF_8) + end + + if state.ascii_only? + %("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}") + else + %("#{JSON::TruffleRuby::Generator.utf8_to_json(string, state.script_safe)}") + end + rescue Encoding::UndefinedConversionError => error + raise ::JSON::GeneratorError.new(error.message, self) + end + end + + module TrueClass + # Returns a JSON string for true: 'true'. + def to_json(*) +'true' end + end + + module FalseClass + # Returns a JSON string for false: 'false'. + def to_json(*) +'false' end + end + + module NilClass + # Returns a JSON string for nil: 'null'. + def to_json(*) +'null' end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/version.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/version.rb new file mode 100644 index 0000000..e8483db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.21.1/lib/json/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module JSON + VERSION = '2.21.1' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/AUTHORS b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/AUTHORS new file mode 100644 index 0000000..0583596 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/AUTHORS @@ -0,0 +1 @@ +The author of kramdown is Thomas Leitner . diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/CONTRIBUTERS b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/CONTRIBUTERS new file mode 100644 index 0000000..fa84260 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/CONTRIBUTERS @@ -0,0 +1,93 @@ + Count Name +======= ==== + 992 Thomas Leitner + 18 Ashwin Maroli + 7 Christian Cornelssen + 6 Gioele Barabucci + 5 Gleb Mazovetskiy + 4 Ted Pak + 4 Shuanglei Tao + 4 Dan Allen + 4 Arne Brasseur + 3 gettalong + 3 Henning Perl + 3 Carsten Bormann + 3 Brandur + 3 Ben Armston + 3 Ashwin Maroli + 3 Alex Marandon + 2 Tom Thorogood + 2 Parker Moore + 2 Nathanael Jones + 2 Max Meyer + 2 Jo Hund + 2 Bryce Willey + 2 Bran + 1 winniehell + 1 utenmiki + 1 tomykaira + 1 tom93 + 1 timcraft + 1 scherr + 1 myqlarson + 1 milo.simpson + 1 l3kn + 1 aschmitz <29508+aschmitz@users.noreply.github.com> + 1 William + 1 Virgil Ierubino <30758921+Convincible@users.noreply.github.com> + 1 Uwe Kubosch + 1 Trevor Wennblom + 1 Tobin Yehle + 1 Tim Blair + 1 Tim Besard + 1 Tim Bates + 1 Sun Yaozhu + 1 Stephen Crosby + 1 Stephen + 1 Stan Hu + 1 Simon Lydell + 1 Simon Coffey + 1 Shusaku NAKAZATO + 1 Sebastian Boehm + 1 Postmodern + 1 Pete Michaud + 1 Paul McMahon + 1 Paul <2528280+psfrolov@users.noreply.github.com> + 1 Noah Doersing + 1 Michal Till + 1 Maxime Kjaer + 1 Matt Hickford + 1 Martyn Chamberlin + 1 Marek Tuchowski + 1 Marcus Stollsteimer + 1 Luca Barbato + 1 Kir Kolyshkin + 1 Jun Aruga + 1 Jonathan Hooper + 1 John Haugeland + 1 John Croisant + 1 Joe Fiorini + 1 Jens Kraemer + 1 Jay Stramel + 1 Hirofumi Wakasugi + 1 Hector Correa + 1 Florian Klampfer + 1 Floreal Morandat florealm@gmail.com + 1 Fangyi Zhou + 1 Diego Galeota + 1 David Rodríguez + 1 Daniel Bair + 1 Damien Pollet + 1 Cédric Boutillier + 1 Christopher Jefferson + 1 Christian Boos + 1 Bob Lail + 1 Ashesh Kumar Singh + 1 Ashe Connor + 1 Antoine Cotten + 1 Andrew + 1 Alpha Chen + 1 Alexey Vasiliev + 1 Alex Tomlins + 1 Alex Taylor + 1 284km diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/COPYING b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/COPYING new file mode 100644 index 0000000..1c29282 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/COPYING @@ -0,0 +1,30 @@ +kramdown - fast, pure-Ruby Markdown-superset converter +Copyright (C) 2009-2013 Thomas Leitner + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Some test cases and the benchmark files are based on test cases from +the MDTest test suite: + + MDTest + Copyright (c) 2007 Michel Fortin + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/README.md b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/README.md new file mode 100644 index 0000000..981c004 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/README.md @@ -0,0 +1,77 @@ +# kramdown + +## Readme first! + +kramdown was originally licensed under the GPL until the 1.0.0 release. However, due to the many +requests it is now released under the MIT license and therefore can easily be used in commercial +projects, too. + +However, if you use kramdown in a commercial setting, please consider **contributing back any +changes** for the benefit of the community and/or [**becoming a +sponsor**](https://github.com/sponsors/gettalong/) or [**a +patron**](https://www.patreon.com/gettalong) - thanks! + +Sponsors: + +* **GROSSWEBER** provides software + development consulting and training services. + + +## Introduction + +kramdown is a fast, pure Ruby Markdown superset converter, using a strict syntax definition and +supporting several common extensions. + +The syntax definition for the kramdown syntax can be found in **doc/syntax.page** (or online at +) and a quick reference is available in +**doc/quickref.page** or online at . + +The kramdown library is mainly written to support the kramdown-to-HTML conversion chain. However, +due to its flexibility (by creating an internal AST) it supports other input and output formats as +well. Here is a list of the supported formats: + +* input formats: kramdown (a Markdown superset), Markdown, GFM, HTML +* output formats: HTML, kramdown, LaTeX (and therefore PDF), PDF via Prawn + +All the documentation on the available input and output formats is available in the **doc/** +directory and online at . + +Starting from version 1.0.0 kramdown is using a versioning scheme with major, minor and patch parts +in the version number where the major number changes on backwards-incompatible changes, the minor +number on the introduction of new features and the patch number on everything else. + +For information about changes between versions, have a look at + or the commit history! + + +## Usage + +kramdown has a very simple API, so using kramdown is as easy as + +```ruby +require 'kramdown' + +Kramdown::Document.new(text).to_html +``` + +For detailed information have a look at the API documentation of the `Kramdown::Document` class. + +The full API documentation is available at , other sites with an +API documentation for kramdown probably don't provide the complete documentation! + +There are also some third-party libraries that extend the functionality of kramdown -- see the +kramdown Wiki at . + + +## Development + +Just clone the git repository as described in **doc/installation.page** and you are good to go. You +probably want to install `rake` so that you can use the provided rake tasks. + +If you want to run the tests, the development dependencies are needed as well as some additional +programs like `tidy` and `latex`. See the `.travis.yml` file for more information. + + +## License + +MIT - see the **COPYING** file. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/VERSION b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/VERSION new file mode 100644 index 0000000..f225a78 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/VERSION @@ -0,0 +1 @@ +2.5.2 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/bin/kramdown b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/bin/kramdown new file mode 100755 index 0000000..6aeb9a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/bin/kramdown @@ -0,0 +1,135 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2019 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'optparse' +require 'rbconfig' +require 'yaml' +require 'kramdown' + +def add_kramdown_options(opts, parsed_options, banner: [], ignore: []) + banner_shown = false + defined_options = [] + Kramdown::Options.definitions.sort.each do |n, definition| + next if ignore.include?(n) + + unless banner_shown + opts.separator("") + banner.each {|part| opts.separator(part) } + opts.separator("") + banner_shown = true + end + + defined_options << n + no = n.to_s.tr('_', '-') + if definition.type == Kramdown::Options::Boolean + opts.on("--[no-]#{no}") {|v| parsed_options[n] = Kramdown::Options.parse(n, v) } + else + type = definition.type + type = String if type == Symbol || type == Object + opts.on("--#{no} ARG", type) {|v| parsed_options[n] = Kramdown::Options.parse(n, v) } + end + + definition.desc.split("\n").each do |line| + opts.separator opts.summary_indent + ' ' * 6 + line + end + opts.separator '' + end + defined_options +end + +config_file = nil +begin + config_dir = case RbConfig::CONFIG['host_os'] + when /bccwin|cygwin|djgpp|mingw|mswin|wince/i + File.expand_path((ENV['HOME'] || ENV['USERPROFILE'] || "~") + "/AppData/Local") + when /darwin|mac os/ + File.expand_path("~/Library/Preferences/") + else + File.expand_path(ENV['XDG_CONFIG_HOME'] || '~/.config') + end + config_file = File.join(config_dir, "kramdownrc") +rescue StandardError +end + +options = {} +format = ['html'] + +defined_options = [] +OptionParser.new do |opts| + opts.banner = "Usage: kramdown [options] [FILE FILE ...]" + opts.summary_indent = ' ' * 4 + + opts.separator "" + opts.separator "Command line options:" + opts.separator "" + + opts.on("-i", "--input ARG", "Specify the input format: kramdown (default), " \ + "html, or markdown") {|v| options[:input] = v } + opts.on("-o", "--output ARG", Array, "Specify one or more output formats separated by commas: " \ + "html (default),", "kramdown, latex, man or remove_html_tags") {|v| format = v } + opts.on("-x", "--extension EXT", Array, "Load one or more extensions (without the 'kramdown-' " \ + "prefix) separated", "by commas (e.g. parser-gfm,syntax-coderay)", + "Note: Use this option before other options!") do |exts| + exts.each do |ext| + require "kramdown-#{ext}" + new_options = add_kramdown_options(opts, options, banner: ["#{ext} options:"], + ignore: defined_options) + defined_options.concat(new_options) + rescue LoadError + $stderr.puts "Couldn't load extension #{ext}, ignoring" + end + end + opts.separator "" + opts.on("--no-config-file", "Do not read any configuration file. Default behavior is to check " \ + "for a", "configuration file and read it if it exists.") { config_file = nil } + opts.on("--config-file FILE", "Specify the name of a configuration file with kramdown options " \ + "in YAML", "format, e.g. \"auto_id_prefix: ARG\" instead of \"--auto-id-prefix ARG\"", + "and \"auto_ids: false\" instead of \"--no-auto-ids\".", + "Default: #{config_file}") {|v| config_file = v } + opts.separator "" + opts.on("-v", "--version", "Show the version of kramdown") do + puts Kramdown::VERSION + exit + end + opts.on("-h", "--help", "Show the help") do + puts opts.summarize(+'', 5, 72) + exit + end + + new_options = add_kramdown_options(opts, options, banner: ["kramdown options:"]) + defined_options.concat(new_options) +end.parse! + +begin + if config_file && File.exist?(config_file) + config_file_options = + if YAML.method(:safe_load).parameters.include?(%i[key permitted_classes]) + YAML.safe_load(File.read(config_file), permitted_classes: [Symbol]) + else # compatibility with Psych < 3.1.0 + YAML.safe_load(File.read(config_file), [Symbol]) + end + case config_file_options + when nil # empty configuration file except perhaps YAML header and comments + # Nothing to do + when Hash + options = config_file_options.merge(options) + else + raise Kramdown::Error, "No YAML map in configuration file \"#{config_file}\"" + end + end + doc = Kramdown::Document.new(ARGF.read, options) + result = '' + format.each {|f| result = doc.send("to_#{f}") } + puts result + doc.warnings.each {|warn| $stderr.puts "Warning: #{warn}" } +rescue Kramdown::Error => e + $stderr.puts "Error: #{e.message}" + exit(1) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.html new file mode 100644 index 0000000..731d0ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.html @@ -0,0 +1,22 @@ + + + + <% if @converter.root.options[:encoding] %> + + <% end %> +<% +extend ::Kramdown::Utils::Html +title = '' +h = @converter.root.children.find {|c| c.type == :header} +if h + collector = lambda {|c| c.children.collect {|cc| cc.type == :text ? escape_html(cc.value, :text) : collector.call(cc)}.join('')} + title = collector.call(h) +end +%> + <%= title %> + + + + <%= @body %> + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.latex new file mode 100644 index 0000000..acdf346 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/data/kramdown/document.latex @@ -0,0 +1,50 @@ +<% +encmap = { + 'UTF-8' => 'utf8x', + 'US-ASCII' => 'ascii', + 'ISO-8859-1' => 'latin1', + 'ISO-8859-2' => 'latin2', + 'ISO-8859-3' => 'latin3', + 'ISO-8859-4' => 'latin4', + 'ISO-8859-5' => 'latin5', + 'ISO-8859-9' => 'latin9', + 'ISO-8859-10' => 'latin10', + 'CP850' => 'cp850', + 'CP852' => 'cp852', + 'CP858' => 'cp858', + 'CP437' => 'cp437', + 'CP865' => 'cp865', + 'CP1250' => 'cp120', + 'CP1252' => 'cp1252', + 'CP1257' => 'cp1257' +} +%> +\documentclass{scrartcl} +<% if RUBY_VERSION >= '1.9' %> +\usepackage[<%= encmap[@body.encoding.name] %>]{inputenc} +<% else %> +\usepackage[mathletters]{ucs} +\usepackage[utf8x]{inputenc} +<% end %> +\usepackage[T1]{fontenc} +\usepackage{listings} +<% @converter.data[:packages].each {|pkg| %>\usepackage{<%= pkg %>} +<% } %> +\usepackage{hyperref} + +<% if @converter.data[:packages].include?('fancyvrb') %> +\VerbatimFootnotes +<% end %> + +<% if @converter.data[:packages].include?('acronym') %> +<% @converter.root.options[:abbrev_defs].each_pair do |k,v| %>\acrodef{<%= @converter.normalize_abbreviation_key(k) %>}[<%= k %>]{<%= @converter.escape(v) %>} +<% end %> +<% end %> + +\setcounter{footnote}{<%= @converter.options[:footnote_nr] - 1 %>} + +\hypersetup{colorlinks=true,urlcolor=blue} + +\begin{document} +<%= @body %> +\end{document} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown.rb new file mode 100644 index 0000000..3f25463 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown.rb @@ -0,0 +1,10 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/document' diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter.rb new file mode 100644 index 0000000..25cf22c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter.rb @@ -0,0 +1,68 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/utils' + +module Kramdown + + # This module contains all available converters, i.e. classes that take a root Element and convert + # it to a specific output format. The result is normally a string. For example, the + # Converter::Html module converts an element tree into valid HTML. + # + # Converters use the Base class for common functionality (like applying a template to the output) + # \- see its API documentation for how to create a custom converter class. + module Converter + + autoload :Base, 'kramdown/converter/base' + autoload :Html, 'kramdown/converter/html' + autoload :Latex, 'kramdown/converter/latex' + autoload :Kramdown, 'kramdown/converter/kramdown' + autoload :Toc, 'kramdown/converter/toc' + autoload :RemoveHtmlTags, 'kramdown/converter/remove_html_tags' + autoload :HashAST, 'kramdown/converter/hash_ast' + autoload :HashAst, 'kramdown/converter/hash_ast' + autoload :Man, 'kramdown/converter/man' + + extend ::Kramdown::Utils::Configurable + + configurable(:syntax_highlighter) + + ['Minted', "Rouge"].each do |klass_name| + kn_down = klass_name.downcase.intern + add_syntax_highlighter(kn_down) do |converter, text, lang, type, opts| + require "kramdown/converter/syntax_highlighter/#{kn_down}" + klass = ::Kramdown::Utils.deep_const_get("::Kramdown::Converter::SyntaxHighlighter::#{klass_name}") + if !klass.const_defined?(:AVAILABLE) || klass::AVAILABLE + add_syntax_highlighter(kn_down, klass) + else + add_syntax_highlighter(kn_down) { nil } + end + syntax_highlighter(kn_down).call(converter, text, lang, type, opts) + end + end + + configurable(:math_engine) + + ["Mathjax"].each do |klass_name| + kn_down = klass_name.downcase.intern + add_math_engine(kn_down) do |converter, el, opts| + require "kramdown/converter/math_engine/#{kn_down}" + klass = ::Kramdown::Utils.deep_const_get("::Kramdown::Converter::MathEngine::#{klass_name}") + if !klass.const_defined?(:AVAILABLE) || klass::AVAILABLE + add_math_engine(kn_down, klass) + else + add_math_engine(kn_down) { nil } + end + math_engine(kn_down).call(converter, el, opts) + end + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/base.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/base.rb new file mode 100644 index 0000000..8809782 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/base.rb @@ -0,0 +1,257 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'erb' +require 'kramdown/utils' +require 'kramdown/document' + +module Kramdown + + module Converter + + # == \Base class for converters + # + # This class serves as base class for all converters. It provides methods that can/should be + # used by all converters (like #generate_id) as well as common functionality that is + # automatically applied to the result (for example, embedding the output into a template). + # + # A converter object is used as a throw-away object, i.e. it is only used for storing the needed + # state information during conversion. Therefore one can't instantiate a converter object + # directly but only use the Base::convert method. + # + # == Implementing a converter + # + # Implementing a new converter is rather easy: just derive a new class from this class and put + # it in the Kramdown::Converter module (the latter is only needed if auto-detection should work + # properly). Then you need to implement the #convert method which has to contain the conversion + # code for converting an element and has to return the conversion result. + # + # The actual transformation of the document tree can be done in any way. However, writing one + # method per element type is a straight forward way to do it - this is how the Html and Latex + # converters do the transformation. + # + # Have a look at the Base::convert method for additional information! + class Base + + # Can be used by a converter for storing arbitrary information during the conversion process. + attr_reader :data + + # The hash with the conversion options. + attr_reader :options + + # The root element that is converted. + attr_reader :root + + # The warnings array. + attr_reader :warnings + + # Initialize the converter with the given +root+ element and +options+ hash. + def initialize(root, options) + @options = options + @root = root + @data = {} + @warnings = [] + end + private_class_method(:new, :allocate) + + # Returns whether the template should be applied before the conversion of the tree. + # + # Defaults to false. + def apply_template_before? + false + end + + # Returns whether the template should be applied after the conversion of the tree. + # + # Defaults to true. + def apply_template_after? + true + end + + # Convert the element tree +tree+ and return the resulting conversion object (normally a + # string) and an array with warning messages. The parameter +options+ specifies the conversion + # options that should be used. + # + # Initializes a new instance of the calling class and then calls the #convert method with + # +tree+ as parameter. + # + # If the +template+ option is specified and non-empty, the template is evaluate with ERB + # before and/or after the tree conversion depending on the result of #apply_template_before? + # and #apply_template_after?. If the template is evaluated before, an empty string is used for + # the body; if evaluated after, the result is used as body. See ::apply_template. + # + # The template resolution is done in the following way (for the converter ConverterName): + # + # 1. Look in the current working directory for the template. + # + # 2. Append +.converter_name+ (e.g. +.html+) to the template name and look for the resulting + # file in the current working directory (the form +.convertername+ is deprecated). + # + # 3. Append +.converter_name+ to the template name and look for it in the kramdown data + # directory (the form +.convertername+ is deprecated). + # + # 4. Check if the template name starts with 'string://' and if so, strip this prefix away and + # use the rest as template. + def self.convert(tree, options = {}) + converter = new(tree, ::Kramdown::Options.merge(options.merge(tree.options[:options] || {}))) + + if !converter.options[:template].empty? && converter.apply_template_before? + apply_template(converter, '') + end + result = converter.convert(tree) + if result.respond_to?(:encode!) && result.encoding != Encoding::BINARY + result.encode!(tree.options[:encoding] || + (raise ::Kramdown::Error, "Missing encoding option on root element")) + end + if !converter.options[:template].empty? && converter.apply_template_after? + result = apply_template(converter, result) + end + + [result, converter.warnings] + end + + # Convert the element +el+ and return the resulting object. + # + # This is the only method that has to be implemented by sub-classes! + def convert(_el) + raise NotImplementedError + end + + # Apply the +template+ using +body+ as the body string. + # + # The template is evaluated using ERB and the body is available in the @body instance variable + # and the converter object in the @converter instance variable. + def self.apply_template(converter, body) # :nodoc: + erb = ERB.new(get_template(converter.options[:template])) + obj = Object.new + obj.instance_variable_set(:@converter, converter) + obj.instance_variable_set(:@body, body) + erb.result(obj.instance_eval { binding }) + end + + # Return the template specified by +template+. + def self.get_template(template) # :nodoc: + format_ext = '.' + ::Kramdown::Utils.snake_case(name.split("::").last) + shipped = File.join(::Kramdown.data_dir, template + format_ext) + if File.exist?(template) + File.read(template) + elsif File.exist?(template + format_ext) + File.read(template + format_ext) + elsif File.exist?(shipped) + File.read(shipped) + elsif template.start_with?('string://') + template.delete_prefix("string://") + else + raise "The specified template file #{template} does not exist" + end + end + + # Add the given warning +text+ to the warning array. + def warning(text) + @warnings << text + end + + # Return +true+ if the header element +el+ should be used for the table of contents (as + # specified by the +toc_levels+ option). + def in_toc?(el) + @options[:toc_levels].include?(el.options[:level]) && (el.attr['class'] || '') !~ /\bno_toc\b/ + end + + # Return the output header level given a level. + # + # Uses the +header_offset+ option for adjusting the header level. + def output_header_level(level) + [[level + @options[:header_offset], 6].min, 1].max + end + + # Extract the code block/span language from the attributes. + def extract_code_language(attr) + if attr['class'] && attr['class'] =~ /\blanguage-\S+/ + attr['class'].scan(/\blanguage-(\S+)/).first.first + end + end + + # See #extract_code_language + # + # *Warning*: This version will modify the given attributes if a language is present. + def extract_code_language!(attr) + lang = extract_code_language(attr) + attr['class'] = attr['class'].sub(/\blanguage-\S+/, '').strip if lang + attr.delete('class') if lang && attr['class'].empty? + lang + end + + # Highlight the given +text+ in the language +lang+ with the syntax highlighter configured + # through the option 'syntax_highlighter'. + def highlight_code(text, lang, type, opts = {}) + return nil unless @options[:syntax_highlighter] + + highlighter = ::Kramdown::Converter.syntax_highlighter(@options[:syntax_highlighter]) + if highlighter + highlighter.call(self, text, lang, type, opts) + else + warning("The configured syntax highlighter #{@options[:syntax_highlighter]} is not available.") + nil + end + end + + # Format the given math element with the math engine configured through the option + # 'math_engine'. + def format_math(el, opts = {}) + return nil unless @options[:math_engine] + + engine = ::Kramdown::Converter.math_engine(@options[:math_engine]) + if engine + engine.call(self, el, opts) + else + warning("The configured math engine #{@options[:math_engine]} is not available.") + nil + end + end + + # Generate an unique alpha-numeric ID from the the string +str+ for use as a header ID. + # + # Uses the option +auto_id_prefix+: the value of this option is prepended to every generated + # ID. + def generate_id(str) + str = ::Kramdown::Utils::Unidecoder.decode(str) if @options[:transliterated_header_ids] + gen_id = basic_generate_id(str) + gen_id = 'section' if gen_id.empty? + @used_ids ||= {} + if @used_ids.key?(gen_id) + gen_id += "-#{@used_ids[gen_id] += 1}" + else + @used_ids[gen_id] = 0 + end + @options[:auto_id_prefix] + gen_id + end + + # The basic version of the ID generator, without any special provisions for empty or unique + # IDs. + def basic_generate_id(str) + gen_id = str.gsub(/^[^a-zA-Z]+/, '') + gen_id.tr!('^a-zA-Z0-9 -', '') + gen_id.tr!(' ', '-') + gen_id.downcase! + gen_id + end + + SMART_QUOTE_INDICES = {lsquo: 0, rsquo: 1, ldquo: 2, rdquo: 3} # :nodoc: + + # Return the entity that represents the given smart_quote element. + def smart_quote_entity(el) + res = @options[:smart_quotes][SMART_QUOTE_INDICES[el.value]] + ::Kramdown::Utils::Entities.entity(res) + end + + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/hash_ast.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/hash_ast.rb new file mode 100644 index 0000000..f69d388 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/hash_ast.rb @@ -0,0 +1,38 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser' +require 'kramdown/converter' +require 'kramdown/utils' + +module Kramdown + + module Converter + + # Converts a Kramdown::Document to a nested hash for further processing or debug output. + class HashAST < Base + + def convert(el) + hash = {type: el.type} + hash[:attr] = el.attr unless el.attr.empty? + hash[:value] = el.value unless el.value.nil? + hash[:options] = el.options unless el.options.empty? + unless el.children.empty? + hash[:children] = [] + el.children.each {|child| hash[:children] << convert(child) } + end + hash + end + + end + + HashAst = HashAST + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/html.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/html.rb new file mode 100644 index 0000000..783c088 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/html.rb @@ -0,0 +1,545 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser' +require 'kramdown/converter' +require 'kramdown/utils' + +module Kramdown + + module Converter + + # Converts a Kramdown::Document to HTML. + # + # You can customize the HTML converter by sub-classing it and overriding the +convert_NAME+ + # methods. Each such method takes the following parameters: + # + # [+el+] The element of type +NAME+ to be converted. + # + # [+indent+] A number representing the current amount of spaces for indent (only used for + # block-level elements). + # + # The return value of such a method has to be a string containing the element +el+ formatted as + # HTML element. + class Html < Base + + include ::Kramdown::Utils::Html + include ::Kramdown::Parser::Html::Constants + + # The amount of indentation used when nesting HTML tags. + attr_accessor :indent + + # Initialize the HTML converter with the given Kramdown document +doc+. + def initialize(root, options) + super + @footnote_counter = @footnote_start = @options[:footnote_nr] + @footnotes = [] + @footnotes_by_name = {} + @footnote_location = nil + @toc = [] + @toc_code = nil + @indent = 2 + @stack = [] + + # stash string representation of symbol to avoid allocations from multiple interpolations. + @highlighter_class = " highlighter-#{options[:syntax_highlighter]}" + @dispatcher = Hash.new {|h, k| h[k] = :"convert_#{k}" } + end + + # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of + # the element. + def convert(el, indent = -@indent) + send(@dispatcher[el.type], el, indent) + end + + # Return the converted content of the children of +el+ as a string. The parameter +indent+ has + # to be the amount of indentation used for the element +el+. + # + # Pushes +el+ onto the @stack before converting the child elements and pops it from the stack + # afterwards. + def inner(el, indent) + result = +'' + indent += @indent + @stack.push(el) + el.children.each do |inner_el| + result << send(@dispatcher[inner_el.type], inner_el, indent) + end + @stack.pop + result + end + + def convert_blank(_el, _indent) + "\n" + end + + def convert_text(el, _indent) + escaped = escape_html(el.value, :text) + @options[:remove_line_breaks_for_cjk] ? fix_cjk_line_break(escaped) : escaped + end + + def convert_p(el, indent) + if el.options[:transparent] + inner(el, indent) + elsif el.children.size == 1 && el.children.first.type == :img && + el.children.first.options[:ial]&.[](:refs)&.include?('standalone') + convert_standalone_image(el, indent) + else + format_as_block_html("p", el.attr, inner(el, indent), indent) + end + end + + # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img + # element. + def convert_standalone_image(el, indent) + figure_attr = el.attr.dup + image_attr = el.children.first.attr.dup + + if image_attr.key?('class') && !figure_attr.key?('class') + figure_attr['class'] = image_attr.delete('class') + end + if image_attr.key?('id') && !figure_attr.key?('id') + figure_attr['id'] = image_attr.delete('id') + end + + body = "#{' ' * (indent + @indent)}\n" \ + "#{' ' * (indent + @indent)}
#{image_attr['alt']}
\n" + format_as_indented_block_html("figure", figure_attr, body, indent) + end + + def convert_codeblock(el, indent) + attr = el.attr.dup + lang = extract_code_language!(attr) + hl_opts = {} + highlighted_code = highlight_code(el.value, el.options[:lang] || lang, :block, hl_opts) + + if highlighted_code + add_syntax_highlighter_to_class_attr(attr, lang || hl_opts[:default_lang]) + "#{' ' * indent}#{highlighted_code}#{' ' * indent}\n" + else + result = escape_html(el.value) + result.chomp! + if el.attr['class'].to_s =~ /\bshow-whitespaces\b/ + result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m| + suffix = ($1 ? '-l' : ($2 ? '-r' : '')) + m.scan(/./).map do |c| + case c + when "\t" then "\t" + when " " then "" + end + end.join + end + end + code_attr = {} + code_attr['class'] = "language-#{lang}" if lang + "#{' ' * indent}" \ + "#{result}\n\n" + end + end + + def convert_blockquote(el, indent) + format_as_indented_block_html("blockquote", el.attr, inner(el, indent), indent) + end + + def convert_header(el, indent) + attr = el.attr.dup + if @options[:auto_ids] && !attr['id'] + attr['id'] = generate_id(el.options[:raw_text]) + end + + if @options[:header_links] && attr['id'].to_s.length > 0 + link = Element.new(:a, nil, nil) + link.attr['href'] = "##{attr['id']}" + el.children.unshift(link) + end + + @toc << [el.options[:level], attr['id'], el.children] if attr['id'] && in_toc?(el) + level = output_header_level(el.options[:level]) + format_as_block_html("h#{level}", attr, inner(el, indent), indent) + end + + def convert_hr(el, indent) + "#{' ' * indent}\n" + end + + ZERO_TO_ONETWENTYEIGHT = (0..128).to_a.freeze + private_constant :ZERO_TO_ONETWENTYEIGHT + + def convert_ul(el, indent) + if !@toc_code && el.options.dig(:ial, :refs)&.include?('toc') + @toc_code = [el.type, el.attr, ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join] + @toc_code.last + elsif !@footnote_location && el.options.dig(:ial, :refs)&.include?('footnotes') + @footnote_location = ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join + else + format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent) + end + end + alias convert_ol convert_ul + + def convert_dl(el, indent) + format_as_indented_block_html("dl", el.attr, inner(el, indent), indent) + end + + def convert_li(el, indent) + output = ' ' * indent << "<#{el.type}" << html_attributes(el.attr) << ">" + res = inner(el, indent) + if el.children.empty? || (el.children.first.type == :p && el.children.first.options[:transparent]) + output << res << (res.match?(/\n\Z/) ? ' ' * indent : '') + else + output << "\n" << res << ' ' * indent + end + output << "\n" + end + alias convert_dd convert_li + + def convert_dt(el, indent) + attr = el.attr.dup + @stack.last.options[:ial][:refs].each do |ref| + if ref =~ /\Aauto_ids(?:-([\w-]+))?/ + attr['id'] = "#{$1}#{basic_generate_id(el.options[:raw_text])}".lstrip + break + end + end if !attr['id'] && @stack.last.options[:ial] && @stack.last.options[:ial][:refs] + format_as_block_html("dt", attr, inner(el, indent), indent) + end + + def convert_html_element(el, indent) + res = inner(el, indent) + if el.options[:category] == :span + "<#{el.value}#{html_attributes(el.attr)}" + \ + (res.empty? && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) ? " />" : ">#{res}") + else + output = +'' + if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw + output << ' ' * indent + end + output << "<#{el.value}#{html_attributes(el.attr)}" + if el.options[:is_closed] && el.options[:content_model] == :raw + output << " />" + elsif !res.empty? && el.options[:content_model] != :block + output << ">#{res}" + elsif !res.empty? + output << ">\n#{res.chomp}\n" << ' ' * indent << "" + elsif HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) + output << " />" + else + output << ">" + end + output << "\n" if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw + output + end + end + + def convert_xml_comment(el, indent) + if el.options[:category] == :block && + (@stack.last.type != :html_element || @stack.last.options[:content_model] != :raw) + ' ' * indent << el.value << "\n" + else + el.value + end + end + alias convert_xml_pi convert_xml_comment + + def convert_table(el, indent) + format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent) + end + alias convert_thead convert_table + alias convert_tbody convert_table + alias convert_tfoot convert_table + alias convert_tr convert_table + + ENTITY_NBSP = ::Kramdown::Utils::Entities.entity('nbsp') # :nodoc: + + def convert_td(el, indent) + res = inner(el, indent) + type = (@stack[-2].type == :thead ? :th : :td) + attr = el.attr + alignment = @stack[-3].options[:alignment][@stack.last.children.index(el)] + if alignment != :default + attr = el.attr.dup + attr['style'] = (attr.key?('style') ? "#{attr['style']}; " : '') + "text-align: #{alignment}" + end + format_as_block_html(type, attr, res.empty? ? entity_to_str(ENTITY_NBSP) : res, indent) + end + + def convert_comment(el, indent) + if el.options[:category] == :block + "#{' ' * indent}\n" + else + "" + end + end + + def convert_br(_el, _indent) + "
" + end + + def convert_a(el, indent) + format_as_span_html("a", el.attr, inner(el, indent)) + end + + def convert_img(el, _indent) + "" + end + + def convert_codespan(el, _indent) + attr = el.attr.dup + lang = extract_code_language(attr) + hl_opts = {} + result = highlight_code(el.value, lang, :span, hl_opts) + if result + add_syntax_highlighter_to_class_attr(attr, lang || hl_opts[:default_lang]) + else + result = escape_html(el.value) + end + + format_as_span_html('code', attr, result) + end + + def convert_footnote(el, _indent) + repeat = '' + name = @options[:footnote_prefix] + el.options[:name] + if (footnote = @footnotes_by_name[name]) + number = footnote[2] + repeat = ":#{footnote[3] += 1}" + else + number = @footnote_counter + @footnote_counter += 1 + @footnotes << [name, el.value, number, 0] + @footnotes_by_name[name] = @footnotes.last + end + formatted_link_text = sprintf(@options[:footnote_link_text], number) + "" \ + "" \ + "#{formatted_link_text}" + end + + def convert_raw(el, _indent) + if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('html') + el.value + (el.options[:category] == :block ? "\n" : '') + else + '' + end + end + + def convert_em(el, indent) + format_as_span_html(el.type, el.attr, inner(el, indent)) + end + alias convert_strong convert_em + + def convert_entity(el, _indent) + entity_to_str(el.value, el.options[:original]) + end + + TYPOGRAPHIC_SYMS = { + mdash: [::Kramdown::Utils::Entities.entity('mdash')], + ndash: [::Kramdown::Utils::Entities.entity('ndash')], + hellip: [::Kramdown::Utils::Entities.entity('hellip')], + laquo_space: [::Kramdown::Utils::Entities.entity('laquo'), + ::Kramdown::Utils::Entities.entity('nbsp')], + raquo_space: [::Kramdown::Utils::Entities.entity('nbsp'), + ::Kramdown::Utils::Entities.entity('raquo')], + laquo: [::Kramdown::Utils::Entities.entity('laquo')], + raquo: [::Kramdown::Utils::Entities.entity('raquo')], + } # :nodoc: + def convert_typographic_sym(el, _indent) + if (result = @options[:typographic_symbols][el.value]) + escape_html(result, :text) + else + TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e) }.join + end + end + + def convert_smart_quote(el, _indent) + entity_to_str(smart_quote_entity(el)) + end + + def convert_math(el, indent) + if (result = format_math(el, indent: indent)) + result + else + attr = el.attr.dup + attr['class'] = "#{attr['class']} kdmath".lstrip + if el.options[:category] == :block + format_as_block_html('div', attr, "$$\n#{el.value}\n$$", indent) + else + format_as_span_html('span', attr, "$#{el.value}$") + end + end + end + + def convert_abbreviation(el, _indent) + title = @root.options[:abbrev_defs][el.value] + attr = @root.options[:abbrev_attr][el.value].dup + attr['title'] = title unless title.empty? + format_as_span_html("abbr", attr, el.value) + end + + def convert_root(el, indent) + result = inner(el, indent) + if @footnote_location + result.sub!(/#{@footnote_location}/, footnote_content.gsub(/\\/, "\\\\\\\\")) + else + result << footnote_content + end + if @toc_code + toc_tree = generate_toc_tree(@toc, @toc_code[0], @toc_code[1] || {}) + text = toc_tree.children.empty? ? '' : convert(toc_tree, 0) + result.sub!(/#{@toc_code.last}/, text.gsub(/\\/, "\\\\\\\\")) + end + result + end + + # Format the given element as span HTML. + def format_as_span_html(name, attr, body) + "<#{name}#{html_attributes(attr)}>#{body}" + end + + # Format the given element as block HTML. + def format_as_block_html(name, attr, body, indent) + "#{' ' * indent}<#{name}#{html_attributes(attr)}>#{body}\n" + end + + # Format the given element as block HTML with a newline after the start tag and indentation + # before the end tag. + def format_as_indented_block_html(name, attr, body, indent) + "#{' ' * indent}<#{name}#{html_attributes(attr)}>\n#{body}#{' ' * indent}\n" + end + + # Add the syntax highlighter name to the 'class' attribute of the given attribute hash. And + # overwrites or add a "language-LANG" part using the +lang+ parameter if +lang+ is not nil. + def add_syntax_highlighter_to_class_attr(attr, lang = nil) + (attr['class'] = (attr['class'] || '') + @highlighter_class).lstrip! + attr['class'].sub!(/\blanguage-\S+|(^)/) { "language-#{lang}#{$1 ? ' ' : ''}" } if lang + end + + # Generate and return an element tree for the table of contents. + def generate_toc_tree(toc, type, attr) + sections = Element.new(type, nil, attr.dup) + sections.attr['id'] ||= 'markdown-toc' + stack = [] + toc.each do |level, id, children| + li = Element.new(:li, nil, nil, level: level) + li.children << Element.new(:p, nil, nil, transparent: true) + a = Element.new(:a, nil) + a.attr['href'] = "##{id}" + a.attr['id'] = "#{sections.attr['id']}-#{id}" + a.children.concat(fix_for_toc_entry(Marshal.load(Marshal.dump(children)))) + li.children.last.children << a + li.children << Element.new(type) + + success = false + until success + if stack.empty? + sections.children << li + stack << li + success = true + elsif stack.last.options[:level] < li.options[:level] + stack.last.children.last.children << li + stack << li + success = true + else + item = stack.pop + item.children.pop if item.children.last.children.empty? + end + end + end + until stack.empty? + item = stack.pop + item.children.pop if item.children.last.children.empty? + end + sections + end + + # Fixes the elements for use in a TOC entry. + def fix_for_toc_entry(elements) + remove_footnotes(elements) + unwrap_links(elements) + elements + end + + # Remove all link elements by unwrapping them. + def unwrap_links(elements) + elements.map! do |c| + unwrap_links(c.children) + c.type == :a ? c.children : c + end.flatten! + end + + # Remove all footnotes from the given elements. + def remove_footnotes(elements) + elements.delete_if do |c| + remove_footnotes(c.children) + c.type == :footnote + end + end + + # Obfuscate the +text+ by using HTML entities. + def obfuscate(text) + result = +'' + text.each_byte do |b| + result << (b > 128 ? b.chr : sprintf("&#%03d;", b)) + end + result.force_encoding(text.encoding) + result + end + + FOOTNOTE_BACKLINK_FMT = "%s%s" + + # Return an HTML ordered list with the footnote content for the used footnotes. + def footnote_content + ol = Element.new(:ol) + ol.attr['start'] = @footnote_start if @footnote_start != 1 + i = 0 + backlink_text = escape_html(@options[:footnote_backlink], :text) + while i < @footnotes.length + name, data, _, repeat = *@footnotes[i] + li = Element.new(:li, nil, 'id' => "fn:#{name}") + li.children = Marshal.load(Marshal.dump(data.children)) + + para = nil + if li.children.last.type == :p || @options[:footnote_backlink_inline] + parent = li + while !parent.children.empty? && ![:p, :header].include?(parent.children.last.type) + parent = parent.children.last + end + para = parent.children.last + insert_space = true + end + + unless para + li.children << (para = Element.new(:p)) + insert_space = false + end + + unless @options[:footnote_backlink].empty? + nbsp = entity_to_str(ENTITY_NBSP) + value = sprintf(FOOTNOTE_BACKLINK_FMT, (insert_space ? nbsp : ''), name, backlink_text) + para.children << Element.new(:raw, value) + (1..repeat).each do |index| + value = sprintf(FOOTNOTE_BACKLINK_FMT, nbsp, "#{name}:#{index}", + "#{backlink_text}#{index + 1}") + para.children << Element.new(:raw, value) + end + end + + ol.children << Element.new(:raw, convert(li, 4)) + i += 1 + end + if ol.children.empty? + '' + else + format_as_indented_block_html('div', {class: "footnotes", role: "doc-endnotes"}, convert(ol, 2), 0) + end + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/kramdown.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/kramdown.rb new file mode 100644 index 0000000..07106de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/kramdown.rb @@ -0,0 +1,458 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/converter' +require 'kramdown/utils' + +module Kramdown + + module Converter + + # Converts an element tree to the kramdown format. + class Kramdown < Base + + # :stopdoc: + + include ::Kramdown::Utils::Html + + def initialize(root, options) + super + @linkrefs = [] + @footnotes = [] + @abbrevs = [] + @stack = [] + @list_indent = @options[:list_indent] + @list_spacing = ' ' * (@list_indent - 2) + end + + def convert(el, opts = {indent: 0}) + res = send("convert_#{el.type}", el, opts) + res = res.dup if res.frozen? + if ![:html_element, :li, :dt, :dd, :td].include?(el.type) && (ial = ial_for_element(el)) + res << ial + res << "\n\n" if el.block? + elsif [:ul, :dl, :ol, :codeblock].include?(el.type) && opts[:next] && + ([el.type, :codeblock].include?(opts[:next].type) || + (opts[:next].type == :blank && opts[:nnext] && + [el.type, :codeblock].include?(opts[:nnext].type))) + res << "^\n\n" + elsif el.block? && + ![:li, :dd, :dt, :td, :th, :tr, :thead, :tbody, :tfoot, :blank].include?(el.type) && + (el.type != :html_element || @stack.last.type != :html_element) && + (el.type != :p || !el.options[:transparent]) && + !([:ul, :dl, :ol].include?(el.type) && @stack.last.type == :li) + res << "\n" + end + res + end + + def inner(el, opts = {indent: 0}) + @stack.push(el) + result = +'' + el.children.each_with_index do |inner_el, index| + options = opts.dup + options[:index] = index + options[:prev] = (index == 0 ? nil : el.children[index - 1]) + options[:pprev] = (index <= 1 ? nil : el.children[index - 2]) + options[:next] = (index == el.children.length - 1 ? nil : el.children[index + 1]) + options[:nnext] = (index >= el.children.length - 2 ? nil : el.children[index + 2]) + result << convert(inner_el, options) + end + @stack.pop + result + end + + def convert_blank(_el, _opts) + "" + end + + ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]{"'|])|^ {0,3}(:)/ + + def convert_text(el, opts) + if opts[:raw_text] || (@stack.last.type == :html_element && @stack.last.options[:content_model] == :raw) + el.value + else + result = el.value.gsub(/\A\n/) do + opts[:prev] && opts[:prev].type == :br ? '' : "\n" + end + result.gsub!(/\s+/, ' ') unless el.options[:cdata] + result.gsub!(ESCAPED_CHAR_RE) do + $1 || !opts[:prev] || opts[:prev].type == :br ? "\\#{$1 || $2}" : $& + end + result + end + end + + def convert_p(el, opts) + w = @options[:line_width] - opts[:indent].to_s.to_i + first, second, *rest = inner(el, opts).strip.gsub(/(.{1,#{w}})( +|$\n?)/, "\\1\n").split(/\n/) + first&.gsub!(/^(?:(#|>)|(\d+)\.(\s)|([+-]\s))/) { $1 || $4 ? "\\#{$1 || $4}" : "#{$2}\\.#{$3}" } + second&.gsub!(/^([=-]+\s*?)$/, "\\\1") + res = [first, second, *rest].compact.join("\n") + "\n" + res.gsub!(/^ {0,3}:/, "\\:") + if el.children.length == 1 && el.children.first.type == :math + res = "\\#{res}" + elsif res.start_with?('\$$') && res.end_with?("\\$$\n") + res.sub!(/^\\\$\$/, '\$\$') + end + res + end + + def convert_codeblock(el, _opts) + el.value.split("\n").map {|l| l.empty? ? " " : " #{l}" }.join("\n") + "\n" + end + + def convert_blockquote(el, opts) + opts[:indent] += 2 + inner(el, opts).chomp.split("\n").map {|l| "> #{l}" }.join("\n") << "\n" + end + + def convert_header(el, opts) + opts[:in_header] = true + res = +'' + res << "#{'#' * output_header_level(el.options[:level])} #{inner(el, opts)}" + res[-1, 1] = "\\#" if res[-1] == '#' + res << " {##{el.attr['id']}}" if el.attr['id'] && !el.attr['id'].strip.empty? + res << "\n" + end + + def convert_hr(_el, _opts) + "* * *\n" + end + + def convert_ul(el, opts) + inner(el, opts).sub(/\n+\Z/, "\n") + end + alias convert_ol convert_ul + alias convert_dl convert_ul + + def convert_li(el, opts) + sym, width = if @stack.last.type == :ul + ['* ' + @list_spacing, el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent] + else + ["#{opts[:index] + 1}.".ljust(4), 4] + end + if (ial = ial_for_element(el)) + sym << ial << " " + end + + opts[:indent] += width + text = inner(el, opts) + newlines = text.scan(/\n*\Z/).first + first, *last = text.split("\n") + last = last.map {|l| " " * width + l }.join("\n") + text = (first.nil? ? "\n" : first + (last.empty? ? "" : "\n") + last + newlines) + if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent] + res = +"#{sym}#{text}" + res << "^\n" if el.children.size == 1 && @stack.last.children.last == el && + (@stack.last.children.any? {|c| !c.children.first || c.children.first.type != :p } || @stack.last.children.size == 1) + res + elsif el.children.first && el.children.first.type == :codeblock + "#{sym}\n #{text}" + else + "#{sym}#{text}" + end + end + + def convert_dd(el, opts) + sym, width = ": " + @list_spacing, (el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent) + if (ial = ial_for_element(el)) + sym << ial << " " + end + + opts[:indent] += width + text = inner(el, opts) + newlines = text.scan(/\n*\Z/).first + first, *last = text.split("\n") + last = last.map {|l| " " * width + l }.join("\n") + text = first.to_s + (last.empty? ? "" : "\n") + last + newlines + text.chomp! if text =~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dd + text << "\n" if text !~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dt + text << "\n" if el.children.empty? + if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent] + "\n#{sym}#{text}" + elsif el.children.first && el.children.first.type == :codeblock + "#{sym}\n #{text}" + else + "#{sym}#{text}" + end + end + + def convert_dt(el, opts) + result = +'' + if (ial = ial_for_element(el)) + result << ial << " " + end + result << inner(el, opts) << "\n" + end + + HTML_TAGS_WITH_BODY = %w[div script iframe textarea th td] + + HTML_ELEMENT_TYPES = [:entity, :text, :html_element].freeze + private_constant :HTML_ELEMENT_TYPES + + def convert_html_element(el, opts) + markdown_attr = el.options[:category] == :block && el.children.any? do |c| + c.type != :html_element && + (c.type != :p || !c.options[:transparent] || + c.children.any? {|t| !HTML_ELEMENT_TYPES.member?(t.type) }) && + c.block? + end + opts[:force_raw_text] = true if %w[script pre code].include?(el.value) + opts[:raw_text] = opts[:force_raw_text] || opts[:block_raw_text] || \ + (el.options[:category] != :span && !markdown_attr) + opts[:block_raw_text] = true if el.options[:category] == :block && opts[:raw_text] + res = inner(el, opts) + if el.options[:category] == :span + "<#{el.value}#{html_attributes(el.attr)}" + \ + (!res.empty? || HTML_TAGS_WITH_BODY.include?(el.value) ? ">#{res}" : " />") + else + output = +'' + attr = el.attr.dup + attr['markdown'] = '1' if markdown_attr + output << "<#{el.value}#{html_attributes(attr)}" + if !res.empty? && el.options[:content_model] != :block + output << ">#{res}" + elsif !res.empty? + output << ">\n#{res}" << "" + elsif HTML_TAGS_WITH_BODY.include?(el.value) + output << ">" + else + output << " />" + end + output << "\n" if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw + output + end + end + + def convert_xml_comment(el, _opts) + if el.options[:category] == :block && + (@stack.last.type != :html_element || @stack.last.options[:content_model] != :raw) + el.value + "\n" + else + el.value.dup + end + end + alias convert_xml_pi convert_xml_comment + + def convert_table(el, opts) + opts[:alignment] = el.options[:alignment] + inner(el, opts) + end + + def convert_thead(el, opts) + rows = inner(el, opts) + if opts[:alignment].all?(:default) + "#{rows}|#{'-' * 10}\n" + else + "#{rows}| " + opts[:alignment].map do |a| + case a + when :left then ":-" + when :right then "-:" + when :center then ":-:" + when :default then "-" + end + end.join(' ') << "\n" + end + end + + def convert_tbody(el, opts) + res = +'' + res << inner(el, opts) + res << '|' << '-' * 10 << "\n" if opts[:next] && opts[:next].type == :tbody + res + end + + def convert_tfoot(el, opts) + "|#{'=' * 10}\n#{inner(el, opts)}" + end + + def convert_tr(el, opts) + "| #{el.children.map {|c| convert(c, opts) }.join(' | ')} |\n" + end + + def convert_td(el, opts) + inner(el, opts) + end + + def convert_comment(el, _opts) + if el.options[:category] == :block + "{::comment}\n#{el.value}\n{:/}\n" + else + "{::comment}#{el.value}{:/}" + end + end + + def convert_br(_el, opts) + opts[:in_header] ? "
" : " \n" + end + + def convert_a(el, opts) + if el.attr['href'].empty? + "[#{inner(el, opts)}]()" + elsif el.attr['href'] =~ /^(?:http|ftp)/ || el.attr['href'].count("()") > 0 + index = if (link_el = @linkrefs.find {|c| c.attr['href'] == el.attr['href'] }) + @linkrefs.index(link_el) + 1 + else + @linkrefs << el + @linkrefs.size + end + "[#{inner(el, opts)}][#{index}]" + else + title = parse_title(el.attr['title']) + "[#{inner(el, opts)}](#{el.attr['href']}#{title})" + end + end + + def convert_img(el, _opts) + alt_text = el.attr['alt'].to_s.gsub(ESCAPED_CHAR_RE) { $1 ? "\\#{$1}" : $2 } + src = el.attr['src'].to_s + if src.empty? + "![#{alt_text}]()" + else + title = parse_title(el.attr['title']) + link = if src.count("()") > 0 + "<#{src}>" + else + src + end + "![#{alt_text}](#{link}#{title})" + end + end + + def convert_codespan(el, _opts) + delim = (el.value.scan(/`+/).max || '') + '`' + "#{delim}#{' ' if delim.size > 1}#{el.value}#{' ' if delim.size > 1}#{delim}" + end + + def convert_footnote(el, _opts) + @footnotes << [el.options[:name], el.value] + "[^#{el.options[:name]}]" + end + + def convert_raw(el, _opts) + attr = (el.options[:type] || []).join(' ') + attr = " type=\"#{attr}\"" unless attr.empty? + if @stack.last.type == :html_element + el.value + elsif el.options[:category] == :block + "{::nomarkdown#{attr}}\n#{el.value}\n{:/}\n" + else + "{::nomarkdown#{attr}}#{el.value}{:/}" + end + end + + def convert_em(el, opts) + "*#{inner(el, opts)}*" + + (opts[:next] && [:em, :strong].include?(opts[:next].type) && !ial_for_element(el) ? '{::}' : '') + end + + def convert_strong(el, opts) + "**#{inner(el, opts)}**" + + (opts[:next] && [:em, :strong].include?(opts[:next].type) && !ial_for_element(el) ? '{::}' : '') + end + + def convert_entity(el, _opts) + entity_to_str(el.value, el.options[:original]) + end + + TYPOGRAPHIC_SYMS = { + mdash: '---', ndash: '--', hellip: '...', + laquo_space: '<< ', raquo_space: ' >>', + laquo: '<<', raquo: '>>' + } + def convert_typographic_sym(el, _opts) + TYPOGRAPHIC_SYMS[el.value] + end + + def convert_smart_quote(el, _opts) + el.value.to_s.match?(/[rl]dquo/) ? "\"" : "'" + end + + def convert_math(el, _opts) + "$$#{el.value}$$" + (el.options[:category] == :block ? "\n" : '') + end + + def convert_abbreviation(el, _opts) + el.value + end + + def convert_root(el, opts) + res = inner(el, opts) + res << create_link_defs + res << create_footnote_defs + res << create_abbrev_defs + res + end + + def create_link_defs + res = +'' + res << "\n\n" unless @linkrefs.empty? + @linkrefs.each_with_index do |el, i| + title = parse_title(el.attr['title']) + res << "[#{i + 1}]: #{el.attr['href']}#{title}\n" + end + res + end + + def create_footnote_defs + res = +'' + @footnotes.each do |name, data| + res << "[^#{name}]:\n" + res << inner(data).chomp.split("\n").map {|l| " #{l}" }.join("\n") + "\n\n" + end + res + end + + def create_abbrev_defs + return '' unless @root.options[:abbrev_defs] + res = +'' + @root.options[:abbrev_defs].each do |name, text| + res << "*[#{name}]: #{text}\n" + res << ial_for_element(Element.new(:unused, nil, @root.options[:abbrev_attr][name])).to_s << "\n\n" + end + res + end + + # Return the IAL containing the attributes of the element +el+. + def ial_for_element(el) + res = el.attr.map do |k, v| + next if [:img, :a].include?(el.type) && ['href', 'src', 'alt', 'title'].include?(k) + next if el.type == :header && k == 'id' && !v.strip.empty? + if v.nil? + '' + elsif k == 'class' && !v.empty? && !v.index(/[.#]/) + " " + v.split(/\s+/).map {|w| ".#{w}" }.join(" ") + elsif k == 'id' && !v.strip.empty? + " ##{v}" + else + " #{k}=\"#{v}\"" + end + end.compact.join + res = "toc" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) && + el.options.dig(:ial, :refs)&.include?('toc') + res = "footnotes" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) && + el.options.dig(:ial, :refs)&.include?('footnotes') + if el.type == :dl && el.options[:ial] && el.options[:ial][:refs] + auto_ids = el.options[:ial][:refs].select {|ref| ref.start_with?('auto_ids') }.join(" ") + res = auto_ids << (res.strip.empty? ? '' : " #{res}") unless auto_ids.empty? + end + res.strip.empty? ? nil : "{:#{res}}" + end + + def parse_title(attr) + attr.to_s.empty? ? '' : ' "' + attr.gsub(/"/, '"') + '"' + end + + # :startdoc: + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/latex.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/latex.rb new file mode 100644 index 0000000..7f23338 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/latex.rb @@ -0,0 +1,626 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'set' +require 'kramdown/converter' + +module Kramdown + + module Converter + + # Converts an element tree to LaTeX. + # + # This converter uses ideas from other Markdown-to-LaTeX converters like Pandoc and Maruku. + # + # You can customize this converter by sub-classing it and overriding the +convert_NAME+ methods. + # Each such method takes the following parameters: + # + # [+el+] The element of type +NAME+ to be converted. + # + # [+opts+] A hash containing processing options that are passed down from parent elements. The + # key :parent is always set and contains the parent element as value. + # + # The return value of such a method has to be a string containing the element +el+ formatted + # correctly as LaTeX markup. + class Latex < Base + + # Initialize the LaTeX converter with the +root+ element and the conversion +options+. + def initialize(root, options) + super + @data[:packages] = Set.new + end + + # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of + # the element. + def convert(el, opts = {}) + send("convert_#{el.type}", el, opts) + end + + # Return the converted content of the children of +el+ as a string. + def inner(el, opts) + result = +'' + options = opts.dup.merge(parent: el) + el.children.each_with_index do |inner_el, index| + options[:index] = index + options[:result] = result + result << send("convert_#{inner_el.type}", inner_el, options) + end + result + end + + def convert_root(el, opts) + inner(el, opts) + end + + def convert_blank(_el, opts) + opts[:result].match?(/\n\n\Z|\A\Z/) ? "" : "\n" + end + + def convert_text(el, _opts) + escape(el.value) + end + + def convert_p(el, opts) + if el.children.size == 1 && el.children.first.type == :img && + !(img = convert_img(el.children.first, opts)).empty? + convert_standalone_image(el, opts, img) + else + "#{latex_link_target(el)}#{inner(el, opts)}\n\n" + end + end + + # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img + # element. + def convert_standalone_image(el, _opts, img) + attrs = attribute_list(el) + "\\begin{figure}#{attrs}\n\\begin{center}\n#{img}\n\\end{center}\n" \ + "\\caption{#{escape(el.children.first.attr['alt'])}}\n" \ + "#{latex_link_target(el, true)}\n\\end{figure}#{attrs}\n" + end + + def convert_codeblock(el, _opts) + show_whitespace = el.attr['class'].to_s =~ /\bshow-whitespaces\b/ + lang = extract_code_language(el.attr) + + if @options[:syntax_highlighter] == :minted && + (highlighted_code = highlight_code(el.value, lang, :block)) + @data[:packages] << 'minted' + "#{latex_link_target(el)}#{highlighted_code}\n" + elsif show_whitespace || lang + options = [] + options << (show_whitespace ? "showspaces=true,showtabs=true" : "showspaces=false,showtabs=false") + options << "language=#{lang}" if lang + options << "basicstyle=\\ttfamily\\footnotesize,columns=fixed,frame=tlbr" + id = el.attr['id'] + options << "label=#{id}" if id + attrs = attribute_list(el) + "#{latex_link_target(el)}\\begin{lstlisting}[#{options.join(',')}]\n" \ + "#{el.value}\n\\end{lstlisting}#{attrs}\n" + else + "#{latex_link_target(el)}\\begin{verbatim}#{el.value}\\end{verbatim}\n" + end + end + + def convert_blockquote(el, opts) + latex_environment(el.children.size > 1 ? 'quotation' : 'quote', el, inner(el, opts)) + end + + def convert_header(el, opts) + type = @options[:latex_headers][output_header_level(el.options[:level]) - 1] + if ((id = el.attr['id']) || + (@options[:auto_ids] && (id = generate_id(el.options[:raw_text])))) && in_toc?(el) + "\\#{type}{#{inner(el, opts)}}\\hypertarget{#{id}}{}\\label{#{id}}\n\n" + else + "\\#{type}*{#{inner(el, opts)}}\n\n" + end + end + + def convert_hr(el, _opts) + attrs = attribute_list(el) + "#{latex_link_target(el)}\\begin{center}#{attrs}\n\\rule{3in}{0.4pt}\n\\end{center}#{attrs}\n" + end + + def convert_ul(el, opts) + if !@data[:has_toc] && el.options.dig(:ial, :refs)&.include?('toc') + @data[:has_toc] = true + '\tableofcontents' + else + latex_environment(el.type == :ul ? 'itemize' : 'enumerate', el, inner(el, opts)) + end + end + alias convert_ol convert_ul + + def convert_dl(el, opts) + latex_environment('description', el, inner(el, opts)) + end + + def convert_li(el, opts) + "\\item{} #{latex_link_target(el, true)}#{inner(el, opts).sub(/\n+\Z/, '')}\n" + end + + def convert_dt(el, opts) + "\\item[#{inner(el, opts)}] " + end + + def convert_dd(el, opts) + "#{latex_link_target(el)}#{inner(el, opts)}\n\n" + end + + def convert_html_element(el, opts) + case el.value + when 'i', 'em' + "\\emph{#{inner(el, opts)}}" + when 'b', 'strong' + "\\textbf{#{inner(el, opts)}}" + else + warning("Can't convert HTML element") + '' + end + end + + def convert_xml_comment(el, _opts) + el.value.split("\n").map {|l| "% #{l}" }.join("\n") + "\n" + end + + def convert_xml_pi(_el, _opts) + warning("Can't convert XML PI") + '' + end + + TABLE_ALIGNMENT_CHAR = {default: 'l', left: 'l', center: 'c', right: 'r'} # :nodoc: + + def convert_table(el, opts) + @data[:packages] << 'longtable' + align = el.options[:alignment].map {|a| TABLE_ALIGNMENT_CHAR[a] }.join('|') + attrs = attribute_list(el) + "#{latex_link_target(el)}\\begin{longtable}{|#{align}|}#{attrs}\n" \ + "\\hline\n#{inner(el, opts)}\\hline\n\\end{longtable}#{attrs}\n\n" + end + + def convert_thead(el, opts) + "#{inner(el, opts)}\\hline\n" + end + + def convert_tbody(el, opts) + inner(el, opts) + end + + def convert_tfoot(el, opts) + "\\hline \\hline \n#{inner(el, opts)}" + end + + def convert_tr(el, opts) + el.children.map {|c| send("convert_#{c.type}", c, opts) }.join(' & ') << "\\\\\n" + end + + def convert_td(el, opts) + inner(el, opts) + end + + def convert_comment(el, _opts) + el.value.split("\n").map {|l| "% #{l}" }.join("\n") << "\n" + end + + def convert_br(_el, opts) + res = +"\\newline" + res << "\n" if (c = opts[:parent].children[opts[:index] + 1]) && + (c.type != :text || c.value !~ /^\s*\n/) + res + end + + def convert_a(el, opts) + url = el.attr['href'] + if url.start_with?('#') + "\\hyperlink{#{url[1..-1].gsub('%', '\\%')}}{#{inner(el, opts)}}" + else + "\\href{#{url.gsub('%', '\\%')}}{#{inner(el, opts)}}" + end + end + + def convert_img(el, _opts) + line = el.options[:location] + if el.attr['src'].match?(/^(https?|ftps?):\/\//) + warning("Cannot include non-local image#{line ? " (line #{line})" : ''}") + '' + elsif !el.attr['src'].empty? + @data[:packages] << 'graphicx' + "#{latex_link_target(el)}\\includegraphics{#{el.attr['src']}}" + else + warning("Cannot include image with empty path#{line ? " (line #{line})" : ''}") + '' + end + end + + def convert_codespan(el, _opts) + lang = extract_code_language(el.attr) + if @options[:syntax_highlighter] == :minted && + (highlighted_code = highlight_code(el.value, lang, :span)) + @data[:packages] << 'minted' + "#{latex_link_target(el)}#{highlighted_code}" + else + "\\texttt{#{latex_link_target(el)}#{escape(el.value)}}" + end + end + + def convert_footnote(el, opts) + @data[:packages] << 'fancyvrb' + "\\footnote{#{inner(el.value, opts).rstrip}}" + end + + def convert_raw(el, _opts) + if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('latex') + el.value + (el.options[:category] == :block ? "\n" : '') + else + '' + end + end + + def convert_em(el, opts) + "\\emph{#{latex_link_target(el)}#{inner(el, opts)}}" + end + + def convert_strong(el, opts) + "\\textbf{#{latex_link_target(el)}#{inner(el, opts)}}" + end + + # Inspired by Maruku: entity conversion table based on the one from htmltolatex + # (http://sourceforge.net/projects/htmltolatex/), with some small adjustments/additions + ENTITY_CONV_TABLE = { + 913 => ['$A$'], + 914 => ['$B$'], + 915 => ['$\Gamma$'], + 916 => ['$\Delta$'], + 917 => ['$E$'], + 918 => ['$Z$'], + 919 => ['$H$'], + 920 => ['$\Theta$'], + 921 => ['$I$'], + 922 => ['$K$'], + 923 => ['$\Lambda$'], + 924 => ['$M$'], + 925 => ['$N$'], + 926 => ['$\Xi$'], + 927 => ['$O$'], + 928 => ['$\Pi$'], + 929 => ['$P$'], + 931 => ['$\Sigma$'], + 932 => ['$T$'], + 933 => ['$Y$'], + 934 => ['$\Phi$'], + 935 => ['$X$'], + 936 => ['$\Psi$'], + 937 => ['$\Omega$'], + 945 => ['$\alpha$'], + 946 => ['$\beta$'], + 947 => ['$\gamma$'], + 948 => ['$\delta$'], + 949 => ['$\epsilon$'], + 950 => ['$\zeta$'], + 951 => ['$\eta$'], + 952 => ['$\theta$'], + 953 => ['$\iota$'], + 954 => ['$\kappa$'], + 955 => ['$\lambda$'], + 956 => ['$\mu$'], + 957 => ['$\nu$'], + 958 => ['$\xi$'], + 959 => ['$o$'], + 960 => ['$\pi$'], + 961 => ['$\rho$'], + 963 => ['$\sigma$'], + 964 => ['$\tau$'], + 965 => ['$\upsilon$'], + 966 => ['$\phi$'], + 967 => ['$\chi$'], + 968 => ['$\psi$'], + 969 => ['$\omega$'], + 962 => ['$\varsigma$'], + 977 => ['$\vartheta$'], + 982 => ['$\varpi$'], + 8230 => ['\ldots'], + 8242 => ['$\prime$'], + 8254 => ['-'], + 8260 => ['/'], + 8472 => ['$\wp$'], + 8465 => ['$\Im$'], + 8476 => ['$\Re$'], + 8501 => ['$\aleph$'], + 8226 => ['$\bullet$'], + 8482 => ['$^{\rm TM}$'], + 8592 => ['$\leftarrow$'], + 8594 => ['$\rightarrow$'], + 8593 => ['$\uparrow$'], + 8595 => ['$\downarrow$'], + 8596 => ['$\leftrightarrow$'], + 8629 => ['$\hookleftarrow$'], + 8657 => ['$\Uparrow$'], + 8659 => ['$\Downarrow$'], + 8656 => ['$\Leftarrow$'], + 8658 => ['$\Rightarrow$'], + 8660 => ['$\Leftrightarrow$'], + 8704 => ['$\forall$'], + 8706 => ['$\partial$'], + 8707 => ['$\exists$'], + 8709 => ['$\emptyset$'], + 8711 => ['$\nabla$'], + 8712 => ['$\in$'], + 8715 => ['$\ni$'], + 8713 => ['$\notin$'], + 8721 => ['$\sum$'], + 8719 => ['$\prod$'], + 8722 => ['$-$'], + 8727 => ['$\ast$'], + 8730 => ['$\surd$'], + 8733 => ['$\propto$'], + 8734 => ['$\infty$'], + 8736 => ['$\angle$'], + 8743 => ['$\wedge$'], + 8744 => ['$\vee$'], + 8745 => ['$\cap$'], + 8746 => ['$\cup$'], + 8747 => ['$\int$'], + 8756 => ['$\therefore$', 'amssymb'], + 8764 => ['$\sim$'], + 8776 => ['$\approx$'], + 8773 => ['$\cong$'], + 8800 => ['$\neq$'], + 8801 => ['$\equiv$'], + 8804 => ['$\leq$'], + 8805 => ['$\geq$'], + 8834 => ['$\subset$'], + 8835 => ['$\supset$'], + 8838 => ['$\subseteq$'], + 8839 => ['$\supseteq$'], + 8836 => ['$\nsubset$', 'amssymb'], + 8853 => ['$\oplus$'], + 8855 => ['$\otimes$'], + 8869 => ['$\perp$'], + 8901 => ['$\cdot$'], + 8968 => ['$\rceil$'], + 8969 => ['$\lceil$'], + 8970 => ['$\lfloor$'], + 8971 => ['$\rfloor$'], + 9001 => ['$\rangle$'], + 9002 => ['$\langle$'], + 9674 => ['$\lozenge$', 'amssymb'], + 9824 => ['$\spadesuit$'], + 9827 => ['$\clubsuit$'], + 9829 => ['$\heartsuit$'], + 9830 => ['$\diamondsuit$'], + 38 => ['\&'], + 34 => ['"'], + 39 => ['\''], + 169 => ['\copyright'], + 60 => ['\textless'], + 62 => ['\textgreater'], + 338 => ['\OE'], + 339 => ['\oe'], + 352 => ['\v{S}'], + 353 => ['\v{s}'], + 376 => ['\"Y'], + 710 => ['\textasciicircum'], + 732 => ['\textasciitilde'], + 8211 => ['--'], + 8212 => ['---'], + 8216 => ['`'], + 8217 => ['\''], + 8220 => ['``'], + 8221 => ['\'\''], + 8224 => ['\dag'], + 8225 => ['\ddag'], + 8240 => ['\permil', 'wasysym'], + 8364 => ['\euro', 'eurosym'], + 8249 => ['\guilsinglleft'], + 8250 => ['\guilsinglright'], + 8218 => ['\quotesinglbase', 'mathcomp'], + 8222 => ['\quotedblbase', 'mathcomp'], + 402 => ['\textflorin', 'mathcomp'], + 381 => ['\v{Z}'], + 382 => ['\v{z}'], + 160 => ['~'], + 161 => ['\textexclamdown'], + 163 => ['\pounds'], + 164 => ['\currency', 'wasysym'], + 165 => ['\textyen', 'textcomp'], + 166 => ['\brokenvert', 'wasysym'], + 167 => ['\S'], + 171 => ['\guillemotleft'], + 187 => ['\guillemotright'], + 174 => ['\textregistered'], + 170 => ['\textordfeminine'], + 172 => ['$\neg$'], + 173 => ['\-'], + 176 => ['$\degree$', 'mathabx'], + 177 => ['$\pm$'], + 180 => ['\''], + 181 => ['$\mu$'], + 182 => ['\P'], + 183 => ['$\cdot$'], + 186 => ['\textordmasculine'], + 162 => ['\cent', 'wasysym'], + 185 => ['$^1$'], + 178 => ['$^2$'], + 179 => ['$^3$'], + 189 => ['$\frac{1}{2}$'], + 188 => ['$\frac{1}{4}$'], + 190 => ['$\frac{3}{4}'], + 192 => ['\`A'], + 193 => ['\\\'A'], + 194 => ['\^A'], + 195 => ['\~A'], + 196 => ['\"A'], + 197 => ['\AA'], + 198 => ['\AE'], + 199 => ['\cC'], + 200 => ['\`E'], + 201 => ['\\\'E'], + 202 => ['\^E'], + 203 => ['\"E'], + 204 => ['\`I'], + 205 => ['\\\'I'], + 206 => ['\^I'], + 207 => ['\"I'], + 208 => ['$\eth$', 'amssymb'], + 209 => ['\~N'], + 210 => ['\`O'], + 211 => ['\\\'O'], + 212 => ['\^O'], + 213 => ['\~O'], + 214 => ['\"O'], + 215 => ['$\times$'], + 216 => ['\O'], + 217 => ['\`U'], + 218 => ['\\\'U'], + 219 => ['\^U'], + 220 => ['\"U'], + 221 => ['\\\'Y'], + 222 => ['\Thorn', 'wasysym'], + 223 => ['\ss'], + 224 => ['\`a'], + 225 => ['\\\'a'], + 226 => ['\^a'], + 227 => ['\~a'], + 228 => ['\"a'], + 229 => ['\aa'], + 230 => ['\ae'], + 231 => ['\cc'], + 232 => ['\`e'], + 233 => ['\\\'e'], + 234 => ['\^e'], + 235 => ['\"e'], + 236 => ['\`i'], + 237 => ['\\\'i'], + 238 => ['\^i'], + 239 => ['\"i'], + 240 => ['$\eth$'], + 241 => ['\~n'], + 242 => ['\`o'], + 243 => ['\\\'o'], + 244 => ['\^o'], + 245 => ['\~o'], + 246 => ['\"o'], + 247 => ['$\divide$'], + 248 => ['\o'], + 249 => ['\`u'], + 250 => ['\\\'u'], + 251 => ['\^u'], + 252 => ['\"u'], + 253 => ['\\\'y'], + 254 => ['\thorn', 'wasysym'], + 255 => ['\"y'], + 8201 => ['\thinspace'], + 8194 => ['\hskip .5em\relax'], + 8195 => ['\quad'], + } # :nodoc: + ENTITY_CONV_TABLE.each_value {|v| v[0] = "#{v[0]}{}" } + + def entity_to_latex(entity) + text, package = ENTITY_CONV_TABLE[entity.code_point] + if text + @data[:packages] << package if package + text + else + warning("Couldn't find entity with code #{entity.code_point} in substitution table!") + '' + end + end + + def convert_entity(el, _opts) + entity_to_latex(el.value) + end + + TYPOGRAPHIC_SYMS = { + mdash: '---', ndash: '--', hellip: '\ldots{}', + laquo_space: '\guillemotleft{}~', raquo_space: '~\guillemotright{}', + laquo: '\guillemotleft{}', raquo: '\guillemotright{}' + } # :nodoc: + def convert_typographic_sym(el, _opts) + if (result = @options[:typographic_symbols][el.value]) + escape(result) + else + TYPOGRAPHIC_SYMS[el.value] + end + end + + def convert_smart_quote(el, opts) + res = entity_to_latex(smart_quote_entity(el)).chomp('{}') + res << "{}" if ((nel = opts[:parent].children[opts[:index] + 1]) && nel.type == :smart_quote) || res =~ /\w$/ + res + end + + def convert_math(el, _opts) + @data[:packages] += %w[amssymb amsmath amsthm amsfonts] + if el.options[:category] == :block + if el.value.match?(/\A\s*\\begin\{/) + el.value + else + latex_environment('displaymath', el, el.value) + end + else + "$#{el.value}$" + end + end + + def convert_abbreviation(el, _opts) + @data[:packages] += %w[acronym] + "\\ac{#{normalize_abbreviation_key(el.value)}}" + end + + # Normalize the abbreviation key so that it only contains allowed ASCII character + def normalize_abbreviation_key(key) + key.gsub(/\W/) {|m| m.unpack1('H*') } + end + + # Wrap the +text+ inside a LaTeX environment of type +type+. The element +el+ is passed on to + # the method #attribute_list -- the resulting string is appended to both the \\begin and the + # \\end lines of the LaTeX environment for easier post-processing of LaTeX environments. + def latex_environment(type, el, text) + attrs = attribute_list(el) + "\\begin{#{type}}#{latex_link_target(el)}#{attrs}\n#{text.rstrip}\n\\end{#{type}}#{attrs}\n" + end + + # Return a string containing a valid \hypertarget command if the element has an ID defined, or + # +nil+ otherwise. If the parameter +add_label+ is +true+, a \label command will also be used + # additionally to the \hypertarget command. + def latex_link_target(el, add_label = false) + if (id = el.attr['id']) + "\\hypertarget{#{id}}{}#{add_label ? "\\label{#{id}}" : ''}" + else + nil + end + end + + # Return a LaTeX comment containing all attributes as 'key="value"' pairs. + def attribute_list(el) + attrs = el.attr.map {|k, v| v.nil? ? '' : " #{k}=\"#{v}\"" }.compact.sort.join + attrs = " % #{attrs}" unless attrs.empty? + attrs + end + + ESCAPE_MAP = { + "^" => "\\^{}", + "\\" => "\\textbackslash{}", + "~" => "\\ensuremath{\\sim}", + "|" => "\\textbar{}", + "<" => "\\textless{}", + ">" => "\\textgreater{}", + "[" => "{[}", + "]" => "{]}", + }.merge(Hash[*"{}$%&_#".each_char.map {|c| [c, "\\#{c}"] }.flatten]) # :nodoc: + ESCAPE_RE = Regexp.union(*ESCAPE_MAP.collect {|k, _v| k }) # :nodoc: + + # Escape the special LaTeX characters in the string +str+. + def escape(str) + str.gsub(ESCAPE_RE) {|m| ESCAPE_MAP[m] } + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/man.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/man.rb new file mode 100644 index 0000000..dd84540 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/man.rb @@ -0,0 +1,300 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/converter' + +module Kramdown + + module Converter + + # Converts a Kramdown::Document to a manpage in groff format. See man(7), groff_man(7) and + # man-pages(7) for information regarding the output. + class Man < Base + + def convert(el, opts = {indent: 0, result: +''}) # :nodoc: + send("convert_#{el.type}", el, opts) + end + + private + + def inner(el, opts, use = :all) + arr = el.children.reject {|e| e.type == :blank } + arr.each_with_index do |inner_el, index| + next if use == :rest && index == 0 + break if use == :first && index > 0 + options = opts.dup + options[:parent] = el + options[:index] = index + options[:prev] = (index == 0 ? nil : arr[index - 1]) + options[:next] = (index == arr.length - 1 ? nil : arr[index + 1]) + convert(inner_el, options) + end + end + + def convert_root(el, opts) + @title_done = false + opts[:result] = +".\\\" generated by kramdown\n" + inner(el, opts) + opts[:result] + end + + def convert_blank(*) + end + alias convert_hr convert_blank + alias convert_xml_pi convert_blank + + def convert_p(el, opts) + if (opts[:index] != 0 && opts[:prev].type != :header) || + (opts[:parent].type == :blockquote && opts[:index] == 0) + opts[:result] << macro("P") + end + inner(el, opts) + newline(opts[:result]) + end + + def convert_header(el, opts) + return unless opts[:parent].type == :root + case el.options[:level] + when 1 + unless @title_done + @title_done = true + data = el.options[:raw_text].scan(/([^(]+)\s*\((\d\w*)\)(?:\s*-+\s*(.*))?/).first || + el.options[:raw_text].scan(/([^\s]+)\s*(?:-*\s+)?()(.*)/).first + return unless data && data[0] + name = data[0] + section = (data[1].to_s.empty? ? el.attr['data-section'] || '7' : data[1]) + description = (data[2].to_s.empty? ? nil : " - #{data[2]}") + date = el.attr['data-date'] ? quote(el.attr['data-date']) : nil + extra = (el.attr['data-extra'] ? quote(escape(el.attr['data-extra'].to_s)) : nil) + opts[:result] << macro("TH", quote(escape(name.upcase)), quote(section), date, extra) + if description + opts[:result] << macro("SH", "NAME") << escape("#{name}#{description}") << "\n" + end + end + when 2 + opts[:result] << macro("SH", quote(escape(el.options[:raw_text]))) + when 3 + opts[:result] << macro("SS", quote(escape(el.options[:raw_text]))) + else + warning("Header levels greater than three are not supported") + end + end + + def convert_codeblock(el, opts) + opts[:result] << macro("sp") << macro("RS", 4) << macro("EX") + opts[:result] << newline(escape(el.value, true)) + opts[:result] << macro("EE") << macro("RE") + end + + def convert_blockquote(el, opts) + opts[:result] << macro("RS") + inner(el, opts) + opts[:result] << macro("RE") + end + + def convert_ul(el, opts) + compact = (el.attr['class'] =~ /\bcompact\b/) + opts[:result] << macro("sp") << macro("PD", 0) if compact + inner(el, opts) + opts[:result] << macro("PD") if compact + end + alias convert_dl convert_ul + alias convert_ol convert_ul + + def convert_li(el, opts) + sym = (opts[:parent].type == :ul ? '\(bu' : "#{opts[:index] + 1}.") + opts[:result] << macro("IP", sym, 4) + inner(el, opts, :first) + if el.children.size > 1 + opts[:result] << macro("RS") + inner(el, opts, :rest) + opts[:result] << macro("RE") + end + end + + def convert_dt(el, opts) + opts[:result] << macro(opts[:prev] && opts[:prev].type == :dt ? "TQ" : "TP") + inner(el, opts) + opts[:result] << "\n" + end + + def convert_dd(el, opts) + inner(el, opts, :first) + if el.children.size > 1 + opts[:result] << macro("RS") + inner(el, opts, :rest) + opts[:result] << macro("RE") + end + opts[:result] << macro("sp") if opts[:next] && opts[:next].type == :dd + end + + TABLE_CELL_ALIGNMENT = {left: 'l', center: 'c', right: 'r', default: 'l'} + + def convert_table(el, opts) + opts[:alignment] = el.options[:alignment].map {|a| TABLE_CELL_ALIGNMENT[a] } + table_options = ["box"] + table_options << "center" if el.attr['class']&.match?(/\bcenter\b/) + opts[:result] << macro("TS") << "#{table_options.join(' ')} ;\n" + inner(el, opts) + opts[:result] << macro("TE") << macro("sp") + end + + def convert_thead(el, opts) + opts[:result] << opts[:alignment].map {|a| "#{a}b" }.join(' ') << " .\n" + inner(el, opts) + opts[:result] << "=\n" + end + + def convert_tbody(el, opts) + opts[:result] << ".T&\n" if opts[:index] != 0 + opts[:result] << opts[:alignment].join(' ') << " .\n" + inner(el, opts) + opts[:result] << (opts[:next].type == :tfoot ? "=\n" : "_\n") if opts[:next] + end + + def convert_tfoot(el, opts) + inner(el, opts) + end + + def convert_tr(el, opts) + inner(el, opts) + opts[:result] << "\n" + end + + def convert_td(el, opts) + result = opts[:result] + opts[:result] = +'' + inner(el, opts) + if opts[:result].include?("\n") + warning("Table cells using links are not supported") + result << "\t" + else + result << opts[:result] << "\t" + end + end + + def convert_html_element(*) + warning("HTML elements are not supported") + end + + def convert_xml_comment(el, opts) + newline(opts[:result]) << ".\"#{escape(el.value, true).rstrip.gsub(/\n/, "\n.\"")}\n" + end + alias convert_comment convert_xml_comment + + def convert_a(el, opts) + if el.children.size == 1 && el.children[0].type == :text && + el.attr['href'] == el.children[0].value + newline(opts[:result]) << macro("UR", escape(el.attr['href'])) << macro("UE") + elsif el.attr['href'].start_with?('mailto:') + newline(opts[:result]) << macro("MT", escape(el.attr['href'].sub(/^mailto:/, ''))) << + macro("UE") + else + newline(opts[:result]) << macro("UR", escape(el.attr['href'])) + inner(el, opts) + newline(opts[:result]) << macro("UE") + end + end + + def convert_img(_el, _opts) + warning("Images are not supported") + end + + def convert_em(el, opts) + opts[:result] << '\fI' + inner(el, opts) + opts[:result] << '\fP' + end + + def convert_strong(el, opts) + opts[:result] << '\fB' + inner(el, opts) + opts[:result] << '\fP' + end + + def convert_codespan(el, opts) + opts[:result] << "\\fB#{escape(el.value)}\\fP" + end + + def convert_br(_el, opts) + newline(opts[:result]) << macro("br") + end + + def convert_abbreviation(el, opts) + opts[:result] << escape(el.value) + end + + def convert_math(el, opts) + if el.options[:category] == :block + convert_codeblock(el, opts) + else + convert_codespan(el, opts) + end + end + + def convert_footnote(*) + warning("Footnotes are not supported") + end + + def convert_raw(*) + warning("Raw content is not supported") + end + + def convert_text(el, opts) + text = escape(el.value) + text.lstrip! if opts[:result][-1] == "\n" + opts[:result] << text + end + + def convert_entity(el, opts) + opts[:result] << unicode_char(el.value.code_point) + end + + def convert_smart_quote(el, opts) + opts[:result] << unicode_char(::Kramdown::Utils::Entities.entity(el.value.to_s).code_point) + end + + TYPOGRAPHIC_SYMS_MAP = { + mdash: '\(em', ndash: '\(em', hellip: '\.\.\.', + laquo_space: '\[Fo]', raquo_space: '\[Fc]', laquo: '\[Fo]', raquo: '\[Fc]' + } + + def convert_typographic_sym(el, opts) + opts[:result] << TYPOGRAPHIC_SYMS_MAP[el.value] + end + + def macro(name, *args) + ".#{[name, *args].compact.join(' ')}\n" + end + + def newline(text) + text << "\n" unless text[-1] == "\n" + text + end + + def quote(text) + "\"#{text.gsub(/"/, '\\"')}\"" + end + + def escape(text, preserve_whitespace = false) + text = (preserve_whitespace ? text.dup : text.gsub(/\s+/, ' ')) + text.gsub!('\\', "\\e") + text.gsub!(/^\./, '\\\\&.') + text.gsub!(/[.'-]/) {|m| "\\#{m}" } + text + end + + def unicode_char(codepoint) + "\\[u#{codepoint.to_s(16).rjust(4, '0')}]" + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/math_engine/mathjax.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/math_engine/mathjax.rb new file mode 100644 index 0000000..3248e93 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/math_engine/mathjax.rb @@ -0,0 +1,32 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown::Converter::MathEngine + + # Uses the MathJax javascript library for displaying math. + # + # Note that the javascript library itself is not include or linked, this has to be done + # separately. Only the math content is marked up correctly. + module Mathjax + + def self.call(converter, el, opts) + value = converter.escape_html(el.value) + result = el.options[:category] == :block ? "\\[#{value}\\]\n" : "\\(#{value}\\)" + if el.attr.empty? + result + elsif el.options[:category] == :block + converter.format_as_block_html('div', el.attr, result, opts[:indent]) + else + converter.format_as_span_html('span', el.attr, "$#{el.value}$") + end + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/remove_html_tags.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/remove_html_tags.rb new file mode 100644 index 0000000..a7db73e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/remove_html_tags.rb @@ -0,0 +1,58 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/converter' + +module Kramdown + + module Converter + + # Removes all block (and optionally span) level HTML tags from the element tree. + # + # This converter can be used on parsed HTML documents to get an element tree that will only + # contain native kramdown elements. + # + # *Note* that the returned element tree may not be fully conformant (i.e. the content models of + # *some elements may be violated)! + # + # This converter modifies the given tree in-place and returns it. + class RemoveHtmlTags < Base + + def initialize(root, options) + super + @options[:template] = '' + end + + def convert(el) + real_el, el = el, el.value if el.type == :footnote + + children = el.children.dup + index = 0 + while index < children.length + if children[index].type == :xml_pi || + (children[index].type == :html_element && (children[index].value == 'style' || + children[index].value == 'script')) + children[index..index] = [] + elsif children[index].type == :html_element && + ((@options[:remove_block_html_tags] && children[index].options[:category] == :block) || + (@options[:remove_span_html_tags] && children[index].options[:category] == :span)) + children[index..index] = children[index].children + else + convert(children[index]) + index += 1 + end + end + el.children = children + real_el || el + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter.rb new file mode 100644 index 0000000..fd9316d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter.rb @@ -0,0 +1,56 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Converter + + # == Container for Syntax Highlighters + # + # This module serves as container for the syntax highlighters that can be used together with + # kramdown. + # + # A syntax highlighter should not store any data itself but should use the provided converter + # object to do so (See Kramdown::Converter::Base#data). + # + # == Implementing a Syntax Highlighter + # + # Implementing a new syntax highlighter is easy because it is just an object that needs to + # respond to #call. + # + # The method #call needs to take the following arguments: + # + # converter:: This argument contains the converter object that calls the syntax highlighter. It + # can be used, for example, to store data in Kramdown::Converter::Base#data for one + # conversion run. + # + # text:: The raw text that should be highlighted. + # + # lang:: The language that the text should be highlighted for (e.g. ruby, python, ...). + # + # type:: The type of text, either :span for span-level code or :block for a codeblock. + # + # opts:: A Hash with options that may be passed from the converter. + # + # The return value of the method should be the highlighted text, suitable for the given + # converter (e.g. HTML for the HTML converter). + # + # == Special Implementation Details + # + # HTML converter:: If the syntax highlighter is used with an HTML converter, it should return + # :block type text correctly wrapped (i.e. normally inside a pre-tag, but may + # also be a table-tag or just a div-tag) but :span type text *without* a + # code-tag! + # + # Also, a syntax highlighter should store the default highlighting language for + # the invocation in the +opts+ hash under the key :default_lang. + module SyntaxHighlighter + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/minted.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/minted.rb new file mode 100644 index 0000000..21c26ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/minted.rb @@ -0,0 +1,35 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown::Converter::SyntaxHighlighter + + # Uses Minted to highlight code blocks and code spans. + module Minted + + def self.call(converter, text, lang, type, _opts) + opts = converter.options[:syntax_highlighter_opts] + + # Fallback to default language + lang ||= opts[:default_lang] + + options = [] + options << "breaklines" if opts[:wrap] + options << "linenos" if opts[:line_numbers] + options << "frame=#{opts[:frame]}" if opts[:frame] + + if lang && type == :block + "\\begin{minted}[#{options.join(',')}]{#{lang}}\n#{text}\n\\end{minted}" + elsif lang && type == :span + "\\mintinline{#{lang}}{#{text}}" + else + nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/rouge.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/rouge.rb new file mode 100644 index 0000000..a286c4d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/syntax_highlighter/rouge.rb @@ -0,0 +1,85 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown::Converter::SyntaxHighlighter + + # Uses Rouge which is CSS-compatible to Pygments to highlight code blocks and code spans. + module Rouge + + begin + require 'rouge' + + # Highlighting via Rouge is available if this constant is +true+. + AVAILABLE = true + rescue LoadError, SyntaxError + AVAILABLE = false # :nodoc: + end + + def self.call(converter, text, lang, type, call_opts) + opts = options(converter, type) + call_opts[:default_lang] = opts[:default_lang] + return nil unless lang || opts[:default_lang] || opts[:guess_lang] + + lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text) + return nil if opts[:disable] || !lexer || (lexer.tag == "plaintext" && !opts[:guess_lang]) + + opts[:css_class] ||= 'highlight' # For backward compatibility when using Rouge 2.0 + formatter = formatter_class(opts).new(opts) + formatter.format(lexer.lex(text)) + end + + def self.options(converter, type) + prepare_options(converter) + converter.data[:syntax_highlighter_rouge][type] + end + + def self.prepare_options(converter) + return if converter.data.key?(:syntax_highlighter_rouge) + + cache = converter.data[:syntax_highlighter_rouge] = {} + + opts = converter.options[:syntax_highlighter_opts].dup + + span_opts = opts.delete(:span)&.dup || {} + block_opts = opts.delete(:block)&.dup || {} + normalize_keys(span_opts) + normalize_keys(block_opts) + + cache[:span] = opts.merge(span_opts) + cache[:span][:wrap] = false + + cache[:block] = opts.merge(block_opts) + end + + def self.normalize_keys(hash) + return if hash.empty? + + hash.keys.each do |k| + hash[k.kind_of?(String) ? Kramdown::Options.str_to_sym(k) : k] = hash.delete(k) + end + end + + def self.formatter_class(opts = {}) + case formatter = opts[:formatter] + when Class + formatter + when /\A[[:upper:]][[:alnum:]_]*\z/ + ::Rouge::Formatters.const_get(formatter, false) + else + # Available in Rouge 2.0 or later + ::Rouge::Formatters::HTMLLegacy + end + rescue NameError + # Fallback to Rouge 1.x + ::Rouge::Formatters::HTML + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/toc.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/toc.rb new file mode 100644 index 0000000..725caa2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/converter/toc.rb @@ -0,0 +1,69 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/converter' + +module Kramdown + + module Converter + + # Converts a Kramdown::Document to an element tree that represents the table of contents. + # + # The returned tree consists of Element objects of type :toc where the root element is just used + # as container object. Each :toc element contains as value the wrapped :header element and under + # the attribute key :id the header ID that should be used (note that this ID may not exist in + # the wrapped element). + # + # Since the TOC tree consists of special :toc elements, one cannot directly feed this tree to + # other converters! + class Toc < Base + + def initialize(root, options) + super + @toc = Element.new(:toc) + @stack = [] + @options[:template] = '' + end + + def convert(el) + if el.type == :header && in_toc?(el) + attr = el.attr.dup + attr['id'] = generate_id(el.options[:raw_text]) if @options[:auto_ids] && !attr['id'] + add_to_toc(el, attr['id']) if attr['id'] + else + el.children.each {|child| convert(child) } + end + @toc + end + + private + + def add_to_toc(el, id) + toc_element = Element.new(:toc, el, id: id) + + success = false + until success + if @stack.empty? + @toc.children << toc_element + @stack << toc_element + success = true + elsif @stack.last.value.options[:level] < el.options[:level] + @stack.last.children << toc_element + @stack << toc_element + success = true + else + @stack.pop + end + end + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/document.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/document.rb new file mode 100644 index 0000000..d31ea11 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/document.rb @@ -0,0 +1,139 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# +# = kramdown +# +# kramdown is fast, pure Ruby Markdown superset converter, using a strict syntax definition and +# supporting several common extensions. +# +# The kramdown library is mainly written to support the kramdown-to-HTML conversion chain. However, +# due to its flexibility it supports other input and output formats as well. Here is a list of the +# supported formats: +# +# * input formats: kramdown (a Markdown superset), Markdown, GFM, HTML +# * output formats: HTML, kramdown, LaTeX (and therefore PDF), PDF via Prawn +# +# All the documentation on the available input and output formats is available at +# http://kramdown.gettalong.org. +# +# == Usage +# +# kramdown has a simple API, so using kramdown is as easy as +# +# require 'kramdown' +# +# Kramdown::Document.new(text).to_html +# +# For detailed information have a look at the *\Kramdown::Document* class. +# +# == License +# +# MIT - see the COPYING file. + +require 'kramdown/version' +require 'kramdown/element' +require 'kramdown/error' +require 'kramdown/parser' +require 'kramdown/converter' +require 'kramdown/options' +require 'kramdown/utils' + +module Kramdown + + # Return the data directory for kramdown. + def self.data_dir + unless defined?(@data_dir) + require 'rbconfig' + @data_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'kramdown')) + @data_dir = File.expand_path(File.join(RbConfig::CONFIG["datadir"], "kramdown")) unless File.exist?(@data_dir) + raise "kramdown data directory not found! This is a bug, please report it!" unless File.directory?(@data_dir) + end + @data_dir + end + + # The main interface to kramdown. + # + # This class provides a one-stop-shop for using kramdown to convert text into various output + # formats. Use it like this: + # + # require 'kramdown' + # doc = Kramdown::Document.new('This *is* some kramdown text') + # puts doc.to_html + # + # The #to_html method is a shortcut for using the Converter::Html class. See #method_missing for + # more information. + # + # The second argument to the ::new method is an options hash for customizing the behaviour of the + # used parser and the converter. See ::new for more information! + class Document + + # The root Element of the element tree. It is immediately available after the ::new method has + # been called. + attr_accessor :root + + # The options hash which holds the options for parsing/converting the Kramdown document. + attr_reader :options + + # An array of warning messages. It is filled with warnings during the parsing phase (i.e. in + # ::new) and the conversion phase. + attr_reader :warnings + + # Create a new Kramdown document from the string +source+ and use the provided +options+. The + # options that can be used are defined in the Options module. + # + # The special options key :input can be used to select the parser that should parse the + # +source+. It has to be the name of a class in the Kramdown::Parser module. For example, to + # select the kramdown parser, one would set the :input key to +Kramdown+. If this key is not + # set, it defaults to +Kramdown+. + # + # The +source+ is immediately parsed by the selected parser so that the root element is + # immediately available and the output can be generated. + def initialize(source, options = {}) + @options = Options.merge(options).freeze + parser = (@options[:input] || 'kramdown').to_s + parser = parser[0..0].upcase + parser[1..-1] + try_require('parser', parser) + if Parser.const_defined?(parser) + @root, @warnings = Parser.const_get(parser).parse(source, @options) + else + raise Kramdown::Error, "kramdown has no parser to handle the specified " \ + "input format: #{@options[:input]}" + end + end + + # Check if a method is invoked that begins with +to_+ and if so, try to instantiate a converter + # class (i.e. a class in the Kramdown::Converter module) and use it for converting the document. + # + # For example, +to_html+ would instantiate the Kramdown::Converter::Html class. + def method_missing(id, *attr, &block) + if id.to_s =~ /^to_(\w+)$/ && (name = Utils.camelize($1)) && + try_require('converter', name) && Converter.const_defined?(name) + output, warnings = Converter.const_get(name).convert(@root, @options) + @warnings.concat(warnings) + output + else + super + end + end + + def inspect # :nodoc: + "" + end + + # Try requiring a parser or converter class and don't raise an error if the file is not found. + def try_require(type, name) + require("kramdown/#{type}/#{Utils.snake_case(name)}") + true + rescue LoadError + true + end + protected :try_require + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/element.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/element.rb new file mode 100644 index 0000000..9aaad96 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/element.rb @@ -0,0 +1,551 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + + # Represents all elements in the element tree. + # + # kramdown only uses this one class for representing all available elements in an element tree + # (paragraphs, headers, emphasis, ...). The type of element can be set via the #type accessor. + # + # The root of a kramdown element tree has to be an element of type :root. It needs to have certain + # option keys set so that conversions work correctly. If only a part of a tree should be + # converted, duplicate the root node and assign the #children appropriately, e.g: + # + # root = doc.root + # new_root = root.dup + # new_root.children = [root.children[0]] # assign new array with elements to convert + # + # Following is a description of all supported element types. + # + # Note that the option :location may contain the start line number of an element in the source + # document. + # + # == Structural Elements + # + # === :root + # + # [Category] None + # [Usage context] As the root element of a document + # [Content model] Block-level elements + # + # Represents the root of a kramdown document. + # + # The root element contains the following option keys: + # + # :encoding:: When running on Ruby 1.9 this key has to be set to the encoding used for the text + # parts of the kramdown document. + # + # :abbrev_defs:: This key may be used to store the mapping of abbreviation to abbreviation + # definition. + # + # :abbrev_attr:: This key may be used to store the mapping of abbreviation to abbreviation + # attributes. + # + # :options:: This key may be used to store options that were set during parsing of the document. + # + # :footnote_count:: This key stores the number of actually referenced footnotes of the document. + # + # === :blank + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] Empty + # + # Represents one or more blank lines. It is not allowed to have two or more consecutive blank + # elements. + # + # The +value+ field may contain the original content of the blank lines. + # + # + # === :p + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] Span-level elements + # + # Represents a paragraph. + # + # If the option :transparent is +true+, this element just represents a block of text. I.e. this + # element just functions as a container for span-level elements. + # + # + # === :header + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] Span-level elements + # + # Represents a header. + # + # The option :level specifies the header level and has to contain a number between 1 and \6. The + # option :raw_text has to contain the raw header text. + # + # + # === :blockquote + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] Block-level elements + # + # Represents a blockquote. + # + # + # === :codeblock + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] Empty + # + # Represents a code block, i.e. a block of text that should be used as-is. + # + # The +value+ field has to contain the content of the code block. + # + # The option :lang specifies a highlighting language with possible HTML style options (e.g. + # php?start_inline=1) and should be used instead of a possibly also available language embedded in + # a class name of the form 'language-LANG'. + # + # + # === :ul + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] One or more :li elements + # + # Represents an unordered list. + # + # + # === :ol + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] One or more :li elements + # + # Represents an ordered list. + # + # + # === :li + # + # [Category] Block-level element + # [Usage context] Inside :ol and :ul elements + # [Content model] Block-level elements + # + # Represents a list item of an ordered or unordered list. + # + # Note that the first child of a list item must not be a :blank element! + # + # + # === :dl + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] One or more groups each consisting of one or more :dt elements followed by one + # or more :dd elements. + # + # Represents a definition list which contains groups consisting of terms and definitions for them. + # + # + # === :dt + # + # [Category] Block-level element + # [Usage context] Before :dt or :dd elements inside a :dl elment + # [Content model] Span-level elements + # + # Represents the term part of a term-definition group in a definition list. + # + # + # === :dd + # + # [Category] Block-level element + # [Usage context] After :dt or :dd elements inside a :dl elment + # [Content model] Block-level elements + # + # Represents the definition part of a term-definition group in a definition list. + # + # + # === :hr + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] None + # + # Represents a horizontal line. + # + # + # === :table + # + # [Category] Block-level element + # [Usage context] Where block-level elements are expected + # [Content model] Zero or one :thead elements, one or more :tbody elements, zero or one :tfoot + # elements + # + # Represents a table. Each table row (i.e. :tr element) of the table has to contain the same + # number of :td elements. + # + # The option :alignment has to be an array containing the alignment values, exactly one for each + # column of the table. The possible alignment values are :left, :center, :right and :default. + # + # + # === :thead + # + # [Category] None + # [Usage context] As first element inside a :table element + # [Content model] One or more :tr elements + # + # Represents the table header. + # + # + # === :tbody + # + # [Category] None + # [Usage context] After a :thead element but before a :tfoot element inside a :table element + # [Content model] One or more :tr elements + # + # Represents a table body. + # + # + # === :tfoot + # + # [Category] None + # [Usage context] As last element inside a :table element + # [Content model] One or more :tr elements + # + # Represents the table footer. + # + # + # === :tr + # + # [Category] None + # [Usage context] Inside :thead, :tbody and :tfoot elements + # [Content model] One or more :td elements + # + # Represents a table row. + # + # + # === :td + # + # [Category] Block-level element + # [Usage context] Inside :tr elements + # [Content model] As child of :thead/:tr span-level elements, as child of :tbody/:tr and + # :tfoot/:tr block-level elements + # + # Represents a table cell. + # + # + # === :math + # + # [Category] Block/span-level element + # [Usage context] Where block/span-level elements are expected + # [Content model] None + # + # Represents mathematical text that is written in LaTeX. + # + # The +value+ field has to contain the actual mathematical text. + # + # The option :category has to be set to either :span or :block depending on the context where the + # element is used. + # + # + # == Text Markup Elements + # + # === :text + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents text. + # + # The +value+ field has to contain the text itself. + # + # + # === :br + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents a hard line break. + # + # + # === :a + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] Span-level elements + # + # Represents a link to an URL. + # + # The attribute +href+ has to be set to the URL to which the link points. The attribute +title+ + # optionally contains the title of the link. + # + # + # === :img + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents an image. + # + # The attribute +src+ has to be set to the URL of the image. The attribute +alt+ has to contain a + # text description of the image. The attribute +title+ optionally contains the title of the image. + # + # + # === :codespan + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents verbatim text. + # + # The +value+ field has to contain the content of the code span. + # + # + # === :footnote + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents a footnote marker. + # + # The +value+ field has to contain an element whose children are the content of the footnote. The + # option :name has to contain a valid and unique footnote name. A valid footnote name consists of + # a word character or a digit and then optionally followed by other word characters, digits or + # dashes. + # + # + # === :em + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] Span-level elements + # + # Represents emphasis of its contents. + # + # + # === :strong + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] Span-level elements + # + # Represents strong importance for its contents. + # + # + # === :entity + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents an HTML entity. + # + # The +value+ field has to contain an instance of Kramdown::Utils::Entities::Entity. The option + # :original can be used to store the original representation of the entity. + # + # + # === :typographic_sym + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents a typographic symbol. + # + # The +value+ field needs to contain a Symbol representing the specific typographic symbol from + # the following list: + # + # :mdash:: An mdash character (---) + # :ndash:: An ndash character (--) + # :hellip:: An ellipsis (...) + # :laquo:: A left guillemet (<<) + # :raquo:: A right guillemet (>>) + # :laquo_space:: A left guillemet with a space (<< ) + # :raquo_space:: A right guillemet with a space ( >>) + # + # + # === :smart_quote + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents a quotation character. + # + # The +value+ field needs to contain a Symbol representing the specific quotation character: + # + # :lsquo:: Left single quote + # :rsquo:: Right single quote + # :ldquo:: Left double quote + # :rdquo:: Right double quote + # + # + # === :abbreviation + # + # [Category] Span-level element + # [Usage context] Where span-level elements are expected + # [Content model] None + # + # Represents a text part that is an abbreviation. + # + # The +value+ field has to contain the text part that is the abbreviation. The definition of the + # abbreviation is stored in the :root element of the document. + # + # + # == Other Elements + # + # === :html_element + # + # [Category] Block/span-level element + # [Usage context] Where block/span-level elements or raw HTML elements are expected + # [Content model] Depends on the element + # + # Represents an HTML element. + # + # The +value+ field has to contain the name of the HTML element the element is representing. + # + # The option :category has to be set to either :span or :block depending on the whether the + # element is a block-level or a span-level element. The option :content_model has to be set to the + # content model for the element (either :block if it contains block-level elements, :span if it + # contains span-level elements or :raw if it contains raw content). + # + # + # === :xml_comment + # + # [Category] Block/span-level element + # [Usage context] Where block/span-level elements are expected or in raw HTML elements + # [Content model] None + # + # Represents an XML/HTML comment. + # + # The +value+ field has to contain the whole XML/HTML comment including the delimiters. + # + # The option :category has to be set to either :span or :block depending on the context where the + # element is used. + # + # + # === :xml_pi + # + # [Category] Block/span-level element + # [Usage context] Where block/span-level elements are expected or in raw HTML elements + # [Content model] None + # + # Represents an XML/HTML processing instruction. + # + # The +value+ field has to contain the whole XML/HTML processing instruction including the + # delimiters. + # + # The option :category has to be set to either :span or :block depending on the context where the + # element is used. + # + # + # === :comment + # + # [Category] Block/span-level element + # [Usage context] Where block/span-level elements are expected + # [Content model] None + # + # Represents a comment. + # + # The +value+ field has to contain the comment. + # + # The option :category has to be set to either :span or :block depending on the context where the + # element is used. If it is set to :span, then no blank lines are allowed in the comment. + # + # + # === :raw + # + # [Category] Block/span-level element + # [Usage context] Where block/span-level elements are expected + # [Content model] None + # + # Represents a raw string that should not be modified. For example, the element could contain some + # HTML code that should be output as-is without modification and escaping. + # + # The +value+ field has to contain the actual raw text. + # + # The option :category has to be set to either :span or :block depending on the context where the + # element is used. If it is set to :span, then no blank lines are allowed in the raw text. + # + # The option :type can be set to an array of strings to define for which converters the raw string + # is valid. + # + class Element + + # A symbol representing the element type. For example, :p or :blockquote. + attr_accessor :type + + # The value of the element. The interpretation of this field depends on the type of the element. + # Many elements don't use this field. + attr_accessor :value + + # The child elements of this element. + attr_accessor :children + + # Create a new Element object of type +type+. The optional parameters +value+, +attr+ and + # +options+ can also be set in this constructor for convenience. + def initialize(type, value = nil, attr = nil, options = nil) + @type, @value, @attr, @options = type, value, attr, options + @children = [] + end + + # The attributes of the element. + def attr + @attr ||= {} + end + + # The options hash for the element. It is used for storing arbitray options. + def options + @options ||= {} + end + + def inspect # :nodoc: + "hallo` the emphasis tag + would normally be converted to an `:html` element with tag type `:em`. + If `html_to_native` is `true`, then the emphasis would be converted to a + native `:em` element. + + This is useful for converters that cannot deal with HTML elements. + + Default: false + Used by: kramdown parser + EOF + + define(:link_defs, Object, {}, <<~EOF) do |val| + Pre-defines link definitions + + This option can be used to pre-define link definitions. The value needs + to be a Hash where the keys are the link identifiers and the values are + two element Arrays with the link URL and the link title. + + If the value is a String, it has to contain a valid YAML hash and the + hash has to follow the above guidelines. + + Default: {} + Used by: kramdown parser + EOF + val = simple_hash_validator(val, :link_defs) + val.each do |_k, v| + if !(Array === v) || v.size > 2 || v.empty? + raise Kramdown::Error, "Invalid structure for hash value of option #{name}" + end + v << nil if v.size == 1 + end + val + end + + define(:footnote_nr, Integer, 1, <<~EOF) + The number of the first footnote + + This option can be used to specify the number that is used for the first + footnote. + + Default: 1 + Used by: HTML converter + EOF + + define(:entity_output, Symbol, :as_char, <<~EOF) + Defines how entities are output + + The possible values are :as_input (entities are output in the same + form as found in the input), :numeric (entities are output in numeric + form), :symbolic (entities are output in symbolic form if possible) or + :as_char (entities are output as characters if possible, only available + on Ruby 1.9). + + Default: :as_char + Used by: HTML converter, kramdown converter + EOF + + TOC_LEVELS_RANGE = (1..6).freeze + TOC_LEVELS_ARRAY = TOC_LEVELS_RANGE.to_a.freeze + private_constant :TOC_LEVELS_RANGE, :TOC_LEVELS_ARRAY + + define(:toc_levels, Object, TOC_LEVELS_ARRAY, <<~EOF) do |val| + Defines the levels that are used for the table of contents + + The individual levels can be specified by separating them with commas + (e.g. 1,2,3) or by using the range syntax (e.g. 1..3). Only the + specified levels are used for the table of contents. + + Default: 1..6 + Used by: HTML/Latex converter + EOF + case val + when String + if val =~ /^(\d)\.\.(\d)$/ + val = Range.new($1.to_i, $2.to_i).to_a + elsif val.match?(/^\d(?:,\d)*$/) + val = val.split(",").map(&:to_i).uniq + else + raise Kramdown::Error, "Invalid syntax for option toc_levels" + end + when Array + unless val.eql?(TOC_LEVELS_ARRAY) + val = val.map(&:to_i).uniq + end + when Range + val = if val.eql?(TOC_LEVELS_RANGE) + TOC_LEVELS_ARRAY + else + val.map(&:to_i).uniq + end + else + raise Kramdown::Error, "Invalid type #{val.class} for option toc_levels" + end + if val.any? {|i| !TOC_LEVELS_RANGE.cover?(i) } + raise Kramdown::Error, "Level numbers for option toc_levels have to be integers from 1 to 6" + end + val + end + + define(:line_width, Integer, 72, <<~EOF) + Defines the line width to be used when outputting a document + + Default: 72 + Used by: kramdown converter + EOF + + define(:latex_headers, Object, %w[section subsection subsubsection paragraph subparagraph subparagraph], <<~EOF) do |val| + Defines the LaTeX commands for different header levels + + The commands for the header levels one to six can be specified by + separating them with commas. + + Default: section,subsection,subsubsection,paragraph,subparagraph,subparagraph + Used by: Latex converter + EOF + simple_array_validator(val, :latex_headers, 6) + end + + SMART_QUOTES_ENTITIES = %w[lsquo rsquo ldquo rdquo].freeze + SMART_QUOTES_STR = SMART_QUOTES_ENTITIES.join(',').freeze + private_constant :SMART_QUOTES_ENTITIES, :SMART_QUOTES_STR + + define(:smart_quotes, Object, SMART_QUOTES_ENTITIES, <<~EOF) do |val| + Defines the HTML entity names or code points for smart quote output + + The entities identified by entity name or code point that should be + used for, in order, a left single quote, a right single quote, a left + double and a right double quote are specified by separating them with + commas. + + Default: lsquo,rsquo,ldquo,rdquo + Used by: HTML/Latex converter + EOF + if val == SMART_QUOTES_STR || val == SMART_QUOTES_ENTITIES + SMART_QUOTES_ENTITIES + else + val = simple_array_validator(val, :smart_quotes, 4) + val.map! {|v| Integer(v) rescue v } + val + end + end + + define(:typographic_symbols, Object, {}, <<~EOF) do |val| + Defines a mapping from typographical symbol to output characters + + Typographical symbols are normally output using their equivalent Unicode + codepoint. However, sometimes one wants to change the output, mostly to + fallback to a sequence of ASCII characters. + + This option allows this by specifying a mapping from typographical + symbol to its output string. For example, the mapping {hellip: ...} would + output the standard ASCII representation of an ellipsis. + + The available typographical symbol names are: + + * hellip: ellipsis + * mdash: em-dash + * ndash: en-dash + * laquo: left guillemet + * raquo: right guillemet + * laquo_space: left guillemet followed by a space + * raquo_space: right guillemet preceeded by a space + + Default: {} + Used by: HTML/Latex converter + EOF + val = simple_hash_validator(val, :typographic_symbols) + val.keys.each do |k| + val[k.kind_of?(String) ? str_to_sym(k) : k] = val.delete(k).to_s + end + val + end + + define(:remove_block_html_tags, Boolean, true, <<~EOF) + Remove block HTML tags + + If this option is `true`, the RemoveHtmlTags converter removes + block HTML tags. + + Default: true + Used by: RemoveHtmlTags converter + EOF + + define(:remove_span_html_tags, Boolean, false, <<~EOF) + Remove span HTML tags + + If this option is `true`, the RemoveHtmlTags converter removes + span HTML tags. + + Default: false + Used by: RemoveHtmlTags converter + EOF + + define(:header_offset, Integer, 0, <<~EOF) + Sets the output offset for headers + + If this option is c (may also be negative) then a header with level n + will be output as a header with level c+n. If c+n is lower than 1, + level 1 will be used. If c+n is greater than 6, level 6 will be used. + + Default: 0 + Used by: HTML converter, Kramdown converter, Latex converter + EOF + + define(:syntax_highlighter, Symbol, :rouge, <<~EOF) + Set the syntax highlighter + + Specifies the syntax highlighter that should be used for highlighting + code blocks and spans. If this option is set to +nil+, no syntax + highlighting is done. + + Options for the syntax highlighter can be set with the + syntax_highlighter_opts configuration option. + + Default: rouge + Used by: HTML/Latex converter + EOF + + define(:syntax_highlighter_opts, Object, {}, <<~EOF) do |val| + Set the syntax highlighter options + + Specifies options for the syntax highlighter set via the + syntax_highlighter configuration option. + + The value needs to be a hash with key-value pairs that are understood by + the used syntax highlighter. + + Default: {} + Used by: HTML/Latex converter + EOF + val = simple_hash_validator(val, :syntax_highlighter_opts) + val.keys.each do |k| + val[k.kind_of?(String) ? str_to_sym(k) : k] = val.delete(k) + end + val + end + + define(:math_engine, Symbol, :mathjax, <<~EOF) + Set the math engine + + Specifies the math engine that should be used for converting math + blocks/spans. If this option is set to +nil+, no math engine is used and + the math blocks/spans are output as is. + + Options for the selected math engine can be set with the + math_engine_opts configuration option. + + Default: mathjax + Used by: HTML converter + EOF + + define(:math_engine_opts, Object, {}, <<~EOF) do |val| + Set the math engine options + + Specifies options for the math engine set via the math_engine + configuration option. + + The value needs to be a hash with key-value pairs that are understood by + the used math engine. + + Default: {} + Used by: HTML converter + EOF + val = simple_hash_validator(val, :math_engine_opts) + val.keys.each do |k| + val[k.kind_of?(String) ? str_to_sym(k) : k] = val.delete(k) + end + val + end + + define(:footnote_backlink, String, '↩', <<~EOF) + Defines the text that should be used for the footnote backlinks + + The footnote backlink is just text, so any special HTML characters will + be escaped. + + If the footnote backlint text is an empty string, no footnote backlinks + will be generated. + + Default: '&8617;' + Used by: HTML converter + EOF + + define(:footnote_backlink_inline, Boolean, false, <<~EOF) + Specifies whether the footnote backlink should always be inline + + With the default of false the footnote backlink is placed at the end of + the last paragraph if there is one, or an extra paragraph with only the + footnote backlink is created. + + Setting this option to true tries to place the footnote backlink in the + last, possibly nested paragraph or header. If this fails (e.g. in the + case of a table), an extra paragraph with only the footnote backlink is + created. + + Default: false + Used by: HTML converter + EOF + + define(:footnote_prefix, String, '', <<~EOF) + Prefix used for footnote IDs + + This option can be used to set a prefix for footnote IDs. This is useful + when rendering multiple documents into the same output file to avoid + duplicate IDs. The prefix should only contain characters that are valid + in an ID! + + Default: '' + Used by: HTML + EOF + + define(:footnote_link_text, String, '%s', <<~EOF) do |val| + The text used for the footnote number in a footnote link + + This option can be used to add additional text to the footnote + link. It should be a format string, and is passed the footnote + number as the only argument to the format string. + e.g. "[footnote %s]" would display as "[footnote 1]". + + Default: '%s' + Used by: HTML + EOF + if !val.include?('%s') + raise Kramdown::Error, "option footnote_link_text needs to contain a '%s'" + end + val + end + + + define(:remove_line_breaks_for_cjk, Boolean, false, <<~EOF) + Specifies whether line breaks should be removed between CJK characters + + Default: false + Used by: HTML converter + EOF + + define(:forbidden_inline_options, Object, %w[template], <<~EOF) do |val| + Defines the options that may not be set using the {::options} extension + + The value needs to be an array of option names. + + Default: [template] + Used by: HTML converter + EOF + val.map! {|item| item.kind_of?(String) ? str_to_sym(item) : item } + simple_array_validator(val, :forbidden_inline_options) + end + + define(:list_indent, Integer, 2, <<~EOF) + Sets the number of spaces to use for list indentation + + Default: 2 + Used by: Kramdown converter + EOF + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser.rb new file mode 100644 index 0000000..ee04bda --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser.rb @@ -0,0 +1,26 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + + # This module contains all available parsers. A parser takes an input string and converts the + # string to an element tree. + # + # New parsers should be derived from the Base class which provides common functionality - see its + # API documentation for how to create a custom converter class. + module Parser + + autoload :Base, 'kramdown/parser/base' + autoload :Kramdown, 'kramdown/parser/kramdown' + autoload :Html, 'kramdown/parser/html' + autoload :Markdown, 'kramdown/parser/markdown' + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/base.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/base.rb new file mode 100644 index 0000000..075385e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/base.rb @@ -0,0 +1,137 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/utils' +require 'kramdown/parser' + +module Kramdown + + module Parser + + # == \Base class for parsers + # + # This class serves as base class for parsers. It provides common methods that can/should be + # used by all parsers, especially by those using StringScanner(Kramdown) for parsing. + # + # A parser object is used as a throw-away object, i.e. it is only used for storing the needed + # state information during parsing. Therefore one can't instantiate a parser object directly but + # only use the Base::parse method. + # + # == Implementing a parser + # + # Implementing a new parser is rather easy: just derive a new class from this class and put it + # in the Kramdown::Parser module -- the latter is needed so that the auto-detection of the new + # parser works correctly. Then you need to implement the +#parse+ method which has to contain + # the parsing code. + # + # Have a look at the Base::parse, Base::new and Base#parse methods for additional information! + class Base + + # The hash with the parsing options. + attr_reader :options + + # The array with the parser warnings. + attr_reader :warnings + + # The original source string. + attr_reader :source + + # The root element of element tree that is created from the source string. + attr_reader :root + + # Initialize the parser object with the +source+ string and the parsing +options+. + # + # The @root element, the @warnings array and @text_type (specifies the default type for newly + # created text nodes) are automatically initialized. + def initialize(source, options) + @source = source + @options = Kramdown::Options.merge(options) + @root = Element.new(:root, nil, nil, encoding: (source.encoding rescue nil), location: 1, + options: {}, abbrev_defs: {}, abbrev_attr: {}) + + @root.options[:abbrev_defs].default_proc = @root.options[:abbrev_attr].default_proc = + lambda do |h, k| + k_mod = k.gsub(/[\s\p{Z}]+/, " ") + k != k_mod ? h[k_mod] : nil + end + @warnings = [] + @text_type = :text + end + private_class_method(:new, :allocate) + + # Parse the +source+ string into an element tree, possibly using the parsing +options+, and + # return the root element of the element tree and an array with warning messages. + # + # Initializes a new instance of the calling class and then calls the +#parse+ method that must + # be implemented by each subclass. + def self.parse(source, options = {}) + parser = new(source, options) + parser.parse + [parser.root, parser.warnings] + end + + # Parse the source string into an element tree. + # + # The parsing code should parse the source provided in @source and build an element tree the + # root of which should be @root. + # + # This is the only method that has to be implemented by sub-classes! + def parse + raise NotImplementedError + end + + # Add the given warning +text+ to the warning array. + def warning(text) + @warnings << text + # TODO: add position information + end + + # Modify the string +source+ to be usable by the parser (unifies line ending characters to + # +\n+ and makes sure +source+ ends with a new line character). + def adapt_source(source) + unless source.valid_encoding? + raise "The source text contains invalid characters for the used encoding #{source.encoding}" + end + source = source.encode('UTF-8') + source.gsub!(/\r\n?/, "\n") + source.chomp! + source << "\n" + end + + # This helper method adds the given +text+ either to the last element in the +tree+ if it is a + # +type+ element or creates a new text element with the given +type+. + def add_text(text, tree = @tree, type = @text_type) + last = tree.children.last + if last && last.type == type + last.value << text + elsif !text.empty? + location = (last && last.options[:location] || tree.options[:location]) + tree.children << Element.new(type, text, nil, location: location) + end + end + + # Extract the part of the StringScanner +strscan+ backed string specified by the +range+. This + # method works correctly under Ruby 1.8 and Ruby 1.9. + def extract_string(range, strscan) + result = nil + begin + enc = strscan.string.encoding + strscan.string.force_encoding('ASCII-8BIT') + result = strscan.string[range].force_encoding(enc) + ensure + strscan.string.force_encoding(enc) + end + result + end + + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/html.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/html.rb new file mode 100644 index 0000000..47093de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/html.rb @@ -0,0 +1,621 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'rexml/parsers/baseparser' +require 'strscan' +require 'kramdown/utils' +require 'kramdown/parser' + +module Kramdown + + module Parser + + # Used for parsing an HTML document. + # + # The parsing code is in the Parser module that can also be used by other parsers. + class Html < Base + + # Contains all constants that are used when parsing. + module Constants + + # :stopdoc: + # The following regexps are based on the ones used by REXML, with some slight modifications. + HTML_DOCTYPE_RE = //im + HTML_COMMENT_RE = //m + HTML_INSTRUCTION_RE = /<\?(.*?)\?>/m + HTML_CDATA_RE = //m + HTML_ATTRIBUTE_RE = /\s*(#{REXML::Parsers::BaseParser::UNAME_STR})(?:\s*=\s*(?:(\p{Word}+)|("|')(.*?)\3))?/m + HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}(?:\s*=\s*(?:\p{Word}+|("|').*?\3))?)*)\s*(\/)?>/m + HTML_TAG_CLOSE_RE = /<\/(#{REXML::Parsers::BaseParser::UNAME_STR})\s*>/m + HTML_ENTITY_RE = /&([\w:][\w.:-]*);|&#(\d+);|&\#x([0-9a-fA-F]+);/ + + HTML_CONTENT_MODEL_BLOCK = %w[address applet article aside blockquote body + dd details div dl fieldset figure figcaption + footer form header hgroup iframe li main + map menu nav noscript object section summary td] + HTML_CONTENT_MODEL_SPAN = %w[a abbr acronym b bdo big button cite caption del dfn dt em + h1 h2 h3 h4 h5 h6 i ins label legend optgroup p q rb rbc + rp rt rtc ruby select small span strong sub sup th tt] + HTML_CONTENT_MODEL_RAW = %w[script style math option textarea pre code kbd samp var] + # The following elements are also parsed as raw since they need child elements that cannot + # be expressed using kramdown syntax: colgroup table tbody thead tfoot tr ul ol + + HTML_CONTENT_MODEL = Hash.new {|h, k| h[k] = :raw } + HTML_CONTENT_MODEL_BLOCK.each {|i| HTML_CONTENT_MODEL[i] = :block } + HTML_CONTENT_MODEL_SPAN.each {|i| HTML_CONTENT_MODEL[i] = :span } + HTML_CONTENT_MODEL_RAW.each {|i| HTML_CONTENT_MODEL[i] = :raw } + + # Some HTML elements like script belong to both categories (i.e. are valid in block and + # span HTML) and don't appear therefore! + # script, textarea + HTML_SPAN_ELEMENTS = %w[a abbr acronym b big bdo br button cite code del dfn em i img input + ins kbd label mark option q rb rbc rp rt rtc ruby samp select small + span strong sub sup time tt u var] + HTML_BLOCK_ELEMENTS = %w[address article aside applet body blockquote caption col colgroup + dd div dl dt fieldset figcaption footer form h1 h2 h3 h4 h5 h6 + header hgroup hr html head iframe legend menu li main map nav ol + optgroup p pre section summary table tbody td th thead tfoot tr ul] + HTML_ELEMENTS_WITHOUT_BODY = %w[area base br col command embed hr img input keygen link + meta param source track wbr] + + HTML_ELEMENT = Hash.new(false) + (HTML_SPAN_ELEMENTS + HTML_BLOCK_ELEMENTS + HTML_ELEMENTS_WITHOUT_BODY + + HTML_CONTENT_MODEL.keys).each do |a| + HTML_ELEMENT[a] = true + end + end + + # Contains the parsing methods. This module can be mixed into any parser to get HTML parsing + # functionality. The only thing that must be provided by the class are instance variable + # @stack for storing the needed state and @src (instance of StringScanner) for the actual + # parsing. + module Parser + + include Constants + + # Process the HTML start tag that has already be scanned/checked via @src. + # + # Does the common processing steps and then yields to the caller for further processing + # (first parameter is the created element; the second parameter is +true+ if the HTML + # element is already closed, ie. contains no body; the third parameter specifies whether the + # body - and the end tag - need to be handled in case closed=false). + def handle_html_start_tag(line = nil) # :yields: el, closed, handle_body + name = @src[1] + name.downcase! if HTML_ELEMENT[name.downcase] + closed = !@src[4].nil? + attrs = parse_html_attributes(@src[2], line, HTML_ELEMENT[name]) + + el = Element.new(:html_element, name, attrs, category: :block) + el.options[:location] = line if line + @tree.children << el + + if !closed && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) + closed = true + end + if name == 'script' || name == 'style' + handle_raw_html_tag(name) + yield(el, false, false) + else + yield(el, closed, true) + end + end + + # Parses the given string for HTML attributes and returns the resulting hash. + # + # If the optional +line+ parameter is supplied, it is used in warning messages. + # + # If the optional +in_html_tag+ parameter is set to +false+, attributes are not modified to + # contain only lowercase letters. + def parse_html_attributes(str, line = nil, in_html_tag = true) + attrs = {} + str.scan(HTML_ATTRIBUTE_RE).each do |attr, val, _sep, quoted_val| + attr.downcase! if in_html_tag + if attrs.key?(attr) + warning("Duplicate HTML attribute '#{attr}' on line #{line || '?'} - overwriting previous one") + end + attrs[attr] = val || quoted_val || "" + end + attrs + end + + # Handle the raw HTML tag at the current position. + def handle_raw_html_tag(name) + curpos = @src.pos + if @src.scan_until(/(?=<\/#{name}\s*>)/mi) + add_text(extract_string(curpos...@src.pos, @src), @tree.children.last, :raw) + @src.scan(HTML_TAG_CLOSE_RE) + else + add_text(@src.rest, @tree.children.last, :raw) + @src.terminate + warning("Found no end tag for '#{name}' - auto-closing it") + end + end + + HTML_RAW_START = /(?=<(#{REXML::Parsers::BaseParser::UNAME_STR}|\/|!--|\?|!\[CDATA\[))/ # :nodoc: + + # Parse raw HTML from the current source position, storing the found elements in +el+. + # Parsing continues until one of the following criteria are fulfilled: + # + # - The end of the document is reached. + # - The matching end tag for the element +el+ is found (only used if +el+ is an HTML + # element). + # + # When an HTML start tag is found, processing is deferred to #handle_html_start_tag, + # providing the block given to this method. + def parse_raw_html(el, &block) + @stack.push(@tree) + @tree = el + + done = false + while !@src.eos? && !done + if (result = @src.scan_until(HTML_RAW_START)) + add_text(result, @tree, :text) + line = @src.current_line_number + if (result = @src.scan(HTML_COMMENT_RE)) + @tree.children << Element.new(:xml_comment, result, nil, category: :block, location: line) + elsif (result = @src.scan(HTML_INSTRUCTION_RE)) + @tree.children << Element.new(:xml_pi, result, nil, category: :block, location: line) + elsif @src.scan(HTML_CDATA_RE) + @tree.children << Element.new(:text, @src[1], nil, cdata: true, location: line) + elsif @src.scan(HTML_TAG_RE) + if method(:handle_html_start_tag).arity.abs >= 1 + handle_html_start_tag(line, &block) + else + handle_html_start_tag(&block) # DEPRECATED: method needs to accept line number in 2.0 + end + elsif @src.scan(HTML_TAG_CLOSE_RE) + if @tree.value == (HTML_ELEMENT[@tree.value] ? @src[1].downcase : @src[1]) + done = true + else + add_text(@src.matched, @tree, :text) + warning("Found invalidly used HTML closing tag for '#{@src[1]}' on " \ + "line #{line} - ignoring it") + end + else + add_text(@src.getch, @tree, :text) + end + else + add_text(@src.rest, @tree, :text) + @src.terminate + if @tree.type == :html_element + warning("Found no end tag for '#{@tree.value}' on line " \ + "#{@tree.options[:location]} - auto-closing it") + end + done = true + end + end + + @tree = @stack.pop + end + + end + + # Converts HTML elements to native elements if possible. + class ElementConverter + + # :stopdoc: + + include Constants + include ::Kramdown::Utils::Entities + + REMOVE_TEXT_CHILDREN = %w[html head hgroup ol ul dl table colgroup tbody thead tfoot tr + select optgroup] + WRAP_TEXT_CHILDREN = %w[body section nav article aside header footer address div li dd + blockquote figure figcaption fieldset form] + REMOVE_WHITESPACE_CHILDREN = %w[body section nav article aside header footer address + div li dd blockquote figure figcaption td th fieldset form] + STRIP_WHITESPACE = %w[address article aside blockquote body caption dd div dl dt fieldset + figcaption form footer header h1 h2 h3 h4 h5 h6 legend li nav p + section td th] + SIMPLE_ELEMENTS = %w[em strong blockquote hr br img p thead tbody tfoot tr td th ul ol dl + li dl dt dd] + + def initialize(root) + @root = root + end + + def self.convert(root, el = root) + new(root).process(el) + end + + # Convert the element +el+ and its children. + def process(el, do_conversion = true, preserve_text = false, parent = nil) + case el.type + when :xml_comment, :xml_pi + ptype = if parent.nil? + 'div' + else + case parent.type + when :html_element then parent.value + when :code_span then 'code' + when :code_block then 'pre' + when :header then 'h1' + else parent.type.to_s + end + end + el.options.replace(category: (HTML_CONTENT_MODEL[ptype] == :span ? :span : :block)) + return + when :html_element + # do nothing + when :root + el.children.map! do |c| + if c.type == :text + process_text(c.value, !do_conversion) + else + process(c) + c + end + end.flatten! + remove_whitespace_children(el) + return + else return + end + + mname = "convert_#{el.value}" + if do_conversion && self.class.method_defined?(mname) + send(mname, el) + else + type = el.value + remove_text_children(el) if do_conversion && REMOVE_TEXT_CHILDREN.include?(type) + + if do_conversion && SIMPLE_ELEMENTS.include?(type) + set_basics(el, type.intern) + process_children(el, do_conversion, preserve_text) + else + process_html_element(el, do_conversion, preserve_text) + end + + if do_conversion + strip_whitespace(el) if STRIP_WHITESPACE.include?(type) + remove_whitespace_children(el) if REMOVE_WHITESPACE_CHILDREN.include?(type) + wrap_text_children(el) if WRAP_TEXT_CHILDREN.include?(type) + end + end + end + + def process_children(el, do_conversion = true, preserve_text = false) + el.children.map! do |c| + if c.type == :text + process_text(c.value, preserve_text || !do_conversion) + else + process(c, do_conversion, preserve_text, el) + c + end + end.flatten! + end + + # Process the HTML text +raw+: compress whitespace (if +preserve+ is +false+) and convert + # entities in entity elements. + def process_text(raw, preserve = false) + raw.gsub!(/\s+/, ' ') unless preserve + src = Kramdown::Utils::StringScanner.new(raw) + result = [] + until src.eos? + if (tmp = src.scan_until(/(?=#{HTML_ENTITY_RE})/o)) + result << Element.new(:text, tmp) + src.scan(HTML_ENTITY_RE) + val = src[1] || src[2]&.to_i || src[3].hex + result << if %w[lsquo rsquo ldquo rdquo].include?(val) + Element.new(:smart_quote, val.intern) + elsif %w[mdash ndash hellip laquo raquo].include?(val) + Element.new(:typographic_sym, val.intern) + else + begin + Element.new(:entity, entity(val), nil, original: src.matched) + rescue ::Kramdown::Error + src.pos -= src.matched_size - 1 + Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp')) + end + end + else + result << Element.new(:text, src.rest) + src.terminate + end + end + result + end + + def process_html_element(el, do_conversion = true, preserve_text = false) + el.options.replace(category: HTML_SPAN_ELEMENTS.include?(el.value) ? :span : :block, + content_model: (do_conversion ? HTML_CONTENT_MODEL[el.value] : :raw)) + process_children(el, do_conversion, preserve_text) + end + + def remove_text_children(el) + el.children.delete_if {|c| c.type == :text } + end + + def wrap_text_children(el) + tmp = [] + last_is_p = false + el.children.each do |c| + if !c.block? || c.type == :text + unless last_is_p + tmp << Element.new(:p, nil, nil, transparent: true) + last_is_p = true + end + tmp.last.children << c + tmp + else + tmp << c + last_is_p = false + end + end + el.children = tmp + end + + def strip_whitespace(el) + return if el.children.empty? + if el.children.first.type == :text + el.children.first.value.lstrip! + end + if el.children.last.type == :text + el.children.last.value.rstrip! + end + end + + def remove_whitespace_children(el) + i = -1 + el.children = el.children.reject do |c| + i += 1 + c.type == :text && c.value.strip.empty? && + (i == 0 || i == el.children.length - 1 || (el.children[i - 1].block? && + el.children[i + 1].block?)) + end + end + + def set_basics(el, type, opts = {}) + el.type = type + el.options.replace(opts) + el.value = nil + end + + def extract_text(el, raw) + raw << el.value.to_s if el.type == :text + el.children.each {|c| extract_text(c, raw) } + end + + def convert_textarea(el) + process_html_element(el, true, true) + end + + def convert_a(el) + if el.attr['href'] + set_basics(el, :a) + process_children(el) + else + process_html_element(el, false) + end + end + + EMPHASIS_TYPE_MAP = {'em' => :em, 'i' => :em, 'strong' => :strong, 'b' => :strong} + def convert_em(el) + text = +'' + extract_text(el, text) + if text =~ /\A\s/ || text =~ /\s\z/ + process_html_element(el, false) + else + set_basics(el, EMPHASIS_TYPE_MAP[el.value]) + process_children(el) + end + end + %w[b strong i].each do |i| + alias_method("convert_#{i}".to_sym, :convert_em) + end + + def convert_h1(el) + set_basics(el, :header, level: el.value[1..1].to_i) + extract_text(el, el.options[:raw_text] = +'') + process_children(el) + end + %w[h2 h3 h4 h5 h6].each do |i| + alias_method("convert_#{i}".to_sym, :convert_h1) + end + + def convert_code(el) + raw = +'' + extract_text(el, raw) + result = process_text(raw, true) + begin + str = result.inject(+'') do |mem, c| + case c.type + when :text + mem << c.value + when :entity + mem << if [60, 62, 34, 38].include?(c.value.code_point) + c.value.code_point.chr + else + c.value.char + end + when :smart_quote, :typographic_sym + mem << entity(c.value.to_s).char + else + raise "Bug - please report" + end + end + result.clear + result << Element.new(:text, str) + rescue StandardError + end + if result.length > 1 || result.first.type != :text + process_html_element(el, false, true) + else + if el.value == 'code' + set_basics(el, :codespan) + el.attr['class']&.gsub!(/\s+\bhighlighter-\w+\b|\bhighlighter-\w+\b\s*/, '') + else + set_basics(el, :codeblock) + if el.children.size == 1 && el.children.first.value == 'code' + value = (el.children.first.attr['class'] || '').scan(/\blanguage-\S+/).first + el.attr['class'] = "#{value} #{el.attr['class']}".rstrip if value + end + end + el.value = result.first.value + el.children.clear + end + end + alias convert_pre convert_code + + def convert_table(el) + unless is_simple_table?(el) + process_html_element(el, false) + return + end + remove_text_children(el) + process_children(el) + set_basics(el, :table) + + calc_alignment = lambda do |c| + if c.type == :tr + el.options[:alignment] = c.children.map do |td| + if td.attr['style'] + td.attr['style'].slice!(/(?:;\s*)?text-align:\s+(center|left|right)/) + td.attr.delete('style') if td.attr['style'].strip.empty? + $1 ? $1.to_sym : :default + else + :default + end + end + else + c.children.each {|cc| calc_alignment.call(cc) } + end + end + calc_alignment.call(el) + el.children.delete_if {|c| c.type == :html_element } + + change_th_type = lambda do |c| + if c.type == :th + c.type = :td + else + c.children.each {|cc| change_th_type.call(cc) } + end + end + change_th_type.call(el) + + if el.children.first.type == :tr + tbody = Element.new(:tbody) + tbody.children = el.children + el.children = [tbody] + end + end + + def is_simple_table?(el) + only_phrasing_content = lambda do |c| + c.children.all? do |cc| + (cc.type == :text || !HTML_BLOCK_ELEMENTS.include?(cc.value)) && only_phrasing_content.call(cc) + end + end + check_cells = proc do |c| + if c.value == 'th' || c.value == 'td' + return false unless only_phrasing_content.call(c) + else + c.children.each {|cc| check_cells.call(cc) } + end + end + check_cells.call(el) + + nr_cells = 0 + check_nr_cells = lambda do |t| + if t.value == 'tr' + count = t.children.count {|cc| cc.value == 'th' || cc.value == 'td' } + if count != nr_cells + if nr_cells == 0 + nr_cells = count + else + nr_cells = -1 + break + end + end + else + t.children.each {|cc| check_nr_cells.call(cc) } + end + end + check_nr_cells.call(el) + return false if nr_cells == -1 || nr_cells == 0 + + alignment = nil + check_alignment = proc do |t| + if t.value == 'tr' + cur_alignment = t.children.select {|cc| cc.value == 'th' || cc.value == 'td' }.map do |cell| + md = /text-align:\s+(center|left|right|justify|inherit)/.match(cell.attr['style'].to_s) + return false if md && (md[1] == 'justify' || md[1] == 'inherit') + md.nil? ? :default : md[1] + end + alignment = cur_alignment if alignment.nil? + return false if alignment != cur_alignment + else + t.children.each {|cc| check_alignment.call(cc) } + end + end + check_alignment.call(el) + + check_rows = lambda do |t, type| + t.children.all? do |r| + (r.value == 'tr' || r.type == :text) && r.children.all? {|c| c.value == type || c.type == :text } + end + end + check_rows.call(el, 'td') || + (el.children.all? do |t| + t.type == :text || (t.value == 'thead' && check_rows.call(t, 'th')) || + ((t.value == 'tfoot' || t.value == 'tbody') && check_rows.call(t, 'td')) + end && el.children.any? {|t| t.value == 'tbody' }) + end + + def convert_script(el) + if is_math_tag?(el) + handle_math_tag(el) + else + process_html_element(el) + end + end + + def is_math_tag?(el) + el.attr['type'].to_s =~ /\bmath\/tex\b/ + end + + def handle_math_tag(el) + set_basics(el, :math, category: (el.attr['type'].include?("mode=display") ? :block : :span)) + el.value = el.children.shift.value.sub(/\A(?:%\s*)?\z/m, '\1') + el.attr.delete('type') + end + + end + + include Parser + + # Parse the source string provided on initialization as HTML document. + def parse + @stack, @tree = [], @root + @src = Kramdown::Utils::StringScanner.new(adapt_source(source)) + + while true + if (result = @src.scan(/\s*#{HTML_INSTRUCTION_RE}/o)) + @tree.children << Element.new(:xml_pi, result.strip, nil, category: :block) + elsif (result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/o)) + # ignore the doctype + elsif (result = @src.scan(/\s*#{HTML_COMMENT_RE}/o)) + @tree.children << Element.new(:xml_comment, result.strip, nil, category: :block) + else + break + end + end + + tag_handler = lambda do |c, closed, handle_body| + parse_raw_html(c, &tag_handler) if !closed && handle_body + end + parse_raw_html(@tree, &tag_handler) + + ElementConverter.convert(@tree) + end + + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown.rb new file mode 100644 index 0000000..7e17f3f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown.rb @@ -0,0 +1,377 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'strscan' +require 'stringio' +require 'kramdown/parser' + +# TODO: use [[:alpha:]] in all regexp to allow parsing of international values in 1.9.1 +# NOTE: use @src.pre_match only before other check/match?/... operations, otherwise the content is changed + +module Kramdown + + module Parser + + # Used for parsing a document in kramdown format. + # + # If you want to extend the functionality of the parser, you need to do the following: + # + # * Create a new subclass + # * add the needed parser methods + # * modify the @block_parsers and @span_parsers variables and add the names of your parser + # methods + # + # Here is a small example for an extended parser class that parses ERB style tags as raw text if + # they are used as span-level elements (an equivalent block-level parser should probably also be + # made to handle the block case): + # + # require 'kramdown/parser/kramdown' + # + # class Kramdown::Parser::ERBKramdown < Kramdown::Parser::Kramdown + # + # def initialize(source, options) + # super + # @span_parsers.unshift(:erb_tags) + # end + # + # ERB_TAGS_START = /<%.*?%>/ + # + # def parse_erb_tags + # @src.pos += @src.matched_size + # @tree.children << Element.new(:raw, @src.matched) + # end + # define_parser(:erb_tags, ERB_TAGS_START, '<%') + # + # end + # + # The new parser can be used like this: + # + # require 'kramdown/document' + # # require the file with the above parser class + # + # Kramdown::Document.new(input_text, :input => 'ERBKramdown').to_html + # + class Kramdown < Base + + include ::Kramdown + + # Create a new Kramdown parser object with the given +options+. + def initialize(source, options) + super + + reset_env + + @alds = {} + @footnotes = {} + @link_defs = {} + update_link_definitions(@options[:link_defs]) + + @block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :atx_header, + :horizontal_rule, :list, :definition_list, :block_html, :setext_header, + :block_math, :table, :footnote_definition, :link_definition, + :abbrev_definition, :block_extensions, :eob_marker, :paragraph] + @span_parsers = [:emphasis, :codespan, :autolink, :span_html, :footnote_marker, :link, + :smart_quotes, :inline_math, :span_extensions, :html_entity, + :typographic_syms, :line_break, :escaped_chars] + + @span_pattern_cache ||= Hash.new {|h, k| h[k] = {} } + end + private_class_method(:new, :allocate) + + # The source string provided on initialization is parsed into the @root element. + def parse + configure_parser + parse_blocks(@root, adapt_source(source)) + update_tree(@root) + correct_abbreviations_attributes + replace_abbreviations(@root) + @footnotes.each do |_name, data| + update_tree(data[:content]) + replace_abbreviations(data[:content]) + end + footnote_count = 0 + @footnotes.each do |name, data| + (footnote_count += 1; next) if data.key?(:marker) + line = data[:content].options[:location] + warning("Footnote definition for '#{name}' on line #{line} is unreferenced - ignoring") + end + @root.options[:footnote_count] = footnote_count + end + + protected + + # :doc: + # + # Update the parser specific link definitions with the data from +link_defs+ (the value of the + # :link_defs option). + # + # The parameter +link_defs+ is a hash where the keys are possibly unnormalized link IDs and + # the values are two element arrays consisting of the link target and a title (can be +nil+). + def update_link_definitions(link_defs) + link_defs.each {|k, v| @link_defs[normalize_link_id(k)] = v } + end + + # Adapt the object to allow parsing like specified in the options. + def configure_parser + @parsers = {} + (@block_parsers + @span_parsers).each do |name| + if self.class.has_parser?(name) + @parsers[name] = self.class.parser(name) + else + raise Kramdown::Error, "Unknown parser: #{name}" + end + end + @span_start, @span_start_re = span_parser_regexps + end + + # Create the needed span parser regexps. + def span_parser_regexps(parsers = @span_parsers) + span_start = /#{parsers.map {|name| @parsers[name].span_start }.join('|')}/ + [span_start, /(?=#{span_start})/] + end + + # Parse all block-level elements in +text+ into the element +el+. + def parse_blocks(el, text = nil) + @stack.push([@tree, @src, @block_ial]) + @tree, @block_ial = el, nil + @src = (text.nil? ? @src : ::Kramdown::Utils::StringScanner.new(text, el.options[:location])) + + status = catch(:stop_block_parsing) do + until @src.eos? + @block_parsers.any? do |name| + if @src.check(@parsers[name].start_re) + send(@parsers[name].method) + else + false + end + end || begin + warning('Warning: this should not occur - no block parser handled the line') + add_text(@src.scan(/.*\n/)) + end + end + end + + @tree, @src, @block_ial = *@stack.pop + status + end + + # Update the tree by parsing all :+raw_text+ elements with the span-level parser (resets the + # environment) and by updating the attributes from the IALs. + def update_tree(element) + last_blank = nil + element.children.map! do |child| + case child.type + when :raw_text + last_blank = nil + reset_env(src: ::Kramdown::Utils::StringScanner.new(child.value, element.options[:location]), + text_type: :text) + parse_spans(child) + child.children + when :eob + update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial] + [] + when :blank + if last_blank + last_blank.value << child.value + [] + else + last_blank = child + child + end + else + last_blank = nil + update_tree(child) + update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial] + # DEPRECATED: option auto_id_stripping will be removed in 2.0 because then this will be + # the default behaviour + if child.type == :dt || (child.type == :header && @options[:auto_id_stripping]) + update_raw_text(child) + end + child + end + end.flatten! + end + + def span_pattern_cache(stop_re, span_start) + @span_pattern_cache[stop_re][span_start] ||= /(?=#{Regexp.union(stop_re, span_start)})/ + end + private :span_pattern_cache + + # Parse all span-level elements in the source string of @src into +el+. + # + # If the parameter +stop_re+ (a regexp) is used, parsing is immediately stopped if the regexp + # matches and if no block is given or if a block is given and it returns +true+. + # + # The parameter +parsers+ can be used to specify the (span-level) parsing methods that should + # be used for parsing. + # + # The parameter +text_type+ specifies the type which should be used for created text nodes. + def parse_spans(el, stop_re = nil, parsers = nil, text_type = @text_type) + @stack.push([@tree, @text_type]) unless @tree.nil? + @tree, @text_type = el, text_type + + span_start = @span_start + span_start_re = @span_start_re + span_start, span_start_re = span_parser_regexps(parsers) if parsers + parsers ||= @span_parsers + + used_re = (stop_re.nil? ? span_start_re : span_pattern_cache(stop_re, span_start)) + stop_re_found = false + while !@src.eos? && !stop_re_found + if (result = @src.scan_until(used_re)) + add_text(result) + if stop_re && @src.check(stop_re) + stop_re_found = (block_given? ? yield : true) + end + processed = parsers.any? do |name| + if @src.check(@parsers[name].start_re) + send(@parsers[name].method) + true + else + false + end + end unless stop_re_found + add_text(@src.getch) if !processed && !stop_re_found + else + (add_text(@src.rest); @src.terminate) unless stop_re + break + end + end + + @tree, @text_type = @stack.pop + + stop_re_found + end + + # Reset the current parsing environment. The parameter +env+ can be used to set initial + # values for one or more environment variables. + def reset_env(opts = {}) + opts = {text_type: :raw_text, stack: []}.merge(opts) + @src = opts[:src] + @tree = opts[:tree] + @block_ial = opts[:block_ial] + @stack = opts[:stack] + @text_type = opts[:text_type] + end + + # Return the current parsing environment. + def save_env + [@src, @tree, @block_ial, @stack, @text_type] + end + + # Restore the current parsing environment. + def restore_env(env) + @src, @tree, @block_ial, @stack, @text_type = *env + end + + # Update the given attributes hash +attr+ with the information from the inline attribute list + # +ial+ and all referenced ALDs. + def update_attr_with_ial(attr, ial) + ial[:refs]&.each do |ref| + update_attr_with_ial(attr, ref) if (ref = @alds[ref]) + end + ial.each do |k, v| + if k == IAL_CLASS_ATTR + attr[k] = "#{attr[k]} #{v}".lstrip + elsif k.kind_of?(String) + attr[k] = v + end + end + end + + # Update the raw text for automatic ID generation. + def update_raw_text(item) + raw_text = +'' + + append_text = lambda do |child| + if child.type == :text + raw_text << child.value + else + child.children.each {|c| append_text.call(c) } + end + end + + append_text.call(item) + item.options[:raw_text] = raw_text + end + + # Create a new block-level element, taking care of applying a preceding block IAL if it + # exists. This method should always be used for creating a block-level element! + def new_block_el(*args) + el = Element.new(*args) + if @block_ial + el.options[:ial] = @block_ial + @block_ial = nil + end + el + end + + @@parsers = {} + + # Struct class holding all the needed data for one block/span-level parser method. + Data = Struct.new(:name, :start_re, :span_start, :method) + + # Add a parser method + # + # * with the given +name+, + # * using +start_re+ as start regexp + # * and, for span parsers, +span_start+ as a String that can be used in a regexp and + # which identifies the starting character(s) + # + # to the registry. The method name is automatically derived from the +name+ or can explicitly + # be set by using the +meth_name+ parameter. + def self.define_parser(name, start_re, span_start = nil, meth_name = "parse_#{name}") + raise "A parser with the name #{name} already exists!" if @@parsers.key?(name) + @@parsers[name] = Data.new(name, start_re, span_start, meth_name) + end + + # Return the Data structure for the parser +name+. + def self.parser(name = nil) + @@parsers[name] + end + + # Return +true+ if there is a parser called +name+. + def self.has_parser?(name) + @@parsers.key?(name) + end + + # Regexp for matching indentation (one tab or four spaces) + INDENT = /^(?:\t| {4})/ + # Regexp for matching the optional space (zero or up to three spaces) + OPT_SPACE = / {0,3}/ + + require 'kramdown/parser/kramdown/blank_line' + require 'kramdown/parser/kramdown/eob' + require 'kramdown/parser/kramdown/paragraph' + require 'kramdown/parser/kramdown/header' + require 'kramdown/parser/kramdown/blockquote' + require 'kramdown/parser/kramdown/table' + require 'kramdown/parser/kramdown/codeblock' + require 'kramdown/parser/kramdown/horizontal_rule' + require 'kramdown/parser/kramdown/list' + require 'kramdown/parser/kramdown/link' + require 'kramdown/parser/kramdown/extensions' + require 'kramdown/parser/kramdown/footnote' + require 'kramdown/parser/kramdown/html' + require 'kramdown/parser/kramdown/escaped_chars' + require 'kramdown/parser/kramdown/html_entity' + require 'kramdown/parser/kramdown/line_break' + require 'kramdown/parser/kramdown/typographic_symbol' + require 'kramdown/parser/kramdown/autolink' + require 'kramdown/parser/kramdown/codespan' + require 'kramdown/parser/kramdown/emphasis' + require 'kramdown/parser/kramdown/smart_quotes' + require 'kramdown/parser/kramdown/math' + require 'kramdown/parser/kramdown/abbreviation' + + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/abbreviation.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/abbreviation.rb new file mode 100644 index 0000000..e9d7764 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/abbreviation.rb @@ -0,0 +1,80 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + ABBREV_DEFINITION_START = /^#{OPT_SPACE}\*\[(.+?)\]:(.*?)\n/ + + # Parse the link definition at the current location. + def parse_abbrev_definition + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + abbrev_id, abbrev_text = @src[1], @src[2] + abbrev_text.strip! + if @root.options[:abbrev_defs][abbrev_id] + warning("Duplicate abbreviation ID '#{abbrev_id}' on line #{start_line_number} " \ + "- overwriting") + end + @tree.children << new_block_el(:eob, :abbrev_def) + @root.options[:abbrev_defs][abbrev_id] = abbrev_text + @root.options[:abbrev_attr][abbrev_id] = @tree.children.last + true + end + define_parser(:abbrev_definition, ABBREV_DEFINITION_START) + + # Correct abbreviation attributes. + def correct_abbreviations_attributes + @root.options[:abbrev_attr].keys.each do |k| + @root.options[:abbrev_attr][k] = @root.options[:abbrev_attr][k].attr + end + end + + # Replace the abbreviation text with elements. + def replace_abbreviations(el, regexps = nil) + return if @root.options[:abbrev_defs].empty? + unless regexps + sorted_abbrevs = @root.options[:abbrev_defs].keys.sort {|a, b| b.length <=> a.length } + regexps = [Regexp.union(*sorted_abbrevs.map do |k| + /#{Regexp.escape(k).gsub(/\\\s/, "[\\s\\p{Z}]+").force_encoding(Encoding::UTF_8)}/ + end)] + regexps << /(?=(?:\W|^)#{regexps.first}(?!\w))/ # regexp should only match on word boundaries + end + el.children.map! do |child| + if child.type == :text && el.options[:content_model] != :raw + if child.value.match?(regexps.first) + result = [] + strscan = Kramdown::Utils::StringScanner.new(child.value, child.options[:location]) + text_lineno = strscan.current_line_number + while (temp = strscan.scan_until(regexps.last)) + abbr_lineno = strscan.current_line_number + abbr = strscan.scan(regexps.first) # begin of line case of abbr with \W char as first one + if abbr.nil? + temp << strscan.scan(/\W|^/) + abbr = strscan.scan(regexps.first) + end + result << Element.new(:text, temp, nil, location: text_lineno) + result << Element.new(:abbreviation, abbr, nil, location: abbr_lineno) + text_lineno = strscan.current_line_number + end + result << Element.new(:text, strscan.rest, nil, location: text_lineno) + else + child + end + else + replace_abbreviations(child, regexps) + child + end + end.flatten! + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/autolink.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/autolink.rb new file mode 100644 index 0000000..5f0ccfd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/autolink.rb @@ -0,0 +1,31 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + ACHARS = '[[:alnum:]]-_.' + AUTOLINK_START_STR = "<((mailto|https?|ftps?):.+?|[#{ACHARS}]+?@[#{ACHARS}]+?)>" + AUTOLINK_START = /#{AUTOLINK_START_STR}/u + + # Parse the autolink at the current location. + def parse_autolink + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + href = (@src[2].nil? ? "mailto:#{@src[1]}" : @src[1]) + el = Element.new(:a, nil, {'href' => href}, location: start_line_number) + add_text(@src[1].sub(/^mailto:/, ''), el) + @tree.children << el + end + define_parser(:autolink, AUTOLINK_START, '<') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blank_line.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blank_line.rb new file mode 100644 index 0000000..0d62c32 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blank_line.rb @@ -0,0 +1,30 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + BLANK_LINE = /(?>^\s*\n)+/ + + # Parse the blank line at the current postition. + def parse_blank_line + @src.pos += @src.matched_size + if (last_child = @tree.children.last) && last_child.type == :blank + last_child.value << @src.matched + else + @tree.children << new_block_el(:blank, @src.matched) + end + true + end + define_parser(:blank_line, BLANK_LINE) + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/block_boundary.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/block_boundary.rb new file mode 100644 index 0000000..bb64299 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/block_boundary.rb @@ -0,0 +1,34 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/extensions' +require 'kramdown/parser/kramdown/blank_line' +require 'kramdown/parser/kramdown/eob' + +module Kramdown + module Parser + class Kramdown + + BLOCK_BOUNDARY = /#{BLANK_LINE}|#{EOB_MARKER}|#{IAL_BLOCK_START}|\Z/ + + # Return +true+ if we are after a block boundary. + def after_block_boundary? + last_child = @tree.children.last + !last_child || last_child.type == :blank || + (last_child.type == :eob && last_child.value.nil?) || @block_ial + end + + # Return +true+ if we are before a block boundary. + def before_block_boundary? + @src.check(self.class::BLOCK_BOUNDARY) + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blockquote.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blockquote.rb new file mode 100644 index 0000000..3732b83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/blockquote.rb @@ -0,0 +1,38 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/blank_line' +require 'kramdown/parser/kramdown/extensions' +require 'kramdown/parser/kramdown/eob' + +module Kramdown + module Parser + class Kramdown + + BLOCKQUOTE_START = /^#{OPT_SPACE}> ?/ + + # Parse the blockquote at the current location. + def parse_blockquote + start_line_number = @src.current_line_number + result = @src.scan(PARAGRAPH_MATCH) + until @src.match?(self.class::LAZY_END) + result << @src.scan(PARAGRAPH_MATCH) + end + result.gsub!(BLOCKQUOTE_START, '') + + el = new_block_el(:blockquote, nil, nil, location: start_line_number) + @tree.children << el + parse_blocks(el, result) + true + end + define_parser(:blockquote, BLOCKQUOTE_START) + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codeblock.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codeblock.rb new file mode 100644 index 0000000..89d2053 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codeblock.rb @@ -0,0 +1,57 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/blank_line' +require 'kramdown/parser/kramdown/extensions' +require 'kramdown/parser/kramdown/eob' +require 'kramdown/parser/kramdown/paragraph' + +module Kramdown + module Parser + class Kramdown + + CODEBLOCK_START = INDENT + CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+(?:(?!#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START})^[ \t]*\S.*\n)*)*/ + + # Parse the indented codeblock at the current location. + def parse_codeblock + start_line_number = @src.current_line_number + data = @src.scan(self.class::CODEBLOCK_MATCH) + data.gsub!(/\n( {0,3}\S)/, ' \\1') + data.gsub!(INDENT, '') + @tree.children << new_block_el(:codeblock, data, nil, location: start_line_number) + true + end + define_parser(:codeblock, CODEBLOCK_START) + + FENCED_CODEBLOCK_START = /^~{3,}/ + FENCED_CODEBLOCK_MATCH = /^((~){3,})\s*?((\S+?)(?:\?\S*)?)?\s*?\n(.*?)^\1\2*\s*?\n/m + + # Parse the fenced codeblock at the current location. + def parse_codeblock_fenced + if @src.check(self.class::FENCED_CODEBLOCK_MATCH) + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + el = new_block_el(:codeblock, @src[5], nil, location: start_line_number, fenced: true) + lang = @src[3].to_s.strip + unless lang.empty? + el.options[:lang] = lang + el.attr['class'] = "language-#{@src[4]}" + end + @tree.children << el + true + else + false + end + end + define_parser(:codeblock_fenced, FENCED_CODEBLOCK_START) + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codespan.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codespan.rb new file mode 100644 index 0000000..9032161 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/codespan.rb @@ -0,0 +1,58 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + CODESPAN_DELIMITER = /`+/ + + # Parse the codespan at the current scanner location. + def parse_codespan + start_line_number = @src.current_line_number + result = @src.scan(CODESPAN_DELIMITER) + simple = (result.length == 1) + saved_pos = @src.save_pos + + if simple && @src.pre_match =~ /\s\Z|\A\Z/ && @src.match?(/\s/) + add_text(result) + return + end + + # assign static regex to avoid allocating the same on every instance + # where +result+ equals a single-backtick. Interpolate otherwise. + if result == '`' + scan_pattern = /`/ + str_sub_pattern = /`\Z/ + else + scan_pattern = /#{result}/ + str_sub_pattern = /#{result}\Z/ + end + + if (text = @src.scan_until(scan_pattern)) + text.sub!(str_sub_pattern, '') + unless simple + text = text[1..-1] if text[0..0] == ' ' + text = text[0..-2] if text[-1..-1] == ' ' + end + @tree.children << Element.new(:codespan, text, nil, { + codespan_delimiter: result, + location: start_line_number, + }) + + else + @src.revert_pos(saved_pos) + add_text(result) + end + end + define_parser(:codespan, CODESPAN_DELIMITER, '`') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/emphasis.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/emphasis.rb new file mode 100644 index 0000000..a69ab4a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/emphasis.rb @@ -0,0 +1,66 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + EMPHASIS_START = /(?:\*\*?|__?)/ + + # Parse the emphasis at the current location. + def parse_emphasis + start_line_number = @src.current_line_number + saved_pos = @src.save_pos + + result = @src.scan(EMPHASIS_START) + element = (result.length == 2 ? :strong : :em) + type = result[0..0] + + if (type == '_' && @src.pre_match =~ /[[:alpha:]]-?[[:alpha:]]*_*\z/) || @src.check(/\s/) || + @tree.type == element || @stack.any? {|el, _| el.type == element } + add_text(result) + return + end + + warnings_pos = @warnings.size + sub_parse = lambda do |delim, elem| + el = Element.new(elem, nil, nil, location: start_line_number) + stop_re = /#{Regexp.escape(delim)}/ + found = parse_spans(el, stop_re) do + (@src.pre_match[-1, 1] !~ /\s/) && + (elem != :em || !@src.match?(/#{Regexp.escape(delim * 2)}(?!#{Regexp.escape(delim)})/)) && + (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alnum:]]/)) && !el.children.empty? + end + [found, el, stop_re] + end + + found, el, stop_re = sub_parse.call(result, element) + if !found && element == :strong && @tree.type != :em + @src.revert_pos(saved_pos) + @src.pos += 1 + found, el, stop_re = sub_parse.call(type, :em) + end + if found + # Useful for implementing underlines. + el.options[:char] = type + + @src.scan(stop_re) + @tree.children << el + else + @warnings.slice!(0...warnings_pos) + @src.revert_pos(saved_pos) + @src.pos += result.length + add_text(result) + end + end + define_parser(:emphasis, EMPHASIS_START, '\*|_') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/eob.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/eob.rb new file mode 100644 index 0000000..82a037a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/eob.rb @@ -0,0 +1,26 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + EOB_MARKER = /^\^\s*?\n/ + + # Parse the EOB marker at the current location. + def parse_eob_marker + @src.pos += @src.matched_size + @tree.children << new_block_el(:eob) + true + end + define_parser(:eob_marker, EOB_MARKER) + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/escaped_chars.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/escaped_chars.rb new file mode 100644 index 0000000..9c2066f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/escaped_chars.rb @@ -0,0 +1,25 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + ESCAPED_CHARS = /\\([\\.*_+`<>()\[\]{}#!:|"'$=-])/ + + # Parse the backslash-escaped character at the current location. + def parse_escaped_chars + @src.pos += @src.matched_size + add_text(@src[1]) + end + define_parser(:escaped_chars, ESCAPED_CHARS, '\\\\') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/extensions.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/extensions.rb new file mode 100644 index 0000000..92ac620 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/extensions.rb @@ -0,0 +1,214 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + IAL_CLASS_ATTR = 'class' + + # Parse the string +str+ and extract all attributes and add all found attributes to the hash + # +opts+. + def parse_attribute_list(str, opts) + return if str.strip.empty? || str.strip == ':' + attrs = str.scan(ALD_TYPE_ANY) + attrs.each do |key, sep, val, ref, id_and_or_class, _, _| + if ref + (opts[:refs] ||= []) << ref + elsif id_and_or_class + id_and_or_class.scan(ALD_TYPE_ID_OR_CLASS).each do |id_attr, class_attr| + if class_attr + opts[IAL_CLASS_ATTR] = "#{opts[IAL_CLASS_ATTR]} #{class_attr}".lstrip + else + opts['id'] = id_attr + end + end + else + val.gsub!(/\\(\}|#{sep})/, "\\1") + opts[key] = val + end + end + warning("No or invalid attributes found in IAL/ALD content: #{str}") if attrs.empty? + end + + # Update the +ial+ with the information from the inline attribute list +opts+. + def update_ial_with_ial(ial, opts) + (ial[:refs] ||= []).concat(opts[:refs]) if opts.key?(:refs) + opts.each do |k, v| + if k == IAL_CLASS_ATTR + ial[k] = "#{ial[k]} #{v}".lstrip + elsif k.kind_of?(String) + ial[k] = v + end + end + end + + # Parse the generic extension at the current point. The parameter +type+ can either be :block + # or :span depending whether we parse a block or span extension tag. + def parse_extension_start_tag(type) + saved_pos = @src.save_pos + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + + error_block = lambda do |msg| + warning(msg) + @src.revert_pos(saved_pos) + add_text(@src.getch) if type == :span + false + end + + if @src[4] || @src.matched == '{:/}' + name = (@src[4] ? "for '#{@src[4]}' " : '') + return error_block.call("Invalid extension stop tag #{name} found on line " \ + "#{start_line_number} - ignoring it") + end + + ext = @src[1] + opts = {} + body = nil + parse_attribute_list(@src[2] || '', opts) + + unless @src[3] + stop_re = (type == :block ? /#{EXT_BLOCK_STOP_STR % ext}/ : /#{EXT_STOP_STR % ext}/) + if (result = @src.scan_until(stop_re)) + body = result.sub!(stop_re, '') + body.chomp! if type == :block + else + return error_block.call("No stop tag for extension '#{ext}' found on line " \ + "#{start_line_number} - ignoring it") + end + end + + if handle_extension(ext, opts, body, type, start_line_number) + true + else + error_block.call("Invalid extension with name '#{ext}' specified on line " \ + "#{start_line_number} - ignoring it") + end + end + + def handle_extension(name, opts, body, type, line_no = nil) + case name + when 'comment' + if body.kind_of?(String) + @tree.children << Element.new(:comment, body, nil, category: type, location: line_no) + end + true + when 'nomarkdown' + if body.kind_of?(String) + @tree.children << Element.new(:raw, body, nil, category: type, + location: line_no, type: opts['type'].to_s.split(/\s+/)) + end + true + when 'options' + opts.select do |k, v| + k = k.to_sym + if Kramdown::Options.defined?(k) + if @options[:forbidden_inline_options].include?(k) || + k == :forbidden_inline_options + warning("Option #{k} may not be set inline") + next false + end + + begin + val = Kramdown::Options.parse(k, v) + @options[k] = val + (@root.options[:options] ||= {})[k] = val + rescue StandardError + end + false + else + true + end + end.each do |k, _v| + warning("Unknown kramdown option '#{k}'") + end + @tree.children << new_block_el(:eob, :extension) if type == :block + true + else + false + end + end + + ALD_ID_CHARS = /[\w-]/ + ALD_ANY_CHARS = /\\\}|[^}]/ + ALD_ID_NAME = /\w#{ALD_ID_CHARS}*/ + ALD_CLASS_NAME = /[^\s.#]+/ + ALD_TYPE_KEY_VALUE_PAIR = /(#{ALD_ID_NAME})=("|')((?:\\\}|\\\2|[^}\2])*?)\2/ + ALD_TYPE_CLASS_NAME = /\.(#{ALD_CLASS_NAME})/ + ALD_TYPE_ID_NAME = /#([A-Za-z][\w:-]*)/ + ALD_TYPE_ID_OR_CLASS = /#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}/ + ALD_TYPE_ID_OR_CLASS_MULTI = /((?:#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME})+)/ + ALD_TYPE_REF = /(#{ALD_ID_NAME})/ + ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_REF}|#{ALD_TYPE_ID_OR_CLASS_MULTI})(?=\s|\Z)/ + ALD_START = /^#{OPT_SPACE}\{:(#{ALD_ID_NAME}):(#{ALD_ANY_CHARS}+)\}\s*?\n/ + + EXT_STOP_STR = "\\{:/(%s)?\\}" + EXT_START_STR = "\\{::(\\w+)(?:\\s(#{ALD_ANY_CHARS}*?)|)(\\/)?\\}" + EXT_BLOCK_START = /^#{OPT_SPACE}(?:#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME})\s*?\n/ + EXT_BLOCK_STOP_STR = "^#{OPT_SPACE}#{EXT_STOP_STR}\s*?\n" + + IAL_BLOCK = /\{:(?!:|\/)(#{ALD_ANY_CHARS}+)\}\s*?\n/ + IAL_BLOCK_START = /^#{OPT_SPACE}#{IAL_BLOCK}/ + + BLOCK_EXTENSIONS_START = /^#{OPT_SPACE}\{:/ + + # Parse one of the block extensions (ALD, block IAL or generic extension) at the current + # location. + def parse_block_extensions + if @src.scan(ALD_START) + parse_attribute_list(@src[2], @alds[@src[1]] ||= {}) + @tree.children << new_block_el(:eob, :ald) + true + elsif @src.check(EXT_BLOCK_START) + parse_extension_start_tag(:block) + elsif @src.scan(IAL_BLOCK_START) + if (last_child = @tree.children.last) && last_child.type != :blank && + (last_child.type != :eob || + [:link_def, :abbrev_def, :footnote_def].include?(last_child.value)) + parse_attribute_list(@src[1], last_child.options[:ial] ||= {}) + @tree.children << new_block_el(:eob, :ial) unless @src.check(IAL_BLOCK_START) + else + parse_attribute_list(@src[1], @block_ial ||= {}) + end + true + else + false + end + end + define_parser(:block_extensions, BLOCK_EXTENSIONS_START) + + EXT_SPAN_START = /#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME}/ + IAL_SPAN_START = /\{:(#{ALD_ANY_CHARS}+)\}/ + SPAN_EXTENSIONS_START = /\{:/ + + # Parse the extension span at the current location. + def parse_span_extensions + if @src.check(EXT_SPAN_START) + parse_extension_start_tag(:span) + elsif @src.check(IAL_SPAN_START) + if (last_child = @tree.children.last) && last_child.type != :text + @src.pos += @src.matched_size + attr = {} + parse_attribute_list(@src[1], attr) + update_ial_with_ial(last_child.options[:ial] ||= {}, attr) + update_attr_with_ial(last_child.attr, attr) + else + warning("Found span IAL after text - ignoring it") + add_text(@src.getch) + end + else + add_text(@src.getch) + end + end + define_parser(:span_extensions, SPAN_EXTENSIONS_START, '\{:') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/footnote.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/footnote.rb new file mode 100644 index 0000000..cf1dc92 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/footnote.rb @@ -0,0 +1,64 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/extensions' +require 'kramdown/parser/kramdown/blank_line' +require 'kramdown/parser/kramdown/codeblock' + +module Kramdown + module Parser + class Kramdown + + FOOTNOTE_DEFINITION_START = /^#{OPT_SPACE}\[\^(#{ALD_ID_NAME})\]:\s*?(.*?\n#{CODEBLOCK_MATCH})/ + + # Parse the foot note definition at the current location. + def parse_footnote_definition + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + + el = Element.new(:footnote_def, nil, nil, location: start_line_number) + parse_blocks(el, @src[2].gsub(INDENT, '')) + if @footnotes[@src[1]] + warning("Duplicate footnote name '#{@src[1]}' on line #{start_line_number} - overwriting") + end + @tree.children << new_block_el(:eob, :footnote_def) + (@footnotes[@src[1]] = {})[:content] = el + @footnotes[@src[1]][:eob] = @tree.children.last + true + end + define_parser(:footnote_definition, FOOTNOTE_DEFINITION_START) + + FOOTNOTE_MARKER_START = /\[\^(#{ALD_ID_NAME})\]/ + + # Parse the footnote marker at the current location. + def parse_footnote_marker + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + fn_def = @footnotes[@src[1]] + if fn_def + if fn_def[:eob] + update_attr_with_ial(fn_def[:eob].attr, fn_def[:eob].options[:ial] || {}) + fn_def[:attr] = fn_def[:eob].attr + fn_def[:options] = fn_def[:eob].options + fn_def.delete(:eob) + end + fn_def[:marker] ||= [] + fn_def[:marker].push(Element.new(:footnote, fn_def[:content], fn_def[:attr], + fn_def[:options].merge(name: @src[1], location: start_line_number))) + @tree.children << fn_def[:marker].last + else + warning("Footnote definition for '#{@src[1]}' not found on line #{start_line_number}") + add_text(@src.matched) + end + end + define_parser(:footnote_marker, FOOTNOTE_MARKER_START, '\[') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/header.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/header.rb new file mode 100644 index 0000000..8424af3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/header.rb @@ -0,0 +1,70 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/block_boundary' +require 'rexml/xmltokens' + +module Kramdown + module Parser + class Kramdown + + SETEXT_HEADER_START = /^#{OPT_SPACE}(?[^ \t].*)\n(?[-=])[-=]*[ \t\r\f\v]*\n/ + + # Parse the Setext header at the current location. + def parse_setext_header + return false unless after_block_boundary? + text, id = parse_header_contents + return false if text.empty? + add_header(@src["level"] == '-' ? 2 : 1, text, id) + true + end + define_parser(:setext_header, SETEXT_HEADER_START) + + ATX_HEADER_START = /^(?\#{1,6})[\t ]*(?[^ \t].*)\n/ + + # Parse the Atx header at the current location. + def parse_atx_header + return false unless after_block_boundary? + text, id = parse_header_contents + text.sub!(/(?#{REXML::XMLTokens::NAME_START_CHAR}#{REXML::XMLTokens::NAME_CHAR}*)}\z/ + + # Returns header text and optional ID. + def parse_header_contents + text = @src["contents"] + text.rstrip! + id_match = HEADER_ID.match(text) + if id_match + id = id_match["id"] + text = text[0...-id_match[0].length] + text.rstrip! + end + [text, id] + end + + def add_header(level, text, id) + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + el = new_block_el(:header, nil, nil, level: level, raw_text: text, location: start_line_number) + add_text(text, el) + el.attr['id'] = id if id + @tree.children << el + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/horizontal_rule.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/horizontal_rule.rb new file mode 100644 index 0000000..f2aa6a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/horizontal_rule.rb @@ -0,0 +1,27 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + HR_START = /^#{OPT_SPACE}(\*|-|_)[ \t]*\1[ \t]*\1(\1|[ \t])*\n/ + + # Parse the horizontal rule at the current location. + def parse_horizontal_rule + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + @tree.children << new_block_el(:hr, nil, nil, location: start_line_number) + true + end + define_parser(:horizontal_rule, HR_START) + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html.rb new file mode 100644 index 0000000..37e6b4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html.rb @@ -0,0 +1,165 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/html' + +module Kramdown + module Parser + class Kramdown + + include Kramdown::Parser::Html::Parser + include Kramdown::Utils::Html + + # Mapping of markdown attribute value to content model. I.e. :raw when "0", :default when "1" + # (use default content model for the HTML element), :span when "span", :block when block and + # for everything else +nil+ is returned. + HTML_MARKDOWN_ATTR_MAP = {"0" => :raw, "1" => :default, "span" => :span, "block" => :block} + + TRAILING_WHITESPACE = /[ \t]*\n/ + + def handle_kramdown_html_tag(el, closed, handle_body) + if @block_ial + el.options[:ial] = @block_ial + @block_ial = nil + end + + content_model = if @tree.type != :html_element || @tree.options[:content_model] != :raw + (@options[:parse_block_html] ? HTML_CONTENT_MODEL[el.value] : :raw) + else + :raw + end + if (val = HTML_MARKDOWN_ATTR_MAP[el.attr.delete('markdown')]) + content_model = (val == :default ? HTML_CONTENT_MODEL[el.value] : val) + end + + @src.scan(TRAILING_WHITESPACE) if content_model == :block + el.options[:content_model] = content_model + el.options[:is_closed] = closed + + if !closed && handle_body + case content_model + when :block + unless parse_blocks(el) + warning("Found no end tag for '#{el.value}' (line #{el.options[:location]}) - auto-closing it") + end + when :span + curpos = @src.pos + if @src.scan_until(/(?=<\/#{el.value}\s*>)/mi) + add_text(extract_string(curpos...@src.pos, @src), el) + @src.scan(HTML_TAG_CLOSE_RE) + else + add_text(@src.rest, el) + @src.terminate + warning("Found no end tag for '#{el.value}' (line #{el.options[:location]}) - auto-closing it") + end + else + parse_raw_html(el) {|iel, ic, ih| handle_kramdown_html_tag(iel, ic, ih) } + end + unless @tree.type == :html_element && @tree.options[:content_model] == :raw + @src.scan(TRAILING_WHITESPACE) + end + end + end + + HTML_BLOCK_START = /^#{OPT_SPACE}<(#{REXML::Parsers::BaseParser::UNAME_STR}|!--|\/)/ + + # Parse the HTML at the current position as block-level HTML. + def parse_block_html + line = @src.current_line_number + if (result = @src.scan(HTML_COMMENT_RE)) + @tree.children << Element.new(:xml_comment, result, nil, category: :block, location: line) + @src.scan(TRAILING_WHITESPACE) + true + elsif @src.check(/^#{OPT_SPACE}#{HTML_TAG_RE}/o) && !HTML_SPAN_ELEMENTS.include?(@src[1].downcase) + @src.pos += @src.matched_size + handle_html_start_tag(line) {|iel, ic, ih| handle_kramdown_html_tag(iel, ic, ih) } + Kramdown::Parser::Html::ElementConverter.convert(@root, @tree.children.last) if @options[:html_to_native] + true + elsif @src.check(/^#{OPT_SPACE}#{HTML_TAG_CLOSE_RE}/o) && !HTML_SPAN_ELEMENTS.include?(@src[1].downcase) + name = @src[1].downcase + + if @tree.type == :html_element && @tree.value == name + @src.pos += @src.matched_size + throw :stop_block_parsing, :found + else + false + end + else + false + end + end + define_parser(:block_html, HTML_BLOCK_START) + + HTML_SPAN_START = /<(#{REXML::Parsers::BaseParser::UNAME_STR}|!--|\/|!\[CDATA\[)/ + + # Parse the HTML at the current position as span-level HTML. + def parse_span_html + line = @src.current_line_number + if (result = @src.scan(HTML_COMMENT_RE)) + @tree.children << Element.new(:xml_comment, result, nil, category: :span, location: line) + elsif @src.scan(HTML_CDATA_RE) + add_text(escape_html(@src[1])) + elsif (result = @src.scan(HTML_TAG_CLOSE_RE)) + warning("Found invalidly used HTML closing tag for '#{@src[1]}' on line #{line}") + add_text(result) + elsif (result = @src.scan(HTML_TAG_RE)) + tag_name = @src[1] + tag_name.downcase! if HTML_ELEMENT[tag_name.downcase] + if HTML_BLOCK_ELEMENTS.include?(tag_name) + warning("Found block HTML tag '#{tag_name}' in span-level text on line #{line}") + add_text(result) + return + end + + attrs = parse_html_attributes(@src[2], line, HTML_ELEMENT[tag_name]) + attrs.each_value {|value| value.gsub!(/\n+/, ' ') unless value.empty? } + + do_parsing = if HTML_CONTENT_MODEL[tag_name] == :raw || @tree.options[:content_model] == :raw + false + else + @options[:parse_span_html] + end + if (val = HTML_MARKDOWN_ATTR_MAP[attrs.delete('markdown')]) + case val + when :block + warning("Cannot use block-level parsing in span-level HTML tag (line #{line}) " \ + "- using default mode") + when :span + do_parsing = true + when :default + do_parsing = HTML_CONTENT_MODEL[tag_name] != :raw + when :raw + do_parsing = false + end + end + + el = Element.new(:html_element, tag_name, attrs, category: :span, location: line, + content_model: (do_parsing ? :span : :raw), is_closed: !@src[4].nil?) + @tree.children << el + stop_re = /<\/#{Regexp.escape(tag_name)}\s*>/ + stop_re = Regexp.new(stop_re.source, Regexp::IGNORECASE) if HTML_ELEMENT[tag_name] + if !@src[4] && !HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) + if parse_spans(el, stop_re, (do_parsing ? nil : [:span_html])) + @src.scan(stop_re) + else + warning("Found no end tag for '#{el.value}' (line #{line}) - auto-closing it") + add_text(@src.rest, el) + @src.terminate + end + end + Kramdown::Parser::Html::ElementConverter.convert(@root, el) if @options[:html_to_native] + else + add_text(@src.getch) + end + end + define_parser(:span_html, HTML_SPAN_START, '<') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html_entity.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html_entity.rb new file mode 100644 index 0000000..dc5e7ad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/html_entity.rb @@ -0,0 +1,34 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/html' + +module Kramdown + module Parser + class Kramdown + + # Parse the HTML entity at the current location. + def parse_html_entity + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + begin + value = ::Kramdown::Utils::Entities.entity(@src[1] || @src[2]&.to_i || @src[3].hex) + @tree.children << Element.new(:entity, value, + nil, original: @src.matched, location: start_line_number) + rescue ::Kramdown::Error + @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp'), + nil, location: start_line_number) + add_text(@src.matched[1..-1]) + end + end + define_parser(:html_entity, Kramdown::Parser::Html::Constants::HTML_ENTITY_RE, '&') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/line_break.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/line_break.rb new file mode 100644 index 0000000..021bb0a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/line_break.rb @@ -0,0 +1,25 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + LINE_BREAK = /( |\\\\)(?=\n)/ + + # Parse the line break at the current location. + def parse_line_break + @tree.children << Element.new(:br, nil, nil, location: @src.current_line_number) + @src.pos += @src.matched_size + end + define_parser(:line_break, LINE_BREAK, '( |\\\\)(?=\n)') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/link.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/link.rb new file mode 100644 index 0000000..f4664f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/link.rb @@ -0,0 +1,149 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/escaped_chars' + +module Kramdown + module Parser + class Kramdown + + # Normalize the link identifier. + def normalize_link_id(id) + id.gsub(/\s+/, ' ').downcase + end + + LINK_DEFINITION_START = /^#{OPT_SPACE}\[([^\n\]]+)\]:[ \t]*(?:<(.*?)>|([^\n]*?\S[^\n]*?))(?:(?:[ \t]*?\n|[ \t]+?)[ \t]*?(["'])(.+?)\4)?[ \t]*?\n/ + + # Parse the link definition at the current location. + def parse_link_definition + return false if @src[3].to_s.match?(/[ \t]+["']/) + @src.pos += @src.matched_size + link_id, link_url, link_title = normalize_link_id(@src[1]), @src[2] || @src[3], @src[5] + if @link_defs[link_id] + warning("Duplicate link ID '#{link_id}' on line #{@src.current_line_number} - overwriting") + end + @tree.children << new_block_el(:eob, :link_def) + @link_defs[link_id] = [link_url, link_title, @tree.children.last] + true + end + define_parser(:link_definition, LINK_DEFINITION_START) + + # This helper methods adds the approriate attributes to the element +el+ of type +a+ or +img+ + # and the element itself to the @tree. + def add_link(el, href, title, alt_text = nil, ial = nil) + el.options[:ial] = ial + update_attr_with_ial(el.attr, ial) if ial + if el.type == :a + el.attr['href'] = href + else + el.attr['src'] = href + el.attr['alt'] = alt_text + el.children.clear + end + el.attr['title'] = title if title + @tree.children << el + end + + LINK_BRACKET_STOP_RE = /(\])|!?\[/ + LINK_PAREN_STOP_RE = /(\()|(\))|\s(?=['"])/ + LINK_INLINE_ID_RE = /\s*?\[([^\]]+)?\]/ + LINK_INLINE_TITLE_RE = /\s*?(["'])(.+?)\1\s*?\)/m + LINK_START = /!?\[(?=[^^])/ + + # Parse the link at the current scanner position. This method is used to parse normal links as + # well as image links. + def parse_link + start_line_number = @src.current_line_number + result = @src.scan(LINK_START) + cur_pos = @src.pos + saved_pos = @src.save_pos + + link_type = (result.match?(/^!/) ? :img : :a) + + # no nested links allowed + if link_type == :a && (@tree.type == :img || @tree.type == :a || + @stack.any? {|t, _| t && (t.type == :img || t.type == :a) }) + add_text(result) + return + end + el = Element.new(link_type, nil, nil, location: start_line_number) + + count = 1 + found = parse_spans(el, LINK_BRACKET_STOP_RE) do + count += (@src[1] ? -1 : 1) + count - el.children.count {|c| c.type == :img } == 0 + end + unless found + @src.revert_pos(saved_pos) + add_text(result) + return + end + alt_text = extract_string(cur_pos...@src.pos, @src).gsub(ESCAPED_CHARS, '\1') + @src.scan(LINK_BRACKET_STOP_RE) + + # reference style link or no link url + if @src.scan(LINK_INLINE_ID_RE) || !@src.check(/\(/) + emit_warning = !@src[1] + link_id = normalize_link_id(@src[1] || alt_text) + if @link_defs.key?(link_id) + link_def = @link_defs[link_id] + add_link(el, link_def[0], link_def[1], alt_text, + link_def[2] && link_def[2].options[:ial]) + else + if emit_warning + warning("No link definition for link ID '#{link_id}' found on line #{start_line_number}") + end + @src.revert_pos(saved_pos) + add_text(result) + end + return + end + + # link url in parentheses + if @src.scan(/\(<(.*?)>/) + link_url = @src[1] + if @src.scan(/\)/) + add_link(el, link_url, nil, alt_text) + return + end + else + link_url = +'' + nr_of_brackets = 0 + while (temp = @src.scan_until(LINK_PAREN_STOP_RE)) + link_url << temp + if @src[2] + nr_of_brackets -= 1 + break if nr_of_brackets == 0 + elsif @src[1] + nr_of_brackets += 1 + else + break + end + end + link_url = link_url[1..-2] + link_url.strip! + + if nr_of_brackets == 0 + add_link(el, link_url, nil, alt_text) + return + end + end + + if @src.scan(LINK_INLINE_TITLE_RE) + add_link(el, link_url, @src[2], alt_text) + else + @src.revert_pos(saved_pos) + add_text(result) + end + end + define_parser(:link, LINK_START, '!?\[') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/list.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/list.rb new file mode 100644 index 0000000..3db5409 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/list.rb @@ -0,0 +1,286 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/blank_line' +require 'kramdown/parser/kramdown/eob' +require 'kramdown/parser/kramdown/horizontal_rule' +require 'kramdown/parser/kramdown/extensions' + +module Kramdown + module Parser + class Kramdown + + LIST_ITEM_IAL = /^\s*(?:\{:(?!(?:#{ALD_ID_NAME})?:|\/)(#{ALD_ANY_CHARS}+)\})\s*/ + LIST_ITEM_IAL_CHECK = /^#{LIST_ITEM_IAL}?\s*\n/ + + PARSE_FIRST_LIST_LINE_REGEXP_CACHE = Hash.new do |h, indentation| + indent_re = /^ {#{indentation}}/ + content_re = /^(?:(?:\t| {4}){#{indentation / 4}} {#{indentation % 4}}|(?:\t| {4}){#{indentation / 4 + 1}}).*\S.*\n/ + lazy_re = /(?!^ {0,#{[indentation, 3].min}}(?:#{IAL_BLOCK}|#{LAZY_END_HTML_STOP}|#{LAZY_END_HTML_START})).*\S.*\n/ + + h[indentation] = [content_re, lazy_re, indent_re] + end + + # Used for parsing the first line of a list item or a definition, i.e. the line with list item + # marker or the definition marker. + def parse_first_list_line(indentation, content) + if content.match?(self.class::LIST_ITEM_IAL_CHECK) + indentation = 4 + else + while content.match?(/^ *\t/) + temp = content.scan(/^ */).first.length + indentation + content.sub!(/^( *)(\t+)/) { $1 << " " * (4 - (temp % 4) + ($2.length - 1) * 4) } + end + indentation += content[/^ */].length + end + content.sub!(/^\s*/, '') + + [content, indentation, *PARSE_FIRST_LIST_LINE_REGEXP_CACHE[indentation]] + end + + PATTERN_TAIL = /[\t| ].*?\n/ + + LIST_START_UL = /^(#{OPT_SPACE}[+*-])(#{PATTERN_TAIL})/ + LIST_START_OL = /^(#{OPT_SPACE}\d+\.)(#{PATTERN_TAIL})/ + LIST_START = /#{LIST_START_UL}|#{LIST_START_OL}/ + + # Parse the ordered or unordered list at the current location. + def parse_list + start_line_number = @src.current_line_number + type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL]) + list = new_block_el(type, nil, nil, location: start_line_number) + + item = nil + content_re, lazy_re, indent_re = nil + eob_found = false + nested_list_found = false + last_is_blank = false + until @src.eos? + start_line_number = @src.current_line_number + if last_is_blank && @src.check(HR_START) + break + elsif @src.scan(EOB_MARKER) + eob_found = true + break + elsif @src.scan(list_start_re) + list.options[:first_list_marker] ||= @src[1].strip + item = Element.new(:li, nil, nil, location: start_line_number) + item.value, indentation, content_re, lazy_re, indent_re = + parse_first_list_line(@src[1].length, @src[2]) + list.children << item + + item.value.sub!(self.class::LIST_ITEM_IAL) do + parse_attribute_list($1, item.options[:ial] ||= {}) + '' + end + + list_start_re = fetch_pattern(type, indentation) + nested_list_found = (item.value =~ LIST_START) + last_is_blank = false + item.value = [item.value] + elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re))) + result.sub!(/^(\t+)/) { " " * 4 * $1.length } + indentation_found = result.sub!(indent_re, '') + if !nested_list_found && indentation_found && result =~ LIST_START + item.value << +'' + nested_list_found = true + elsif nested_list_found && !indentation_found && result =~ LIST_START + result = " " * (indentation + 4) << result + end + item.value.last << result + last_is_blank = false + elsif (result = @src.scan(BLANK_LINE)) + nested_list_found = true + last_is_blank = true + item.value.last << result + else + break + end + end + + @tree.children << list + + last = nil + list.children.each do |it| + temp = Element.new(:temp, nil, nil, location: it.options[:location]) + + env = save_env + location = it.options[:location] + it.value.each do |val| + @src = ::Kramdown::Utils::StringScanner.new(val, location) + parse_blocks(temp) + location = @src.current_line_number + end + restore_env(env) + + it.children = temp.children + it.value = nil + + it_children = it.children + next if it_children.empty? + + # Handle the case where an EOB marker is inserted by a block IAL for the first paragraph + it_children.delete_at(1) if it_children.first.type == :p && + it_children.length >= 2 && it_children[1].type == :eob && it_children.first.options[:ial] + + if it_children.first.type == :p && + (it_children.length < 2 || it_children[1].type != :blank || + (it == list.children.last && it_children.length == 2 && !eob_found)) && + (list.children.last != it || list.children.size == 1 || + list.children[0..-2].any? {|cit| !cit.children.first || cit.children.first.type != :p || cit.children.first.options[:transparent] }) + it_children.first.children.first.value << "\n" if it_children.size > 1 && it_children[1].type != :blank + it_children.first.options[:transparent] = true + end + + last = (it_children.last.type == :blank ? it_children.pop : nil) + end + + @tree.children << last if !last.nil? && !eob_found + + true + end + define_parser(:list, LIST_START) + + DEFINITION_LIST_START = /^(#{OPT_SPACE}:)(#{PATTERN_TAIL})/ + + # Parse the ordered or unordered list at the current location. + def parse_definition_list + children = @tree.children + if !children.last || (children.length == 1 && children.last.type != :p) || + (children.length >= 2 && children[-1].type != :p && + (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p)) + return false + end + + first_as_para = false + deflist = new_block_el(:dl) + para = @tree.children.pop + if para.type == :blank + para = @tree.children.pop + first_as_para = true + end + # take location from preceding para which is the first definition term + deflist.options[:location] = para.options[:location] + para.children.first.value.split("\n").each do |term| + el = Element.new(:dt, nil, nil, location: @src.current_line_number) + term.sub!(self.class::LIST_ITEM_IAL) do + parse_attribute_list($1, el.options[:ial] ||= {}) + '' + end + el.options[:raw_text] = term + el.children << Element.new(:raw_text, term) + deflist.children << el + end + deflist.options[:ial] = para.options[:ial] + + item = nil + content_re, lazy_re, indent_re = nil + def_start_re = DEFINITION_LIST_START + last_is_blank = false + until @src.eos? + start_line_number = @src.current_line_number + if @src.scan(def_start_re) + item = Element.new(:dd, nil, nil, location: start_line_number) + item.options[:first_as_para] = first_as_para + item.value, indentation, content_re, lazy_re, indent_re = + parse_first_list_line(@src[1].length, @src[2]) + deflist.children << item + + item.value.sub!(self.class::LIST_ITEM_IAL) do |_match| + parse_attribute_list($1, item.options[:ial] ||= {}) + '' + end + + def_start_re = fetch_pattern(:dl, indentation) + first_as_para = false + last_is_blank = false + elsif @src.check(EOB_MARKER) + break + elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re))) + result.sub!(/^(\t+)/) { " " * ($1 ? 4 * $1.length : 0) } + result.sub!(indent_re, '') + item.value << result + first_as_para = false + last_is_blank = false + elsif (result = @src.scan(BLANK_LINE)) + first_as_para = true + item.value << result + last_is_blank = true + else + break + end + end + + last = nil + deflist.children.each do |it| + next if it.type == :dt + + parse_blocks(it, it.value) + it.value = nil + it_children = it.children + next if it_children.empty? + + last = (it_children.last.type == :blank ? it_children.pop : nil) + + if it_children.first && it_children.first.type == :p && !it.options.delete(:first_as_para) + it_children.first.children.first.value << "\n" if it_children.size > 1 + it_children.first.options[:transparent] = true + end + end + + children = @tree.children + if children.length >= 1 && children.last.type == :dl + children[-1].children.concat(deflist.children) + elsif children.length >= 2 && children[-1].type == :blank && + children[-2].type == :dl + children.pop + children[-1].children.concat(deflist.children) + else + children << deflist + end + + children << last if last + + true + end + define_parser(:definition_list, DEFINITION_LIST_START) + + private + + # precomputed patterns for indentations 1..4 and fallback expression + # to compute pattern when indentation is outside the 1..4 range. + def fetch_pattern(type, indentation) + case type + when :ul + case indentation + when 1 then /^( {0}[+*-])(#{PATTERN_TAIL})/o + when 2 then /^( {0,1}[+*-])(#{PATTERN_TAIL})/o + when 3 then /^( {0,2}[+*-])(#{PATTERN_TAIL})/o + else /^( {0,3}[+*-])(#{PATTERN_TAIL})/o + end + when :ol + case indentation + when 1 then /^( {0}\d+\.)(#{PATTERN_TAIL})/o + when 2 then /^( {0,1}\d+\.)(#{PATTERN_TAIL})/o + when 3 then /^( {0,2}\d+\.)(#{PATTERN_TAIL})/o + else /^( {0,3}\d+\.)(#{PATTERN_TAIL})/o + end + when :dl + case indentation + when 1 then /^( {0}:)(#{PATTERN_TAIL})/o + when 2 then /^( {0,1}:)(#{PATTERN_TAIL})/o + when 3 then /^( {0,2}:)(#{PATTERN_TAIL})/o + else /^( {0,3}:)(#{PATTERN_TAIL})/o + end + end + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/math.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/math.rb new file mode 100644 index 0000000..7812292 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/math.rb @@ -0,0 +1,53 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/block_boundary' + +module Kramdown + module Parser + class Kramdown + + BLOCK_MATH_START = /^#{OPT_SPACE}(\\)?\$\$(.*?)\$\$(\s*?\n)?/m + + # Parse the math block at the current location. + def parse_block_math + start_line_number = @src.current_line_number + if !after_block_boundary? + return false + elsif @src[1] + @src.scan(/^#{OPT_SPACE}\\/o) if @src[3] + return false + end + + saved_pos = @src.save_pos + @src.pos += @src.matched_size + data = @src[2].strip + if before_block_boundary? + @tree.children << new_block_el(:math, data, nil, category: :block, location: start_line_number) + true + else + @src.revert_pos(saved_pos) + false + end + end + define_parser(:block_math, BLOCK_MATH_START) + + INLINE_MATH_START = /\$\$(.*?)\$\$/m + + # Parse the inline math at the current location. + def parse_inline_math + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + @tree.children << Element.new(:math, @src[1].strip, nil, category: :span, location: start_line_number) + end + define_parser(:inline_math, INLINE_MATH_START, '\$') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/paragraph.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/paragraph.rb new file mode 100644 index 0000000..f6af5ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/paragraph.rb @@ -0,0 +1,62 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/blank_line' +require 'kramdown/parser/kramdown/extensions' +require 'kramdown/parser/kramdown/eob' +require 'kramdown/parser/kramdown/list' +require 'kramdown/parser/kramdown/html' + +module Kramdown + module Parser + class Kramdown + + LAZY_END_HTML_SPAN_ELEMENTS = HTML_SPAN_ELEMENTS + %w[script] + LAZY_END_HTML_START = /<(?>(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR})/ + LAZY_END_HTML_STOP = /<\/(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR}\s*>/m + + LAZY_END = /#{BLANK_LINE}|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/ + + PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/ + PARAGRAPH_MATCH = /^.*?\n/ + PARAGRAPH_END = /#{LAZY_END}|#{DEFINITION_LIST_START}/ + + # Parse the paragraph at the current location. + def parse_paragraph + pos = @src.pos + start_line_number = @src.current_line_number + result = @src.scan(PARAGRAPH_MATCH) + until @src.match?(paragraph_end) + result << @src.scan(PARAGRAPH_MATCH) + end + result.rstrip! + if (last_child = @tree.children.last) && last_child.type == :p + last_item_in_para = last_child.children.last + if last_item_in_para && last_item_in_para.type == @text_type + joiner = (extract_string((pos - 3)...pos, @src) == " \n" ? " \n" : "\n") + last_item_in_para.value << joiner << result + else + add_text(result, last_child) + end + else + @tree.children << new_block_el(:p, nil, nil, location: start_line_number) + result.lstrip! + add_text(result, @tree.children.last) + end + true + end + define_parser(:paragraph, PARAGRAPH_START) + + def paragraph_end + self.class::PARAGRAPH_END + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/smart_quotes.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/smart_quotes.rb new file mode 100644 index 0000000..3a9026a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/smart_quotes.rb @@ -0,0 +1,174 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# +#-- +# Parts of this file are based on code from RubyPants: +# +# = RubyPants -- SmartyPants ported to Ruby +# +# Ported by Christian Neukirchen +# Copyright (C) 2004 Christian Neukirchen +# +# Incooporates ideas, comments and documentation by Chad Miller +# Copyright (C) 2004 Chad Miller +# +# Original SmartyPants by John Gruber +# Copyright (C) 2003 John Gruber +# +# +# = RubyPants -- SmartyPants ported to Ruby +# +# +# [snip] +# +# == Authors +# +# John Gruber did all of the hard work of writing this software in +# Perl for Movable Type and almost all of this useful documentation. +# Chad Miller ported it to Python to use with Pyblosxom. +# +# Christian Neukirchen provided the Ruby port, as a general-purpose +# library that follows the *Cloth API. +# +# +# == Copyright and License +# +# === SmartyPants license: +# +# Copyright (c) 2003 John Gruber +# (http://daringfireball.net) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name "SmartyPants" nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# This software is provided by the copyright holders and contributors +# "as is" and any express or implied warranties, including, but not +# limited to, the implied warranties of merchantability and fitness +# for a particular purpose are disclaimed. In no event shall the +# copyright owner or contributors be liable for any direct, indirect, +# incidental, special, exemplary, or consequential damages (including, +# but not limited to, procurement of substitute goods or services; +# loss of use, data, or profits; or business interruption) however +# caused and on any theory of liability, whether in contract, strict +# liability, or tort (including negligence or otherwise) arising in +# any way out of the use of this software, even if advised of the +# possibility of such damage. +# +# === RubyPants license +# +# RubyPants is a derivative work of SmartyPants and smartypants.py. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# This software is provided by the copyright holders and contributors +# "as is" and any express or implied warranties, including, but not +# limited to, the implied warranties of merchantability and fitness +# for a particular purpose are disclaimed. In no event shall the +# copyright owner or contributors be liable for any direct, indirect, +# incidental, special, exemplary, or consequential damages (including, +# but not limited to, procurement of substitute goods or services; +# loss of use, data, or profits; or business interruption) however +# caused and on any theory of liability, whether in contract, strict +# liability, or tort (including negligence or otherwise) arising in +# any way out of the use of this software, even if advised of the +# possibility of such damage. +# +# == Links +# +# John Gruber:: http://daringfireball.net +# SmartyPants:: http://daringfireball.net/projects/smartypants +# +# Chad Miller:: http://web.chad.org +# +# Christian Neukirchen:: http://kronavita.de/chris +# +#++ +# + +module Kramdown + module Parser + class Kramdown + + SQ_PUNCT = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]' + SQ_CLOSE = %![^ \\\\\t\r\n\\[{(-]! + + SQ_RULES = [ + [/("|')(?=[_*]{1,2}\S)/, [:lquote1]], + [/("|')(?=#{SQ_PUNCT}(?!\.\.)\B)/, [:rquote1]], + # Special case for double sets of quotes, e.g.: + #

He said, "'Quoted' words in a larger quote."

+ [/(\s?)"'(?=\w)/, [1, :ldquo, :lsquo]], + [/(\s?)'"(?=\w)/, [1, :lsquo, :ldquo]], + # Special case for decade abbreviations (the '80s): + [/(\s?)'(?=\d\ds)/, [1, :rsquo]], + + # Get most opening single/double quotes: + [/(\s)('|")(?=\w)/, [1, :lquote2]], + # Single/double closing quotes: + [/(#{SQ_CLOSE})('|")/, [1, :rquote2]], + # Special case for e.g. "Custer's Last Stand." + [/("|')(?=\s|s\b|$)/, [:rquote1]], + # Any remaining single quotes should be opening ones: + [/(.?)'/m, [1, :lsquo]], + [/(.?)"/m, [1, :ldquo]], + ] # '" + + SQ_SUBSTS = { + [:rquote1, '"'] => :rdquo, + [:rquote1, "'"] => :rsquo, + [:rquote2, '"'] => :rdquo, + [:rquote2, "'"] => :rsquo, + [:lquote1, '"'] => :ldquo, + [:lquote1, "'"] => :lsquo, + [:lquote2, '"'] => :ldquo, + [:lquote2, "'"] => :lsquo, + } + SMART_QUOTES_RE = /[^\\]?["']/ + + # Parse the smart quotes at current location. + def parse_smart_quotes + start_line_number = @src.current_line_number + substs = SQ_RULES.find {|reg, _subst| @src.scan(reg) }[1] + substs.each do |subst| + if subst.kind_of?(Integer) + add_text(@src[subst]) + else + val = SQ_SUBSTS[[subst, @src[subst.to_s[-1, 1].to_i]]] || subst + @tree.children << Element.new(:smart_quote, val, nil, location: start_line_number) + end + end + end + define_parser(:smart_quotes, SMART_QUOTES_RE, '[^\\\\]?["\']') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/table.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/table.rb new file mode 100644 index 0000000..53103ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/table.rb @@ -0,0 +1,171 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser/kramdown/block_boundary' + +module Kramdown + module Parser + class Kramdown + + TABLE_SEP_LINE = /^([+|: \t-]*?-[+|: \t-]*?)[ \t]*\n/ + TABLE_HSEP_ALIGN = /[ \t]?(:?)-+(:?)[ \t]?/ + TABLE_FSEP_LINE = /^[+|: \t=]*?=[+|: \t=]*?[ \t]*\n/ + TABLE_ROW_LINE = /^(.*?)[ \t]*\n/ + TABLE_PIPE_CHECK = /(?:\||.*?[^\\\n]\|)/ + TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\n/ + TABLE_START = /^#{OPT_SPACE}(?=\S)#{TABLE_LINE}/ + + # Parse the table at the current location. + def parse_table + return false unless after_block_boundary? + + saved_pos = @src.save_pos + orig_pos = @src.pos + table = new_block_el(:table, nil, nil, alignment: [], location: @src.current_line_number) + leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/) + @src.scan(TABLE_SEP_LINE) + + rows = [] + has_footer = false + columns = 0 + + add_container = lambda do |type, force| + if !has_footer || type != :tbody || force + cont = Element.new(type) + cont.children, rows = rows, [] + table.children << cont + end + end + + until @src.eos? + break unless @src.check(TABLE_LINE) + if @src.scan(TABLE_SEP_LINE) + if rows.empty? + # nothing to do, ignoring multiple consecutive separator lines + elsif table.options[:alignment].empty? && !has_footer + add_container.call(:thead, false) + table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right| + (left.empty? && right.empty? && :default) || (right.empty? && :left) || + (left.empty? && :right) || :center + end + else # treat as normal separator line + add_container.call(:tbody, false) + end + elsif @src.scan(TABLE_FSEP_LINE) + add_container.call(:tbody, true) unless rows.empty? + has_footer = true + elsif @src.scan(TABLE_ROW_LINE) + trow = Element.new(:tr) + + # parse possible code spans on the line and correctly split the line into cells + env = save_env + cells = [] + @src[1].split(/(.*?<\/code>)/).each_with_index do |str, i| + if i.odd? + (cells.empty? ? cells : cells.last) << str + else + reset_env(src: Kramdown::Utils::StringScanner.new(str, @src.current_line_number)) + root = Element.new(:root) + parse_spans(root, nil, [:codespan]) + + root.children.each do |c| + if c.type == :raw_text + f, *l = c.value.split(/(? 1}#{c.value}#{' ' if delim.size > 1}#{delim}" + (cells.empty? ? cells : cells.last) << tmp + end + end + end + end + restore_env(env) + + cells.shift if leading_pipe && cells.first.strip.empty? + cells.pop if cells.last.strip.empty? + cells.each do |cell_text| + tcell = Element.new(:td) + tcell.children << Element.new(:raw_text, cell_text.strip) + trow.children << tcell + end + columns = [columns, cells.length].max + rows << trow + else + break + end + end + + unless before_block_boundary? + @src.revert_pos(saved_pos) + return false + end + + # Parse all lines of the table with the code span parser + env = save_env + l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos - 1), @src), + @src.current_line_number) + reset_env(src: l_src) + root = Element.new(:root) + parse_spans(root, nil, [:codespan, :span_html]) + restore_env(env) + + # Check if each line has at least one unescaped pipe that is not inside a code span/code + # HTML element + # Note: It doesn't matter that we parse *all* span HTML elements because the row splitting + # algorithm above only takes elements into account! + pipe_on_line = false + while (c = root.children.shift) + next unless (lines = c.value) + lines = lines.split("\n") + if c.type == :codespan + if lines.size > 2 || (lines.size == 2 && !pipe_on_line) + break + elsif lines.size == 2 && pipe_on_line + pipe_on_line = false + end + else + break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/o + pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/o) + end + end + @src.revert_pos(saved_pos) and return false unless pipe_on_line + + add_container.call(has_footer ? :tfoot : :tbody, false) unless rows.empty? + + if table.children.none? {|el| el.type == :tbody } + warning("Found table without body on line #{table.options[:location]} - ignoring it") + @src.revert_pos(saved_pos) + return false + end + + # adjust all table rows to have equal number of columns, same for alignment defs + table.children.each do |kind| + kind.children.each do |row| + (columns - row.children.length).times do + row.children << Element.new(:td) + end + end + end + if table.options[:alignment].length > columns + table.options[:alignment] = table.options[:alignment][0...columns] + else + table.options[:alignment] += [:default] * (columns - table.options[:alignment].length) + end + + @tree.children << table + + true + end + define_parser(:table, TABLE_START) + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/typographic_symbol.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/typographic_symbol.rb new file mode 100644 index 0000000..d8bbc63 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/kramdown/typographic_symbol.rb @@ -0,0 +1,44 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Parser + class Kramdown + + TYPOGRAPHIC_SYMS = [['---', :mdash], ['--', :ndash], ['...', :hellip], + ['\\<<', '<<'], ['\\>>', '>>'], + ['<< ', :laquo_space], [' >>', :raquo_space], + ['<<', :laquo], ['>>', :raquo]] + TYPOGRAPHIC_SYMS_SUBST = Hash[*TYPOGRAPHIC_SYMS.flatten] + TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k, _v| Regexp.escape(k) }.join('|')}/ + + # Parse the typographic symbols at the current location. + def parse_typographic_syms + start_line_number = @src.current_line_number + @src.pos += @src.matched_size + val = TYPOGRAPHIC_SYMS_SUBST[@src.matched] + if val.kind_of?(Symbol) + @tree.children << Element.new(:typographic_sym, val, nil, location: start_line_number) + elsif @src.matched == '\\<<' + @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'), + nil, location: start_line_number) + @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'), + nil, location: start_line_number) + else + @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'), + nil, location: start_line_number) + @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'), + nil, location: start_line_number) + end + end + define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE, '--|\\.\\.\\.|(?:\\\\| )?(?:<<|>>)') + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/markdown.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/markdown.rb new file mode 100644 index 0000000..8902029 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/parser/markdown.rb @@ -0,0 +1,57 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'kramdown/parser' + +module Kramdown + + module Parser + + # Used for parsing a document in Markdown format. + # + # This parser is based on the kramdown parser and removes the parser methods for the additional + # non-Markdown features. However, since some things are handled differently by the kramdown + # parser methods (like deciding when a list item contains just text), this parser differs from + # real Markdown parsers in some respects. + # + # Note, though, that the parser basically fails just one of the Markdown test cases (some others + # also fail but those failures are negligible). + class Markdown < Kramdown + + # Array with all the parsing methods that should be removed from the standard kramdown parser. + EXTENDED = [:codeblock_fenced, :table, :definition_list, :footnote_definition, + :abbrev_definition, :block_math, :block_extensions, + :footnote_marker, :smart_quotes, :inline_math, :span_extensions, :typographic_syms] + + def initialize(source, options) # :nodoc: + super + @block_parsers.delete_if {|i| EXTENDED.include?(i) } + @span_parsers.delete_if {|i| EXTENDED.include?(i) } + end + + # :stopdoc: + + BLOCK_BOUNDARY = /#{BLANK_LINE}|#{EOB_MARKER}|\Z/ + LAZY_END = /#{BLANK_LINE}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}| + ^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/x + CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+)*/ + PARAGRAPH_END = LAZY_END + + IAL_RAND_CHARS = (('a'..'z').to_a + ('0'..'9').to_a) + IAL_RAND_STRING = (1..20).collect { IAL_RAND_CHARS[rand(IAL_RAND_CHARS.size)] }.join + LIST_ITEM_IAL = /^\s*(#{IAL_RAND_STRING})?\s*\n/ + IAL_SPAN_START = LIST_ITEM_IAL + + # :startdoc: + + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils.rb new file mode 100644 index 0000000..b63894d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils.rb @@ -0,0 +1,45 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + + # == \Utils Module + # + # This module contains utility class/modules/methods that can be used by both parsers and + # converters. + module Utils + + autoload :Entities, 'kramdown/utils/entities' + autoload :Html, 'kramdown/utils/html' + autoload :Unidecoder, 'kramdown/utils/unidecoder' + autoload :StringScanner, 'kramdown/utils/string_scanner' + autoload :Configurable, 'kramdown/utils/configurable' + autoload :LRUCache, 'kramdown/utils/lru_cache' + + # Treat +name+ as if it were snake cased (e.g. snake_case) and camelize it (e.g. SnakeCase). + def self.camelize(name) + name.split('_').inject(+'') {|s, x| s << x[0..0].upcase << x[1..-1] } + end + + # Treat +name+ as if it were camelized (e.g. CamelizedName) and snake-case it (e.g. camelized_name). + def self.snake_case(name) + name = name.dup + name.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2') + name.gsub!(/([a-z])([A-Z])/, '\1_\2') + name.downcase! + name + end + + def self.deep_const_get(str) + ::Object.const_get(str) + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/configurable.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/configurable.rb new file mode 100644 index 0000000..d334f46 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/configurable.rb @@ -0,0 +1,45 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Utils + + # Methods for registering configurable extensions. + module Configurable + + # Create a new configurable extension called +name+. + # + # Three methods will be defined on the calling object which allow to use this configurable + # extension: + # + # configurables:: Returns a hash of hashes that is used to store all configurables of the + # object. + # + # (ext_name):: Return the configured extension +ext_name+. + # + # add_(ext_name, data=nil, &block):: Define an extension +ext_name+ by specifying either + # the data as argument or by using a block. + def configurable(name) + unless respond_to?(:configurables) + singleton_class.send(:define_method, :configurables) do + @_configurables ||= Hash.new {|h, k| h[k] = {} } + end + end + singleton_class.send(:define_method, name) do |data| + configurables[name][data] + end + singleton_class.send(:define_method, "add_#{name}".intern) do |data, *args, &block| + configurables[name][data] = args.first || block + end + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/entities.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/entities.rb new file mode 100644 index 0000000..4086fd2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/entities.rb @@ -0,0 +1,1000 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + + module Utils + + # Provides convenience methods for handling named and numeric entities. + module Entities + + # Represents an entity that has a +code_point+ and +name+. + Entity = Struct.new(:code_point, :name) do + # Return the UTF8 representation of the entity. + def char + [code_point].pack('U*') rescue nil + end + end + + # Array of arrays. Each sub-array specifies a code point and the associated name. + # + # This table is not used directly -- Entity objects are automatically created from it and put + # into a Hash map when this file is loaded. + ENTITY_TABLE = [ + + # html4 + [913, 'Alpha'], + [914, 'Beta'], + [915, 'Gamma'], + [916, 'Delta'], + [917, 'Epsilon'], + [918, 'Zeta'], + [919, 'Eta'], + [920, 'Theta'], + [921, 'Iota'], + [922, 'Kappa'], + [923, 'Lambda'], + [924, 'Mu'], + [925, 'Nu'], + [926, 'Xi'], + [927, 'Omicron'], + [928, 'Pi'], + [929, 'Rho'], + [931, 'Sigma'], + [932, 'Tau'], + [933, 'Upsilon'], + [934, 'Phi'], + [935, 'Chi'], + [936, 'Psi'], + [937, 'Omega'], + [945, 'alpha'], + [946, 'beta'], + [947, 'gamma'], + [948, 'delta'], + [949, 'epsilon'], + [950, 'zeta'], + [951, 'eta'], + [952, 'theta'], + [953, 'iota'], + [954, 'kappa'], + [955, 'lambda'], + [956, 'mu'], + [957, 'nu'], + [958, 'xi'], + [959, 'omicron'], + [960, 'pi'], + [961, 'rho'], + [963, 'sigma'], + [964, 'tau'], + [965, 'upsilon'], + [966, 'phi'], + [967, 'chi'], + [968, 'psi'], + [969, 'omega'], + [962, 'sigmaf'], + [977, 'thetasym'], + [978, 'upsih'], + [982, 'piv'], + [988, 'Gammad'], + [989, 'gammad'], + [8204, 'zwnj'], + [8205, 'zwj'], + [8206, 'lrm'], + [8207, 'rlm'], + [8230, 'hellip'], + [8242, 'prime'], + [8243, 'Prime'], + [8254, 'oline'], + [8260, 'frasl'], + [8472, 'weierp'], + [8465, 'image'], + [8476, 'real'], + [8501, 'alefsym'], + [8226, 'bull'], + [8482, 'trade'], + [8592, 'larr'], + [8594, 'rarr'], + [8593, 'uarr'], + [8595, 'darr'], + [8596, 'harr'], + [8629, 'crarr'], + [8657, 'uArr'], + [8659, 'dArr'], + [8656, 'lArr'], + [8658, 'rArr'], + [8660, 'hArr'], + [8704, 'forall'], + [8706, 'part'], + [8707, 'exist'], + [8709, 'empty'], + [8711, 'nabla'], + [8712, 'isin'], + [8715, 'ni'], + [8713, 'notin'], + [8721, 'sum'], + [8719, 'prod'], + [8722, 'minus'], + [8727, 'lowast'], + [8730, 'radic'], + [8733, 'prop'], + [8734, 'infin'], + [8736, 'ang'], + [8743, 'and'], + [8744, 'or'], + [8745, 'cap'], + [8746, 'cup'], + [8747, 'int'], + [8756, 'there4'], + [8764, 'sim'], + [8776, 'asymp'], + [8773, 'cong'], + [8800, 'ne'], + [8801, 'equiv'], + [8804, 'le'], + [8805, 'ge'], + [8834, 'sub'], + [8835, 'sup'], + [8838, 'sube'], + [8839, 'supe'], + [8836, 'nsub'], + [8853, 'oplus'], + [8855, 'otimes'], + [8869, 'perp'], + [8901, 'sdot'], + [8942, 'vellip'], + [8968, 'rceil'], + [8969, 'lceil'], + [8970, 'lfloor'], + [8971, 'rfloor'], + [9001, 'rang'], + [9002, 'lang'], + [9674, 'loz'], + [9824, 'spades'], + [9827, 'clubs'], + [9829, 'hearts'], + [9830, 'diams'], + [38, 'amp'], + [34, 'quot'], + [39, 'apos'], + [169, 'copy'], + [60, 'lt'], + [62, 'gt'], + [338, 'OElig'], + [339, 'oelig'], + [352, 'Scaron'], + [353, 'scaron'], + [376, 'Yuml'], + [710, 'circ'], + [732, 'tilde'], + [8211, 'ndash'], + [8212, 'mdash'], + [8216, 'lsquo'], + [8217, 'rsquo'], + [8220, 'ldquo'], + [8221, 'rdquo'], + [8224, 'dagger'], + [8225, 'Dagger'], + [8240, 'permil'], + [8364, 'euro'], + [8249, 'lsaquo'], + [8250, 'rsaquo'], + [160, 'nbsp'], + [161, 'iexcl'], + [163, 'pound'], + [164, 'curren'], + [165, 'yen'], + [166, 'brvbar'], + [167, 'sect'], + [168, 'uml'], + [171, 'laquo'], + [187, 'raquo'], + [174, 'reg'], + [170, 'ordf'], + [172, 'not'], + [173, 'shy'], + [175, 'macr'], + [176, 'deg'], + [177, 'plusmn'], + [180, 'acute'], + [181, 'micro'], + [182, 'para'], + [183, 'middot'], + [184, 'cedil'], + [186, 'ordm'], + [162, 'cent'], + [185, 'sup1'], + [178, 'sup2'], + [179, 'sup3'], + [189, 'frac12'], + [188, 'frac14'], + [190, 'frac34'], + [8531, 'frac13'], + [8532, 'frac23'], + [8533, 'frac15'], + [8534, 'frac25'], + [8535, 'frac35'], + [8536, 'frac45'], + [8537, 'frac16'], + [8538, 'frac56'], + [8539, 'frac18'], + [8540, 'frac38'], + [8541, 'frac58'], + [8542, 'frac78'], + [191, 'iquest'], + [192, 'Agrave'], + [193, 'Aacute'], + [194, 'Acirc'], + [195, 'Atilde'], + [196, 'Auml'], + [197, 'Aring'], + [198, 'AElig'], + [199, 'Ccedil'], + [200, 'Egrave'], + [201, 'Eacute'], + [202, 'Ecirc'], + [203, 'Euml'], + [204, 'Igrave'], + [205, 'Iacute'], + [206, 'Icirc'], + [207, 'Iuml'], + [208, 'ETH'], + [209, 'Ntilde'], + [210, 'Ograve'], + [211, 'Oacute'], + [212, 'Ocirc'], + [213, 'Otilde'], + [214, 'Ouml'], + [215, 'times'], + [216, 'Oslash'], + [217, 'Ugrave'], + [218, 'Uacute'], + [219, 'Ucirc'], + [220, 'Uuml'], + [221, 'Yacute'], + [222, 'THORN'], + [223, 'szlig'], + [224, 'agrave'], + [225, 'aacute'], + [226, 'acirc'], + [227, 'atilde'], + [228, 'auml'], + [229, 'aring'], + [230, 'aelig'], + [231, 'ccedil'], + [232, 'egrave'], + [233, 'eacute'], + [234, 'ecirc'], + [235, 'euml'], + [236, 'igrave'], + [237, 'iacute'], + [238, 'icirc'], + [239, 'iuml'], + [240, 'eth'], + [241, 'ntilde'], + [242, 'ograve'], + [243, 'oacute'], + [244, 'ocirc'], + [245, 'otilde'], + [246, 'ouml'], + [247, 'divide'], + [248, 'oslash'], + [249, 'ugrave'], + [250, 'uacute'], + [251, 'ucirc'], + [252, 'uuml'], + [253, 'yacute'], + [254, 'thorn'], + [255, 'yuml'], + + [8218, 'sbquo'], + [402, 'fnof'], + [8222, 'bdquo'], + + [128, 8364], + [130, 8218], + [131, 402], + [132, 8222], + [133, 8230], + [134, 8224], + [135, 8225], + [136, 710], + [137, 8240], + [138, 352], + [139, 8249], + [140, 338], + [142, 381], + [145, 8216], + [146, 8217], + [147, 8220], + [148, 8221], + [149, 8226], + [150, 8211], + [151, 8212], + [152, 732], + [153, 8482], + [154, 353], + [155, 8250], + [156, 339], + [158, 382], + [159, 376], + + [8194, 'ensp'], + [8195, 'emsp'], + [8201, 'thinsp'], + + # html5 + [10218, 'Lang'], + [10219, 'Rang'], + [10220, 'loang'], + [10221, 'roang'], + [10229, 'xlarr'], + [10229, 'longleftarrow'], + [10229, 'LongLeftArrow'], + [10230, 'xrarr'], + [10230, 'longrightarrow'], + [10230, 'LongRightArrow'], + [10231, 'xharr'], + [10231, 'longleftrightarrow'], + [10231, 'LongLeftRightArrow'], + [10232, 'xlArr'], + [10232, 'Longleftarrow'], + [10232, 'DoubleLongLeftArrow'], + [10233, 'xrArr'], + [10233, 'Longrightarrow'], + [10233, 'DoubleLongRightArrow'], + [10234, 'xhArr'], + [10234, 'Longleftrightarrow'], + [10234, 'DoubleLongLeftRightArrow'], + [10236, 'xmap'], + [10236, 'longmapsto'], + [10239, 'dzigrarr'], + [10498, 'nvlArr'], + [10499, 'nvrArr'], + [10500, 'nvHarr'], + [10501, 'Map'], + [10508, 'lbarr'], + [10509, 'rbarr'], + [10509, 'bkarow'], + [10510, 'lBarr'], + [10511, 'rBarr'], + [10511, 'dbkarow'], + [10512, 'RBarr'], + [10512, 'drbkarow'], + [10513, 'DDotrahd'], + [10514, 'UpArrowBar'], + [10515, 'DownArrowBar'], + [10518, 'Rarrtl'], + [10521, 'latail'], + [10522, 'ratail'], + [10523, 'lAtail'], + [10524, 'rAtail'], + [10525, 'larrfs'], + [10526, 'rarrfs'], + [10527, 'larrbfs'], + [10528, 'rarrbfs'], + [10531, 'nwarhk'], + [10532, 'nearhk'], + [10533, 'searhk'], + [10533, 'hksearow'], + [10534, 'swarhk'], + [10534, 'hkswarow'], + [10535, 'nwnear'], + [10536, 'nesear'], + [10536, 'toea'], + [10537, 'seswar'], + [10537, 'tosa'], + [10538, 'swnwar'], + [10547, 'rarrc'], + [10549, 'cudarrr'], + [10550, 'ldca'], + [10551, 'rdca'], + [10552, 'cudarrl'], + [10553, 'larrpl'], + [10556, 'curarrm'], + [10557, 'cularrp'], + [10565, 'rarrpl'], + [10568, 'harrcir'], + [10569, 'Uarrocir'], + [10570, 'lurdshar'], + [10571, 'ldrushar'], + [10574, 'LeftRightVector'], + [10575, 'RightUpDownVector'], + [10576, 'DownLeftRightVector'], + [10577, 'LeftUpDownVector'], + [10578, 'LeftVectorBar'], + [10579, 'RightVectorBar'], + [10580, 'RightUpVectorBar'], + [10581, 'RightDownVectorBar'], + [10582, 'DownLeftVectorBar'], + [10583, 'DownRightVectorBar'], + [10584, 'LeftUpVectorBar'], + [10585, 'LeftDownVectorBar'], + [10586, 'LeftTeeVector'], + [10587, 'RightTeeVector'], + [10588, 'RightUpTeeVector'], + [10589, 'RightDownTeeVector'], + [10590, 'DownLeftTeeVector'], + [10591, 'DownRightTeeVector'], + [10592, 'LeftUpTeeVector'], + [10593, 'LeftDownTeeVector'], + [10594, 'lHar'], + [10595, 'uHar'], + [10596, 'rHar'], + [10597, 'dHar'], + [10598, 'luruhar'], + [10599, 'ldrdhar'], + [10600, 'ruluhar'], + [10601, 'rdldhar'], + [10602, 'lharul'], + [10603, 'llhard'], + [10604, 'rharul'], + [10605, 'lrhard'], + [10606, 'udhar'], + [10606, 'UpEquilibrium'], + [10607, 'duhar'], + [10607, 'ReverseUpEquilibrium'], + [10608, 'RoundImplies'], + [10609, 'erarr'], + [10610, 'simrarr'], + [10611, 'larrsim'], + [10612, 'rarrsim'], + [10613, 'rarrap'], + [10614, 'ltlarr'], + [10616, 'gtrarr'], + [10617, 'subrarr'], + [10619, 'suplarr'], + [10620, 'lfisht'], + [10621, 'rfisht'], + [10622, 'ufisht'], + [10623, 'dfisht'], + [10629, 'lopar'], + [10630, 'ropar'], + [10635, 'lbrke'], + [10636, 'rbrke'], + [10637, 'lbrkslu'], + [10638, 'rbrksld'], + [10639, 'lbrksld'], + [10640, 'rbrkslu'], + [10641, 'langd'], + [10642, 'rangd'], + [10643, 'lparlt'], + [10644, 'rpargt'], + [10645, 'gtlPar'], + [10646, 'ltrPar'], + [10650, 'vzigzag'], + [10652, 'vangrt'], + [10653, 'angrtvbd'], + [10660, 'ange'], + [10661, 'range'], + [10662, 'dwangle'], + [10663, 'uwangle'], + [10664, 'angmsdaa'], + [10665, 'angmsdab'], + [10666, 'angmsdac'], + [10667, 'angmsdad'], + [10668, 'angmsdae'], + [10669, 'angmsdaf'], + [10670, 'angmsdag'], + [10671, 'angmsdah'], + [10672, 'bemptyv'], + [10673, 'demptyv'], + [10674, 'cemptyv'], + [10675, 'raemptyv'], + [10676, 'laemptyv'], + [10677, 'ohbar'], + [10678, 'omid'], + [10679, 'opar'], + [10681, 'operp'], + [10683, 'olcross'], + [10684, 'odsold'], + [10686, 'olcir'], + [10687, 'ofcir'], + [10688, 'olt'], + [10689, 'ogt'], + [10690, 'cirscir'], + [10691, 'cirE'], + [10692, 'solb'], + [10693, 'bsolb'], + [10697, 'boxbox'], + [10701, 'trisb'], + [10702, 'rtriltri'], + [10703, 'LeftTriangleBar'], + [10704, 'RightTriangleBar'], + [10716, 'iinfin'], + [10717, 'infintie'], + [10718, 'nvinfin'], + [10723, 'eparsl'], + [10724, 'smeparsl'], + [10725, 'eqvparsl'], + [10731, 'lozf'], + [10731, 'blacklozenge'], + [10740, 'RuleDelayed'], + [10742, 'dsol'], + [10752, 'xodot'], + [10752, 'bigodot'], + [10753, 'xoplus'], + [10753, 'bigoplus'], + [10754, 'xotime'], + [10754, 'bigotimes'], + [10756, 'xuplus'], + [10756, 'biguplus'], + [10758, 'xsqcup'], + [10758, 'bigsqcup'], + [10764, 'qint'], + [10764, 'iiiint'], + [10765, 'fpartint'], + [10768, 'cirfnint'], + [10769, 'awint'], + [10770, 'rppolint'], + [10771, 'scpolint'], + [10772, 'npolint'], + [10773, 'pointint'], + [10774, 'quatint'], + [10775, 'intlarhk'], + [10786, 'pluscir'], + [10787, 'plusacir'], + [10788, 'simplus'], + [10789, 'plusdu'], + [10790, 'plussim'], + [10791, 'plustwo'], + [10793, 'mcomma'], + [10794, 'minusdu'], + [10797, 'loplus'], + [10798, 'roplus'], + [10799, 'Cross'], + [10800, 'timesd'], + [10801, 'timesbar'], + [10803, 'smashp'], + [10804, 'lotimes'], + [10805, 'rotimes'], + [10806, 'otimesas'], + [10807, 'Otimes'], + [10808, 'odiv'], + [10809, 'triplus'], + [10810, 'triminus'], + [10811, 'tritime'], + [10812, 'iprod'], + [10812, 'intprod'], + [10815, 'amalg'], + [10816, 'capdot'], + [10818, 'ncup'], + [10819, 'ncap'], + [10820, 'capand'], + [10821, 'cupor'], + [10822, 'cupcap'], + [10823, 'capcup'], + [10824, 'cupbrcap'], + [10825, 'capbrcup'], + [10826, 'cupcup'], + [10827, 'capcap'], + [10828, 'ccups'], + [10829, 'ccaps'], + [10832, 'ccupssm'], + [10835, 'And'], + [10836, 'Or'], + [10837, 'andand'], + [10838, 'oror'], + [10839, 'orslope'], + [10840, 'andslope'], + [10842, 'andv'], + [10843, 'orv'], + [10844, 'andd'], + [10845, 'ord'], + [10847, 'wedbar'], + [10854, 'sdote'], + [10858, 'simdot'], + [10861, 'congdot'], + [10862, 'easter'], + [10863, 'apacir'], + [10864, 'apE'], + [10865, 'eplus'], + [10866, 'pluse'], + [10867, 'Esim'], + [10868, 'Colone'], + [10869, 'Equal'], + [10871, 'eDDot'], + [10871, 'ddotseq'], + [10872, 'equivDD'], + [10873, 'ltcir'], + [10874, 'gtcir'], + [10875, 'ltquest'], + [10876, 'gtquest'], + [10877, 'les'], + [10877, 'LessSlantEqual'], + [10877, 'leqslant'], + [10878, 'ges'], + [10878, 'GreaterSlantEqual'], + [10878, 'geqslant'], + [10879, 'lesdot'], + [10880, 'gesdot'], + [10881, 'lesdoto'], + [10882, 'gesdoto'], + [10883, 'lesdotor'], + [10884, 'gesdotol'], + [10885, 'lap'], + [10885, 'lessapprox'], + [10886, 'gap'], + [10886, 'gtrapprox'], + [10887, 'lne'], + [10887, 'lneq'], + [10888, 'gne'], + [10888, 'gneq'], + [10889, 'lnap'], + [10889, 'lnapprox'], + [10890, 'gnap'], + [10890, 'gnapprox'], + [10891, 'lEg'], + [10891, 'lesseqqgtr'], + [10892, 'gEl'], + [10892, 'gtreqqless'], + [10893, 'lsime'], + [10894, 'gsime'], + [10895, 'lsimg'], + [10896, 'gsiml'], + [10897, 'lgE'], + [10898, 'glE'], + [10899, 'lesges'], + [10900, 'gesles'], + [10901, 'els'], + [10901, 'eqslantless'], + [10902, 'egs'], + [10902, 'eqslantgtr'], + [10903, 'elsdot'], + [10904, 'egsdot'], + [10905, 'el'], + [10906, 'eg'], + [10909, 'siml'], + [10910, 'simg'], + [10911, 'simlE'], + [10912, 'simgE'], + [10913, 'LessLess'], + [10914, 'GreaterGreater'], + [10916, 'glj'], + [10917, 'gla'], + [10918, 'ltcc'], + [10919, 'gtcc'], + [10920, 'lescc'], + [10921, 'gescc'], + [10922, 'smt'], + [10923, 'lat'], + [10924, 'smte'], + [10925, 'late'], + [10926, 'bumpE'], + [10927, 'pre'], + [10927, 'preceq'], + [10927, 'PrecedesEqual'], + [10928, 'sce'], + [10928, 'succeq'], + [10928, 'SucceedsEqual'], + [10931, 'prE'], + [10932, 'scE'], + [10933, 'prnE'], + [10933, 'precneqq'], + [10934, 'scnE'], + [10934, 'succneqq'], + [10935, 'prap'], + [10935, 'precapprox'], + [10936, 'scap'], + [10936, 'succapprox'], + [10937, 'prnap'], + [10937, 'precnapprox'], + [10938, 'scnap'], + [10938, 'succnapprox'], + [10939, 'Pr'], + [10940, 'Sc'], + [10941, 'subdot'], + [10942, 'supdot'], + [10943, 'subplus'], + [10944, 'supplus'], + [10945, 'submult'], + [10946, 'supmult'], + [10947, 'subedot'], + [10948, 'supedot'], + [10949, 'subE'], + [10949, 'subseteqq'], + [10950, 'supE'], + [10950, 'supseteqq'], + [10951, 'subsim'], + [10952, 'supsim'], + [10955, 'subnE'], + [10955, 'subsetneqq'], + [10956, 'supnE'], + [10956, 'supsetneqq'], + [10959, 'csub'], + [10960, 'csup'], + [10961, 'csube'], + [10962, 'csupe'], + [10963, 'subsup'], + [10964, 'supsub'], + [10965, 'subsub'], + [10966, 'supsup'], + [10967, 'suphsub'], + [10968, 'supdsub'], + [10969, 'forkv'], + [10970, 'topfork'], + [10971, 'mlcp'], + [10980, 'Dashv'], + [10980, 'DoubleLeftTee'], + [10982, 'Vdashl'], + [10983, 'Barv'], + [10984, 'vBar'], + [10985, 'vBarv'], + [10987, 'Vbar'], + [10988, 'Not'], + [10989, 'bNot'], + [10990, 'rnmid'], + [10991, 'cirmid'], + [10992, 'midcir'], + [10993, 'topcir'], + [10994, 'nhpar'], + [10995, 'parsim'], + [11005, 'parsl'], + [64256, 'fflig'], + [64257, 'filig'], + [64258, 'fllig'], + [64259, 'ffilig'], + [64260, 'ffllig'], + [119964, 'Ascr'], + [119966, 'Cscr'], + [119967, 'Dscr'], + [119970, 'Gscr'], + [119973, 'Jscr'], + [119974, 'Kscr'], + [119977, 'Nscr'], + [119978, 'Oscr'], + [119979, 'Pscr'], + [119980, 'Qscr'], + [119982, 'Sscr'], + [119983, 'Tscr'], + [119984, 'Uscr'], + [119985, 'Vscr'], + [119986, 'Wscr'], + [119987, 'Xscr'], + [119988, 'Yscr'], + [119989, 'Zscr'], + [119990, 'ascr'], + [119991, 'bscr'], + [119992, 'cscr'], + [119993, 'dscr'], + [119995, 'fscr'], + [119997, 'hscr'], + [119998, 'iscr'], + [119999, 'jscr'], + [120000, 'kscr'], + [120001, 'lscr'], + [120002, 'mscr'], + [120003, 'nscr'], + [120005, 'pscr'], + [120006, 'qscr'], + [120007, 'rscr'], + [120008, 'sscr'], + [120009, 'tscr'], + [120010, 'uscr'], + [120011, 'vscr'], + [120012, 'wscr'], + [120013, 'xscr'], + [120014, 'yscr'], + [120015, 'zscr'], + [120068, 'Afr'], + [120069, 'Bfr'], + [120071, 'Dfr'], + [120072, 'Efr'], + [120073, 'Ffr'], + [120074, 'Gfr'], + [120077, 'Jfr'], + [120078, 'Kfr'], + [120079, 'Lfr'], + [120080, 'Mfr'], + [120081, 'Nfr'], + [120082, 'Ofr'], + [120083, 'Pfr'], + [120084, 'Qfr'], + [120086, 'Sfr'], + [120087, 'Tfr'], + [120088, 'Ufr'], + [120089, 'Vfr'], + [120090, 'Wfr'], + [120091, 'Xfr'], + [120092, 'Yfr'], + [120094, 'afr'], + [120095, 'bfr'], + [120096, 'cfr'], + [120097, 'dfr'], + [120098, 'efr'], + [120099, 'ffr'], + [120100, 'gfr'], + [120101, 'hfr'], + [120102, 'ifr'], + [120103, 'jfr'], + [120104, 'kfr'], + [120105, 'lfr'], + [120106, 'mfr'], + [120107, 'nfr'], + [120108, 'ofr'], + [120109, 'pfr'], + [120110, 'qfr'], + [120111, 'rfr'], + [120112, 'sfr'], + [120113, 'tfr'], + [120114, 'ufr'], + [120115, 'vfr'], + [120116, 'wfr'], + [120117, 'xfr'], + [120118, 'yfr'], + [120119, 'zfr'], + [120120, 'Aopf'], + [120121, 'Bopf'], + [120123, 'Dopf'], + [120124, 'Eopf'], + [120125, 'Fopf'], + [120126, 'Gopf'], + [120128, 'Iopf'], + [120129, 'Jopf'], + [120130, 'Kopf'], + [120131, 'Lopf'], + [120132, 'Mopf'], + [120134, 'Oopf'], + [120138, 'Sopf'], + [120139, 'Topf'], + [120140, 'Uopf'], + [120141, 'Vopf'], + [120142, 'Wopf'], + [120143, 'Xopf'], + [120144, 'Yopf'], + [120146, 'aopf'], + [120147, 'bopf'], + [120148, 'copf'], + [120149, 'dopf'], + [120150, 'eopf'], + [120151, 'fopf'], + [120152, 'gopf'], + [120153, 'hopf'], + [120154, 'iopf'], + [120155, 'jopf'], + [120156, 'kopf'], + [120157, 'lopf'], + [120158, 'mopf'], + [120159, 'nopf'], + [120160, 'oopf'], + [120161, 'popf'], + [120162, 'qopf'], + [120163, 'ropf'], + [120164, 'sopf'], + [120165, 'topf'], + [120166, 'uopf'], + [120167, 'vopf'], + [120168, 'wopf'], + [120169, 'xopf'], + [120170, 'yopf'], + [120171, 'zopf'], + [60, 'nvlt'], + [61, 'bne'], + [62, 'nvgt'], + [102, 'fjlig'], + [8287, 'ThickSpace'], + [8605, 'nrarrw'], + [8706, 'npart'], + [8736, 'nang'], + [8745, 'caps'], + [8746, 'cups'], + [8764, 'nvsim'], + [8765, 'race'], + [8766, 'acE'], + [8770, 'nesim'], + [8770, 'NotEqualTilde'], + [8779, 'napid'], + [8781, 'nvap'], + [8782, 'nbump'], + [8782, 'NotHumpDownHump'], + [8783, 'nbumpe'], + [8783, 'NotHumpEqual'], + [8784, 'nedot'], + [8801, 'bnequiv'], + [8804, 'nvle'], + [8805, 'nvge'], + [8806, 'nlE'], + [8806, 'nleqq'], + [8807, 'ngE'], + [8807, 'ngeqq'], + [8807, 'NotGreaterFullEqual'], + [8808, 'lvertneqq'], + [8808, 'lvnE'], + [8809, 'gvertneqq'], + [8809, 'gvnE'], + [8810, 'nLtv'], + [8810, 'NotLessLess'], + [8810, 'nLt'], + [8811, 'nGtv'], + [8811, 'NotGreaterGreater'], + [8811, 'nGt'], + [8831, 'NotSucceedsTilde'], + [8834, 'NotSubset'], + [8834, 'nsubset'], + [8834, 'vnsub'], + [8835, 'NotSuperset'], + [8835, 'nsupset'], + [8835, 'vnsup'], + [8842, 'varsubsetneq'], + [8842, 'vsubne'], + [8843, 'varsupsetneq'], + [8843, 'vsupne'], + [8847, 'NotSquareSubset'], + [8848, 'NotSquareSuperset'], + [8851, 'sqcaps'], + [8852, 'sqcups'], + [8884, 'nvltrie'], + [8885, 'nvrtrie'], + [8920, 'nLl'], + [8921, 'nGg'], + [8922, 'lesg'], + [8923, 'gesl'], + [8949, 'notindot'], + [8953, 'notinE'], + [10547, 'nrarrc'], + [10703, 'NotLeftTriangleBar'], + [10704, 'NotRightTriangleBar'], + [10861, 'ncongdot'], + [10864, 'napE'], + [10877, 'nleqslant'], + [10877, 'nles'], + [10877, 'NotLessSlantEqual'], + [10878, 'ngeqslant'], + [10878, 'nges'], + [10878, 'NotGreaterSlantEqual'], + [10913, 'NotNestedLessLess'], + [10914, 'NotNestedGreaterGreater'], + [10924, 'smtes'], + [10925, 'lates'], + [10927, 'NotPrecedesEqual'], + [10927, 'npre'], + [10927, 'npreceq'], + [10928, 'NotSucceedsEqual'], + [10928, 'nsce'], + [10928, 'nsucceq'], + [10949, 'nsubE'], + [10949, 'nsubseteqq'], + [10950, 'nsupE'], + [10950, 'nsupseteqq'], + [10955, 'varsubsetneqq'], + [10955, 'vsubnE'], + [10956, 'varsupsetneqq'], + [10956, 'vsupnE'], + [11005, 'nparsl'], + + ] + + # Contains the mapping of code point (or name) to the actual Entity object. + ENTITY_MAP = Hash.new do |h, k| + if k.kind_of?(Integer) + h[k] = Entity.new(k, nil) + else + raise Kramdown::Error, "Can't handle generic non-integer character reference '#{k}'" + end + end + + ENTITY_TABLE.each do |code_point, data| + ENTITY_MAP[code_point] = if data.kind_of?(String) + ENTITY_MAP[data] = Entity.new(code_point, data) + else + ENTITY_MAP[data] + end + end + + # Return the entity for the given code point or name +point_or_name+. + def entity(point_or_name) + ENTITY_MAP[point_or_name] + end + + module_function :entity + + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/html.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/html.rb new file mode 100644 index 0000000..18bc12c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/html.rb @@ -0,0 +1,84 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'rexml/parsers/baseparser' + +module Kramdown + + module Utils + + # Provides convenience methods for HTML related tasks. + # + # *Note* that this module has to be mixed into a class that has a @root (containing an element + # of type :root) and an @options (containing an options hash) instance variable so that some of + # the methods can work correctly. + module Html + + # Convert the entity +e+ to a string. The optional parameter +original+ may contain the + # original representation of the entity. + # + # This method uses the option +entity_output+ to determine the output form for the entity. + def entity_to_str(e, original = nil) + entity_output = @options[:entity_output] + + if entity_output == :as_char && + (c = e.char.encode(@root.options[:encoding]) rescue nil) && + ((c = e.char) == '"' || !ESCAPE_MAP.key?(c)) + c + elsif (entity_output == :as_input || entity_output == :as_char) && original + original + elsif (entity_output == :symbolic || ESCAPE_MAP.key?(e.char)) && !e.name.nil? + "&#{e.name};" + else # default to :numeric + "&##{e.code_point};" + end + end + + # Return the HTML representation of the attributes +attr+. + def html_attributes(attr) + return '' if attr.empty? + + attr.map do |k, v| + v.nil? || (k == 'id' && v.strip.empty?) ? '' : " #{k}=\"#{escape_html(v.to_s, :attribute)}\"" + end.join + end + + # :stopdoc: + ESCAPE_MAP = { + '<' => '<', + '>' => '>', + '&' => '&', + '"' => '"', + } + ESCAPE_ALL_RE = /<|>|&/ + ESCAPE_TEXT_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&/) + ESCAPE_ATTRIBUTE_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&|"/) + ESCAPE_RE_FROM_TYPE = {all: ESCAPE_ALL_RE, text: ESCAPE_TEXT_RE, attribute: ESCAPE_ATTRIBUTE_RE} + # :startdoc: + + # Escape the special HTML characters in the string +str+. The parameter +type+ specifies what + # is escaped: :all - all special HTML characters except the quotation mark as well as + # entities, :text - all special HTML characters except the quotation mark but no entities and + # :attribute - all special HTML characters including the quotation mark but no entities. + def escape_html(str, type = :all) + str.gsub(ESCAPE_RE_FROM_TYPE[type]) {|m| ESCAPE_MAP[m] || m } + end + + REDUNDANT_LINE_BREAK_REGEX = /([\p{Han}\p{Hiragana}\p{Katakana}]+)\n([\p{Han}\p{Hiragana}\p{Katakana}]+)/u + def fix_cjk_line_break(str) + while str.gsub!(REDUNDANT_LINE_BREAK_REGEX, '\1\2') + end + str + end + + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/lru_cache.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/lru_cache.rb new file mode 100644 index 0000000..13068c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/lru_cache.rb @@ -0,0 +1,41 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + module Utils + + # A simple least recently used (LRU) cache. + # + # The cache relies on the fact that Ruby's Hash class maintains insertion order. So deleting + # and re-inserting a key-value pair on access moves the key to the last position. When an + # entry is added and the cache is full, the first entry is removed. + class LRUCache + + # Creates a new LRUCache that can hold +size+ entries. + def initialize(size) + @size = size + @cache = {} + end + + # Returns the stored value for +key+ or +nil+ if no value was stored under the key. + def [](key) + (val = @cache.delete(key)).nil? ? nil : @cache[key] = val + end + + # Stores the +value+ under the +key+. + def []=(key, value) + @cache.delete(key) + @cache[key] = value + @cache.shift if @cache.length > @size + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/string_scanner.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/string_scanner.rb new file mode 100644 index 0000000..de07690 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/string_scanner.rb @@ -0,0 +1,81 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'strscan' + +module Kramdown + module Utils + + # This patched StringScanner adds line number information for current scan position and a + # start_line_number override for nested StringScanners. + class StringScanner < ::StringScanner + + # The start line number. Used for nested StringScanners that scan a sub-string of the source + # document. The kramdown parser uses this, e.g., for span level parsers. + attr_reader :start_line_number + + # Takes the start line number as optional second argument. + # + # Note: The original second argument is no longer used so this should be safe. + def initialize(string, start_line_number = 1) + super(string) + @start_line_number = start_line_number || 1 + @previous_pos = 0 + @previous_line_number = @start_line_number + end + + # Sets the byte position of the scan pointer. + # + # Note: This also resets some internal variables, so always use pos= when setting the position + # and don't use any other method for that! + def pos=(pos) + if self.pos > pos + @previous_line_number = @start_line_number + @previous_pos = 0 + end + super + end + + # Return information needed to revert the byte position of the string scanner in a performant + # way. + # + # The returned data can be fed to #revert_pos to revert the position to the saved one. + # + # Note: Just saving #pos won't be enough. + def save_pos + [pos, @previous_pos, @previous_line_number] + end + + # Revert the position to one saved by #save_pos. + def revert_pos(data) + self.pos = data[0] + @previous_pos, @previous_line_number = data[1], data[2] + end + + # Returns the line number for current charpos. + # + # NOTE: Requires that all line endings are normalized to '\n' + # + # NOTE: Normally we'd have to add one to the count of newlines to get the correct line number. + # However we add the one indirectly by using a one-based start_line_number. + def current_line_number + # Not using string[@previous_pos..best_pos].count('\n') because it is slower + strscan = ::StringScanner.new(string) + strscan.pos = @previous_pos + old_pos = pos + 1 + @previous_line_number += 1 while strscan.skip_until(/\n/) && strscan.pos <= old_pos + + @previous_pos = (eos? ? pos : pos + 1) + @previous_line_number + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/unidecoder.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/unidecoder.rb new file mode 100644 index 0000000..dacf2d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/utils/unidecoder.rb @@ -0,0 +1,46 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# +# This file is based on code originally from the Stringex library and needs the data files from +# Stringex to work correctly. + +module Kramdown + module Utils + + # Provides the ability to tranliterate Unicode strings into plain ASCII ones. + module Unidecoder + + gem 'stringex' + path = $:.find do |dir| + File.directory?(File.join(File.expand_path(dir), "stringex", "unidecoder_data")) + end + + if path + CODEPOINTS = Hash.new do |h, k| + h[k] = YAML.load_file(File.join(path, "stringex", "unidecoder_data", "#{k}.yml")) + end + + # Transliterate string from Unicode into ASCII. + def self.decode(string) + string.gsub(/[^\x00-\x7f]/u) do |codepoint| + unpacked = codepoint.unpack1("U") + CODEPOINTS[sprintf("x%02x", unpacked >> 8)][unpacked & 255] + rescue StandardError + "?" + end + end + else + def self.decode(string) + string + end + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/version.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/version.rb new file mode 100644 index 0000000..ec428be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/lib/kramdown/version.rb @@ -0,0 +1,15 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +module Kramdown + + # The kramdown version. + VERSION = '2.5.2' + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/man/man1/kramdown.1 b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/man/man1/kramdown.1 new file mode 100644 index 0000000..8022582 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/man/man1/kramdown.1 @@ -0,0 +1,373 @@ +.\" generated by kramdown +.TH "KRAMDOWN" "1" "January 2019" +.SH NAME +kramdown \- a fast, pure\-Ruby Markdown\-superset converter +.SH "SYNOPSIS" +\fBkramdown\fP [\fIoptions\fP] [\fIFILE\fP\.\.\.] +.SH "DESCRIPTION" +kramdown is primarily used for parsing a superset of Markdown and converting it to different output formats\. It supports standard Markdown (with some minor modifications) and various extensions like tables and definition lists\. Due to its modular architecture it also allows other input formats than Markdown, for example, HTML or Github Flavored Markdown\. +.P +If \fIFILE\fP is not specified, kramdown reads from the standard input\. The result is written to the standard output\. +.P +There are two sets of options that kramdown accepts: The first one includes the options that are used directly by the kramdown binary\. The second set of options controls how kramdown parses and converts its input\. +.P +Default values for this second set can be set using YAML via the configuration file \fBkramdownrc\fP\&\. Note that configuration option names use underscores, not dashes (dashes are just used in the CLI options names), and boolean options do not have a \fBno\fP variant but a value of \fBtrue\fP or \fBfalse\fP\&\. This file has to be in XDG_CONFIG_HOME on Linux/Unix, ~/Library/Preferences on macOS and ~/AppData/Local on Windows\. +.SH "CLI\-ONLY OPTIONS" +.TP +\fB\-i\fP \fIFORMAT\fP, \fB\-\-input\fP \fIFORMAT\fP +Specify the input format\. Available input formats: \fIkramdown\fP (this is the default), \fImarkdown\fP, or \fIhtml\fP\&\. The input format \fIGFM\fP is available through the \fBkramdown\-parser\-gfm\fP gem\. +.TP +\fB\-o\fP \fIFORMAT\fP, \fB\-\-output\fP \fIFORMAT\fP +Specify one or more output formats separated by commas: \fIhtml\fP (default), \fIkramdown\fP, \fIlatex\fP, \fIman\fP or \fIremove_html_tags\fP\&\. The converter \fIpdf\fP is available through the \fBkramdown\-converter\-pdf\fP gem\. +.TP +\fB\-x\fP \fIEXT\fP, \fB\-\-extension\fP \fIEXT\fP +Load one or more extensions\. The name of the extension should not include the \fBkramdown\-\fP prefix, e\.g\. just \fBparser\-gfm\fP\&\. Multiple extensions can be loaded by separating them with commas\. +.RS +.P +Note: This option has to be used before any other options that rely on the extension already being loaded\. +.RE +.TP +\fB\-\-no\-config\-file\fP +Do not read any configuration file\. Default behavior is to check for a configuration file and read it if it exists\. +.TP +\fB\-\-config\-file\fP \fIFILE\fP +Override the default path and name of the configuration file\. +.TP +\fB\-v\fP, \fB\-\-version\fP +Show the version of kramdown\. +.TP +\fB\-h\fP, \fB\-\-help\fP +Show the help\. +.SH "KRAMDOWN OPTIONS" +.TP +\fB\-\-auto\-id\-prefix\fP \fIARG\fP +Prefix used for automatically generated header IDs +.RS +.P +This option can be used to set a prefix for the automatically generated header IDs so that there is no conflict when rendering multiple kramdown documents into one output file separately\. The prefix should only contain characters that are valid in an ID! +.P +Default: \[u2018]\[u2019] Used by: HTML/Latex converter +.RE +.TP +\fB\-\-[no\-]auto\-id\-stripping\fP +Strip all formatting from header text for automatic ID generation +.RS +.P +If this option is \fBtrue\fP, only the text elements of a header are used for generating the ID later (in contrast to just using the raw header text line)\. +.P +This option will be removed in version 2\.0 because this will be the default then\. +.P +Default: false Used by: kramdown parser +.RE +.TP +\fB\-\-[no\-]auto\-ids\fP +Use automatic header ID generation +.RS +.P +If this option is \fBtrue\fP, ID values for all headers are automatically generated if no ID is explicitly specified\. +.P +Default: true Used by: HTML/Latex converter +.RE +.TP +\fB\-\-entity\-output\fP \fIARG\fP +Defines how entities are output +.RS +.P +The possible values are :as_input (entities are output in the same form as found in the input), :numeric (entities are output in numeric form), :symbolic (entities are output in symbolic form if possible) or :as_char (entities are output as characters if possible, only available on Ruby 1\.9)\. +.P +Default: :as_char Used by: HTML converter, kramdown converter +.RE +.TP +\fB\-\-footnote\-backlink\fP \fIARG\fP +Defines the text that should be used for the footnote backlinks +.RS +.P +The footnote backlink is just text, so any special HTML characters will be escaped\. +.P +If the footnote backlint text is an empty string, no footnote backlinks will be generated\. +.P +Default: \[u2018]\[u0026]8617;\[u2019] Used by: HTML converter +.RE +.TP +\fB\-\-[no\-]footnote\-backlink\-inline\fP +Specifies whether the footnote backlink should always be inline +.RS +.P +With the default of false the footnote backlink is placed at the end of the last paragraph if there is one, or an extra paragraph with only the footnote backlink is created\. +.P +Setting this option to true tries to place the footnote backlink in the last, possibly nested paragraph or header\. If this fails (e\.g\. in the case of a table), an extra paragraph with only the footnote backlink is created\. +.P +Default: false Used by: HTML converter +.RE +.TP +\fB\-\-footnote\-link\-text\fP \fIARG\fP +The text used for the footnote number in a footnote link +.RS +.P +This option can be used to add additional text to the footnote link\. It should be a format string, and is passed the footnote number as the only argument to the format string\. e\.g\. \[u201c][footnote %s]\[u201d] would display as \[u201c][footnote 1]\[u201d]\&\. +.P +Default: \[u2018]%s\[u2019] Used by: HTML +.RE +.TP +\fB\-\-footnote\-nr\fP \fIARG\fP +The number of the first footnote +.RS +.P +This option can be used to specify the number that is used for the first footnote\. +.P +Default: 1 Used by: HTML converter +.RE +.TP +\fB\-\-footnote\-prefix\fP \fIARG\fP +Prefix used for footnote IDs +.RS +.P +This option can be used to set a prefix for footnote IDs\. This is useful when rendering multiple documents into the same output file to avoid duplicate IDs\. The prefix should only contain characters that are valid in an ID! +.P +Default: \[u2018]\[u2019] Used by: HTML +.RE +.TP +\fB\-\-forbidden\-inline\-options\fP \fIARG\fP +Defines the options that may not be set using the {::options} extension +.RS +.P +The value needs to be an array of option names\. +.P +Default: [template] Used by: HTML converter +.RE +.TP +\fB\-\-[no\-]header\-links\fP +Adds anchor tags within headers that can be used to generate permalinks when not using a table of contents\. +.RS +.P +The anchor tags are empty, but can be styled to your liking\. +.P +Default: false +.RE +.TP +\fB\-\-header\-offset\fP \fIARG\fP +Sets the output offset for headers +.RS +.P +If this option is c (may also be negative) then a header with level n will be output as a header with level c+n\. If c+n is lower than 1, level 1 will be used\. If c+n is greater than 6, level 6 will be used\. +.P +Default: 0 Used by: HTML converter, Kramdown converter, Latex converter +.RE +.TP +\fB\-\-[no\-]html\-to\-native\fP +Convert HTML elements to native elements +.RS +.P +If this option is \fBtrue\fP, the parser converts HTML elements to native elements\. For example, when parsing \fBhallo\fP the emphasis tag would normally be converted to an \fB:html\fP element with tag type \fB:em\fP\&\. If \fBhtml_to_native\fP is \fBtrue\fP, then the emphasis would be converted to a native \fB:em\fP element\. +.P +This is useful for converters that cannot deal with HTML elements\. +.P +Default: false Used by: kramdown parser +.RE +.TP +\fB\-\-latex\-headers\fP \fIARG\fP +Defines the LaTeX commands for different header levels +.RS +.P +The commands for the header levels one to six can be specified by separating them with commas\. +.P +Default: section,subsection,subsubsection,paragraph,subparagraph,subparagraph Used by: Latex converter +.RE +.TP +\fB\-\-line\-width\fP \fIARG\fP +Defines the line width to be used when outputting a document +.RS +.P +Default: 72 Used by: kramdown converter +.RE +.TP +\fB\-\-link\-defs\fP \fIARG\fP +Pre\-defines link definitions +.RS +.P +This option can be used to pre\-define link definitions\. The value needs to be a Hash where the keys are the link identifiers and the values are two element Arrays with the link URL and the link title\. +.P +If the value is a String, it has to contain a valid YAML hash and the hash has to follow the above guidelines\. +.P +Default: {} Used by: kramdown parser +.RE +.TP +\fB\-\-list\-indent\fP \fIARG\fP +Sets the number of spaces to use for list indentation +.RS +.P +Default: 2 Used by: Kramdown converter +.RE +.TP +\fB\-\-math\-engine\fP \fIARG\fP +Set the math engine +.RS +.P +Specifies the math engine that should be used for converting math blocks/spans\. If this option is set to +nil+, no math engine is used and the math blocks/spans are output as is\. +.P +Options for the selected math engine can be set with the math_engine_opts configuration option\. +.P +Default: mathjax Used by: HTML converter +.RE +.TP +\fB\-\-math\-engine\-opts\fP \fIARG\fP +Set the math engine options +.RS +.P +Specifies options for the math engine set via the math_engine configuration option\. +.P +The value needs to be a hash with key\-value pairs that are understood by the used math engine\. +.P +Default: {} Used by: HTML converter +.RE +.TP +\fB\-\-[no\-]parse\-block\-html\fP +Process kramdown syntax in block HTML tags +.RS +.P +If this option is \fBtrue\fP, the kramdown parser processes the content of block HTML tags as text containing block\-level elements\. Since this is not wanted normally, the default is \fBfalse\fP\&\. It is normally better to selectively enable kramdown processing via the markdown attribute\. +.P +Default: false Used by: kramdown parser +.RE +.TP +\fB\-\-[no\-]parse\-span\-html\fP +Process kramdown syntax in span HTML tags +.RS +.P +If this option is \fBtrue\fP, the kramdown parser processes the content of span HTML tags as text containing span\-level elements\. +.P +Default: true Used by: kramdown parser +.RE +.TP +\fB\-\-[no\-]remove\-block\-html\-tags\fP +Remove block HTML tags +.RS +.P +If this option is \fBtrue\fP, the RemoveHtmlTags converter removes block HTML tags\. +.P +Default: true Used by: RemoveHtmlTags converter +.RE +.TP +\fB\-\-[no\-]remove\-line\-breaks\-for\-cjk\fP +Specifies whether line breaks should be removed between CJK characters +.RS +.P +Default: false Used by: HTML converter +.RE +.TP +\fB\-\-[no\-]remove\-span\-html\-tags\fP +Remove span HTML tags +.RS +.P +If this option is \fBtrue\fP, the RemoveHtmlTags converter removes span HTML tags\. +.P +Default: false Used by: RemoveHtmlTags converter +.RE +.TP +\fB\-\-smart\-quotes\fP \fIARG\fP +Defines the HTML entity names or code points for smart quote output +.RS +.P +The entities identified by entity name or code point that should be used for, in order, a left single quote, a right single quote, a left double and a right double quote are specified by separating them with commas\. +.P +Default: lsquo,rsquo,ldquo,rdquo Used by: HTML/Latex converter +.RE +.TP +\fB\-\-syntax\-highlighter\fP \fIARG\fP +Set the syntax highlighter +.RS +.P +Specifies the syntax highlighter that should be used for highlighting code blocks and spans\. If this option is set to +nil+, no syntax highlighting is done\. +.P +Options for the syntax highlighter can be set with the syntax_highlighter_opts configuration option\. +.P +Default: rouge Used by: HTML/Latex converter +.RE +.TP +\fB\-\-syntax\-highlighter\-opts\fP \fIARG\fP +Set the syntax highlighter options +.RS +.P +Specifies options for the syntax highlighter set via the syntax_highlighter configuration option\. +.P +The value needs to be a hash with key\-value pairs that are understood by the used syntax highlighter\. +.P +Default: {} Used by: HTML/Latex converter +.RE +.TP +\fB\-\-template\fP \fIARG\fP +The name of an ERB template file that should be used to wrap the output or the ERB template itself\. +.RS +.P +This is used to wrap the output in an environment so that the output can be used as a stand\-alone document\. For example, an HTML template would provide the needed header and body tags so that the whole output is a valid HTML file\. If no template is specified, the output will be just the converted text\. +.P +When resolving the template file, the given template name is used first\. If such a file is not found, the converter extension (the same as the converter name) is appended\. If the file still cannot be found, the templates name is interpreted as a template name that is provided by kramdown (without the converter extension)\. If the file is still not found, the template name is checked if it starts with \[u2018]string://\[u2019] and if it does, this prefix is removed and the rest is used as template content\. +.P +kramdown provides a default template named \[u2018]document\[u2019] for each converter\. +.P +Default: \[u2018]\[u2019] Used by: all converters +.RE +.TP +\fB\-\-toc\-levels\fP \fIARG\fP +Defines the levels that are used for the table of contents +.RS +.P +The individual levels can be specified by separating them with commas (e\.g\. 1,2,3) or by using the range syntax (e\.g\. 1\.\.3)\. Only the specified levels are used for the table of contents\. +.P +Default: 1\.\.6 Used by: HTML/Latex converter +.RE +.TP +\fB\-\-[no\-]transliterated\-header\-ids\fP +Transliterate the header text before generating the ID +.RS +.P +Only ASCII characters are used in headers IDs\. This is not good for languages with many non\-ASCII characters\. By enabling this option the header text is transliterated to ASCII as good as possible so that the resulting header ID is more useful\. +.P +The stringex library needs to be installed for this feature to work! +.P +Default: false Used by: HTML/Latex converter +.RE +.TP +\fB\-\-typographic\-symbols\fP \fIARG\fP +Defines a mapping from typographical symbol to output characters +.RS +.P +Typographical symbols are normally output using their equivalent Unicode codepoint\. However, sometimes one wants to change the output, mostly to fallback to a sequence of ASCII characters\. +.P +This option allows this by specifying a mapping from typographical symbol to its output string\. For example, the mapping {hellip: \.\.\.} would output the standard ASCII representation of an ellipsis\. +.P +The available typographical symbol names are: +.IP \(bu 4 +hellip: ellipsis +.IP \(bu 4 +mdash: em\-dash +.IP \(bu 4 +ndash: en\-dash +.IP \(bu 4 +laquo: left guillemet +.IP \(bu 4 +raquo: right guillemet +.IP \(bu 4 +laquo_space: left guillemet followed by a space +.IP \(bu 4 +raquo_space: right guillemet preceeded by a space +.P +Default: {} Used by: HTML/Latex converter +.RE +.SH "EXIT STATUS" +The exit status is 0 if no error happened\. Otherwise it is 1\. +.SH "SEE ALSO" +The kramdown website +.UR http://kramdown\.gettalong\.org +.UE +for more information, especially on the supported input syntax\. +.SH "AUTHOR" +kramdown was written by Thomas Leitner +.MT t_leitner@gmx\.at +.UE +\&\. +.P +This manual page was written by Thomas Leitner +.MT t_leitner@gmx\.at +.UE +\&\. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/run_tests.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/run_tests.rb new file mode 100644 index 0000000..5c819e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/run_tests.rb @@ -0,0 +1,46 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +$:.unshift File.dirname(__FILE__) + '/../lib' +require 'kramdown' +require 'test/unit/assertions' +require 'yaml' + +include Test::Unit::Assertions + +arg = ARGV[0] || File.join(File.dirname(__FILE__), 'testcases') + +arg = if File.directory?(arg) + File.join(arg, '**/*.text') + else + arg + '.text' + end + +width = ((size = `stty size 2>/dev/null`).length > 0 ? size.split.last.to_i : 72) rescue 72 +width -= 8 +fwidth = 0 +Dir[arg].each {|f| fwidth = [fwidth, f.length + 10].max }.each do |file| + print(('Testing ' + file + ' ').ljust([fwidth, width].min)) + $stdout.flush + + html_file = file.sub('.text', '.html') + opts_file = file.sub('.text', '.options') + opts_file = File.join(File.dirname(file), 'options') unless File.exist?(opts_file) + options = File.exist?(opts_file) ? YAML.safe_load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1} + doc = Kramdown::Document.new(File.read(file), options) + begin + assert_equal(File.read(html_file), doc.to_html) + puts 'PASSED' + rescue StandardError + puts ' FAILED' + puts $!.message if $VERBOSE + puts $!.backtrace if $DEBUG + end + puts "Warnings:\n" + doc.warnings.join("\n") if !doc.warnings.empty? && $VERBOSE +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_files.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_files.rb new file mode 100644 index 0000000..6c49618 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_files.rb @@ -0,0 +1,313 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'minitest/autorun' +require 'kramdown' +require 'yaml' +require 'tmpdir' +require 'open3' + +begin + require 'kramdown/converter/syntax_highlighter/rouge' + + Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class.send(:define_method, :format) do |tokens, &b| + super(tokens, &b).sub(/<\/code><\/pre>\n?/, "\n") + end + + # custom formatter for tests + module Rouge + module Formatters + class RougeHTMLFormatters < Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class + + tag 'rouge_html_formatters' + + def stream(tokens, &b) + yield %(
) + super + yield %(
) + end + + end + end + end +rescue LoadError, SyntaxError, NameError +end + +Encoding.default_external = 'utf-8' + +class TestFiles < Minitest::Test + + EXCLUDE_KD_FILES = [].compact + + # Generate test methods for kramdown-to-xxx conversion + Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| + next if EXCLUDE_KD_FILES.any? {|f| text_file =~ /#{f}/ } + basename = text_file.sub(/\.text$/, '') + opts_file = text_file.sub(/\.text$/, '.options') + (Dir[basename + ".*"] - [text_file, opts_file]).each do |output_file| + output_format = File.extname(output_file)[1..-1] + next unless Kramdown::Converter.const_defined?(output_format[0..0].upcase + output_format[1..-1]) + define_method('test_' + text_file.tr('.', '_') + "_to_#{output_format}") do + opts_file = File.join(File.dirname(text_file), 'options') unless File.exist?(opts_file) + options = File.exist?(opts_file) ? YAML.load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1} + doc = Kramdown::Document.new(File.read(text_file), options) + assert_equal(File.read(output_file), doc.send("to_#{output_format}")) + end + end + end + + # Generate test methods for html-to-{html,kramdown} conversion + `tidy -v 2>&1` + if $?.exitstatus != 0 + warn("Skipping html-to-{html,kramdown} tests because tidy executable is missing") + else + EXCLUDE_HTML_FILES = [ + 'test/testcases/block/06_codeblock/whitespace.html', # bc of span inside pre + 'test/testcases/block/09_html/simple.html', # bc of xml elements + 'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element + 'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option + 'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option + 'test/testcases/block/06_codeblock/rouge/simple.html', # bc of double surrounding
+ 'test/testcases/block/06_codeblock/rouge/multiple.html', # bc of double surrounding
+ 'test/testcases/block/06_codeblock/highlighting.html', # bc of span elements inside code element + 'test/testcases/block/06_codeblock/highlighting-opts.html', # bc of span elements inside code element + 'test/testcases/block/06_codeblock/guess_lang_css_class.html', # bc of double surrounding
+ 'test/testcases/block/12_extension/options3.html', # bc of rouge + 'test/testcases/block/14_table/empty_tag_in_cell.html', # bc of tidy + 'test/testcases/block/15_math/mathjax_preview.html', # bc of mathjax preview + 'test/testcases/block/15_math/mathjax_preview_simple.html', # bc of mathjax preview + 'test/testcases/block/15_math/mathjax_preview_as_code.html', # bc of mathjax preview + 'test/testcases/span/05_html/mark_element.html', # bc of tidy + 'test/testcases/block/09_html/xml.html', # bc of tidy + 'test/testcases/span/05_html/xml.html', # bc of tidy + 'test/testcases/block/04_header/with_header_links.html', # because of header_links option + ].compact + EXCLUDE_HTML_TEXT_FILES = [ + 'test/testcases/block/09_html/parse_as_span.htmlinput', + 'test/testcases/block/09_html/parse_as_raw.htmlinput', + ].compact + Dir[File.dirname(__FILE__) + '/testcases/**/*.{html,htmlinput}'].each do |html_file| + next if EXCLUDE_HTML_FILES.any? {|f| html_file =~ /#{f}/ } + + out_files = [] + out_files << [(html_file =~ /\.htmlinput$/ ? html_file.sub(/input$/, '') : html_file), :to_html] + if html_file =~ /\.htmlinput$/ && EXCLUDE_HTML_TEXT_FILES.none? {|f| html_file =~ /#{f}/ } + out_files << [html_file.sub(/htmlinput$/, 'text'), :to_kramdown] + end + out_files.select {|f, _| File.exist?(f) }.each do |out_file, out_method| + define_method('test_' + html_file.tr('.', '_') + "_to_#{File.extname(out_file)}") do + opts_file = html_file.sub(/\.html(input)?$/, '.options') + opts_file = File.join(File.dirname(html_file), 'options') unless File.exist?(opts_file) + options = File.exist?(opts_file) ? YAML.load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1} + doc = Kramdown::Document.new(File.read(html_file), options.merge(input: 'html')) + if out_method == :to_html + assert_equal(tidy_output(File.read(out_file)), tidy_output(doc.send(out_method))) + else + assert_equal(File.read(out_file), doc.send(out_method)) + end + end + end + end + end + + def tidy_output(out) + cmd = "tidy -q --doctype omit -utf8" + result, error, status = Open3.capture3(cmd, stdin_data: out) + if status.exitstatus == 2 + raise "Problem using tidy: #{error}" + end + result + end + + # Generate test methods for text-to-latex conversion and compilation + `latex -v 2>&1` + if $?.exitstatus != 0 + warn("Skipping latex compilation tests because latex executable is missing") + else + EXCLUDE_LATEX_FILES = [ + 'test/testcases/span/01_link/image_in_a.text', # bc of image link + 'test/testcases/span/01_link/imagelinks.text', # bc of image links + 'test/testcases/span/01_link/empty_title.text', + 'test/testcases/span/04_footnote/markers.text', # bc of footnote in header + 'test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text', + 'test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text', + 'test/testcases/block/03_paragraph/standalone_image.text', # bc of standalone image + 'test/testcases/cjk-line-break.text', # latex unicode support + 'test/testcases/block/04_header/with_auto_ids.text', # bc of Unicode characters + ].compact + Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| + next if EXCLUDE_LATEX_FILES.any? {|f| text_file =~ /#{f}$/ } + define_method('test_' + text_file.tr('.', '_') + "_to_latex_compilation") do + latex = Kramdown::Document.new(File.read(text_file), auto_ids: false, footnote_nr: 1, + template: 'document').to_latex + Dir.mktmpdir do |tmpdir| + result = IO.popen("latex -output-directory='#{tmpdir}' 2>/dev/null", 'r+') do |io| + io.write(latex) + io.close_write + io.read + end + assert($?.exitstatus == 0, result.scan(/^!(.*\n.*)/).join("\n")) + end + end + end + end + + # Generate test methods for text->kramdown->html conversion + `tidy -v 2>&1` + if $?.exitstatus != 0 + warn("Skipping text->kramdown->html tests because tidy executable is missing") + else + EXCLUDE_TEXT_FILES = [ + 'test/testcases/span/05_html/markdown_attr.text', # bc of markdown attr + 'test/testcases/block/09_html/markdown_attr.text', # bc of markdown attr + 'test/testcases/span/extension/options.text', # bc of parse_span_html option + 'test/testcases/block/12_extension/options.text', # bc of options option + 'test/testcases/block/12_extension/options3.text', # bc of options option + 'test/testcases/block/09_html/content_model/tables.text', # bc of parse_block_html option + 'test/testcases/block/09_html/html_to_native/header.text', # bc of auto_ids option that interferes + 'test/testcases/block/09_html/html_to_native/table_simple.text', # bc of tr style attr getting removed + 'test/testcases/block/09_html/simple.text', # bc of webgen:block elements + 'test/testcases/block/11_ial/simple.text', # bc of change of ordering of attributes in header + 'test/testcases/span/extension/comment.text', # bc of comment text modifications (can this be avoided?) + 'test/testcases/block/04_header/header_type_offset.text', # bc of header_offset being applied twice + 'test/testcases/block/06_codeblock/rouge/simple.text', + 'test/testcases/block/06_codeblock/rouge/multiple.text', # check, what document contain more, than one code block + 'test/testcases/block/14_table/empty_tag_in_cell.text', # bc of tidy + 'test/testcases/span/01_link/link_defs_with_ial.text', # bc of attribute ordering + 'test/testcases/span/05_html/mark_element.text', # bc of tidy + 'test/testcases/block/09_html/xml.text', # bc of tidy + 'test/testcases/span/05_html/xml.text', # bc of tidy + 'test/testcases/block/03_paragraph/standalone_image.text', # bc of standalone image + 'test/testcases/cjk-line-break.text', + 'test/testcases/block/09_html/standalone_image_in_div.html', # bc of standalone image + 'test/testcases/span/abbreviations/abbrev_in_html.text', # bc of invalid abbr tag in SVG + ].compact + Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| + next if EXCLUDE_TEXT_FILES.any? {|f| text_file =~ /#{f}$/ } + html_file = text_file.sub(/\.text$/, '.html') + next unless File.exist?(html_file) + define_method('test_' + text_file.tr('.', '_') + "_to_kramdown_to_html") do + opts_file = text_file.sub(/\.text$/, '.options') + opts_file = File.join(File.dirname(text_file), 'options') unless File.exist?(opts_file) + options = File.exist?(opts_file) ? YAML.load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1} + kdtext = Kramdown::Document.new(File.read(text_file), options).to_kramdown + html = Kramdown::Document.new(kdtext, options).to_html + assert_equal(tidy_output(File.read(html_file)), tidy_output(html)) + kdtext4 = Kramdown::Document.new(File.read(text_file), options.merge({list_indent: 4})).to_kramdown + html = Kramdown::Document.new(kdtext4, options).to_html + assert_equal(tidy_output(File.read(html_file)), tidy_output(html)) + end + end + end + + # Generate test methods for html-to-kramdown-to-html conversion + `tidy -v 2>&1` + if $?.exitstatus != 0 + warn("Skipping html-to-kramdown-to-html tests because tidy executable is missing") + else + EXCLUDE_HTML_KD_FILES = [ + 'test/testcases/span/extension/options.html', # bc of parse_span_html option + 'test/testcases/span/05_html/normal.html', # bc of br tag before closing p tag + 'test/testcases/block/12_extension/nomarkdown.html', # bc of nomarkdown extension + 'test/testcases/block/12_extension/options3.html', # bc of rouge + 'test/testcases/block/09_html/simple.html', # bc of webgen:block elements + 'test/testcases/block/09_html/markdown_attr.html', # bc of markdown attr + 'test/testcases/block/09_html/html_to_native/table_simple.html', # bc of invalidly converted simple table + 'test/testcases/block/06_codeblock/whitespace.html', # bc of entity to char conversion + 'test/testcases/block/06_codeblock/rouge/simple.html', # bc of double surrounding
+ 'test/testcases/block/06_codeblock/rouge/multiple.html', # bc of double surrounding
+ 'test/testcases/block/06_codeblock/guess_lang_css_class.html', # bc of double surrounding
+ 'test/testcases/block/06_codeblock/highlighting.html', # bc of span elements inside code element + 'test/testcases/block/06_codeblock/highlighting-opts.html', # bc of span elements inside code element + 'test/testcases/block/11_ial/simple.html', # bc of change of ordering of attributes in header + 'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element + 'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option + 'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option + 'test/testcases/block/16_toc/toc_exclude.html', # bc of different attribute ordering + 'test/testcases/span/autolinks/url_links.html', # bc of quot entity being converted to char + 'test/testcases/block/14_table/empty_tag_in_cell.html', # bc of tidy + 'test/testcases/span/01_link/link_defs_with_ial.html', # bc of attribute ordering + 'test/testcases/span/05_html/mark_element.html', # bc of tidy + 'test/testcases/block/09_html/xml.html', # bc of tidy + 'test/testcases/span/05_html/xml.html', # bc of tidy + 'test/testcases/block/03_paragraph/standalone_image.html', # bc of standalone image + 'test/testcases/block/15_math/normal.html', # bc of mathjax and HTML parser + 'test/testcases/block/15_math/gh_128.html', # bc of mathjax and HTML parser + 'test/testcases/span/04_footnote/backlink_inline.html', # bc of mathjax + 'test/testcases/block/09_html/standalone_image_in_div.html', # bc of standalone image + 'test/testcases/block/09_html/processing_instruction.html', # bc of PI + 'test/testcases/block/04_header/with_header_links.html', # bc of header_links option + ].compact + Dir[File.dirname(__FILE__) + '/testcases/**/*.html'].each do |html_file| + next if EXCLUDE_HTML_KD_FILES.any? {|f| html_file =~ /#{f}$/ } + define_method('test_' + html_file.tr('.', '_') + "_to_kramdown_to_html") do + kd = Kramdown::Document.new(File.read(html_file), input: 'html', + auto_ids: false, footnote_nr: 1).to_kramdown + opts_file = html_file.sub(/\.html$/, '.options') + opts_file = File.join(File.dirname(html_file), 'options') unless File.exist?(opts_file) + options = File.exist?(opts_file) ? YAML.load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1} + doc = Kramdown::Document.new(kd, options) + assert_equal(tidy_output(File.read(html_file)), tidy_output(doc.to_html)) + end + end + end + + # Generate test methods for text-manpage conversion + Dir[File.dirname(__FILE__) + '/testcases/man/**/*.text'].each do |text_file| + define_method('test_' + text_file.tr('.', '_') + "_to_man_extra") do + man_file = text_file.sub(/\.text$/, '.man') + doc = Kramdown::Document.new(File.read(text_file)) + assert_equal(File.read(man_file), doc.to_man) + end + end + + EXCLUDE_MODIFY = [ + 'test/testcases/block/06_codeblock/rouge/multiple.text', # bc of HTMLFormater in options + 'test/testcases/block/04_header/with_header_links.text', # bc of header_links option + ].compact + + # Generate test methods for asserting that converters don't modify the document tree. + Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| + opts_file = text_file.sub(/\.text$/, '.options') + options = File.exist?(opts_file) ? YAML.load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1} + (Kramdown::Converter.constants.map(&:to_sym) - + [:Base, :RemoveHtmlTags, :MathEngine, :SyntaxHighlighter]).each do |conv_class| + next if EXCLUDE_MODIFY.any? {|f| text_file =~ /#{f}$/ } + define_method("test_whether_#{conv_class}_modifies_tree_with_file_#{text_file.tr('.', '_')}") do + doc = Kramdown::Document.new(File.read(text_file), options) + options_before = Marshal.load(Marshal.dump(doc.options)) + abbrev_proc = doc.root.options[:abbrev_defs].default_proc + doc.root.options[:abbrev_defs].default_proc = doc.root.options[:abbrev_attr].default_proc = nil + tree_before = Marshal.load(Marshal.dump(doc.root)) + doc.root.options[:abbrev_defs].default_proc = doc.root.options[:abbrev_attr].default_proc = + abbrev_proc + Kramdown::Converter.const_get(conv_class).convert(doc.root, doc.options) + assert_equal(options_before, doc.options) + assert_tree_not_changed(tree_before, doc.root) + end + end + end + + def assert_tree_not_changed(old, new) + assert_equal(old.type, new.type, "type mismatch") + if old.value.kind_of?(Kramdown::Element) + assert_tree_not_changed(old.value, new.value) + else + assert(old.value == new.value, "value mismatch") + end + assert_equal(old.attr, new.attr, "attr mismatch") + assert_equal(old.options, new.options, "options mismatch") + assert_equal(old.children.length, new.children.length, "children count mismatch") + + old.children.each_with_index do |child, index| + assert_tree_not_changed(child, new.children[index]) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_location.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_location.rb new file mode 100644 index 0000000..533ba5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_location.rb @@ -0,0 +1,216 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'minitest/autorun' +require 'kramdown' + +Encoding.default_external = 'utf-8' + +describe 'location' do + # checks that +element+'s :location option corresponds to the location stored + # in the element.attr['class'] + def check_element_for_location(element) + if (match = /^line-(\d+)/.match(element.attr['class'] || '')) + expected_line = match[1].to_i + assert_equal(expected_line, element.options[:location]) + end + element.children.each do |child| + check_element_for_location(child) + end + end + + # Test cases consist of a kramdown string that uses IALs to specify the expected + # line numbers for a given element. + test_cases = { + 'autolink' => %(testing autolinks\n\n{:.line-3}), + 'blockquote' => %( + > block quote1 + > + > * {:.line-3} list item in block quote + > * {:.line-4} list item in block quote + > {:.line-3} + {:.line-1} + + > block quote2 + {:.line-8} + ), + 'codeblock' => %(\na para\n\n~~~~\ntest code 1\n~~~~\n{:.line-3}\n\n test code 2\n{:.line-8}\n), + 'codespan' => %(a para\n\nanother para ``{:.line-3} with code\n), + 'emphasis' => %( + para *span*{:.line-1} + {:.line-1} + + ## header *span*{:.line-4} + {:.line-4} + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum *short span on single line*{:.line-11} + dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + *long span over multiple lines - proident, sunt in culpa qui officia deserunt + mollit anim id est laborum.*{:.line-13} + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + `code span`{:.line-18} + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + {:.line-7} + ), + 'header' => %( + # header1 + {:.line-1} + + ## header2 + {:.line-4} + + ## header3 + {:.line-7} + + header4 + ======= + {:.line-10} + + ^ + + header5 + ------- + {:.line-16} + ), + 'horizontal_rule' => %(\na para\n\n----\n{:.line-3}\n), + 'html_entity' => "a para\n\nanother para with &{:.line-3} html entity.\n", + 'link' => %( + a para + + This is [a link](http://rubyforge.org){:.line-3} to a page. + + Here comes a ![smiley](../images/smiley.png){:.line-5} + ), + 'list' => %( + * {:.line-1} list item + * {:.line-2} list item + * {:.line-3} list item + {:.line-1} + + {:.line-7} + 1. {:.line-7} list item + 2. {:.line-8} list item + 3. {:.line-9} list item + + {:.line-12} + definition term 1 + : {:.line-13} definition definition 1 + definition term 2 + : {:.line-15} definition definition 2 + ), + 'math_block' => %(\na para\n\n$$5+5$$\n{:.line-3}\n), + 'math_inline' => %(\na para\n\nanother para with inline math $$5+5$${:.line-3}\n), + 'paragraph' => %( + para1 + {:.line-1} + + para2 + {:.line-4} + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + {:.line-7} + + {:.line-14} + para with leading IAL + ), + 'table' => %( + a para + + |first|second|third| + |-----|------|-----| + |a |b |c | + {:.line-3} + ), + 'typographic_symbol' => %( + a para + + another para ---{:.line-3} + + another para ...{:.line-5} + ), + 'gh issue 129' => %( + `|` + {:.line-1} + ), + 'gh issue 131' => %( + * {:.line-1} test + line 2 + * {:.line-3} second + * {:.line-4} third + * {:.line-5} * {:.line-5} one + * {:.line-6} two + ), + 'gh issue 158' => %( + 😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁 + {:.line-1} + + - {:.line-4} T + {:.line-4} + + # T + {:.line-7} + ), + 'gh issue 243 - HTML raw elements' => %( +
    +
  • Test
  • +
+ ), + } + test_cases.each do |name, test_string| + it "Handles #{name}" do + doc = Kramdown::Document.new(test_string.gsub(/^ /, '').strip) + check_element_for_location(doc.root) + end + end + + it 'adds location info to duplicate abbreviation definition warnings' do + test_string = %(This snippet contains a duplicate abbreviation definition + +*[duplicate]: The first definition +*[duplicate]: The second definition + ) + doc = Kramdown::Document.new(test_string.strip) + assert_equal(["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"], doc.warnings) + end + + it 'handles abbreviations' do + str = "This *is* ABC and\n**and** ABC second\nanother ABC\nas ABC as\nABC at the end.\n\n*[ABC]: ABC" + doc = Kramdown::Document.new(str) + doc.root.children.first.children.select {|e| e.type == :abbreviation }.each_with_index do |e, i| + assert_equal(i + 1, e.options[:location]) + end + end + + it 'handles line breaks' do + str = "First \nsecond\\\\\nthird \n" + doc = Kramdown::Document.new(str) + doc.root.children.first.children.select {|e| e.type == :br }.each_with_index do |e, i| + assert_equal(i + 1, e.options[:location]) + end + end + + it 'handles smart quotes' do + str = "This is 'first'\nand 'second' and\n'third'" + doc = Kramdown::Document.new(str) + doc.root.children.first.children.select {|e| e.type == :smart_quote }.each_with_index do |e, i| + assert_equal(((i + 1) / 2.0).ceil, e.options[:location]) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_string_scanner_kramdown.rb b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_string_scanner_kramdown.rb new file mode 100644 index 0000000..7efc4d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/test_string_scanner_kramdown.rb @@ -0,0 +1,27 @@ +# -*- coding: utf-8; frozen_string_literal: true -*- +# +#-- +# Copyright (C) 2009-2026 Thomas Leitner +# +# This file is part of kramdown which is licensed under the MIT. +#++ +# + +require 'minitest/autorun' +require 'kramdown/utils/string_scanner' + +describe Kramdown::Utils::StringScanner do + [ + ["...........X............", [/X/], 1], + ["1\n2\n3\n4\n5\n6X", [/X/], 6], + ["1\n2\n3\n4\n5\n6X\n7\n8X", [/X/, /X/], 8], + [(".\n" * 1000) + 'X', [/X/], 1001], + ].each_with_index do |test_data, i| + test_string, scan_regexes, expect = test_data + it "computes the correct current_line_number for example ##{i + 1}" do + str_sc = Kramdown::Utils::StringScanner.new(test_string) + scan_regexes.each {|scan_re| str_sc.scan_until(scan_re) } + assert_equal(expect, str_sc.current_line_number) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.html new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.html @@ -0,0 +1 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.text new file mode 100644 index 0000000..2cbdaa6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/spaces.text @@ -0,0 +1,3 @@ + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.html new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.html @@ -0,0 +1 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.text new file mode 100644 index 0000000..69d6a47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/01_blank_line/tabs.text @@ -0,0 +1,6 @@ + + + + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.html new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.html @@ -0,0 +1 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.text new file mode 100644 index 0000000..8d15802 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/beginning.text @@ -0,0 +1,3 @@ +^ + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.html new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.html @@ -0,0 +1 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.text new file mode 100644 index 0000000..db56ec3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/end.text @@ -0,0 +1,3 @@ + + +^ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.html new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.html @@ -0,0 +1 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.text new file mode 100644 index 0000000..87210a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/02_eob/middle.text @@ -0,0 +1,5 @@ + + +^ + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html new file mode 100644 index 0000000..810cfc0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html @@ -0,0 +1,18 @@ +

This is a para.

+ +

This is a para.

+ +

This is a para.

+ +

This is a para.

+ +
This is a code block.
+
+ +

And this is another.

+ +

A para + with + mixed +indents. + and with much indent

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html.gfm b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html.gfm new file mode 100644 index 0000000..4440c62 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.html.gfm @@ -0,0 +1,18 @@ +

This is a para.

+ +

This is a para.

+ +

This is a para.

+ +

This is a para.

+ +
This is a code block.
+
+ +

And this is another.

+ +

A para +
with +
mixed +
indents. +
and with much indent

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.text new file mode 100644 index 0000000..5849f5b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/indented.text @@ -0,0 +1,19 @@ +This is a para. + + This is a para. + + This is a para. + + This is a para. + + This is a code block. + + + +And this is another. + +A para + with + mixed +indents. + and with much indent diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.html new file mode 100644 index 0000000..9bc47db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.html @@ -0,0 +1,9 @@ +

First line
+https://example.com

+ +

First line
+https://example.com

+ +

Last Line

+ +

Last Line\

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.text new file mode 100644 index 0000000..bbc4cc5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/line_break_last_line.text @@ -0,0 +1,9 @@ +First line + + +First line\\ + + +Last Line + +Last Line\\ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.html new file mode 100644 index 0000000..6a209e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.html @@ -0,0 +1,5 @@ +

One paragraph +over + multiple lines.

+ +

Second one without newline.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.text new file mode 100644 index 0000000..7f1169d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/no_newline_at_end.text @@ -0,0 +1,5 @@ + One paragraph +over + multiple lines. + +Second one without newline. \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.html new file mode 100644 index 0000000..0d20e17 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.html @@ -0,0 +1 @@ +

This is just a normal paragraph.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.text new file mode 100644 index 0000000..0b01324 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/one_para.text @@ -0,0 +1 @@ +This is just a normal paragraph. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.html new file mode 100644 index 0000000..7faa971 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.html @@ -0,0 +1,13 @@ +

para

+ +
+ standalone image +
standalone image
+
+ +
+ standalone image +
standalone image
+
+ +

para

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.text new file mode 100644 index 0000000..3010140 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/standalone_image.text @@ -0,0 +1,9 @@ +para +{:standalone} + +![standalone image](some.jpg){:#id .class key="value" standalone} + +![standalone image](some.jpg){:#id .class key="value" standalone} +{:#block-id .block-class block-key="block-value"} + +para diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.kramdown b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.kramdown new file mode 100644 index 0000000..2108d98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.kramdown @@ -0,0 +1,7 @@ +aa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa +\: No definiion list + +a: + +*a*: + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.text new file mode 100644 index 0000000..031d2d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/to_kramdown.text @@ -0,0 +1,5 @@ +aa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa : No definiion list + +a: + +*a*: diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.html new file mode 100644 index 0000000..d6194ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.html @@ -0,0 +1,4 @@ +

This is just a normal paragraph. +That goes on to the second line.

+ +

Another paragraph.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.text new file mode 100644 index 0000000..b0c730d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/two_para.text @@ -0,0 +1,4 @@ +This is just a normal paragraph. +That goes on to the second line. + +Another paragraph. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.html new file mode 100644 index 0000000..a8831e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.html @@ -0,0 +1 @@ +

some text

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.options new file mode 100644 index 0000000..63936b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.options @@ -0,0 +1 @@ +:html_to_native: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.text new file mode 100644 index 0000000..e5fe18a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/03_paragraph/with_html_to_native.text @@ -0,0 +1 @@ +

some text diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.html new file mode 100644 index 0000000..0704107 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.html @@ -0,0 +1,57 @@ +

This is a header

+ +

This is a header

+ +

This is a header

+ +

This is a header

+ +
This is a header
+ +
This is a header
+ +

Header

+

Header

+ +

Header

+
+

blockquote

+
+ +
header
+

paragraph

+ +
+

blockquote +### not a header

+
+ +

header

+ +

header

+ +

header

+ +

header #

+ +

header

+ +

#

+ +

#

+ +

Header

+ +

Header

+ +

Header

+ +

Header

+ +

Header {#9ab}

+ +

Header{#noid}

+ +

Header ##{#noid}

+ +

Last

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.text new file mode 100644 index 0000000..392b3f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header.text @@ -0,0 +1,54 @@ +# This is a header + +## This is a header + +### This is a header + +#### This is a header + +##### This is a header + +###### This is a header + +# Header +^ +# Header + +##Header ##### +> blockquote + +###### header +paragraph + +> blockquote +### not a header + +# header # + +# header# + +#header# + +# header \# + +# header + +# + +# + +### Header {#id} + +### Header ## {#Id} + +### Header ## {#id} + +### Header {#A-Za-z0-9_:t} + +### Header {#9ab} + +### Header{#noid} + +### Header ##{#noid} + +### Last diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.html new file mode 100644 index 0000000..9f49c3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.html @@ -0,0 +1 @@ +

header

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.text new file mode 100644 index 0000000..7b74be4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/atx_header_no_newline_at_end.text @@ -0,0 +1 @@ +# header \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.html new file mode 100644 index 0000000..e031b9a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.html @@ -0,0 +1,11 @@ +

Lorem ipsum

+ +

Lorem ipsum

+ +

Lorem ipsum

+ +
Lorem ipsum
+ +

Lorem ipsum

+ +

Lorem ipsum

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.kramdown b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.kramdown new file mode 100644 index 0000000..a77deb9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.kramdown @@ -0,0 +1,12 @@ +## Lorem ipsum + +### Lorem ipsum + +#### Lorem ipsum + +###### Lorem ipsum + +## Lorem ipsum + +### Lorem ipsum + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.latex new file mode 100644 index 0000000..c9017e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.latex @@ -0,0 +1,12 @@ +\subsection*{Lorem ipsum} + +\subsubsection*{Lorem ipsum} + +\paragraph*{Lorem ipsum} + +\subparagraph*{Lorem ipsum} + +\subsection*{Lorem ipsum} + +\subsubsection*{Lorem ipsum} + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.options new file mode 100644 index 0000000..a805035 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.options @@ -0,0 +1,2 @@ +:header_offset: 1 +:auto_ids: false \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.text new file mode 100644 index 0000000..bfaefa2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/header_type_offset.text @@ -0,0 +1,13 @@ +# Lorem ipsum + +## Lorem ipsum + +### Lorem ipsum + +###### Lorem ipsum + +Lorem ipsum +=========== + +Lorem ipsum +----------- diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.html new file mode 100644 index 0000000..147c345 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.html @@ -0,0 +1,32 @@ +

test

+ +

test2

+ +

test

+

para

+ +
   header =
+
+ +

=

+ +

This is a para. +With two lines. +And not a header. +=================

+ +
+

Blockquote. +Not a Header +-

+
+ +

header

+ +

header

+ +

header

+ +

header{#noid}

+ +

header

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.text new file mode 100644 index 0000000..ae94ecd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header.text @@ -0,0 +1,39 @@ +test +- + +test2 +========= + +test +- +para + + header += + + += + +This is a para. +With two lines. +And not a header. +================= + +> Blockquote. +Not a Header +- + +header {#id} +------------ + +header {#Id} +====== + +header {#A-Za-z0-9_:} +------ + +header{#noid} +----- + +header +------ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.html new file mode 100644 index 0000000..9f49c3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.html @@ -0,0 +1 @@ +

header

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.text new file mode 100644 index 0000000..0f00750 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/setext_header_no_newline_at_end.text @@ -0,0 +1,2 @@ +header +====== \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.html new file mode 100644 index 0000000..724d391 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.html @@ -0,0 +1,3 @@ +

Header 1

+ +

123

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.options new file mode 100644 index 0000000..83305cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.options @@ -0,0 +1,2 @@ +:auto_ids: true +:auto_id_prefix: hallo_ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.text new file mode 100644 index 0000000..acf09fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_prefix.text @@ -0,0 +1,3 @@ +# Header 1 + +# 123 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.html new file mode 100644 index 0000000..1d342cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.html @@ -0,0 +1 @@ +

This is a header

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.options new file mode 100644 index 0000000..68800f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.options @@ -0,0 +1 @@ +:auto_id_stripping: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.text new file mode 100644 index 0000000..2b57bc8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_id_stripping.text @@ -0,0 +1 @@ +# This is a header diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.html new file mode 100644 index 0000000..af8126d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.html @@ -0,0 +1,21 @@ +

This is a header

+ +

12. Another one-1-here

+ +

Do ^& it now

+ +

Hallo

+ +

Not now

+ +

Hallo

+ +

23232

+ +

33333

+ +

hallO

+ +

Header without ID

+ +

Transliterated: Đây-là-ví-dụ

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.options new file mode 100644 index 0000000..0a1fec8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.options @@ -0,0 +1,2 @@ +:auto_ids: true +:transliterated_header_ids: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.text new file mode 100644 index 0000000..f4cd91b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_auto_ids.text @@ -0,0 +1,24 @@ +# This is a header + +## 12. Another one-1-here + +### Do ^& it now + +Hallo +===== + +Not now +------- + +# Hallo + +# 23232 + +# 33333 + +## hallO + +# Header without ID +{: id=""} + +# Transliterated: Đây-là-ví-dụ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.html new file mode 100644 index 0000000..64ae37f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.html @@ -0,0 +1,7 @@ +

This is a header

+ +

12. Another one-1-here

+ +

Do ^& it now

+ +

Header without ID

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.options new file mode 100644 index 0000000..87f9047 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.options @@ -0,0 +1,2 @@ +:header_links: true +:auto_ids: false diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.text new file mode 100644 index 0000000..0166e29 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_header_links.text @@ -0,0 +1,8 @@ +# This is a header {#header} + +## 12. Another one-1-here + +### Do ^& it now + +# Header without ID +{: id=""} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.html new file mode 100644 index 0000000..880dc9e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.html @@ -0,0 +1 @@ +

foo
bar

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.text new file mode 100644 index 0000000..c7fe2ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/04_header/with_line_break.text @@ -0,0 +1 @@ +# foo
bar diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.html new file mode 100644 index 0000000..734bb7a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.html @@ -0,0 +1,25 @@ +
+

A normal blockquote.

+
+ +
+

A normal blockquote.

+
+ +
+

A normal blockquote.

+
+ +
+

A normal blockquote.

+
+ +
> A codeblock
+
+ +
+

Blockquote +with +mixed +indents.

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.text new file mode 100644 index 0000000..70850b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/indented.text @@ -0,0 +1,14 @@ +> A normal blockquote. + + > A normal blockquote. + + > A normal blockquote. + + > A normal blockquote. + + > A codeblock + +> Blockquote + > with + >mixed +> indents. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.html new file mode 100644 index 0000000..00a2102 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.html @@ -0,0 +1,34 @@ +
+

This is a long +long line.

+
+ +
+
+

Nested quote +inside +still inside

+
+
+ +
+
+

This is a subquote. +over multipline lines. +continuing +here

+
+
+ +
+

This is a quote + no code

+
+ +
+

This is a quote

+
+ +
+

This is a quote

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.text new file mode 100644 index 0000000..adde6a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/lazy.text @@ -0,0 +1,20 @@ +> This is a long +long line. + +> > Nested quote +inside +> still inside + +> > This is a subquote. +> > over multipline lines. +> continuing +here + +> This is a quote + no code + +> This is a quote +{: #id} + +> This is a quote +^ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.html new file mode 100644 index 0000000..4bc94f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.html @@ -0,0 +1,10 @@ +
+

foo

+ +
+

bar + baz

+
+ +

foo

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.text new file mode 100644 index 0000000..2176882 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/nested.text @@ -0,0 +1,6 @@ +> foo +> +> > bar +>> baz +> +> foo diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.html new file mode 100644 index 0000000..1de4a60 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.html @@ -0,0 +1,4 @@ +
+

This is a block quote +with no newline.

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.text new file mode 100644 index 0000000..402648a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/no_newline_at_end.text @@ -0,0 +1,2 @@ +> This is a block quote +> with no newline. \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.html new file mode 100644 index 0000000..4a9aaf5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.html @@ -0,0 +1,3 @@ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.text new file mode 100644 index 0000000..a2b33bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/very_long_line.text @@ -0,0 +1 @@ +> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.html new file mode 100644 index 0000000..30abd99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.html @@ -0,0 +1,15 @@ +
+

Example:

+ +
sub status {
+    print "working";
+}
+
+ +

Or:

+ +
sub status {
+    return "working";
+}
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.text new file mode 100644 index 0000000..3b188dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/05_blockquote/with_code_blocks.text @@ -0,0 +1,11 @@ +>Example: +> +> sub status { +> print "working"; +> } +> +> Or: +> +> sub status { +> return "working"; +> } diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.html new file mode 100644 index 0000000..142a5d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.html @@ -0,0 +1,4 @@ +
x = Class.new
+
+
<a>href</a>
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.options new file mode 100644 index 0000000..72e9bc1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.options @@ -0,0 +1 @@ +:enable_coderay: false diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.text new file mode 100644 index 0000000..af4d0bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/disable-highlighting.text @@ -0,0 +1,4 @@ + x = Class.new +^ + href +{: lang="html"} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.html new file mode 100644 index 0000000..d9f9da3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.html @@ -0,0 +1,4 @@ +

Some para

+ +

~~~~~~ +not codeblock

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.text new file mode 100644 index 0000000..60ea366 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/error.text @@ -0,0 +1,4 @@ +Some para + +~~~~~~ +not codeblock diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.html new file mode 100644 index 0000000..066e909 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.html @@ -0,0 +1,15 @@ +
class Foo
+  def bar
+    puts 'Hello'
+  end
+end
+
+
+ +
class Foo
+  def bar
+    puts 'Hello'
+  end
+end
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.options new file mode 100644 index 0000000..bfc92f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.options @@ -0,0 +1,2 @@ +:syntax_highlighter_opts: + guess_lang: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.text new file mode 100644 index 0000000..4b074a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/guess_lang_css_class.text @@ -0,0 +1,13 @@ +~~~ +class Foo + def bar + puts 'Hello' + end +end +~~~ + + class Foo + def bar + puts 'Hello' + end + end diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex new file mode 100644 index 0000000..a092a1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex @@ -0,0 +1,9 @@ +\begin{minted}[breaklines,linenos]{ruby} +x = Class.new + +\end{minted} + +\begin{minted}[breaklines,linenos]{html} +this is a reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, long link + +\end{minted} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.options new file mode 100644 index 0000000..b773fc8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.options @@ -0,0 +1,4 @@ +:syntax_highlighter: minted +:syntax_highlighter_opts: + wrap: true + line_numbers: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.text new file mode 100644 index 0000000..2636518 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted-with-opts.text @@ -0,0 +1,5 @@ + x = Class.new +{: .language-ruby} + + this is a reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, long link +{: .language-html} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.latex new file mode 100644 index 0000000..354d6ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.latex @@ -0,0 +1,8 @@ +\begin{minted}[]{ruby} +x = Class.new + +\end{minted} +\begin{minted}[]{html} +href + +\end{minted} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.options new file mode 100644 index 0000000..b2ee189 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.options @@ -0,0 +1,3 @@ +:syntax_highlighter: minted +:syntax_highlighter_opts: + default_lang: ruby diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.text new file mode 100644 index 0000000..5ac4746 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-minted.text @@ -0,0 +1,4 @@ + x = Class.new +^ + href +{: .language-html} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.html new file mode 100644 index 0000000..b694d37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.html @@ -0,0 +1,6 @@ +
x = Class.new
+
+
+
<a>href</a>
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.options new file mode 100644 index 0000000..be21a32 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.options @@ -0,0 +1,7 @@ +:syntax_highlighter_opts: + block: + css: class + default_lang: ruby + wrap: span + line_numbers: null + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.text new file mode 100644 index 0000000..5ac4746 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting-opts.text @@ -0,0 +1,4 @@ + x = Class.new +^ + href +{: .language-html} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.html new file mode 100644 index 0000000..33dd015 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.html @@ -0,0 +1,5 @@ +
x = Class.new
+
+
<a>href</a>
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.options new file mode 100644 index 0000000..8133537 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.options @@ -0,0 +1,5 @@ +:coderay_default_lang: ruby +:coderay_wrap: span +:coderay_line_numbers: ~ +:coderay_css: class + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.text new file mode 100644 index 0000000..5ac4746 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/highlighting.text @@ -0,0 +1,4 @@ + x = Class.new +^ + href +{: .language-html} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.html new file mode 100644 index 0000000..b096a9e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.html @@ -0,0 +1,164 @@ + +

B

+ +
                       BBBBBBBB. 
+
+
+
+           BBBB BB BBBBBBBB BBBBB. BBBBBBB BB BBBBB BB BBB BBBB BBBBB BBB BBB BBBB BBB BBBBBBB BBB BBBBBBB. B BBB'B BBBBB BBBB BBB BBBB BBBBBBB BBBB BBBB BBBB BBBBBBBB.
+
+
+                BBB BBBBB BBBBB BBB BBBB BBBB BBBB, BBB BBBBB BB BBBBB BBB BB BBBBBB BBBB BBB BBBBB BBBB BB. BBBBB BBB BBBBB BBBBB BBB BBBB BB BBBB BBBB BBBBB.
+
+
+                         BBBB BBBBB, BBBBB, BBBBBBBB?
+
+                   BB BBB BB BBBB BBB BBBB BBB BBBBBB /BBB BB BBBBBBBBB BBBB BBBBBBB BBBBBB BB BBB. 
+
+
+                   BBBB BBBBBBBB BBB BBBB BB BBBBB BBB BBBBBB BBBB BBBBB BBBBBB BBBBBBBBB BBBB BB BBBBB......................................................................
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+              BBBBB B'B BBB BBBBB. BBBB BBBBB BBBBB. ( B BBBBB BBBBBBBBBB BBBBB BBBB'B BBBBB BBBBB. BBB BBBB BBBBB BBBB BBBB. BBBBBBB BBB BB BBBBBBB BBB BBB B BBBB BBBBBBBBBBBB. BBBBB BBBBB.)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+             BBBB'B BB
+
+ +

.

+ +
        B BBB BBB BBB ? B. B BBB BBBBBB BBBB BBB BBBB. BBBBBBB BB BBBBBBB B BBBB BBBB BBB BBBBBB. 
+
+
+
+
+
+
+
+
+
+
+
+
+
+         BBBB BB 'BBBB' BBBB BBBBB.
+
+
+                           BBBBBBBB B BBBB BBBBBB BB BBBBBBBB BBB BBBBBBB BBBBBBB BBBBBBB. 
+
+
+     B BBBB BB BBBB. BBBBB BBBBBBBB. BBB BB BB. BB BB BBBB BB BBBBBBBBBB. BB BBBBBBBB BB BBBBBBBBB. 
+
+
+                     BBBBBBBB BB BBBB. BBBBBBB BBB BBBBB BBBBB BBBBB. B'BB BBBBBBB BB BBBBB BBBBB BBBBBBB BBB BBBBB. BBBB. 
+
+  B BBBBBB BBBB BB BBBB BBB. (BB BBB BBBBB BBBBB...............B)
+
+
+
+           BBBB!
+
+
+
+         BBBB BB BBB BBBBBBB BBBBBB.            B
+
+ +

B

+ +
     BBBBB BB/BBB BBBBB!  BBBB BBBB BBBBBBBBBBB 'BBB'B BBBBBB.' 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          BBBB BBBBBBB BBBB BB BBB BBBBBBBB BB BBBB BBBBBB BBB BBBBBBBBB BBBB. BBBBBBBB BBBBBBB BBBB BBBB BBBB BB BBBB BB BBBB BB BBBB B BBB BB BBBBB BBBBBB.  B BBBB BBBBBBB BB BBBB BBBBB B BBB BBBBBBB BB BBBBB BBBB. BBB BBBBBBB BBBB. B BBB BBBB BBBB B BBBB BBBBBB BBB B BBBBBB BBBBBB. BBB BB BBBBBB BBBBBB BBBBBBBBBB BB...BBBBB BBBB BBBB BB BBBBB. (BBBBBBB BBB BBBBBB BBB'B BBBB BBB BBBBB BBB BB BBBBB BBBBBBBBBBB  BBBBB B BBBB BBBB BBBBB. 
+
+
+
+
+
+
+
+
+
+BBBBB BB BB BBBB B'B BBBB BBBBB BBBBB BBB BB BBBBBB/BBB (BBBBB) BBBBBB BB. 
+                          BBBBBBBB. B BBB BBBB BB BB BBB/BBBBBB BBBBBB BBB BBBB BBBBBBBB BB BB B BBBBBB BBBBBB BBBBB. (BBB/B BBB BBBB BBBB...BBB BBB BBB BBBB BB BB B BBBB BB BBB BB? BBBBBBB B BBB B BBBB BBBBBBBB BBB B BBB BBB BBBBB BBBB BBB BBBB BB B BBBBBBBB BB BBBBB BB BB BBB BBBBB BBB BB BBBBB BBBBBBB B BBB BBBBBBB. BBBBBB (BBBBB) BBBB BBBBB BBBBBBB BBBBB BBBB BBBB BBB. 100 BBBBBB BB BBBBB. BBBB BBB BBB BBBBBB BBB BB. BBB BBBB BB BBB BBBBB! BBB BB BBBBBB BBBBB B BBB'B BBBBBBBBB BBBB BBB BBB. (BBBBBB BBBBBBB BB BBBB BBBBB (BBBBBB BBBBB BBBBB BBBBB.))
+
+
+    BBB B BBBBBBBBBBB BBBB BBB BB BBB. BBBBB BBB BBBBB B BBBB BBBBBB BBBBB BBB. BB BBBBBB BBB BBBB B BBB BB BBBBBBBB BBBBBB BBBB BBB B BBBBBB BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBBBBBB.
+
+
+
+
+
+
+
+
+
+
+
+           BBBBB!!!!!!!
+
+
+         B BBB BBBB BBBBBB BBBB BBBB BBBB B BBB BBBBB BBB BBBBB B BBBB BBBBBBB BB BB BBBB BBBBBBBBB. B BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBB.
+
+                                               BB BB, BB BBBBBB BBBB, (BBBBBB BB BBB BBBB . BBBBB BB BBBB BBBB BB BB BBBB BBBB B BBBB BB BB (BB BBBB BB BBB BBBBBBB BB BBBBBBB. )) BB'BB BBB BBB'B BB BB BBBB BB B BBBB B BBBBB (BB BBBBBB BB BBB B'BB BBBBBBBB BB BBBB BBBB.)
+
+
+  B BBBBB B'BB BBB BB BBBB BBB BBB.
+
+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.test b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.test new file mode 100644 index 0000000..1bf8901 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/issue_gh45.test @@ -0,0 +1,188 @@ + + + B + + + + + BBBBBBBB. + + + + BBBB BB BBBBBBBB BBBBB. BBBBBBB BB BBBBB BB BBB BBBB BBBBB BBB BBB BBBB BBB BBBBBBB BBB BBBBBBB. B BBB'B BBBBB BBBB BBB BBBB BBBBBBB BBBB BBBB BBBB BBBBBBBB. + + + BBB BBBBB BBBBB BBB BBBB BBBB BBBB, BBB BBBBB BB BBBBB BBB BB BBBBBB BBBB BBB BBBBB BBBB BB. BBBBB BBB BBBBB BBBBB BBB BBBB BB BBBB BBBB BBBBB. + + + BBBB BBBBB, BBBBB, BBBBBBBB? + + BB BBB BB BBBB BBB BBBB BBB BBBBBB /BBB BB BBBBBBBBB BBBB BBBBBBB BBBBBB BB BBB. + + + BBBB BBBBBBBB BBB BBBB BB BBBBB BBB BBBBBB BBBB BBBBB BBBBBB BBBBBBBBB BBBB BB BBBBB...................................................................... + + + + + + + + + + + + + + + + + + + + + + BBBBB B'B BBB BBBBB. BBBB BBBBB BBBBB. ( B BBBBB BBBBBBBBBB BBBBB BBBB'B BBBBB BBBBB. BBB BBBB BBBBB BBBB BBBB. BBBBBBB BBB BB BBBBBBB BBB BBB B BBBB BBBBBBBBBBBB. BBBBB BBBBB.) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BBBB'B BB + + + + + + + + + + + + + + + + + + +. + + B BBB BBB BBB ? B. B BBB BBBBBB BBBB BBB BBBB. BBBBBBB BB BBBBBBB B BBBB BBBB BBB BBBBBB. + + + + + + + + + + + + + + BBBB BB 'BBBB' BBBB BBBBB. + + + BBBBBBBB B BBBB BBBBBB BB BBBBBBBB BBB BBBBBBB BBBBBBB BBBBBBB. + + + B BBBB BB BBBB. BBBBB BBBBBBBB. BBB BB BB. BB BB BBBB BB BBBBBBBBBB. BB BBBBBBBB BB BBBBBBBBB. + + + BBBBBBBB BB BBBB. BBBBBBB BBB BBBBB BBBBB BBBBB. B'BB BBBBBBB BB BBBBB BBBBB BBBBBBB BBB BBBBB. BBBB. + + B BBBBBB BBBB BB BBBB BBB. (BB BBB BBBBB BBBBB...............B) + + + + BBBB! + + + + BBBB BB BBB BBBBBBB BBBBBB. +B + +B + + + + BBBBB BB/BBB BBBBB! BBBB BBBB BBBBBBBBBBB 'BBB'B BBBBBB.' + + + + + + + + + + + + + + + BBBB BBBBBBB BBBB BB BBB BBBBBBBB BB BBBB BBBBBB BBB BBBBBBBBB BBBB. BBBBBBBB BBBBBBB BBBB BBBB BBBB BB BBBB BB BBBB BB BBBB B BBB BB BBBBB BBBBBB. B BBBB BBBBBBB BB BBBB BBBBB B BBB BBBBBBB BB BBBBB BBBB. BBB BBBBBBB BBBB. B BBB BBBB BBBB B BBBB BBBBBB BBB B BBBBBB BBBBBB. BBB BB BBBBBB BBBBBB BBBBBBBBBB BB...BBBBB BBBB BBBB BB BBBBB. (BBBBBBB BBB BBBBBB BBB'B BBBB BBB BBBBB BBB BB BBBBB BBBBBBBBBBB BBBBB B BBBB BBBB BBBBB. + + + + + + + + + + BBBBB BB BB BBBB B'B BBBB BBBBB BBBBB BBB BB BBBBBB/BBB (BBBBB) BBBBBB BB. + BBBBBBBB. B BBB BBBB BB BB BBB/BBBBBB BBBBBB BBB BBBB BBBBBBBB BB BB B BBBBBB BBBBBB BBBBB. (BBB/B BBB BBBB BBBB...BBB BBB BBB BBBB BB BB B BBBB BB BBB BB? BBBBBBB B BBB B BBBB BBBBBBBB BBB B BBB BBB BBBBB BBBB BBB BBBB BB B BBBBBBBB BB BBBBB BB BB BBB BBBBB BBB BB BBBBB BBBBBBB B BBB BBBBBBB. BBBBBB (BBBBB) BBBB BBBBB BBBBBBB BBBBB BBBB BBBB BBB. 100 BBBBBB BB BBBBB. BBBB BBB BBB BBBBBB BBB BB. BBB BBBB BB BBB BBBBB! BBB BB BBBBBB BBBBB B BBB'B BBBBBBBBB BBBB BBB BBB. (BBBBBB BBBBBBB BB BBBB BBBBB (BBBBBB BBBBB BBBBB BBBBB.)) + + + BBB B BBBBBBBBBBB BBBB BBB BB BBB. BBBBB BBB BBBBB B BBBB BBBBBB BBBBB BBB. BB BBBBBB BBB BBBB B BBB BB BBBBBBBB BBBBBB BBBB BBB B BBBBBB BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBBBBBB. + + + + + + + + + + + + BBBBB!!!!!!! + + + B BBB BBBB BBBBBB BBBB BBBB BBBB B BBB BBBBB BBB BBBBB B BBBB BBBBBBB BB BB BBBB BBBBBBBBB. B BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBB. + + BB BB, BB BBBBBB BBBB, (BBBBBB BB BBB BBBB . BBBBB BB BBBB BBBB BB BB BBBB BBBB B BBBB BB BB (BB BBBB BB BBB BBBBBBB BB BBBBBBB. )) BB'BB BBB BBB'B BB BB BBBB BB B BBBB B BBBBB (BB BBBBBB BB BBB B'BB BBBBBBBB BB BBBB BBBB.) + + + B BBBBB B'BB BBB BB BBBB BBB BBB. + + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.html new file mode 100644 index 0000000..47188f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.html @@ -0,0 +1,4 @@ +
This is some code
+
+This is some  other code
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.text new file mode 100644 index 0000000..2a95de6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/lazy.text @@ -0,0 +1,5 @@ + This is some +code + + This is some + other code diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.html new file mode 100644 index 0000000..7a003b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.html @@ -0,0 +1,2 @@ +
test  
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.text new file mode 100644 index 0000000..b64563f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end.text @@ -0,0 +1 @@ + test \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.html new file mode 100644 index 0000000..005870e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.html @@ -0,0 +1,2 @@ +
test   test
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.text new file mode 100644 index 0000000..65df71e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/no_newline_at_end_1.text @@ -0,0 +1,2 @@ + test +test diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.html new file mode 100644 index 0000000..0bd2c1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.html @@ -0,0 +1,13 @@ +
starting code
+
+ +

paragraph

+ +
other code  
+with samples 
+
+ +

paragraph

+ +
  ending code
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.text new file mode 100644 index 0000000..40ea702 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/normal.text @@ -0,0 +1,10 @@ + starting code + +paragraph + + other code + with samples + +paragraph + + ending code diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.html new file mode 100644 index 0000000..2cc34d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.html @@ -0,0 +1,2 @@ +
x = Class.new
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.options new file mode 100644 index 0000000..5688828 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.options @@ -0,0 +1,4 @@ +:syntax_highlighter: rouge +:syntax_highlighter_opts: + block: + disable: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.text new file mode 100644 index 0000000..0e50b41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/disabled.text @@ -0,0 +1 @@ + x = Class.new diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.html new file mode 100644 index 0000000..6ece543 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.html @@ -0,0 +1,11 @@ +
puts "Hello"
+
+
+ +
puts "World"
+
+
+ +
$foo = new Bar;
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.options new file mode 100644 index 0000000..b910f75 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.options @@ -0,0 +1,4 @@ +:syntax_highlighter: rouge +:syntax_highlighter_opts: + default_lang: ruby + formatter: RougeHTMLFormatters diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.text new file mode 100644 index 0000000..d1dd283 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/multiple.text @@ -0,0 +1,11 @@ +~~~ ruby +puts "Hello" +~~~ + +~~~ ruby +puts "World" +~~~ + +~~~ php?start_inline=1 +$foo = new Bar; +~~~ \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.html new file mode 100644 index 0000000..1c2259a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.html @@ -0,0 +1,10 @@ +
x = Class.new
+
+
+
<a>href</a>
+
+
+ +
$foo = new Bar;
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.options new file mode 100644 index 0000000..f59e0ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.options @@ -0,0 +1,3 @@ +:syntax_highlighter: rouge +:syntax_highlighter_opts: + default_lang: ruby diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.text new file mode 100644 index 0000000..6c740e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/rouge/simple.text @@ -0,0 +1,9 @@ + x = Class.new +^ + href +{: .language-html} + + +~~~ php?start_inline=1 +$foo = new Bar; +~~~ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.html new file mode 100644 index 0000000..1ddd91e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.html @@ -0,0 +1,7 @@ +
Here comes some code.
+
+ +
~~~~~~~
+code with tildes
+~~~~~~~~
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.text new file mode 100644 index 0000000..7625a1b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/tilde_syntax.text @@ -0,0 +1,9 @@ +~~~~~~~~ +Here comes some code. +~~~~~~~~ + +~~~~~~~~~~~~ +~~~~~~~ +code with tildes +~~~~~~~~ +~~~~~~~~~~~~~~~~~~ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.html new file mode 100644 index 0000000..dcbb40f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.html @@ -0,0 +1,3 @@ +
This	issome
+whitespace
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.text new file mode 100644 index 0000000..b15c9c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/whitespace.text @@ -0,0 +1,3 @@ + This is some + whitespace +{:.show-whitespaces} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.html new file mode 100644 index 0000000..f7c20b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.html @@ -0,0 +1,13 @@ +

paragraph

+ +
code block
+
+continued here
+
+ +

ended

+ +
next blank line has 4 spaces
+
+ +

paragraph

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.text new file mode 100644 index 0000000..e51dfa5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_blank_line.text @@ -0,0 +1,12 @@ +paragraph + + code block + + continued here + + +ended + + next blank line has 4 spaces + +paragraph diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.html new file mode 100644 index 0000000..cca17a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.html @@ -0,0 +1,6 @@ +
code block
+
+continued here
+
+
new block here
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.text new file mode 100644 index 0000000..834c768 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_eob_marker.text @@ -0,0 +1,5 @@ + code block + + continued here +^ + new block here diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.html new file mode 100644 index 0000000..77085b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.html @@ -0,0 +1,6 @@ +
code block
+
+continued here
+
+
new block here
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.text new file mode 100644 index 0000000..4489f2d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_ial.text @@ -0,0 +1,5 @@ + code block + + continued here +{:.cls} + new block here diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html new file mode 100644 index 0000000..f5872c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html @@ -0,0 +1,24 @@ +
def what?
+  42
+end
+
+ +
def what?
+  42
+end
+
+ +
def what?
+  42
+end
+
+ +
def what?
+  42
+end
+
+ +
def what?
+  42
+end
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options new file mode 100644 index 0000000..e2e91db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options @@ -0,0 +1,2 @@ +:syntax_highlighter: null + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text new file mode 100644 index 0000000..07f437e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text @@ -0,0 +1,33 @@ +~~~ ruby +def what? + 42 +end +~~~ + +~~~ ruby +def what? + 42 +end +~~~ +{:.class1} + +~~~ +def what? + 42 +end +~~~ +{: .language-ruby} + +~~~ ruby +def what? + 42 +end +~~~ +{: .language-python} + +~~~ ruby +def what? + 42 +end +~~~ +{: class="language-python"} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html new file mode 100644 index 0000000..2530b1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html @@ -0,0 +1,8 @@ +
text
+
+ +
text
+
+ +
text
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options new file mode 100644 index 0000000..871923c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options @@ -0,0 +1,2 @@ +:enable_coderay: false + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text new file mode 100644 index 0000000..60424a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text @@ -0,0 +1,11 @@ +~~~ asn.1 +text +~~~ + +~~~ asn#w1 +text +~~~ + +~~~ русский +text +~~~ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html new file mode 100644 index 0000000..aa4b60f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html @@ -0,0 +1,3 @@ +
s1'dim'a'500'm'500'q'500''
+index'j'j+1'j-1''
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options new file mode 100644 index 0000000..871923c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options @@ -0,0 +1,2 @@ +:enable_coderay: false + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text new file mode 100644 index 0000000..423d5b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text @@ -0,0 +1,4 @@ +~~~ act-iii +s1'dim'a'500'm'500'q'500'' +index'j'j+1'j-1'' +~~~ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.html new file mode 100644 index 0000000..068811c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.html @@ -0,0 +1,7 @@ +

_ * _

+ +

— * * *

+ +

_ - *

+ +

———————————————- test

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.text new file mode 100644 index 0000000..a024710 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/error.text @@ -0,0 +1,7 @@ +_ * _ + +--- * * * + +_ - * + +---------------------------------------------- test diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.html new file mode 100644 index 0000000..e74b6e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.html @@ -0,0 +1,19 @@ +
+
+
+ +

d- -

+ +
+
+
+ +

para

+

text

+ +
+ +
- - -
+
+ +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.text new file mode 100644 index 0000000..986101a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/normal.text @@ -0,0 +1,20 @@ +*** +* * * +- - - + +d- - + +--- +___ +*** + +para +----------- +text + +* * * + + - - - + +* * * +{:.test} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.html new file mode 100644 index 0000000..dbb86e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.text new file mode 100644 index 0000000..a5798b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/sepspaces.text @@ -0,0 +1,3 @@ +- - - +* * * +_ _ _ _ _ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.html new file mode 100644 index 0000000..dbb86e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.text new file mode 100644 index 0000000..464fe20 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/07_horizontal_rule/septabs.text @@ -0,0 +1,3 @@ +- - - +* * * +_ _ _ _ _ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.latex new file mode 100644 index 0000000..e71fde2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.latex @@ -0,0 +1,3 @@ +\begin{itemize} +\item{} {[}and{]} another +\end{itemize} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.text new file mode 100644 index 0000000..515e3a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/brackets_in_item.text @@ -0,0 +1 @@ +* \[and\] another diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.html new file mode 100644 index 0000000..5a6ebb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.html @@ -0,0 +1,21 @@ +

I have read the book +1984. It was great +- other say that, too!

+ +

I have read the book +1984. It was great +- other say that, too!

+ +

I have read the book + 1984. It was great.

+ +

I have read the book 1984. + - it was great!

+ +

1984. Was great!

+ +

1984.5 is not a book.

+ +

1984.

+ +

- This too!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.text new file mode 100644 index 0000000..264dcfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/escaping.text @@ -0,0 +1,21 @@ +I have read the book +1984. It was great +- other say that, too! + +I have read the book +1984\. It was great +\- other say that, too! + +I have read the book + 1984. It was great. + +I have read the book 1984. + - it was great! + +1984\. Was great! + +1984.5 is not a book. + +1984\. + +\- This too! diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.html new file mode 100644 index 0000000..e6dfd3a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.html @@ -0,0 +1,10 @@ +
    +
  • IAL at first +continued
  • +
  • another {:.cls}
  • +
  • IAL at last + code
  • +
  • X + test
  • +
  • X OK
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.text new file mode 100644 index 0000000..67bee70 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/item_ial.text @@ -0,0 +1,8 @@ +* {:.cls} IAL at first + continued +* another {:.cls} +* {:.cls} IAL at last + code +* {::nomarkdown type="html"}X{:/nomarkdown} + test +* {::nomarkdown type="html"}X{:/nomarkdown} OK diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.html new file mode 100644 index 0000000..01a5f9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.html @@ -0,0 +1,39 @@ +
    +
  • This is a simple +list item
  • +
  • +

    Followed by another +list item

    +
  • +
  • +

    Followed by

    + +

    a para list item +continued here

    +
  • +
  • and a normal one
  • +
  • +

    and

    + +

    a para +continued here

    +
  • +
+ +

para

+ +
    +
  • multi line +list item
  • +
+ +

para

+ +
    +
  • list item line1 + one line + two lines
  • +
  • list item line2 +one line +two lines
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.text new file mode 100644 index 0000000..f372422 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy.text @@ -0,0 +1,29 @@ +* This is a simple +list item +* Followed by another +list item + + +* Followed by + + a para list item +continued here +* and a normal one +* and + + a para +continued here + +para + +* multi line +list item + +para + +* list item line1 + one line + two lines +* list item line2 + one line +two lines diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.html new file mode 100644 index 0000000..90c7447 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.html @@ -0,0 +1,9 @@ +
    +
  1. Root level + * Second level +
      +
    • Third level + * Back to second level
    • +
    +
  2. +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.text new file mode 100644 index 0000000..97a7755 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/lazy_and_nested.text @@ -0,0 +1,4 @@ +1. Root level + * Second level + * Third level + * Back to second level diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.html new file mode 100644 index 0000000..ecf51c7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.html @@ -0,0 +1,9 @@ +
    +
  • Starting a list
  • +
+ +
+ +
    +
  • Starting a new list
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.text new file mode 100644 index 0000000..c7fcd47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_hr.text @@ -0,0 +1,5 @@ +* Starting a list + +* * * + +* Starting a new list diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.html new file mode 100644 index 0000000..672428e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.html @@ -0,0 +1,40 @@ +
    +
  • list item
  • +
+ +
+

blockquote

+
+ +

para +* * * +para + - no list

+ +
    +
  • +

    item

    + +
    +

    block

    +
    + +

    header

    +
  • +
  • +

    test

    + +
    codeblock
    +
    + +

    test

    +
  • +
  • +

    test

    + +
    codeblock
    +
    + +

    test

    +
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.text new file mode 100644 index 0000000..f680262 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/list_and_others.text @@ -0,0 +1,26 @@ +* list item + +> blockquote + +para +* * * +para + - no list + ++ item + + > block + + ## header + +* test + + codeblock + + test + +* test + + codeblock + + test diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.html new file mode 100644 index 0000000..9bc47e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.html @@ -0,0 +1,117 @@ +

With tabs/spaces, no paras:

+ +
    +
  • item1
  • +
  • item2
  • +
  • item3
  • +
+ +

With tabs/spaces, paras:

+ +
    +
  • +

    item1

    +
  • +
  • +

    item2

    +
  • +
  • +

    item3

    +
  • +
+ +

With tabs/spaces, no paras:

+ +
    +
  1. item1
  2. +
  3. item2
  4. +
  5. item3
  6. +
+ +

With tabs/spaces, paras:

+ +
    +
  1. +

    item1

    +
  2. +
  3. +

    item2

    +
  4. +
  5. +

    item3

    +
  6. +
+ +

Nested, without paras:

+ +
    +
  • item1 +
      +
    • item2 +
        +
      • item3
      • +
      +
    • +
    +
  • +
+ +

Nested, with paras:

+ +
    +
  • +

    item1

    + +
      +
    • item2 +
        +
      • item3 (level 3)
      • +
      +
    • +
    +
  • +
+ +

Ordered, without paras:

+ +
    +
  1. item1
  2. +
  3. item2 +
      +
    • do
    • +
    • it
    • +
    • now
    • +
    +
  4. +
  5. item3
  6. +
+ +

Ordered, with paras:

+ +
    +
  1. +

    item1

    +
  2. +
  3. +

    item2

    + +
      +
    • do
    • +
    • it
    • +
    • now
    • +
    +
  4. +
  5. +

    item3

    +
  6. +
+ +

Mixed tabs and spaces:

+ +
    +
  • some text +
      +
    • nested
    • +
    +
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.text new file mode 100644 index 0000000..22b578d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/mixed.text @@ -0,0 +1,66 @@ +With tabs/spaces, no paras: + +* item1 ++ item2 +- item3 + +With tabs/spaces, paras: + +- item1 + +* item2 + ++ item3 + +With tabs/spaces, no paras: + +1. item1 +20. item2 +3. item3 + +With tabs/spaces, paras: + +1. item1 + +2. item2 + +3. item3 + +Nested, without paras: + +* item1 + * item2 + * item3 + +Nested, with paras: + ++ item1 + + * item2 + * item3 (level 3) + +Ordered, without paras: + +1. item1 +2. item2 + * do + * it + * now +3. item3 + +Ordered, with paras: + +1. item1 + +2. item2 + + * do + * it + * now + +3. item3 + +Mixed tabs and spaces: + +* some text + * nested diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.html new file mode 100644 index 0000000..1921ee9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.html @@ -0,0 +1,17 @@ +
    +
  • some item +
      +
    • nested
    • +
    +
  • +
  • last item
  • +
+
    +
  • +

    some text

    + +
      +
    • nested
    • +
    +
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.text new file mode 100644 index 0000000..c71d864 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested.text @@ -0,0 +1,7 @@ +* some item + * nested +* last item +^ +* some text + + * nested diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.kramdown b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.kramdown new file mode 100644 index 0000000..dfede9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.kramdown @@ -0,0 +1,7 @@ +* First item + * Sub item 1 + * Sub sub item + * Sub item 2 +* Second item + * Sub item + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.text new file mode 100644 index 0000000..414afcc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/nested_compact.text @@ -0,0 +1,6 @@ +* First item + * Sub item 1 + * Sub sub item + * Sub item 2 +* Second item + * Sub item diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.html new file mode 100644 index 0000000..3f4cd0f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.html @@ -0,0 +1,39 @@ +
    +
  • +
    This is a code block.
    +
    +
  • +
  • +
    +

    This is a blockquote.

    +
    +
  • +
  • +

    A header

    +
  • +
+
    +
  • +
    This is a code block.
    +
    +
  • +
  • +
    +

    This is a blockquote. +continued by some para.

    +
    +
  • +
  • +

    A header

    +

    a para

    +
  • +
+
    +
  • +
      +
    • nested list
    • +
    • other nested item
    • +
    +
  • +
  • item 2
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.text new file mode 100644 index 0000000..321cef6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/other_first_element.text @@ -0,0 +1,18 @@ +* + This is a code block. +* > This is a blockquote. +* ## A header +^ +* + This is a code block. + +* > This is a blockquote. + continued by some para. + +* A header + ========= + a para +^ +* * nested list + * other nested item +* item 2 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.html new file mode 100644 index 0000000..84e5a6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.html @@ -0,0 +1,19 @@ +
    +
  1. This is a simple list item
  2. +
  3. +

    Followed by another

    +
  4. +
  5. +

    Followed by

    + +

    a para list item

    +
  6. +
  7. and a normal one
  8. +
  9. +

    and

    + +

    a para

    +
  10. +
+ +

para

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.text new file mode 100644 index 0000000..aaf7dae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ol.text @@ -0,0 +1,13 @@ +1. This is a simple list item +3. Followed by another + + +10. Followed by + + a para list item +1. and a normal one +2. and + + a para + +para diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.html new file mode 100644 index 0000000..68db05e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.html @@ -0,0 +1,48 @@ +
    +
  • This is a simple list item
  • +
  • +

    Followed by another

    +
  • +
  • +

    Followed by

    + +

    a para list item

    +
  • +
  • and a normal one
  • +
  • +

    and

    + +

    a para

    +
  • +
+ +

para

+ +
    +
  • multi line +list item
  • +
+ +

para

+ +
    +
  • list item line1 +one line +two lines
  • +
  • list item line2 +one line +two lines
  • +
+ +

para

+ +
    +
  • list item line3 +one line +two lines
  • +
  • list item line4 + one line + two lines
  • +
+ +

para

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.text new file mode 100644 index 0000000..ccd25c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/simple_ul.text @@ -0,0 +1,36 @@ +* This is a simple list item +* Followed by another + + +* Followed by + + a para list item +* and a normal one +* and + + a para + +para + +* multi line + list item + +para + +* list item line1 + one line + two lines +* list item line2 + one line + two lines + +para + +* list item line3 + one line + two lines +* list item line4 + one line + two lines + +para diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.html new file mode 100644 index 0000000..e079461 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.html @@ -0,0 +1,3 @@ +
    +
  • single
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.text new file mode 100644 index 0000000..877d369 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/single_item.text @@ -0,0 +1 @@ +* single diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.html new file mode 100644 index 0000000..e329931 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.html @@ -0,0 +1,72 @@ +
    +
  • +

    not a para +here

    + +
    +

    blockquote

    +
    +
  • +
  • +

    and not + here

    + +
    +

    blockquote

    +
    +
  • +
  • +

    this is a para

    +
  • +
  • +
    +

    blockquote

    +
    +
  • +
  • +

    this too

    +
  • +
+ +

A paragraph + 1. followed not by ol +- followed not by ul

+ +

A compact list:

+ +
    +
  • compact
  • +
  • list
  • +
  • items
  • +
+ +

A normal list:

+ +
    +
  • +

    not

    +
  • +
  • +

    compact

    +
  • +
  • +

    but here

    +
  • +
+ +

List item without content:

+ +
    +
  • +
  • a
  • +
+ +
    +
  • +
  • +

    one

    +
  • +
  • +

    two

    +
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.text new file mode 100644 index 0000000..7253f4a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/08_list/special_cases.text @@ -0,0 +1,49 @@ +* not a para + here + + > blockquote + +* and not + here + + >blockquote + +* this is a para + +* > blockquote + +* this too + +^ + +A paragraph + 1. followed not by ol +- followed not by ul + +A compact list: + +* compact +* list +* items + +A normal list: + +* not + +* compact + +* but here + +List item without content: + +* +* a +^ + +* + +* one + +* two + +^ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.html new file mode 100644 index 0000000..43c82af --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.html @@ -0,0 +1,10 @@ +
++-----------------------+ +| Use XML, be Happy :-) | +|_______________________| + +
+ +

Inline section <goes> here.

+ +

Inline test *case* *section* <goes> here end.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.text new file mode 100644 index 0000000..a4de06f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/cdata_section.text @@ -0,0 +1,10 @@ +
+
+ +Inline ]]> here. + +Inline test *case* ]]> here end. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.html new file mode 100644 index 0000000..8d31bd4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.html @@ -0,0 +1,18 @@ + + +

para1

+ + + +

para2

+ + +

para

+ +
+

This is +

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.text new file mode 100644 index 0000000..b632bf2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/comment.text @@ -0,0 +1,15 @@ + + +para1 + + + +para2 + + para + +> This is +> diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.html new file mode 100644 index 0000000..587d55a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.html @@ -0,0 +1,6 @@ +
+
text
+
+

para

+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.options new file mode 100644 index 0000000..a660da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.options @@ -0,0 +1 @@ +:parse_block_html: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.text new file mode 100644 index 0000000..1e381d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/deflists.text @@ -0,0 +1,6 @@ +
+
*text*
+
+para +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.html new file mode 100644 index 0000000..e11dc14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.html @@ -0,0 +1,14 @@ + + + + + + + + + +
Usage +Output +
Some data +

Some more

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.options new file mode 100644 index 0000000..a660da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.options @@ -0,0 +1 @@ +:parse_block_html: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.text new file mode 100644 index 0000000..c0cf2e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/content_model/tables.text @@ -0,0 +1,14 @@ + + + + + + + + + +
*Usage* +Output +
Some *data* +# Some more +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.html new file mode 100644 index 0000000..743c822 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.html @@ -0,0 +1,15 @@ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.text new file mode 100644 index 0000000..44a060d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html5_attributes.text @@ -0,0 +1,15 @@ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

+ +

paragraph

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.html new file mode 100644 index 0000000..f51c75b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.html @@ -0,0 +1,7 @@ +

Para

+
division
+ +
+

Quote

+
+
division
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.text new file mode 100644 index 0000000..cdcbff6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_after_block.text @@ -0,0 +1,5 @@ +Para +
division
+ +> Quote +
division
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.html new file mode 100644 index 0000000..93d695a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.html @@ -0,0 +1,15 @@ +

para

+ +
codeblock
+
+ +
+

test

+
+ +
<p>codeblock</p>
+
+ +
+

test

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.options new file mode 100644 index 0000000..a660da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.options @@ -0,0 +1 @@ +:parse_block_html: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.text new file mode 100644 index 0000000..a3cfda7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_codeblocks.text @@ -0,0 +1,13 @@ +para + + codeblock + +
+ test +
+ +

codeblock

+ +
+ test +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.html new file mode 100644 index 0000000..65cb7e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.html @@ -0,0 +1,5 @@ +

header

+ +
+====== +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.text new file mode 100644 index 0000000..64dc477 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_and_headers.text @@ -0,0 +1,6 @@ +header +====== + +
+====== +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.html new file mode 100644 index 0000000..f4b3221 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.html @@ -0,0 +1,10 @@ +

This is a code span with <entities> that should be preserved. +This is a simple code span.

+ +

Some <

+ +
Some very important < thing
+
+ +
Some code<<
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.text new file mode 100644 index 0000000..fda7db5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/code.text @@ -0,0 +1,9 @@ +This is a code span with <entities> that should be preserved. +This is a simple code span. + +

Some <

+ +
Some very important < thing
+ +
Some code<<
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.html new file mode 100644 index 0000000..dacd437 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.html @@ -0,0 +1,7 @@ +
+ + +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.text new file mode 100644 index 0000000..1788630 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/comment.text @@ -0,0 +1,8 @@ +
+ + + +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.html new file mode 100644 index 0000000..e4389c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.html @@ -0,0 +1,6 @@ +

This is sizedhallo.

+ +

This is strongitalic, yes!.

+ +

This is not converted, as is + this.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.text new file mode 100644 index 0000000..7c75930 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/emphasis.text @@ -0,0 +1,6 @@ +This is sizedhallo. + +This is strongitalic, yes!. + +This is not converted, as is + this. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.html new file mode 100644 index 0000000..5c80ce6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.html @@ -0,0 +1 @@ +

This is *raw* HTML text containing < entities!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.text new file mode 100644 index 0000000..5c80ce6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/entity.text @@ -0,0 +1 @@ +

This is *raw* HTML text containing < entities!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.html new file mode 100644 index 0000000..aebb206 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.html @@ -0,0 +1,6 @@ +

Some headerhere!

+

hallo

+

hallo

+

hallo

+
hallo
+
hallo
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.options new file mode 100644 index 0000000..987b4d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.options @@ -0,0 +1,2 @@ +:auto_ids: true +:html_to_native: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.text new file mode 100644 index 0000000..27eed3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/header.text @@ -0,0 +1,6 @@ +

Some headerhere!

+

hallo

+

hallo

+

hallo

+
hallo
+
hallo
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.html new file mode 100644 index 0000000..6eaccfe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.html @@ -0,0 +1,8 @@ +
+
kram
+
down
+
kram
+
down
+
kram
+
down
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.text new file mode 100644 index 0000000..6eaccfe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_dl.text @@ -0,0 +1,8 @@ +
+
kram
+
down
+
kram
+
down
+
kram
+
down
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.html new file mode 100644 index 0000000..eeebdfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.html @@ -0,0 +1,15 @@ +
    +
  1. This is a simple list item
  2. +
  3. +

    Followed by another

    +
  4. +
  5. +

    Followed by

    +

    a para list item

    +
  6. +
  7. and a normal one
  8. +
  9. +

    and

    +

    a para

    +
  10. +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.text new file mode 100644 index 0000000..41246df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ol.text @@ -0,0 +1,17 @@ +
    +
  1. This is a simple list item
  2. +
  3. +

    Followed by another

    +
  4. +
  5. +

    Followed by

    + +

    a para list item

    +
  6. +
  7. and a normal one
  8. +
  9. +

    and

    + +

    a para

    +
  10. +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.html new file mode 100644 index 0000000..c9b38d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.html @@ -0,0 +1,19 @@ +
    +
  • This is a simple list item
  • +
  • +

    Followed by another

    +
  • +
  • +

    Followed by

    +

    a para list item

    +
  • +
  • and a normal one
  • +
  • +

    and

    +

    a para

    +
  • +
+ +
    +
  • multi line list item
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.text new file mode 100644 index 0000000..5a2d68e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/list_ul.text @@ -0,0 +1,22 @@ +
    +
  • This is a simple list item
  • +
  • +

    Followed by another

    +
  • +
  • +

    Followed by

    + +

    a para list item

    +
  • +
  • and a normal one
  • +
  • +

    and

    + +

    a para

    +
  • +
+ +
    +
  • multi line +list item
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/options new file mode 100644 index 0000000..63936b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/options @@ -0,0 +1 @@ +:html_to_native: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.html new file mode 100644 index 0000000..a276b1c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.html @@ -0,0 +1,3 @@ +

Some text here and end

+ +

Some other text here

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.text new file mode 100644 index 0000000..b10035c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/paragraph.text @@ -0,0 +1,4 @@ +

Some text here and end +

+ +

Some other text here

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.html new file mode 100644 index 0000000..bdd79ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.html @@ -0,0 +1,12 @@ + + + + + + + + + +
UsageOther
Some *data* +

Some more

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.text new file mode 100644 index 0000000..bdd79ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_normal.text @@ -0,0 +1,12 @@ + + + + + + + + + +
UsageOther
Some *data* +

Some more

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.html new file mode 100644 index 0000000..0567d73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.html @@ -0,0 +1,64 @@ + + + + + + + + + + + +
UsageOutput
Some *data*Some more
+ + + + + + + + + + + + + + + + + + + + +
UsageOutput
Some *data*Some more
footlocker
+ + + + + + + + + + + + +
UsageOutput
Some *data*Some more
+ + + + + + + + + + +
Usage +Output +
Some *data* +Some more +
+ + +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.text new file mode 100644 index 0000000..7d29430 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/table_simple.text @@ -0,0 +1,74 @@ + + + + + + + + + +
Usage +Output +
Some *data* +Some more +
+ + + + + + + + + + + + + + + + + + + + +
Usage +Output +
Some *data* +Some more +
foot +locker +
+ + + + + + + + + + +
Usage +Output +
Some *data* +Some more +
+ + + + + + + + + + +
Usage +Output +
Some *data* +Some more +
+ + +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.html new file mode 100644 index 0000000..2443965 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.html @@ -0,0 +1 @@ +

This is … something “to remember”!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.text new file mode 100644 index 0000000..ee33c5c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/html_to_native/typography.text @@ -0,0 +1 @@ +

This is … something “to remember”!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.html new file mode 100644 index 0000000..77e0d78 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.html @@ -0,0 +1,5 @@ +

para

+ +

</div>

+ +

para

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.text new file mode 100644 index 0000000..f2fc834 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_1.text @@ -0,0 +1,5 @@ +para + +
+ +para diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.html new file mode 100644 index 0000000..b5da12f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.html @@ -0,0 +1,5 @@ +

para

+ +
+ +

para

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.text new file mode 100644 index 0000000..675c94f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/invalid_html_2.text @@ -0,0 +1,5 @@ +para + +
+ +para diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.html new file mode 100644 index 0000000..930b8f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.html @@ -0,0 +1,38 @@ +
+

para

+
+ +
+para +
+ +
+

para

+
+ +
+*para* +
+ +

+

para

+

+ +

+para +

+ +

+para +

+ +

+*para* +

+ +
+
emphasize
+
+

para

+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.text new file mode 100644 index 0000000..12e5aee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/markdown_attr.text @@ -0,0 +1,38 @@ +
+*para* +
+ +
+*para* +
+ +
+*para* +
+ +
+*para* +
+ +

+*para* +

+ +

+*para* +

+ +

+*para* +

+ +

+*para* +

+ +
+
*emphasize*
+
+para +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.html new file mode 100644 index 0000000..90bda03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.html @@ -0,0 +1,24 @@ +
+This is some text +
+ +
+This is some text +
+ +
+</p> +
+ +
+

Foo

+
+ +

This is some +text

+ +

http://example.com

+ +
+<http://example.com> +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.text new file mode 100644 index 0000000..1d1c71c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/not_parsed.text @@ -0,0 +1,24 @@ +
+This is some text +
+ +
+This is some text +
+ +
+

+
+ +
+

Foo

+
+ +

This is some +text

+ + + +
+ +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.html new file mode 100644 index 0000000..860f9b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.html @@ -0,0 +1,35 @@ +

baz { |qux| quux }

+ +

This is some para. +

+ + + + +

parsed +This too +

+ + + + + + + + + +

http://example.com

+ + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.htmlinput b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.htmlinput new file mode 100644 index 0000000..22b9ea5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.htmlinput @@ -0,0 +1,34 @@ +

baz { |qux| quux }

+ +

This is some para. +

+ + + + +

parsed +This too +

+ + + + + + + + + +

http://example.com

+ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.options new file mode 100644 index 0000000..a660da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.options @@ -0,0 +1 @@ +:parse_block_html: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.text new file mode 100644 index 0000000..e0617c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_raw.text @@ -0,0 +1,33 @@ +

baz { |qux| quux }

+ +This is some para. + + + + +

*parsed* +This too +

+ + + + + + + + + + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.html new file mode 100644 index 0000000..2a6191f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.html @@ -0,0 +1,12 @@ +

This text +should be parsed +as span +

+ +

This produces `

+

` an unwanted result.</p>

+ +

This text too

+

+some text +

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.htmlinput b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.htmlinput new file mode 100644 index 0000000..4199b8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.htmlinput @@ -0,0 +1,12 @@ +

This text +should be parsed +as span +

+ +

This produces `

+

` an unwanted result.</p>

+ +

This text too

+

+some text +

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.options new file mode 100644 index 0000000..a660da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.options @@ -0,0 +1 @@ +:parse_block_html: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.text new file mode 100644 index 0000000..d07cf6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_as_span.text @@ -0,0 +1,9 @@ +

This *text +should* be parsed +as span +

+ +

This produces `

` an unwanted result.

+ +

This *text* too

+some text diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.html new file mode 100644 index 0000000..8de78c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.html @@ -0,0 +1,21 @@ +

+

test

+
+ +
+
test
+
+
+
test
+
+
+
+ +
+
code block with </div>
+
+
+ +
+

No matching end tag

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.options new file mode 100644 index 0000000..a660da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.options @@ -0,0 +1 @@ +:parse_block_html: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.text new file mode 100644 index 0000000..b8b1845 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/parse_block_html.text @@ -0,0 +1,17 @@ +
+ test +
+ +
+ test +
+ test +
+
+ +
+ code block with
+
+ +
+No matching end tag diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.html new file mode 100644 index 0000000..939b996 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.html @@ -0,0 +1,12 @@ +

<?xml version=”1.0”?>

+ +

para

+ +

<? test ?> para

+ +

other

+ +

<? +multiline text +is allowed +?>

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.text new file mode 100644 index 0000000..fcb866f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/processing_instruction.text @@ -0,0 +1,12 @@ + + +para + + para + +other + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.html new file mode 100644 index 0000000..0d926c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.html @@ -0,0 +1,60 @@ +
+

test

+
+ +

+para2 +

+ +
+

tes

+ +

test +weiter +

+
+ +

para4

+ +
+
+
+

foo

+
+
+
+
+

bar 

+
+
+ +

para5

+ +
+

id

+
+

test

+ +
+

hallo

+
+
+

hallo

+
+ +

para6

+ +
+
+

Another para.

+
+ +

Test

+ +

Test

+ +

Test + +

+ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.options new file mode 100644 index 0000000..a660da2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.options @@ -0,0 +1 @@ +:parse_block_html: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.text new file mode 100644 index 0000000..a2ffe25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/simple.text @@ -0,0 +1,55 @@ +
+test +
+ +

+para2 +

+ +
+

tes

+ +

test +weiter +

+
+ +para4 + +
+
+
+foo +
+
+
+
bar  +
+
+ +para5 + +
id +
test + +
+hallo +
+hallo +
+ +para6 + +
+Another para. +
+ +Test + +

Test

+ +

Test + +

+ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.htmlinput b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.htmlinput new file mode 100644 index 0000000..72ff453 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.htmlinput @@ -0,0 +1,7 @@ +
+ inside +
+ +
+ text +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.text new file mode 100644 index 0000000..7f0d12c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/standalone_image_in_div.text @@ -0,0 +1,8 @@ +
+![inside](src.png) +
+ +
+[text](website.html) +
+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.kramdown b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.kramdown new file mode 100644 index 0000000..f8d6802 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.kramdown @@ -0,0 +1,8 @@ + + + + + + +
test
+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.text new file mode 100644 index 0000000..32e01da --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/table.text @@ -0,0 +1,7 @@ + + + + + + +
test
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.html new file mode 100644 index 0000000..6f5693e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.html @@ -0,0 +1,8 @@ +

This is a

+ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.text new file mode 100644 index 0000000..a240f5c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/textarea.text @@ -0,0 +1,8 @@ +This is a + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.html new file mode 100644 index 0000000..d941bc0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.html @@ -0,0 +1,8 @@ + + +doit + +doit + +doit</some> + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.text new file mode 100644 index 0000000..6427fae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/09_html/xml.text @@ -0,0 +1,7 @@ + + +doit + +doit + +doit diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.html new file mode 100644 index 0000000..74b03d5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.html @@ -0,0 +1,2 @@ +

Some paragraph

+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.text new file mode 100644 index 0000000..f58768a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/10_ald/simple.text @@ -0,0 +1,8 @@ +Some paragraph + +{:id: ref1} +{:id: .class1} + {:id: #id} + {:id: key="value"} + {:id: .class2 .class3 ref2 #id-with key="value" key='value' key='dfsd\}' } +{:test: k ey=value} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.html new file mode 100644 index 0000000..9857a03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.html @@ -0,0 +1 @@ +

A header

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.options new file mode 100644 index 0000000..8776b55 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.options @@ -0,0 +1 @@ +:auto_ids: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.text new file mode 100644 index 0000000..f521fb0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/auto_id_and_ial.text @@ -0,0 +1,2 @@ +## A header +{:#myid .cls} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.html new file mode 100644 index 0000000..84cc368 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.html @@ -0,0 +1,11 @@ +
+test +
+ +
+

test

+
+ +
+

para

+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.text new file mode 100644 index 0000000..827645c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/nested.text @@ -0,0 +1,15 @@ +{:.cls} +
+test +
+{:#id} + +{:.cls} +
+test +
+{:#id} + +{:.cls} +> para +{:#id} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.html new file mode 100644 index 0000000..1086f0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.html @@ -0,0 +1,29 @@ +

Some paragraph.

+ +

Some paragraph.

+ +
+

quote

+
+ +
    +
  • list
  • +
+ +
code block
+
+ +
other code block
+
+ +

A header

+ +

Some paragraph here

+ +

Some paragraph here

+ +

Paragraph

+

Paragraph

+ +

Another header

+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.text new file mode 100644 index 0000000..b97eef3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/11_ial/simple.text @@ -0,0 +1,41 @@ +Some paragraph. +{:.class .-class id key="val"} + +Some paragraph. +{:.cls1#id.cls2} + +> quote +{: #id} + {: .class} + +* list +{: key="val"} + + code block +{: #other} + + other code block + +## A header +{:#myid} + +{:.cls} +Some paragraph here + +{:.cls1} +{:.cls2} +Some paragraph here + +Paragraph +{:.cls} +Paragraph + +Another header +============== +{: .class #other} + +{:id: #id key="valo"} +{:id: #other .myclass other} +{:other: key1="val\"" - ig.nored as_is#this key2='val\'' .other-class} + +{:.invalid} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.html new file mode 100644 index 0000000..20b4c66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.html @@ -0,0 +1,8 @@ +

This is a simple paragraph.

+ + + +

And another paragraph

+ +

{::comment} +Another paragraph

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.text new file mode 100644 index 0000000..2dfc919 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/comment.text @@ -0,0 +1,12 @@ +This is a simple paragraph. + +{::comment} +This is a comment {:/}which is {:/comment} ignored. +{:/comment} + +And another paragraph + +{::comment this='is' .ignore /} + +{::comment} +Another paragraph diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.html new file mode 100644 index 0000000..17aae5c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.html @@ -0,0 +1,8 @@ +

paragraph

+ +

{::something} +anotherthing +{:/something}

+ +

{::something/} +paragraph

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.text new file mode 100644 index 0000000..ae94a8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/ignored.text @@ -0,0 +1,8 @@ +paragraph + +{::something} +anotherthing +{:/something} + +{::something/} +paragraph diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.html new file mode 100644 index 0000000..7fe58d5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.html @@ -0,0 +1,10 @@ +

This is a simple paragraph.

+ +This *is* not processed + +

And another paragraph

+ +bold + +

{::nomarkdown} +Another paragraph

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.kramdown b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.kramdown new file mode 100644 index 0000000..2cee512 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.kramdown @@ -0,0 +1,20 @@ +This is a simple paragraph. + +{::nomarkdown} +This *is* not processed +{:/} + +And another paragraph + +{::nomarkdown type="html"} +bold +{:/} + +{::nomarkdown type="latex"} +\begin{itemize} +\item[Yes] YESSSS! +\end{itemize} +{:/} + +\{::nomarkdown} Another paragraph + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.latex new file mode 100644 index 0000000..5af0263 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.latex @@ -0,0 +1,13 @@ +This is a simple paragraph. + +This *is* not processed + +And another paragraph + +\begin{itemize} +\item[Yes] YESSSS! +\end{itemize} + +\{::nomarkdown\} +Another paragraph + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.text new file mode 100644 index 0000000..43d441d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/nomarkdown.text @@ -0,0 +1,21 @@ +This is a simple paragraph. + +{::nomarkdown} +This *is* not processed + {:/nomarkdown} + +And another paragraph + +{::nomarkdown this='is' .ignore /} + +{::nomarkdown type='html'} +bold +{:/} +{::nomarkdown type="latex"} +\begin{itemize} +\item[Yes] YESSSS! +\end{itemize} +{:/} + +{::nomarkdown} +Another paragraph diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.html new file mode 100644 index 0000000..bf3a47f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.html @@ -0,0 +1,21 @@ +

No header id

+ +

without header id

+ +
+some *para* +
+ +
+

some para

+
+ +

Some text10.

+ +
+
    +
  1. +

    Some text. 

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.text new file mode 100644 index 0000000..b63f34b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options.text @@ -0,0 +1,23 @@ +# No header id + +{::options unusedvar="val" /} + +# without header id + +
+some *para* +
+ +{::options parse_block_html="true" parse_span_html="true" /} + +
+some *para* +
+ +{::options footnote_nr="10" /} + +Some text[^ab]. + +[^ab]: Some text. + +{::options template="/etc/passwd" /} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.html new file mode 100644 index 0000000..2db8e20 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.html @@ -0,0 +1,10 @@ + +

Some text1.

+ +
+
    +
  1. +

    Some text. 

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.text new file mode 100644 index 0000000..78abfbe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options2.text @@ -0,0 +1,5 @@ +{::options footnote_nr="da10" /} + +Some text[^ab]. + +[^ab]: Some text. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.html new file mode 100644 index 0000000..d5a5ad6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.html @@ -0,0 +1,8 @@ +
x = Class.new
+
+
+ +
x = Class.new
+
+
+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.text new file mode 100644 index 0000000..f37839b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/12_extension/options3.text @@ -0,0 +1,7 @@ + x = Class.new +{: .language-ruby} + +{::options syntax_highlighter_opts="{default_lang: ruby\}" /} + + x = Class.new + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.html new file mode 100644 index 0000000..398628a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.html @@ -0,0 +1,15 @@ +
+
item
+
def
+
item2
+
def
+
+ +
+
item
+
def
+
item2
+
def
+
item3
+
def
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.text new file mode 100644 index 0000000..f1797a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/auto_ids.text @@ -0,0 +1,18 @@ +{:auto_ids} +item +: def + +item2 +: def + +^ + +{:auto_ids-prefix-} +item +: def + +item2 +: def + +{:#id} item3 +: def diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.html new file mode 100644 index 0000000..7c5cc04 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.html @@ -0,0 +1 @@ +

: no definition

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.text new file mode 100644 index 0000000..cd3671b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/definition_at_beginning.text @@ -0,0 +1 @@ +: no definition diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.html new file mode 100644 index 0000000..3090b1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.html @@ -0,0 +1,4 @@ +
+
item
+
definition
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.text new file mode 100644 index 0000000..587c3b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/deflist_ial.text @@ -0,0 +1,4 @@ +{:.dl-horizontal} +item +: definition +{:.dl-other} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.html new file mode 100644 index 0000000..0ed1197 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.html @@ -0,0 +1,17 @@ +
+
item
+
definition +continued
+
another {:.cls}
+
+
code
+
+
+
IAL at last + no code bc of text
+
term
+
definition
+
term1
+
term2
+
definition
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.text new file mode 100644 index 0000000..2058d74 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/item_ial.text @@ -0,0 +1,16 @@ +item +: {:.cls} definition + continued +: another {:.cls} +: {:.class} + code +: {:.cls} IAL at last + no code bc of text + + +{:.class} term +: definition + +{:.class1} term1 +{:.class2} term2 +: definition diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.html new file mode 100644 index 0000000..e2e089b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.html @@ -0,0 +1,13 @@ +
+
kram
+
down
+
now
+
definition 1
+
definition 2
+
+

definition 3

+
+
+

definition 4

+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.text new file mode 100644 index 0000000..b834258 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/multiple_terms.text @@ -0,0 +1,10 @@ +kram +*down* +now +: definition 1 +: definition 2 + +: definition 3 + + +: definition 4 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.html new file mode 100644 index 0000000..c16f962 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.html @@ -0,0 +1,2 @@ +

This is a para +: and not a definition list

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.text new file mode 100644 index 0000000..98b52b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/no_def_list.text @@ -0,0 +1,2 @@ +This is a para +\: and not a definition list diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.html new file mode 100644 index 0000000..5f28fdf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.html @@ -0,0 +1,10 @@ +
+
term
+
+

definition

+
+
definition
+
+

definition

+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.text new file mode 100644 index 0000000..280fa47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/para_wrapping.text @@ -0,0 +1,6 @@ +term + +: definition +: definition + +: definition diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.html new file mode 100644 index 0000000..0a1c4dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.html @@ -0,0 +1,8 @@ +
+
kram
+
down
+
+
+
kram
+
down
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.text new file mode 100644 index 0000000..56fedf1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/separated_by_eob.text @@ -0,0 +1,5 @@ +kram +: down +^ +kram +: down diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.html new file mode 100644 index 0000000..791f145 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.html @@ -0,0 +1,10 @@ +
+
kram
+
down
+
novalue
+
+
kram
+
down +kram
+
down
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.text new file mode 100644 index 0000000..e3bf730 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/simple.text @@ -0,0 +1,10 @@ +kram +: down + +novalue +: + +kram +: down +kram +: down diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.html new file mode 100644 index 0000000..cf7d785 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.html @@ -0,0 +1,4 @@ +
+
kram
+
down
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.text new file mode 100644 index 0000000..76eb355 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/styled_terms.text @@ -0,0 +1,2 @@ +*kram* +: down diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.html new file mode 100644 index 0000000..b4df878 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.html @@ -0,0 +1,3 @@ +

para

+ +

: no definition

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.text new file mode 100644 index 0000000..30ab445 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/too_much_space.text @@ -0,0 +1,4 @@ +para + + +: no definition diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.html new file mode 100644 index 0000000..45b5865 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.html @@ -0,0 +1,38 @@ +
+
kram
+
this is some +text
+
+

this is some +more text

+
+
kram
+
+
+

blockquote

+
+
+
kram
+
+
code
+
+
+
kram
+
+
+
kram
+
down
+
+
+
kram
+
+

header

+
+
kram
+
+
    +
  • list
  • +
  • items
  • +
+
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.text new file mode 100644 index 0000000..15195ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/13_definition_list/with_blocks.text @@ -0,0 +1,24 @@ +kram +: this is some + text + + : this is some + more text + +kram +: > blockquote + +kram +: + code + +kram +: kram + : down + +kram +: # header + +kram +: * list + * items diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.html new file mode 100644 index 0000000..af9b3e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.html @@ -0,0 +1,8 @@ + + + + + + + +
first line of cell
second line of cell
another cell
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.options new file mode 100644 index 0000000..63936b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.options @@ -0,0 +1 @@ +:html_to_native: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.text new file mode 100644 index 0000000..60fec0b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/empty_tag_in_cell.text @@ -0,0 +1 @@ +| first line of cell
second line of cell | another cell | diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.html new file mode 100644 index 0000000..302e97a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.html @@ -0,0 +1,12 @@ +

No table body

+ +

|-|-|-

+ +

|no|table|here|

+ +

|no|table|here| +paragraph

+ +

|-|-| +|-|-|

+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.text new file mode 100644 index 0000000..3565d5b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/errors.text @@ -0,0 +1,13 @@ +No table body + +|-|-|- + +[5]: test +|no|table|here| + +|no|table|here| +paragraph + +|-|-| +|-|-| + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.html new file mode 100644 index 0000000..b4528a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.html @@ -0,0 +1,52 @@ +

cell 1 | cell 2

+ +

cell 1 | cell 2

+ + + + + + + + +
cell 1cell 2 | continued
+ + + + + + + + +
cell 1cell 2
+ + + + + + + + +
cell 1code | span
+ +

cell 1 code | span

+ +

cell 1 | code | span

+ + + + + + + + + + + + + + +
cell 1cell `2cell 3
cell 1`cell 2cell 3
+ +

cell 1 | cell 2 | cell 3 +cell 1 | cell 2 | cell 3

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.text new file mode 100644 index 0000000..a8a24d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/escaping.text @@ -0,0 +1,19 @@ +`cell 1 | cell 2` + +cell 1 \| cell 2 + +cell 1 | cell 2 \| continued + +cell 1 | cell `2` + +cell 1 | `code | span` + +cell 1 `code | span` + +cell 1 \| `code | span` + +cell 1 | cell `2 | cell 3 +cell 1` | cell 2 | cell 3 + +cell 1 \| cell `2 | cell 3 +cell 1` | cell 2 | cell 3 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.html new file mode 100644 index 0000000..e6596ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.html @@ -0,0 +1,65 @@ +

Simple footer

+ + + + + + + + + + + + + + +
cell1cell2
cell3cell4
+ +

Full footer

+ + + + + + + + + + + + + + +
cell1cell2
cell3cell4
+ +

Footer with separator lines

+ + + + + + + + + + + + + + + + + + +
cell1cell2
cell3cell4
cell5cell6
+ +

Empty footer

+ + + + + + + + +
cell1cell2
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.text new file mode 100644 index 0000000..faaed8d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/footer.text @@ -0,0 +1,25 @@ +Simple footer + +| cell1 | cell2 +|= +| cell3 | cell4 + +Full footer + +| cell1 | cell2 +|=======|=======| +| cell3 | cell4 + +Footer with separator lines + +| cell1 | cell2 +|=======|=======| +| cell3 | cell4 +|--- +| cell5 | cell6 +|--- + +Empty footer + +| cell1 | cell2 +|= diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.html new file mode 100644 index 0000000..647f2c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.html @@ -0,0 +1,117 @@ +

Simple header

+ + + + + + + + + + + + + + +
cell1cell2
cell3cell4
+ +

Full header

+ + + + + + + + + + + + + + +
cell1cell2
cell3cell4
+ +

With alignment and superfluous alignment defs

+ + + + + + + + + + + + + + + + + + + + +
defaultleftcenterrightdefault
cell1cell2cell3cell4cell5
+ +

With leading sep line

+ + + + + + + + + + + + + + +
cell1cell2
cell3cell4
+ +

Multiple bodies

+ + + + + + + + + + + + + + + + + + + + +
cell1cell2
cell3cell4
cell5cell6
+ +

Sep line with tab

+ + + + + + + + + + + + + + + + + + +
rightcenter
cell1cell2
cell3cell4
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.text new file mode 100644 index 0000000..6961bfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/header.text @@ -0,0 +1,39 @@ +Simple header + +| cell1 | cell2 +|----- +| cell3 | cell4 + +Full header + +| cell1 | cell2 +|-------|-------| +| cell3 | cell4 + +With alignment and superfluous alignment defs + +| default | left | center | right | default +|-| :- |:-: | -: | - | :-: | :- +| cell1 | cell2 | cell3 | cell4 | cell5 + +With leading sep line + +|:-:|-:| +| cell1 | cell2 +|-------|-------| +| cell3 | cell4 + +Multiple bodies + +| cell1 | cell2 ++ :-: | +| cell3 | cell4 +|----||| +| cell5 | cell6 + +Sep line with tab + +right | center +---: | :---: +cell1 | cell2 +cell3 | cell4 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.html new file mode 100644 index 0000000..dce46b1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.html @@ -0,0 +1,3 @@ +

No table

+ +

| Some | thing | here

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.text new file mode 100644 index 0000000..90f90b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/no_table.text @@ -0,0 +1,3 @@ +No table + +\| Some \| thing \| here diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.html new file mode 100644 index 0000000..506b442 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.html @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + +
cell1cell2
cell3cell4
cell5cell6 |
cell7cell8
+ +

Missing cells at end

+ + + + + + + + + + + + + + + + + + + +
cell1cell2cell3
cell1  
 cell2cell3
+ +

Escaped pipe characters

+ + + + + + + + + + + + + + + + +
cell1 | cell1cell2
cell1cell2 |
cell1 | concell2
+ +

Table with code elements

+ + + + + + + + + + + + + + + + +
This is a span | with a pipe.   
Some span</em> herea span | with apipe.
+ +

Special cases regarding codespan syntax

+ + + + + + + + +
ab
+ + + + + + + +
a
+ + + + + + + + + +
tablewithial
+ + + + + + + + + +
tablewithial
+ +

not starting with a bar

+ + + + + + + + +
simpletable
+ + + + + + + + + + + + + + +
head1head2
cell1cell2
+ + + + + + + + + + + + + + +
head1head2
 cell2
+ + + + + + + + + + + + + + + + +
ab
cd
ef
+ + + + + + + + + + + + + + +
KeyValue type
Type"GROUP"|"UNKNOWN"
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.text new file mode 100644 index 0000000..0f225a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/simple.text @@ -0,0 +1,53 @@ +| cell1 | cell2 | +|cell3 | cell4| +|cell5|cell6 \| +| cell7|cell8 + +Missing cells at end + +| cell1 | cell2 | cell3 | +| cell1 || +|| cell2 | cell3 + +Escaped pipe characters + +| cell1 \| cell1 | cell2 | +| cell1 | cell2 \| +| cell1 `|` con | cell2 + +Table with code elements + +| This is a span | with a pipe. +| Some span | here | a span | with a | pipe. + +Special cases regarding codespan syntax + +|a|`b` + +|`a` + +{:.cls} +| table | with | ial + +| table | with | ial +{:.cls} + +not starting with a bar + +simple | table + +head1 | head2 +------|------ +cell1 | cell2 + + head1 | head2 +-------|------ + | cell2 + +| a | b | + c | d +| e | f | + +| Key | Value type | +|--------|------------------------| +| `Type` | `"GROUP"`\|`"UNKNOWN"` | diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.html new file mode 100644 index 0000000..0084283 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.html @@ -0,0 +1,25 @@ + + + + + + + + + + + +
this is 1a table
with afootnote
+ +
+
    +
  1. +

    Something

    + +
    +

    special here

    +
    +

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.latex new file mode 100644 index 0000000..99b5312 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.latex @@ -0,0 +1,11 @@ +\begin{longtable}{|l|l|} +\hline +this is \footnote{Something + +\begin{quote} +special here +\end{quote}} & a table\\ +with a & footnote\\ +\hline +\end{longtable} + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.text new file mode 100644 index 0000000..345fc5d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/14_table/table_with_footnote.text @@ -0,0 +1,6 @@ +| this is [^1] | a table +| with a | footnote + +[^1]: Something + + > special here diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.html new file mode 100644 index 0000000..9b2c127 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.html @@ -0,0 +1 @@ +\[<script>alert('a')</script> <script>alert('b<')</script>\] diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.text new file mode 100644 index 0000000..95252a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/gh_128.text @@ -0,0 +1 @@ +$$ $$ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.html new file mode 100644 index 0000000..5d6b343 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.html @@ -0,0 +1,3 @@ +
$$ +5+5 +$$
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.options new file mode 100644 index 0000000..06d559e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.options @@ -0,0 +1 @@ +:math_engine: ~ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.text new file mode 100644 index 0000000..fdee5cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/no_engine.text @@ -0,0 +1,2 @@ +{: #math-id} +$$5+5$$ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.html new file mode 100644 index 0000000..f80d56b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.html @@ -0,0 +1,30 @@ +

This is a para. +\(\text{LaTeX} \lambda_5\)

+ +\[\lambda_5 = \alpha + 4\] + +

\(\lambda_\alpha > 5\) +This is a para.

+ +\[\begin{align*} +&=5 \\ +&=6 \\ +\end{align*}\] + +\[5+5\] + +\[5+5\] + +\[5+5\] + +\[5+5\] + +
$$5+5$$
+
+ +
\[5+5\] +
+
\[5+5\] +
+ +\[|x| = 5\] diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.text new file mode 100644 index 0000000..aa5984a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/15_math/normal.text @@ -0,0 +1,30 @@ +This is a para. +$$ \text{LaTeX} \lambda_5 $$ + +$$\lambda_5 = \alpha + 4$$ + +$$\lambda_\alpha > 5$$ +This is a para. + +$$\begin{align*} +&=5 \\ +&=6 \\ +\end{align*}$$ + +$$5+5$$ + + $$5+5$$ + + $$5+5$$ + + $$5+5$$ + + $$5+5$$ + +{:.cls} +$$5+5$$ +^ +$$5+5$$ +{:.cls} + +$$|x| = 5$$ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.html new file mode 100644 index 0000000..bbb831e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.html @@ -0,0 +1,14 @@ + +

Header level 1

+ +

Header level 2

+ +

Header level 3

+ +

Header level 4

+ +

Other header level 1

+ +

Other header level 2

+ +

Other header level 3

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.text new file mode 100644 index 0000000..11ad829 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/no_toc.text @@ -0,0 +1,16 @@ +* Here comes the table of content +{:toc} + +# Header level 1 + +## Header level 2 + +### Header level 3 + +#### Header level 4 + +# Other header level 1 + +## Other header level 2 + +### Other header level 3 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.html new file mode 100644 index 0000000..d352684 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.html @@ -0,0 +1,35 @@ +

Contents

+ + + +

Header level 1

+ +

Header level 2

+ +

Header level 3

+ +

Header level 4

+ +

Other header level 1

+ +

Other header level 2

+ +

Other header level 3

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.options new file mode 100644 index 0000000..8776b55 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.options @@ -0,0 +1 @@ +:auto_ids: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.text new file mode 100644 index 0000000..d8f0b86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_exclude.text @@ -0,0 +1,19 @@ +# Contents +{:.no_toc} + +* Here comes the table of content +{:toc} + +# Header level 1 + +## Header level 2 + +### Header level 3 + +#### Header level 4 + +# Other header level 1 + +## Other header level 2 + +### Other header level 3 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.html new file mode 100644 index 0000000..e50a07c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.html @@ -0,0 +1,24 @@ + + +

Header level 1

+ +

Header \` level 2

+ +

Header level 3

+ +

Header level 4

+ +

Other header level 1

+ +

Other header level 2

+ +

Other header level 3

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.options new file mode 100644 index 0000000..bdfbeba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.options @@ -0,0 +1,2 @@ +:toc_levels: 2..3 +:auto_ids: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.text new file mode 100644 index 0000000..1a62dea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_levels.text @@ -0,0 +1,16 @@ +* Here comes the table of content +{:toc} + +# Header level 1 + +## Header \\\` level 2 + +### Header level 3 + +#### Header level 4 + +# Other header level 1 + +## Other header level 2 + +### Other header level 3 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.html new file mode 100644 index 0000000..f979601 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.html @@ -0,0 +1,13 @@ + + +

Header1 level 1

+ +
+
    +
  1. +

    Some footnote content here 

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.options new file mode 100644 index 0000000..8776b55 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.options @@ -0,0 +1 @@ +:auto_ids: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.text new file mode 100644 index 0000000..5879ed5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_footnotes.text @@ -0,0 +1,6 @@ +* Here comes the table of content +{:toc} + +# Header[^1] level 1 + +[^1]: Some footnote content here diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.html new file mode 100644 index 0000000..ebde543 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.html @@ -0,0 +1,8 @@ +

Header

+ +

Header

+ + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.options new file mode 100644 index 0000000..36c20f5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.options @@ -0,0 +1,2 @@ +:auto_ids: true +:auto_id_stripping: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.text new file mode 100644 index 0000000..9b4ac07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/block/16_toc/toc_with_links.text @@ -0,0 +1,8 @@ +# [Header] + +# [Header] + +[header]: test.html + +* toc +{:toc} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.html new file mode 100644 index 0000000..8299316 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.html @@ -0,0 +1,4 @@ +

一二三四五

+ +

あいうえお

+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.options new file mode 100644 index 0000000..4c86d36 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.options @@ -0,0 +1 @@ +:remove_line_breaks_for_cjk: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.text new file mode 100644 index 0000000..969c04c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/cjk-line-break.text @@ -0,0 +1,12 @@ +一 +二 +三 +四 +五 + +あ +い +う +え +お + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.html new file mode 100644 index 0000000..0339347 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.html @@ -0,0 +1,46 @@ +

Das ist gewöhnlich ein Über-Problem mit manchen
+Sälen http://example.org und anderen Dinge. Siehe +Über mich!

+ +
+

Vielleicht höre ich nicht richtig?

+
+ +
    +
  • Sollten wir uns das überlegen? Verhöhne mich nicht!
  • +
  • Ho ho höher! Sind *wir* da?
  • +
+ +

Titel sind urschön

+ +

Manche mögens ärmer

+ +
öha
+was nun?
+
+ +
+
Töne
+
Laute Geräusche
+
vielleicht noch was ähnliches
+
+ + + + + + + + + + + + + + + + +
hochhöheram höchsten
überdrübermüde
+ +

Das ist schön +gemacht

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.text new file mode 100644 index 0000000..65edf4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/encoding.text @@ -0,0 +1,28 @@ +Das ist gewöhnlich *ein* [Über-Problem](http://example.org) mit manchen +Sälen und anderen Dinge. Siehe +![Über mich](http://example.org)! + +> Vielleicht *höre*{:.red} ich nicht richtig? +{:.test} + +* Sollten wir uns das überl*egen*? *Verhöhne* mich nicht! +* Ho ho höher! Sind \*wir\* da? + +Titel sind urschön +================== + +## Manche mögens *ärmer* {#hot} + + öha + was nun? + +Töne +: Laute Geräusche +: vielleicht noch was ä*hnliches* + +| hoch | höher | am höchsten | +|----------------------------| +| über | drüber | müde | + +

Das ist schön +gemacht

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.man new file mode 100644 index 0000000..a03d148 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.man @@ -0,0 +1,123 @@ +.\" generated by kramdown +.TH "NAME" "1" "November 2016" "Some extra data" +.SH NAME +name \- description +.SH "SYNOPSIS" +\fBname\fP [\fBOPTIONS\fP] \fIarguments\fP\.\.\. +.SH "DESCRIPTION" +This is a normal paragraph\. +.sp +.PD 0 +.IP \(bu 4 +A +.IP \(bu 4 +compact +.IP \(bu 4 +list +.IP \(bu 4 +with multiple +.RS +.IP \(bu 4 +items and +.RS +.IP \(bu 4 +nested +.RE +.RE +.IP \(bu 4 +as well +.PD +.RS +.P +blockquotes are fine +.IP 1. 4 +numbered lists +.IP 2. 4 +work too +.RS +.IP 1. 4 +and they +.IP 2. 4 +can be +.RS +.IP 1. 4 +nested +.RE +.RE +.IP 3. 4 +again +.RE +.sp +.RS 4 +.EX +Some fancy code + going + on + here +.EE +.RE +.TP +\fB\-o\fP +.TQ +\fB\-\-option\fP +Description lists +.sp +are useful as well +.P +And compact definition lists: +.sp +.PD 0 +.TP +\fBo\fP +Option +.TP +\fBk\fP +Key +.TP +\fBv\fP +Value +.PD +.TS +box center ; +l l l l . +tables can be centered +.TE +.sp +.TS +box ; +lb lb cb rb . +Default aligned Left aligned Center aligned Right aligned += +.T& +l l c r . +First body part Second cell Third cell fourth cell +Second \fIline\fP foo \fBstrong\fP baz +Third line \fBquux\fP baz bar +_ +.T& +l l c r . +Second body +2nd line += +Footer row one +Footer row two +.TE +.sp +.P +Inline formatting like \fIemphasis\fP, \fBstrong\fP and \fBcode span\fP work as ususal\. +.UR are_well\.html +Links +.UE +work, too! As do +.br +line breaks\. +.P +Abbreviations like MD can be used but the abbreviation title is ignored\. +.P +Math elements work \fB\elambda = 5\fP inline and in block form: +.sp +.RS 4 +.EX +\elambda_5 = \ealpha + 4 +.EE +.RE diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.text new file mode 100644 index 0000000..a0a2614 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/example.text @@ -0,0 +1,85 @@ +# name(1) - description +{: data-date="November 2016" data-extra="Some extra data"} + +## SYNOPSIS + +`name` \[`OPTIONS`\] *arguments*... + +## DESCRIPTION + +This is a normal paragraph. + +* A +* compact +* list +* with multiple + * items and + * nested +* as well +{:.compact} + +> blockquotes are fine +> +> 1. numbered lists +> +> 2. work too +> 1. and they +> 2. can be +> 1. nested +> +> 3. again + +~~~ +Some fancy code + going + on + here +~~~ + +`-o` +`--option` +: Description lists +: are useful as well + +And compact definition lists: + +`o` +: Option + +`k` +: Key + +`v` +: Value +{:.compact} + +| tables | can | be | centered | +{:.center} + +|-----------------+------------+-----------------+----------------| +| Default aligned |Left aligned| Center aligned | Right aligned | +|-----------------|:-----------|:---------------:|---------------:| +| First body part |Second cell | Third cell | fourth cell | +| Second *line* |foo | **strong** | baz | +| Third line |`quux` | baz | bar | +|-----------------+------------+-----------------+----------------| +| Second body | | | | +| 2nd line | | | | +|=================+============+=================+================| +| Footer row one | | | | +| Footer row two | | | | +|-----------------+------------+-----------------+----------------| + + +Inline formatting like *emphasis*, **strong** and `code span` work +as ususal. [Links](are_well.html) work, too! As do\\ +line breaks. + +Abbreviations like MD can be used but the abbreviation title is +ignored. + +*[MD]: Markdown + +Math elements work $$\lambda = 5$$ inline and in block form: + +$$\lambda_5 = \alpha + 4$$ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.man new file mode 100644 index 0000000..8e47527 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.man @@ -0,0 +1,4 @@ +.\" generated by kramdown +.TH "NAME" "7" +.SH NAME +name \- description diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.text new file mode 100644 index 0000000..832c921 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-dash-description.text @@ -0,0 +1 @@ +# name -- description diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.man new file mode 100644 index 0000000..e59dc5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.man @@ -0,0 +1,4 @@ +.\" generated by kramdown +.TH "NAME" "1" "November 2016" "Something extra" +.SH NAME +name \- description diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.text new file mode 100644 index 0000000..941482c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-description.text @@ -0,0 +1,2 @@ +# name description +{: data-section="1" data-date="November 2016" data-extra="Something extra"} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.man new file mode 100644 index 0000000..8df4ff7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.man @@ -0,0 +1,4 @@ +.\" generated by kramdown +.TH "NAME" "1" +.SH NAME +name \- description diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.text new file mode 100644 index 0000000..5f3e765 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section-description.text @@ -0,0 +1 @@ +# name(1) -- description diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.man new file mode 100644 index 0000000..7ca8757 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.man @@ -0,0 +1,2 @@ +.\" generated by kramdown +.TH "NAME" "1" diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.text new file mode 100644 index 0000000..da98dbd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name-section.text @@ -0,0 +1 @@ +# name(1) diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.man new file mode 100644 index 0000000..8488496 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.man @@ -0,0 +1,2 @@ +.\" generated by kramdown +.TH "NAME" "7" diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.text new file mode 100644 index 0000000..5f4656a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/heading-name.text @@ -0,0 +1 @@ +# name diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.man new file mode 100644 index 0000000..14ab233 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.man @@ -0,0 +1,4 @@ +.\" generated by kramdown +.SH "NAME" +works +.SS "Sub section" diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.text new file mode 100644 index 0000000..d1f5f86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/sections.text @@ -0,0 +1,11 @@ +## NAME + +works + +### Sub section + +#### Ignored + +##### Ignored + +###### Ignored diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.man b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.man new file mode 100644 index 0000000..710a4f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.man @@ -0,0 +1,8 @@ +.\" generated by kramdown +\&\. at the start of the line +.P +line with \efB backslash symbol +.P +some \. other \- escaped \' symbols +.P +\&\. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.text new file mode 100644 index 0000000..052b94f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/man/text-escaping.text @@ -0,0 +1,7 @@ +. at the start of the line + +line with \fB backslash symbol + +some . other - escaped \' symbols + +. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.html new file mode 100644 index 0000000..a1102ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.html @@ -0,0 +1,5 @@ +

This is [] empty.

+ +

This is [][] empty.

+ +

This is empty.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.text new file mode 100644 index 0000000..cca5de5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty.text @@ -0,0 +1,5 @@ +This is [] empty. + +This is [][] empty. + +This is [](test.html) empty. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.htmlinput b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.htmlinput new file mode 100644 index 0000000..b95b2cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.htmlinput @@ -0,0 +1,3 @@ +

Image with empty title: alt text

+ +

Link reference with empty title.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.text new file mode 100644 index 0000000..baabe7d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/empty_title.text @@ -0,0 +1,7 @@ +Image with empty title: ![alt text](/images/other.png) + +Link [reference][1] with empty title. + + + +[1]: http://example.tld diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.html new file mode 100644 index 0000000..e1f4ade --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.html @@ -0,0 +1,5 @@ +

Simple: Some alt text

+ +

Nested: Some alt ![img](text.png) text

+ +

Simple: Some text alt text text

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.text new file mode 100644 index 0000000..bdbfb65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/image_in_a.text @@ -0,0 +1,5 @@ +Simple: [Some ![alt text](/images/other.png)](local.html) + +Nested: [Some ![alt ![img](text.png) text](/images/other.png)](local.html) + +Simple: [Some *text ![alt text](/images/other.png) text*](local.html) diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.html new file mode 100644 index 0000000..565d36f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.html @@ -0,0 +1,15 @@ +

Simple: alt text

+ +

Simple with title: alt text

+ +

Empty img link: alt text

+ +

Reference style: alt text

+ +

Reference style with title: alt text

+ +

No alt text:

+ +

No id: imgo

+ +

With escaped pipe: an | pipe

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.text new file mode 100644 index 0000000..05050a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/imagelinks.text @@ -0,0 +1,18 @@ +Simple: ![alt text](/images/other.png) + +Simple with title: ![alt text](/images/other.png "title") + +Empty img link: ![alt text]() + +Reference style: ![alt text][img] + +Reference style with title: ![alt text][imgo] + +No alt text: ![](other.png) + +No id: ![imgo] + +[img]: other.png +[imgo]: other.png "Title" + +With escaped pipe: ![an \| pipe](other.png) diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.html new file mode 100644 index 0000000..8d00efa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.html @@ -0,0 +1,46 @@ +

simple URL

+ +

simple URL

+ +

simple URL with formatting

+ +

simple URL with single quoted title

+ +

simple URL with double quoted title

+ +

simple URL [with ] escaped

+ +

simple URL with ] escaped

+ +

simple URL [with] nested

+ +

simple URL with [no](link.html) inside

+ +

simple URL with parens

+ +

simple URL with parens

+ +

simple URL broken +on line

+ +

simple URL with spaces

+ +

simple URL with spaces

+ +

simple URL with spaces

+ +

simple leading/trailing spaces

+ +

simple leading/trailing spaces

+ +

simple leading/trailing spaces

+ +

bad [URL not

+ +

bad [URL with parens](something(new.html)

+ +

bad [URL with empty title](something.html ‘’)

+ +

bad [URL](

+ +

bad [URL](no

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.text new file mode 100644 index 0000000..c705764 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/inline.text @@ -0,0 +1,48 @@ +simple [URL]() + +simple [URL](something.html) + +simple [URL *with* formatting](something.html) + +simple [URL with single quoted title](something.html 'a t"itle') + +simple [URL with double quoted title](something.html "a t'itle") + +simple [URL \[with \] escaped](something.html) + +simple [URL with \] escaped](something.html) + +simple [URL [with] nested](something.html) + +simple [URL with [no](link.html) inside](something.html) + +simple [URL with parens](/something/to(do)) + +simple [URL with parens](/something/to(do "doit") + +simple [URL broken +on line](something.html +"title") + +simple [URL with spaces](with spaces.html) + +simple [URL with spaces](with spaces.html 'title') + +simple [URL with spaces](with (spaces).html) + +simple [leading/trailing spaces]( spaces.html) + +simple [leading/trailing spaces](spaces.html ) + +simple [leading/trailing spaces]( spaces.html ) + + +bad [URL [not](something.html) + +bad [URL with parens](something(new.html) + +bad [URL with empty title](something.html '') + +bad [URL]( + +bad [URL](no diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.latex new file mode 100644 index 0000000..63e58e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.latex @@ -0,0 +1,6 @@ +\href{https://example.com/~tilde/}{https://example.com/\ensuremath{\sim}tilde/} + +\href{http://example.com/percent\%20percent}{http://example.com/percent\%20percent} + +\href{http://example.com/hash#hash}{http://example.com/hash\#hash} + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.text new file mode 100644 index 0000000..9b27ae8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/latex_escaping.text @@ -0,0 +1,5 @@ + + + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.html new file mode 100644 index 0000000..15e2ca7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.html @@ -0,0 +1,9 @@ +

This is a para. +[id]: http://www.example.com/

+ +
[4]: nourl
+
+ +

Points to 1 and 2 and 3 but not [4]

+ +

Points to _.:,;!?- and otherid8

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.text new file mode 100644 index 0000000..16a25b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs.text @@ -0,0 +1,27 @@ +This is a para. +[id]: http://www.example.com/ + +[otherid1]: http://wwww.example.com/ "title 1" +[otherid2]: http://wwww.example.com/ 'title 2' +[otherid3]: +[otherid4]: 'title' +[otherid5]: some spaces.html +[otherid6]: some spaces.html 'title' +[otherid7]: some spaces + "title" +[otherid8]:test.html#'test' 'title' + +[break]: http://www.example.com/test/asdf.html + 'Another title' + +[1]: ignored.url + [1]: one.url + [2]: two.url + [3]: three.url + [4]: nourl + +Points to [1] and [2] and [3] but not [4] + +[_.:,;!?-]: http://example.com + +Points to [_.:,;!?-] and [otherid8] diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.html new file mode 100644 index 0000000..f56d77d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.html @@ -0,0 +1,4 @@ +

Link def with attr and attr 2 and attr 3 and attr before

+ +

test

+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.text new file mode 100644 index 0000000..59398a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/link_defs_with_ial.text @@ -0,0 +1,16 @@ +Link def with [attr] and [attr 2] and [attr 3] and [attr before] + +[attr]: http://example.com 'title' +{: hreflang="en" .test} + +[attr 2]: http://example.com 'title' +{: hreflang="en"} +{: .test} + +[attr 3]: http://example.com +{: .test} +test + +{: hreflang="en"} +{: .test} +[attr before]: http://example.com diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.html new file mode 100644 index 0000000..ecaa31e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.html @@ -0,0 +1,3 @@ +

This is a link.

+ +

This is a link.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.text new file mode 100644 index 0000000..2cf0ece --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/links_with_angle_brackets.text @@ -0,0 +1,3 @@ +This is a [link](). + +This is a [link]( 'and title'). diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.html new file mode 100644 index 0000000..f6fed18 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.html @@ -0,0 +1,37 @@ + +

simple URL and URL

+ +

simple URL and URL

+ +

simple 1 and isurl

+ +

simple 1 and isurl

+ +

this is [a holy isurl]

+ +

no [resolution][] here and [here]

+ +

with a break in +the text

+ +

this not [isurl] and not [isurl]

+ +

a Link with_BIG letters

+ +

bad [no URL] d isurl

+ +

[no url] invalid.html +[no url]:

+ +

“title”

+ +

test url but no title +test [urldef]

+ +

[urldef]: some.url ‘title”

+ +

some with spaces

+ +

this is a ‘special’ occasion for /all/ of us

+ +

this is predefined for URI

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.options new file mode 100644 index 0000000..efb4b01 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.options @@ -0,0 +1,3 @@ +:link_defs: + predefined: [predefined.html] + URI: [uri.html, My URI] diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.text new file mode 100644 index 0000000..9f39fa7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/01_link/reference.text @@ -0,0 +1,53 @@ +[isurl]: someurl.html + [1]: otherurl.html + +simple [URL][1] and [URL][isurl] + +simple [URL] [1] and [URL] +[isurl] + +simple [1][] and [isurl][] + +simple [1] and [isurl] + +this is [a holy [isurl]] + +no [resolution][] here and [here] + +with a [break in +the text] + + [break in the text]: url.html + +this not \[isurl] and not [isurl\] + +a [Link with_BIG] letters + + [link WITH_big]: letters.html + 'This is the title' + +bad [no URL] d [isurl] + +[no url] invalid.html +[no url]: + +[URL but no title]: invalid.html + + "title" + +test [url but no title] +test [urldef] + +[urldef]: some.url 'title" + + +some [with spaces] + +[with spaces]: with spaces.html "title" + +this [is a 'special' occasion for /all/ of us] + +[is a 'special' occasion for /all/ of us]: occasion.html + + +this is [predefined] for [URI] diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.html new file mode 100644 index 0000000..127e694 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.html @@ -0,0 +1,3 @@ +

This __is **empty.

+ +

This **is empty.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.text new file mode 100644 index 0000000..c99d053 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/empty.text @@ -0,0 +1,3 @@ +This __is **empty. + +This ****is empty. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.html new file mode 100644 index 0000000..e62f03f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.html @@ -0,0 +1,9 @@ +

This is a *star.

+ +

This is a **star.

+ +

This is *a *star.

+ +

This is *a star*.

+ +

This** is** a star.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.text new file mode 100644 index 0000000..e80e5eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/errors.text @@ -0,0 +1,9 @@ +This is a *star. + +This is a **star. + +This is **a *star*. + +This is *a star\*. + +This** is** a star. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.html new file mode 100644 index 0000000..3d34cee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.html @@ -0,0 +1,41 @@ +
    +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
  • test test
  • +
+
    +
  • ab
  • +
  • ab
  • +
  • abc
  • +
  • ab
  • +
  • ab
  • +
  • abc
  • +
+
    +
  • _a_b
  • +
  • a_b_
  • +
  • a_b_c
  • +
  • __a__b
  • +
  • a__b__
  • +
  • a__b__c
  • +
  • a__2__c
  • +
  • a__2__3
  • +
  • 1__2__3
  • +
+
    +
  • a _b_ c
  • +
  • a __b__ c
  • +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.text new file mode 100644 index 0000000..ba67e84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/nesting.text @@ -0,0 +1,36 @@ +- ***test test*** +- ___test test___ +- *test **test*** +- **test *test*** +- ***test* test** +- ***test** test* +- ***test* test** +- **test *test*** +- *test **test*** +- _test __test___ +- __test _test___ +- ___test_ test__ +- ___test__ test_ +- ___test_ test__ +- __test _test___ +- _test __test___ +^ +- *a*b +- a*b* +- a*b*c +- **a**b +- a**b** +- a**b**c +^ +- _a_b +- a_b_ +- a_b_c +- __a__b +- a__b__ +- a__b__c +- a__2__c +- a__2__3 +- 1__2__3 +^ +- *a _b_ c* +- **a __b__ c** diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.html new file mode 100644 index 0000000..b7ddf43 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.html @@ -0,0 +1,70 @@ +

This is so hard.

+ +

This is so hard too.

+ +

At start +At start

+ +

At end +At end

+ +

At start +At start

+ +

At end +At end

+ +

And nested.

+ +

And nest**ed.

+ +

And *nested* like this.

+ +

And not_nest_ed.

+ +

And nested.

+ +

And nested.

+ +

And neste.

+ +

And lonely * here*.

+ +

And lonely ** here**.

+ +

And lonely ** here.

+ +

** and here**.

+ +

And compli*cated * here

+ +

Some**what more * **here

+ +

Do it *this* way +Or this *this* way +Or that *that* way +Or that *that* way

+ +

http://blah.com/blah_%28 +http://blah.com/blah__%28 +http://blah.com/blah___%28 +http://blah.com/blah____%28 +http://blah.com/blah_____%28 +http://blah.com/blah______%28

+ +

A-_B

+ +
    +
  • test
  • +
  • test
  • +
  • test
  • +
  • (“test”)
  • +
  • (test)
  • +
  • test
  • +
  • `test
  • +
  • test
  • +
+ +

it–by design–cannot have side-effects.

+ +

it—by design—cannot have side-effects.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.options new file mode 100644 index 0000000..2e6e0a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.options @@ -0,0 +1 @@ +:entity_output: :numeric diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.text new file mode 100644 index 0000000..a242125 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/02_emphasis/normal.text @@ -0,0 +1,68 @@ +This *is* so **hard**. + +This _is_ so __hard__ too. + +*At* start +*At* start + +At *end* +At *end* + +_At_ start +_At_ start + +At _end_ +At _end_ + +And *nest**ed***. + +And *nest**ed*. + +And *nest**ed* like** this. + +And *not_nest_ed*. + +And ***nested***. + +And ___nested___. + +And **nest*e***. + +And lonely * here*. + +And lonely ** here**. + +And **lonely ** here**. + +** and here**. + +And **compli*cated \*** here + +Some***what* more * ***he*re + +Do it *\*this\** way +Or this \**this*\* way +Or that *\*that*\* way +Or that \**that\** way + +[http://blah.com/blah_%28](http://blah.com/blah_%28) +[http://blah.com/blah__%28](http://blah.com/blah__%28) +[http://blah.com/blah___%28](http://blah.com/blah___%28) +[http://blah.com/blah____%28](http://blah.com/blah____%28) +[http://blah.com/blah_____%28](http://blah.com/blah_____%28) +[http://blah.com/blah______%28](http://blah.com/blah______%28) + +[A-_B](A_-B) + +- _test_ +- '_test_' +- "_test_" +- ("_test_") +- (_test_) +- “_test_” +- \`_test_' +- „_test_“ + +it--by design--_cannot have side-effects_. + +it---by design---_cannot have side-effects_. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.html new file mode 100644 index 0000000..20c5051 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.html @@ -0,0 +1,5 @@ +

This is `` empty.

+ +

This is ``empty.

+ +

This is ````empty.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.text new file mode 100644 index 0000000..cbb9152 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/empty.text @@ -0,0 +1,5 @@ +This is `` empty. + +This is ``empty. + +This is ````empty. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.html new file mode 100644 index 0000000..1d341a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.html @@ -0,0 +1 @@ +

Not ended `span.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.text new file mode 100644 index 0000000..7a948b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/errors.text @@ -0,0 +1 @@ +Not ended `span. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.latex new file mode 100644 index 0000000..a1f84d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.latex @@ -0,0 +1,2 @@ +You can say \mintinline{ruby}{x = Class.new}, for example. + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.options new file mode 100644 index 0000000..c11ebb6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.options @@ -0,0 +1 @@ +:syntax_highlighter: minted diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.text new file mode 100644 index 0000000..7373290 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting-minted.text @@ -0,0 +1 @@ +You can say `x = Class.new`{:.language-ruby}, for example. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.html new file mode 100644 index 0000000..4294542 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.html @@ -0,0 +1 @@ +

You can say x = Class.new, for example.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.text new file mode 100644 index 0000000..7373290 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/highlighting.text @@ -0,0 +1 @@ +You can say `x = Class.new`{:.language-ruby}, for example. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.html new file mode 100644 index 0000000..ec21686 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.html @@ -0,0 +1 @@ +

This is a code-span

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.options new file mode 100644 index 0000000..bfc92f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.options @@ -0,0 +1,2 @@ +:syntax_highlighter_opts: + guess_lang: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.text new file mode 100644 index 0000000..f704439 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal-css-class.text @@ -0,0 +1 @@ +This is a `code-span` diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.html new file mode 100644 index 0000000..6de2257 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.html @@ -0,0 +1,20 @@ +

This is a simple span.

+ +

With some<ht>&ml in it.

+ +

And ` backticks.

+ +

And ``some`` more.

+ +

With backslash in\ it.

+ +

This is a ` literal backtick. +As `are` these!

+ +

No literal backtick.

+ +

something

+ +

` `

+ +

a ` `

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.text new file mode 100644 index 0000000..c188959 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/normal.text @@ -0,0 +1,20 @@ +This is `a` simple span. + +With `some&ml` in it. + +And `` ` `` backticks. + +And ``` ``some`` ``` more. + +With backslash `in\` it. + +This is a ` literal backtick. +As \`are\` these! + +No `` literal backtick``. + +`something` + +` ` + +a ` ` diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.html new file mode 100644 index 0000000..7822f78 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.html @@ -0,0 +1 @@ +

You can say Class.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.options new file mode 100644 index 0000000..34094e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.options @@ -0,0 +1,4 @@ +:syntax_highlighter: rouge +:syntax_highlighter_opts: + span: + disable: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.text new file mode 100644 index 0000000..d958d91 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/disabled.text @@ -0,0 +1 @@ +You can say `Class`{:.language-ruby}. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.html new file mode 100644 index 0000000..4294542 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.html @@ -0,0 +1 @@ +

You can say x = Class.new, for example.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.options new file mode 100644 index 0000000..9ac61e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.options @@ -0,0 +1 @@ +:syntax_highlighter: rouge diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.text new file mode 100644 index 0000000..7373290 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/03_codespan/rouge/simple.text @@ -0,0 +1 @@ +You can say `x = Class.new`{:.language-ruby}, for example. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.html new file mode 100644 index 0000000..f18212b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.html @@ -0,0 +1,79 @@ +

This is 123456789

+ +
+
    +
  1. + +

    A paragraph 

    +
  2. +
  3. + +

    A header 

    +
  4. +
  5. + +
    +

    blockquote

    + +

    paragraph 

    +
    +
  6. +
  7. + +
    codeblock
    +
    +

    +
  8. +
  9. + +
      +
    • item 1
    • +
    • item 2 +
        +
      • +

        sub item

        + +
        +

        blockquote

        + +

        header 

        +
        +
      • +
      +
    • +
    +
  10. +
  11. + + + + + + + + + + + + +
    ab
    cd
    +

    +
  12. +
  13. + +
    +

    +
  14. +
  15. + +\[x + 2\] +

    +
  16. +
  17. + +
    test +
    +

    +
  18. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.options new file mode 100644 index 0000000..ac54fc0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.options @@ -0,0 +1 @@ +footnote_backlink_inline: true diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.text new file mode 100644 index 0000000..55f94a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_inline.text @@ -0,0 +1,38 @@ +This is [^paragraph][^header][^blockquote][^codeblock][^list][^table][^hrule][^mathblock][^html] + +[^paragraph]: + A paragraph + +[^header]: + # A header + +[^blockquote]: + > blockquote + > + > paragraph + +[^codeblock]: + codeblock + +[^list]: + * item 1 + * item 2 + * sub item + + > blockquote + > + > # header + +[^table]: + | a | b | + | c | d | + +[^hrule]: + *** + +[^mathblock]: + $$x + 2$$ + +[^html]: +
test +
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.html new file mode 100644 index 0000000..bed0869 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.html @@ -0,0 +1,9 @@ +

Some footnote here1

+ +
+
    +
  1. +

    Some text here text &8617; <img />

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.options new file mode 100644 index 0000000..4c677ef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.options @@ -0,0 +1 @@ +:footnote_backlink: 'text &8617; ' diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.text new file mode 100644 index 0000000..41a6f98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/backlink_text.text @@ -0,0 +1,3 @@ +Some footnote here[^fn] + +[^fn]: Some text here diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.html new file mode 100644 index 0000000..9012cc0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.html @@ -0,0 +1,17 @@ +

Some para.

+ +
+

blockquote

+
+ +
    +
  • a list +with some text
  • +
+ +
    +
  • other list
  • +
+
code
+
+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.latex new file mode 100644 index 0000000..965653c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.latex @@ -0,0 +1,17 @@ +Some para. + +\begin{quote} +blockquote +\end{quote} + +\begin{itemize} +\item{} a list +with some text +\end{itemize} + +\begin{itemize} +\item{} other list +\end{itemize} +\begin{verbatim}code +\end{verbatim} + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.text new file mode 100644 index 0000000..44b52e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/definitions.text @@ -0,0 +1,24 @@ +Some para. + +[^footnote]: ignored definition +[^footnote]: Some footnote text + +> blockquote + +[^other]: some + foot + + note text + +* a list + with some text + +[^tnote]: foot note + +* other list +^ + code + +[^1]: + > a blockquote + and some para diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.html new file mode 100644 index 0000000..0867c86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.html @@ -0,0 +1,12 @@ +

This is a[footnote 1] footnote[footnote 1]. And another[footnote 2].

+ +
+
    +
  1. +

    Some text.  2

    +
  2. +
  3. +

    Some other text. 

    +
  4. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.options new file mode 100644 index 0000000..092fd1a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.options @@ -0,0 +1 @@ +:footnote_link_text: "[footnote %s]" diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.text new file mode 100644 index 0000000..3876de0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_link_text.text @@ -0,0 +1,4 @@ +This is a[^ab] footnote[^ab]. And another[^bc]. + +[^ab]: Some text. +[^bc]: Some other text. \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.html new file mode 100644 index 0000000..77c0a84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.html @@ -0,0 +1,12 @@ +

This is a footnote35. And another36.

+ +
+
    +
  1. +

    Some text. 

    +
  2. +
  3. +

    Some other text. 

    +
  4. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.latex new file mode 100644 index 0000000..8f07dde --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.latex @@ -0,0 +1,2 @@ +This is a footnote\footnote{Some text.}. And another\footnote{Some other text.}. + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.options new file mode 100644 index 0000000..f606ecf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.options @@ -0,0 +1 @@ +:footnote_nr: 35 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.text new file mode 100644 index 0000000..cad2935 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_nr.text @@ -0,0 +1,4 @@ +This is a footnote[^ab]. And another[^bc]. + +[^ab]: Some text. +[^bc]: Some other text. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.html new file mode 100644 index 0000000..90aa226 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.html @@ -0,0 +1,12 @@ +

This is a1 footnote1. And another2.

+ +
+
    +
  1. +

    Some text.  2

    +
  2. +
  3. +

    Some other text. 

    +
  4. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.options new file mode 100644 index 0000000..51d78bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.options @@ -0,0 +1 @@ +:footnote_prefix: adf123- diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.text new file mode 100644 index 0000000..884053e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/footnote_prefix.text @@ -0,0 +1,4 @@ +This is a[^ab] footnote[^ab]. And another[^bc]. + +[^ab]: Some text. +[^bc]: Some other text. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.html new file mode 100644 index 0000000..d4e97ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.html @@ -0,0 +1,17 @@ +

Lorem ipsum1 dolor sit amet.

+ +

Lorem ipsum2 dolor sit amet.

+ +
+
    +
  1. +

    Consecutur adisping.3 

    +
  2. +
  3. +

    Sed ut perspiciatis unde omnis. 

    +
  4. +
  5. +

    Sed ut. 

    +
  6. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.text new file mode 100644 index 0000000..f4f91e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/inside_footnote.text @@ -0,0 +1,9 @@ +Lorem ipsum[^first] dolor sit amet. + +Lorem ipsum[^second] dolor sit amet. + +[^first]: Consecutur adisping.[^third] + +[^second]: Sed ut perspiciatis unde omnis. + +[^third]: Sed ut. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.html new file mode 100644 index 0000000..90f2ccb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.html @@ -0,0 +1,46 @@ +

This is some *ref.1

+ +
+

a blockquote 2

+
+ +
    +
  • and a list item 3
  • +
+ +

And a header4

+ +

A marker without a definition [^without].

+ +

A marker 5 used twice1 and thrice1.

+ +
+
    +
  1. +

    Some foot note text  2 3

    +
  2. +
  3. +

    other text +with more lines

    + +
    +

    and a quote

    +
    +

    +
  4. +
  5. +

    some text 

    +
  6. +
  7. + +
    code block
    +continued here
    +
    +

    +
  8. +
  9. + +

    +
  10. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.latex new file mode 100644 index 0000000..8f406b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.latex @@ -0,0 +1,23 @@ +This is some *ref.\footnote{Some foot note text} + +\begin{quote} +a blockquote \footnote{other text +with more lines + +\begin{quote} +and a quote +\end{quote}} +\end{quote} + +\begin{itemize} +\item{} and a list item \footnote{some \emph{text}} +\end{itemize} + +\section*{And a header\footnote{\begin{verbatim}code block +continued here +\end{verbatim}}} + +A marker without a definition {[}\^{}without{]}. + +A marker \footnote{} used twice\footnote{Some foot note text} and thrice\footnote{Some foot note text}. + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.options new file mode 100644 index 0000000..5cfe250 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.options @@ -0,0 +1,2 @@ +:auto_ids: false +:entity_output: :symbolic diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.text new file mode 100644 index 0000000..42b77fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/markers.text @@ -0,0 +1,27 @@ +This is some *ref.[^fn] + +[^fn]: Some foot note text +{: .class} + +> a blockquote [^3] + +* and a list item [^1] + +# And a header[^now] + +[^1]:some *text* +[^3]: other text + with more lines + + > and a quote + +A marker without a definition [^without]. + +A marker [^empty] used twice[^fn] and thrice[^fn]. + +[^now]: + + code block + continued here + +[^empty]: diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.html new file mode 100644 index 0000000..a87f359 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.html @@ -0,0 +1,11 @@ +
+
    +
  1. +

    Footnote \` text 

    +
  2. +
+
+ +

Some para with a1 footnote.

+ +

And another para.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.options new file mode 100644 index 0000000..2e6e0a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.options @@ -0,0 +1 @@ +:entity_output: :numeric diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.text new file mode 100644 index 0000000..97c0ab1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/placement.text @@ -0,0 +1,8 @@ +* footnotes will be placed here +{:footnotes} + +Some para with a[^1] footnote. + +[^1]: Footnote \\\` text + +And another para. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.html new file mode 100644 index 0000000..64ce4ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.html @@ -0,0 +1,14 @@ +

Something

+

something1.

+ +

Footnotes

+ +

Test

+
+
    +
  1. + +

    A note 

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.options new file mode 100644 index 0000000..5cfe250 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.options @@ -0,0 +1,2 @@ +:auto_ids: false +:entity_output: :symbolic diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.text new file mode 100644 index 0000000..6a60c61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/regexp_problem.text @@ -0,0 +1,52 @@ +# Something +something[^note1]. + +# Footnotes +[^note1]: + A note + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# Test diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.html new file mode 100644 index 0000000..e6f2d79 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.html @@ -0,0 +1,9 @@ +

Some footnote here1

+ +
+
    +
  1. +

    Some text here

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.options new file mode 100644 index 0000000..0512dd6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.options @@ -0,0 +1 @@ +:footnote_backlink: '' diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.text new file mode 100644 index 0000000..41a6f98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/04_footnote/without_backlink.text @@ -0,0 +1,3 @@ +Some footnote here[^fn] + +[^fn]: Some text here diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.html new file mode 100644 index 0000000..e7cec40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.html @@ -0,0 +1 @@ +

Link: test

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.text new file mode 100644 index 0000000..8f39d95 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/across_lines.text @@ -0,0 +1,2 @@ +Link: test diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.html new file mode 100644 index 0000000..c49bb52 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.html @@ -0,0 +1,7 @@ +

+ +

First some text and then a

+ +

and then text.

+ +

A it.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.text new file mode 100644 index 0000000..e0a7783 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/button.text @@ -0,0 +1,7 @@ + + +First some text and then a + + and then text. + +A it. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.html new file mode 100644 index 0000000..030552f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.html @@ -0,0 +1 @@ +

This is some text

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.text new file mode 100644 index 0000000..383f0a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/invalid.text @@ -0,0 +1 @@ +This is some text diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.html new file mode 100644 index 0000000..7d0d6ad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.html @@ -0,0 +1 @@ +

Link: text

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.text new file mode 100644 index 0000000..fb01619 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/link_with_mailto.text @@ -0,0 +1 @@ +Link: text diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.html new file mode 100644 index 0000000..b6989b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.html @@ -0,0 +1,3 @@ +

Lorem ipsum.

+ +

Test

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.text new file mode 100644 index 0000000..6ae30e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/mark_element.text @@ -0,0 +1,3 @@ +Lorem ipsum. + +Test diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.html new file mode 100644 index 0000000..44158c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.html @@ -0,0 +1,6 @@ +

This is text +This is *text* +This is text +This is text +This is *nothing* to fear about. +This is <http://example.com>.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.text new file mode 100644 index 0000000..dcc10ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/markdown_attr.text @@ -0,0 +1,6 @@ +This is *text* +This is *text* +This is *text* +This is *text* +This is *nothing* to *fear* about. +This is . diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.html new file mode 100644 index 0000000..3cdc646 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.html @@ -0,0 +1,43 @@ +

Empty !

+ +

title is a title.

+ +

This is <? a PI ?>.

+ +

This is comment.

+ +

This is multiline comment.

+ +

This is tag +now .

+ +

This is tag + now.

+ +

This is an empty tag.

+ +

This is something strange.

+ +

Auto-closing:

+ +

Expanding:

+ +

An invalid tag: <hR>

+ +

A <p>block tag</p>.

+ +

An invalid </closing> tag.

+ +

A tag.

+ +

An unclosed tag.

+ +

Some element with | pipe symbol

+ +

Some element with | pipe symbol

+ +

Some element with | pipe +symbol|

+ +

underlined

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.text new file mode 100644 index 0000000..0156d7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/normal.text @@ -0,0 +1,43 @@ +Empty ! + +title is a title. + +This is . + +This is comment. + +This is multiline comment. + +This is tag +now . + +This is tag + now. + +This is an empty tag. + +This is _something strange_. + +Auto-closing:
+ +Expanding: + +An invalid tag:
+ +A

block tag

. + +An invalid tag. + +A tag. + +An unclosed *tag.* + +Some element with | pipe symbol + +Some element with | pipe symbol + +Some element with | pipe +symbol| + +underlined diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.html new file mode 100644 index 0000000..808f1db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.html @@ -0,0 +1,2 @@ +

This is raw --version and --version and --version and +---version.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.text new file mode 100644 index 0000000..5b128fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/raw_span_elements.text @@ -0,0 +1,2 @@ +This is raw --version and --version and --version and +---version. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.html new file mode 100644 index 0000000..00b43c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.html @@ -0,0 +1,5 @@ +

This doit test

+ +

This doit test

+ +

This doit</some> test

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.text new file mode 100644 index 0000000..bc234de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/05_html/xml.text @@ -0,0 +1,5 @@ +This doit test + +This doit test + +This doit test diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.html new file mode 100644 index 0000000..6bddfda --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.html @@ -0,0 +1,25 @@ +

This is some text.

+ +

There is some real concern about OtHeR!

+ +

is some Think empty about Oesterreich. CSS und CSS3

+ +

no abbrev here because there is someone and kulis some

+ +
    +
  • (X)HTML test
  • +
  • line two
  • +
+ +

(X)HTML

+ +
    +
  • test (X)HTML
  • +
+ +

This is awesome.

+ +

hello foo bar babble.

+ +

hello foo +bar babble.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.text new file mode 100644 index 0000000..f5ec88e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev.text @@ -0,0 +1,41 @@ +This is some text. + +*[is some]: Yes it is +*[OtHeR!]: This & that + +*[is some]: It is, yes +*[empty]: + +There *is some real* concern about OtHeR! + +is some Think empty about Oesterreich. CSS und CSS3 + +no abbrev here because there is someone and kulis some + +*[Oesterreich]: Very nice country + +*[CSS]: Cascading +*[CSS3]: Cascading 3 + +* (X)HTML test +* line two + +[(X)HTML](http://en.wikipedia.org/wiki/Xhtml) + +* test (X)HTML + +*[(X)HTML]: (eXtensible) HyperText Markup Language + + +This is awesome. + +{:.testit} +*[awesome]: Some text here +{:.test} + +*[foo bar]: baz + +hello foo bar babble. + +hello foo +bar babble. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.html new file mode 100644 index 0000000..108fcfc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.html @@ -0,0 +1,2 @@ +
*[4]: noabbrev
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.text new file mode 100644 index 0000000..3f3a0e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_defs.text @@ -0,0 +1,5 @@ +*[ABBR]: Some abbreviations + *[one abbr]: one abbrev + *[2 and other]: another + *[3]: yet another + *[4]: noabbrev diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.html new file mode 100644 index 0000000..6da3ca4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.html @@ -0,0 +1,9 @@ +

This is some TEST to check.

+ + + This TEST fails. + + + This TEST fails. + + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.text new file mode 100644 index 0000000..e0a0e88 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/abbrev_in_html.text @@ -0,0 +1,10 @@ +This is some TEST to check. + + + This TEST fails. + + + This TEST fails. + + +*[TEST]: This Escapes SVG Text. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.html new file mode 100644 index 0000000..7cce8be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.html @@ -0,0 +1,9 @@ +

There is a TXT file here. 1

+ +
+
    +
  1. +

    A TXT file. 

    +
  2. +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.text new file mode 100644 index 0000000..e7709cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/abbreviations/in_footnote.text @@ -0,0 +1,5 @@ +There is a TXT file here. [^1] + +*[TXT]: Text File + +[^1]: A TXT file. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.html new file mode 100644 index 0000000..90eae7d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.html @@ -0,0 +1,15 @@ +

This should be a http://www.example.com/ link. +This should be a john.doe@example.com link. +As should john.doe@example.com this. +As should john_doe@example.com this. +As should CSS@example.com this. +Another ampersand http://www.example.com/?doit&x=y link. +More entities http://www.example.com/?doit&x="y&z=y.

+ +

Email international übung@macht.den.meister.de, ü.äß@hülse.de +Email invalid: <me@example.com>

+ +

Autolink with underscore: http://www.example.com/with_under_score

+ +

http://www.example.com/

+ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.text new file mode 100644 index 0000000..033e8af --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/autolinks/url_links.text @@ -0,0 +1,16 @@ +This should be a link. +This should be a link. +As should this. +As should this. +As should this. +Another ampersand link. +More entities . + +Email international <übung@macht.den.meister.de>, <ü.äß@hülse.de> +Email invalid: <[me@example.com](mailtos:me@example.com)> + +Autolink with underscore: + + + +*[CSS]: Cascading diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.html new file mode 100644 index 0000000..015d594 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.html @@ -0,0 +1,47 @@ +

\

+ +

.

+ +

*

+ +

_

+ +

+

+ +

-

+ +

`

+ +

(

+ +

)

+ +

[

+ +

]

+ +

{

+ +

}

+ +

#

+ +

!

+ +

<<

+ +

>>

+ +

:

+ +

|

+ +

"

+ +

'

+ +

=

+ +

>

+ +

<

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.text new file mode 100644 index 0000000..1c47104 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/escaped_chars/normal.text @@ -0,0 +1,47 @@ +\\ + +\. + +\* + +\_ + +\+ + +\- + +\` + +\( + +\) + +\[ + +\] + +\{ + +\} + +\# + +\! + +\<< + +\>> + +\: + +\| + +\" + +\' + +\= + +\> + +\< diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.html new file mode 100644 index 0000000..3544d49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.html @@ -0,0 +1,6 @@ +

This is a paragraph. +This is a paragraph. +This is a . +This is a paragraph. +This is a {:/comment} simple {:/} paragraph. +This is a {::comment} paragraph.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.text new file mode 100644 index 0000000..8b9e8d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/comment.text @@ -0,0 +1,6 @@ +This is a {::comment}simple{:/} paragraph. +This is a {::comment}simple{:/comment} paragraph. +This is a {::comment}simple {:/other} paragraph{:/comment}. +This is a {::comment/} paragraph. +This is a {:/comment} simple {:/} paragraph. +This is a {::comment} paragraph. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.html new file mode 100644 index 0000000..63c2c40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.html @@ -0,0 +1 @@ +

This is {::something}paragraph{:/}

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.text new file mode 100644 index 0000000..a7e7737 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/ignored.text @@ -0,0 +1 @@ +This is {::something}paragraph{:/} diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.html new file mode 100644 index 0000000..83de931 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.html @@ -0,0 +1 @@ +

This is *some* text.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.text new file mode 100644 index 0000000..57c4b38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/nomarkdown.text @@ -0,0 +1 @@ +This is {::nomarkdown}*some*{:/} text. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.html new file mode 100644 index 0000000..48e3076 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.html @@ -0,0 +1 @@ +

This is an option *true*!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.text new file mode 100644 index 0000000..e289491 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/extension/options.text @@ -0,0 +1 @@ +This is an {::options parse_span_html="false" /} option *true*! diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.html new file mode 100644 index 0000000..c0f3a47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.html @@ -0,0 +1,6 @@ +

This is a span.

+ +

This is a span.

+ +

This is an{: .ignored} span ial. +This is an{: .escaped} span ial.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.text new file mode 100644 index 0000000..8945602 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/ial/simple.text @@ -0,0 +1,6 @@ +This is a `span`{: .hund #dog}. + +This is a `span`{: .hund #dog}{: .katz key='val'}. + +This is an{: .ignored} span ial. +This is an\{: .escaped} span ial. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.html new file mode 100644 index 0000000..11066a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.html @@ -0,0 +1,11 @@ +

This is a line
+with a line break.

+ +

This is a line +without a line break.

+ +

This is a line
+with a line\
+break.

+ +

Line break on last line.

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.latex new file mode 100644 index 0000000..a62ff56 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.latex @@ -0,0 +1,12 @@ +This is a line\newline +with a line break. + +This is a line +without a line break. + +This is a line \newline +with a line\textbackslash{} \newline +break. + +Line break on last line. + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.text new file mode 100644 index 0000000..92f866f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/line_breaks/normal.text @@ -0,0 +1,11 @@ +This is a line +with a line break. + +This is a line +without a line break. + +This is a line \\ +with a line\\ +break. + +Line break on last line. diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.html new file mode 100644 index 0000000..3b93c54 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.html @@ -0,0 +1 @@ +

$5+5$ inline math

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.options new file mode 100644 index 0000000..06d559e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.options @@ -0,0 +1 @@ +:math_engine: ~ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.text new file mode 100644 index 0000000..a22f9fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/no_engine.text @@ -0,0 +1 @@ +$$5+5$$ inline math diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.html new file mode 100644 index 0000000..459d03f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.html @@ -0,0 +1,10 @@ +

This is \(\lambda_\alpha > 5\) some math. With \(1 ++ 1\) new line characters in between.

+ +

\(5+5\) inline math, $5.00 $$no math$$

+ +

$$5+5$$ inline math

+ +

\(5+5\)

+ +

$$5+5$$

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.text new file mode 100644 index 0000000..e37a007 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/math/normal.text @@ -0,0 +1,10 @@ +This is $$\lambda_\alpha > 5$$ some math. With $$1 ++ 1$$ new line characters in between. + +$$5+5$$ inline math, $5.00 \$$no math$$ + +\$\$5+5$$ inline math + +\$$5+5$$ + +\$\$5+5$$ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.html new file mode 100644 index 0000000..21a2903 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.html @@ -0,0 +1,6 @@ +

This is the A&O. © 2008 by me +As well \& as this. Some ŗ other +values may ¯ may also show but +not st. like &#xYZ;.

+ +

This <span> is BS&T; done!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.options new file mode 100644 index 0000000..036c561 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.options @@ -0,0 +1 @@ +:entity_output: :as_input diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.text new file mode 100644 index 0000000..7ef42c7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities.text @@ -0,0 +1,6 @@ +This is the A&O. © 2008 by me +As well \& as this. Some ŗ other +values may ¯ may also show but +not st. like &#xYZ;. + +This <span> is BS&T; done! diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.html new file mode 100644 index 0000000..ed2817b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.html @@ -0,0 +1 @@ +

This "is" 'the' A&O. © 2008 by me ŗ and λ

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.options new file mode 100644 index 0000000..32a751e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.options @@ -0,0 +1,2 @@ +:entity_output: :as_char +:smart_quotes: apos,apos,quot,quot diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.text new file mode 100644 index 0000000..279b511 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_char.text @@ -0,0 +1 @@ +This "is" 'the' A&O. © 2008 by me ŗ and λ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.html new file mode 100644 index 0000000..d2eec9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.html @@ -0,0 +1 @@ +

This is the A&O. © 2008 by me ŗ and λ

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.options new file mode 100644 index 0000000..036c561 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.options @@ -0,0 +1 @@ +:entity_output: :as_input diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.text new file mode 100644 index 0000000..1ddf7cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_as_input.text @@ -0,0 +1 @@ +This is the A&O. © 2008 by me ŗ and λ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.html new file mode 100644 index 0000000..d04613e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.html @@ -0,0 +1 @@ +

This is the A&O. © 2008 by me ŗ and λ

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.options new file mode 100644 index 0000000..2e6e0a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.options @@ -0,0 +1 @@ +:entity_output: :numeric diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.text new file mode 100644 index 0000000..1ddf7cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_numeric.text @@ -0,0 +1 @@ +This is the A&O. © 2008 by me ŗ and λ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.html new file mode 100644 index 0000000..258ba14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.html @@ -0,0 +1 @@ +

This is the A&O. © 2008 by me ŗ and λ

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.options new file mode 100644 index 0000000..c195785 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.options @@ -0,0 +1 @@ +:entity_output: :symbolic diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.text new file mode 100644 index 0000000..1ddf7cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/entities_symbolic.text @@ -0,0 +1 @@ +This is the A&O. © 2008 by me ŗ and λ diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.html new file mode 100644 index 0000000..dcce4cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.html @@ -0,0 +1 @@ +

2 > 1 > 0

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.text new file mode 100644 index 0000000..7dfb7f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/greaterthan.text @@ -0,0 +1 @@ +2 > 1 > 0 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.html new file mode 100644 index 0000000..8ebac23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.html @@ -0,0 +1 @@ +

0 < 1 < 2

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.text new file mode 100644 index 0000000..038df8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/lowerthan.text @@ -0,0 +1 @@ +0 < 1 < 2 diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.html new file mode 100644 index 0000000..02d1dbc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.html @@ -0,0 +1,40 @@ +

This is… something—this too–!

+ +

This «is» some text, « this » too!

+ +

“Fancy quotes” are ‘cool’, even in the ’80s! +Je t’ aime. You’re a funny one! Thomas’ name +Mark’s name. “…you” +“‘Nested’ quotes are ‘possible’”, too! +‘“Otherway” is “round”’!

+ +

‘Opening now!’

+ +

’80s are really cool.

+ +

Cluster’s Last Stand.

+ +

Nam liber tempor +“…At vero eos et accusam”

+ +

Single underscores should work.”

+ +

Single asterisks should work.”

+ +

Double underscores should work.’

+ +

Double asterisks should work.’

+ +

Hurrah!

+ +

Absolutely.’

+ +

“…some Text”

+ +

“… some Text”

+ +

This: “…some Text”

+ +

This: “… some Text”

+ +

”[foo]” “[foo]” d “[foo]”

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.options new file mode 100644 index 0000000..4f1c17c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.options @@ -0,0 +1 @@ +:entity_output: symbolic diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.text new file mode 100644 index 0000000..27e090e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography.text @@ -0,0 +1,40 @@ +This is... something---this too--! + +This <> some text, << this >> too! + +"Fancy quotes" are 'cool', even in the '80s! +Je t' aime. You're a funny one! Thomas' name +Mark's name. "...you" +"'Nested' quotes are 'possible'", too! +'"Otherway" is "round"'! + +'Opening now!' + +'80s are really cool. + +Cluster's Last Stand. + +Nam liber tempor +"...At vero eos et accusam" + +"_Single underscores_ should work." + +"*Single asterisks* should work." + +'__Double underscores__ should work.' + +'**Double asterisks** should work.' + +"_Hurrah!_" + +'__Absolutely__.' + +"...some Text" + +"... some Text" + +This: "...some Text" + +This: "... some Text" + +"\[foo]" "\[foo]" d "\[foo]" diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.html b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.html new file mode 100644 index 0000000..4a6c226 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.html @@ -0,0 +1,3 @@ +

This ... something---this too--!

+ +

This <<is>> some text, << this >> too!

diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.latex b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.latex new file mode 100644 index 0000000..c7d9ba5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.latex @@ -0,0 +1,4 @@ +This ... something---this too--! + +This \textless{}\textless{}is\textgreater{}\textgreater{} some text, \textless{}\textless{} this \textgreater{}\textgreater{} too! + diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.options b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.options new file mode 100644 index 0000000..d0a0313 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.options @@ -0,0 +1,8 @@ +typographic_symbols: + hellip: '...' + mdash: '---' + ndash: '--' + laquo: '<<' + raquo: '>>' + laquo_space: '<< ' + raquo_space: ' >>' diff --git a/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.text b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.text new file mode 100644 index 0000000..a3d59b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/kramdown-2.5.2/test/testcases/span/text_substitutions/typography_subst.text @@ -0,0 +1,3 @@ +This ... something---this too--! + +This <> some text, << this >> too! diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CHANGELOG.md new file mode 100644 index 0000000..232adbd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CHANGELOG.md @@ -0,0 +1 @@ +# Moved to [GitHub releases](https://github.com/guard/listen/releases) page. diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CONTRIBUTING.md b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CONTRIBUTING.md new file mode 100644 index 0000000..7e5b197 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/CONTRIBUTING.md @@ -0,0 +1,45 @@ +Contribute to Listen +=================== + +File an issue +------------- + +If you haven't already, first see [TROUBLESHOOTING](https://github.com/guard/listen/blob/master/README.md#Issues-and-Troubleshooting) for known issues, solutions and workarounds. + +You can report bugs and feature requests to [GitHub Issues](https://github.com/guard/listen/issues). + +**Please don't ask question in the issue tracker**, instead ask them in our +[Google group](http://groups.google.com/group/guard-dev) or on `#guard` (irc.freenode.net). + +Try to figure out where the issue belongs to: Is it an issue with Listen itself or with Guard? + + +**It's most likely that your bug gets resolved faster if you provide as much information as possible!** + +The MOST useful information is debugging output from Listen (`LISTEN_GEM_DEBUGGING=1`) - see [TROUBLESHOOTING](https://github.com/guard/listen/blob/master/README.md#Issues-and-Troubleshooting) for details. + + +Development +----------- + +* Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames). +* Source hosted at [GitHub](https://github.com/guard/listen). + +Pull requests are very welcome! Please try to follow these simple rules if applicable: + +* Please create a topic branch for every separate change you make. +* Make sure your patches are well tested. All specs run with `rake spec` must pass. +* Update the [Yard](http://yardoc.org/) documentation. +* Update the [README](https://github.com/guard/listen/blob/master/README.md). +* Please **do not change** the version number. + +The title of your PR will automatically be included in the release notes for the next version of the gem. A maintainer can add one of the following GitHub labels to the PR to automatically categorize it when the release notes are generated: + +- ⚠️ Breaking +- ✨ Feature +- 🐛 Bug Fix +- 📚 Docs +- 🏠 Housekeeping + +For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on +`#guard` (irc.freenode.net). diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/LICENSE.txt new file mode 100644 index 0000000..b5f71c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2013 Thibaud Guillaume-Gentil + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/README.md b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/README.md new file mode 100644 index 0000000..1ba0e48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/README.md @@ -0,0 +1,490 @@ +# Listen + +The `listen` gem listens to file modifications and notifies you about the changes. + +[![Development Status](https://github.com/guard/listen/workflows/Development/badge.svg)](https://github.com/guard/listen/actions?workflow=Development) +[![Gem Version](https://badge.fury.io/rb/listen.svg)](http://badge.fury.io/rb/listen) +[![Code Climate](https://codeclimate.com/github/guard/listen.svg)](https://codeclimate.com/github/guard/listen) +[![Coverage Status](https://coveralls.io/repos/guard/listen/badge.svg?branch=master)](https://coveralls.io/r/guard/listen) + +## Features + +* OS-optimized adapters on MRI for Mac OS X 10.6+, Linux, \*BSD and Windows, [more info](#listen-adapters) below. +* Detects file modification, addition and removal. +* You can watch multiple directories. +* Regexp-patterns for ignoring paths for more accuracy and speed +* Increased change detection accuracy on OS X HFS and VFAT volumes. +* Continuous Integration: tested on selected Ruby environments via [Github Workflows](https://github.com/guard/listen/tree/master/.github/workflows). + +## Issues / limitations + +* Limited support for symlinked directories ([#279](https://github.com/guard/listen/issues/279)): + * Symlinks are always followed ([#25](https://github.com/guard/listen/issues/25)). + * Symlinked directories pointing within a watched directory are not supported ([#273](https://github.com/guard/listen/pull/273). +* No directory/adapter-specific configuration options. +* Support for plugins planned for future. +* TCP functionality was removed in `listen` [3.0.0](https://github.com/guard/listen/releases/tag/v3.0.0) ([#319](https://github.com/guard/listen/issues/319), [#218](https://github.com/guard/listen/issues/218)). There are plans to extract this feature to separate gems ([#258](https://github.com/guard/listen/issues/258)), until this is finished, you can use by locking the `listen` gem to version `'~> 2.10'`. +* Some filesystems won't work without polling (VM/Vagrant Shared folders, NFS, Samba, sshfs, etc.). +* Windows and \*BSD adapter aren't continuously and automatically tested. +* OSX adapter has some performance limitations ([#342](https://github.com/guard/listen/issues/342)). +* Listeners do not notify across forked processes, if you wish for multiple processes to receive change notifications you must [listen inside of each process](https://github.com/guard/listen/issues/398#issuecomment-223957952). + +Pull requests or help is very welcome for these. + +## Install + +The simplest way to install `listen` is to use [Bundler](http://bundler.io). + +```ruby +gem 'listen' +``` + +## Complete Example +Here is a complete example of using the `listen` gem: +```ruby +require 'listen' + +listener = Listen.to('/srv/app') do |modified, added, removed| + puts(modified: modified, added: added, removed: removed) +end +listener.start +sleep +``` +Running the above in the background, you can see the callback block being called in response to each command: +``` +$ cd /srv/app +$ touch a.txt +{:modified=>[], :added=>["/srv/app/a.txt"], :removed=>[]} + +$ echo more >> a.txt +{:modified=>["/srv/app/a.txt"], :added=>[], :removed=>[]} + +$ mv a.txt b.txt +{:modified=>[], :added=>["/srv/app/b.txt"], :removed=>["/srv/app/a.txt"]} + +$ vi b.txt +# add a line to this new file and press ZZ to save and exit +{:modified=>["/srv/app/b.txt"], :added=>[], :removed=>[]} + +$ vi c.txt +# add a line and press ZZ to save and exit +{:modified=>[], :added=>["/srv/app/c.txt"], :removed=>[]} + +$ rm b.txt c.txt +{:modified=>[], :added=>[], :removed=>["/srv/app/b.txt", "/srv/app/c.txt"]} +``` + +## Usage + +Call `Listen.to` with one or more directories and the "changes" callback passed as a block. + +``` ruby +listener = Listen.to('dir/to/listen', 'dir/to/listen2') do |modified, added, removed| + puts "modified absolute path array: #{modified}" + puts "added absolute path array: #{added}" + puts "removed absolute path array: #{removed}" +end +listener.start # starts a listener thread--does not block + +# do whatever you want here...just don't exit the process :) + +sleep +``` +## Changes Callback + +Changes to the listened-to directories are reported by the listener thread in a callback. +The callback receives **three** array parameters: `modified`, `added` and `removed`, in that order. +Each of these three is always an array with 0 or more entries. +Each array entry is an absolute path. + +### Pause / start / stop + +Listeners can also be easily paused and later un-paused with start: + +``` ruby +listener = Listen.to('dir/path/to/listen') { |modified, added, removed| puts 'handle changes here...' } + +listener.start +listener.paused? # => false +listener.processing? # => true + +listener.pause # stops processing changes (but keeps on collecting them) +listener.paused? # => true +listener.processing? # => false + +listener.start # resumes processing changes +listener.stop # stop both listening to changes and processing them +``` + + Note: While paused, `listen` keeps on collecting changes in the background - to clear them, call `stop`. + + Note: You should keep track of all started listeners and `stop` them properly on finish. + +### Ignore / ignore! + +`Listen` ignores some directories and extensions by default (See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer). +You can add ignoring patterns with the `ignore` option/method or overwrite default with `ignore!` option/method. + +``` ruby +listener = Listen.to('dir/path/to/listen', ignore: /\.txt/) { |modified, added, removed| # ... } +listener.start +listener.ignore! /\.pkg/ # overwrite all patterns and only ignore pkg extension. +listener.ignore /\.rb/ # ignore rb extension in addition of pkg. +sleep +``` + +Note: `:ignore` regexp patterns are evaluated against relative paths. + +Note: Ignoring paths does not improve performance, except when Polling ([#274](https://github.com/guard/listen/issues/274)). + +### Only + +`Listen` watches all files (less the ignored ones) by default. If you want to only listen to a specific type of file (i.e., just `.rb` extension), you should use the `only` option/method. + +``` ruby +listener = Listen.to('dir/path/to/listen', only: /\.rb$/) { |modified, added, removed| # ... } +listener.start +listener.only /_spec\.rb$/ # overwrite all existing only patterns. +sleep +``` + +Note: `:only` regexp patterns are evaluated only against relative **file** paths. + + +## Options + +All the following options can be set through the `Listen.to` after the directory path(s) params. + +``` ruby +ignore: [%r{/foo/bar}, /\.pid$/, /\.coffee$/] # Ignore a list of paths + # default: See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer + +ignore!: %r{/foo/bar} # Same as ignore options, but overwrite default ignored paths. + +only: %r{.rb$} # Only listen to specific files + # default: none + +latency: 0.5 # Set the delay (**in seconds**) between checking for changes + # default: 0.25 sec (1.0 sec for polling) + +wait_for_delay: 4 # Set the delay (**in seconds**) between calls to the callback when changes exist + # default: 0.10 sec + +force_polling: true # Force the use of the polling adapter + # default: none + +relative: false # Whether changes should be relative to current dir or not + # default: false + +polling_fallback_message: 'custom message' # Set a custom polling fallback message (or disable it with false) + # default: "Listen will be polling for changes. Learn more at https://github.com/guard/listen#listen-adapters." +``` + +## Logging and Debugging + +`Listen` logs its activity to `Listen.logger`. +This is the primary method of debugging. + +### Custom Logger +You can call `Listen.logger =` to set a custom `listen` logger for the process. For example: +``` ruby +Listen.logger = Rails.logger +``` + +### Default Logger +If no custom logger is set, a default `listen` logger which logs to to `STDERR` will be created and assigned to `Listen.logger`. + +The default logger defaults to the `error` logging level (severity). +You can override the logging level by setting the environment variable `LISTEN_GEM_DEBUGGING=`. +For ``, all standard `::Logger` levels are supported, with any mix of upper-/lower-case: +``` ruby +export LISTEN_GEM_DEBUGGING=debug # or 2 [deprecated] +export LISTEN_GEM_DEBUGGING=info # or 1 or true or yes [deprecated] +export LISTEN_GEM_DEBUGGING=warn +export LISTEN_GEM_DEBUGGING=fatal +export LISTEN_GEM_DEBUGGING=error +``` +The default of `error` will be used if an unsupported value is set. + +Note: The alternate values `1`, `2`, `true` and `yes` shown above are deprecated and will be removed from `listen` v4.0. + +### Disabling Logging +If you want to disable `listen` logging, set +``` ruby +Listen.logger = ::Logger.new('/dev/null') +``` + +### Adapter Warnings +If listen is having trouble with the underlying adapter, it will display warnings with `Kernel#warn` by default, +which in turn writes to STDERR. +Sometimes this is not desirable, for example in an environment where STDERR is ignored. +For these reasons, the behavior can be configured using `Listen.adapter_warn_behavior =`: +``` ruby +Listen.adapter_warn_behavior = :warn # default (true means the same) +Listen.adapter_warn_behavior = :log # send to logger.warn +Listen.adapter_warn_behavior = :silent # suppress all adapter warnings (nil or false mean the same) +``` +Also there are some cases where specific warnings are not helpful. +For example, if you are using the polling adapter--and expect to--you can suppress the warning about it +by providing a callable object like a lambda or proc that determines the behavior based on the `message`: +``` ruby +Listen.adapter_warn_behavior = ->(message) do + case message + when /Listen will be polling for changes/ + :silent + when /directory is already being watched/ + :log + else + :warn + end +end +``` +In cases where the `Listen` gem is embedded inside another service--such as `guard`--the above configuration +can be set in the environment variable `LISTEN_GEM_ADAPTER_WARN_BEHAVIOR=warn|log|silent`. + +## Listen Adapters + +The `Listen` gem has a set of adapters to notify it when there are changes. + +There are 4 OS-specific adapters to support Darwin, Linux, \*BSD and Windows. +These adapters are fast as they use some system-calls to implement the notifying function. + +There is also a polling adapter - although it's much slower than other adapters, +it works on every platform/system and scenario (including network filesystems such as VM shared folders). + +The Darwin and Linux adapters are dependencies of the `listen` gem so they work out of the box. For other adapters a specific gem will have to be added to your Gemfile, please read below. + +The `listen` gem will choose the best adapter automatically, if present. If you +want to force the use of the polling adapter, use the `:force_polling` option +while initializing the listener. + +### On Windows + +If you are on Windows, it's recommended to use the [`wdm`](https://github.com/Maher4Ever/wdm) adapter instead of polling. + +Please add the following to your Gemfile: + +```ruby +gem 'wdm', '>= 0.1.0' +``` + +### On \*BSD + +If you are on \*BSD you can try to use the [`rb-kqueue`](https://github.com/mat813/rb-kqueue) adapter instead of polling. + +Please add the following to your Gemfile: + +```ruby +gem 'rb-kqueue', '>= 0.2' +``` + +### Getting the [polling fallback message](#options)? + +If you see: +``` +Listen will be polling for changes. +``` + +This means the Listen gem can’t find an optimized adapter. Typically this is caused by: + +- You’re on Windows and WDM gem isn’t installed. +- You’re running the app without Bundler or RubyGems. +- Using Sass which includes an ancient (the “dinosaur” type of ancient) version of the Listen gem. + +Possible solutions: + +1. Suppress the message by using the :force_polling option. Or, you could just ignore the message since it’s harmless. +2. Windows users: Install the WDM gem. +3. Upgrade Ruby (use RubyInstaller for Windows or RVM/rbenv for Mac) and RubyGems. +3. Run your apps using Bundler. +4. Sass users: Install the latest version of Listen and try again. + +#### Simplified Bundler and Sass example +Create a Gemfile with these lines: +``` +source 'https://rubygems.org' +gem 'listen' +gem 'sass' +``` +Next, use Bundler to update gems: +``` +$ bundle update +$ bundle exec sass --watch # ... or whatever app is using Listen. +``` + +### Increasing the amount of inotify watchers + +If you are running Debian, RedHat, or another similar Linux distribution, run the following in a terminal: +``` +$ sudo sh -c "echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf" +$ sudo sysctl -p +``` +If you are running ArchLinux, search the `/etc/sysctl.d/` directory for config files with the setting: +``` +$ grep -H -s "fs.inotify.max_user_watches" /etc/sysctl.d/* +/etc/sysctl.d/40-max_user_watches.conf:fs.inotify.max_user_watches=100000 +``` +Then change the setting in the file you found above to a higher value (see [here](https://www.archlinux.org/news/deprecation-of-etcsysctlconf/) for why): +``` +$ sudo sh -c "echo fs.inotify.max_user_watches=524288 > /etc/sysctl.d/40-max-user-watches.conf" +$ sudo sysctl --system +``` + +#### The technical details +Listen uses `inotify` by default on Linux to monitor directories for changes. +It's not uncommon to encounter a system limit on the number of files you can monitor. +For example, Ubuntu Lucid's (64bit) `inotify` limit is set to 8192. + +You can get your current inotify file watch limit by executing: +``` +$ cat /proc/sys/fs/inotify/max_user_watches +``` +When this limit is not enough to monitor all files inside a directory, the limit must be increased for Listen to work properly. + +You can set a new limit temporarily with: +``` +$ sudo sysctl fs.inotify.max_user_watches=524288 +$ sudo sysctl -p +``` +If you like to make your limit permanent, use: +``` +$ sudo sh -c "echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf" +$ sudo sysctl -p +``` +You may also need to pay attention to the values of `max_queued_events` and `max_user_instances` if Listen keeps on complaining. + +While 524,288 is the maximum number of files that can be watched. Each file watch [takes up 1,080 bytes](https://stackoverflow.com/a/7091897/1156119) on a 64-bit system, so assuming that all 524,288 watches are consumed, that allocates around 540 MiB. +If you're in an environment that is particularly memory-constrained, consider to specify a lower number. + +#### More info +Man page for [inotify(7)](https://linux.die.net/man/7/inotify). +Blog post: [limit of inotify](https://blog.sorah.jp/2012/01/24/inotify-limitation). + +### Issues and Troubleshooting + +If the gem doesn't work as expected, start by setting `LISTEN_GEM_DEBUGGING=debug` or `LISTEN_GEM_DEBUGGING=info` as described above in [Logging and Debugging](#logging-and-debugging). + +*NOTE: without providing the output after setting the `LISTEN_GEM_DEBUGGING=debug` environment variable, it is usually impossible to guess why `listen` is not working as expected.* + +#### 3 steps before you start diagnosing problems +These 3 steps will: + +- help quickly troubleshoot obscure problems (trust me, most of them are obscure) +- help quickly identify the area of the problem (a full list is below) +- help you get familiar with listen's diagnostic mode (it really comes in handy, trust me) +- help you create relevant output before you submit an issue (so we can respond with answers instead of tons of questions) + +Step 1 - The most important option in Listen +For effective troubleshooting set the `LISTEN_GEM_DEBUGGING=info` variable before starting `listen`. + +Step 2 - Verify polling works +Polling has to work ... or something is really wrong (and we need to know that before anything else). + +(see force_polling option). + +After starting `listen`, you should see something like: +``` +INFO -- : Record.build(): 0.06773114204406738 seconds +``` +Step 3 - Trigger some changes directly without using editors or apps +Make changes e.g. touch foo or echo "a" >> foo (for troubleshooting, avoid using an editor which could generate too many misleading events). + +You should see something like: +``` +INFO -- : listen: raw changes: [[:added, "/home/me/foo"]] +INFO -- : listen: final changes: {:modified=>[], :added=>["/home/me/foo"], :removed=>[]} +``` +"raw changes" contains changes collected during the :wait_for_delay and :latency intervals, while "final changes" is what listen decided are relevant changes (for better editor support). + +## Performance + +If `listen` seems slow or unresponsive, make sure you're not using the Polling adapter (you should see a warning upon startup if you are). + +Also, if the directories you're watching contain many files, make sure you're: + +* not using Polling (ideally) +* using `:ignore` and `:only` options to avoid tracking directories you don't care about (important with Polling and on MacOS) +* running `listen` with the `:latency` and `:wait_for_delay` options not too small or too big (depends on needs) +* not watching directories with log files, database files or other frequently changing files +* not using a version of `listen` prior to 2.7.7 +* not getting silent crashes within `listen` (see `LISTEN_GEM_DEBUGGING=debug`) +* not running multiple instances of `listen` in the background +* using a file system with atime modification disabled (ideally) +* not using a filesystem with inaccurate file modification times (ideally), e.g. HFS, VFAT +* not buffering to a slow terminal (e.g. transparency + fancy font + slow gfx card + lots of output) +* ideally not running a slow encryption stack, e.g. btrfs + ecryptfs + +When in doubt, `LISTEN_GEM_DEBUGGING=debug` can help discover the actual events and time they happened. + +## Tips and Techniques +- Watch only directories you're interested in. +- Set your editor to save quickly (e.g. without backup files, without atomic-save) +- Tweak the `:latency` and `:wait_for_delay` options until you get good results (see [options](#options)). +- Add `:ignore` rules to silence all events you don't care about (reduces a lot of noise, especially if you use it on directories) + +## Development + +* Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames). +* Source hosted at [GitHub](https://github.com/guard/listen). + +Pull requests are very welcome! Please try to follow these simple rules if applicable: + +* Please create a topic branch for every separate change you make. +* Make sure your patches are well tested. All specs must pass on [CI](https://github.com/guard/listen/actions?workflow=Development). +* Update the [Yard](http://yardoc.org/) documentation. +* Update the [README](https://github.com/guard/listen/blob/master/README.md). +* Please **do not change** the version number. + +For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on +`#guard` (irc.freenode.net). + +## Releasing + +### Prerequisites + +* You must have commit rights to the GitHub repository. +* You must have push rights for rubygems.org. + +### How to release + +1. Run `bundle install` to make sure that you have all the gems necessary for testing and releasing. +2. **Ensure all tests are passing by running `bundle exec rake`.** +3. Determine which would be the correct next version number according to [semver](http://semver.org/). +4. Update the version in `./lib/listen/version.rb`. +5. Update the version in the Install section of `./README.md` (`gem 'listen', '~> X.Y'`). +6. Commit the version in a single commit, the message should be "Preparing vX.Y.Z" +7. Run `bundle exec rake release:full`; this will tag, push to GitHub, and publish to rubygems.org. +8. Update and publish the release notes on the [GitHub releases page](https://github.com/guard/listen/releases) if necessary + +## Acknowledgments + +* [Michael Kessler (netzpirat)][] for having written the [initial specs](https://github.com/guard/listen/commit/1e457b13b1bb8a25d2240428ce5ed488bafbed1f). +* [Travis Tilley (ttilley)][] for this awesome work on [fssm][] & [rb-fsevent][]. +* [Natalie Weizenbaum (nex3)][] for [rb-inotify][], a thorough inotify wrapper. +* [Mathieu Arnold (mat813)][] for [rb-kqueue][], a simple kqueue wrapper. +* [Maher Sallam][] for [wdm][], windows support wouldn't exist without him. +* [Yehuda Katz (wycats)][] for [vigilo][], that has been a great source of inspiration. + +## Author + +[Thibaud Guillaume-Gentil](https://github.com/thibaudgg) ([@thibaudgg](https://twitter.com/thibaudgg)) + +## Contributors + +[https://github.com/guard/listen/graphs/contributors](https://github.com/guard/listen/graphs/contributors) + +[Thibaud Guillaume-Gentil (thibaudgg)]: https://github.com/thibaudgg +[Maher Sallam]: https://github.com/Maher4Ever +[Michael Kessler (netzpirat)]: https://github.com/netzpirat +[Travis Tilley (ttilley)]: https://github.com/ttilley +[fssm]: https://github.com/ttilley/fssm +[rb-fsevent]: https://github.com/thibaudgg/rb-fsevent +[Mathieu Arnold (mat813)]: https://github.com/mat813 +[Natalie Weizenbaum (nex3)]: https://github.com/nex3 +[rb-inotify]: https://github.com/nex3/rb-inotify +[stereobooster]: https://github.com/stereobooster +[rb-fchange]: https://github.com/stereobooster/rb-fchange +[rb-kqueue]: https://github.com/mat813/rb-kqueue +[Yehuda Katz (wycats)]: https://github.com/wycats +[vigilo]: https://github.com/wycats/vigilo +[wdm]: https://github.com/Maher4Ever/wdm diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/bin/listen b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/bin/listen new file mode 100755 index 0000000..59ade96 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/bin/listen @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'listen' +require 'listen/cli' + +if !defined?(JRUBY_VERSION) && Signal.list.keys.include?('INT') + Signal.trap('INT') { Thread.new { Listen.stop } } +end + +Listen::CLI.start diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen.rb new file mode 100644 index 0000000..03857fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'logger' +require 'weakref' +require 'listen/logger' +require 'listen/listener' + +# Won't print anything by default because of level - unless you've set +# LISTEN_GEM_DEBUGGING or provided your own logger with a high enough level +Listen.logger.info "Listen loglevel set to: #{Listen.logger.level}" +Listen.logger.info "Listen version: #{Listen::VERSION}" + +module Listen + @listeners = Queue.new + + class << self + # Listens to file system modifications on a either single directory or + # multiple directories. + # + # @param (see Listen::Listener#new) + # + # @yield [modified, added, removed] the changed files + # @yieldparam [Array] modified the list of modified files + # @yieldparam [Array] added the list of added files + # @yieldparam [Array] removed the list of removed files + # + # @return [Listen::Listener] the listener + # + def to(*args, &block) + Listener.new(*args, &block).tap do |listener| + @listeners.enq(WeakRef.new(listener)) + end + end + + # This is used by the `listen` binary to handle Ctrl-C + # + def stop + while (listener = @listeners.deq(true)) + begin + listener.stop + rescue WeakRef::RefError + end + end + rescue ThreadError + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter.rb new file mode 100644 index 0000000..dce8623 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'listen/adapter/base' +require 'listen/adapter/bsd' +require 'listen/adapter/darwin' +require 'listen/adapter/linux' +require 'listen/adapter/polling' +require 'listen/adapter/windows' + +module Listen + module Adapter + OPTIMIZED_ADAPTERS = [Darwin, Linux, BSD, Windows].freeze + POLLING_FALLBACK_MESSAGE = 'Listen will be polling for changes.'\ + 'Learn more at https://github.com/guard/listen#listen-adapters.' + + class << self + def select(options = {}) + Listen.logger.debug 'Adapter: considering polling ...' + return Polling if options[:force_polling] + Listen.logger.debug 'Adapter: considering optimized backend...' + return _usable_adapter_class if _usable_adapter_class + Listen.logger.debug 'Adapter: falling back to polling...' + _warn_polling_fallback(options) + Polling + rescue + Listen.logger.warn format('Adapter: failed: %s:%s', $ERROR_POSITION.inspect, + $ERROR_POSITION * "\n") + raise + end + + private + + def _usable_adapter_class + OPTIMIZED_ADAPTERS.find(&:usable?) + end + + def _warn_polling_fallback(options) + msg = options.fetch(:polling_fallback_message, POLLING_FALLBACK_MESSAGE) + Listen.adapter_warn("[Listen warning]:\n #{msg}") if msg + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/base.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/base.rb new file mode 100644 index 0000000..b7e1039 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/base.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +require 'listen/options' +require 'listen/record' +require 'listen/change' +require 'listen/thread' + +module Listen + module Adapter + class Base + attr_reader :options, :config + + # TODO: only used by tests + DEFAULTS = {}.freeze + + def initialize(config) + @started = false + @config = config + + @configured = nil + + fail 'No directories to watch!' if config.directories.empty? + + defaults = self.class.const_get('DEFAULTS') + @options = Listen::Options.new(config.adapter_options, defaults) + rescue + _log_exception 'adapter config failed: %s:%s called from: %s', caller + raise + end + + # TODO: it's a separate method as a temporary workaround for tests + # rubocop:disable Metrics/MethodLength + def configure + if @configured + Listen.logger.warn('Adapter already configured!') + return + end + + @configured = true + + @callbacks ||= {} + config.directories.each do |dir| + callback = @callbacks[dir] || lambda do |event| + _process_event(dir, event) + end + @callbacks[dir] = callback + _configure(dir, &callback) + end + + @snapshots ||= {} + # TODO: separate config per directory (some day maybe) + change_config = Change::Config.new(config.queue, config.silencer) + config.directories.each do |dir| + record = Record.new(dir, config.silencer) + snapshot = Change.new(change_config, record) + @snapshots[dir] = snapshot + end + end + # rubocop:enable Metrics/MethodLength + + def started? + @started + end + + def start + configure + + if started? + Listen.logger.warn('Adapter already started!') + return + end + + @started = true + + @run_thread = Listen::Thread.new("run_thread") do + @snapshots.each_value do |snapshot| + _timed('Record.build()') { snapshot.record.build } + end + _run + end + end + + def stop + _stop + config.queue.close # this causes queue.pop to return `nil` to the front-end + end + + private + + def _stop + @run_thread&.kill + @run_thread = nil + end + + def _timed(title) + start = MonotonicTime.now + yield + diff = MonotonicTime.now - start + Listen.logger.info format('%s: %.05f seconds', title, diff) + rescue + Listen.logger.warn "#{title} crashed: #{$ERROR_INFO.inspect}" + raise + end + + # TODO: allow backend adapters to pass specific invalidation objects + # e.g. Darwin -> DirRescan, INotify -> MoveScan, etc. + def _queue_change(type, dir, rel_path, options) + @snapshots[dir].invalidate(type, rel_path, options) + end + + def _log_exception(msg, caller_stack) + formatted = format( + msg, + $ERROR_INFO, + $ERROR_POSITION * "\n", + caller_stack * "\n" + ) + + Listen.logger.error(formatted) + end + + class << self + def usable? + const_get('OS_REGEXP') =~ RbConfig::CONFIG['target_os'] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/bsd.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/bsd.rb new file mode 100644 index 0000000..186ded3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/bsd.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +# Listener implementation for BSD's `kqueue`. +# @see http://www.freebsd.org/cgi/man.cgi?query=kqueue +# @see https://github.com/mat813/rb-kqueue/blob/master/lib/rb-kqueue/queue.rb +# +module Listen + module Adapter + class BSD < Base + OS_REGEXP = /bsd|dragonfly/i + + DEFAULTS = { + events: [ + :delete, + :write, + :extend, + :attrib, + :rename + # :link, :revoke + ] + }.freeze + + BUNDLER_DECLARE_GEM = <<-EOS.gsub(/^ {6}/, '') + Please add the following to your Gemfile to avoid polling for changes: + gem 'rb-kqueue', '>= 0.2' + EOS + + def self.usable? + return false unless super + require 'rb-kqueue' + require 'find' + true + rescue LoadError + Listen.adapter_warn(BUNDLER_DECLARE_GEM) + false + end + + private + + def _configure(directory, &callback) + @worker ||= KQueue::Queue.new + @callback = callback + # use Record to make a snapshot of dir, so we + # can detect new files + _find(directory.to_s) { |path| _watch_file(path, @worker) } + end + + def _run + @worker.run + end + + def _process_event(dir, event) + full_path = _event_path(event) + if full_path.directory? + # Force dir content tracking to kick in, or we won't have + # names of added files + _queue_change(:dir, dir, '.', recursive: true) + elsif full_path.exist? + path = full_path.relative_path_from(dir) + _queue_change(:file, dir, path.to_s, change: _change(event.flags)) + end + + # If it is a directory, and it has a write flag, it means a + # file has been added so find out which and deal with it. + # No need to check for removed files, kqueue will forget them + # when the vfs does. + _watch_for_new_file(event) if full_path.directory? + end + + def _change(event_flags) + { modified: [:attrib, :extend], + added: [:write], + removed: [:rename, :delete] }.each do |change, flags| + return change unless (flags & event_flags).empty? + end + nil + end + + def _event_path(event) + Pathname.new(event.watcher.path) + end + + def _watch_for_new_file(event) + queue = event.watcher.queue + _find(_event_path(event).to_s) do |file_path| + unless queue.watchers.find { |_, v| v.path == file_path.to_s } + _watch_file(file_path, queue) + end + end + end + + def _watch_file(path, queue) + queue.watch_file(path, *options.events, &@callback) + rescue Errno::ENOENT => e + Listen.logger.warn "kqueue: watch file failed: #{e.message}" + end + + # Quick rubocop workaround + def _find(*paths, &block) + Find.send(:find, *paths, &block) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/config.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/config.rb new file mode 100644 index 0000000..5a068a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/config.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'pathname' + +module Listen + module Adapter + class Config + attr_reader :directories, :silencer, :queue, :adapter_options + + def initialize(directories, queue, silencer, adapter_options) + # Default to current directory if no directories are supplied + directories = [Dir.pwd] if directories.to_a.empty? + + # TODO: fix (flatten, array, compact?) + @directories = directories.map do |directory| + Pathname.new(directory.to_s).realpath + end + + @directories.each do |pathname| + unless pathname.directory? + fail ArgumentError, "must be a directory: #{pathname}" + end + end + + @silencer = silencer + @queue = queue + @adapter_options = adapter_options + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/darwin.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/darwin.rb new file mode 100644 index 0000000..07c7a56 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/darwin.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'listen/thread' + +module Listen + module Adapter + # Adapter implementation for Mac OS X `FSEvents`. + # + class Darwin < Base + OS_REGEXP = /darwin(?(1|2)\d+)/i + + # The default delay between checking for changes. + DEFAULTS = { latency: 0.1 }.freeze + + INCOMPATIBLE_GEM_VERSION = <<-EOS.gsub(/^ {8}/, '') + rb-fsevent > 0.9.4 no longer supports OS X 10.6 through 10.8. + + Please add the following to your Gemfile to avoid polling for changes: + require 'rbconfig' + if RbConfig::CONFIG['target_os'] =~ /darwin(1[0-3])/i + gem 'rb-fsevent', '<= 0.9.4' + end + EOS + + def self.usable? + version = RbConfig::CONFIG['target_os'][OS_REGEXP, :major_version] + return false unless version + return true if version.to_i >= 13 # darwin13 is OS X 10.9 + + require 'rb-fsevent' + fsevent_version = Gem::Version.new(FSEvent::VERSION) + return true if fsevent_version <= Gem::Version.new('0.9.4') + Listen.adapter_warn(INCOMPATIBLE_GEM_VERSION) + false + end + + private + + def _configure(dir, &callback) + @callbacks[dir] = callback + end + + def _run + require 'rb-fsevent' + worker = FSEvent.new + dirs_to_watch = @callbacks.keys.map(&:to_s) + Listen.logger.info { "fsevent: watching: #{dirs_to_watch.inspect}" } + worker.watch(dirs_to_watch, { latency: options.latency }, &method(:_process_changes)) + @worker_thread = Listen::Thread.new("worker_thread") { worker.run } + end + + def _process_changes(dirs) + dirs.each do |dir| + dir = Pathname.new(dir.sub(%r{/$}, '')) + + @callbacks.each do |watched_dir, callback| + if watched_dir.eql?(dir) || Listen::Directory.ascendant_of?(watched_dir, dir) + callback.call(dir) + end + end + end + end + + def _process_event(dir, path) + Listen.logger.debug { "fsevent: processing path: #{path.inspect}" } + # TODO: does this preserve symlinks? + rel_path = path.relative_path_from(dir).to_s + _queue_change(:dir, dir, rel_path, recursive: true) + end + + def _stop + @worker_thread&.kill + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/linux.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/linux.rb new file mode 100644 index 0000000..5b78ee3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/linux.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +module Listen + module Adapter + # @see https://github.com/nex3/rb-inotify + class Linux < Base + OS_REGEXP = /linux/i + + DEFAULTS = { + events: [ + :recursive, + :attrib, + :create, + :modify, + :delete, + :move, + :close_write + ], + wait_for_delay: 0.1 + }.freeze + + private + + README_URL = 'https://github.com/guard/listen'\ + '/blob/master/README.md#increasing-the-amount-of-inotify-watchers' + + def _configure(directory, &callback) + require 'rb-inotify' + @worker ||= ::INotify::Notifier.new + @worker.watch(directory.to_s, *options.events, &callback) + rescue Errno::ENOSPC + raise ::Listen::Error::INotifyMaxWatchesExceeded, <<~EOS + Unable to monitor directories for changes because iNotify max watches exceeded. See #{README_URL} . + EOS + end + + def _run + @worker.run + end + + # rubocop:disable Metrics/MethodLength + def _process_event(dir, event) + # NOTE: avoid using event.absolute_name since new API + # will need to have a custom recursion implemented + # to properly match events to configured directories + path = Pathname.new(event.watcher.path) + event.name + rel_path = path.relative_path_from(dir).to_s + + Listen.logger.debug { "inotify: #{rel_path} (#{event.flags.inspect})" } + + if /1|true/ =~ ENV['LISTEN_GEM_SIMULATE_FSEVENT'] + if (event.flags & [:moved_to, :moved_from]) || _dir_event?(event) + rel_path = path.dirname.relative_path_from(dir).to_s + end + _queue_change(:dir, dir, rel_path, {}) + return + end + + return if _skip_event?(event) + + cookie_params = event.cookie.zero? ? {} : { cookie: event.cookie } + + # NOTE: don't pass options to force rescanning the directory, so we can + # detect moving/deleting a whole tree + if _dir_event?(event) + _queue_change(:dir, dir, rel_path, cookie_params) + return + end + + params = cookie_params.merge(change: _change(event.flags)) + + _queue_change(:file, dir, rel_path, params) + end + # rubocop:enable Metrics/MethodLength + + def _skip_event?(event) + # Event on root directory + return true if event.name == '' + # INotify reports changes to files inside directories as events + # on the directories themselves too. + # + # @see http://linux.die.net/man/7/inotify + _dir_event?(event) && (event.flags & [:close, :modify]).any? + end + + def _change(event_flags) + { modified: [:attrib, :close_write], + moved_to: [:moved_to], + moved_from: [:moved_from], + added: [:create], + removed: [:delete] }.each do |change, flags| + return change unless (flags & event_flags).empty? + end + nil + end + + def _dir_event?(event) + event.flags.include?(:isdir) + end + + def _stop + @worker&.close + + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/polling.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/polling.rb new file mode 100644 index 0000000..57cda9c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/polling.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Listen + module Adapter + # Polling Adapter that works cross-platform and + # has no dependencies. This is the adapter that + # uses the most CPU processing power and has higher + # file IO than the other implementations. + # + class Polling < Base + OS_REGEXP = // # match every OS + + DEFAULTS = { latency: 1.0, wait_for_delay: 0.05 }.freeze + + private + + def _configure(_, &callback) + @polling_callbacks ||= [] + @polling_callbacks << callback + end + + def _run + loop do + start = MonotonicTime.now + @polling_callbacks.each do |callback| + callback.call(nil) + if (nap_time = options.latency - (MonotonicTime.now - start)) > 0 + # TODO: warn if nap_time is negative (polling too slow) + sleep(nap_time) + end + end + end + end + + def _process_event(dir, _) + _queue_change(:dir, dir, '.', recursive: true) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/windows.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/windows.rb new file mode 100644 index 0000000..799d458 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/adapter/windows.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +module Listen + module Adapter + # Adapter implementation for Windows `wdm`. + # + class Windows < Base + OS_REGEXP = /mswin|mingw|cygwin/i + + BUNDLER_DECLARE_GEM = <<-EOS.gsub(/^ {6}/, '') + Please add the following to your Gemfile to avoid polling for changes: + gem 'wdm', '>= 0.1.0' + EOS + + def self.usable? + return false unless super + require 'wdm' + true + rescue LoadError + Listen.logger.debug format('wdm - load failed: %s:%s', $ERROR_INFO, + $ERROR_POSITION * "\n") + + Listen.adapter_warn(BUNDLER_DECLARE_GEM) + false + end + + private + + def _configure(dir) + require 'wdm' + Listen.logger.debug 'wdm - starting...' + @worker ||= WDM::Monitor.new + @worker.watch_recursively(dir.to_s, :files) do |change| + yield([:file, change]) + end + + @worker.watch_recursively(dir.to_s, :directories) do |change| + yield([:dir, change]) + end + + @worker.watch_recursively(dir.to_s, :attributes, :last_write) do |change| + yield([:attr, change]) + end + end + + def _run + @worker.run! + end + + # rubocop:disable Metrics/MethodLength + def _process_event(dir, event) + Listen.logger.debug "wdm - callback: #{event.inspect}" + + type, change = event + + full_path = Pathname(change.path) + + rel_path = full_path.relative_path_from(dir).to_s + + options = { change: _change(change.type) } + + case type + when :file + _queue_change(:file, dir, rel_path, options) + when :attr + unless full_path.directory? + _queue_change(:file, dir, rel_path, options) + end + when :dir + case change.type + when :removed + # TODO: check if watched dir? + _queue_change(:dir, dir, Pathname(rel_path).dirname.to_s, {}) + when :added + _queue_change(:dir, dir, rel_path, {}) + # do nothing - changed directory means either: + # - removed subdirs (handled above) + # - added subdirs (handled above) + # - removed files (handled by _file_callback) + # - added files (handled by _file_callback) + # so what's left? + end + end + end + # rubocop:enable Metrics/MethodLength + + def _change(type) + { modified: [:modified, :attrib], # TODO: is attrib really passed? + added: [:added, :renamed_new_file], + removed: [:removed, :renamed_old_file] }.find do |change, types| + types.include?(type) and break change + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/backend.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/backend.rb new file mode 100644 index 0000000..cab286c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/backend.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'listen/adapter' +require 'listen/adapter/base' +require 'listen/adapter/config' + +require 'forwardable' + +# This class just aggregates configuration object to avoid Listener specs +# from exploding with huge test setup blocks +module Listen + class Backend + extend Forwardable + + def initialize(directories, queue, silencer, config) + adapter_select_opts = config.adapter_select_options + + adapter_class = Adapter.select(adapter_select_opts) + + # Use default from adapter if possible + @min_delay_between_events = config.min_delay_between_events + @min_delay_between_events ||= adapter_class::DEFAULTS[:wait_for_delay] + @min_delay_between_events ||= 0.1 + + adapter_opts = config.adapter_instance_options(adapter_class) + + aconfig = Adapter::Config.new(directories, queue, silencer, adapter_opts) + @adapter = adapter_class.new(aconfig) + end + + delegate start: :adapter + delegate stop: :adapter + + attr_reader :min_delay_between_events + + private + + attr_reader :adapter + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/change.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/change.rb new file mode 100644 index 0000000..c19b900 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/change.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'listen/file' +require 'listen/directory' + +module Listen + # TODO: rename to Snapshot + class Change + # TODO: test this class for coverage + class Config + def initialize(queue, silencer) + @queue = queue + @silencer = silencer + end + + def silenced?(path, type) + @silencer.silenced?(Pathname(path), type) + end + + def queue(*args) + @queue << args + end + end + + attr_reader :record + + def initialize(config, record) + @config = config + @record = record + end + + # Invalidate some part of the snapshot/record (dir, file, subtree, etc.) + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity + def invalidate(type, rel_path, options) + watched_dir = Pathname.new(record.root) + + change = options[:change] + cookie = options[:cookie] + + if !cookie && @config.silenced?(rel_path, type) + Listen.logger.debug { "(silenced): #{rel_path.inspect}" } + return + end + + path = watched_dir + rel_path + + Listen.logger.debug do + log_details = options[:silence] && 'recording' || change || 'unknown' + "#{log_details}: #{type}:#{path} (#{options.inspect})" + end + + if change + options = cookie ? { cookie: cookie } : {} + @config.queue(type, change, watched_dir, rel_path, options) + elsif type == :dir + # NOTE: POSSIBLE RECURSION + # TODO: fix - use a queue instead + Directory.scan(self, rel_path, options) + elsif (change = File.change(record, rel_path)) && !options[:silence] + @config.queue(:file, change, watched_dir, rel_path) + end + end + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/cli.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/cli.rb new file mode 100644 index 0000000..e317313 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/cli.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require 'thor' +require 'listen' +require 'logger' + +module Listen + class CLI < Thor + default_task :start + + desc 'start', 'Starts Listen' + + class_option :verbose, + type: :boolean, + default: false, + aliases: '-v', + banner: 'Verbose' + + class_option :directory, + type: :array, + default: ['.'], + aliases: '-d', + banner: 'One or more directories to listen to' + + class_option :relative, + type: :boolean, + default: false, + aliases: '-r', + banner: 'Convert paths relative to current directory' + + def start + Listen::Forwarder.new(options).start + end + end + + class Forwarder + attr_reader :logger + + def initialize(options) + @options = options + @logger = ::Logger.new(STDOUT, level: ::Logger::INFO) + @logger.formatter = proc { |_, _, _, msg| "#{msg}\n" } + end + + def start + logger.info 'Starting listen...' + + directory = @options[:directory] + relative = @options[:relative] + callback = proc do |modified, added, removed| + if @options[:verbose] + logger.info "+ #{added}" unless added.empty? + logger.info "- #{removed}" unless removed.empty? + logger.info "> #{modified}" unless modified.empty? + end + end + + listener = Listen.to(*directory, relative: relative, &callback) + + listener.start + + sleep 0.5 while listener.processing? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/directory.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/directory.rb new file mode 100644 index 0000000..19178b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/directory.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require 'set' + +module Listen + # TODO: refactor (turn it into a normal object, cache the stat, etc) + class Directory + # rubocop:disable Metrics/MethodLength + def self.scan(snapshot, rel_path, options) + record = snapshot.record + dir = Pathname.new(record.root) + previous = record.dir_entries(rel_path) + + record.add_dir(rel_path) + + # TODO: use children(with_directory: false) + path = dir + rel_path + current = Set.new(_children(path)) + + Listen.logger.debug do + format('%s: %s(%s): %s -> %s', + (options[:silence] ? 'Recording' : 'Scanning'), + rel_path, options.inspect, previous.inspect, current.inspect) + end + + begin + current.each do |full_path| + type = ::File.lstat(full_path.to_s).directory? ? :dir : :file + item_rel_path = full_path.relative_path_from(dir).to_s + _change(snapshot, type, item_rel_path, options) + end + rescue Errno::ENOENT + # The directory changed meanwhile, so rescan it + current = Set.new(_children(path)) + retry + end + + # TODO: this is not tested properly + previous = previous.reject { |entry, _| current.include?(path + entry) } + + _async_changes(snapshot, Pathname.new(rel_path), previous, options) + rescue Errno::ENOENT, Errno::EHOSTDOWN + record.unset_path(rel_path) + _async_changes(snapshot, Pathname.new(rel_path), previous, options) + rescue Errno::ENOTDIR + # TODO: path not tested + record.unset_path(rel_path) + _async_changes(snapshot, path, previous, options) + _change(snapshot, :file, rel_path, options) + rescue + Listen.logger.warn { format('scan DIED: %s:%s', $ERROR_INFO, $ERROR_POSITION * "\n") } + raise + end + # rubocop:enable Metrics/MethodLength + + def self.ascendant_of?(base, other) + other.ascend do |ascendant| + break true if base == ascendant + end + end + + def self._async_changes(snapshot, path, previous, options) + fail "Not a Pathname: #{path.inspect}" unless path.respond_to?(:children) + previous.each do |entry, data| + # TODO: this is a hack with insufficient testing + type = data.key?(:mtime) ? :file : :dir + rel_path_s = (path + entry).to_s + _change(snapshot, type, rel_path_s, options) + end + end + + def self._change(snapshot, type, path, options) + return snapshot.invalidate(type, path, options) if type == :dir + + # Minor param cleanup for tests + # TODO: use a dedicated Event class + opts = options.dup + opts.delete(:recursive) + snapshot.invalidate(type, path, opts) + end + + def self._children(path) + return path.children unless RUBY_ENGINE == 'jruby' + + # JRuby inconsistency workaround, see: + # https://github.com/jruby/jruby/issues/3840 + exists = path.exist? + directory = path.directory? + exists && !directory and raise Errno::ENOTDIR, path.to_s + path.children + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/error.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/error.rb new file mode 100644 index 0000000..a5f2dc1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/error.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# Besides programming error exceptions like ArgumentError, +# all public interface exceptions should be declared here and inherit from Listen::Error. +module Listen + class Error < RuntimeError + class NotStarted < Error; end + class SymlinkLoop < Error; end + class INotifyMaxWatchesExceeded < Error; end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/config.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/config.rb new file mode 100644 index 0000000..058a8e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/config.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Listen + module Event + class Config + attr_reader :listener, :event_queue, :min_delay_between_events + + def initialize( + listener, + event_queue, + queue_optimizer, + wait_for_delay, + &block + ) + @listener = listener + @event_queue = event_queue + @queue_optimizer = queue_optimizer + @min_delay_between_events = wait_for_delay + @block = block + end + + def sleep(seconds) + Kernel.sleep(seconds) + end + + def call(*args) + @block&.call(*args) + end + + def callable? + @block + end + + def optimize_changes(changes) + @queue_optimizer.smoosh_changes(changes) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/loop.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/loop.rb new file mode 100644 index 0000000..9275673 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/loop.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +require 'timeout' +require 'listen/event/processor' +require 'listen/thread' +require 'listen/error' + +module Listen + module Event + class Loop + include Listen::FSM + + Error = ::Listen::Error + NotStarted = ::Listen::Error::NotStarted # for backward compatibility + + start_state :pre_start + state :pre_start + state :starting + state :started + state :stopped + + def initialize(config) + @config = config + @wait_thread = nil + @reasons = ::Queue.new + initialize_fsm + end + + def wakeup_on_event + if started? && @wait_thread&.alive? + _wakeup(:event) + end + end + + def started? + state == :started + end + + MAX_STARTUP_SECONDS = 5.0 + + # @raises Error::NotStarted if background thread hasn't started in MAX_STARTUP_SECONDS + def start + # TODO: use a Fiber instead? + return unless state == :pre_start + + transition! :starting + + @wait_thread = Listen::Thread.new("wait_thread") do + _process_changes + end + + Listen.logger.debug("Waiting for processing to start...") + + wait_for_state(:started, timeout: MAX_STARTUP_SECONDS) or + raise Error::NotStarted, "thread didn't start in #{MAX_STARTUP_SECONDS} seconds (in state: #{state.inspect})" + + Listen.logger.debug('Processing started.') + end + + def pause + # TODO: works? + # fail NotImplementedError + end + + def stop + transition! :stopped + + @wait_thread&.join + @wait_thread = nil + end + + def stopped? + state == :stopped + end + + private + + def _process_changes + processor = Event::Processor.new(@config, @reasons) + + transition! :started + + processor.loop_for(@config.min_delay_between_events) + end + + def _wakeup(reason) + @reasons << reason + @wait_thread.wakeup + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/processor.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/processor.rb new file mode 100644 index 0000000..63e207c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/processor.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +require 'listen/monotonic_time' + +module Listen + module Event + class Processor + def initialize(config, reasons) + @config = config + @listener = config.listener + @reasons = reasons + _reset_no_unprocessed_events + end + + # TODO: implement this properly instead of checking the state at arbitrary + # points in time + def loop_for(latency) + @latency = latency + + loop do + event = _wait_until_events + _check_stopped + _wait_until_events_calm_down + _wait_until_no_longer_paused + _process_changes(event) + end + rescue Stopped + Listen.logger.debug('Processing stopped') + end + + private + + class Stopped < RuntimeError + end + + def _wait_until_events_calm_down + loop do + now = MonotonicTime.now + + # Assure there's at least latency between callbacks to allow + # for accumulating changes + diff = _deadline - now + break if diff <= 0 + + # give events a bit of time to accumulate so they can be + # compressed/optimized + _sleep(diff) + end + end + + def _wait_until_no_longer_paused + @listener.wait_for_state(*(Listener.states.keys - [:paused])) + end + + def _check_stopped + if @listener.stopped? + _flush_wakeup_reasons + raise Stopped + end + end + + def _sleep(seconds) + _check_stopped + config.sleep(seconds) + _check_stopped + + _flush_wakeup_reasons do |reason| + if reason == :event && !@listener.paused? + _remember_time_of_first_unprocessed_event + end + end + end + + def _remember_time_of_first_unprocessed_event + @_remember_time_of_first_unprocessed_event ||= MonotonicTime.now + end + + def _reset_no_unprocessed_events + @_remember_time_of_first_unprocessed_event = nil + end + + def _deadline + @_remember_time_of_first_unprocessed_event + @latency + end + + # blocks until event is popped + # returns the event or `nil` when the event_queue is closed + # rubocop:disable Naming/MemoizedInstanceVariableName + def _wait_until_events + config.event_queue.pop.tap do |_event| + @_remember_time_of_first_unprocessed_event ||= MonotonicTime.now + end + end + # rubocop:enable Naming/MemoizedInstanceVariableName + + def _flush_wakeup_reasons + until @reasons.empty? + reason = @reasons.pop + yield reason if block_given? + end + end + + # for easier testing without sleep loop + def _process_changes(event) + _reset_no_unprocessed_events + + changes = [event] + changes << config.event_queue.pop until config.event_queue.empty? + + return unless config.callable? + + hash = config.optimize_changes(changes) + result = [hash[:modified], hash[:added], hash[:removed]] + return if result.all?(&:empty?) + + block_start = MonotonicTime.now + exception_note = " (exception)" + ::Listen::Thread.rescue_and_log('_process_changes') do + config.call(*result) + exception_note = nil + end + Listen.logger.debug "Callback#{exception_note} took #{MonotonicTime.now - block_start} sec" + end + + attr_reader :config + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/queue.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/queue.rb new file mode 100644 index 0000000..0521ddd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/event/queue.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'forwardable' + +module Listen + module Event + class Queue + extend Forwardable + + class Config + def initialize(relative) + @relative = relative + end + + def relative? + @relative + end + end + + def initialize(config) + @event_queue = ::Queue.new + @config = config + end + + def <<(args) + type, change, dir, path, options = *args + fail "Invalid type: #{type.inspect}" unless [:dir, :file].include? type + fail "Invalid change: #{change.inspect}" unless change.is_a?(Symbol) + fail "Invalid path: #{path.inspect}" unless path.is_a?(String) + + dir = if @config.relative? + _safe_relative_from_cwd(dir) + else + dir + end + @event_queue << [type, change, dir, path, options] + end + + delegate empty?: :@event_queue + delegate pop: :@event_queue + delegate close: :@event_queue + + private + + def _safe_relative_from_cwd(dir) + dir.relative_path_from(Pathname.pwd) + rescue ArgumentError + dir + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/file.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/file.rb new file mode 100644 index 0000000..41df632 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/file.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require 'digest' + +module Listen + class File + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity + def self.change(record, rel_path) + path = Pathname.new(record.root) + rel_path + lstat = path.lstat + + data = { mtime: lstat.mtime.to_f, mode: lstat.mode, size: lstat.size } + + record_data = record.file_data(rel_path) + + if record_data.empty? + record.update_file(rel_path, data) + return :added + end + + if data[:mode] != record_data[:mode] + record.update_file(rel_path, data) + return :modified + end + + if data[:mtime] != record_data[:mtime] + record.update_file(rel_path, data) + return :modified + end + + if data[:size] != record_data[:size] + record.update_file(rel_path, data) + return :modified + end + + return if /1|true/ =~ ENV['LISTEN_GEM_DISABLE_HASHING'] + return unless inaccurate_mac_time?(lstat) + + # Check if change happened within 1 second (maybe it's even + # too much, e.g. 0.3-0.5 could be sufficient). + # + # With rb-fsevent, there's a (configurable) latency between + # when file was changed and when the event was triggered. + # + # If a file is saved at ???14.998, by the time the event is + # actually received by Listen, the time could already be e.g. + # ???15.7. + # + # And since Darwin adapter uses directory scanning, the file + # mtime may be the same (e.g. file was changed at ???14.001, + # then at ???14.998, but the fstat time would be ???14.0 in + # both cases). + # + # If change happened at ???14.999997, the mtime is 14.0, so for + # an mtime=???14.0 we assume it could even be almost ???15.0 + # + # So if Time.now.to_f is ???15.999998 and stat reports mtime + # at ???14.0, then event was due to that file'd change when: + # + # ???15.999997 - ???14.999998 < 1.0s + # + # So the "2" is "1 + 1" (1s to cover rb-fsevent latency + + # 1s maximum difference between real mtime and that recorded + # in the file system) + # + return if data[:mtime].to_i + 2 <= Time.now.to_f + + sha = Digest::SHA256.file(path).digest + record.update_file(rel_path, data.merge(sha: sha)) + if record_data[:sha] && sha != record_data[:sha] + :modified + end + rescue SystemCallError + record.unset_path(rel_path) + :removed + rescue + Listen.logger.debug "lstat failed for: #{rel_path} (#{$ERROR_INFO})" + raise + end + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity + + def self.inaccurate_mac_time?(stat) + # 'mac' means Modified/Accessed/Created + + # Since precision depends on mounted FS (e.g. you can have a FAT partiion + # mounted on Linux), check for fields with a remainder to detect this + + [stat.mtime, stat.ctime, stat.atime].map(&:usec).all?(&:zero?) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/fsm.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/fsm.rb new file mode 100644 index 0000000..4235448 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/fsm.rb @@ -0,0 +1,131 @@ +# frozen_string_literal: true + +# Code copied from https://github.com/celluloid/celluloid-fsm + +module Listen + module FSM + # Included hook to extend class methods + def self.included(klass) + klass.send :extend, ClassMethods + end + + module ClassMethods + # Obtain or set the start state + # Passing a state name sets the start state + def start_state(new_start_state = nil) + if new_start_state + new_start_state.is_a?(Symbol) or raise ArgumentError, "state name must be a Symbol (got #{new_start_state.inspect})" + @start_state = new_start_state + else + defined?(@start_state) or raise ArgumentError, "`start_state :` must be declared before `new`" + @start_state + end + end + + # The valid states for this FSM, as a hash with state name symbols as keys and State objects as values. + def states + @states ||= {} + end + + # Declare an FSM state and optionally provide a callback block to fire on state entry + # Options: + # * to: a state or array of states this state can transition to + def state(state_name, to: nil, &block) + state_name.is_a?(Symbol) or raise ArgumentError, "state name must be a Symbol (got #{state_name.inspect})" + states[state_name] = State.new(state_name, to, &block) + end + end + + # NOTE: including classes must call initialize_fsm from their initialize method. + def initialize_fsm + @fsm_initialized = true + @state = self.class.start_state + @mutex = ::Mutex.new + @state_changed = ::ConditionVariable.new + end + + # Current state of the FSM, stored as a symbol + attr_reader :state + + # checks for one of the given states to wait for + # if not already, waits for a state change (up to timeout seconds--`nil` means infinite) + # returns truthy iff the transition to one of the desired state has occurred + def wait_for_state(*wait_for_states, timeout: nil) + wait_for_states.each do |state| + state.is_a?(Symbol) or raise ArgumentError, "states must be symbols (got #{state.inspect})" + end + @mutex.synchronize do + if !wait_for_states.include?(@state) + @state_changed.wait(@mutex, timeout) + end + wait_for_states.include?(@state) + end + end + + private + + def transition(new_state_name) + new_state_name.is_a?(Symbol) or raise ArgumentError, "state name must be a Symbol (got #{new_state_name.inspect})" + if (new_state = validate_and_sanitize_new_state(new_state_name)) + transition_with_callbacks!(new_state) + end + end + + # Low-level, immediate state transition with no checks or callbacks. + def transition!(new_state_name) + new_state_name.is_a?(Symbol) or raise ArgumentError, "state name must be a Symbol (got #{new_state_name.inspect})" + @fsm_initialized or raise ArgumentError, "FSM not initialized. You must call initialize_fsm from initialize!" + @mutex.synchronize do + yield if block_given? + @state = new_state_name + @state_changed.broadcast + end + end + + def validate_and_sanitize_new_state(new_state_name) + return nil if @state == new_state_name + + if current_state && !current_state.valid_transition?(new_state_name) + valid = current_state.transitions.map(&:to_s).join(', ') + msg = "#{self.class} can't change state from '#{@state}' to '#{new_state_name}', only to: #{valid}" + raise ArgumentError, msg + end + + unless (new_state = self.class.states[new_state_name]) + new_state_name == self.class.start_state or raise ArgumentError, "invalid state for #{self.class}: #{new_state_name}" + end + + new_state + end + + def transition_with_callbacks!(new_state) + transition! new_state.name + new_state.call(self) + end + + def current_state + self.class.states[@state] + end + + class State + attr_reader :name, :transitions + + def initialize(name, transitions, &block) + @name = name + @block = block + @transitions = if transitions + Array(transitions).map(&:to_sym) + end + end + + def call(obj) + obj.instance_eval(&@block) if @block + end + + def valid_transition?(new_state) + # All transitions are allowed if none are expressly declared + !@transitions || @transitions.include?(new_state.to_sym) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener.rb new file mode 100644 index 0000000..d886fdb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +require 'English' + +require 'listen/version' + +require 'listen/backend' + +require 'listen/silencer' +require 'listen/silencer/controller' + +require 'listen/queue_optimizer' + +require 'listen/fsm' + +require 'listen/event/loop' +require 'listen/event/queue' +require 'listen/event/config' + +require 'listen/listener/config' + +module Listen + class Listener + include Listen::FSM + + # Initializes the directories listener. + # + # @param [String] directory the directories to listen to + # @param [Hash] options the listen options (see Listen::Listener::Options) + # + # @yield [modified, added, removed] the changed files + # @yieldparam [Array] modified the list of modified files + # @yieldparam [Array] added the list of added files + # @yieldparam [Array] removed the list of removed files + # + # rubocop:disable Metrics/MethodLength + def initialize(*dirs, &block) + options = dirs.last.is_a?(Hash) ? dirs.pop : {} + + @config = Config.new(options) + + eq_config = Event::Queue::Config.new(@config.relative?) + queue = Event::Queue.new(eq_config) + + silencer = Silencer.new + rules = @config.silencer_rules + @silencer_controller = Silencer::Controller.new(silencer, rules) + + @backend = Backend.new(dirs, queue, silencer, @config) + + optimizer_config = QueueOptimizer::Config.new(@backend, silencer) + + pconfig = Event::Config.new( + self, + queue, + QueueOptimizer.new(optimizer_config), + @backend.min_delay_between_events, + &block) + + @processor = Event::Loop.new(pconfig) + + initialize_fsm + end + # rubocop:enable Metrics/MethodLength + + start_state :initializing + + state :initializing, to: [:backend_started, :stopped] + + state :backend_started, to: [:processing_events, :stopped] do + @backend.start + end + + state :processing_events, to: [:paused, :stopped] do + @processor.start + end + + state :paused, to: [:processing_events, :stopped] do + @processor.pause + end + + state :stopped, to: [:backend_started] do + @backend.stop # halt events ASAP + @processor.stop + end + + # Starts processing events and starts adapters + # or resumes invoking callbacks if paused + def start + case state + when :initializing + transition :backend_started + transition :processing_events + when :paused + transition :processing_events + else + raise ArgumentError, "cannot start from state #{state.inspect}" + end + end + + # Stops both listening for events and processing them + def stop + transition :stopped + end + + # Stops invoking callbacks (messages pile up) + def pause + transition :paused + end + + # processing means callbacks are called + def processing? + state == :processing_events + end + + def paused? + state == :paused + end + + def stopped? + state == :stopped + end + + def ignore(regexps) + @silencer_controller.append_ignores(regexps) + end + + def ignore!(regexps) + @silencer_controller.replace_with_bang_ignores(regexps) + end + + def only(regexps) + @silencer_controller.replace_with_only(regexps) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener/config.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener/config.rb new file mode 100644 index 0000000..56e4b7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/listener/config.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Listen + class Listener + class Config + DEFAULTS = { + # Listener options + debug: false, # TODO: is this broken? + wait_for_delay: nil, # NOTE: should be provided by adapter if possible + relative: false, + + # Backend selecting options + force_polling: false, + polling_fallback_message: nil + }.freeze + + def initialize(opts) + @options = DEFAULTS.merge(opts) + @relative = @options[:relative] + @min_delay_between_events = @options[:wait_for_delay] + @silencer_rules = @options # silencer will extract what it needs + end + + def relative? + @relative + end + + attr_reader :min_delay_between_events, :silencer_rules + + def adapter_instance_options(klass) + valid_keys = klass.const_get('DEFAULTS').keys + Hash[@options.select { |key, _| valid_keys.include?(key) }] + end + + def adapter_select_options + valid_keys = %w[force_polling polling_fallback_message].map(&:to_sym) + Hash[@options.select { |key, _| valid_keys.include?(key) }] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/logger.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/logger.rb new file mode 100644 index 0000000..0bb9806 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/logger.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module Listen + @logger = nil + + # Listen.logger will always be present. + # If you don't want logging, set Listen.logger = ::Logger.new('/dev/null', level: ::Logger::UNKNOWN) + + @adapter_warn_behavior = :warn + + class << self + attr_writer :logger + attr_accessor :adapter_warn_behavior + + def logger + @logger ||= default_logger + end + + def adapter_warn(message) + case ENV['LISTEN_GEM_ADAPTER_WARN_BEHAVIOR']&.to_sym || adapter_warn_behavior_callback(message) + when :log + logger.warn(message) + when :silent, nil, false + # do nothing + else # :warn + warn(message) + end + end + + private + + def default_logger + level = + case ENV['LISTEN_GEM_DEBUGGING'].to_s + when /debug|2/i + ::Logger::DEBUG + when /info|true|yes|1/i + ::Logger::INFO + when /warn/i + ::Logger::WARN + when /fatal/i + ::Logger::FATAL + else + ::Logger::ERROR + end + + ::Logger.new(STDERR, level: level) + end + + def adapter_warn_behavior_callback(message) + if adapter_warn_behavior.respond_to?(:call) + case behavior = adapter_warn_behavior.call(message) + when Symbol + behavior + when false, nil + :silent + else + :warn + end + else + adapter_warn_behavior + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/monotonic_time.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/monotonic_time.rb new file mode 100644 index 0000000..51b0fc9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/monotonic_time.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Listen + module MonotonicTime + class << self + if defined?(Process::CLOCK_MONOTONIC) + + def now + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + + elsif defined?(Process::CLOCK_MONOTONIC_RAW) + + def now + Process.clock_gettime(Process::CLOCK_MONOTONIC_RAW) + end + + else + + def now + Time.now.to_f + end + + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/options.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/options.rb new file mode 100644 index 0000000..6502578 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/options.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Listen + class Options + def initialize(opts, defaults) + @options = {} + given_options = opts.dup + defaults.each_key do |key| + @options[key] = given_options.delete(key) || defaults[key] + end + + given_options.empty? or raise ArgumentError, "Unknown options: #{given_options.inspect}" + end + + def respond_to_missing?(name, *_) + @options.has_key?(name) + end + + def method_missing(name, *_) + respond_to_missing?(name) or raise NameError, "Bad option: #{name.inspect} (valid:#{@options.keys.inspect})" + @options[name] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/queue_optimizer.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/queue_optimizer.rb new file mode 100644 index 0000000..2ccf4cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/queue_optimizer.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +module Listen + class QueueOptimizer + class Config + def initialize(adapter_class, silencer) + @adapter_class = adapter_class + @silencer = silencer + end + + def exist?(path) + Pathname(path).exist? + end + + def silenced?(path, type) + @silencer.silenced?(path, type) + end + + def debug(*args, &block) + Listen.logger.debug(*args, &block) + end + end + + def smoosh_changes(changes) + # TODO: adapter could be nil at this point (shutdown) + cookies = changes.group_by do |_, _, _, _, options| + (options || {})[:cookie] + end + _squash_changes(_reinterpret_related_changes(cookies)) + end + + def initialize(config) + @config = config + end + + private + + attr_reader :config + + # groups changes into the expected structure expected by + # clients + def _squash_changes(changes) + # We combine here for backward compatibility + # Newer clients should receive dir and path separately + changes = changes.map { |change, dir, path| [change, dir + path] } + + actions = changes.group_by(&:last).map do |path, action_list| + [_logical_action_for(path, action_list.map(&:first)), path.to_s] + end + + config.debug("listen: raw changes: #{actions.inspect}") + + { modified: [], added: [], removed: [] }.tap do |squashed| + actions.each do |type, path| + squashed[type] << path unless type.nil? + end + config.debug("listen: final changes: #{squashed.inspect}") + end + end + + def _logical_action_for(path, actions) + actions << :added if actions.delete(:moved_to) + actions << :removed if actions.delete(:moved_from) + + modified = actions.find { |x| x == :modified } + _calculate_add_remove_difference(actions, path, modified) + end + + def _calculate_add_remove_difference(actions, path, default_if_exists) + added = actions.count { |x| x == :added } + removed = actions.count { |x| x == :removed } + diff = added - removed + + # TODO: avoid checking if path exists and instead assume the events are + # in order (if last is :removed, it doesn't exist, etc.) + if config.exist?(path) + if diff > 0 + :added + elsif diff.zero? && added > 0 + :modified + else + default_if_exists + end + else + diff < 0 ? :removed : nil + end + end + + # remove extraneous rb-inotify events, keeping them only if it's a possible + # editor rename() call (e.g. Kate and Sublime) + def _reinterpret_related_changes(cookies) + table = { moved_to: :added, moved_from: :removed } + cookies.flat_map do |_, changes| + if (editor_modified = editor_modified?(changes)) + [[:modified, *editor_modified]] + else + not_silenced = changes.reject do |type, _, _, path, _| + config.silenced?(Pathname(path), type) + end + not_silenced.map do |_, change, dir, path, _| + [table.fetch(change, change), dir, path] + end + end + end + end + + def editor_modified?(changes) + return unless changes.size == 2 + + from_type = from = nil + to_type = to_dir = to = nil + + changes.each do |data| + case data[1] + when :moved_from + from_type, _from_change, _, from, = data + when :moved_to + to_type, _to_change, to_dir, to, = data + end + end + + # Expect an ignored moved_from and non-ignored moved_to + # to qualify as an "editor modify" + if from && to && config.silenced?(Pathname(from), from_type) && !config.silenced?(Pathname(to), to_type) + [to_dir, to] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record.rb new file mode 100644 index 0000000..362c380 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +require 'listen/record/entry' +require 'listen/record/symlink_detector' + +module Listen + class Record + # TODO: one Record object per watched directory? + # TODO: deprecate + + attr_reader :root + + def initialize(directory, silencer) + reset_tree + @root = directory.to_s + @silencer = silencer + end + + def add_dir(rel_path) + if !empty_dirname?(rel_path.to_s) + @tree[rel_path.to_s] + end + end + + def update_file(rel_path, data) + dirname, basename = Pathname(rel_path).split.map(&:to_s) + _fast_update_file(dirname, basename, data) + end + + def unset_path(rel_path) + dirname, basename = Pathname(rel_path).split.map(&:to_s) + _fast_unset_path(dirname, basename) + end + + def file_data(rel_path) + dirname, basename = Pathname(rel_path).split.map(&:to_s) + if empty_dirname?(dirname) + @tree[basename].dup + else + @tree[dirname][basename] ||= {} + @tree[dirname][basename].dup + end + end + + def dir_entries(rel_path) + rel_path_s = rel_path.to_s + subtree = if empty_dirname?(rel_path_s) + @tree + else + @tree[rel_path_s] + end + + subtree.each_with_object({}) do |(key, values), result| + # only return data for file entries inside the dir (which will each be sub-hashes) + if values.is_a?(Hash) + result[key] = values.has_key?(:mtime) ? values : {} + end + end + end + + def build + reset_tree + # TODO: test with a file name given + # TODO: test other permissions + # TODO: test with mixed encoding + symlink_detector = SymlinkDetector.new + remaining = ::Queue.new + remaining << Entry.new(root, nil, nil) + _fast_build_dir(remaining, symlink_detector) until remaining.empty? + end + + private + + def empty_dirname?(dirname) + ['.', ''].include?(dirname) + end + + def reset_tree + @tree = Hash.new { |h, k| h[k] = {} } + end + + def _fast_update_file(dirname, basename, data) + if empty_dirname?(dirname.to_s) + @tree[basename] = @tree[basename].merge(data) + else + @tree[dirname][basename] = (@tree[dirname][basename] || {}).merge(data) + end + end + + def _fast_unset_path(dirname, basename) + # this may need to be reworked to properly remove + # entries from a tree, without adding non-existing dirs to the record + if empty_dirname?(dirname.to_s) + if @tree.key?(basename) + @tree.delete(basename) + end + elsif @tree.key?(dirname) + @tree[dirname].delete(basename) + end + end + + def _fast_build_dir(remaining, symlink_detector) + entry = remaining.pop + return if @silencer.silenced?(entry.record_dir_key, :dir) + + children = entry.children # NOTE: children() implicitly tests if dir + symlink_detector.verify_unwatched!(entry) + children.each { |child| remaining << child } + add_dir(entry.record_dir_key) + rescue Errno::ENOTDIR + _fast_try_file(entry) + rescue SystemCallError, SymlinkDetector::Error + _fast_unset_path(entry.relative, entry.name) + end + + def _fast_try_file(entry) + _fast_update_file(entry.relative, entry.name, entry.meta) + rescue SystemCallError + _fast_unset_path(entry.relative, entry.name) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/entry.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/entry.rb new file mode 100644 index 0000000..a01a159 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/entry.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Listen + # @private api + class Record + # Represents a directory entry (dir or file) + class Entry + # file: "/home/me/watched_dir", "app/models", "foo.rb" + # dir, "/home/me/watched_dir", "." + def initialize(root, relative, name = nil) + @root = root + @relative = relative + @name = name + end + + attr_reader :root, :relative, :name + + def children + child_relative = _join + (_entries(sys_path) - %w[. ..]).map do |name| + Entry.new(@root, child_relative, name) + end + end + + def meta + lstat = ::File.lstat(sys_path) + { mtime: lstat.mtime.to_f, mode: lstat.mode, size: lstat.size } + end + + # record hash is e.g. + # if @record["/home/me/watched_dir"]["project/app/models"]["foo.rb"] + # if @record["/home/me/watched_dir"]["project/app"]["models"] + # record_dir_key is "project/app/models" + def record_dir_key + ::File.join(*[@relative, @name].compact) + end + + def sys_path + # Use full path in case someone uses chdir + ::File.join(*[@root, @relative, @name].compact) + end + + def real_path + @real_path ||= ::File.realpath(sys_path) + end + + private + + def _join + args = [@relative, @name].compact + args.empty? ? nil : ::File.join(*args) + end + + def _entries(dir) + return Dir.entries(dir) unless RUBY_ENGINE == 'jruby' + + # JRuby inconsistency workaround, see: + # https://github.com/jruby/jruby/issues/3840 + exists = ::File.exist?(dir) + directory = ::File.directory?(dir) + return Dir.entries(dir) unless exists && !directory + raise Errno::ENOTDIR, dir + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/symlink_detector.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/symlink_detector.rb new file mode 100644 index 0000000..1da60f5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/record/symlink_detector.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'set' +require 'listen/error' + +module Listen + # @private api + class Record + class SymlinkDetector + README_URL = 'https://github.com/guard/listen/blob/master/README.md' + + SYMLINK_LOOP_ERROR = <<-EOS.freeze + ** ERROR: directory is already being watched! ** + + Directory: %s + + is already being watched through: %s + + MORE INFO: #{README_URL} + EOS + + Error = ::Listen::Error # for backward compatibility + + def initialize + @real_dirs = Set.new + end + + def verify_unwatched!(entry) + real_path = entry.real_path + @real_dirs.add?(real_path) or _fail(entry.sys_path, real_path) + end + + # Leaving this stub here since some warning work-arounds were referring to it. + # Deprecated. Will be removed in Listen v4.0. + def warn(message) + Listen.adapter_warn(message) + end + + private + + def _fail(symlinked, real_path) + warn(format(SYMLINK_LOOP_ERROR, symlinked, real_path)) + raise ::Listen::Error::SymlinkLoop, 'Failed due to looped symlinks' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer.rb new file mode 100644 index 0000000..3cc7936 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +module Listen + class Silencer + # The default list of directories that get ignored. + DEFAULT_IGNORED_FILES = %r{\A(?: + \.git + | \.svn + | \.hg + | \.rbx + | \.bundle + | bundle + | vendor/bundle + | log + | tmp + | vendor/ruby + + # emacs temp files + | \#.+\# + | \.\#.+ + )(/|\z)}x + + # The default list of files that get ignored. + DEFAULT_IGNORED_EXTENSIONS = %r{(?: + # Kate's tmp\/swp files + \..*\d+\.new + | \.kate-swp + + # Gedit tmp files + | \.goutputstream-.{6} + + # Intellij files + | ___jb_bak___ + | ___jb_old___ + + # Vim swap files and write test + | \.sw[px] + | \.swpx + | ^4913 + + # Sed temporary files - but without actual words, like 'sedatives' + | (?:\A + sed + + (?: + [a-zA-Z0-9]{0}[A-Z]{1}[a-zA-Z0-9]{5} | + [a-zA-Z0-9]{1}[A-Z]{1}[a-zA-Z0-9]{4} | + [a-zA-Z0-9]{2}[A-Z]{1}[a-zA-Z0-9]{3} | + [a-zA-Z0-9]{3}[A-Z]{1}[a-zA-Z0-9]{2} | + [a-zA-Z0-9]{4}[A-Z]{1}[a-zA-Z0-9]{1} | + [a-zA-Z0-9]{5}[A-Z]{1}[a-zA-Z0-9]{0} + ) + ) + + # Mutagen sync temporary files + | \.mutagen-temporary.* + + # other files + | \.DS_Store + | \.tmp + | ~ + )\z}x + + # TODO: deprecate these mutators; use attr_reader instead + attr_accessor :only_patterns, :ignore_patterns + + def initialize(**options) + configure(options) + end + + # TODO: deprecate this mutator + def configure(options) + @only_patterns = options[:only] ? Array(options[:only]) : nil + @ignore_patterns = _init_ignores(options[:ignore], options[:ignore!]) + end + + def silenced?(relative_path, type) + path = relative_path.to_s # in case it is a Pathname + + _ignore?(path) || (only_patterns && type == :file && !_only?(path)) + end + + private + + def _ignore?(path) + ignore_patterns.any? { |pattern| path =~ pattern } + end + + def _only?(path) + only_patterns.any? { |pattern| path =~ pattern } + end + + def _init_ignores(ignores, overrides) + patterns = [] + unless overrides + patterns << DEFAULT_IGNORED_FILES + patterns << DEFAULT_IGNORED_EXTENSIONS + end + + patterns << ignores + patterns << overrides + + patterns.compact.flatten + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer/controller.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer/controller.rb new file mode 100644 index 0000000..bb94d4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/silencer/controller.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Listen + class Silencer + class Controller + def initialize(silencer, default_options) + @silencer = silencer + + opts = default_options + + @prev_silencer_options = {} + rules = [:only, :ignore, :ignore!].map do |option| + [option, opts[option]] if opts.key? option + end + + _reconfigure_silencer(Hash[rules.compact]) + end + + def append_ignores(*regexps) + prev_ignores = Array(@prev_silencer_options[:ignore]) + _reconfigure_silencer(ignore: [prev_ignores + regexps]) + end + + def replace_with_bang_ignores(regexps) + _reconfigure_silencer(ignore!: regexps) + end + + def replace_with_only(regexps) + _reconfigure_silencer(only: regexps) + end + + private + + def _reconfigure_silencer(extra_options) + opts = extra_options.dup + opts = opts.map do |key, value| + [key, Array(value).flatten.compact] + end + opts = Hash[opts] + + if opts.key?(:ignore) && opts[:ignore].empty? + opts.delete(:ignore) + end + + @prev_silencer_options = opts + @silencer.configure(@prev_silencer_options.dup.freeze) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/thread.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/thread.rb new file mode 100644 index 0000000..a1e6b3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/thread.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'thread' + +require_relative 'logger' + +module Listen + module Thread + class << self + # Creates a new thread with the given name. + # Any exceptions raised by the thread will be logged with the thread name and complete backtrace. + # rubocop:disable Style/MultilineBlockChain + def new(name, &block) + thread_name = "listen-#{name}" + caller_stack = caller + + ::Thread.new do + rescue_and_log(thread_name, caller_stack: caller_stack, &block) + end.tap do |thread| + thread.name = thread_name + end + end + # rubocop:enable Style/MultilineBlockChain + + def rescue_and_log(method_name, *args, caller_stack: nil) + yield(*args) + rescue => exception + _log_exception(exception, method_name, caller_stack: caller_stack) + end + + private + + def _log_exception(exception, thread_name, caller_stack: nil) + complete_backtrace = if caller_stack + [*exception.backtrace, "--- Thread.new ---", *caller_stack] + else + exception.backtrace + end + message = "Exception rescued in #{thread_name}:\n#{_exception_with_causes(exception)}\n#{complete_backtrace * "\n"}" + Listen.logger.error(message) + end + + def _exception_with_causes(exception) + result = +"#{exception.class}: #{exception}" + if exception.cause + result << "\n" + result << "--- Caused by: ---\n" + result << _exception_with_causes(exception.cause) + end + result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/version.rb b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/version.rb new file mode 100644 index 0000000..c8bf841 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/listen-3.10.0/lib/listen/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module Listen + VERSION = '3.10.0' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.document b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.document new file mode 100644 index 0000000..e2b9569 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.document @@ -0,0 +1,4 @@ +BSDL +COPYING +README.md +lib/ diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.rdoc_options b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.rdoc_options new file mode 100644 index 0000000..2d29a05 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.rdoc_options @@ -0,0 +1,3 @@ +--- +main_page: README.md +title: Documentation for Logger diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL new file mode 100644 index 0000000..66d9359 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING new file mode 100644 index 0000000..48e5a96 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md new file mode 100644 index 0000000..ceb1a21 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md @@ -0,0 +1,104 @@ +# Logger + +Logger is a simple but powerful logging utility to output messages in your Ruby program. + +Logger has the following features: + + * Print messages to different levels such as `info` and `error` + * Auto-rolling of log files + * Setting the format of log messages + * Specifying a program name in conjunction with the message + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'logger' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install logger + +## Usage + +### Simple Example + +```ruby +require 'logger' + +# Create a Logger that prints to STDOUT +log = Logger.new(STDOUT) +log.debug("Created Logger") + +log.info("Program finished") + +# Create a Logger that prints to STDERR +error_log = Logger.new(STDERR) +error_log = error_log.error("fatal error") +``` + +## Development + +After checking out the repo, run the following to install dependencies. + +``` +$ bin/setup +``` + +Then, run the tests as: + +``` +$ rake test +``` + +To install this gem onto your local machine, run + +``` +$ rake install +``` + +To release a new version, update the version number in `lib/logger/version.rb`, and then run + +``` +$ rake release +``` + +which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Advanced Development + +### Run tests of a specific file + +``` +$ ruby test/logger/test_logger.rb +``` + +### Run tests filtering test methods by a name + +`--name` option is available as: + +``` +$ ruby test/logger/test_logger.rb --name test_lshift +``` + +### Publish documents to GitHub Pages + +``` +$ rake gh-pages +``` + +Then, git commit and push the generated HTMLs onto `gh-pages` branch. + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/logger. + +## License + +The gem is available as open source under the terms of the [BSD-2-Clause](BSDL). diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb new file mode 100644 index 0000000..4911a3f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb @@ -0,0 +1,789 @@ +# frozen_string_literal: true +# logger.rb - simple logging utility +# Copyright (C) 2000-2003, 2005, 2008, 2011 NAKAMURA, Hiroshi . +# +# Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair +# License:: +# You can redistribute it and/or modify it under the same terms of Ruby's +# license; either the dual license version in 2003, or any later version. +# Revision:: $Id$ +# +# A simple system for logging messages. See Logger for more documentation. + +require 'fiber' +require 'monitor' +require 'rbconfig' + +require_relative 'logger/version' +require_relative 'logger/formatter' +require_relative 'logger/log_device' +require_relative 'logger/severity' +require_relative 'logger/errors' + +# \Class \Logger provides a simple but sophisticated logging utility that +# you can use to create one or more +# {event logs}[https://en.wikipedia.org/wiki/Logging_(software)#Event_logs] +# for your program. +# Each such log contains a chronological sequence of entries +# that provides a record of the program's activities. +# +# == About the Examples +# +# All examples on this page assume that \Logger has been required: +# +# require 'logger' +# +# == Synopsis +# +# Create a log with Logger.new: +# +# # Single log file. +# logger = Logger.new('t.log') +# # Size-based rotated logging: 3 10-megabyte files. +# logger = Logger.new('t.log', 3, 10485760) +# # Period-based rotated logging: daily (also allowed: 'weekly', 'monthly'). +# logger = Logger.new('t.log', 'daily') +# # Log to an IO stream. +# logger = Logger.new($stdout) +# +# Add entries (level, message) with Logger#add: +# +# logger.add(Logger::DEBUG, 'Maximal debugging info') +# logger.add(Logger::INFO, 'Non-error information') +# logger.add(Logger::WARN, 'Non-error warning') +# logger.add(Logger::ERROR, 'Non-fatal error') +# logger.add(Logger::FATAL, 'Fatal error') +# logger.add(Logger::UNKNOWN, 'Most severe') +# +# Close the log with Logger#close: +# +# logger.close +# +# == Entries +# +# You can add entries with method Logger#add: +# +# logger.add(Logger::DEBUG, 'Maximal debugging info') +# logger.add(Logger::INFO, 'Non-error information') +# logger.add(Logger::WARN, 'Non-error warning') +# logger.add(Logger::ERROR, 'Non-fatal error') +# logger.add(Logger::FATAL, 'Fatal error') +# logger.add(Logger::UNKNOWN, 'Most severe') +# +# These shorthand methods also add entries: +# +# logger.debug('Maximal debugging info') +# logger.info('Non-error information') +# logger.warn('Non-error warning') +# logger.error('Non-fatal error') +# logger.fatal('Fatal error') +# logger.unknown('Most severe') +# +# When you call any of these methods, +# the entry may or may not be written to the log, +# depending on the entry's severity and on the log level; +# see {Log Level}[rdoc-ref:Logger@Log+Level] +# +# An entry always has: +# +# - A severity (the required argument to #add). +# - An automatically created timestamp. +# +# And may also have: +# +# - A message. +# - A program name. +# +# Example: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO, 'My message.', 'mung') +# # => I, [2022-05-07T17:21:46.536234 #20536] INFO -- mung: My message. +# +# The default format for an entry is: +# +# "%s, [%s #%d] %5s -- %s: %s\n" +# +# where the values to be formatted are: +# +# - \Severity (one letter). +# - Timestamp. +# - Process id. +# - \Severity (word). +# - Program name. +# - Message. +# +# You can use a different entry format by: +# +# - Setting a custom format proc (affects following entries); +# see {formatter=}[Logger.html#attribute-i-formatter]. +# - Calling any of the methods above with a block +# (affects only the one entry). +# Doing so can have two benefits: +# +# - Context: the block can evaluate the entire program context +# and create a context-dependent message. +# - Performance: the block is not evaluated unless the log level +# permits the entry actually to be written: +# +# logger.error { my_slow_message_generator } +# +# Contrast this with the string form, where the string is +# always evaluated, regardless of the log level: +# +# logger.error("#{my_slow_message_generator}") +# +# === \Severity +# +# The severity of a log entry has two effects: +# +# - Determines whether the entry is selected for inclusion in the log; +# see {Log Level}[rdoc-ref:Logger@Log+Level]. +# - Indicates to any log reader (whether a person or a program) +# the relative importance of the entry. +# +# === Timestamp +# +# The timestamp for a log entry is generated automatically +# when the entry is created. +# +# The logged timestamp is formatted by method +# {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime] +# using this format string: +# +# '%Y-%m-%dT%H:%M:%S.%6N' +# +# Example: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO) +# # => I, [2022-05-07T17:04:32.318331 #20536] INFO -- : nil +# +# You can set a different format using method #datetime_format=. +# +# === Message +# +# The message is an optional argument to an entry method: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO, 'My message') +# # => I, [2022-05-07T18:15:37.647581 #20536] INFO -- : My message +# +# For the default entry formatter, Logger::Formatter, +# the message object may be: +# +# - A string: used as-is. +# - An Exception: message.message is used. +# - Anything else: message.inspect is used. +# +# *Note*: Logger::Formatter does not escape or sanitize +# the message passed to it. +# Developers should be aware that malicious data (user input) +# may be in the message, and should explicitly escape untrusted data. +# +# You can use a custom formatter to escape message data; +# see the example at {formatter=}[Logger.html#attribute-i-formatter]. +# +# === Program Name +# +# The program name is an optional argument to an entry method: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO, 'My message', 'mung') +# # => I, [2022-05-07T18:17:38.084716 #20536] INFO -- mung: My message +# +# The default program name for a new logger may be set in the call to +# Logger.new via optional keyword argument +progname+: +# +# logger = Logger.new('t.log', progname: 'mung') +# +# The default program name for an existing logger may be set +# by a call to method #progname=: +# +# logger.progname = 'mung' +# +# The current program name may be retrieved with method +# {progname}[Logger.html#attribute-i-progname]: +# +# logger.progname # => "mung" +# +# == Log Level +# +# The log level setting determines whether an entry is actually +# written to the log, based on the entry's severity. +# +# These are the defined severities (least severe to most severe): +# +# logger = Logger.new($stdout) +# logger.add(Logger::DEBUG, 'Maximal debugging info') +# # => D, [2022-05-07T17:57:41.776220 #20536] DEBUG -- : Maximal debugging info +# logger.add(Logger::INFO, 'Non-error information') +# # => I, [2022-05-07T17:59:14.349167 #20536] INFO -- : Non-error information +# logger.add(Logger::WARN, 'Non-error warning') +# # => W, [2022-05-07T18:00:45.337538 #20536] WARN -- : Non-error warning +# logger.add(Logger::ERROR, 'Non-fatal error') +# # => E, [2022-05-07T18:02:41.592912 #20536] ERROR -- : Non-fatal error +# logger.add(Logger::FATAL, 'Fatal error') +# # => F, [2022-05-07T18:05:24.703931 #20536] FATAL -- : Fatal error +# logger.add(Logger::UNKNOWN, 'Most severe') +# # => A, [2022-05-07T18:07:54.657491 #20536] ANY -- : Most severe +# +# The default initial level setting is Logger::DEBUG, the lowest level, +# which means that all entries are to be written, regardless of severity: +# +# logger = Logger.new($stdout) +# logger.level # => 0 +# logger.add(0, "My message") +# # => D, [2022-05-11T15:10:59.773668 #20536] DEBUG -- : My message +# +# You can specify a different setting in a new logger +# using keyword argument +level+ with an appropriate value: +# +# logger = Logger.new($stdout, level: Logger::ERROR) +# logger = Logger.new($stdout, level: 'error') +# logger = Logger.new($stdout, level: :error) +# logger.level # => 3 +# +# With this level, entries with severity Logger::ERROR and higher +# are written, while those with lower severities are not written: +# +# logger = Logger.new($stdout, level: Logger::ERROR) +# logger.add(3) +# # => E, [2022-05-11T15:17:20.933362 #20536] ERROR -- : nil +# logger.add(2) # Silent. +# +# You can set the log level for an existing logger +# with method #level=: +# +# logger.level = Logger::ERROR +# +# These shorthand methods also set the level: +# +# logger.debug! # => 0 +# logger.info! # => 1 +# logger.warn! # => 2 +# logger.error! # => 3 +# logger.fatal! # => 4 +# +# You can retrieve the log level with method #level. +# +# logger.level = Logger::ERROR +# logger.level # => 3 +# +# These methods return whether a given +# level is to be written: +# +# logger.level = Logger::ERROR +# logger.debug? # => false +# logger.info? # => false +# logger.warn? # => false +# logger.error? # => true +# logger.fatal? # => true +# +# == Log File Rotation +# +# By default, a log file is a single file that grows indefinitely +# (until explicitly closed); there is no file rotation. +# +# To keep log files to a manageable size, +# you can use _log_ _file_ _rotation_, which uses multiple log files: +# +# - Each log file has entries for a non-overlapping +# time interval. +# - Only the most recent log file is open and active; +# the others are closed and inactive. +# +# === Size-Based Rotation +# +# For size-based log file rotation, call Logger.new with: +# +# - Argument +logdev+ as a file path. +# - Argument +shift_age+ with a positive integer: +# the number of log files to be in the rotation. +# - Argument +shift_size+ as a positive integer: +# the maximum size (in bytes) of each log file; +# defaults to 1048576 (1 megabyte). +# +# Examples: +# +# logger = Logger.new('t.log', 3) # Three 1-megabyte files. +# logger = Logger.new('t.log', 5, 10485760) # Five 10-megabyte files. +# +# For these examples, suppose: +# +# logger = Logger.new('t.log', 3) +# +# Logging begins in the new log file, +t.log+; +# the log file is "full" and ready for rotation +# when a new entry would cause its size to exceed +shift_size+. +# +# The first time +t.log+ is full: +# +# - +t.log+ is closed and renamed to +t.log.0+. +# - A new file +t.log+ is opened. +# +# The second time +t.log+ is full: +# +# - +t.log.0 is renamed as +t.log.1+. +# - +t.log+ is closed and renamed to +t.log.0+. +# - A new file +t.log+ is opened. +# +# Each subsequent time that +t.log+ is full, +# the log files are rotated: +# +# - +t.log.1+ is removed. +# - +t.log.0 is renamed as +t.log.1+. +# - +t.log+ is closed and renamed to +t.log.0+. +# - A new file +t.log+ is opened. +# +# === Periodic Rotation +# +# For periodic rotation, call Logger.new with: +# +# - Argument +logdev+ as a file path. +# - Argument +shift_age+ as a string period indicator. +# +# Examples: +# +# logger = Logger.new('t.log', 'daily') # Rotate log files daily. +# logger = Logger.new('t.log', 'weekly') # Rotate log files weekly. +# logger = Logger.new('t.log', 'monthly') # Rotate log files monthly. +# +# Example: +# +# logger = Logger.new('t.log', 'daily') +# +# When the given period expires: +# +# - The base log file, +t.log+ is closed and renamed +# with a date-based suffix such as +t.log.20220509+. +# - A new log file +t.log+ is opened. +# - Nothing is removed. +# +# The default format for the suffix is '%Y%m%d', +# which produces a suffix similar to the one above. +# You can set a different format using create-time option +# +shift_period_suffix+; +# see details and suggestions at +# {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime]. +# +class Logger + _, name, rev = %w$Id$ + if name + name = name.chomp(",v") + else + name = File.basename(__FILE__) + end + rev ||= "v#{VERSION}" + ProgName = "#{name}/#{rev}" + + include Severity + + # Logging severity threshold (e.g. Logger::INFO). + def level + level_override[level_key] || @level + end + + # Sets the log level; returns +severity+. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + # Argument +severity+ may be an integer, a string, or a symbol: + # + # logger.level = Logger::ERROR # => 3 + # logger.level = 3 # => 3 + # logger.level = 'error' # => "error" + # logger.level = :error # => :error + # + # Logger#sev_threshold= is an alias for Logger#level=. + # + def level=(severity) + @level = Severity.coerce(severity) + end + + # Adjust the log level during the block execution for the current Fiber only + # + # logger.with_level(:debug) do + # logger.debug { "Hello" } + # end + def with_level(severity) + prev, level_override[level_key] = level, Severity.coerce(severity) + begin + yield + ensure + if prev + level_override[level_key] = prev + else + level_override.delete(level_key) + end + end + end + + # Program name to include in log messages. + attr_accessor :progname + + # Sets the date-time format. + # + # Argument +datetime_format+ should be either of these: + # + # - A string suitable for use as a format for method + # {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime]. + # - +nil+: the logger uses '%Y-%m-%dT%H:%M:%S.%6N'. + # + def datetime_format=(datetime_format) + @default_formatter.datetime_format = datetime_format + end + + # Returns the date-time format; see #datetime_format=. + # + def datetime_format + @default_formatter.datetime_format + end + + # Sets or retrieves the logger entry formatter proc. + # + # When +formatter+ is +nil+, the logger uses Logger::Formatter. + # + # When +formatter+ is a proc, a new entry is formatted by the proc, + # which is called with four arguments: + # + # - +severity+: The severity of the entry. + # - +time+: A Time object representing the entry's timestamp. + # - +progname+: The program name for the entry. + # - +msg+: The message for the entry (string or string-convertible object). + # + # The proc should return a string containing the formatted entry. + # + # This custom formatter uses + # {String#dump}[https://docs.ruby-lang.org/en/master/String.html#method-i-dump] + # to escape the message string: + # + # logger = Logger.new($stdout, progname: 'mung') + # original_formatter = logger.formatter || Logger::Formatter.new + # logger.formatter = proc { |severity, time, progname, msg| + # original_formatter.call(severity, time, progname, msg.dump) + # } + # logger.add(Logger::INFO, "hello \n ''") + # logger.add(Logger::INFO, "\f\x00\xff\\\"") + # + # Output: + # + # I, [2022-05-13T13:16:29.637488 #8492] INFO -- mung: "hello \n ''" + # I, [2022-05-13T13:16:29.637610 #8492] INFO -- mung: "\f\x00\xFF\\\"" + # + attr_accessor :formatter + + alias sev_threshold level + alias sev_threshold= level= + + # Returns +true+ if the log level allows entries with severity + # Logger::DEBUG to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def debug?; level <= DEBUG; end + + # Sets the log level to Logger::DEBUG. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def debug!; self.level = DEBUG; end + + # Returns +true+ if the log level allows entries with severity + # Logger::INFO to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def info?; level <= INFO; end + + # Sets the log level to Logger::INFO. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def info!; self.level = INFO; end + + # Returns +true+ if the log level allows entries with severity + # Logger::WARN to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def warn?; level <= WARN; end + + # Sets the log level to Logger::WARN. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def warn!; self.level = WARN; end + + # Returns +true+ if the log level allows entries with severity + # Logger::ERROR to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def error?; level <= ERROR; end + + # Sets the log level to Logger::ERROR. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def error!; self.level = ERROR; end + + # Returns +true+ if the log level allows entries with severity + # Logger::FATAL to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def fatal?; level <= FATAL; end + + # Sets the log level to Logger::FATAL. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def fatal!; self.level = FATAL; end + + # :call-seq: + # Logger.new(logdev, shift_age = 0, shift_size = 1048576, **options) + # + # With the single argument +logdev+, + # returns a new logger with all default options: + # + # Logger.new('t.log') # => # + # + # Argument +logdev+ must be one of: + # + # - A string filepath: entries are to be written + # to the file at that path; if the file at that path exists, + # new entries are appended. + # - An IO stream (typically $stdout, $stderr. or + # an open file): entries are to be written to the given stream. + # - +nil+ or +File::NULL+: no entries are to be written. + # + # Argument +shift_age+ must be one of: + # + # - The number of log files to be in the rotation. + # See {Size-Based Rotation}[rdoc-ref:Logger@Size-Based+Rotation]. + # - A string period indicator. + # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. + # + # Argument +shift_size+ is the maximum size (in bytes) of each log file. + # See {Size-Based Rotation}[rdoc-ref:Logger@Size-Based+Rotation]. + # + # Examples: + # + # Logger.new('t.log') + # Logger.new($stdout) + # + # The keyword options are: + # + # - +level+: sets the log level; default value is Logger::DEBUG. + # See {Log Level}[rdoc-ref:Logger@Log+Level]: + # + # Logger.new('t.log', level: Logger::ERROR) + # + # - +progname+: sets the default program name; default is +nil+. + # See {Program Name}[rdoc-ref:Logger@Program+Name]: + # + # Logger.new('t.log', progname: 'mung') + # + # - +formatter+: sets the entry formatter; default is +nil+. + # See {formatter=}[Logger.html#attribute-i-formatter]. + # + # - +datetime_format+: sets the format for entry timestamp; + # default is +nil+. + # See #datetime_format=. + # + # - +binmode+: sets whether the logger writes in binary mode; + # default is +false+. + # + # - +shift_period_suffix+: sets the format for the filename suffix + # for periodic log file rotation; default is '%Y%m%d'. + # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. + # + # - +reraise_write_errors+: An array of exception classes, which will + # be reraised if there is an error when writing to the log device. + # The default is to swallow all exceptions raised. + # - +skip_header+: If +true+, prevents the logger from writing a header + # when creating a new log file. The default is +false+, meaning + # the header will be written as usual. + # + def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, + progname: nil, formatter: nil, datetime_format: nil, + binmode: false, shift_period_suffix: '%Y%m%d', + reraise_write_errors: [], skip_header: false) + self.level = level + self.progname = progname + @default_formatter = Formatter.new + self.datetime_format = datetime_format + self.formatter = formatter + @logdev = nil + @level_override = {} + if logdev && logdev != File::NULL + @logdev = LogDevice.new(logdev, shift_age: shift_age, + shift_size: shift_size, + shift_period_suffix: shift_period_suffix, + binmode: binmode, + reraise_write_errors: reraise_write_errors, + skip_header: skip_header) + end + end + + # Sets the logger's output stream: + # + # - If +logdev+ is +nil+, reopens the current output stream. + # - If +logdev+ is a filepath, opens the indicated file for append. + # - If +logdev+ is an IO stream + # (usually $stdout, $stderr, or an open File object), + # opens the stream for append. + # + # Example: + # + # logger = Logger.new('t.log') + # logger.add(Logger::ERROR, 'one') + # logger.close + # logger.add(Logger::ERROR, 'two') # Prints 'log writing failed. closed stream' + # logger.reopen + # logger.add(Logger::ERROR, 'three') + # logger.close + # File.readlines('t.log') + # # => + # # ["# Logfile created on 2022-05-12 14:21:19 -0500 by logger.rb/v1.5.0\n", + # # "E, [2022-05-12T14:21:27.596726 #22428] ERROR -- : one\n", + # # "E, [2022-05-12T14:23:05.847241 #22428] ERROR -- : three\n"] + # + def reopen(logdev = nil, shift_age = nil, shift_size = nil, shift_period_suffix: nil, binmode: nil) + @logdev&.reopen(logdev, shift_age: shift_age, shift_size: shift_size, + shift_period_suffix: shift_period_suffix, binmode: binmode) + self + end + + # Creates a log entry, which may or may not be written to the log, + # depending on the entry's severity and on the log level. + # See {Log Level}[rdoc-ref:Logger@Log+Level] + # and {Entries}[rdoc-ref:Logger@Entries] for details. + # + # Examples: + # + # logger = Logger.new($stdout, progname: 'mung') + # logger.add(Logger::INFO) + # logger.add(Logger::ERROR, 'No good') + # logger.add(Logger::ERROR, 'No good', 'gnum') + # + # Output: + # + # I, [2022-05-12T16:25:31.469726 #36328] INFO -- mung: mung + # E, [2022-05-12T16:25:55.349414 #36328] ERROR -- mung: No good + # E, [2022-05-12T16:26:35.841134 #36328] ERROR -- gnum: No good + # + # These convenience methods have implicit severity: + # + # - #debug. + # - #info. + # - #warn. + # - #error. + # - #fatal. + # - #unknown. + # + def add(severity, message = nil, progname = nil) + severity ||= UNKNOWN + if @logdev.nil? or severity < level + return true + end + if progname.nil? + progname = @progname + end + if message.nil? + if block_given? + message = yield + else + message = progname + progname = @progname + end + end + @logdev.write( + format_message(format_severity(severity), Time.now, progname, message)) + true + end + alias log add + + # Writes the given +msg+ to the log with no formatting; + # returns the number of characters written, + # or +nil+ if no log device exists: + # + # logger = Logger.new($stdout) + # logger << 'My message.' # => 10 + # + # Output: + # + # My message. + # + def <<(msg) + @logdev&.write(msg) + end + + # Equivalent to calling #add with severity Logger::DEBUG. + # + def debug(progname = nil, &block) + add(DEBUG, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::INFO. + # + def info(progname = nil, &block) + add(INFO, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::WARN. + # + def warn(progname = nil, &block) + add(WARN, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::ERROR. + # + def error(progname = nil, &block) + add(ERROR, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::FATAL. + # + def fatal(progname = nil, &block) + add(FATAL, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::UNKNOWN. + # + def unknown(progname = nil, &block) + add(UNKNOWN, nil, progname, &block) + end + + # Closes the logger; returns +nil+: + # + # logger = Logger.new('t.log') + # logger.close # => nil + # logger.info('foo') # Prints "log writing failed. closed stream" + # + # Related: Logger#reopen. + def close + @logdev&.close + end + +private + + # \Severity label for logging (max 5 chars). + SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY).freeze + + def format_severity(severity) + SEV_LABEL[severity] || 'ANY' + end + + # Guarantee the existence of this ivar even when subclasses don't call the superclass constructor. + def level_override + unless defined?(@level_override) + bad = self.class.instance_method(:initialize) + file, line = bad.source_location + Kernel.warn <<~";;;", uplevel: 2 + Logger not initialized properly + #{file}:#{line}: info: #{bad.owner}\##{bad.name}: \ + does not call super probably + ;;; + end + @level_override ||= {} + end + + def level_key + Fiber.current + end + + def format_message(severity, datetime, progname, msg) + (@formatter || @default_formatter).call(severity, datetime, progname, msg) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb new file mode 100644 index 0000000..8858179 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Logger + # not used after 1.2.7. just for compat. + class Error < RuntimeError # :nodoc: + end + class ShiftingError < Error # :nodoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb new file mode 100644 index 0000000..c634dbf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class Logger + # Default formatter for log messages. + class Formatter + Format = "%.1s, [%s #%d] %5s -- %s: %s\n" + DatetimeFormat = "%Y-%m-%dT%H:%M:%S.%6N" + + attr_accessor :datetime_format + + def initialize + @datetime_format = nil + end + + def call(severity, time, progname, msg) + sprintf(Format, severity, format_datetime(time), Process.pid, severity, progname, msg2str(msg)) + end + + private + + def format_datetime(time) + time.strftime(@datetime_format || DatetimeFormat) + end + + def msg2str(msg) + case msg + when ::String + msg + when ::Exception + "#{ msg.message } (#{ msg.class })\n#{ msg.backtrace.join("\n") if msg.backtrace }" + else + msg.inspect + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb new file mode 100644 index 0000000..e16f3b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb @@ -0,0 +1,265 @@ +# frozen_string_literal: true + +require_relative 'period' + +class Logger + # Device used for logging messages. + class LogDevice + include Period + + attr_reader :dev + attr_reader :filename + include MonitorMixin + + def initialize( + log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, + binmode: false, reraise_write_errors: [], skip_header: false + ) + @dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil + @binmode = binmode + @reraise_write_errors = reraise_write_errors + @skip_header = skip_header + mon_initialize + set_dev(log) + set_file(shift_age, shift_size, shift_period_suffix) if @filename + end + + def write(message) + handle_write_errors("writing") do + synchronize do + if @shift_age and @dev.respond_to?(:stat) + handle_write_errors("shifting") {check_shift_log} + end + handle_write_errors("writing") {@dev.write(message)} + end + end + end + + def close + begin + synchronize do + @dev.close rescue nil + end + rescue Exception + @dev.close rescue nil + end + end + + def reopen(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: nil) + # reopen the same filename if no argument, do nothing for IO + log ||= @filename if @filename + @binmode = binmode unless binmode.nil? + if log + synchronize do + if @filename and @dev + @dev.close rescue nil # close only file opened by Logger + @filename = nil + end + set_dev(log) + set_file(shift_age, shift_size, shift_period_suffix) if @filename + end + end + self + end + + private + + # :stopdoc: + + MODE = File::WRONLY | File::APPEND + # TruffleRuby < 24.2 does not have File::SHARE_DELETE + if File.const_defined? :SHARE_DELETE + MODE_TO_OPEN = MODE | File::SHARE_DELETE | File::BINARY + else + MODE_TO_OPEN = MODE | File::BINARY + end + MODE_TO_CREATE = MODE_TO_OPEN | File::CREAT | File::EXCL + + def set_dev(log) + if log.respond_to?(:write) and log.respond_to?(:close) + @dev = log + if log.respond_to?(:path) and path = log.path + if File.exist?(path) + @filename = path + end + end + else + @dev = open_logfile(log) + @filename = log + end + end + + def set_file(shift_age, shift_size, shift_period_suffix) + @shift_age = shift_age || @shift_age || 7 + @shift_size = shift_size || @shift_size || 1048576 + @shift_period_suffix = shift_period_suffix || @shift_period_suffix || '%Y%m%d' + + unless @shift_age.is_a?(Integer) + base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now + @next_rotate_time = next_rotate_time(base_time, @shift_age) + end + end + + if MODE_TO_OPEN == MODE + def fixup_mode(dev) + dev + end + else + def fixup_mode(dev) + return dev if @binmode + dev.autoclose = false + old_dev = dev + dev = File.new(dev.fileno, mode: MODE, path: dev.path) + old_dev.close + PathAttr.set_path(dev, filename) if defined?(PathAttr) + dev + end + end + + def open_logfile(filename) + begin + dev = File.open(filename, MODE_TO_OPEN) + rescue Errno::ENOENT + create_logfile(filename) + else + dev = fixup_mode(dev) + dev.sync = true + dev.binmode if @binmode + dev + end + end + + def create_logfile(filename) + begin + logdev = File.open(filename, MODE_TO_CREATE) + logdev.flock(File::LOCK_EX) + logdev = fixup_mode(logdev) + logdev.sync = true + logdev.binmode if @binmode + add_log_header(logdev) unless @skip_header + logdev.flock(File::LOCK_UN) + logdev + rescue Errno::EEXIST + # file is created by another process + open_logfile(filename) + end + end + + def handle_write_errors(mesg) + yield + rescue *@reraise_write_errors + raise + rescue + warn("log #{mesg} failed. #{$!}") + end + + def add_log_header(file) + file.write( + "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName] + ) if file.size == 0 + end + + def check_shift_log + if @shift_age.is_a?(Integer) + # Note: always returns false if '0'. + if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size) + lock_shift_log { shift_log_age } + end + else + now = Time.now + if now >= @next_rotate_time + @next_rotate_time = next_rotate_time(now, @shift_age) + lock_shift_log { shift_log_period(previous_period_end(now, @shift_age)) } + end + end + end + + def lock_shift_log + retry_limit = 8 + retry_sleep = 0.1 + begin + File.open(@filename, MODE_TO_OPEN) do |lock| + lock.flock(File::LOCK_EX) # inter-process locking. will be unlocked at closing file + if File.identical?(@filename, lock) and File.identical?(lock, @dev) + yield # log shifting + else + # log shifted by another process (i-node before locking and i-node after locking are different) + @dev.close rescue nil + @dev = open_logfile(@filename) + end + end + true + rescue Errno::ENOENT + # @filename file would not exist right after #rename and before #create_logfile + if retry_limit <= 0 + warn("log rotation inter-process lock failed. #{$!}") + else + sleep retry_sleep + retry_limit -= 1 + retry_sleep *= 2 + retry + end + end + rescue + warn("log rotation inter-process lock failed. #{$!}") + end + + def shift_log_age + (@shift_age-3).downto(0) do |i| + if FileTest.exist?("#{@filename}.#{i}") + File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}") + end + end + shift_log_file("#{@filename}.0") + end + + def shift_log_period(period_end) + suffix = period_end.strftime(@shift_period_suffix) + age_file = "#{@filename}.#{suffix}" + if FileTest.exist?(age_file) + # try to avoid filename crash caused by Timestamp change. + idx = 0 + # .99 can be overridden; avoid too much file search with 'loop do' + while idx < 100 + idx += 1 + age_file = "#{@filename}.#{suffix}.#{idx}" + break unless FileTest.exist?(age_file) + end + end + shift_log_file(age_file) + end + + def shift_log_file(shifted) + stat = @dev.stat + @dev.close rescue nil + File.rename(@filename, shifted) + @dev = create_logfile(@filename) + mode, uid, gid = stat.mode, stat.uid, stat.gid + begin + @dev.chmod(mode) if mode + mode = nil + @dev.chown(uid, gid) + rescue Errno::EPERM + if mode + # failed to chmod, probably nothing can do more. + elsif uid + uid = nil + retry # to change gid only + end + end + return true + end + end +end + +File.open(__FILE__) do |f| + File.new(f.fileno, autoclose: false, path: "").path +rescue IOError + module PathAttr # :nodoc: + attr_reader :path + + def self.set_path(file, path) + file.extend(self).instance_variable_set(:@path, path) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb new file mode 100644 index 0000000..a0359de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +class Logger + module Period + module_function + + SiD = 24 * 60 * 60 + + def next_rotate_time(now, shift_age) + case shift_age + when 'daily', :daily + t = Time.mktime(now.year, now.month, now.mday) + SiD + when 'weekly', :weekly + t = Time.mktime(now.year, now.month, now.mday) + SiD * (7 - now.wday) + when 'monthly', :monthly + t = Time.mktime(now.year, now.month, 1) + SiD * 32 + return Time.mktime(t.year, t.month, 1) + when 'now', 'everytime', :now, :everytime + return now + else + raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime" + end + if t.hour.nonzero? or t.min.nonzero? or t.sec.nonzero? + hour = t.hour + t = Time.mktime(t.year, t.month, t.mday) + t += SiD if hour > 12 + end + t + end + + def previous_period_end(now, shift_age) + case shift_age + when 'daily', :daily + t = Time.mktime(now.year, now.month, now.mday) - SiD / 2 + when 'weekly', :weekly + t = Time.mktime(now.year, now.month, now.mday) - (SiD * now.wday + SiD / 2) + when 'monthly', :monthly + t = Time.mktime(now.year, now.month, 1) - SiD / 2 + when 'now', 'everytime', :now, :everytime + return now + else + raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime" + end + Time.mktime(t.year, t.month, t.mday, 23, 59, 59) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb new file mode 100644 index 0000000..e96fb0d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +class Logger + # Logging severity. + module Severity + # Low-level information, mostly for developers. + DEBUG = 0 + # Generic (useful) information about system operation. + INFO = 1 + # A warning. + WARN = 2 + # A handleable error condition. + ERROR = 3 + # An unhandleable error that results in a program crash. + FATAL = 4 + # An unknown message that should always be logged. + UNKNOWN = 5 + + LEVELS = { + "debug" => DEBUG, + "info" => INFO, + "warn" => WARN, + "error" => ERROR, + "fatal" => FATAL, + "unknown" => UNKNOWN, + } + private_constant :LEVELS + + def self.coerce(severity) + if severity.is_a?(Integer) + severity + else + key = severity.to_s.downcase + LEVELS[key] || raise(ArgumentError, "invalid log level: #{severity}") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb new file mode 100644 index 0000000..0d74bec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Logger + VERSION = "1.7.0" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/.yardopts b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/.yardopts new file mode 100644 index 0000000..0a782de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/.yardopts @@ -0,0 +1 @@ +--title 'Ruby Public Suffix API Documentation' diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/CHANGELOG.md new file mode 100644 index 0000000..49347e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/CHANGELOG.md @@ -0,0 +1,649 @@ +# Changelog + + +## 7.0.5 - 2026-03-03 + +### Fixed + +- Fix release crash caused by unconditional rubocop/yard requires in Rakefile. + + +## 7.0.4 - 2026-03-03 + +### Fixed + +- Fix release workflow. + + +## 7.0.3 - 2026-03-03 + +### Changed + +- Updated definitions. + + +## 7.0.2 - 2026-01-04 + +### Changed + +- Excluded symlinks and unnecessary files from gem packaging. On Windows symlinks cannot be created without Administrator privileges or with developer mode enabled #496. + + +## 7.0.1 - 2026-01-03 + +### Changed + +- Updated definitions. + + +## 7.0.0 - 2024-11-17 + +### Changed + +- Updated definitions. +- Minimum Ruby version is 3.2 + + +## 6.0.2 - 2024-04-30 + +### Changed + +- Updated definitions. + + +## 6.0.1 - 2024-07-23 + +### Changed + +- Updated definitions. + + +## 6.0.0 - 2024-06-17 + +Same as 5.1.0. Re-releasing as a major version change due to a major ruby version requirement change. + +### Changed + +- Updated definitions. +- Minimum Ruby version is 3.0 + + +## 5.1.1 - 2024-06-17 + +No significant changes. Releasing a mini version to address 5.1.0 release with major ruby requirement change #315. + + +## 5.1.0 - 2024-06-15 + +### Changed + +- Updated definitions. +- Minimum Ruby version is 3.0 + + +## 5.0.5 - 2024-04-02 + +### Changed + +- Updated definitions. + + +## 5.0.4 - 2023-11-17 + +### Changed + +- Reduced .gem file size #258. (Thanks @ybiquitous) +- Updated definitions. + + +## 5.0.3 - 2023-07-11 + +### Fixed + +- Fixed automated release workflow. + + +## 5.0.2 - 2023-07-11 + +### Changed + +- Updated definitions. + + +## 5.0.1 - 2022-12-07 + +### Changed + +- Updated definitions. + + +## 5.0.0 - 2022-07-24 + +### Changed + +- Minimum Ruby version is 2.6 +- Updated definitions. + + +## 4.0.7 - 2022-04-12 + +### Fixed + +- Fixed YARD rake task #179 + +### Changed + +- Updated definitions. + + +## 4.0.6 - 2020-09-02 + +### Changed + +- Updated definitions. + + +## 4.0.5 - 2020-05-09 + +### Changed + +- Updated definitions. + + +## 4.0.4 - 2020-04-05 + +### Changed + +- Updated definitions. + + +## 4.0.3 - 2020-01-05 + +### Fixed + +- Fixed 2.7 deprecations and warnings #167. (Thanks @BrianHawley) + + +## 4.0.2 - 2019-12-27 + +### Changed + +- Updated definitions. + + +## 4.0.1 - 2019-08-09 + +### Changed + +- Updated definitions. + + +## 4.0.0 - 2019-06-25 + +### Changed + +- Minimum Ruby version is 2.3 + + +## 3.1.1 - 2019-06-25 + +IMPORTANT: 3.x is the latest version compatible with Ruby 2.1 and Ruby 2.2. + +### Changed + +- Updated definitions. +- Rolled back support for Ruby 2.3 #161, #162 + + +## 3.1.0 - 2019-05-27 + +### Changed + +- Updated definitions. +- Minimum Ruby version is 2.3 +- Upgraded to Bundler 2.x + + +## 3.0.3 - 2018-08-15 + +### Changed + +- Updated definitions. + + +## 3.0.2 - 2018-02-12 + +### Changed + +- Updated definitions. + + +## 3.0.1 - 2017-11-08 + +### Changed + +- Updated definitions. +- Improve performance and avoid allocation #146. (Thanks @robholland) + + +## 3.0.0 - 2017-08-04 + +This new version includes a major redesign of the library internals, with the goal to drastically improve the lookup time while reducing storage space. + +For this reason, several public methods that are no longer applicable have been deprecated and/or removed. You can find more information at #133. + +### Changed + +- Updated definitions. +- Dropped support for Ruby < 2.1 +- `PublicSuffix::List#rules` is now protected. You should not rely on it as the internal rule representation is subject to change to optimize performances. +- Removed `PublicSuffix::List.clear`, it was an unnecessary accessor method. Use `PublicSuffix::List.default = nil` if you **really** need to reset the default list. You shouldn't. +- `PublicSuffix::List#select` is now private. You should not use it, instead use `PublicSuffix::List#find`. +- `PublicSuffix::List` no longer implements Enumerable. Instead, use `#each` to loop over, or get an Enumerator. +- Redesigned internal list storage and lookup algorithm to achieve O(1) lookup time (see #133). + + +## 2.0.5 - 2017-01-02 + +### Changed + +- Updated definitions. +- Initialization performance improvements #128. (Thanks @casperisfine) + + +## 2.0.4 - 2016-11-07 + +### Fixed + +- Fixed a bug that caused the GEM to be published with the wrong version number in the gemspec #121. + +### Changed + +- Updated definitions. + + +## 2.0.3 - 2016-09-30 + +### Changed + +- Updated definitions. + + +## 2.0.2 - 2016-06-10 + +### Changed + +- Updated definitions. + + +## 2.0.1 - 2016-05-22 + +### Fixed + +- Fix bug that prevented .valid? to reset the default rule + + +## 2.0.0 - 2016-05-20 + +### Added + +- Added PublicSuffix.domain # => sld.tld +- Added the ability to disable the use of private domains either at runtime, in addition to the ability to not load the private domains section when reading the list (`private_domains: false`). This feature also superseded the `private_domains` class-level attribute, that is no longer available. + +### Changed + +- Considerable performance improvements #92 +- Updated definitions. +- Removed deprecated PublicSuffix::InvalidDomain exception +- If the suffix is now listed, then the prevaling rule is "*" as defined by the PSL algorithm #91 +- Input validation is performed only if you call `PublicSuffix.parse` or `PublicSuffix.list` +- Input with leading dot is invalid per PSL acceptance tests +- Removed `private_domains` class-level attribute. It is replaced by the `private_domains: false` option in the list parse method. +- The default list now assumes you use UTF-8 for reading the input #94, + +### Removed + +- Removed futile utility helpers such as `Domain#rule`, `Domain#is_a_domain?`, `Domain#is_a_subdomain?`, `Domain#valid?`. You can easily obtain the same result by having a custom method that reconstructs the logic, and/or calling `PublicSuffix.{domain|parse}(domain.to_s)`. + + +## 1.5.3 - 2015-12-14 + +### Fixed + +- Don't duplicate rule indices when creating index #77. (Thanks @ags) + +### Changed + +- Updated definitions. + + +## 1.5.2 - 2015-10-27 + +### Changed + +- Updated definitions. + + +## 1.5.1 - 2015-04-10 + +### Fixed + +- Ignore case for parsing and validating #62 + +### Changed + +- Updated definitions. + + +## 1.5.0 - 2015-03-24 + +### Changed + +- Dropped support for Ruby < 2.0 +- Updated definitions. + + +## 1.4.6 - 2014-09-10 + +### Changed + +- Updated definitions. + + +## 1.4.5 - 2014-08-18 + +### Changed + +- Updated definitions. + + +## 1.4.4 - 2014-06-17 + +### Changed + +- Updated definitions. + + +## 1.4.3 - 2014-06-12 + +### Changed + +- Updated definitions. + + +## 1.4.2 - 2014-03-10 + +### Changed + +- Updated definitions. + + +## 1.4.1 - 2014-03-07 + +### Changed + +- Updated definitions. + + +## 1.4.0 - 2014-02-01 + +### Changed + +- Moved the definitions in the lib folder. +- Updated definitions. + + +## 1.3.3 - 2013-12-01 + +### Changed + +- Updated definitions. + + +## 1.3.2 - 2013-11-11 + +### Changed + +- Updated definitions. + + +## 1.3.1 - 2013-08-09 + +### Changed + +- Updated definitions. + + +## 1.3.0 - 2013-04-03 + +### Added + +- Ability to skip Private Domains #28. (Thanks @rb2k) + +### Changed + +- Updated definitions. + + +## 1.2.1 - 2013-03-26 + +### Changed + +- Updated definitions. + + +## 1.2.0 - 2012-12-24 + +### Added + +- Allow a custom List on `PublicSuffix.parse` #26. (Thanks @itspriddle) + +### Fixed + +- PublicSuffix.parse and PublicSuffix.valid? crashes when input is nil #20. + +### Changed + +- Updated definitions. + + +## 1.1.3 - 2012-09-17 + +### Changed + +- Updated definitions. + + +## 1.1.2 - 2012-09-03 + +### Changed + +- Updated definitions. + + +## 1.1.1 - 2012-06-26 + +### Changed + +- Updated definitions. + + +## 1.1.0 - 2012-03-16 + +### Fixed + +- #valid? and #parse consider URIs as valid domains #15 + +### Changed + +- Updated definitions. +- Removed deprecatd PublicSuffixService::RuleList. + + +## 1.0.0 - 2011-12-24 + +### Changed + +- Updated definitions. + + +## 1.0.0.rc1 - 2011-12-24 + +The library is now known as PublicSuffix. + + +## 0.9.1 - 2011-12-24 + +### Changed + +- Renamed PublicSuffixService::RuleList to PublicSuffixService::List. +- Renamed PublicSuffixService::List#list to PublicSuffixService::List#rules. +- Renamed PublicSuffixService to PublicSuffix. +- Updated definitions. + + +## 0.9.0 - 2011-06-17 + +### Changed + +- Minimum Ruby version increased to Ruby 1.8.7. +- rake/gempackagetask is deprecated. Use rubygems/package_task instead. + + +## 0.8.4 - 2011-06-17 + +### Fixed + +- Reverted bugfix for issue #12 for Ruby 1.8.6. This is the latest version compatible with Ruby 1.8.6. + + +## 0.8.3 - 2011-05-27 + +### Fixed + +- Fixed ArgumentError: invalid byte sequence in US-ASCII with Ruby 1.9.2 (#12). + +### Changed + +- Updated definitions (#11). +- Renamed definitions.txt to definitions.dat. + + +## 0.8.2 - 2011-03-11 + +### Added + +- Added support for rubygems-test. + +### Changed + +- Integrated Bundler. +- Updated definitions. + + +## 0.8.1 - 2010-12-07 + +### Fixed + +- The files in the release 0.8.0 have wrong permission 600 and can't be loaded #10. + + +## 0.8.0 - 2010-12-05 + +### Added + +- Add support for Fully Qualified Domain Names #7 + +### Changed + +- Update public suffix list to d1a5599b49fa 2010-10-25 15:10 +0100 #9 + + +## 0.7.0 - 2010-10-09 + +### Fixed + +- RuleList cache is not recreated when a new rule is appended to the list #6 +- PublicSuffixService.valid? should return false if the domain is not defined or not allowed #4, #5 + +### Changed + +- Using YARD to document the code instead of RDoc. + + +## 0.6.0 - 2010-09-18 + +### Added + +- PublicSuffixService.parse raises DomainNotAllowed when trying to parse a domain name which exists, but is not allowed by the current definition list #3 + + PublicSuffixService.parse("nic.do") + # => PublicSuffixService::DomainNotAllowed + +### Changed + +- Renamed PublicSuffixService::InvalidDomain to PublicSuffixService::DomainInvalid + + +## 0.5.2 - 2010-09-17 + +### Changed + +- Update public suffix list to 248ea690d671 2010-09-16 18:02 +0100 + + +## 0.5.1 - 2010-09-15 + +### Changed + +- Update public suffix list to 14dc66dd53c1 2010-09-15 17:09 +0100 + + +## 0.5.0 - 2010-09-13 + +### Changed + +- Improve documentation for Domain#domain and Domain#subdomain #1. +- Performance improvements #2. + + +## 0.4.0 - 2010-05-31 + +### Changed + +- Rename library from DomainName to PublicSuffixService to reduce the probability of name conflicts. + + +## 0.3.1 - 2010-05-31 + +### Changed + +- Deprecated DomainName library. + + +## 0.3.0 - 2010-05-31 + +### Changed + +- DomainName#domain and DomainName#subdomain are no longer alias of Domain#sld and Domain#tld. +- Removed DomainName#labels and decoupled Rule from DomainName. +- DomainName#valid? no longer instantiates new DomainName objects. This means less overhead. +- Refactoring the entire DomainName API. Removed the internal on-the-fly parsing. Added a bunch of new methods to check and validate the DomainName. + + +## 0.2.0 - 2010-05-31 + +### Added + +- DomainName#valid? +- DomainName#parse and DomainName#parse! +- DomainName#valid_domain? and DomainName#valid_subdomain? + +### Changed + +- Make sure RuleList lookup is only performed once. + + +## 0.1.0 - 2010-05-31 + +- Initial version diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/Gemfile b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/Gemfile new file mode 100644 index 0000000..a498957 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/Gemfile @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gemspec + +gem "rake" + +gem "memory_profiler", require: false +gem "minitest" +gem "minitest-reporters" +gem "mocha", "~> 3.0.1" +gem "rubocop", "~> 1.85.0", require: false +gem "rubocop-minitest", require: false +gem "rubocop-rake", require: false +gem "yard" diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/LICENSE.txt new file mode 100644 index 0000000..2d60588 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2009-2026 Simone Carletti + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/README.md b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/README.md new file mode 100644 index 0000000..05ae1d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/README.md @@ -0,0 +1,231 @@ +# PublicSuffix for Ruby + +`PublicSuffix` is a Ruby domain name parser based on the [Public Suffix List](https://publicsuffix.org/). + +[![Build Status](https://github.com/weppos/publicsuffix-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/weppos/publicsuffix-ruby/actions/workflows/tests.yml) +[![Tidelift dependencies](https://tidelift.com/badges/package/rubygems/public_suffix)](https://tidelift.com/subscription/pkg/rubygems-public-suffix?utm_source=rubygems-public-suffix&utm_medium=referral&utm_campaign=enterprise) + + +## Links + +- [Homepage](https://simonecarletti.com/code/publicsuffix-ruby) +- [Repository](https://github.com/weppos/publicsuffix-ruby) +- [API Documentation](https://rubydoc.info/gems/public_suffix) +- [Introducing the Public Suffix List library for Ruby](https://simonecarletti.com/blog/2010/06/public-suffix-list-library-for-ruby/) + + +## Requirements + +`PublicSuffix` requires **Ruby >= 3.2**. For older versions of Ruby, use a previous release. + + +## Installation + +You can install the gem manually: + +```shell +gem install public_suffix +``` + +Or use Bundler and define it as a dependency in your `Gemfile`: + +```ruby +gem 'public_suffix' +``` + +## Usage + +Extract the domain out from a name: + +```ruby +PublicSuffix.domain("google.com") +# => "google.com" +PublicSuffix.domain("www.google.com") +# => "google.com" +PublicSuffix.domain("www.google.co.uk") +# => "google.co.uk" +``` + +Parse a domain without subdomains: + +```ruby +domain = PublicSuffix.parse("google.com") +# => # +domain.tld +# => "com" +domain.sld +# => "google" +domain.trd +# => nil +domain.domain +# => "google.com" +domain.subdomain +# => nil +``` + +Parse a domain with subdomains: + +```ruby +domain = PublicSuffix.parse("www.google.com") +# => # +domain.tld +# => "com" +domain.sld +# => "google" +domain.trd +# => "www" +domain.domain +# => "google.com" +domain.subdomain +# => "www.google.com" +``` + +Simple validation example: + +```ruby +PublicSuffix.valid?("google.com") +# => true + +PublicSuffix.valid?("www.google.com") +# => true + +# Explicitly forbidden, it is listed as a private domain +PublicSuffix.valid?("blogspot.com") +# => false + +# Unknown/not-listed TLD domains are valid by default +PublicSuffix.valid?("example.tldnotlisted") +# => true +``` + +Strict validation (without applying the default * rule): + +```ruby +PublicSuffix.valid?("example.tldnotlisted", default_rule: nil) +# => false +``` + + +## Fully qualified domain names + +This library automatically recognizes Fully Qualified Domain Names. A FQDN is a domain name that ends with a trailing dot. + +```ruby +# Parse a standard domain name +PublicSuffix.domain("www.google.com") +# => "google.com" + +# Parse a fully qualified domain name +PublicSuffix.domain("www.google.com.") +# => "google.com" +``` + +## Private domains + +This library supports toggling private (non-ICANN) domain handling. + +```ruby +# Extract a domain including private domains (by default) +PublicSuffix.domain("something.blogspot.com") +# => "something.blogspot.com" + +# Extract a domain excluding private domains +PublicSuffix.domain("something.blogspot.com", ignore_private: true) +# => "blogspot.com" + +# It also works for #parse and #valid? +PublicSuffix.parse("something.blogspot.com", ignore_private: true) +PublicSuffix.valid?("something.blogspot.com", ignore_private: true) +``` + +If you don't care about private domains at all, it's more efficient to exclude them when the list is parsed: + +```ruby +# Disable support for private TLDs +PublicSuffix::List.default = PublicSuffix::List.parse(File.read(PublicSuffix::List::DEFAULT_LIST_PATH), private_domains: false) +# => "blogspot.com" +PublicSuffix.domain("something.blogspot.com") +# => "blogspot.com" +``` + +## Adding custom domains + +To manually add a domain to the list: + +```ruby +PublicSuffix::List.default << PublicSuffix::Rule.factory('onmicrosoft.com') +``` + +## What is the public suffix list? + +The [Public Suffix List](https://publicsuffix.org) is a cross-vendor initiative to provide an accurate list of domain name suffixes. + +The Public Suffix List is an initiative of the Mozilla Project, but is maintained as a community resource. It is available for use in any software, but was originally created to meet the needs of browser manufacturers. + +A "public suffix" is one under which Internet users can directly register names. Some examples of public suffixes are ".com", ".co.uk" and "pvt.k12.wy.us". The Public Suffix List is a list of all known public suffixes. + + +## Why use the public suffix list instead of regular expressions? + +Previously, browsers used an algorithm which basically only denied setting wide-ranging cookies for top-level domains with no dots (e.g. com or org). However, this did not work for top-level domains where only third-level registrations are allowed (e.g. co.uk). In these cases, websites could set a cookie for co.uk which will be passed onto every website registered under co.uk. + +Clearly, this was a security risk as it allowed websites other than the one setting the cookie to read it, and therefore potentially extract sensitive information. + +Since there is no algorithmic method of finding the highest level at which a domain may be registered for a particular top-level domain (the policies differ with each registry), the only method is to create a list of all top-level domains and the level at which domains can be registered. This is the aim of the effective TLD list. + +As well as being used to prevent cookies from being set where they shouldn't be, the list can also potentially be used for other applications where the registry controlled and privately controlled parts of a domain name need to be known, for example when grouping by top-level domains. + +Source: https://wiki.mozilla.org/Public_Suffix_List + +Not convinced yet? Check out [this real world example](https://stackoverflow.com/q/288810/123527). + + +## Does PublicSuffix make network requests? + +No. `PublicSuffix` comes with a bundled list. It does not make any HTTP requests to parse or validate a domain. + + +## Terminology + +- **TLD** (Top-Level Domain): The last segment of a domain name. For example, in `mozilla.org`, the `.org` portion is the TLD. + +- **SLD** (Second-Level Domain): A domain directly below a top-level domain. For example, in `https://www.mozilla.org/en-US/`, `mozilla` is the second-level domain of the `.org` TLD. + +- **TRD** (Third-Level Domain): Also known as a subdomain, this is the part of the domain before the SLD or root domain. For example, in `https://www.mozilla.org/en-US/`, `www` is the TRD. + +- **FQDN** (Fully Qualified Domain Name): A complete domain name that includes the hostname, domain, and top-level domain, ending with a trailing dot. The format is `[hostname].[domain].[tld].` (e.g., `www.mozilla.org.`). + + +## Documentation and support + +### Documentation + +Library documentation is auto-generated from the [README](https://github.com/weppos/publicsuffix-ruby/blob/master/README.md) and source code, and is available at https://rubydoc.info/gems/public_suffix. + +### Bug reports and contributions + +- **Bug Tracker**: https://github.com/weppos/publicsuffix-ruby/issues +- **Code Repository**: https://github.com/weppos/publicsuffix-ruby + +Contributions are welcome! Please include tests and/or feature coverage for every patch, and create a topic branch for every separate change you make. + +### Enterprise support + +[Consider subscribing to Tidelift](https://tidelift.com/subscription/pkg/rubygems-public-suffix?utm_source=rubygems-public-suffix&utm_medium=referral&utm_campaign=readme), which provides enterprise support for this project as part of the Tidelift Subscription. Tidelift subscriptions help fund the project, allowing us to ship releases, bugfixes, and security updates more frequently. + + +## Security and vulnerability reporting + +For full information and details about our security policy, please visit [`SECURITY.md`](SECURITY.md). + + +## Changelog + +See [CHANGELOG.md](CHANGELOG.md) for details. + + +## License + +Copyright (c) 2009-2026 Simone Carletti. [MIT License](LICENSE.txt). + +The [Public Suffix List source](https://publicsuffix.org/list/) is subject to the terms of the Mozilla Public License, v. 2.0. diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/SECURITY.md b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/SECURITY.md new file mode 100644 index 0000000..da6e619 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/SECURITY.md @@ -0,0 +1,24 @@ +# Security Policy + +## Supported Versions + +Security updates are provided only for the current minor version. + +If you are using a previous minor version, we recommend to upgrade to the current minor version. This project uses [semantic versioning](https://semver.org/), therefore you can upgrade to a more recent minor version without incurring into breaking changes. + +Exceptionally, we may support previous minor versions upon request if there are significant reasons preventing to immediately switch the latest minor version. + +Older major versions are no longer supported. + + +## Reporting a Vulnerability + +To make a report, please email weppos@weppos.net. + +> [!IMPORTANT] +> Please consider encrypting your report with GPG using the key [0x420da82a989398df](https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x420da82a989398df). + + +## Tracking Security Updates + +Information about security vulnerabilities are published in the [Security Advisories](https://github.com/weppos/publicsuffix-ruby/security/advisories) page. diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/data/list.txt b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/data/list.txt new file mode 100644 index 0000000..3476dc9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/data/list.txt @@ -0,0 +1,16298 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, +// rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. + +// Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. + +// ===BEGIN ICANN DOMAINS=== + +// ac : http://nic.ac/rules.htm +ac +com.ac +edu.ac +gov.ac +mil.ac +net.ac +org.ac + +// ad : https://www.iana.org/domains/root/db/ad.html +// Confirmed by Amadeu Abril i Abril (CORE) 2024-11-17 +ad + +// ae : https://www.iana.org/domains/root/db/ae.html +ae +ac.ae +co.ae +gov.ae +mil.ae +net.ae +org.ae +sch.ae + +// aero : https://information.aero/registration/policies/dmp +aero +// 2LDs +airline.aero +airport.aero +// 2LDs (currently not accepting registration, seemingly never have) +// As of 2024-07, these are marked as reserved for potential 3LD +// registrations (clause 11 "allocated subdomains" in the 2006 TLD +// policy), but the relevant industry partners have not opened them up +// for registration. Current status can be determined from the TLD's +// policy document: 2LDs that are open for registration must list +// their policy in the TLD's policy. Any 2LD without such a policy is +// not open for registrations. +accident-investigation.aero +accident-prevention.aero +aerobatic.aero +aeroclub.aero +aerodrome.aero +agents.aero +air-surveillance.aero +air-traffic-control.aero +aircraft.aero +airtraffic.aero +ambulance.aero +association.aero +author.aero +ballooning.aero +broker.aero +caa.aero +cargo.aero +catering.aero +certification.aero +championship.aero +charter.aero +civilaviation.aero +club.aero +conference.aero +consultant.aero +consulting.aero +control.aero +council.aero +crew.aero +design.aero +dgca.aero +educator.aero +emergency.aero +engine.aero +engineer.aero +entertainment.aero +equipment.aero +exchange.aero +express.aero +federation.aero +flight.aero +freight.aero +fuel.aero +gliding.aero +government.aero +groundhandling.aero +group.aero +hanggliding.aero +homebuilt.aero +insurance.aero +journal.aero +journalist.aero +leasing.aero +logistics.aero +magazine.aero +maintenance.aero +marketplace.aero +media.aero +microlight.aero +modelling.aero +navigation.aero +parachuting.aero +paragliding.aero +passenger-association.aero +pilot.aero +press.aero +production.aero +recreation.aero +repbody.aero +res.aero +research.aero +rotorcraft.aero +safety.aero +scientist.aero +services.aero +show.aero +skydiving.aero +software.aero +student.aero +taxi.aero +trader.aero +trading.aero +trainer.aero +union.aero +workinggroup.aero +works.aero + +// af : https://www.nic.af/domain-price +af +com.af +edu.af +gov.af +net.af +org.af + +// ag : http://www.nic.ag/prices.htm +ag +co.ag +com.ag +net.ag +nom.ag +org.ag + +// ai : http://nic.com.ai/ +ai +com.ai +net.ai +off.ai +org.ai + +// al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31 +al +com.al +edu.al +gov.al +mil.al +net.al +org.al + +// am : https://www.amnic.net/policy/en/Policy_EN.pdf +// Confirmed by ISOC AM 2024-11-18 +am +co.am +com.am +commune.am +net.am +org.am + +// ao : https://www.iana.org/domains/root/db/ao.html +// https://www.dns.ao/ao/ +ao +co.ao +ed.ao +edu.ao +gov.ao +gv.ao +it.ao +og.ao +org.ao +pb.ao + +// aq : https://www.iana.org/domains/root/db/aq.html +aq + +// ar : https://nic.ar/es/nic-argentina/normativa +ar +bet.ar +com.ar +coop.ar +edu.ar +gob.ar +gov.ar +int.ar +mil.ar +musica.ar +mutual.ar +net.ar +org.ar +seg.ar +senasa.ar +tur.ar + +// arpa : https://www.iana.org/domains/root/db/arpa.html +// Confirmed by registry 2008-06-18 +arpa +e164.arpa +home.arpa +in-addr.arpa +ip6.arpa +iris.arpa +uri.arpa +urn.arpa + +// as : https://www.iana.org/domains/root/db/as.html +as +gov.as + +// asia : https://www.iana.org/domains/root/db/asia.html +asia + +// at : https://www.iana.org/domains/root/db/at.html +// Confirmed by registry 2008-06-17 +at +ac.at +sth.ac.at +co.at +gv.at +or.at + +// au : https://www.iana.org/domains/root/db/au.html +// https://www.auda.org.au/ +// Confirmed by registry 2025-07-16 +au +// 2LDs +asn.au +com.au +edu.au +gov.au +id.au +net.au +org.au +// Historic 2LDs (closed to new registration, but sites still exist) +conf.au +oz.au +// CGDNs : https://www.auda.org.au/au-domain-names/the-different-au-domain-names/state-and-territory-domain-names/ +act.au +nsw.au +nt.au +qld.au +sa.au +tas.au +vic.au +wa.au +// 3LDs +act.edu.au +catholic.edu.au +// eq.edu.au - Removed at the request of the Queensland Department of Education +nsw.edu.au +nt.edu.au +qld.edu.au +sa.edu.au +tas.edu.au +vic.edu.au +wa.edu.au +// act.gov.au - Bug 984824 - Removed at request of Greg Tankard +// nsw.gov.au - Bug 547985 - Removed at request of +// nt.gov.au - Bug 940478 - Removed at request of Greg Connors +qld.gov.au +sa.gov.au +tas.gov.au +vic.gov.au +wa.gov.au +// 4LDs +// education.tas.edu.au - Removed at the request of the Department of Education Tasmania +// schools.nsw.edu.au - Removed at the request of the New South Wales Department of Education. + +// aw : https://www.iana.org/domains/root/db/aw.html +aw +com.aw + +// ax : https://www.iana.org/domains/root/db/ax.html +ax + +// az : https://www.iana.org/domains/root/db/az.html +// Confirmed via https://whois.az/?page_id=10 2024-12-11 +az +biz.az +co.az +com.az +edu.az +gov.az +info.az +int.az +mil.az +name.az +net.az +org.az +pp.az +// No longer available for registration, however domains exist as of 2024-12-11 +// see https://whois.az/?page_id=783 +pro.az + +// ba : https://www.iana.org/domains/root/db/ba.html +ba +com.ba +edu.ba +gov.ba +mil.ba +net.ba +org.ba + +// bb : https://www.iana.org/domains/root/db/bb.html +bb +biz.bb +co.bb +com.bb +edu.bb +gov.bb +info.bb +net.bb +org.bb +store.bb +tv.bb + +// bd : https://www.iana.org/domains/root/db/bd.html +// Confirmed by registry +bd +ac.bd +ai.bd +co.bd +com.bd +edu.bd +gov.bd +id.bd +info.bd +it.bd +mil.bd +net.bd +org.bd +sch.bd +tv.bd + +// be : https://www.iana.org/domains/root/db/be.html +// Confirmed by registry 2008-06-08 +be +ac.be + +// bf : https://www.iana.org/domains/root/db/bf.html +bf +gov.bf + +// bg : https://www.iana.org/domains/root/db/bg.html +// https://www.register.bg/user/static/rules/en/index.html +bg +0.bg +1.bg +2.bg +3.bg +4.bg +5.bg +6.bg +7.bg +8.bg +9.bg +a.bg +b.bg +c.bg +d.bg +e.bg +f.bg +g.bg +h.bg +i.bg +j.bg +k.bg +l.bg +m.bg +n.bg +o.bg +p.bg +q.bg +r.bg +s.bg +t.bg +u.bg +v.bg +w.bg +x.bg +y.bg +z.bg + +// bh : https://www.iana.org/domains/root/db/bh.html +bh +com.bh +edu.bh +gov.bh +net.bh +org.bh + +// bi : https://www.iana.org/domains/root/db/bi.html +// http://whois.nic.bi/ +bi +co.bi +com.bi +edu.bi +or.bi +org.bi + +// biz : https://www.iana.org/domains/root/db/biz.html +biz + +// bj : https://nic.bj/bj-suffixes.txt +// Submitted by registry +bj +africa.bj +agro.bj +architectes.bj +assur.bj +avocats.bj +co.bj +com.bj +eco.bj +econo.bj +edu.bj +info.bj +loisirs.bj +money.bj +net.bj +org.bj +ote.bj +restaurant.bj +resto.bj +tourism.bj +univ.bj + +// bm : https://www.bermudanic.bm/domain-registration/index.php +bm +com.bm +edu.bm +gov.bm +net.bm +org.bm + +// bn : http://www.bnnic.bn/faqs +bn +com.bn +edu.bn +gov.bn +net.bn +org.bn + +// bo : https://nic.bo +// Confirmed by registry 2024-11-19 +bo +com.bo +edu.bo +gob.bo +int.bo +mil.bo +net.bo +org.bo +tv.bo +web.bo +// Social Domains +academia.bo +agro.bo +arte.bo +blog.bo +bolivia.bo +ciencia.bo +cooperativa.bo +democracia.bo +deporte.bo +ecologia.bo +economia.bo +empresa.bo +indigena.bo +industria.bo +info.bo +medicina.bo +movimiento.bo +musica.bo +natural.bo +nombre.bo +noticias.bo +patria.bo +plurinacional.bo +politica.bo +profesional.bo +pueblo.bo +revista.bo +salud.bo +tecnologia.bo +tksat.bo +transporte.bo +wiki.bo + +// br : http://registro.br/dominio/categoria.html +// Submitted by registry +br +9guacu.br +abc.br +adm.br +adv.br +agr.br +aju.br +am.br +anani.br +aparecida.br +api.br +app.br +arq.br +art.br +ato.br +b.br +barueri.br +belem.br +bet.br +bhz.br +bib.br +bio.br +blog.br +bmd.br +boavista.br +bsb.br +campinagrande.br +campinas.br +caxias.br +cim.br +cng.br +cnt.br +com.br +contagem.br +coop.br +coz.br +cri.br +cuiaba.br +curitiba.br +def.br +des.br +det.br +dev.br +ecn.br +eco.br +edu.br +emp.br +enf.br +eng.br +esp.br +etc.br +eti.br +far.br +feira.br +flog.br +floripa.br +fm.br +fnd.br +fortal.br +fot.br +foz.br +fst.br +g12.br +geo.br +ggf.br +goiania.br +gov.br +// gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil +ac.gov.br +al.gov.br +am.gov.br +ap.gov.br +ba.gov.br +ce.gov.br +df.gov.br +es.gov.br +go.gov.br +ma.gov.br +mg.gov.br +ms.gov.br +mt.gov.br +pa.gov.br +pb.gov.br +pe.gov.br +pi.gov.br +pr.gov.br +rj.gov.br +rn.gov.br +ro.gov.br +rr.gov.br +rs.gov.br +sc.gov.br +se.gov.br +sp.gov.br +to.gov.br +gru.br +ia.br +imb.br +ind.br +inf.br +jab.br +jampa.br +jdf.br +joinville.br +jor.br +jus.br +leg.br +leilao.br +lel.br +log.br +londrina.br +macapa.br +maceio.br +manaus.br +maringa.br +mat.br +med.br +mil.br +morena.br +mp.br +mus.br +natal.br +net.br +niteroi.br +*.nom.br +not.br +ntr.br +odo.br +ong.br +org.br +osasco.br +palmas.br +poa.br +ppg.br +pro.br +psc.br +psi.br +pvh.br +qsl.br +radio.br +rec.br +recife.br +rep.br +ribeirao.br +rio.br +riobranco.br +riopreto.br +salvador.br +sampa.br +santamaria.br +santoandre.br +saobernardo.br +saogonca.br +seg.br +sjc.br +slg.br +slz.br +social.br +sorocaba.br +srv.br +taxi.br +tc.br +tec.br +teo.br +the.br +tmp.br +trd.br +tur.br +tv.br +udi.br +vet.br +vix.br +vlog.br +wiki.br +xyz.br +zlg.br + +// bs : http://www.nic.bs/rules.html +bs +com.bs +edu.bs +gov.bs +net.bs +org.bs + +// bt : https://www.iana.org/domains/root/db/bt.html +bt +com.bt +edu.bt +gov.bt +net.bt +org.bt + +// bv : No registrations at this time. +// Submitted by registry +bv + +// bw : https://www.iana.org/domains/root/db/bw.html +// https://nic.net.bw/bw-name-structure +bw +ac.bw +co.bw +gov.bw +net.bw +org.bw + +// by : https://www.iana.org/domains/root/db/by.html +// http://tld.by/rules_2006_en.html +// list of other 2nd level tlds ? +by +gov.by +mil.by +// Official information does not indicate that com.by is a reserved +// second-level domain, but it's being used as one (see www.google.com.by and +// www.yahoo.com.by, for example), so we list it here for safety's sake. +com.by +// http://hoster.by/ +of.by + +// bz : https://www.iana.org/domains/root/db/bz.html +// http://www.belizenic.bz/ +bz +co.bz +com.bz +edu.bz +gov.bz +net.bz +org.bz + +// ca : https://www.iana.org/domains/root/db/ca.html +ca +// ca geographical names +ab.ca +bc.ca +mb.ca +nb.ca +nf.ca +nl.ca +ns.ca +nt.ca +nu.ca +on.ca +pe.ca +qc.ca +sk.ca +yk.ca +// gc.ca: https://en.wikipedia.org/wiki/.gc.ca +// see also: http://registry.gc.ca/en/SubdomainFAQ +gc.ca + +// cat : https://www.iana.org/domains/root/db/cat.html +cat + +// cc : https://www.iana.org/domains/root/db/cc.html +cc + +// cd : https://www.iana.org/domains/root/db/cd.html +// https://www.nic.cd +cd +gov.cd + +// cf : https://www.iana.org/domains/root/db/cf.html +cf + +// cg : https://www.iana.org/domains/root/db/cg.html +cg + +// ch : https://www.iana.org/domains/root/db/ch.html +ch + +// ci : https://www.iana.org/domains/root/db/ci.html +ci +ac.ci +aéroport.ci +asso.ci +co.ci +com.ci +ed.ci +edu.ci +go.ci +gouv.ci +int.ci +net.ci +or.ci +org.ci + +// ck : https://www.iana.org/domains/root/db/ck.html +*.ck +!www.ck + +// cl : https://www.nic.cl +// Confirmed by .CL registry +cl +co.cl +gob.cl +gov.cl +mil.cl + +// cm : https://www.iana.org/domains/root/db/cm.html plus bug 981927 +cm +co.cm +com.cm +gov.cm +net.cm + +// cn : https://www.iana.org/domains/root/db/cn.html +// Submitted by registry +cn +ac.cn +com.cn +edu.cn +gov.cn +mil.cn +net.cn +org.cn +公司.cn +網絡.cn +网络.cn +// cn geographic names +ah.cn +bj.cn +cq.cn +fj.cn +gd.cn +gs.cn +gx.cn +gz.cn +ha.cn +hb.cn +he.cn +hi.cn +hk.cn +hl.cn +hn.cn +jl.cn +js.cn +jx.cn +ln.cn +mo.cn +nm.cn +nx.cn +qh.cn +sc.cn +sd.cn +sh.cn +sn.cn +sx.cn +tj.cn +tw.cn +xj.cn +xz.cn +yn.cn +zj.cn + +// co : https://www.iana.org/domains/root/db/co.html +// https://www.cointernet.com.co/como-funciona-un-dominio-restringido +// Confirmed by registry 2024-11-18 +co +com.co +edu.co +gov.co +mil.co +net.co +nom.co +org.co + +// com : https://www.iana.org/domains/root/db/com.html +com + +// coop : https://www.iana.org/domains/root/db/coop.html +coop + +// cr : https://nic.cr/capitulo-1-registro-de-un-nombre-de-dominio/ +cr +ac.cr +co.cr +ed.cr +fi.cr +go.cr +or.cr +sa.cr + +// cu : https://www.iana.org/domains/root/db/cu.html +cu +com.cu +edu.cu +gob.cu +inf.cu +nat.cu +net.cu +org.cu + +// cv : https://www.iana.org/domains/root/db/cv.html +// https://ola.cv/domain-extensions-under-cv/ +// Confirmed by registry 2024-11-26 +cv +com.cv +edu.cv +id.cv +int.cv +net.cv +nome.cv +org.cv +publ.cv + +// cw : https://www.uoc.cw/cw-registry +// Confirmed by registry 2024-11-19 +cw +com.cw +edu.cw +net.cw +org.cw + +// cx : https://www.iana.org/domains/root/db/cx.html +// list of other 2nd level tlds ? +cx +gov.cx + +// cy : http://www.nic.cy/ +// Submitted by Panayiotou Fotia +// https://nic.cy/wp-content/uploads/2024/01/Create-Request-for-domain-name-registration-1.pdf +cy +ac.cy +biz.cy +com.cy +ekloges.cy +gov.cy +ltd.cy +mil.cy +net.cy +org.cy +press.cy +pro.cy +tm.cy + +// cz : https://www.iana.org/domains/root/db/cz.html +// Confirmed by registry 2025-08-06 +cz +gov.cz + +// de : https://www.iana.org/domains/root/db/de.html +// Confirmed by registry (with technical +// reservations) 2008-07-01 +de + +// dj : https://www.iana.org/domains/root/db/dj.html +dj + +// dk : https://www.iana.org/domains/root/db/dk.html +// Confirmed by registry 2008-06-17 +dk + +// dm : https://www.iana.org/domains/root/db/dm.html +// https://nic.dm/policies/pdf/DMRulesandGuidelines2024v1.pdf +// Confirmed by registry 2024-11-19 +dm +co.dm +com.dm +edu.dm +gov.dm +net.dm +org.dm + +// do : https://www.iana.org/domains/root/db/do.html +do +art.do +com.do +edu.do +gob.do +gov.do +mil.do +net.do +org.do +sld.do +web.do + +// dz : http://www.nic.dz/images/pdf_nic/charte.pdf +dz +art.dz +asso.dz +com.dz +edu.dz +gov.dz +net.dz +org.dz +pol.dz +soc.dz +tm.dz + +// ec : https://www.nic.ec/ +// Submitted by registry +ec +abg.ec +adm.ec +agron.ec +arqt.ec +art.ec +bar.ec +chef.ec +com.ec +cont.ec +cpa.ec +cue.ec +dent.ec +dgn.ec +disco.ec +doc.ec +edu.ec +eng.ec +esm.ec +fin.ec +fot.ec +gal.ec +gob.ec +gov.ec +gye.ec +ibr.ec +info.ec +k12.ec +lat.ec +loj.ec +med.ec +mil.ec +mktg.ec +mon.ec +net.ec +ntr.ec +odont.ec +org.ec +pro.ec +prof.ec +psic.ec +psiq.ec +pub.ec +rio.ec +rrpp.ec +sal.ec +tech.ec +tul.ec +tur.ec +uio.ec +vet.ec +xxx.ec + +// edu : https://www.iana.org/domains/root/db/edu.html +edu + +// ee : https://www.internet.ee/domains/general-domains-and-procedure-for-registration-of-sub-domains-under-general-domains +ee +aip.ee +com.ee +edu.ee +fie.ee +gov.ee +lib.ee +med.ee +org.ee +pri.ee +riik.ee + +// eg : https://www.iana.org/domains/root/db/eg.html +// https://domain.eg/en/domain-rules/subdomain-names-types/ +eg +ac.eg +com.eg +edu.eg +eun.eg +gov.eg +info.eg +me.eg +mil.eg +name.eg +net.eg +org.eg +sci.eg +sport.eg +tv.eg + +// er : https://www.iana.org/domains/root/db/er.html +*.er + +// es : https://www.dominios.es/en +es +com.es +edu.es +gob.es +nom.es +org.es + +// et : https://www.iana.org/domains/root/db/et.html +et +biz.et +com.et +edu.et +gov.et +info.et +name.et +net.et +org.et + +// eu : https://www.iana.org/domains/root/db/eu.html +eu + +// fi : https://www.iana.org/domains/root/db/fi.html +fi +// aland.fi : https://www.iana.org/domains/root/db/ax.html +// This domain is being phased out in favor of .ax. As there are still many +// domains under aland.fi, we still keep it on the list until aland.fi is +// completely removed. +aland.fi + +// fj : https://www.iana.org/domains/root/db/fj.html +fj +ac.fj +biz.fj +com.fj +edu.fj +gov.fj +id.fj +info.fj +mil.fj +name.fj +net.fj +org.fj +pro.fj + +// fk : https://www.iana.org/domains/root/db/fk.html +*.fk + +// fm : https://www.iana.org/domains/root/db/fm.html +fm +com.fm +edu.fm +net.fm +org.fm + +// fo : https://www.iana.org/domains/root/db/fo.html +fo + +// fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +fr +asso.fr +com.fr +gouv.fr +nom.fr +prd.fr +tm.fr +// Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes +avoues.fr +cci.fr +greta.fr +huissier-justice.fr + +// ga : https://www.iana.org/domains/root/db/ga.html +ga + +// gb : This registry is effectively dormant +// Submitted by registry +gb + +// gd : https://www.iana.org/domains/root/db/gd.html +gd +edu.gd +gov.gd + +// ge : https://nic.ge/en/administrator/the-ge-domain-regulations +// Confirmed by registry 2024-11-20 +ge +com.ge +edu.ge +gov.ge +net.ge +org.ge +pvt.ge +school.ge + +// gf : https://www.iana.org/domains/root/db/gf.html +gf + +// gg : https://www.channelisles.net/register-1/register-direct +// Confirmed by registry 2013-11-28 +gg +co.gg +net.gg +org.gg + +// gh : https://www.iana.org/domains/root/db/gh.html +// https://www.nic.gh/ +// Although domains directly at second level are not possible at the moment, +// they have been possible for some time and may come back. +gh +biz.gh +com.gh +edu.gh +gov.gh +mil.gh +net.gh +org.gh + +// gi : http://www.nic.gi/rules.html +gi +com.gi +edu.gi +gov.gi +ltd.gi +mod.gi +org.gi + +// gl : https://www.iana.org/domains/root/db/gl.html +// http://nic.gl +gl +co.gl +com.gl +edu.gl +net.gl +org.gl + +// gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm +gm + +// gn : http://psg.com/dns/gn/gn.txt +// Submitted by registry +gn +ac.gn +com.gn +edu.gn +gov.gn +net.gn +org.gn + +// gov : https://www.iana.org/domains/root/db/gov.html +gov + +// gp : http://www.nic.gp/index.php?lang=en +gp +asso.gp +com.gp +edu.gp +mobi.gp +net.gp +org.gp + +// gq : https://www.iana.org/domains/root/db/gq.html +gq + +// gr : https://www.iana.org/domains/root/db/gr.html +// Submitted by registry +gr +com.gr +edu.gr +gov.gr +net.gr +org.gr + +// gs : https://www.iana.org/domains/root/db/gs.html +gs + +// gt : https://www.gt/sitio/registration_policy.php?lang=en +gt +com.gt +edu.gt +gob.gt +ind.gt +mil.gt +net.gt +org.gt + +// gu : http://gadao.gov.gu/register.html +// University of Guam : https://www.uog.edu +// Submitted by uognoc@triton.uog.edu +gu +com.gu +edu.gu +gov.gu +guam.gu +info.gu +net.gu +org.gu +web.gu + +// gw : https://www.iana.org/domains/root/db/gw.html +// gw : https://nic.gw/regras/ +gw + +// gy : https://www.iana.org/domains/root/db/gy.html +// http://registry.gy/ +gy +co.gy +com.gy +edu.gy +gov.gy +net.gy +org.gy + +// hk : https://www.hkirc.hk +// Submitted by registry +hk +com.hk +edu.hk +gov.hk +idv.hk +net.hk +org.hk +个人.hk +個人.hk +公司.hk +政府.hk +敎育.hk +教育.hk +箇人.hk +組織.hk +組织.hk +網絡.hk +網络.hk +组織.hk +组织.hk +网絡.hk +网络.hk + +// hm : https://www.iana.org/domains/root/db/hm.html +hm + +// hn : https://www.iana.org/domains/root/db/hn.html +hn +com.hn +edu.hn +gob.hn +mil.hn +net.hn +org.hn + +// hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf +hr +com.hr +from.hr +iz.hr +name.hr + +// ht : http://www.nic.ht/info/charte.cfm +ht +adult.ht +art.ht +asso.ht +com.ht +coop.ht +edu.ht +firm.ht +gouv.ht +info.ht +med.ht +net.ht +org.ht +perso.ht +pol.ht +pro.ht +rel.ht +shop.ht + +// hu : https://www.iana.org/domains/root/db/hu.html +// Confirmed by registry 2008-06-12 +hu +2000.hu +agrar.hu +bolt.hu +casino.hu +city.hu +co.hu +erotica.hu +erotika.hu +film.hu +forum.hu +games.hu +hotel.hu +info.hu +ingatlan.hu +jogasz.hu +konyvelo.hu +lakas.hu +media.hu +news.hu +org.hu +priv.hu +reklam.hu +sex.hu +shop.hu +sport.hu +suli.hu +szex.hu +tm.hu +tozsde.hu +utazas.hu +video.hu + +// id : https://www.iana.org/domains/root/db/id.html +id +ac.id +biz.id +co.id +desa.id +go.id +kop.id +mil.id +my.id +net.id +or.id +ponpes.id +sch.id +web.id +// xn--9tfky.id (.id, Und-Bali) +ᬩᬮᬶ.id + +// ie : https://www.iana.org/domains/root/db/ie.html +ie +gov.ie + +// il : http://www.isoc.org.il/domains/ +// see also: https://en.isoc.org.il/il-cctld/registration-rules +// ISOC-IL (operated by .il Registry) +il +ac.il +co.il +gov.il +idf.il +k12.il +muni.il +net.il +org.il +// xn--4dbrk0ce ("Israel", Hebrew) : IL +ישראל +// xn--4dbgdty6c.xn--4dbrk0ce. +אקדמיה.ישראל +// xn--5dbhl8d.xn--4dbrk0ce. +ישוב.ישראל +// xn--8dbq2a.xn--4dbrk0ce. +צהל.ישראל +// xn--hebda8b.xn--4dbrk0ce. +ממשל.ישראל + +// im : https://www.nic.im/ +// Submitted by registry +im +ac.im +co.im +ltd.co.im +plc.co.im +com.im +net.im +org.im +tt.im +tv.im + +// in : https://www.iana.org/domains/root/db/in.html +// see also: https://registry.in/policies +// Please note, that nic.in is not an official eTLD, but used by most +// government institutions. +// Confirmed by Gaurav Kansal 2025-11-06 +in +5g.in +6g.in +ac.in +ai.in +am.in +bank.in +bihar.in +biz.in +business.in +ca.in +cn.in +co.in +com.in +coop.in +cs.in +delhi.in +dr.in +edu.in +er.in +fin.in +firm.in +gen.in +gov.in +gujarat.in +ind.in +info.in +int.in +internet.in +io.in +me.in +mil.in +net.in +nic.in +org.in +pg.in +post.in +pro.in +res.in +travel.in +tv.in +uk.in +up.in +us.in + +// info : https://www.iana.org/domains/root/db/info.html +info + +// int : https://www.iana.org/domains/root/db/int.html +// Confirmed by registry 2008-06-18 +int +eu.int + +// io : http://www.nic.io/rules.htm +io +co.io +com.io +edu.io +gov.io +mil.io +net.io +nom.io +org.io + +// iq : http://www.cmc.iq/english/iq/iqregister1.htm +iq +com.iq +edu.iq +gov.iq +mil.iq +net.iq +org.iq + +// ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules +// Also see http://www.nic.ir/Internationalized_Domain_Names +// Two .ir entries added at request of , 2010-04-16 +ir +ac.ir +co.ir +gov.ir +id.ir +net.ir +org.ir +sch.ir +// xn--mgba3a4f16a.ir (.ir, Persian YEH) +ایران.ir +// xn--mgba3a4fra.ir (.ir, Arabic YEH) +ايران.ir + +// is : http://www.isnic.is/domain/rules.php +// Confirmed by registry 2024-11-17 +is + +// it : https://www.iana.org/domains/root/db/it.html +// https://www.nic.it/ +it +edu.it +gov.it +// Regions (3.3.1) +// https://www.nic.it/en/manage-your-it/forms-and-docs -> "Assignment and Management of domain names" +abr.it +abruzzo.it +aosta-valley.it +aostavalley.it +bas.it +basilicata.it +cal.it +calabria.it +cam.it +campania.it +emilia-romagna.it +emiliaromagna.it +emr.it +friuli-v-giulia.it +friuli-ve-giulia.it +friuli-vegiulia.it +friuli-venezia-giulia.it +friuli-veneziagiulia.it +friuli-vgiulia.it +friuliv-giulia.it +friulive-giulia.it +friulivegiulia.it +friulivenezia-giulia.it +friuliveneziagiulia.it +friulivgiulia.it +fvg.it +laz.it +lazio.it +lig.it +liguria.it +lom.it +lombardia.it +lombardy.it +lucania.it +mar.it +marche.it +mol.it +molise.it +piedmont.it +piemonte.it +pmn.it +pug.it +puglia.it +sar.it +sardegna.it +sardinia.it +sic.it +sicilia.it +sicily.it +taa.it +tos.it +toscana.it +trentin-sud-tirol.it +trentin-süd-tirol.it +trentin-sudtirol.it +trentin-südtirol.it +trentin-sued-tirol.it +trentin-suedtirol.it +trentino.it +trentino-a-adige.it +trentino-aadige.it +trentino-alto-adige.it +trentino-altoadige.it +trentino-s-tirol.it +trentino-stirol.it +trentino-sud-tirol.it +trentino-süd-tirol.it +trentino-sudtirol.it +trentino-südtirol.it +trentino-sued-tirol.it +trentino-suedtirol.it +trentinoa-adige.it +trentinoaadige.it +trentinoalto-adige.it +trentinoaltoadige.it +trentinos-tirol.it +trentinostirol.it +trentinosud-tirol.it +trentinosüd-tirol.it +trentinosudtirol.it +trentinosüdtirol.it +trentinosued-tirol.it +trentinosuedtirol.it +trentinsud-tirol.it +trentinsüd-tirol.it +trentinsudtirol.it +trentinsüdtirol.it +trentinsued-tirol.it +trentinsuedtirol.it +tuscany.it +umb.it +umbria.it +val-d-aosta.it +val-daosta.it +vald-aosta.it +valdaosta.it +valle-aosta.it +valle-d-aosta.it +valle-daosta.it +valleaosta.it +valled-aosta.it +valledaosta.it +vallee-aoste.it +vallée-aoste.it +vallee-d-aoste.it +vallée-d-aoste.it +valleeaoste.it +valléeaoste.it +valleedaoste.it +valléedaoste.it +vao.it +vda.it +ven.it +veneto.it +// Provinces (3.3.2) +ag.it +agrigento.it +al.it +alessandria.it +alto-adige.it +altoadige.it +an.it +ancona.it +andria-barletta-trani.it +andria-trani-barletta.it +andriabarlettatrani.it +andriatranibarletta.it +ao.it +aosta.it +aoste.it +ap.it +aq.it +aquila.it +ar.it +arezzo.it +ascoli-piceno.it +ascolipiceno.it +asti.it +at.it +av.it +avellino.it +ba.it +balsan.it +balsan-sudtirol.it +balsan-südtirol.it +balsan-suedtirol.it +bari.it +barletta-trani-andria.it +barlettatraniandria.it +belluno.it +benevento.it +bergamo.it +bg.it +bi.it +biella.it +bl.it +bn.it +bo.it +bologna.it +bolzano.it +bolzano-altoadige.it +bozen.it +bozen-sudtirol.it +bozen-südtirol.it +bozen-suedtirol.it +br.it +brescia.it +brindisi.it +bs.it +bt.it +bulsan.it +bulsan-sudtirol.it +bulsan-südtirol.it +bulsan-suedtirol.it +bz.it +ca.it +cagliari.it +caltanissetta.it +campidano-medio.it +campidanomedio.it +campobasso.it +carbonia-iglesias.it +carboniaiglesias.it +carrara-massa.it +carraramassa.it +caserta.it +catania.it +catanzaro.it +cb.it +ce.it +cesena-forli.it +cesena-forlì.it +cesenaforli.it +cesenaforlì.it +ch.it +chieti.it +ci.it +cl.it +cn.it +co.it +como.it +cosenza.it +cr.it +cremona.it +crotone.it +cs.it +ct.it +cuneo.it +cz.it +dell-ogliastra.it +dellogliastra.it +en.it +enna.it +fc.it +fe.it +fermo.it +ferrara.it +fg.it +fi.it +firenze.it +florence.it +fm.it +foggia.it +forli-cesena.it +forlì-cesena.it +forlicesena.it +forlìcesena.it +fr.it +frosinone.it +ge.it +genoa.it +genova.it +go.it +gorizia.it +gr.it +grosseto.it +iglesias-carbonia.it +iglesiascarbonia.it +im.it +imperia.it +is.it +isernia.it +kr.it +la-spezia.it +laquila.it +laspezia.it +latina.it +lc.it +le.it +lecce.it +lecco.it +li.it +livorno.it +lo.it +lodi.it +lt.it +lu.it +lucca.it +macerata.it +mantova.it +massa-carrara.it +massacarrara.it +matera.it +mb.it +mc.it +me.it +medio-campidano.it +mediocampidano.it +messina.it +mi.it +milan.it +milano.it +mn.it +mo.it +modena.it +monza.it +monza-brianza.it +monza-e-della-brianza.it +monzabrianza.it +monzaebrianza.it +monzaedellabrianza.it +ms.it +mt.it +na.it +naples.it +napoli.it +no.it +novara.it +nu.it +nuoro.it +og.it +ogliastra.it +olbia-tempio.it +olbiatempio.it +or.it +oristano.it +ot.it +pa.it +padova.it +padua.it +palermo.it +parma.it +pavia.it +pc.it +pd.it +pe.it +perugia.it +pesaro-urbino.it +pesarourbino.it +pescara.it +pg.it +pi.it +piacenza.it +pisa.it +pistoia.it +pn.it +po.it +pordenone.it +potenza.it +pr.it +prato.it +pt.it +pu.it +pv.it +pz.it +ra.it +ragusa.it +ravenna.it +rc.it +re.it +reggio-calabria.it +reggio-emilia.it +reggiocalabria.it +reggioemilia.it +rg.it +ri.it +rieti.it +rimini.it +rm.it +rn.it +ro.it +roma.it +rome.it +rovigo.it +sa.it +salerno.it +sassari.it +savona.it +si.it +siena.it +siracusa.it +so.it +sondrio.it +sp.it +sr.it +ss.it +südtirol.it +suedtirol.it +sv.it +ta.it +taranto.it +te.it +tempio-olbia.it +tempioolbia.it +teramo.it +terni.it +tn.it +to.it +torino.it +tp.it +tr.it +trani-andria-barletta.it +trani-barletta-andria.it +traniandriabarletta.it +tranibarlettaandria.it +trapani.it +trento.it +treviso.it +trieste.it +ts.it +turin.it +tv.it +ud.it +udine.it +urbino-pesaro.it +urbinopesaro.it +va.it +varese.it +vb.it +vc.it +ve.it +venezia.it +venice.it +verbania.it +vercelli.it +verona.it +vi.it +vibo-valentia.it +vibovalentia.it +vicenza.it +viterbo.it +vr.it +vs.it +vt.it +vv.it + +// je : https://www.iana.org/domains/root/db/je.html +// Confirmed by registry 2013-11-28 +je +co.je +net.je +org.je + +// jm : http://www.com.jm/register.html +*.jm + +// jo : https://www.dns.jo/JoFamily.aspx +// Confirmed by registry 2024-11-17 +jo +agri.jo +ai.jo +com.jo +edu.jo +eng.jo +fm.jo +gov.jo +mil.jo +net.jo +org.jo +per.jo +phd.jo +sch.jo +tv.jo + +// jobs : https://www.iana.org/domains/root/db/jobs.html +jobs + +// jp : https://www.iana.org/domains/root/db/jp.html +// http://jprs.co.jp/en/jpdomain.html +// Confirmed by registry 2024-11-22 +jp +// jp organizational type names +ac.jp +ad.jp +co.jp +ed.jp +go.jp +gr.jp +lg.jp +ne.jp +or.jp +// jp prefecture type names +aichi.jp +akita.jp +aomori.jp +chiba.jp +ehime.jp +fukui.jp +fukuoka.jp +fukushima.jp +gifu.jp +gunma.jp +hiroshima.jp +hokkaido.jp +hyogo.jp +ibaraki.jp +ishikawa.jp +iwate.jp +kagawa.jp +kagoshima.jp +kanagawa.jp +kochi.jp +kumamoto.jp +kyoto.jp +mie.jp +miyagi.jp +miyazaki.jp +nagano.jp +nagasaki.jp +nara.jp +niigata.jp +oita.jp +okayama.jp +okinawa.jp +osaka.jp +saga.jp +saitama.jp +shiga.jp +shimane.jp +shizuoka.jp +tochigi.jp +tokushima.jp +tokyo.jp +tottori.jp +toyama.jp +wakayama.jp +yamagata.jp +yamaguchi.jp +yamanashi.jp +三重.jp +京都.jp +佐賀.jp +兵庫.jp +北海道.jp +千葉.jp +和歌山.jp +埼玉.jp +大分.jp +大阪.jp +奈良.jp +宮城.jp +宮崎.jp +富山.jp +山口.jp +山形.jp +山梨.jp +岐阜.jp +岡山.jp +岩手.jp +島根.jp +広島.jp +徳島.jp +愛媛.jp +愛知.jp +新潟.jp +東京.jp +栃木.jp +沖縄.jp +滋賀.jp +熊本.jp +石川.jp +神奈川.jp +福井.jp +福岡.jp +福島.jp +秋田.jp +群馬.jp +茨城.jp +長崎.jp +長野.jp +青森.jp +静岡.jp +香川.jp +高知.jp +鳥取.jp +鹿児島.jp +// jp geographic type names +// http://jprs.jp/doc/rule/saisoku-1.html +// 2024-11-22: JPRS confirmed that jp geographic type names no longer accept new registrations. +// Once all existing registrations expire (marking full discontinuation), these suffixes +// will be removed from the PSL. +*.kawasaki.jp +!city.kawasaki.jp +*.kitakyushu.jp +!city.kitakyushu.jp +*.kobe.jp +!city.kobe.jp +*.nagoya.jp +!city.nagoya.jp +*.sapporo.jp +!city.sapporo.jp +*.sendai.jp +!city.sendai.jp +*.yokohama.jp +!city.yokohama.jp +// 4th level registration +aisai.aichi.jp +ama.aichi.jp +anjo.aichi.jp +asuke.aichi.jp +chiryu.aichi.jp +chita.aichi.jp +fuso.aichi.jp +gamagori.aichi.jp +handa.aichi.jp +hazu.aichi.jp +hekinan.aichi.jp +higashiura.aichi.jp +ichinomiya.aichi.jp +inazawa.aichi.jp +inuyama.aichi.jp +isshiki.aichi.jp +iwakura.aichi.jp +kanie.aichi.jp +kariya.aichi.jp +kasugai.aichi.jp +kira.aichi.jp +kiyosu.aichi.jp +komaki.aichi.jp +konan.aichi.jp +kota.aichi.jp +mihama.aichi.jp +miyoshi.aichi.jp +nishio.aichi.jp +nisshin.aichi.jp +obu.aichi.jp +oguchi.aichi.jp +oharu.aichi.jp +okazaki.aichi.jp +owariasahi.aichi.jp +seto.aichi.jp +shikatsu.aichi.jp +shinshiro.aichi.jp +shitara.aichi.jp +tahara.aichi.jp +takahama.aichi.jp +tobishima.aichi.jp +toei.aichi.jp +togo.aichi.jp +tokai.aichi.jp +tokoname.aichi.jp +toyoake.aichi.jp +toyohashi.aichi.jp +toyokawa.aichi.jp +toyone.aichi.jp +toyota.aichi.jp +tsushima.aichi.jp +yatomi.aichi.jp +akita.akita.jp +daisen.akita.jp +fujisato.akita.jp +gojome.akita.jp +hachirogata.akita.jp +happou.akita.jp +higashinaruse.akita.jp +honjo.akita.jp +honjyo.akita.jp +ikawa.akita.jp +kamikoani.akita.jp +kamioka.akita.jp +katagami.akita.jp +kazuno.akita.jp +kitaakita.akita.jp +kosaka.akita.jp +kyowa.akita.jp +misato.akita.jp +mitane.akita.jp +moriyoshi.akita.jp +nikaho.akita.jp +noshiro.akita.jp +odate.akita.jp +oga.akita.jp +ogata.akita.jp +semboku.akita.jp +yokote.akita.jp +yurihonjo.akita.jp +aomori.aomori.jp +gonohe.aomori.jp +hachinohe.aomori.jp +hashikami.aomori.jp +hiranai.aomori.jp +hirosaki.aomori.jp +itayanagi.aomori.jp +kuroishi.aomori.jp +misawa.aomori.jp +mutsu.aomori.jp +nakadomari.aomori.jp +noheji.aomori.jp +oirase.aomori.jp +owani.aomori.jp +rokunohe.aomori.jp +sannohe.aomori.jp +shichinohe.aomori.jp +shingo.aomori.jp +takko.aomori.jp +towada.aomori.jp +tsugaru.aomori.jp +tsuruta.aomori.jp +abiko.chiba.jp +asahi.chiba.jp +chonan.chiba.jp +chosei.chiba.jp +choshi.chiba.jp +chuo.chiba.jp +funabashi.chiba.jp +futtsu.chiba.jp +hanamigawa.chiba.jp +ichihara.chiba.jp +ichikawa.chiba.jp +ichinomiya.chiba.jp +inzai.chiba.jp +isumi.chiba.jp +kamagaya.chiba.jp +kamogawa.chiba.jp +kashiwa.chiba.jp +katori.chiba.jp +katsuura.chiba.jp +kimitsu.chiba.jp +kisarazu.chiba.jp +kozaki.chiba.jp +kujukuri.chiba.jp +kyonan.chiba.jp +matsudo.chiba.jp +midori.chiba.jp +mihama.chiba.jp +minamiboso.chiba.jp +mobara.chiba.jp +mutsuzawa.chiba.jp +nagara.chiba.jp +nagareyama.chiba.jp +narashino.chiba.jp +narita.chiba.jp +noda.chiba.jp +oamishirasato.chiba.jp +omigawa.chiba.jp +onjuku.chiba.jp +otaki.chiba.jp +sakae.chiba.jp +sakura.chiba.jp +shimofusa.chiba.jp +shirako.chiba.jp +shiroi.chiba.jp +shisui.chiba.jp +sodegaura.chiba.jp +sosa.chiba.jp +tako.chiba.jp +tateyama.chiba.jp +togane.chiba.jp +tohnosho.chiba.jp +tomisato.chiba.jp +urayasu.chiba.jp +yachimata.chiba.jp +yachiyo.chiba.jp +yokaichiba.chiba.jp +yokoshibahikari.chiba.jp +yotsukaido.chiba.jp +ainan.ehime.jp +honai.ehime.jp +ikata.ehime.jp +imabari.ehime.jp +iyo.ehime.jp +kamijima.ehime.jp +kihoku.ehime.jp +kumakogen.ehime.jp +masaki.ehime.jp +matsuno.ehime.jp +matsuyama.ehime.jp +namikata.ehime.jp +niihama.ehime.jp +ozu.ehime.jp +saijo.ehime.jp +seiyo.ehime.jp +shikokuchuo.ehime.jp +tobe.ehime.jp +toon.ehime.jp +uchiko.ehime.jp +uwajima.ehime.jp +yawatahama.ehime.jp +echizen.fukui.jp +eiheiji.fukui.jp +fukui.fukui.jp +ikeda.fukui.jp +katsuyama.fukui.jp +mihama.fukui.jp +minamiechizen.fukui.jp +obama.fukui.jp +ohi.fukui.jp +ono.fukui.jp +sabae.fukui.jp +sakai.fukui.jp +takahama.fukui.jp +tsuruga.fukui.jp +wakasa.fukui.jp +ashiya.fukuoka.jp +buzen.fukuoka.jp +chikugo.fukuoka.jp +chikuho.fukuoka.jp +chikujo.fukuoka.jp +chikushino.fukuoka.jp +chikuzen.fukuoka.jp +chuo.fukuoka.jp +dazaifu.fukuoka.jp +fukuchi.fukuoka.jp +hakata.fukuoka.jp +higashi.fukuoka.jp +hirokawa.fukuoka.jp +hisayama.fukuoka.jp +iizuka.fukuoka.jp +inatsuki.fukuoka.jp +kaho.fukuoka.jp +kasuga.fukuoka.jp +kasuya.fukuoka.jp +kawara.fukuoka.jp +keisen.fukuoka.jp +koga.fukuoka.jp +kurate.fukuoka.jp +kurogi.fukuoka.jp +kurume.fukuoka.jp +minami.fukuoka.jp +miyako.fukuoka.jp +miyama.fukuoka.jp +miyawaka.fukuoka.jp +mizumaki.fukuoka.jp +munakata.fukuoka.jp +nakagawa.fukuoka.jp +nakama.fukuoka.jp +nishi.fukuoka.jp +nogata.fukuoka.jp +ogori.fukuoka.jp +okagaki.fukuoka.jp +okawa.fukuoka.jp +oki.fukuoka.jp +omuta.fukuoka.jp +onga.fukuoka.jp +onojo.fukuoka.jp +oto.fukuoka.jp +saigawa.fukuoka.jp +sasaguri.fukuoka.jp +shingu.fukuoka.jp +shinyoshitomi.fukuoka.jp +shonai.fukuoka.jp +soeda.fukuoka.jp +sue.fukuoka.jp +tachiarai.fukuoka.jp +tagawa.fukuoka.jp +takata.fukuoka.jp +toho.fukuoka.jp +toyotsu.fukuoka.jp +tsuiki.fukuoka.jp +ukiha.fukuoka.jp +umi.fukuoka.jp +usui.fukuoka.jp +yamada.fukuoka.jp +yame.fukuoka.jp +yanagawa.fukuoka.jp +yukuhashi.fukuoka.jp +aizubange.fukushima.jp +aizumisato.fukushima.jp +aizuwakamatsu.fukushima.jp +asakawa.fukushima.jp +bandai.fukushima.jp +date.fukushima.jp +fukushima.fukushima.jp +furudono.fukushima.jp +futaba.fukushima.jp +hanawa.fukushima.jp +higashi.fukushima.jp +hirata.fukushima.jp +hirono.fukushima.jp +iitate.fukushima.jp +inawashiro.fukushima.jp +ishikawa.fukushima.jp +iwaki.fukushima.jp +izumizaki.fukushima.jp +kagamiishi.fukushima.jp +kaneyama.fukushima.jp +kawamata.fukushima.jp +kitakata.fukushima.jp +kitashiobara.fukushima.jp +koori.fukushima.jp +koriyama.fukushima.jp +kunimi.fukushima.jp +miharu.fukushima.jp +mishima.fukushima.jp +namie.fukushima.jp +nango.fukushima.jp +nishiaizu.fukushima.jp +nishigo.fukushima.jp +okuma.fukushima.jp +omotego.fukushima.jp +ono.fukushima.jp +otama.fukushima.jp +samegawa.fukushima.jp +shimogo.fukushima.jp +shirakawa.fukushima.jp +showa.fukushima.jp +soma.fukushima.jp +sukagawa.fukushima.jp +taishin.fukushima.jp +tamakawa.fukushima.jp +tanagura.fukushima.jp +tenei.fukushima.jp +yabuki.fukushima.jp +yamato.fukushima.jp +yamatsuri.fukushima.jp +yanaizu.fukushima.jp +yugawa.fukushima.jp +anpachi.gifu.jp +ena.gifu.jp +gifu.gifu.jp +ginan.gifu.jp +godo.gifu.jp +gujo.gifu.jp +hashima.gifu.jp +hichiso.gifu.jp +hida.gifu.jp +higashishirakawa.gifu.jp +ibigawa.gifu.jp +ikeda.gifu.jp +kakamigahara.gifu.jp +kani.gifu.jp +kasahara.gifu.jp +kasamatsu.gifu.jp +kawaue.gifu.jp +kitagata.gifu.jp +mino.gifu.jp +minokamo.gifu.jp +mitake.gifu.jp +mizunami.gifu.jp +motosu.gifu.jp +nakatsugawa.gifu.jp +ogaki.gifu.jp +sakahogi.gifu.jp +seki.gifu.jp +sekigahara.gifu.jp +shirakawa.gifu.jp +tajimi.gifu.jp +takayama.gifu.jp +tarui.gifu.jp +toki.gifu.jp +tomika.gifu.jp +wanouchi.gifu.jp +yamagata.gifu.jp +yaotsu.gifu.jp +yoro.gifu.jp +annaka.gunma.jp +chiyoda.gunma.jp +fujioka.gunma.jp +higashiagatsuma.gunma.jp +isesaki.gunma.jp +itakura.gunma.jp +kanna.gunma.jp +kanra.gunma.jp +katashina.gunma.jp +kawaba.gunma.jp +kiryu.gunma.jp +kusatsu.gunma.jp +maebashi.gunma.jp +meiwa.gunma.jp +midori.gunma.jp +minakami.gunma.jp +naganohara.gunma.jp +nakanojo.gunma.jp +nanmoku.gunma.jp +numata.gunma.jp +oizumi.gunma.jp +ora.gunma.jp +ota.gunma.jp +shibukawa.gunma.jp +shimonita.gunma.jp +shinto.gunma.jp +showa.gunma.jp +takasaki.gunma.jp +takayama.gunma.jp +tamamura.gunma.jp +tatebayashi.gunma.jp +tomioka.gunma.jp +tsukiyono.gunma.jp +tsumagoi.gunma.jp +ueno.gunma.jp +yoshioka.gunma.jp +asaminami.hiroshima.jp +daiwa.hiroshima.jp +etajima.hiroshima.jp +fuchu.hiroshima.jp +fukuyama.hiroshima.jp +hatsukaichi.hiroshima.jp +higashihiroshima.hiroshima.jp +hongo.hiroshima.jp +jinsekikogen.hiroshima.jp +kaita.hiroshima.jp +kui.hiroshima.jp +kumano.hiroshima.jp +kure.hiroshima.jp +mihara.hiroshima.jp +miyoshi.hiroshima.jp +naka.hiroshima.jp +onomichi.hiroshima.jp +osakikamijima.hiroshima.jp +otake.hiroshima.jp +saka.hiroshima.jp +sera.hiroshima.jp +seranishi.hiroshima.jp +shinichi.hiroshima.jp +shobara.hiroshima.jp +takehara.hiroshima.jp +abashiri.hokkaido.jp +abira.hokkaido.jp +aibetsu.hokkaido.jp +akabira.hokkaido.jp +akkeshi.hokkaido.jp +asahikawa.hokkaido.jp +ashibetsu.hokkaido.jp +ashoro.hokkaido.jp +assabu.hokkaido.jp +atsuma.hokkaido.jp +bibai.hokkaido.jp +biei.hokkaido.jp +bifuka.hokkaido.jp +bihoro.hokkaido.jp +biratori.hokkaido.jp +chippubetsu.hokkaido.jp +chitose.hokkaido.jp +date.hokkaido.jp +ebetsu.hokkaido.jp +embetsu.hokkaido.jp +eniwa.hokkaido.jp +erimo.hokkaido.jp +esan.hokkaido.jp +esashi.hokkaido.jp +fukagawa.hokkaido.jp +fukushima.hokkaido.jp +furano.hokkaido.jp +furubira.hokkaido.jp +haboro.hokkaido.jp +hakodate.hokkaido.jp +hamatonbetsu.hokkaido.jp +hidaka.hokkaido.jp +higashikagura.hokkaido.jp +higashikawa.hokkaido.jp +hiroo.hokkaido.jp +hokuryu.hokkaido.jp +hokuto.hokkaido.jp +honbetsu.hokkaido.jp +horokanai.hokkaido.jp +horonobe.hokkaido.jp +ikeda.hokkaido.jp +imakane.hokkaido.jp +ishikari.hokkaido.jp +iwamizawa.hokkaido.jp +iwanai.hokkaido.jp +kamifurano.hokkaido.jp +kamikawa.hokkaido.jp +kamishihoro.hokkaido.jp +kamisunagawa.hokkaido.jp +kamoenai.hokkaido.jp +kayabe.hokkaido.jp +kembuchi.hokkaido.jp +kikonai.hokkaido.jp +kimobetsu.hokkaido.jp +kitahiroshima.hokkaido.jp +kitami.hokkaido.jp +kiyosato.hokkaido.jp +koshimizu.hokkaido.jp +kunneppu.hokkaido.jp +kuriyama.hokkaido.jp +kuromatsunai.hokkaido.jp +kushiro.hokkaido.jp +kutchan.hokkaido.jp +kyowa.hokkaido.jp +mashike.hokkaido.jp +matsumae.hokkaido.jp +mikasa.hokkaido.jp +minamifurano.hokkaido.jp +mombetsu.hokkaido.jp +moseushi.hokkaido.jp +mukawa.hokkaido.jp +muroran.hokkaido.jp +naie.hokkaido.jp +nakagawa.hokkaido.jp +nakasatsunai.hokkaido.jp +nakatombetsu.hokkaido.jp +nanae.hokkaido.jp +nanporo.hokkaido.jp +nayoro.hokkaido.jp +nemuro.hokkaido.jp +niikappu.hokkaido.jp +niki.hokkaido.jp +nishiokoppe.hokkaido.jp +noboribetsu.hokkaido.jp +numata.hokkaido.jp +obihiro.hokkaido.jp +obira.hokkaido.jp +oketo.hokkaido.jp +okoppe.hokkaido.jp +otaru.hokkaido.jp +otobe.hokkaido.jp +otofuke.hokkaido.jp +otoineppu.hokkaido.jp +oumu.hokkaido.jp +ozora.hokkaido.jp +pippu.hokkaido.jp +rankoshi.hokkaido.jp +rebun.hokkaido.jp +rikubetsu.hokkaido.jp +rishiri.hokkaido.jp +rishirifuji.hokkaido.jp +saroma.hokkaido.jp +sarufutsu.hokkaido.jp +shakotan.hokkaido.jp +shari.hokkaido.jp +shibecha.hokkaido.jp +shibetsu.hokkaido.jp +shikabe.hokkaido.jp +shikaoi.hokkaido.jp +shimamaki.hokkaido.jp +shimizu.hokkaido.jp +shimokawa.hokkaido.jp +shinshinotsu.hokkaido.jp +shintoku.hokkaido.jp +shiranuka.hokkaido.jp +shiraoi.hokkaido.jp +shiriuchi.hokkaido.jp +sobetsu.hokkaido.jp +sunagawa.hokkaido.jp +taiki.hokkaido.jp +takasu.hokkaido.jp +takikawa.hokkaido.jp +takinoue.hokkaido.jp +teshikaga.hokkaido.jp +tobetsu.hokkaido.jp +tohma.hokkaido.jp +tomakomai.hokkaido.jp +tomari.hokkaido.jp +toya.hokkaido.jp +toyako.hokkaido.jp +toyotomi.hokkaido.jp +toyoura.hokkaido.jp +tsubetsu.hokkaido.jp +tsukigata.hokkaido.jp +urakawa.hokkaido.jp +urausu.hokkaido.jp +uryu.hokkaido.jp +utashinai.hokkaido.jp +wakkanai.hokkaido.jp +wassamu.hokkaido.jp +yakumo.hokkaido.jp +yoichi.hokkaido.jp +aioi.hyogo.jp +akashi.hyogo.jp +ako.hyogo.jp +amagasaki.hyogo.jp +aogaki.hyogo.jp +asago.hyogo.jp +ashiya.hyogo.jp +awaji.hyogo.jp +fukusaki.hyogo.jp +goshiki.hyogo.jp +harima.hyogo.jp +himeji.hyogo.jp +ichikawa.hyogo.jp +inagawa.hyogo.jp +itami.hyogo.jp +kakogawa.hyogo.jp +kamigori.hyogo.jp +kamikawa.hyogo.jp +kasai.hyogo.jp +kasuga.hyogo.jp +kawanishi.hyogo.jp +miki.hyogo.jp +minamiawaji.hyogo.jp +nishinomiya.hyogo.jp +nishiwaki.hyogo.jp +ono.hyogo.jp +sanda.hyogo.jp +sannan.hyogo.jp +sasayama.hyogo.jp +sayo.hyogo.jp +shingu.hyogo.jp +shinonsen.hyogo.jp +shiso.hyogo.jp +sumoto.hyogo.jp +taishi.hyogo.jp +taka.hyogo.jp +takarazuka.hyogo.jp +takasago.hyogo.jp +takino.hyogo.jp +tamba.hyogo.jp +tatsuno.hyogo.jp +toyooka.hyogo.jp +yabu.hyogo.jp +yashiro.hyogo.jp +yoka.hyogo.jp +yokawa.hyogo.jp +ami.ibaraki.jp +asahi.ibaraki.jp +bando.ibaraki.jp +chikusei.ibaraki.jp +daigo.ibaraki.jp +fujishiro.ibaraki.jp +hitachi.ibaraki.jp +hitachinaka.ibaraki.jp +hitachiomiya.ibaraki.jp +hitachiota.ibaraki.jp +ibaraki.ibaraki.jp +ina.ibaraki.jp +inashiki.ibaraki.jp +itako.ibaraki.jp +iwama.ibaraki.jp +joso.ibaraki.jp +kamisu.ibaraki.jp +kasama.ibaraki.jp +kashima.ibaraki.jp +kasumigaura.ibaraki.jp +koga.ibaraki.jp +miho.ibaraki.jp +mito.ibaraki.jp +moriya.ibaraki.jp +naka.ibaraki.jp +namegata.ibaraki.jp +oarai.ibaraki.jp +ogawa.ibaraki.jp +omitama.ibaraki.jp +ryugasaki.ibaraki.jp +sakai.ibaraki.jp +sakuragawa.ibaraki.jp +shimodate.ibaraki.jp +shimotsuma.ibaraki.jp +shirosato.ibaraki.jp +sowa.ibaraki.jp +suifu.ibaraki.jp +takahagi.ibaraki.jp +tamatsukuri.ibaraki.jp +tokai.ibaraki.jp +tomobe.ibaraki.jp +tone.ibaraki.jp +toride.ibaraki.jp +tsuchiura.ibaraki.jp +tsukuba.ibaraki.jp +uchihara.ibaraki.jp +ushiku.ibaraki.jp +yachiyo.ibaraki.jp +yamagata.ibaraki.jp +yawara.ibaraki.jp +yuki.ibaraki.jp +anamizu.ishikawa.jp +hakui.ishikawa.jp +hakusan.ishikawa.jp +kaga.ishikawa.jp +kahoku.ishikawa.jp +kanazawa.ishikawa.jp +kawakita.ishikawa.jp +komatsu.ishikawa.jp +nakanoto.ishikawa.jp +nanao.ishikawa.jp +nomi.ishikawa.jp +nonoichi.ishikawa.jp +noto.ishikawa.jp +shika.ishikawa.jp +suzu.ishikawa.jp +tsubata.ishikawa.jp +tsurugi.ishikawa.jp +uchinada.ishikawa.jp +wajima.ishikawa.jp +fudai.iwate.jp +fujisawa.iwate.jp +hanamaki.iwate.jp +hiraizumi.iwate.jp +hirono.iwate.jp +ichinohe.iwate.jp +ichinoseki.iwate.jp +iwaizumi.iwate.jp +iwate.iwate.jp +joboji.iwate.jp +kamaishi.iwate.jp +kanegasaki.iwate.jp +karumai.iwate.jp +kawai.iwate.jp +kitakami.iwate.jp +kuji.iwate.jp +kunohe.iwate.jp +kuzumaki.iwate.jp +miyako.iwate.jp +mizusawa.iwate.jp +morioka.iwate.jp +ninohe.iwate.jp +noda.iwate.jp +ofunato.iwate.jp +oshu.iwate.jp +otsuchi.iwate.jp +rikuzentakata.iwate.jp +shiwa.iwate.jp +shizukuishi.iwate.jp +sumita.iwate.jp +tanohata.iwate.jp +tono.iwate.jp +yahaba.iwate.jp +yamada.iwate.jp +ayagawa.kagawa.jp +higashikagawa.kagawa.jp +kanonji.kagawa.jp +kotohira.kagawa.jp +manno.kagawa.jp +marugame.kagawa.jp +mitoyo.kagawa.jp +naoshima.kagawa.jp +sanuki.kagawa.jp +tadotsu.kagawa.jp +takamatsu.kagawa.jp +tonosho.kagawa.jp +uchinomi.kagawa.jp +utazu.kagawa.jp +zentsuji.kagawa.jp +akune.kagoshima.jp +amami.kagoshima.jp +hioki.kagoshima.jp +isa.kagoshima.jp +isen.kagoshima.jp +izumi.kagoshima.jp +kagoshima.kagoshima.jp +kanoya.kagoshima.jp +kawanabe.kagoshima.jp +kinko.kagoshima.jp +kouyama.kagoshima.jp +makurazaki.kagoshima.jp +matsumoto.kagoshima.jp +minamitane.kagoshima.jp +nakatane.kagoshima.jp +nishinoomote.kagoshima.jp +satsumasendai.kagoshima.jp +soo.kagoshima.jp +tarumizu.kagoshima.jp +yusui.kagoshima.jp +aikawa.kanagawa.jp +atsugi.kanagawa.jp +ayase.kanagawa.jp +chigasaki.kanagawa.jp +ebina.kanagawa.jp +fujisawa.kanagawa.jp +hadano.kanagawa.jp +hakone.kanagawa.jp +hiratsuka.kanagawa.jp +isehara.kanagawa.jp +kaisei.kanagawa.jp +kamakura.kanagawa.jp +kiyokawa.kanagawa.jp +matsuda.kanagawa.jp +minamiashigara.kanagawa.jp +miura.kanagawa.jp +nakai.kanagawa.jp +ninomiya.kanagawa.jp +odawara.kanagawa.jp +oi.kanagawa.jp +oiso.kanagawa.jp +sagamihara.kanagawa.jp +samukawa.kanagawa.jp +tsukui.kanagawa.jp +yamakita.kanagawa.jp +yamato.kanagawa.jp +yokosuka.kanagawa.jp +yugawara.kanagawa.jp +zama.kanagawa.jp +zushi.kanagawa.jp +aki.kochi.jp +geisei.kochi.jp +hidaka.kochi.jp +higashitsuno.kochi.jp +ino.kochi.jp +kagami.kochi.jp +kami.kochi.jp +kitagawa.kochi.jp +kochi.kochi.jp +mihara.kochi.jp +motoyama.kochi.jp +muroto.kochi.jp +nahari.kochi.jp +nakamura.kochi.jp +nankoku.kochi.jp +nishitosa.kochi.jp +niyodogawa.kochi.jp +ochi.kochi.jp +okawa.kochi.jp +otoyo.kochi.jp +otsuki.kochi.jp +sakawa.kochi.jp +sukumo.kochi.jp +susaki.kochi.jp +tosa.kochi.jp +tosashimizu.kochi.jp +toyo.kochi.jp +tsuno.kochi.jp +umaji.kochi.jp +yasuda.kochi.jp +yusuhara.kochi.jp +amakusa.kumamoto.jp +arao.kumamoto.jp +aso.kumamoto.jp +choyo.kumamoto.jp +gyokuto.kumamoto.jp +kamiamakusa.kumamoto.jp +kikuchi.kumamoto.jp +kumamoto.kumamoto.jp +mashiki.kumamoto.jp +mifune.kumamoto.jp +minamata.kumamoto.jp +minamioguni.kumamoto.jp +nagasu.kumamoto.jp +nishihara.kumamoto.jp +oguni.kumamoto.jp +ozu.kumamoto.jp +sumoto.kumamoto.jp +takamori.kumamoto.jp +uki.kumamoto.jp +uto.kumamoto.jp +yamaga.kumamoto.jp +yamato.kumamoto.jp +yatsushiro.kumamoto.jp +ayabe.kyoto.jp +fukuchiyama.kyoto.jp +higashiyama.kyoto.jp +ide.kyoto.jp +ine.kyoto.jp +joyo.kyoto.jp +kameoka.kyoto.jp +kamo.kyoto.jp +kita.kyoto.jp +kizu.kyoto.jp +kumiyama.kyoto.jp +kyotamba.kyoto.jp +kyotanabe.kyoto.jp +kyotango.kyoto.jp +maizuru.kyoto.jp +minami.kyoto.jp +minamiyamashiro.kyoto.jp +miyazu.kyoto.jp +muko.kyoto.jp +nagaokakyo.kyoto.jp +nakagyo.kyoto.jp +nantan.kyoto.jp +oyamazaki.kyoto.jp +sakyo.kyoto.jp +seika.kyoto.jp +tanabe.kyoto.jp +uji.kyoto.jp +ujitawara.kyoto.jp +wazuka.kyoto.jp +yamashina.kyoto.jp +yawata.kyoto.jp +asahi.mie.jp +inabe.mie.jp +ise.mie.jp +kameyama.mie.jp +kawagoe.mie.jp +kiho.mie.jp +kisosaki.mie.jp +kiwa.mie.jp +komono.mie.jp +kumano.mie.jp +kuwana.mie.jp +matsusaka.mie.jp +meiwa.mie.jp +mihama.mie.jp +minamiise.mie.jp +misugi.mie.jp +miyama.mie.jp +nabari.mie.jp +shima.mie.jp +suzuka.mie.jp +tado.mie.jp +taiki.mie.jp +taki.mie.jp +tamaki.mie.jp +toba.mie.jp +tsu.mie.jp +udono.mie.jp +ureshino.mie.jp +watarai.mie.jp +yokkaichi.mie.jp +furukawa.miyagi.jp +higashimatsushima.miyagi.jp +ishinomaki.miyagi.jp +iwanuma.miyagi.jp +kakuda.miyagi.jp +kami.miyagi.jp +kawasaki.miyagi.jp +marumori.miyagi.jp +matsushima.miyagi.jp +minamisanriku.miyagi.jp +misato.miyagi.jp +murata.miyagi.jp +natori.miyagi.jp +ogawara.miyagi.jp +ohira.miyagi.jp +onagawa.miyagi.jp +osaki.miyagi.jp +rifu.miyagi.jp +semine.miyagi.jp +shibata.miyagi.jp +shichikashuku.miyagi.jp +shikama.miyagi.jp +shiogama.miyagi.jp +shiroishi.miyagi.jp +tagajo.miyagi.jp +taiwa.miyagi.jp +tome.miyagi.jp +tomiya.miyagi.jp +wakuya.miyagi.jp +watari.miyagi.jp +yamamoto.miyagi.jp +zao.miyagi.jp +aya.miyazaki.jp +ebino.miyazaki.jp +gokase.miyazaki.jp +hyuga.miyazaki.jp +kadogawa.miyazaki.jp +kawaminami.miyazaki.jp +kijo.miyazaki.jp +kitagawa.miyazaki.jp +kitakata.miyazaki.jp +kitaura.miyazaki.jp +kobayashi.miyazaki.jp +kunitomi.miyazaki.jp +kushima.miyazaki.jp +mimata.miyazaki.jp +miyakonojo.miyazaki.jp +miyazaki.miyazaki.jp +morotsuka.miyazaki.jp +nichinan.miyazaki.jp +nishimera.miyazaki.jp +nobeoka.miyazaki.jp +saito.miyazaki.jp +shiiba.miyazaki.jp +shintomi.miyazaki.jp +takaharu.miyazaki.jp +takanabe.miyazaki.jp +takazaki.miyazaki.jp +tsuno.miyazaki.jp +achi.nagano.jp +agematsu.nagano.jp +anan.nagano.jp +aoki.nagano.jp +asahi.nagano.jp +azumino.nagano.jp +chikuhoku.nagano.jp +chikuma.nagano.jp +chino.nagano.jp +fujimi.nagano.jp +hakuba.nagano.jp +hara.nagano.jp +hiraya.nagano.jp +iida.nagano.jp +iijima.nagano.jp +iiyama.nagano.jp +iizuna.nagano.jp +ikeda.nagano.jp +ikusaka.nagano.jp +ina.nagano.jp +karuizawa.nagano.jp +kawakami.nagano.jp +kiso.nagano.jp +kisofukushima.nagano.jp +kitaaiki.nagano.jp +komagane.nagano.jp +komoro.nagano.jp +matsukawa.nagano.jp +matsumoto.nagano.jp +miasa.nagano.jp +minamiaiki.nagano.jp +minamimaki.nagano.jp +minamiminowa.nagano.jp +minowa.nagano.jp +miyada.nagano.jp +miyota.nagano.jp +mochizuki.nagano.jp +nagano.nagano.jp +nagawa.nagano.jp +nagiso.nagano.jp +nakagawa.nagano.jp +nakano.nagano.jp +nozawaonsen.nagano.jp +obuse.nagano.jp +ogawa.nagano.jp +okaya.nagano.jp +omachi.nagano.jp +omi.nagano.jp +ookuwa.nagano.jp +ooshika.nagano.jp +otaki.nagano.jp +otari.nagano.jp +sakae.nagano.jp +sakaki.nagano.jp +saku.nagano.jp +sakuho.nagano.jp +shimosuwa.nagano.jp +shinanomachi.nagano.jp +shiojiri.nagano.jp +suwa.nagano.jp +suzaka.nagano.jp +takagi.nagano.jp +takamori.nagano.jp +takayama.nagano.jp +tateshina.nagano.jp +tatsuno.nagano.jp +togakushi.nagano.jp +togura.nagano.jp +tomi.nagano.jp +ueda.nagano.jp +wada.nagano.jp +yamagata.nagano.jp +yamanouchi.nagano.jp +yasaka.nagano.jp +yasuoka.nagano.jp +chijiwa.nagasaki.jp +futsu.nagasaki.jp +goto.nagasaki.jp +hasami.nagasaki.jp +hirado.nagasaki.jp +iki.nagasaki.jp +isahaya.nagasaki.jp +kawatana.nagasaki.jp +kuchinotsu.nagasaki.jp +matsuura.nagasaki.jp +nagasaki.nagasaki.jp +obama.nagasaki.jp +omura.nagasaki.jp +oseto.nagasaki.jp +saikai.nagasaki.jp +sasebo.nagasaki.jp +seihi.nagasaki.jp +shimabara.nagasaki.jp +shinkamigoto.nagasaki.jp +togitsu.nagasaki.jp +tsushima.nagasaki.jp +unzen.nagasaki.jp +ando.nara.jp +gose.nara.jp +heguri.nara.jp +higashiyoshino.nara.jp +ikaruga.nara.jp +ikoma.nara.jp +kamikitayama.nara.jp +kanmaki.nara.jp +kashiba.nara.jp +kashihara.nara.jp +katsuragi.nara.jp +kawai.nara.jp +kawakami.nara.jp +kawanishi.nara.jp +koryo.nara.jp +kurotaki.nara.jp +mitsue.nara.jp +miyake.nara.jp +nara.nara.jp +nosegawa.nara.jp +oji.nara.jp +ouda.nara.jp +oyodo.nara.jp +sakurai.nara.jp +sango.nara.jp +shimoichi.nara.jp +shimokitayama.nara.jp +shinjo.nara.jp +soni.nara.jp +takatori.nara.jp +tawaramoto.nara.jp +tenkawa.nara.jp +tenri.nara.jp +uda.nara.jp +yamatokoriyama.nara.jp +yamatotakada.nara.jp +yamazoe.nara.jp +yoshino.nara.jp +aga.niigata.jp +agano.niigata.jp +gosen.niigata.jp +itoigawa.niigata.jp +izumozaki.niigata.jp +joetsu.niigata.jp +kamo.niigata.jp +kariwa.niigata.jp +kashiwazaki.niigata.jp +minamiuonuma.niigata.jp +mitsuke.niigata.jp +muika.niigata.jp +murakami.niigata.jp +myoko.niigata.jp +nagaoka.niigata.jp +niigata.niigata.jp +ojiya.niigata.jp +omi.niigata.jp +sado.niigata.jp +sanjo.niigata.jp +seiro.niigata.jp +seirou.niigata.jp +sekikawa.niigata.jp +shibata.niigata.jp +tagami.niigata.jp +tainai.niigata.jp +tochio.niigata.jp +tokamachi.niigata.jp +tsubame.niigata.jp +tsunan.niigata.jp +uonuma.niigata.jp +yahiko.niigata.jp +yoita.niigata.jp +yuzawa.niigata.jp +beppu.oita.jp +bungoono.oita.jp +bungotakada.oita.jp +hasama.oita.jp +hiji.oita.jp +himeshima.oita.jp +hita.oita.jp +kamitsue.oita.jp +kokonoe.oita.jp +kuju.oita.jp +kunisaki.oita.jp +kusu.oita.jp +oita.oita.jp +saiki.oita.jp +taketa.oita.jp +tsukumi.oita.jp +usa.oita.jp +usuki.oita.jp +yufu.oita.jp +akaiwa.okayama.jp +asakuchi.okayama.jp +bizen.okayama.jp +hayashima.okayama.jp +ibara.okayama.jp +kagamino.okayama.jp +kasaoka.okayama.jp +kibichuo.okayama.jp +kumenan.okayama.jp +kurashiki.okayama.jp +maniwa.okayama.jp +misaki.okayama.jp +nagi.okayama.jp +niimi.okayama.jp +nishiawakura.okayama.jp +okayama.okayama.jp +satosho.okayama.jp +setouchi.okayama.jp +shinjo.okayama.jp +shoo.okayama.jp +soja.okayama.jp +takahashi.okayama.jp +tamano.okayama.jp +tsuyama.okayama.jp +wake.okayama.jp +yakage.okayama.jp +aguni.okinawa.jp +ginowan.okinawa.jp +ginoza.okinawa.jp +gushikami.okinawa.jp +haebaru.okinawa.jp +higashi.okinawa.jp +hirara.okinawa.jp +iheya.okinawa.jp +ishigaki.okinawa.jp +ishikawa.okinawa.jp +itoman.okinawa.jp +izena.okinawa.jp +kadena.okinawa.jp +kin.okinawa.jp +kitadaito.okinawa.jp +kitanakagusuku.okinawa.jp +kumejima.okinawa.jp +kunigami.okinawa.jp +minamidaito.okinawa.jp +motobu.okinawa.jp +nago.okinawa.jp +naha.okinawa.jp +nakagusuku.okinawa.jp +nakijin.okinawa.jp +nanjo.okinawa.jp +nishihara.okinawa.jp +ogimi.okinawa.jp +okinawa.okinawa.jp +onna.okinawa.jp +shimoji.okinawa.jp +taketomi.okinawa.jp +tarama.okinawa.jp +tokashiki.okinawa.jp +tomigusuku.okinawa.jp +tonaki.okinawa.jp +urasoe.okinawa.jp +uruma.okinawa.jp +yaese.okinawa.jp +yomitan.okinawa.jp +yonabaru.okinawa.jp +yonaguni.okinawa.jp +zamami.okinawa.jp +abeno.osaka.jp +chihayaakasaka.osaka.jp +chuo.osaka.jp +daito.osaka.jp +fujiidera.osaka.jp +habikino.osaka.jp +hannan.osaka.jp +higashiosaka.osaka.jp +higashisumiyoshi.osaka.jp +higashiyodogawa.osaka.jp +hirakata.osaka.jp +ibaraki.osaka.jp +ikeda.osaka.jp +izumi.osaka.jp +izumiotsu.osaka.jp +izumisano.osaka.jp +kadoma.osaka.jp +kaizuka.osaka.jp +kanan.osaka.jp +kashiwara.osaka.jp +katano.osaka.jp +kawachinagano.osaka.jp +kishiwada.osaka.jp +kita.osaka.jp +kumatori.osaka.jp +matsubara.osaka.jp +minato.osaka.jp +minoh.osaka.jp +misaki.osaka.jp +moriguchi.osaka.jp +neyagawa.osaka.jp +nishi.osaka.jp +nose.osaka.jp +osakasayama.osaka.jp +sakai.osaka.jp +sayama.osaka.jp +sennan.osaka.jp +settsu.osaka.jp +shijonawate.osaka.jp +shimamoto.osaka.jp +suita.osaka.jp +tadaoka.osaka.jp +taishi.osaka.jp +tajiri.osaka.jp +takaishi.osaka.jp +takatsuki.osaka.jp +tondabayashi.osaka.jp +toyonaka.osaka.jp +toyono.osaka.jp +yao.osaka.jp +ariake.saga.jp +arita.saga.jp +fukudomi.saga.jp +genkai.saga.jp +hamatama.saga.jp +hizen.saga.jp +imari.saga.jp +kamimine.saga.jp +kanzaki.saga.jp +karatsu.saga.jp +kashima.saga.jp +kitagata.saga.jp +kitahata.saga.jp +kiyama.saga.jp +kouhoku.saga.jp +kyuragi.saga.jp +nishiarita.saga.jp +ogi.saga.jp +omachi.saga.jp +ouchi.saga.jp +saga.saga.jp +shiroishi.saga.jp +taku.saga.jp +tara.saga.jp +tosu.saga.jp +yoshinogari.saga.jp +arakawa.saitama.jp +asaka.saitama.jp +chichibu.saitama.jp +fujimi.saitama.jp +fujimino.saitama.jp +fukaya.saitama.jp +hanno.saitama.jp +hanyu.saitama.jp +hasuda.saitama.jp +hatogaya.saitama.jp +hatoyama.saitama.jp +hidaka.saitama.jp +higashichichibu.saitama.jp +higashimatsuyama.saitama.jp +honjo.saitama.jp +ina.saitama.jp +iruma.saitama.jp +iwatsuki.saitama.jp +kamiizumi.saitama.jp +kamikawa.saitama.jp +kamisato.saitama.jp +kasukabe.saitama.jp +kawagoe.saitama.jp +kawaguchi.saitama.jp +kawajima.saitama.jp +kazo.saitama.jp +kitamoto.saitama.jp +koshigaya.saitama.jp +kounosu.saitama.jp +kuki.saitama.jp +kumagaya.saitama.jp +matsubushi.saitama.jp +minano.saitama.jp +misato.saitama.jp +miyashiro.saitama.jp +miyoshi.saitama.jp +moroyama.saitama.jp +nagatoro.saitama.jp +namegawa.saitama.jp +niiza.saitama.jp +ogano.saitama.jp +ogawa.saitama.jp +ogose.saitama.jp +okegawa.saitama.jp +omiya.saitama.jp +otaki.saitama.jp +ranzan.saitama.jp +ryokami.saitama.jp +saitama.saitama.jp +sakado.saitama.jp +satte.saitama.jp +sayama.saitama.jp +shiki.saitama.jp +shiraoka.saitama.jp +soka.saitama.jp +sugito.saitama.jp +toda.saitama.jp +tokigawa.saitama.jp +tokorozawa.saitama.jp +tsurugashima.saitama.jp +urawa.saitama.jp +warabi.saitama.jp +yashio.saitama.jp +yokoze.saitama.jp +yono.saitama.jp +yorii.saitama.jp +yoshida.saitama.jp +yoshikawa.saitama.jp +yoshimi.saitama.jp +aisho.shiga.jp +gamo.shiga.jp +higashiomi.shiga.jp +hikone.shiga.jp +koka.shiga.jp +konan.shiga.jp +kosei.shiga.jp +koto.shiga.jp +kusatsu.shiga.jp +maibara.shiga.jp +moriyama.shiga.jp +nagahama.shiga.jp +nishiazai.shiga.jp +notogawa.shiga.jp +omihachiman.shiga.jp +otsu.shiga.jp +ritto.shiga.jp +ryuoh.shiga.jp +takashima.shiga.jp +takatsuki.shiga.jp +torahime.shiga.jp +toyosato.shiga.jp +yasu.shiga.jp +akagi.shimane.jp +ama.shimane.jp +gotsu.shimane.jp +hamada.shimane.jp +higashiizumo.shimane.jp +hikawa.shimane.jp +hikimi.shimane.jp +izumo.shimane.jp +kakinoki.shimane.jp +masuda.shimane.jp +matsue.shimane.jp +misato.shimane.jp +nishinoshima.shimane.jp +ohda.shimane.jp +okinoshima.shimane.jp +okuizumo.shimane.jp +shimane.shimane.jp +tamayu.shimane.jp +tsuwano.shimane.jp +unnan.shimane.jp +yakumo.shimane.jp +yasugi.shimane.jp +yatsuka.shimane.jp +arai.shizuoka.jp +atami.shizuoka.jp +fuji.shizuoka.jp +fujieda.shizuoka.jp +fujikawa.shizuoka.jp +fujinomiya.shizuoka.jp +fukuroi.shizuoka.jp +gotemba.shizuoka.jp +haibara.shizuoka.jp +hamamatsu.shizuoka.jp +higashiizu.shizuoka.jp +ito.shizuoka.jp +iwata.shizuoka.jp +izu.shizuoka.jp +izunokuni.shizuoka.jp +kakegawa.shizuoka.jp +kannami.shizuoka.jp +kawanehon.shizuoka.jp +kawazu.shizuoka.jp +kikugawa.shizuoka.jp +kosai.shizuoka.jp +makinohara.shizuoka.jp +matsuzaki.shizuoka.jp +minamiizu.shizuoka.jp +mishima.shizuoka.jp +morimachi.shizuoka.jp +nishiizu.shizuoka.jp +numazu.shizuoka.jp +omaezaki.shizuoka.jp +shimada.shizuoka.jp +shimizu.shizuoka.jp +shimoda.shizuoka.jp +shizuoka.shizuoka.jp +susono.shizuoka.jp +yaizu.shizuoka.jp +yoshida.shizuoka.jp +ashikaga.tochigi.jp +bato.tochigi.jp +haga.tochigi.jp +ichikai.tochigi.jp +iwafune.tochigi.jp +kaminokawa.tochigi.jp +kanuma.tochigi.jp +karasuyama.tochigi.jp +kuroiso.tochigi.jp +mashiko.tochigi.jp +mibu.tochigi.jp +moka.tochigi.jp +motegi.tochigi.jp +nasu.tochigi.jp +nasushiobara.tochigi.jp +nikko.tochigi.jp +nishikata.tochigi.jp +nogi.tochigi.jp +ohira.tochigi.jp +ohtawara.tochigi.jp +oyama.tochigi.jp +sakura.tochigi.jp +sano.tochigi.jp +shimotsuke.tochigi.jp +shioya.tochigi.jp +takanezawa.tochigi.jp +tochigi.tochigi.jp +tsuga.tochigi.jp +ujiie.tochigi.jp +utsunomiya.tochigi.jp +yaita.tochigi.jp +aizumi.tokushima.jp +anan.tokushima.jp +ichiba.tokushima.jp +itano.tokushima.jp +kainan.tokushima.jp +komatsushima.tokushima.jp +matsushige.tokushima.jp +mima.tokushima.jp +minami.tokushima.jp +miyoshi.tokushima.jp +mugi.tokushima.jp +nakagawa.tokushima.jp +naruto.tokushima.jp +sanagochi.tokushima.jp +shishikui.tokushima.jp +tokushima.tokushima.jp +wajiki.tokushima.jp +adachi.tokyo.jp +akiruno.tokyo.jp +akishima.tokyo.jp +aogashima.tokyo.jp +arakawa.tokyo.jp +bunkyo.tokyo.jp +chiyoda.tokyo.jp +chofu.tokyo.jp +chuo.tokyo.jp +edogawa.tokyo.jp +fuchu.tokyo.jp +fussa.tokyo.jp +hachijo.tokyo.jp +hachioji.tokyo.jp +hamura.tokyo.jp +higashikurume.tokyo.jp +higashimurayama.tokyo.jp +higashiyamato.tokyo.jp +hino.tokyo.jp +hinode.tokyo.jp +hinohara.tokyo.jp +inagi.tokyo.jp +itabashi.tokyo.jp +katsushika.tokyo.jp +kita.tokyo.jp +kiyose.tokyo.jp +kodaira.tokyo.jp +koganei.tokyo.jp +kokubunji.tokyo.jp +komae.tokyo.jp +koto.tokyo.jp +kouzushima.tokyo.jp +kunitachi.tokyo.jp +machida.tokyo.jp +meguro.tokyo.jp +minato.tokyo.jp +mitaka.tokyo.jp +mizuho.tokyo.jp +musashimurayama.tokyo.jp +musashino.tokyo.jp +nakano.tokyo.jp +nerima.tokyo.jp +ogasawara.tokyo.jp +okutama.tokyo.jp +ome.tokyo.jp +oshima.tokyo.jp +ota.tokyo.jp +setagaya.tokyo.jp +shibuya.tokyo.jp +shinagawa.tokyo.jp +shinjuku.tokyo.jp +suginami.tokyo.jp +sumida.tokyo.jp +tachikawa.tokyo.jp +taito.tokyo.jp +tama.tokyo.jp +toshima.tokyo.jp +chizu.tottori.jp +hino.tottori.jp +kawahara.tottori.jp +koge.tottori.jp +kotoura.tottori.jp +misasa.tottori.jp +nanbu.tottori.jp +nichinan.tottori.jp +sakaiminato.tottori.jp +tottori.tottori.jp +wakasa.tottori.jp +yazu.tottori.jp +yonago.tottori.jp +asahi.toyama.jp +fuchu.toyama.jp +fukumitsu.toyama.jp +funahashi.toyama.jp +himi.toyama.jp +imizu.toyama.jp +inami.toyama.jp +johana.toyama.jp +kamiichi.toyama.jp +kurobe.toyama.jp +nakaniikawa.toyama.jp +namerikawa.toyama.jp +nanto.toyama.jp +nyuzen.toyama.jp +oyabe.toyama.jp +taira.toyama.jp +takaoka.toyama.jp +tateyama.toyama.jp +toga.toyama.jp +tonami.toyama.jp +toyama.toyama.jp +unazuki.toyama.jp +uozu.toyama.jp +yamada.toyama.jp +arida.wakayama.jp +aridagawa.wakayama.jp +gobo.wakayama.jp +hashimoto.wakayama.jp +hidaka.wakayama.jp +hirogawa.wakayama.jp +inami.wakayama.jp +iwade.wakayama.jp +kainan.wakayama.jp +kamitonda.wakayama.jp +katsuragi.wakayama.jp +kimino.wakayama.jp +kinokawa.wakayama.jp +kitayama.wakayama.jp +koya.wakayama.jp +koza.wakayama.jp +kozagawa.wakayama.jp +kudoyama.wakayama.jp +kushimoto.wakayama.jp +mihama.wakayama.jp +misato.wakayama.jp +nachikatsuura.wakayama.jp +shingu.wakayama.jp +shirahama.wakayama.jp +taiji.wakayama.jp +tanabe.wakayama.jp +wakayama.wakayama.jp +yuasa.wakayama.jp +yura.wakayama.jp +asahi.yamagata.jp +funagata.yamagata.jp +higashine.yamagata.jp +iide.yamagata.jp +kahoku.yamagata.jp +kaminoyama.yamagata.jp +kaneyama.yamagata.jp +kawanishi.yamagata.jp +mamurogawa.yamagata.jp +mikawa.yamagata.jp +murayama.yamagata.jp +nagai.yamagata.jp +nakayama.yamagata.jp +nanyo.yamagata.jp +nishikawa.yamagata.jp +obanazawa.yamagata.jp +oe.yamagata.jp +oguni.yamagata.jp +ohkura.yamagata.jp +oishida.yamagata.jp +sagae.yamagata.jp +sakata.yamagata.jp +sakegawa.yamagata.jp +shinjo.yamagata.jp +shirataka.yamagata.jp +shonai.yamagata.jp +takahata.yamagata.jp +tendo.yamagata.jp +tozawa.yamagata.jp +tsuruoka.yamagata.jp +yamagata.yamagata.jp +yamanobe.yamagata.jp +yonezawa.yamagata.jp +yuza.yamagata.jp +abu.yamaguchi.jp +hagi.yamaguchi.jp +hikari.yamaguchi.jp +hofu.yamaguchi.jp +iwakuni.yamaguchi.jp +kudamatsu.yamaguchi.jp +mitou.yamaguchi.jp +nagato.yamaguchi.jp +oshima.yamaguchi.jp +shimonoseki.yamaguchi.jp +shunan.yamaguchi.jp +tabuse.yamaguchi.jp +tokuyama.yamaguchi.jp +toyota.yamaguchi.jp +ube.yamaguchi.jp +yuu.yamaguchi.jp +chuo.yamanashi.jp +doshi.yamanashi.jp +fuefuki.yamanashi.jp +fujikawa.yamanashi.jp +fujikawaguchiko.yamanashi.jp +fujiyoshida.yamanashi.jp +hayakawa.yamanashi.jp +hokuto.yamanashi.jp +ichikawamisato.yamanashi.jp +kai.yamanashi.jp +kofu.yamanashi.jp +koshu.yamanashi.jp +kosuge.yamanashi.jp +minami-alps.yamanashi.jp +minobu.yamanashi.jp +nakamichi.yamanashi.jp +nanbu.yamanashi.jp +narusawa.yamanashi.jp +nirasaki.yamanashi.jp +nishikatsura.yamanashi.jp +oshino.yamanashi.jp +otsuki.yamanashi.jp +showa.yamanashi.jp +tabayama.yamanashi.jp +tsuru.yamanashi.jp +uenohara.yamanashi.jp +yamanakako.yamanashi.jp +yamanashi.yamanashi.jp + +// ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains +ke +ac.ke +co.ke +go.ke +info.ke +me.ke +mobi.ke +ne.ke +or.ke +sc.ke + +// kg : http://www.domain.kg/dmn_n.html +kg +com.kg +edu.kg +gov.kg +mil.kg +net.kg +org.kg + +// kh : https://trc.gov.kh +// Submitted by khnic@trc.gov.kh +kh +com.kh +edu.kh +gov.kh +net.kh +org.kh + +// ki : https://www.iana.org/domains/root/db/ki.html +ki +biz.ki +com.ki +edu.ki +gov.ki +info.ki +net.ki +org.ki + +// km : https://www.iana.org/domains/root/db/km.html +// http://www.domaine.km/documents/charte.doc +km +ass.km +com.km +edu.km +gov.km +mil.km +nom.km +org.km +prd.km +tm.km +// These are only mentioned as proposed suggestions at domaine.km, but +// https://www.iana.org/domains/root/db/km.html says they're available for registration: +asso.km +coop.km +gouv.km +medecin.km +notaires.km +pharmaciens.km +presse.km +veterinaire.km + +// kn : https://www.iana.org/domains/root/db/kn.html +// http://www.dot.kn/domainRules.html +kn +edu.kn +gov.kn +net.kn +org.kn + +// kp : http://www.kcce.kp/en_index.php +kp +com.kp +edu.kp +gov.kp +org.kp +rep.kp +tra.kp + +// kr : https://www.iana.org/domains/root/db/kr.html +// see also: https://krnic.kisa.or.kr/jsp/infoboard/law/domBylawsReg.jsp +kr +ac.kr +ai.kr +co.kr +es.kr +go.kr +hs.kr +io.kr +it.kr +kg.kr +me.kr +mil.kr +ms.kr +ne.kr +or.kr +pe.kr +re.kr +sc.kr +// kr geographical names +busan.kr +chungbuk.kr +chungnam.kr +daegu.kr +daejeon.kr +gangwon.kr +gwangju.kr +gyeongbuk.kr +gyeonggi.kr +gyeongnam.kr +incheon.kr +jeju.kr +jeonbuk.kr +jeonnam.kr +seoul.kr +ulsan.kr + +// kw : https://www.nic.kw/policies/ +// Confirmed by registry +kw +com.kw +edu.kw +emb.kw +gov.kw +ind.kw +net.kw +org.kw + +// ky : http://www.icta.ky/da_ky_reg_dom.php +// Confirmed by registry 2008-06-17 +ky +com.ky +edu.ky +net.ky +org.ky + +// kz : https://www.iana.org/domains/root/db/kz.html +// see also: http://www.nic.kz/rules/index.jsp +kz +com.kz +edu.kz +gov.kz +mil.kz +net.kz +org.kz + +// la : https://www.iana.org/domains/root/db/la.html +// Submitted by registry +la +com.la +edu.la +gov.la +info.la +int.la +net.la +org.la +per.la + +// lb : https://www.iana.org/domains/root/db/lb.html +// Submitted by registry +lb +com.lb +edu.lb +gov.lb +net.lb +org.lb + +// lc : https://www.iana.org/domains/root/db/lc.html +// see also: http://www.nic.lc/rules.htm +lc +co.lc +com.lc +edu.lc +gov.lc +net.lc +org.lc + +// li : https://www.iana.org/domains/root/db/li.html +li + +// lk : https://www.iana.org/domains/root/db/lk.html +lk +ac.lk +assn.lk +com.lk +edu.lk +gov.lk +grp.lk +hotel.lk +int.lk +ltd.lk +net.lk +ngo.lk +org.lk +sch.lk +soc.lk +web.lk + +// lr : http://psg.com/dns/lr/lr.txt +// Submitted by registry +lr +com.lr +edu.lr +gov.lr +net.lr +org.lr + +// ls : http://www.nic.ls/ +// Confirmed by registry +ls +ac.ls +biz.ls +co.ls +edu.ls +gov.ls +info.ls +net.ls +org.ls +sc.ls + +// lt : https://www.iana.org/domains/root/db/lt.html +lt +// gov.lt : http://www.gov.lt/index_en.php +gov.lt + +// lu : http://www.dns.lu/en/ +lu + +// lv : https://www.iana.org/domains/root/db/lv.html +lv +asn.lv +com.lv +conf.lv +edu.lv +gov.lv +id.lv +mil.lv +net.lv +org.lv + +// ly : http://www.nic.ly/regulations.php +ly +com.ly +edu.ly +gov.ly +id.ly +med.ly +net.ly +org.ly +plc.ly +sch.ly + +// ma : https://www.iana.org/domains/root/db/ma.html +// http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf +ma +ac.ma +co.ma +gov.ma +net.ma +org.ma +press.ma + +// mc : http://www.nic.mc/ +mc +asso.mc +tm.mc + +// md : https://www.iana.org/domains/root/db/md.html +md + +// me : https://www.iana.org/domains/root/db/me.html +me +ac.me +co.me +edu.me +gov.me +its.me +net.me +org.me +priv.me + +// mg : https://nic.mg +mg +co.mg +com.mg +edu.mg +gov.mg +mil.mg +nom.mg +org.mg +prd.mg + +// mh : https://www.iana.org/domains/root/db/mh.html +mh + +// mil : https://www.iana.org/domains/root/db/mil.html +mil + +// mk : https://www.iana.org/domains/root/db/mk.html +// see also: http://dns.marnet.net.mk/postapka.php +mk +com.mk +edu.mk +gov.mk +inf.mk +name.mk +net.mk +org.mk + +// ml : https://www.iana.org/domains/root/db/ml.html +// Confirmed by Boubacar NDIAYE 2024-12-31 +ml +ac.ml +art.ml +asso.ml +com.ml +edu.ml +gouv.ml +gov.ml +info.ml +inst.ml +net.ml +org.ml +pr.ml +presse.ml + +// mm : https://www.iana.org/domains/root/db/mm.html +*.mm + +// mn : https://www.iana.org/domains/root/db/mn.html +mn +edu.mn +gov.mn +org.mn + +// mo : http://www.monic.net.mo/ +mo +com.mo +edu.mo +gov.mo +net.mo +org.mo + +// mobi : https://www.iana.org/domains/root/db/mobi.html +mobi + +// mp : http://www.dot.mp/ +// Confirmed by registry 2008-06-17 +mp + +// mq : https://www.iana.org/domains/root/db/mq.html +mq + +// mr : https://www.iana.org/domains/root/db/mr.html +mr +gov.mr + +// ms : https://www.iana.org/domains/root/db/ms.html +ms +com.ms +edu.ms +gov.ms +net.ms +org.ms + +// mt : https://www.nic.org.mt/go/policy +// Submitted by registry +mt +com.mt +edu.mt +net.mt +org.mt + +// mu : https://www.iana.org/domains/root/db/mu.html +mu +ac.mu +co.mu +com.mu +gov.mu +net.mu +or.mu +org.mu + +// museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ +museum + +// mv : https://www.iana.org/domains/root/db/mv.html +// "mv" included because, contra Wikipedia, google.mv exists. +mv +aero.mv +biz.mv +com.mv +coop.mv +edu.mv +gov.mv +info.mv +int.mv +mil.mv +museum.mv +name.mv +net.mv +org.mv +pro.mv + +// mw : http://www.registrar.mw/ +mw +ac.mw +biz.mw +co.mw +com.mw +coop.mw +edu.mw +gov.mw +int.mw +net.mw +org.mw + +// mx : http://www.nic.mx/ +// Submitted by registry +mx +com.mx +edu.mx +gob.mx +net.mx +org.mx + +// my : http://www.mynic.my/ +// Available strings: https://mynic.my/resources/domains/buying-a-domain/ +my +biz.my +com.my +edu.my +gov.my +mil.my +name.my +net.my +org.my + +// mz : http://www.uem.mz/ +// Submitted by registry +mz +ac.mz +adv.mz +co.mz +edu.mz +gov.mz +mil.mz +net.mz +org.mz + +// na : http://www.na-nic.com.na/ +na +alt.na +co.na +com.na +gov.na +net.na +org.na + +// name : http://www.nic.name/ +// Regarding 2LDs: https://github.com/publicsuffix/list/issues/2306 +name + +// nc : http://www.cctld.nc/ +nc +asso.nc +nom.nc + +// ne : https://www.iana.org/domains/root/db/ne.html +ne + +// net : https://www.iana.org/domains/root/db/net.html +net + +// nf : https://www.iana.org/domains/root/db/nf.html +nf +arts.nf +com.nf +firm.nf +info.nf +net.nf +other.nf +per.nf +rec.nf +store.nf +web.nf + +// ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds +ng +com.ng +edu.ng +gov.ng +i.ng +mil.ng +mobi.ng +name.ng +net.ng +org.ng +sch.ng + +// ni : http://www.nic.ni/ +ni +ac.ni +biz.ni +co.ni +com.ni +edu.ni +gob.ni +in.ni +info.ni +int.ni +mil.ni +net.ni +nom.ni +org.ni +web.ni + +// nl : https://www.iana.org/domains/root/db/nl.html +// https://www.sidn.nl/ +nl + +// no : https://www.norid.no/en/om-domenenavn/regelverk-for-no/ +// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ +// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ +// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ +// RSS feed: https://teknisk.norid.no/en/feed/ +no +// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ +fhs.no +folkebibl.no +fylkesbibl.no +idrett.no +museum.no +priv.no +vgs.no +// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ +dep.no +herad.no +kommune.no +mil.no +stat.no +// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ +// counties +aa.no +ah.no +bu.no +fm.no +hl.no +hm.no +jan-mayen.no +mr.no +nl.no +nt.no +of.no +ol.no +oslo.no +rl.no +sf.no +st.no +svalbard.no +tm.no +tr.no +va.no +vf.no +// primary and lower secondary schools per county +gs.aa.no +gs.ah.no +gs.bu.no +gs.fm.no +gs.hl.no +gs.hm.no +gs.jan-mayen.no +gs.mr.no +gs.nl.no +gs.nt.no +gs.of.no +gs.ol.no +gs.oslo.no +gs.rl.no +gs.sf.no +gs.st.no +gs.svalbard.no +gs.tm.no +gs.tr.no +gs.va.no +gs.vf.no +// cities +akrehamn.no +åkrehamn.no +algard.no +ålgård.no +arna.no +bronnoysund.no +brønnøysund.no +brumunddal.no +bryne.no +drobak.no +drøbak.no +egersund.no +fetsund.no +floro.no +florø.no +fredrikstad.no +hokksund.no +honefoss.no +hønefoss.no +jessheim.no +jorpeland.no +jørpeland.no +kirkenes.no +kopervik.no +krokstadelva.no +langevag.no +langevåg.no +leirvik.no +mjondalen.no +mjøndalen.no +mo-i-rana.no +mosjoen.no +mosjøen.no +nesoddtangen.no +orkanger.no +osoyro.no +osøyro.no +raholt.no +råholt.no +sandnessjoen.no +sandnessjøen.no +skedsmokorset.no +slattum.no +spjelkavik.no +stathelle.no +stavern.no +stjordalshalsen.no +stjørdalshalsen.no +tananger.no +tranby.no +vossevangen.no +// communities +aarborte.no +aejrie.no +afjord.no +åfjord.no +agdenes.no +nes.akershus.no +aknoluokta.no +ákŋoluokta.no +al.no +ål.no +alaheadju.no +álaheadju.no +alesund.no +ålesund.no +alstahaug.no +alta.no +áltá.no +alvdal.no +amli.no +åmli.no +amot.no +åmot.no +andasuolo.no +andebu.no +andoy.no +andøy.no +ardal.no +årdal.no +aremark.no +arendal.no +ås.no +aseral.no +åseral.no +asker.no +askim.no +askoy.no +askøy.no +askvoll.no +asnes.no +åsnes.no +audnedaln.no +aukra.no +aure.no +aurland.no +aurskog-holand.no +aurskog-høland.no +austevoll.no +austrheim.no +averoy.no +averøy.no +badaddja.no +bådåddjå.no +bærum.no +bahcavuotna.no +báhcavuotna.no +bahccavuotna.no +báhccavuotna.no +baidar.no +báidár.no +bajddar.no +bájddar.no +balat.no +bálát.no +balestrand.no +ballangen.no +balsfjord.no +bamble.no +bardu.no +barum.no +batsfjord.no +båtsfjord.no +bearalvahki.no +bearalváhki.no +beardu.no +beiarn.no +berg.no +bergen.no +berlevag.no +berlevåg.no +bievat.no +bievát.no +bindal.no +birkenes.no +bjerkreim.no +bjugn.no +bodo.no +bodø.no +bokn.no +bomlo.no +bømlo.no +bremanger.no +bronnoy.no +brønnøy.no +budejju.no +nes.buskerud.no +bygland.no +bykle.no +cahcesuolo.no +čáhcesuolo.no +davvenjarga.no +davvenjárga.no +davvesiida.no +deatnu.no +dielddanuorri.no +divtasvuodna.no +divttasvuotna.no +donna.no +dønna.no +dovre.no +drammen.no +drangedal.no +dyroy.no +dyrøy.no +eid.no +eidfjord.no +eidsberg.no +eidskog.no +eidsvoll.no +eigersund.no +elverum.no +enebakk.no +engerdal.no +etne.no +etnedal.no +evenassi.no +evenášši.no +evenes.no +evje-og-hornnes.no +farsund.no +fauske.no +fedje.no +fet.no +finnoy.no +finnøy.no +fitjar.no +fjaler.no +fjell.no +fla.no +flå.no +flakstad.no +flatanger.no +flekkefjord.no +flesberg.no +flora.no +folldal.no +forde.no +førde.no +forsand.no +fosnes.no +fræna.no +frana.no +frei.no +frogn.no +froland.no +frosta.no +froya.no +frøya.no +fuoisku.no +fuossko.no +fusa.no +fyresdal.no +gaivuotna.no +gáivuotna.no +galsa.no +gálsá.no +gamvik.no +gangaviika.no +gáŋgaviika.no +gaular.no +gausdal.no +giehtavuoatna.no +gildeskal.no +gildeskål.no +giske.no +gjemnes.no +gjerdrum.no +gjerstad.no +gjesdal.no +gjovik.no +gjøvik.no +gloppen.no +gol.no +gran.no +grane.no +granvin.no +gratangen.no +grimstad.no +grong.no +grue.no +gulen.no +guovdageaidnu.no +ha.no +hå.no +habmer.no +hábmer.no +hadsel.no +hægebostad.no +hagebostad.no +halden.no +halsa.no +hamar.no +hamaroy.no +hammarfeasta.no +hámmárfeasta.no +hammerfest.no +hapmir.no +hápmir.no +haram.no +hareid.no +harstad.no +hasvik.no +hattfjelldal.no +haugesund.no +os.hedmark.no +valer.hedmark.no +våler.hedmark.no +hemne.no +hemnes.no +hemsedal.no +hitra.no +hjartdal.no +hjelmeland.no +hobol.no +hobøl.no +hof.no +hol.no +hole.no +holmestrand.no +holtalen.no +holtålen.no +os.hordaland.no +hornindal.no +horten.no +hoyanger.no +høyanger.no +hoylandet.no +høylandet.no +hurdal.no +hurum.no +hvaler.no +hyllestad.no +ibestad.no +inderoy.no +inderøy.no +iveland.no +ivgu.no +jevnaker.no +jolster.no +jølster.no +jondal.no +kafjord.no +kåfjord.no +karasjohka.no +kárášjohka.no +karasjok.no +karlsoy.no +karmoy.no +karmøy.no +kautokeino.no +klabu.no +klæbu.no +klepp.no +kongsberg.no +kongsvinger.no +kraanghke.no +kråanghke.no +kragero.no +kragerø.no +kristiansand.no +kristiansund.no +krodsherad.no +krødsherad.no +kvæfjord.no +kvænangen.no +kvafjord.no +kvalsund.no +kvam.no +kvanangen.no +kvinesdal.no +kvinnherad.no +kviteseid.no +kvitsoy.no +kvitsøy.no +laakesvuemie.no +lærdal.no +lahppi.no +láhppi.no +lardal.no +larvik.no +lavagis.no +lavangen.no +leangaviika.no +leaŋgaviika.no +lebesby.no +leikanger.no +leirfjord.no +leka.no +leksvik.no +lenvik.no +lerdal.no +lesja.no +levanger.no +lier.no +lierne.no +lillehammer.no +lillesand.no +lindas.no +lindås.no +lindesnes.no +loabat.no +loabát.no +lodingen.no +lødingen.no +lom.no +loppa.no +lorenskog.no +lørenskog.no +loten.no +løten.no +lund.no +lunner.no +luroy.no +lurøy.no +luster.no +lyngdal.no +lyngen.no +malatvuopmi.no +málatvuopmi.no +malselv.no +målselv.no +malvik.no +mandal.no +marker.no +marnardal.no +masfjorden.no +masoy.no +måsøy.no +matta-varjjat.no +mátta-várjjat.no +meland.no +meldal.no +melhus.no +meloy.no +meløy.no +meraker.no +meråker.no +midsund.no +midtre-gauldal.no +moareke.no +moåreke.no +modalen.no +modum.no +molde.no +heroy.more-og-romsdal.no +sande.more-og-romsdal.no +herøy.møre-og-romsdal.no +sande.møre-og-romsdal.no +moskenes.no +moss.no +muosat.no +muosát.no +naamesjevuemie.no +nååmesjevuemie.no +nærøy.no +namdalseid.no +namsos.no +namsskogan.no +nannestad.no +naroy.no +narviika.no +narvik.no +naustdal.no +navuotna.no +návuotna.no +nedre-eiker.no +nesna.no +nesodden.no +nesseby.no +nesset.no +nissedal.no +nittedal.no +nord-aurdal.no +nord-fron.no +nord-odal.no +norddal.no +nordkapp.no +bo.nordland.no +bø.nordland.no +heroy.nordland.no +herøy.nordland.no +nordre-land.no +nordreisa.no +nore-og-uvdal.no +notodden.no +notteroy.no +nøtterøy.no +odda.no +oksnes.no +øksnes.no +omasvuotna.no +oppdal.no +oppegard.no +oppegård.no +orkdal.no +orland.no +ørland.no +orskog.no +ørskog.no +orsta.no +ørsta.no +osen.no +osteroy.no +osterøy.no +valer.ostfold.no +våler.østfold.no +ostre-toten.no +østre-toten.no +overhalla.no +ovre-eiker.no +øvre-eiker.no +oyer.no +øyer.no +oygarden.no +øygarden.no +oystre-slidre.no +øystre-slidre.no +porsanger.no +porsangu.no +porsáŋgu.no +porsgrunn.no +rade.no +råde.no +radoy.no +radøy.no +rælingen.no +rahkkeravju.no +ráhkkerávju.no +raisa.no +ráisa.no +rakkestad.no +ralingen.no +rana.no +randaberg.no +rauma.no +rendalen.no +rennebu.no +rennesoy.no +rennesøy.no +rindal.no +ringebu.no +ringerike.no +ringsaker.no +risor.no +risør.no +rissa.no +roan.no +rodoy.no +rødøy.no +rollag.no +romsa.no +romskog.no +rømskog.no +roros.no +røros.no +rost.no +røst.no +royken.no +røyken.no +royrvik.no +røyrvik.no +ruovat.no +rygge.no +salangen.no +salat.no +sálat.no +sálát.no +saltdal.no +samnanger.no +sandefjord.no +sandnes.no +sandoy.no +sandøy.no +sarpsborg.no +sauda.no +sauherad.no +sel.no +selbu.no +selje.no +seljord.no +siellak.no +sigdal.no +siljan.no +sirdal.no +skanit.no +skánit.no +skanland.no +skånland.no +skaun.no +skedsmo.no +ski.no +skien.no +skierva.no +skiervá.no +skiptvet.no +skjak.no +skjåk.no +skjervoy.no +skjervøy.no +skodje.no +smola.no +smøla.no +snaase.no +snåase.no +snasa.no +snåsa.no +snillfjord.no +snoasa.no +sogndal.no +sogne.no +søgne.no +sokndal.no +sola.no +solund.no +somna.no +sømna.no +sondre-land.no +søndre-land.no +songdalen.no +sor-aurdal.no +sør-aurdal.no +sor-fron.no +sør-fron.no +sor-odal.no +sør-odal.no +sor-varanger.no +sør-varanger.no +sorfold.no +sørfold.no +sorreisa.no +sørreisa.no +sortland.no +sorum.no +sørum.no +spydeberg.no +stange.no +stavanger.no +steigen.no +steinkjer.no +stjordal.no +stjørdal.no +stokke.no +stor-elvdal.no +stord.no +stordal.no +storfjord.no +strand.no +stranda.no +stryn.no +sula.no +suldal.no +sund.no +sunndal.no +surnadal.no +sveio.no +svelvik.no +sykkylven.no +tana.no +bo.telemark.no +bø.telemark.no +time.no +tingvoll.no +tinn.no +tjeldsund.no +tjome.no +tjøme.no +tokke.no +tolga.no +tonsberg.no +tønsberg.no +torsken.no +træna.no +trana.no +tranoy.no +tranøy.no +troandin.no +trogstad.no +trøgstad.no +tromsa.no +tromso.no +tromsø.no +trondheim.no +trysil.no +tvedestrand.no +tydal.no +tynset.no +tysfjord.no +tysnes.no +tysvær.no +tysvar.no +ullensaker.no +ullensvang.no +ulvik.no +unjarga.no +unjárga.no +utsira.no +vaapste.no +vadso.no +vadsø.no +værøy.no +vaga.no +vågå.no +vagan.no +vågan.no +vagsoy.no +vågsøy.no +vaksdal.no +valle.no +vang.no +vanylven.no +vardo.no +vardø.no +varggat.no +várggát.no +varoy.no +vefsn.no +vega.no +vegarshei.no +vegårshei.no +vennesla.no +verdal.no +verran.no +vestby.no +sande.vestfold.no +vestnes.no +vestre-slidre.no +vestre-toten.no +vestvagoy.no +vestvågøy.no +vevelstad.no +vik.no +vikna.no +vindafjord.no +voagat.no +volda.no +voss.no + +// np : http://www.mos.com.np/register.html +*.np + +// nr : http://cenpac.net.nr/dns/index.html +// Submitted by registry +nr +biz.nr +com.nr +edu.nr +gov.nr +info.nr +net.nr +org.nr + +// nu : https://www.iana.org/domains/root/db/nu.html +nu + +// nz : https://www.iana.org/domains/root/db/nz.html +// Submitted by registry +nz +ac.nz +co.nz +cri.nz +geek.nz +gen.nz +govt.nz +health.nz +iwi.nz +kiwi.nz +maori.nz +māori.nz +mil.nz +net.nz +org.nz +parliament.nz +school.nz + +// om : https://www.iana.org/domains/root/db/om.html +om +co.om +com.om +edu.om +gov.om +med.om +museum.om +net.om +org.om +pro.om + +// onion : https://tools.ietf.org/html/rfc7686 +onion + +// org : https://www.iana.org/domains/root/db/org.html +org + +// pa : http://www.nic.pa/ +// Some additional second level "domains" resolve directly as hostnames, such as +// pannet.pa, so we add a rule for "pa". +pa +abo.pa +ac.pa +com.pa +edu.pa +gob.pa +ing.pa +med.pa +net.pa +nom.pa +org.pa +sld.pa + +// pe : https://www.nic.pe/InformeFinalComision.pdf +pe +com.pe +edu.pe +gob.pe +mil.pe +net.pe +nom.pe +org.pe + +// pf : http://www.gobin.info/domainname/formulaire-pf.pdf +pf +com.pf +edu.pf +org.pf + +// pg : https://www.iana.org/domains/root/db/pg.html +*.pg + +// ph : https://www.iana.org/domains/root/db/ph.html +// Submitted by registry +ph +com.ph +edu.ph +gov.ph +i.ph +mil.ph +net.ph +ngo.ph +org.ph + +// pk : https://pk5.pknic.net.pk/pk5/msgNamepk.PK +// Contact Email: staff@pknic.net.pk +pk +ac.pk +biz.pk +com.pk +edu.pk +fam.pk +gkp.pk +gob.pk +gog.pk +gok.pk +gop.pk +gos.pk +gov.pk +net.pk +org.pk +web.pk + +// pl : https://www.dns.pl/en/ +// Confirmed by registry 2024-11-18 +pl +com.pl +net.pl +org.pl +// pl functional domains : https://www.dns.pl/en/list_of_functional_domain_names +agro.pl +aid.pl +atm.pl +auto.pl +biz.pl +edu.pl +gmina.pl +gsm.pl +info.pl +mail.pl +media.pl +miasta.pl +mil.pl +nieruchomosci.pl +nom.pl +pc.pl +powiat.pl +priv.pl +realestate.pl +rel.pl +sex.pl +shop.pl +sklep.pl +sos.pl +szkola.pl +targi.pl +tm.pl +tourism.pl +travel.pl +turystyka.pl +// Government domains : https://www.dns.pl/informacje_o_rejestracji_domen_gov_pl +// In accordance with the .gov.pl Domain Name Regulations : https://www.dns.pl/regulamin_gov_pl +gov.pl +ap.gov.pl +griw.gov.pl +ic.gov.pl +is.gov.pl +kmpsp.gov.pl +konsulat.gov.pl +kppsp.gov.pl +kwp.gov.pl +kwpsp.gov.pl +mup.gov.pl +mw.gov.pl +oia.gov.pl +oirm.gov.pl +oke.gov.pl +oow.gov.pl +oschr.gov.pl +oum.gov.pl +pa.gov.pl +pinb.gov.pl +piw.gov.pl +po.gov.pl +pr.gov.pl +psp.gov.pl +psse.gov.pl +pup.gov.pl +rzgw.gov.pl +sa.gov.pl +sdn.gov.pl +sko.gov.pl +so.gov.pl +sr.gov.pl +starostwo.gov.pl +ug.gov.pl +ugim.gov.pl +um.gov.pl +umig.gov.pl +upow.gov.pl +uppo.gov.pl +us.gov.pl +uw.gov.pl +uzs.gov.pl +wif.gov.pl +wiih.gov.pl +winb.gov.pl +wios.gov.pl +witd.gov.pl +wiw.gov.pl +wkz.gov.pl +wsa.gov.pl +wskr.gov.pl +wsse.gov.pl +wuoz.gov.pl +wzmiuw.gov.pl +zp.gov.pl +zpisdn.gov.pl +// pl regional domains : https://www.dns.pl/en/list_of_regional_domain_names +augustow.pl +babia-gora.pl +bedzin.pl +beskidy.pl +bialowieza.pl +bialystok.pl +bielawa.pl +bieszczady.pl +boleslawiec.pl +bydgoszcz.pl +bytom.pl +cieszyn.pl +czeladz.pl +czest.pl +dlugoleka.pl +elblag.pl +elk.pl +glogow.pl +gniezno.pl +gorlice.pl +grajewo.pl +ilawa.pl +jaworzno.pl +jelenia-gora.pl +jgora.pl +kalisz.pl +karpacz.pl +kartuzy.pl +kaszuby.pl +katowice.pl +kazimierz-dolny.pl +kepno.pl +ketrzyn.pl +klodzko.pl +kobierzyce.pl +kolobrzeg.pl +konin.pl +konskowola.pl +kutno.pl +lapy.pl +lebork.pl +legnica.pl +lezajsk.pl +limanowa.pl +lomza.pl +lowicz.pl +lubin.pl +lukow.pl +malbork.pl +malopolska.pl +mazowsze.pl +mazury.pl +mielec.pl +mielno.pl +mragowo.pl +naklo.pl +nowaruda.pl +nysa.pl +olawa.pl +olecko.pl +olkusz.pl +olsztyn.pl +opoczno.pl +opole.pl +ostroda.pl +ostroleka.pl +ostrowiec.pl +ostrowwlkp.pl +pila.pl +pisz.pl +podhale.pl +podlasie.pl +polkowice.pl +pomorskie.pl +pomorze.pl +prochowice.pl +pruszkow.pl +przeworsk.pl +pulawy.pl +radom.pl +rawa-maz.pl +rybnik.pl +rzeszow.pl +sanok.pl +sejny.pl +skoczow.pl +slask.pl +slupsk.pl +sosnowiec.pl +stalowa-wola.pl +starachowice.pl +stargard.pl +suwalki.pl +swidnica.pl +swiebodzin.pl +swinoujscie.pl +szczecin.pl +szczytno.pl +tarnobrzeg.pl +tgory.pl +turek.pl +tychy.pl +ustka.pl +walbrzych.pl +warmia.pl +warszawa.pl +waw.pl +wegrow.pl +wielun.pl +wlocl.pl +wloclawek.pl +wodzislaw.pl +wolomin.pl +wroclaw.pl +zachpomor.pl +zagan.pl +zarow.pl +zgora.pl +zgorzelec.pl + +// pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +pm + +// pn : https://www.iana.org/domains/root/db/pn.html +pn +co.pn +edu.pn +gov.pn +net.pn +org.pn + +// post : https://www.iana.org/domains/root/db/post.html +post + +// pr : http://www.nic.pr/index.asp?f=1 +pr +biz.pr +com.pr +edu.pr +gov.pr +info.pr +isla.pr +name.pr +net.pr +org.pr +pro.pr +// these aren't mentioned on nic.pr, but on https://www.iana.org/domains/root/db/pr.html +ac.pr +est.pr +prof.pr + +// pro : http://registry.pro/get-pro +pro +aaa.pro +aca.pro +acct.pro +avocat.pro +bar.pro +cpa.pro +eng.pro +jur.pro +law.pro +med.pro +recht.pro + +// ps : https://www.iana.org/domains/root/db/ps.html +// http://www.nic.ps/registration/policy.html#reg +ps +com.ps +edu.ps +gov.ps +net.ps +org.ps +plo.ps +sec.ps + +// pt : https://www.dns.pt/en/domain/pt-terms-and-conditions-registration-rules/ +pt +com.pt +edu.pt +gov.pt +int.pt +net.pt +nome.pt +org.pt +publ.pt + +// pw : https://www.iana.org/domains/root/db/pw.html +// Confirmed by registry in private correspondence with @dnsguru 2024-12-09 +pw +gov.pw + +// py : https://www.iana.org/domains/root/db/py.html +// Submitted by registry +py +com.py +coop.py +edu.py +gov.py +mil.py +net.py +org.py + +// qa : http://domains.qa/en/ +qa +com.qa +edu.qa +gov.qa +mil.qa +name.qa +net.qa +org.qa +sch.qa + +// re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +// Confirmed by registry 2024-11-18 +re +// Closed for registration on 2013-03-15 but domains are still maintained +asso.re +com.re + +// ro : http://www.rotld.ro/ +ro +arts.ro +com.ro +firm.ro +info.ro +nom.ro +nt.ro +org.ro +rec.ro +store.ro +tm.ro +www.ro + +// rs : https://www.rnids.rs/en/domains/national-domains +rs +ac.rs +co.rs +edu.rs +gov.rs +in.rs +org.rs + +// ru : https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf +// Submitted by George Georgievsky +ru + +// rw : https://www.iana.org/domains/root/db/rw.html +rw +ac.rw +co.rw +coop.rw +gov.rw +mil.rw +net.rw +org.rw + +// sa : http://www.nic.net.sa/ +sa +com.sa +edu.sa +gov.sa +med.sa +net.sa +org.sa +pub.sa +sch.sa + +// sb : http://www.sbnic.net.sb/ +// Submitted by registry +sb +com.sb +edu.sb +gov.sb +net.sb +org.sb + +// sc : http://www.nic.sc/ +sc +com.sc +edu.sc +gov.sc +net.sc +org.sc + +// sd : https://www.iana.org/domains/root/db/sd.html +// Submitted by registry +sd +com.sd +edu.sd +gov.sd +info.sd +med.sd +net.sd +org.sd +tv.sd + +// se : https://www.iana.org/domains/root/db/se.html +// https://data.internetstiftelsen.se/barred_domains_list.txt -> Second level domains & Sub-domains +// Confirmed by Registry Services 2024-11-20 +se +a.se +ac.se +b.se +bd.se +brand.se +c.se +d.se +e.se +f.se +fh.se +fhsk.se +fhv.se +g.se +h.se +i.se +k.se +komforb.se +kommunalforbund.se +komvux.se +l.se +lanbib.se +m.se +n.se +naturbruksgymn.se +o.se +org.se +p.se +parti.se +pp.se +press.se +r.se +s.se +t.se +tm.se +u.se +w.se +x.se +y.se +z.se + +// sg : https://www.sgnic.sg/domain-registration/sg-categories-rules +// Confirmed by registry 2024-11-19 +sg +com.sg +edu.sg +gov.sg +net.sg +org.sg + +// sh : http://nic.sh/rules.htm +sh +com.sh +gov.sh +mil.sh +net.sh +org.sh + +// si : https://www.iana.org/domains/root/db/si.html +si + +// sj : No registrations at this time. +// Submitted by registry +sj + +// sk : https://www.iana.org/domains/root/db/sk.html +// https://sk-nic.sk/ +sk +org.sk + +// sl : http://www.nic.sl +// Submitted by registry +sl +com.sl +edu.sl +gov.sl +net.sl +org.sl + +// sm : https://www.iana.org/domains/root/db/sm.html +sm + +// sn : https://www.iana.org/domains/root/db/sn.html +sn +art.sn +com.sn +edu.sn +gouv.sn +org.sn +univ.sn + +// so : http://sonic.so/policies/ +so +com.so +edu.so +gov.so +me.so +net.so +org.so + +// sr : https://www.iana.org/domains/root/db/sr.html +sr + +// ss : https://registry.nic.ss/ +// Submitted by registry +ss +biz.ss +co.ss +com.ss +edu.ss +gov.ss +me.ss +net.ss +org.ss +sch.ss + +// st : http://www.nic.st/html/policyrules/ +st +co.st +com.st +consulado.st +edu.st +embaixada.st +mil.st +net.st +org.st +principe.st +saotome.st +store.st + +// su : https://www.iana.org/domains/root/db/su.html +su + +// sv : https://www.iana.org/domains/root/db/sv.html +sv +com.sv +edu.sv +gob.sv +org.sv +red.sv + +// sx : https://www.iana.org/domains/root/db/sx.html +// Submitted by registry +sx +gov.sx + +// sy : https://www.iana.org/domains/root/db/sy.html +sy +com.sy +edu.sy +gov.sy +mil.sy +net.sy +org.sy + +// sz : https://www.iana.org/domains/root/db/sz.html +// http://www.sispa.org.sz/ +sz +ac.sz +co.sz +org.sz + +// tc : https://www.iana.org/domains/root/db/tc.html +tc + +// td : https://www.iana.org/domains/root/db/td.html +td + +// tel : https://www.iana.org/domains/root/db/tel.html +// http://www.telnic.org/ +tel + +// tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +tf + +// tg : https://www.iana.org/domains/root/db/tg.html +// http://www.nic.tg/ +tg + +// th : https://www.iana.org/domains/root/db/th.html +// Submitted by registry +th +ac.th +co.th +go.th +in.th +mi.th +net.th +or.th + +// tj : http://www.nic.tj/policy.html +tj +ac.tj +biz.tj +co.tj +com.tj +edu.tj +go.tj +gov.tj +int.tj +mil.tj +name.tj +net.tj +nic.tj +org.tj +test.tj +web.tj + +// tk : https://www.iana.org/domains/root/db/tk.html +tk + +// tl : https://www.iana.org/domains/root/db/tl.html +tl +gov.tl + +// tm : https://www.nic.tm/local.html +// Confirmed by registry 2024-11-19 +tm +co.tm +com.tm +edu.tm +gov.tm +mil.tm +net.tm +nom.tm +org.tm + +// tn : http://www.registre.tn/fr/ +// https://whois.ati.tn/ +tn +com.tn +ens.tn +fin.tn +gov.tn +ind.tn +info.tn +intl.tn +mincom.tn +nat.tn +net.tn +org.tn +perso.tn +tourism.tn + +// to : https://www.iana.org/domains/root/db/to.html +// Submitted by registry +to +com.to +edu.to +gov.to +mil.to +net.to +org.to + +// tr : https://nic.tr/ +// https://nic.tr/forms/eng/policies.pdf +// https://nic.tr/index.php?USRACTN=PRICELST +tr +av.tr +bbs.tr +bel.tr +biz.tr +com.tr +dr.tr +edu.tr +gen.tr +gov.tr +info.tr +k12.tr +kep.tr +mil.tr +name.tr +net.tr +org.tr +pol.tr +tel.tr +tsk.tr +tv.tr +web.tr +// Used by Northern Cyprus +nc.tr +// Used by government agencies of Northern Cyprus +gov.nc.tr + +// tt : https://www.nic.tt/ +// Confirmed by registry 2024-11-19 +tt +biz.tt +co.tt +com.tt +edu.tt +gov.tt +info.tt +mil.tt +name.tt +net.tt +org.tt +pro.tt + +// tv : https://www.iana.org/domains/root/db/tv.html +// Not listing any 2LDs as reserved since none seem to exist in practice, +// Wikipedia notwithstanding. +tv + +// tw : https://www.iana.org/domains/root/db/tw.html +// https://twnic.tw/dnservice_catag.php +// Confirmed by registry 2024-11-26 +tw +club.tw +com.tw +ebiz.tw +edu.tw +game.tw +gov.tw +idv.tw +mil.tw +net.tw +org.tw + +// tz : http://www.tznic.or.tz/index.php/domains +// Submitted by registry +tz +ac.tz +co.tz +go.tz +hotel.tz +info.tz +me.tz +mil.tz +mobi.tz +ne.tz +or.tz +sc.tz +tv.tz + +// ua : https://hostmaster.ua/policy/?ua +// Submitted by registry +ua +// ua 2LD +com.ua +edu.ua +gov.ua +in.ua +net.ua +org.ua +// ua geographic names +// https://hostmaster.ua/2ld/ +cherkassy.ua +cherkasy.ua +chernigov.ua +chernihiv.ua +chernivtsi.ua +chernovtsy.ua +ck.ua +cn.ua +cr.ua +crimea.ua +cv.ua +dn.ua +dnepropetrovsk.ua +dnipropetrovsk.ua +donetsk.ua +dp.ua +if.ua +ivano-frankivsk.ua +kh.ua +kharkiv.ua +kharkov.ua +kherson.ua +khmelnitskiy.ua +khmelnytskyi.ua +kiev.ua +kirovograd.ua +km.ua +kr.ua +kropyvnytskyi.ua +krym.ua +ks.ua +kv.ua +kyiv.ua +lg.ua +lt.ua +lugansk.ua +luhansk.ua +lutsk.ua +lv.ua +lviv.ua +mk.ua +mykolaiv.ua +nikolaev.ua +od.ua +odesa.ua +odessa.ua +pl.ua +poltava.ua +rivne.ua +rovno.ua +rv.ua +sb.ua +sebastopol.ua +sevastopol.ua +sm.ua +sumy.ua +te.ua +ternopil.ua +uz.ua +uzhgorod.ua +uzhhorod.ua +vinnica.ua +vinnytsia.ua +vn.ua +volyn.ua +yalta.ua +zakarpattia.ua +zaporizhzhe.ua +zaporizhzhia.ua +zhitomir.ua +zhytomyr.ua +zp.ua +zt.ua + +// ug : https://www.registry.co.ug/ +// https://www.registry.co.ug, https://whois.co.ug +// Confirmed by registry 2025-01-20 +ug +ac.ug +co.ug +com.ug +edu.ug +go.ug +gov.ug +mil.ug +ne.ug +or.ug +org.ug +sc.ug +us.ug + +// uk : https://www.iana.org/domains/root/db/uk.html +// Submitted by registry +uk +ac.uk +co.uk +gov.uk +ltd.uk +me.uk +net.uk +nhs.uk +org.uk +plc.uk +police.uk +*.sch.uk + +// us : https://www.iana.org/domains/root/db/us.html +// Confirmed via the .us zone file by William Harrison 2024-12-10 +us +dni.us +isa.us +nsn.us +// Geographic Names +ak.us +al.us +ar.us +as.us +az.us +ca.us +co.us +ct.us +dc.us +de.us +fl.us +ga.us +gu.us +hi.us +ia.us +id.us +il.us +in.us +ks.us +ky.us +la.us +ma.us +md.us +me.us +mi.us +mn.us +mo.us +ms.us +mt.us +nc.us +nd.us +ne.us +nh.us +nj.us +nm.us +nv.us +ny.us +oh.us +ok.us +or.us +pa.us +pr.us +ri.us +sc.us +sd.us +tn.us +tx.us +ut.us +va.us +vi.us +vt.us +wa.us +wi.us +wv.us +wy.us +// The registrar notes several more specific domains available in each state, +// such as state.*.us, dst.*.us, etc., but resolution of these is somewhat +// haphazard; in some states these domains resolve as addresses, while in others +// only subdomains are available, or even nothing at all. We include the +// most common ones where it's clear that different sites are different +// entities. +k12.ak.us +k12.al.us +k12.ar.us +k12.as.us +k12.az.us +k12.ca.us +k12.co.us +k12.ct.us +k12.dc.us +k12.fl.us +k12.ga.us +k12.gu.us +// k12.hi.us - Bug 614565 - Hawaii has a state-wide DOE login +k12.ia.us +k12.id.us +k12.il.us +k12.in.us +k12.ks.us +k12.ky.us +k12.la.us +k12.ma.us +k12.md.us +k12.me.us +k12.mi.us +k12.mn.us +k12.mo.us +k12.ms.us +k12.mt.us +k12.nc.us +// k12.nd.us - Bug 1028347 - Removed at request of Travis Rosso +k12.ne.us +k12.nh.us +k12.nj.us +k12.nm.us +k12.nv.us +k12.ny.us +k12.oh.us +k12.ok.us +k12.or.us +k12.pa.us +k12.pr.us +// k12.ri.us - Removed at request of Kim Cournoyer +k12.sc.us +// k12.sd.us - Bug 934131 - Removed at request of James Booze +k12.tn.us +k12.tx.us +k12.ut.us +k12.va.us +k12.vi.us +k12.vt.us +k12.wa.us +k12.wi.us +// k12.wv.us - Bug 947705 - Removed at request of Verne Britton +cc.ak.us +lib.ak.us +cc.al.us +lib.al.us +cc.ar.us +lib.ar.us +cc.as.us +lib.as.us +cc.az.us +lib.az.us +cc.ca.us +lib.ca.us +cc.co.us +lib.co.us +cc.ct.us +lib.ct.us +cc.dc.us +lib.dc.us +cc.de.us +cc.fl.us +lib.fl.us +cc.ga.us +lib.ga.us +cc.gu.us +lib.gu.us +cc.hi.us +lib.hi.us +cc.ia.us +lib.ia.us +cc.id.us +lib.id.us +cc.il.us +lib.il.us +cc.in.us +lib.in.us +cc.ks.us +lib.ks.us +cc.ky.us +lib.ky.us +cc.la.us +lib.la.us +cc.ma.us +lib.ma.us +cc.md.us +lib.md.us +cc.me.us +lib.me.us +cc.mi.us +lib.mi.us +cc.mn.us +lib.mn.us +cc.mo.us +lib.mo.us +cc.ms.us +cc.mt.us +lib.mt.us +cc.nc.us +lib.nc.us +cc.nd.us +lib.nd.us +cc.ne.us +lib.ne.us +cc.nh.us +lib.nh.us +cc.nj.us +lib.nj.us +cc.nm.us +lib.nm.us +cc.nv.us +lib.nv.us +cc.ny.us +lib.ny.us +cc.oh.us +lib.oh.us +cc.ok.us +lib.ok.us +cc.or.us +lib.or.us +cc.pa.us +lib.pa.us +cc.pr.us +lib.pr.us +cc.ri.us +lib.ri.us +cc.sc.us +lib.sc.us +cc.sd.us +lib.sd.us +cc.tn.us +lib.tn.us +cc.tx.us +lib.tx.us +cc.ut.us +lib.ut.us +cc.va.us +lib.va.us +cc.vi.us +lib.vi.us +cc.vt.us +lib.vt.us +cc.wa.us +lib.wa.us +cc.wi.us +lib.wi.us +cc.wv.us +cc.wy.us +k12.wy.us +// lib.wv.us - Bug 941670 - Removed at request of Larry W Arnold +lib.wy.us +// k12.ma.us contains school districts in Massachusetts. The 4LDs are +// managed independently except for private (PVT), charter (CHTR) and +// parochial (PAROCH) schools. Those are delegated directly to the +// 5LD operators. +chtr.k12.ma.us +paroch.k12.ma.us +pvt.k12.ma.us +// Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following +// see also: https://domreg.merit.edu : domreg@merit.edu +// see also: whois -h whois.domreg.merit.edu help +ann-arbor.mi.us +cog.mi.us +dst.mi.us +eaton.mi.us +gen.mi.us +mus.mi.us +tec.mi.us +washtenaw.mi.us + +// uy : http://www.nic.org.uy/ +uy +com.uy +edu.uy +gub.uy +mil.uy +net.uy +org.uy + +// uz : http://www.reg.uz/ +uz +co.uz +com.uz +net.uz +org.uz + +// va : https://www.iana.org/domains/root/db/va.html +va + +// vc : https://www.iana.org/domains/root/db/vc.html +// Submitted by registry +vc +com.vc +edu.vc +gov.vc +mil.vc +net.vc +org.vc + +// ve : https://registro.nic.ve/ +// https://nic.ve/site/user-agreement -> under "III. Clasificación de Nombres de Dominio" +// Submitted by registry nic@nic.ve and nicve@conatel.gob.ve +ve +arts.ve +bib.ve +co.ve +com.ve +e12.ve +edu.ve +emprende.ve +firm.ve +gob.ve +gov.ve +ia.ve +info.ve +int.ve +mil.ve +net.ve +nom.ve +org.ve +rar.ve +rec.ve +store.ve +tec.ve +web.ve + +// vg : https://www.iana.org/domains/root/db/vg.html +// Confirmed by registry 2025-01-10 +vg +edu.vg + +// vi : https://www.iana.org/domains/root/db/vi.html +vi +co.vi +com.vi +k12.vi +net.vi +org.vi + +// vn : https://www.vnnic.vn/en/domain/cctld-vn +// https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt +vn +ac.vn +ai.vn +biz.vn +com.vn +edu.vn +gov.vn +health.vn +id.vn +info.vn +int.vn +io.vn +name.vn +net.vn +org.vn +pro.vn + +// vn geographical names +angiang.vn +bacgiang.vn +backan.vn +baclieu.vn +bacninh.vn +baria-vungtau.vn +bentre.vn +binhdinh.vn +binhduong.vn +binhphuoc.vn +binhthuan.vn +camau.vn +cantho.vn +caobang.vn +daklak.vn +daknong.vn +danang.vn +dienbien.vn +dongnai.vn +dongthap.vn +gialai.vn +hagiang.vn +haiduong.vn +haiphong.vn +hanam.vn +hanoi.vn +hatinh.vn +haugiang.vn +hoabinh.vn +hue.vn +hungyen.vn +khanhhoa.vn +kiengiang.vn +kontum.vn +laichau.vn +lamdong.vn +langson.vn +laocai.vn +longan.vn +namdinh.vn +nghean.vn +ninhbinh.vn +ninhthuan.vn +phutho.vn +phuyen.vn +quangbinh.vn +quangnam.vn +quangngai.vn +quangninh.vn +quangtri.vn +soctrang.vn +sonla.vn +tayninh.vn +thaibinh.vn +thainguyen.vn +thanhhoa.vn +thanhphohochiminh.vn +thuathienhue.vn +tiengiang.vn +travinh.vn +tuyenquang.vn +vinhlong.vn +vinhphuc.vn +yenbai.vn + +// vu : https://www.iana.org/domains/root/db/vu.html +// http://www.vunic.vu/ +vu +com.vu +edu.vu +net.vu +org.vu + +// wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +wf + +// ws : https://www.iana.org/domains/root/db/ws.html +// http://samoanic.ws/index.dhtml +ws +com.ws +edu.ws +gov.ws +net.ws +org.ws + +// yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +yt + +// IDN ccTLDs +// When submitting patches, please maintain a sort by ISO 3166 ccTLD, then +// U-label, and follow this format: +// // A-Label ("", [, variant info]) : +// // [sponsoring org] +// U-Label + +// xn--mgbaam7a8h ("Emerat", Arabic) : AE +// http://nic.ae/english/arabicdomain/rules.jsp +امارات + +// xn--y9a3aq ("hye", Armenian) : AM +// ISOC AM (operated by .am Registry) +հայ + +// xn--54b7fta0cc ("Bangla", Bangla) : BD +বাংলা + +// xn--90ae ("bg", Bulgarian) : BG +бг + +// xn--mgbcpq6gpa1a ("albahrain", Arabic) : BH +البحرين + +// xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY +// Operated by .by registry +бел + +// xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN +// CNNIC +// https://www.cnnic.cn/11/192/index.html +中国 + +// xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN +// CNNIC +// https://www.cnnic.com.cn/AU/MediaC/Announcement/201609/t20160905_54470.htm +中國 + +// xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ +الجزائر + +// xn--wgbh1c ("Egypt/Masr", Arabic) : EG +// http://www.dotmasr.eg/ +مصر + +// xn--e1a4c ("eu", Cyrillic) : EU +// https://eurid.eu +ею + +// xn--qxa6a ("eu", Greek) : EU +// https://eurid.eu +ευ + +// xn--mgbah1a3hjkrd ("Mauritania", Arabic) : MR +موريتانيا + +// xn--node ("ge", Georgian Mkhedruli) : GE +გე + +// xn--qxam ("el", Greek) : GR +// Hellenic Ministry of Infrastructure, Transport, and Networks +ελ + +// xn--j6w193g ("Hong Kong", Chinese) : HK +// https://www.hkirc.hk +// Submitted by registry +// https://www.hkirc.hk/content.jsp?id=30#!/34 +香港 +個人.香港 +公司.香港 +政府.香港 +教育.香港 +組織.香港 +網絡.香港 + +// xn--2scrj9c ("Bharat", Kannada) : IN +// India +ಭಾರತ + +// xn--3hcrj9c ("Bharat", Oriya) : IN +// India +ଭାରତ + +// xn--45br5cyl ("Bharatam", Assamese) : IN +// India +ভাৰত + +// xn--h2breg3eve ("Bharatam", Sanskrit) : IN +// India +भारतम् + +// xn--h2brj9c8c ("Bharot", Santali) : IN +// India +भारोत + +// xn--mgbgu82a ("Bharat", Sindhi) : IN +// India +ڀارت + +// xn--rvc1e0am3e ("Bharatam", Malayalam) : IN +// India +ഭാരതം + +// xn--h2brj9c ("Bharat", Devanagari) : IN +// India +भारत + +// xn--mgbbh1a ("Bharat", Kashmiri) : IN +// India +بارت + +// xn--mgbbh1a71e ("Bharat", Arabic) : IN +// India +بھارت + +// xn--fpcrj9c3d ("Bharat", Telugu) : IN +// India +భారత్ + +// xn--gecrj9c ("Bharat", Gujarati) : IN +// India +ભારત + +// xn--s9brj9c ("Bharat", Gurmukhi) : IN +// India +ਭਾਰਤ + +// xn--45brj9c ("Bharat", Bengali) : IN +// India +ভারত + +// xn--xkc2dl3a5ee0h ("India", Tamil) : IN +// India +இந்தியா + +// xn--mgba3a4f16a ("Iran", Persian) : IR +ایران + +// xn--mgba3a4fra ("Iran", Arabic) : IR +ايران + +// xn--mgbtx2b ("Iraq", Arabic) : IQ +// Communications and Media Commission +عراق + +// xn--mgbayh7gpa ("al-Ordon", Arabic) : JO +// National Information Technology Center (NITC) +// Royal Scientific Society, Al-Jubeiha +الاردن + +// xn--3e0b707e ("Republic of Korea", Hangul) : KR +한국 + +// xn--80ao21a ("Kaz", Kazakh) : KZ +қаз + +// xn--q7ce6a ("Lao", Lao) : LA +ລາວ + +// xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK +// https://nic.lk +ලංකා + +// xn--xkc2al3hye2a ("Ilangai", Tamil) : LK +// https://nic.lk +இலங்கை + +// xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA +المغرب + +// xn--d1alf ("mkd", Macedonian) : MK +// MARnet +мкд + +// xn--l1acc ("mon", Mongolian) : MN +мон + +// xn--mix891f ("Macao", Chinese, Traditional) : MO +// MONIC / HNET Asia (Registry Operator for .mo) +澳門 + +// xn--mix082f ("Macao", Chinese, Simplified) : MO +澳门 + +// xn--mgbx4cd0ab ("Malaysia", Malay) : MY +مليسيا + +// xn--mgb9awbf ("Oman", Arabic) : OM +عمان + +// xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK +پاکستان + +// xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK +پاكستان + +// xn--ygbi2ammx ("Falasteen", Arabic) : PS +// The Palestinian National Internet Naming Authority (PNINA) +// http://www.pnina.ps +فلسطين + +// xn--90a3ac ("srb", Cyrillic) : RS +// https://www.rnids.rs/en/domains/national-domains +срб +ак.срб +обр.срб +од.срб +орг.срб +пр.срб +упр.срб + +// xn--p1ai ("rf", Russian-Cyrillic) : RU +// https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf +// Submitted by George Georgievsky +рф + +// xn--wgbl6a ("Qatar", Arabic) : QA +// http://www.ict.gov.qa/ +قطر + +// xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA +// http://www.nic.net.sa/ +السعودية + +// xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant): SA +السعودیة + +// xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA +السعودیۃ + +// xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA +السعوديه + +// xn--mgbpl2fh ("sudan", Arabic) : SD +// Operated by .sd registry +سودان + +// xn--yfro4i67o Singapore ("Singapore", Chinese) : SG +新加坡 + +// xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG +சிங்கப்பூர் + +// xn--ogbpf8fl ("Syria", Arabic) : SY +سورية + +// xn--mgbtf8fl ("Syria", Arabic, variant) : SY +سوريا + +// xn--o3cw4h ("Thai", Thai) : TH +// http://www.thnic.co.th +ไทย +ทหาร.ไทย +ธุรกิจ.ไทย +เน็ต.ไทย +รัฐบาล.ไทย +ศึกษา.ไทย +องค์กร.ไทย + +// xn--pgbs0dh ("Tunisia", Arabic) : TN +// http://nic.tn +تونس + +// xn--kpry57d ("Taiwan", Chinese, Traditional) : TW +// https://twnic.tw/dnservice_catag.php +台灣 + +// xn--kprw13d ("Taiwan", Chinese, Simplified) : TW +// http://www.twnic.net/english/dn/dn_07a.htm +台湾 + +// xn--nnx388a ("Taiwan", Chinese, variant) : TW +臺灣 + +// xn--j1amh ("ukr", Cyrillic) : UA +укр + +// xn--mgb2ddes ("AlYemen", Arabic) : YE +اليمن + +// xxx : http://icmregistry.com +xxx + +// ye : http://www.y.net.ye/services/domain_name.htm +ye +com.ye +edu.ye +gov.ye +mil.ye +net.ye +org.ye + +// za : https://www.iana.org/domains/root/db/za.html +ac.za +agric.za +alt.za +co.za +edu.za +gov.za +grondar.za +law.za +mil.za +net.za +ngo.za +nic.za +nis.za +nom.za +org.za +school.za +tm.za +web.za + +// zm : https://zicta.zm/ +// Submitted by registry +zm +ac.zm +biz.zm +co.zm +com.zm +edu.zm +gov.zm +info.zm +mil.zm +net.zm +org.zm +sch.zm + +// zw : https://www.potraz.gov.zw/ +// Confirmed by registry 2017-01-25 +zw +ac.zw +co.zw +gov.zw +mil.zw +org.zw + +// newGTLDs + +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-02-18T15:51:43Z +// This list is auto-generated, don't edit it manually. +// aaa : American Automobile Association, Inc. +// https://www.iana.org/domains/root/db/aaa.html +aaa + +// aarp : AARP +// https://www.iana.org/domains/root/db/aarp.html +aarp + +// abb : ABB Ltd +// https://www.iana.org/domains/root/db/abb.html +abb + +// abbott : Abbott Laboratories, Inc. +// https://www.iana.org/domains/root/db/abbott.html +abbott + +// abbvie : AbbVie Inc. +// https://www.iana.org/domains/root/db/abbvie.html +abbvie + +// abc : Disney Enterprises, Inc. +// https://www.iana.org/domains/root/db/abc.html +abc + +// able : Able Inc. +// https://www.iana.org/domains/root/db/able.html +able + +// abogado : Registry Services, LLC +// https://www.iana.org/domains/root/db/abogado.html +abogado + +// abudhabi : Abu Dhabi Systems and Information Centre +// https://www.iana.org/domains/root/db/abudhabi.html +abudhabi + +// academy : Binky Moon, LLC +// https://www.iana.org/domains/root/db/academy.html +academy + +// accenture : Accenture plc +// https://www.iana.org/domains/root/db/accenture.html +accenture + +// accountant : dot Accountant Limited +// https://www.iana.org/domains/root/db/accountant.html +accountant + +// accountants : Binky Moon, LLC +// https://www.iana.org/domains/root/db/accountants.html +accountants + +// aco : ACO Severin Ahlmann GmbH & Co. KG +// https://www.iana.org/domains/root/db/aco.html +aco + +// actor : Dog Beach, LLC +// https://www.iana.org/domains/root/db/actor.html +actor + +// ads : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/ads.html +ads + +// adult : ICM Registry AD LLC +// https://www.iana.org/domains/root/db/adult.html +adult + +// aeg : Aktiebolaget Electrolux +// https://www.iana.org/domains/root/db/aeg.html +aeg + +// aetna : Aetna Life Insurance Company +// https://www.iana.org/domains/root/db/aetna.html +aetna + +// afl : Australian Football League +// https://www.iana.org/domains/root/db/afl.html +afl + +// africa : ZA Central Registry NPC trading as Registry.Africa +// https://www.iana.org/domains/root/db/africa.html +africa + +// agakhan : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/agakhan.html +agakhan + +// agency : Binky Moon, LLC +// https://www.iana.org/domains/root/db/agency.html +agency + +// aig : American International Group, Inc. +// https://www.iana.org/domains/root/db/aig.html +aig + +// airbus : Airbus S.A.S. +// https://www.iana.org/domains/root/db/airbus.html +airbus + +// airforce : Dog Beach, LLC +// https://www.iana.org/domains/root/db/airforce.html +airforce + +// airtel : Bharti Airtel Limited +// https://www.iana.org/domains/root/db/airtel.html +airtel + +// akdn : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/akdn.html +akdn + +// alibaba : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/alibaba.html +alibaba + +// alipay : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/alipay.html +alipay + +// allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft +// https://www.iana.org/domains/root/db/allfinanz.html +allfinanz + +// allstate : Allstate Fire and Casualty Insurance Company +// https://www.iana.org/domains/root/db/allstate.html +allstate + +// ally : Ally Financial Inc. +// https://www.iana.org/domains/root/db/ally.html +ally + +// alsace : Region Grand Est +// https://www.iana.org/domains/root/db/alsace.html +alsace + +// alstom : ALSTOM +// https://www.iana.org/domains/root/db/alstom.html +alstom + +// amazon : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/amazon.html +amazon + +// americanexpress : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/americanexpress.html +americanexpress + +// americanfamily : AmFam, Inc. +// https://www.iana.org/domains/root/db/americanfamily.html +americanfamily + +// amex : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/amex.html +amex + +// amfam : AmFam, Inc. +// https://www.iana.org/domains/root/db/amfam.html +amfam + +// amica : Amica Mutual Insurance Company +// https://www.iana.org/domains/root/db/amica.html +amica + +// amsterdam : Gemeente Amsterdam +// https://www.iana.org/domains/root/db/amsterdam.html +amsterdam + +// analytics : Campus IP LLC +// https://www.iana.org/domains/root/db/analytics.html +analytics + +// android : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/android.html +android + +// anquan : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/anquan.html +anquan + +// anz : Australia and New Zealand Banking Group Limited +// https://www.iana.org/domains/root/db/anz.html +anz + +// aol : Yahoo Inc. +// https://www.iana.org/domains/root/db/aol.html +aol + +// apartments : Binky Moon, LLC +// https://www.iana.org/domains/root/db/apartments.html +apartments + +// app : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/app.html +app + +// apple : Apple Inc. +// https://www.iana.org/domains/root/db/apple.html +apple + +// aquarelle : Aquarelle.com +// https://www.iana.org/domains/root/db/aquarelle.html +aquarelle + +// arab : League of Arab States +// https://www.iana.org/domains/root/db/arab.html +arab + +// aramco : Aramco Services Company +// https://www.iana.org/domains/root/db/aramco.html +aramco + +// archi : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/archi.html +archi + +// army : Dog Beach, LLC +// https://www.iana.org/domains/root/db/army.html +army + +// art : UK Creative Ideas Limited +// https://www.iana.org/domains/root/db/art.html +art + +// arte : Association Relative à la Télévision Européenne G.E.I.E. +// https://www.iana.org/domains/root/db/arte.html +arte + +// asda : Asda Stores Limited +// https://www.iana.org/domains/root/db/asda.html +asda + +// associates : Binky Moon, LLC +// https://www.iana.org/domains/root/db/associates.html +associates + +// athleta : The Gap, Inc. +// https://www.iana.org/domains/root/db/athleta.html +athleta + +// attorney : Dog Beach, LLC +// https://www.iana.org/domains/root/db/attorney.html +attorney + +// auction : Dog Beach, LLC +// https://www.iana.org/domains/root/db/auction.html +auction + +// audi : AUDI Aktiengesellschaft +// https://www.iana.org/domains/root/db/audi.html +audi + +// audible : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/audible.html +audible + +// audio : XYZ.COM LLC +// https://www.iana.org/domains/root/db/audio.html +audio + +// auspost : Australian Postal Corporation +// https://www.iana.org/domains/root/db/auspost.html +auspost + +// author : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/author.html +author + +// auto : XYZ.COM LLC +// https://www.iana.org/domains/root/db/auto.html +auto + +// autos : XYZ.COM LLC +// https://www.iana.org/domains/root/db/autos.html +autos + +// aws : AWS Registry LLC +// https://www.iana.org/domains/root/db/aws.html +aws + +// axa : AXA Group Operations SAS +// https://www.iana.org/domains/root/db/axa.html +axa + +// azure : Microsoft Corporation +// https://www.iana.org/domains/root/db/azure.html +azure + +// baby : XYZ.COM LLC +// https://www.iana.org/domains/root/db/baby.html +baby + +// baidu : Baidu, Inc. +// https://www.iana.org/domains/root/db/baidu.html +baidu + +// banamex : Citigroup Inc. +// https://www.iana.org/domains/root/db/banamex.html +banamex + +// band : Dog Beach, LLC +// https://www.iana.org/domains/root/db/band.html +band + +// bank : fTLD Registry Services LLC +// https://www.iana.org/domains/root/db/bank.html +bank + +// bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// https://www.iana.org/domains/root/db/bar.html +bar + +// barcelona : Municipi de Barcelona +// https://www.iana.org/domains/root/db/barcelona.html +barcelona + +// barclaycard : Barclays Bank PLC +// https://www.iana.org/domains/root/db/barclaycard.html +barclaycard + +// barclays : Barclays Bank PLC +// https://www.iana.org/domains/root/db/barclays.html +barclays + +// barefoot : Gallo Vineyards, Inc. +// https://www.iana.org/domains/root/db/barefoot.html +barefoot + +// bargains : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bargains.html +bargains + +// baseball : MLB Advanced Media DH, LLC +// https://www.iana.org/domains/root/db/baseball.html +baseball + +// basketball : Fédération Internationale de Basketball (FIBA) +// https://www.iana.org/domains/root/db/basketball.html +basketball + +// bauhaus : Werkhaus GmbH +// https://www.iana.org/domains/root/db/bauhaus.html +bauhaus + +// bayern : Bayern Connect GmbH +// https://www.iana.org/domains/root/db/bayern.html +bayern + +// bbc : British Broadcasting Corporation +// https://www.iana.org/domains/root/db/bbc.html +bbc + +// bbt : BB&T Corporation +// https://www.iana.org/domains/root/db/bbt.html +bbt + +// bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A. +// https://www.iana.org/domains/root/db/bbva.html +bbva + +// bcg : The Boston Consulting Group, Inc. +// https://www.iana.org/domains/root/db/bcg.html +bcg + +// bcn : Municipi de Barcelona +// https://www.iana.org/domains/root/db/bcn.html +bcn + +// beats : Beats Electronics, LLC +// https://www.iana.org/domains/root/db/beats.html +beats + +// beauty : XYZ.COM LLC +// https://www.iana.org/domains/root/db/beauty.html +beauty + +// beer : Registry Services, LLC +// https://www.iana.org/domains/root/db/beer.html +beer + +// berlin : dotBERLIN GmbH & Co. KG +// https://www.iana.org/domains/root/db/berlin.html +berlin + +// best : BestTLD Pty Ltd +// https://www.iana.org/domains/root/db/best.html +best + +// bestbuy : BBY Solutions, Inc. +// https://www.iana.org/domains/root/db/bestbuy.html +bestbuy + +// bet : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/bet.html +bet + +// bharti : Bharti Enterprises (Holding) Private Limited +// https://www.iana.org/domains/root/db/bharti.html +bharti + +// bible : American Bible Society +// https://www.iana.org/domains/root/db/bible.html +bible + +// bid : dot Bid Limited +// https://www.iana.org/domains/root/db/bid.html +bid + +// bike : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bike.html +bike + +// bing : Microsoft Corporation +// https://www.iana.org/domains/root/db/bing.html +bing + +// bingo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bingo.html +bingo + +// bio : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/bio.html +bio + +// black : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/black.html +black + +// blackfriday : Registry Services, LLC +// https://www.iana.org/domains/root/db/blackfriday.html +blackfriday + +// blockbuster : Dish DBS Corporation +// https://www.iana.org/domains/root/db/blockbuster.html +blockbuster + +// blog : Knock Knock WHOIS There, LLC +// https://www.iana.org/domains/root/db/blog.html +blog + +// bloomberg : Bloomberg IP Holdings LLC +// https://www.iana.org/domains/root/db/bloomberg.html +bloomberg + +// blue : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/blue.html +blue + +// bms : Bristol-Myers Squibb Company +// https://www.iana.org/domains/root/db/bms.html +bms + +// bmw : Bayerische Motoren Werke Aktiengesellschaft +// https://www.iana.org/domains/root/db/bmw.html +bmw + +// bnpparibas : BNP Paribas +// https://www.iana.org/domains/root/db/bnpparibas.html +bnpparibas + +// boats : XYZ.COM LLC +// https://www.iana.org/domains/root/db/boats.html +boats + +// boehringer : Boehringer Ingelheim International GmbH +// https://www.iana.org/domains/root/db/boehringer.html +boehringer + +// bofa : Bank of America Corporation +// https://www.iana.org/domains/root/db/bofa.html +bofa + +// bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// https://www.iana.org/domains/root/db/bom.html +bom + +// bond : ShortDot SA +// https://www.iana.org/domains/root/db/bond.html +bond + +// boo : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/boo.html +boo + +// book : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/book.html +book + +// booking : Booking.com B.V. +// https://www.iana.org/domains/root/db/booking.html +booking + +// bosch : Robert Bosch GMBH +// https://www.iana.org/domains/root/db/bosch.html +bosch + +// bostik : Bostik SA +// https://www.iana.org/domains/root/db/bostik.html +bostik + +// boston : Registry Services, LLC +// https://www.iana.org/domains/root/db/boston.html +boston + +// bot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/bot.html +bot + +// boutique : Binky Moon, LLC +// https://www.iana.org/domains/root/db/boutique.html +boutique + +// box : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/box.html +box + +// bradesco : Banco Bradesco S.A. +// https://www.iana.org/domains/root/db/bradesco.html +bradesco + +// bridgestone : Bridgestone Corporation +// https://www.iana.org/domains/root/db/bridgestone.html +bridgestone + +// broadway : Celebrate Broadway, Inc. +// https://www.iana.org/domains/root/db/broadway.html +broadway + +// broker : Dog Beach, LLC +// https://www.iana.org/domains/root/db/broker.html +broker + +// brother : Brother Industries, Ltd. +// https://www.iana.org/domains/root/db/brother.html +brother + +// brussels : DNS.be vzw +// https://www.iana.org/domains/root/db/brussels.html +brussels + +// build : Plan Bee LLC +// https://www.iana.org/domains/root/db/build.html +build + +// builders : Binky Moon, LLC +// https://www.iana.org/domains/root/db/builders.html +builders + +// business : Binky Moon, LLC +// https://www.iana.org/domains/root/db/business.html +business + +// buy : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/buy.html +buy + +// buzz : DOTSTRATEGY CO. +// https://www.iana.org/domains/root/db/buzz.html +buzz + +// bzh : Association www.bzh +// https://www.iana.org/domains/root/db/bzh.html +bzh + +// cab : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cab.html +cab + +// cafe : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cafe.html +cafe + +// cal : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/cal.html +cal + +// call : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/call.html +call + +// calvinklein : PVH gTLD Holdings LLC +// https://www.iana.org/domains/root/db/calvinklein.html +calvinklein + +// cam : Cam Connecting SARL +// https://www.iana.org/domains/root/db/cam.html +cam + +// camera : Binky Moon, LLC +// https://www.iana.org/domains/root/db/camera.html +camera + +// camp : Binky Moon, LLC +// https://www.iana.org/domains/root/db/camp.html +camp + +// canon : Canon Inc. +// https://www.iana.org/domains/root/db/canon.html +canon + +// capetown : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/capetown.html +capetown + +// capital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/capital.html +capital + +// capitalone : Capital One Financial Corporation +// https://www.iana.org/domains/root/db/capitalone.html +capitalone + +// car : XYZ.COM LLC +// https://www.iana.org/domains/root/db/car.html +car + +// caravan : Caravan International, Inc. +// https://www.iana.org/domains/root/db/caravan.html +caravan + +// cards : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cards.html +cards + +// care : Binky Moon, LLC +// https://www.iana.org/domains/root/db/care.html +care + +// career : dotCareer LLC +// https://www.iana.org/domains/root/db/career.html +career + +// careers : Binky Moon, LLC +// https://www.iana.org/domains/root/db/careers.html +careers + +// cars : XYZ.COM LLC +// https://www.iana.org/domains/root/db/cars.html +cars + +// casa : Registry Services, LLC +// https://www.iana.org/domains/root/db/casa.html +casa + +// case : Digity, LLC +// https://www.iana.org/domains/root/db/case.html +case + +// cash : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cash.html +cash + +// casino : Binky Moon, LLC +// https://www.iana.org/domains/root/db/casino.html +casino + +// catering : Binky Moon, LLC +// https://www.iana.org/domains/root/db/catering.html +catering + +// catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/catholic.html +catholic + +// cba : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/cba.html +cba + +// cbn : The Christian Broadcasting Network, Inc. +// https://www.iana.org/domains/root/db/cbn.html +cbn + +// cbre : CBRE, Inc. +// https://www.iana.org/domains/root/db/cbre.html +cbre + +// center : Binky Moon, LLC +// https://www.iana.org/domains/root/db/center.html +center + +// ceo : XYZ.COM LLC +// https://www.iana.org/domains/root/db/ceo.html +ceo + +// cern : European Organization for Nuclear Research ("CERN") +// https://www.iana.org/domains/root/db/cern.html +cern + +// cfa : CFA Institute +// https://www.iana.org/domains/root/db/cfa.html +cfa + +// cfd : ShortDot SA +// https://www.iana.org/domains/root/db/cfd.html +cfd + +// chanel : Chanel International B.V. +// https://www.iana.org/domains/root/db/chanel.html +chanel + +// channel : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/channel.html +channel + +// charity : Public Interest Registry +// https://www.iana.org/domains/root/db/charity.html +charity + +// chase : JPMorgan Chase Bank, National Association +// https://www.iana.org/domains/root/db/chase.html +chase + +// chat : Binky Moon, LLC +// https://www.iana.org/domains/root/db/chat.html +chat + +// cheap : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cheap.html +cheap + +// chintai : CHINTAI Corporation +// https://www.iana.org/domains/root/db/chintai.html +chintai + +// christmas : XYZ.COM LLC +// https://www.iana.org/domains/root/db/christmas.html +christmas + +// chrome : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/chrome.html +chrome + +// church : Binky Moon, LLC +// https://www.iana.org/domains/root/db/church.html +church + +// cipriani : Hotel Cipriani Srl +// https://www.iana.org/domains/root/db/cipriani.html +cipriani + +// circle : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/circle.html +circle + +// cisco : Cisco Technology, Inc. +// https://www.iana.org/domains/root/db/cisco.html +cisco + +// citadel : Citadel Domain LLC +// https://www.iana.org/domains/root/db/citadel.html +citadel + +// citi : Citigroup Inc. +// https://www.iana.org/domains/root/db/citi.html +citi + +// citic : CITIC Group Corporation +// https://www.iana.org/domains/root/db/citic.html +citic + +// city : Binky Moon, LLC +// https://www.iana.org/domains/root/db/city.html +city + +// claims : Binky Moon, LLC +// https://www.iana.org/domains/root/db/claims.html +claims + +// cleaning : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cleaning.html +cleaning + +// click : Waterford Limited +// https://www.iana.org/domains/root/db/click.html +click + +// clinic : Binky Moon, LLC +// https://www.iana.org/domains/root/db/clinic.html +clinic + +// clinique : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/clinique.html +clinique + +// clothing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/clothing.html +clothing + +// cloud : Aruba PEC S.p.A. +// https://www.iana.org/domains/root/db/cloud.html +cloud + +// club : Registry Services, LLC +// https://www.iana.org/domains/root/db/club.html +club + +// clubmed : Club Méditerranée S.A. +// https://www.iana.org/domains/root/db/clubmed.html +clubmed + +// coach : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coach.html +coach + +// codes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/codes.html +codes + +// coffee : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coffee.html +coffee + +// college : XYZ.COM LLC +// https://www.iana.org/domains/root/db/college.html +college + +// cologne : dotKoeln GmbH +// https://www.iana.org/domains/root/db/cologne.html +cologne + +// commbank : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/commbank.html +commbank + +// community : Binky Moon, LLC +// https://www.iana.org/domains/root/db/community.html +community + +// company : Binky Moon, LLC +// https://www.iana.org/domains/root/db/company.html +company + +// compare : Registry Services, LLC +// https://www.iana.org/domains/root/db/compare.html +compare + +// computer : Binky Moon, LLC +// https://www.iana.org/domains/root/db/computer.html +computer + +// comsec : VeriSign, Inc. +// https://www.iana.org/domains/root/db/comsec.html +comsec + +// condos : Binky Moon, LLC +// https://www.iana.org/domains/root/db/condos.html +condos + +// construction : Binky Moon, LLC +// https://www.iana.org/domains/root/db/construction.html +construction + +// consulting : Dog Beach, LLC +// https://www.iana.org/domains/root/db/consulting.html +consulting + +// contact : Dog Beach, LLC +// https://www.iana.org/domains/root/db/contact.html +contact + +// contractors : Binky Moon, LLC +// https://www.iana.org/domains/root/db/contractors.html +contractors + +// cooking : Registry Services, LLC +// https://www.iana.org/domains/root/db/cooking.html +cooking + +// cool : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cool.html +cool + +// corsica : Collectivité de Corse +// https://www.iana.org/domains/root/db/corsica.html +corsica + +// country : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/country.html +country + +// coupon : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/coupon.html +coupon + +// coupons : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coupons.html +coupons + +// courses : Registry Services, LLC +// https://www.iana.org/domains/root/db/courses.html +courses + +// cpa : American Institute of Certified Public Accountants +// https://www.iana.org/domains/root/db/cpa.html +cpa + +// credit : Binky Moon, LLC +// https://www.iana.org/domains/root/db/credit.html +credit + +// creditcard : Binky Moon, LLC +// https://www.iana.org/domains/root/db/creditcard.html +creditcard + +// creditunion : DotCooperation LLC +// https://www.iana.org/domains/root/db/creditunion.html +creditunion + +// cricket : dot Cricket Limited +// https://www.iana.org/domains/root/db/cricket.html +cricket + +// crown : Crown Equipment Corporation +// https://www.iana.org/domains/root/db/crown.html +crown + +// crs : Federated Co-operatives Limited +// https://www.iana.org/domains/root/db/crs.html +crs + +// cruise : Viking River Cruises (Bermuda) Ltd. +// https://www.iana.org/domains/root/db/cruise.html +cruise + +// cruises : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cruises.html +cruises + +// cuisinella : SCHMIDT GROUPE S.A.S. +// https://www.iana.org/domains/root/db/cuisinella.html +cuisinella + +// cymru : Nominet UK +// https://www.iana.org/domains/root/db/cymru.html +cymru + +// cyou : ShortDot SA +// https://www.iana.org/domains/root/db/cyou.html +cyou + +// dad : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dad.html +dad + +// dance : Dog Beach, LLC +// https://www.iana.org/domains/root/db/dance.html +dance + +// data : Dish DBS Corporation +// https://www.iana.org/domains/root/db/data.html +data + +// date : dot Date Limited +// https://www.iana.org/domains/root/db/date.html +date + +// dating : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dating.html +dating + +// datsun : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/datsun.html +datsun + +// day : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/day.html +day + +// dclk : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dclk.html +dclk + +// dds : Registry Services, LLC +// https://www.iana.org/domains/root/db/dds.html +dds + +// deal : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/deal.html +deal + +// dealer : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/dealer.html +dealer + +// deals : Binky Moon, LLC +// https://www.iana.org/domains/root/db/deals.html +deals + +// degree : Dog Beach, LLC +// https://www.iana.org/domains/root/db/degree.html +degree + +// delivery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/delivery.html +delivery + +// dell : Dell Inc. +// https://www.iana.org/domains/root/db/dell.html +dell + +// deloitte : Deloitte Touche Tohmatsu +// https://www.iana.org/domains/root/db/deloitte.html +deloitte + +// delta : Delta Air Lines, Inc. +// https://www.iana.org/domains/root/db/delta.html +delta + +// democrat : Dog Beach, LLC +// https://www.iana.org/domains/root/db/democrat.html +democrat + +// dental : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dental.html +dental + +// dentist : Dog Beach, LLC +// https://www.iana.org/domains/root/db/dentist.html +dentist + +// desi +// https://www.iana.org/domains/root/db/desi.html +desi + +// design : Registry Services, LLC +// https://www.iana.org/domains/root/db/design.html +design + +// dev : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dev.html +dev + +// dhl : Deutsche Post AG +// https://www.iana.org/domains/root/db/dhl.html +dhl + +// diamonds : Binky Moon, LLC +// https://www.iana.org/domains/root/db/diamonds.html +diamonds + +// diet : XYZ.COM LLC +// https://www.iana.org/domains/root/db/diet.html +diet + +// digital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/digital.html +digital + +// direct : Binky Moon, LLC +// https://www.iana.org/domains/root/db/direct.html +direct + +// directory : Binky Moon, LLC +// https://www.iana.org/domains/root/db/directory.html +directory + +// discount : Binky Moon, LLC +// https://www.iana.org/domains/root/db/discount.html +discount + +// discover : Discover Financial Services +// https://www.iana.org/domains/root/db/discover.html +discover + +// dish : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dish.html +dish + +// diy : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/diy.html +diy + +// dnp : Dai Nippon Printing Co., Ltd. +// https://www.iana.org/domains/root/db/dnp.html +dnp + +// docs : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/docs.html +docs + +// doctor : Binky Moon, LLC +// https://www.iana.org/domains/root/db/doctor.html +doctor + +// dog : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dog.html +dog + +// domains : Binky Moon, LLC +// https://www.iana.org/domains/root/db/domains.html +domains + +// dot : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dot.html +dot + +// download : dot Support Limited +// https://www.iana.org/domains/root/db/download.html +download + +// drive : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/drive.html +drive + +// dtv : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dtv.html +dtv + +// dubai : Dubai Smart Government Department +// https://www.iana.org/domains/root/db/dubai.html +dubai + +// dupont : DuPont Specialty Products USA, LLC +// https://www.iana.org/domains/root/db/dupont.html +dupont + +// durban : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/durban.html +durban + +// dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/dvag.html +dvag + +// dvr : DISH Technologies L.L.C. +// https://www.iana.org/domains/root/db/dvr.html +dvr + +// earth : Interlink Systems Innovation Institute K.K. +// https://www.iana.org/domains/root/db/earth.html +earth + +// eat : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/eat.html +eat + +// eco : Big Room Inc. +// https://www.iana.org/domains/root/db/eco.html +eco + +// edeka : EDEKA Verband kaufmännischer Genossenschaften e.V. +// https://www.iana.org/domains/root/db/edeka.html +edeka + +// education : Binky Moon, LLC +// https://www.iana.org/domains/root/db/education.html +education + +// email : Binky Moon, LLC +// https://www.iana.org/domains/root/db/email.html +email + +// emerck : Merck KGaA +// https://www.iana.org/domains/root/db/emerck.html +emerck + +// energy : Binky Moon, LLC +// https://www.iana.org/domains/root/db/energy.html +energy + +// engineer : Dog Beach, LLC +// https://www.iana.org/domains/root/db/engineer.html +engineer + +// engineering : Binky Moon, LLC +// https://www.iana.org/domains/root/db/engineering.html +engineering + +// enterprises : Binky Moon, LLC +// https://www.iana.org/domains/root/db/enterprises.html +enterprises + +// epson : Seiko Epson Corporation +// https://www.iana.org/domains/root/db/epson.html +epson + +// equipment : Binky Moon, LLC +// https://www.iana.org/domains/root/db/equipment.html +equipment + +// ericsson : Telefonaktiebolaget L M Ericsson +// https://www.iana.org/domains/root/db/ericsson.html +ericsson + +// erni : ERNI Group Holding AG +// https://www.iana.org/domains/root/db/erni.html +erni + +// esq : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/esq.html +esq + +// estate : Binky Moon, LLC +// https://www.iana.org/domains/root/db/estate.html +estate + +// eurovision : European Broadcasting Union (EBU) +// https://www.iana.org/domains/root/db/eurovision.html +eurovision + +// eus : Puntueus Fundazioa +// https://www.iana.org/domains/root/db/eus.html +eus + +// events : Binky Moon, LLC +// https://www.iana.org/domains/root/db/events.html +events + +// exchange : Binky Moon, LLC +// https://www.iana.org/domains/root/db/exchange.html +exchange + +// expert : Binky Moon, LLC +// https://www.iana.org/domains/root/db/expert.html +expert + +// exposed : Binky Moon, LLC +// https://www.iana.org/domains/root/db/exposed.html +exposed + +// express : Binky Moon, LLC +// https://www.iana.org/domains/root/db/express.html +express + +// extraspace : Extra Space Storage LLC +// https://www.iana.org/domains/root/db/extraspace.html +extraspace + +// fage : Fage International S.A. +// https://www.iana.org/domains/root/db/fage.html +fage + +// fail : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fail.html +fail + +// fairwinds : FairWinds Partners, LLC +// https://www.iana.org/domains/root/db/fairwinds.html +fairwinds + +// faith : dot Faith Limited +// https://www.iana.org/domains/root/db/faith.html +faith + +// family : Dog Beach, LLC +// https://www.iana.org/domains/root/db/family.html +family + +// fan : Dog Beach, LLC +// https://www.iana.org/domains/root/db/fan.html +fan + +// fans : ZDNS International Limited +// https://www.iana.org/domains/root/db/fans.html +fans + +// farm : Binky Moon, LLC +// https://www.iana.org/domains/root/db/farm.html +farm + +// farmers : Farmers Insurance Exchange +// https://www.iana.org/domains/root/db/farmers.html +farmers + +// fashion : Registry Services, LLC +// https://www.iana.org/domains/root/db/fashion.html +fashion + +// fast : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/fast.html +fast + +// fedex : Federal Express Corporation +// https://www.iana.org/domains/root/db/fedex.html +fedex + +// feedback : Top Level Spectrum, Inc. +// https://www.iana.org/domains/root/db/feedback.html +feedback + +// ferrari : Fiat Chrysler Automobiles N.V. +// https://www.iana.org/domains/root/db/ferrari.html +ferrari + +// ferrero : Ferrero Trading Lux S.A. +// https://www.iana.org/domains/root/db/ferrero.html +ferrero + +// fidelity : Fidelity Brokerage Services LLC +// https://www.iana.org/domains/root/db/fidelity.html +fidelity + +// fido : Rogers Communications Canada Inc. +// https://www.iana.org/domains/root/db/fido.html +fido + +// film : Motion Picture Domain Registry Pty Ltd +// https://www.iana.org/domains/root/db/film.html +film + +// final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// https://www.iana.org/domains/root/db/final.html +final + +// finance : Binky Moon, LLC +// https://www.iana.org/domains/root/db/finance.html +finance + +// financial : Binky Moon, LLC +// https://www.iana.org/domains/root/db/financial.html +financial + +// fire : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/fire.html +fire + +// firestone : Bridgestone Licensing Services, Inc +// https://www.iana.org/domains/root/db/firestone.html +firestone + +// firmdale : Firmdale Holdings Limited +// https://www.iana.org/domains/root/db/firmdale.html +firmdale + +// fish : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fish.html +fish + +// fishing : Registry Services, LLC +// https://www.iana.org/domains/root/db/fishing.html +fishing + +// fit : Registry Services, LLC +// https://www.iana.org/domains/root/db/fit.html +fit + +// fitness : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fitness.html +fitness + +// flickr : Flickr, Inc. +// https://www.iana.org/domains/root/db/flickr.html +flickr + +// flights : Binky Moon, LLC +// https://www.iana.org/domains/root/db/flights.html +flights + +// flir : FLIR Systems, Inc. +// https://www.iana.org/domains/root/db/flir.html +flir + +// florist : Binky Moon, LLC +// https://www.iana.org/domains/root/db/florist.html +florist + +// flowers : XYZ.COM LLC +// https://www.iana.org/domains/root/db/flowers.html +flowers + +// fly : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/fly.html +fly + +// foo : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/foo.html +foo + +// food : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/food.html +food + +// football : Binky Moon, LLC +// https://www.iana.org/domains/root/db/football.html +football + +// ford : Ford Motor Company +// https://www.iana.org/domains/root/db/ford.html +ford + +// forex : Dog Beach, LLC +// https://www.iana.org/domains/root/db/forex.html +forex + +// forsale : Dog Beach, LLC +// https://www.iana.org/domains/root/db/forsale.html +forsale + +// forum : Waterford Limited +// https://www.iana.org/domains/root/db/forum.html +forum + +// foundation : Public Interest Registry +// https://www.iana.org/domains/root/db/foundation.html +foundation + +// fox : FOX Registry, LLC +// https://www.iana.org/domains/root/db/fox.html +fox + +// free : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/free.html +free + +// fresenius : Fresenius Immobilien-Verwaltungs-GmbH +// https://www.iana.org/domains/root/db/fresenius.html +fresenius + +// frl : FRLregistry B.V. +// https://www.iana.org/domains/root/db/frl.html +frl + +// frogans : OP3FT +// https://www.iana.org/domains/root/db/frogans.html +frogans + +// frontier : Frontier Communications Corporation +// https://www.iana.org/domains/root/db/frontier.html +frontier + +// ftr : Frontier Communications Corporation +// https://www.iana.org/domains/root/db/ftr.html +ftr + +// fujitsu : Fujitsu Limited +// https://www.iana.org/domains/root/db/fujitsu.html +fujitsu + +// fun : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/fun.html +fun + +// fund : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fund.html +fund + +// furniture : Binky Moon, LLC +// https://www.iana.org/domains/root/db/furniture.html +furniture + +// futbol : Dog Beach, LLC +// https://www.iana.org/domains/root/db/futbol.html +futbol + +// fyi : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fyi.html +fyi + +// gal : Asociación puntoGAL +// https://www.iana.org/domains/root/db/gal.html +gal + +// gallery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gallery.html +gallery + +// gallo : Gallo Vineyards, Inc. +// https://www.iana.org/domains/root/db/gallo.html +gallo + +// gallup : Gallup, Inc. +// https://www.iana.org/domains/root/db/gallup.html +gallup + +// game : XYZ.COM LLC +// https://www.iana.org/domains/root/db/game.html +game + +// games : Dog Beach, LLC +// https://www.iana.org/domains/root/db/games.html +games + +// gap : The Gap, Inc. +// https://www.iana.org/domains/root/db/gap.html +gap + +// garden : Registry Services, LLC +// https://www.iana.org/domains/root/db/garden.html +garden + +// gay : Registry Services, LLC +// https://www.iana.org/domains/root/db/gay.html +gay + +// gbiz : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gbiz.html +gbiz + +// gdn : Joint Stock Company "Navigation-information systems" +// https://www.iana.org/domains/root/db/gdn.html +gdn + +// gea : GEA Group Aktiengesellschaft +// https://www.iana.org/domains/root/db/gea.html +gea + +// gent : Easyhost BV +// https://www.iana.org/domains/root/db/gent.html +gent + +// genting : Resorts World Inc Pte. Ltd. +// https://www.iana.org/domains/root/db/genting.html +genting + +// george : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/george.html +george + +// ggee : GMO Internet, Inc. +// https://www.iana.org/domains/root/db/ggee.html +ggee + +// gift : DotGift, LLC +// https://www.iana.org/domains/root/db/gift.html +gift + +// gifts : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gifts.html +gifts + +// gives : Public Interest Registry +// https://www.iana.org/domains/root/db/gives.html +gives + +// giving : Public Interest Registry +// https://www.iana.org/domains/root/db/giving.html +giving + +// glass : Binky Moon, LLC +// https://www.iana.org/domains/root/db/glass.html +glass + +// gle : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gle.html +gle + +// global : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/global.html +global + +// globo : Globo Comunicação e Participações S.A +// https://www.iana.org/domains/root/db/globo.html +globo + +// gmail : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gmail.html +gmail + +// gmbh : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gmbh.html +gmbh + +// gmo : GMO Internet, Inc. +// https://www.iana.org/domains/root/db/gmo.html +gmo + +// gmx : 1&1 Mail & Media GmbH +// https://www.iana.org/domains/root/db/gmx.html +gmx + +// godaddy : Go Daddy East, LLC +// https://www.iana.org/domains/root/db/godaddy.html +godaddy + +// gold : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gold.html +gold + +// goldpoint : YODOBASHI CAMERA CO.,LTD. +// https://www.iana.org/domains/root/db/goldpoint.html +goldpoint + +// golf : Binky Moon, LLC +// https://www.iana.org/domains/root/db/golf.html +golf + +// goodyear : The Goodyear Tire & Rubber Company +// https://www.iana.org/domains/root/db/goodyear.html +goodyear + +// goog : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/goog.html +goog + +// google : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/google.html +google + +// gop : Republican State Leadership Committee, Inc. +// https://www.iana.org/domains/root/db/gop.html +gop + +// got : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/got.html +got + +// grainger : Grainger Registry Services, LLC +// https://www.iana.org/domains/root/db/grainger.html +grainger + +// graphics : Binky Moon, LLC +// https://www.iana.org/domains/root/db/graphics.html +graphics + +// gratis : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gratis.html +gratis + +// green : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/green.html +green + +// gripe : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gripe.html +gripe + +// grocery : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/grocery.html +grocery + +// group : Binky Moon, LLC +// https://www.iana.org/domains/root/db/group.html +group + +// gucci : Guccio Gucci S.p.a. +// https://www.iana.org/domains/root/db/gucci.html +gucci + +// guge : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/guge.html +guge + +// guide : Binky Moon, LLC +// https://www.iana.org/domains/root/db/guide.html +guide + +// guitars : XYZ.COM LLC +// https://www.iana.org/domains/root/db/guitars.html +guitars + +// guru : Binky Moon, LLC +// https://www.iana.org/domains/root/db/guru.html +guru + +// hair : XYZ.COM LLC +// https://www.iana.org/domains/root/db/hair.html +hair + +// hamburg : Hamburg Top-Level-Domain GmbH +// https://www.iana.org/domains/root/db/hamburg.html +hamburg + +// hangout : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/hangout.html +hangout + +// haus : Dog Beach, LLC +// https://www.iana.org/domains/root/db/haus.html +haus + +// hbo : HBO Registry Services, Inc. +// https://www.iana.org/domains/root/db/hbo.html +hbo + +// hdfc : HDFC BANK LIMITED +// https://www.iana.org/domains/root/db/hdfc.html +hdfc + +// hdfcbank : HDFC BANK LIMITED +// https://www.iana.org/domains/root/db/hdfcbank.html +hdfcbank + +// health : Registry Services, LLC +// https://www.iana.org/domains/root/db/health.html +health + +// healthcare : Binky Moon, LLC +// https://www.iana.org/domains/root/db/healthcare.html +healthcare + +// help : Innovation service Limited +// https://www.iana.org/domains/root/db/help.html +help + +// helsinki : City of Helsinki +// https://www.iana.org/domains/root/db/helsinki.html +helsinki + +// here : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/here.html +here + +// hermes : HERMES INTERNATIONAL +// https://www.iana.org/domains/root/db/hermes.html +hermes + +// hiphop : Dot Hip Hop, LLC +// https://www.iana.org/domains/root/db/hiphop.html +hiphop + +// hisamitsu : Hisamitsu Pharmaceutical Co.,Inc. +// https://www.iana.org/domains/root/db/hisamitsu.html +hisamitsu + +// hitachi : Hitachi, Ltd. +// https://www.iana.org/domains/root/db/hitachi.html +hitachi + +// hiv : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/hiv.html +hiv + +// hkt : PCCW-HKT DataCom Services Limited +// https://www.iana.org/domains/root/db/hkt.html +hkt + +// hockey : Binky Moon, LLC +// https://www.iana.org/domains/root/db/hockey.html +hockey + +// holdings : Binky Moon, LLC +// https://www.iana.org/domains/root/db/holdings.html +holdings + +// holiday : Binky Moon, LLC +// https://www.iana.org/domains/root/db/holiday.html +holiday + +// homedepot : Home Depot Product Authority, LLC +// https://www.iana.org/domains/root/db/homedepot.html +homedepot + +// homegoods : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/homegoods.html +homegoods + +// homes : XYZ.COM LLC +// https://www.iana.org/domains/root/db/homes.html +homes + +// homesense : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/homesense.html +homesense + +// honda : Honda Motor Co., Ltd. +// https://www.iana.org/domains/root/db/honda.html +honda + +// horse : Registry Services, LLC +// https://www.iana.org/domains/root/db/horse.html +horse + +// hospital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/hospital.html +hospital + +// host : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/host.html +host + +// hosting : XYZ.COM LLC +// https://www.iana.org/domains/root/db/hosting.html +hosting + +// hot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/hot.html +hot + +// hotel : HOTEL Top-Level-Domain S.a.r.l +// https://www.iana.org/domains/root/db/hotel.html +hotel + +// hotels : Booking.com B.V. +// https://www.iana.org/domains/root/db/hotels.html +hotels + +// hotmail : Microsoft Corporation +// https://www.iana.org/domains/root/db/hotmail.html +hotmail + +// house : Binky Moon, LLC +// https://www.iana.org/domains/root/db/house.html +house + +// how : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/how.html +how + +// hsbc : HSBC Global Services (UK) Limited +// https://www.iana.org/domains/root/db/hsbc.html +hsbc + +// hughes : Hughes Satellite Systems Corporation +// https://www.iana.org/domains/root/db/hughes.html +hughes + +// hyatt : Hyatt GTLD, L.L.C. +// https://www.iana.org/domains/root/db/hyatt.html +hyatt + +// hyundai : Hyundai Motor Company +// https://www.iana.org/domains/root/db/hyundai.html +hyundai + +// ibm : International Business Machines Corporation +// https://www.iana.org/domains/root/db/ibm.html +ibm + +// icbc : Industrial and Commercial Bank of China Limited +// https://www.iana.org/domains/root/db/icbc.html +icbc + +// ice : IntercontinentalExchange, Inc. +// https://www.iana.org/domains/root/db/ice.html +ice + +// icu : ShortDot SA +// https://www.iana.org/domains/root/db/icu.html +icu + +// ieee : IEEE Global LLC +// https://www.iana.org/domains/root/db/ieee.html +ieee + +// ifm : ifm electronic gmbh +// https://www.iana.org/domains/root/db/ifm.html +ifm + +// ikano : Ikano S.A. +// https://www.iana.org/domains/root/db/ikano.html +ikano + +// imamat : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/imamat.html +imamat + +// imdb : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/imdb.html +imdb + +// immo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/immo.html +immo + +// immobilien : Dog Beach, LLC +// https://www.iana.org/domains/root/db/immobilien.html +immobilien + +// inc : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/inc.html +inc + +// industries : Binky Moon, LLC +// https://www.iana.org/domains/root/db/industries.html +industries + +// infiniti : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/infiniti.html +infiniti + +// ing : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/ing.html +ing + +// ink : Registry Services, LLC +// https://www.iana.org/domains/root/db/ink.html +ink + +// institute : Binky Moon, LLC +// https://www.iana.org/domains/root/db/institute.html +institute + +// insurance : fTLD Registry Services LLC +// https://www.iana.org/domains/root/db/insurance.html +insurance + +// insure : Binky Moon, LLC +// https://www.iana.org/domains/root/db/insure.html +insure + +// international : Binky Moon, LLC +// https://www.iana.org/domains/root/db/international.html +international + +// intuit : Intuit Administrative Services, Inc. +// https://www.iana.org/domains/root/db/intuit.html +intuit + +// investments : Binky Moon, LLC +// https://www.iana.org/domains/root/db/investments.html +investments + +// ipiranga : Ipiranga Produtos de Petroleo S.A. +// https://www.iana.org/domains/root/db/ipiranga.html +ipiranga + +// irish : Binky Moon, LLC +// https://www.iana.org/domains/root/db/irish.html +irish + +// ismaili : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/ismaili.html +ismaili + +// ist : Istanbul Metropolitan Municipality +// https://www.iana.org/domains/root/db/ist.html +ist + +// istanbul : Istanbul Metropolitan Municipality +// https://www.iana.org/domains/root/db/istanbul.html +istanbul + +// itau : Itau Unibanco Holding S.A. +// https://www.iana.org/domains/root/db/itau.html +itau + +// itv : ITV Services Limited +// https://www.iana.org/domains/root/db/itv.html +itv + +// jaguar : Jaguar Land Rover Ltd +// https://www.iana.org/domains/root/db/jaguar.html +jaguar + +// java : Oracle Corporation +// https://www.iana.org/domains/root/db/java.html +java + +// jcb : JCB Co., Ltd. +// https://www.iana.org/domains/root/db/jcb.html +jcb + +// jeep : FCA US LLC. +// https://www.iana.org/domains/root/db/jeep.html +jeep + +// jetzt : Binky Moon, LLC +// https://www.iana.org/domains/root/db/jetzt.html +jetzt + +// jewelry : Binky Moon, LLC +// https://www.iana.org/domains/root/db/jewelry.html +jewelry + +// jio : Reliance Industries Limited +// https://www.iana.org/domains/root/db/jio.html +jio + +// jll : Jones Lang LaSalle Incorporated +// https://www.iana.org/domains/root/db/jll.html +jll + +// jmp : Matrix IP LLC +// https://www.iana.org/domains/root/db/jmp.html +jmp + +// jnj : Johnson & Johnson Services, Inc. +// https://www.iana.org/domains/root/db/jnj.html +jnj + +// joburg : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/joburg.html +joburg + +// jot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/jot.html +jot + +// joy : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/joy.html +joy + +// jpmorgan : JPMorgan Chase Bank, National Association +// https://www.iana.org/domains/root/db/jpmorgan.html +jpmorgan + +// jprs : Japan Registry Services Co., Ltd. +// https://www.iana.org/domains/root/db/jprs.html +jprs + +// juegos : Dog Beach, LLC +// https://www.iana.org/domains/root/db/juegos.html +juegos + +// juniper : JUNIPER NETWORKS, INC. +// https://www.iana.org/domains/root/db/juniper.html +juniper + +// kaufen : Dog Beach, LLC +// https://www.iana.org/domains/root/db/kaufen.html +kaufen + +// kddi : KDDI CORPORATION +// https://www.iana.org/domains/root/db/kddi.html +kddi + +// kerryhotels : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kerryhotels.html +kerryhotels + +// kerryproperties : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kerryproperties.html +kerryproperties + +// kfh : Kuwait Finance House +// https://www.iana.org/domains/root/db/kfh.html +kfh + +// kia : KIA MOTORS CORPORATION +// https://www.iana.org/domains/root/db/kia.html +kia + +// kids : DotKids Foundation Limited +// https://www.iana.org/domains/root/db/kids.html +kids + +// kim : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/kim.html +kim + +// kindle : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/kindle.html +kindle + +// kitchen : Binky Moon, LLC +// https://www.iana.org/domains/root/db/kitchen.html +kitchen + +// kiwi : DOT KIWI LIMITED +// https://www.iana.org/domains/root/db/kiwi.html +kiwi + +// koeln : dotKoeln GmbH +// https://www.iana.org/domains/root/db/koeln.html +koeln + +// komatsu : Komatsu Ltd. +// https://www.iana.org/domains/root/db/komatsu.html +komatsu + +// kosher : Kosher Marketing Assets LLC +// https://www.iana.org/domains/root/db/kosher.html +kosher + +// kpmg : KPMG International Cooperative (KPMG International Genossenschaft) +// https://www.iana.org/domains/root/db/kpmg.html +kpmg + +// kpn : Koninklijke KPN N.V. +// https://www.iana.org/domains/root/db/kpn.html +kpn + +// krd : KRG Department of Information Technology +// https://www.iana.org/domains/root/db/krd.html +krd + +// kred : KredTLD Pty Ltd +// https://www.iana.org/domains/root/db/kred.html +kred + +// kuokgroup : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kuokgroup.html +kuokgroup + +// kyoto : Academic Institution: Kyoto Jyoho Gakuen +// https://www.iana.org/domains/root/db/kyoto.html +kyoto + +// lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” +// https://www.iana.org/domains/root/db/lacaixa.html +lacaixa + +// lamborghini : Automobili Lamborghini S.p.A. +// https://www.iana.org/domains/root/db/lamborghini.html +lamborghini + +// lamer : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/lamer.html +lamer + +// land : Binky Moon, LLC +// https://www.iana.org/domains/root/db/land.html +land + +// landrover : Jaguar Land Rover Ltd +// https://www.iana.org/domains/root/db/landrover.html +landrover + +// lanxess : LANXESS Corporation +// https://www.iana.org/domains/root/db/lanxess.html +lanxess + +// lasalle : Jones Lang LaSalle Incorporated +// https://www.iana.org/domains/root/db/lasalle.html +lasalle + +// lat : XYZ.COM LLC +// https://www.iana.org/domains/root/db/lat.html +lat + +// latino : Dish DBS Corporation +// https://www.iana.org/domains/root/db/latino.html +latino + +// latrobe : La Trobe University +// https://www.iana.org/domains/root/db/latrobe.html +latrobe + +// law : Registry Services, LLC +// https://www.iana.org/domains/root/db/law.html +law + +// lawyer : Dog Beach, LLC +// https://www.iana.org/domains/root/db/lawyer.html +lawyer + +// lds : IRI Domain Management, LLC +// https://www.iana.org/domains/root/db/lds.html +lds + +// lease : Binky Moon, LLC +// https://www.iana.org/domains/root/db/lease.html +lease + +// leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc +// https://www.iana.org/domains/root/db/leclerc.html +leclerc + +// lefrak : LeFrak Organization, Inc. +// https://www.iana.org/domains/root/db/lefrak.html +lefrak + +// legal : Binky Moon, LLC +// https://www.iana.org/domains/root/db/legal.html +legal + +// lego : LEGO Juris A/S +// https://www.iana.org/domains/root/db/lego.html +lego + +// lexus : TOYOTA MOTOR CORPORATION +// https://www.iana.org/domains/root/db/lexus.html +lexus + +// lgbt : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/lgbt.html +lgbt + +// lidl : Schwarz Domains und Services GmbH & Co. KG +// https://www.iana.org/domains/root/db/lidl.html +lidl + +// life : Binky Moon, LLC +// https://www.iana.org/domains/root/db/life.html +life + +// lifeinsurance : American Council of Life Insurers +// https://www.iana.org/domains/root/db/lifeinsurance.html +lifeinsurance + +// lifestyle : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/lifestyle.html +lifestyle + +// lighting : Binky Moon, LLC +// https://www.iana.org/domains/root/db/lighting.html +lighting + +// like : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/like.html +like + +// lilly : Eli Lilly and Company +// https://www.iana.org/domains/root/db/lilly.html +lilly + +// limited : Binky Moon, LLC +// https://www.iana.org/domains/root/db/limited.html +limited + +// limo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/limo.html +limo + +// lincoln : Ford Motor Company +// https://www.iana.org/domains/root/db/lincoln.html +lincoln + +// link : Nova Registry Ltd +// https://www.iana.org/domains/root/db/link.html +link + +// live : Dog Beach, LLC +// https://www.iana.org/domains/root/db/live.html +live + +// living : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/living.html +living + +// llc : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/llc.html +llc + +// llp : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/llp.html +llp + +// loan : dot Loan Limited +// https://www.iana.org/domains/root/db/loan.html +loan + +// loans : Binky Moon, LLC +// https://www.iana.org/domains/root/db/loans.html +loans + +// locker : Orange Domains LLC +// https://www.iana.org/domains/root/db/locker.html +locker + +// locus : Locus Analytics LLC +// https://www.iana.org/domains/root/db/locus.html +locus + +// lol : XYZ.COM LLC +// https://www.iana.org/domains/root/db/lol.html +lol + +// london : Dot London Domains Limited +// https://www.iana.org/domains/root/db/london.html +london + +// lotte : Lotte Holdings Co., Ltd. +// https://www.iana.org/domains/root/db/lotte.html +lotte + +// lotto : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/lotto.html +lotto + +// love : Waterford Limited +// https://www.iana.org/domains/root/db/love.html +love + +// lpl : LPL Holdings, Inc. +// https://www.iana.org/domains/root/db/lpl.html +lpl + +// lplfinancial : LPL Holdings, Inc. +// https://www.iana.org/domains/root/db/lplfinancial.html +lplfinancial + +// ltd : Binky Moon, LLC +// https://www.iana.org/domains/root/db/ltd.html +ltd + +// ltda : InterNetX, Corp +// https://www.iana.org/domains/root/db/ltda.html +ltda + +// lundbeck : H. Lundbeck A/S +// https://www.iana.org/domains/root/db/lundbeck.html +lundbeck + +// luxe : Registry Services, LLC +// https://www.iana.org/domains/root/db/luxe.html +luxe + +// luxury : Luxury Partners, LLC +// https://www.iana.org/domains/root/db/luxury.html +luxury + +// madrid : Comunidad de Madrid +// https://www.iana.org/domains/root/db/madrid.html +madrid + +// maif : Mutuelle Assurance Instituteur France (MAIF) +// https://www.iana.org/domains/root/db/maif.html +maif + +// maison : Binky Moon, LLC +// https://www.iana.org/domains/root/db/maison.html +maison + +// makeup : XYZ.COM LLC +// https://www.iana.org/domains/root/db/makeup.html +makeup + +// man : MAN Truck & Bus SE +// https://www.iana.org/domains/root/db/man.html +man + +// management : Binky Moon, LLC +// https://www.iana.org/domains/root/db/management.html +management + +// mango : PUNTO FA S.L. +// https://www.iana.org/domains/root/db/mango.html +mango + +// map : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/map.html +map + +// market : Dog Beach, LLC +// https://www.iana.org/domains/root/db/market.html +market + +// marketing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/marketing.html +marketing + +// markets : Dog Beach, LLC +// https://www.iana.org/domains/root/db/markets.html +markets + +// marriott : Marriott Worldwide Corporation +// https://www.iana.org/domains/root/db/marriott.html +marriott + +// marshalls : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/marshalls.html +marshalls + +// mattel : Mattel IT Services, Inc. +// https://www.iana.org/domains/root/db/mattel.html +mattel + +// mba : Binky Moon, LLC +// https://www.iana.org/domains/root/db/mba.html +mba + +// mckinsey : McKinsey Holdings, Inc. +// https://www.iana.org/domains/root/db/mckinsey.html +mckinsey + +// med : Medistry LLC +// https://www.iana.org/domains/root/db/med.html +med + +// media : Binky Moon, LLC +// https://www.iana.org/domains/root/db/media.html +media + +// meet : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/meet.html +meet + +// melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation +// https://www.iana.org/domains/root/db/melbourne.html +melbourne + +// meme : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/meme.html +meme + +// memorial : Dog Beach, LLC +// https://www.iana.org/domains/root/db/memorial.html +memorial + +// men : Exclusive Registry Limited +// https://www.iana.org/domains/root/db/men.html +men + +// menu : Dot Menu Registry, LLC +// https://www.iana.org/domains/root/db/menu.html +menu + +// merck : Merck Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/merck.html +merck + +// merckmsd : MSD Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/merckmsd.html +merckmsd + +// miami : Registry Services, LLC +// https://www.iana.org/domains/root/db/miami.html +miami + +// microsoft : Microsoft Corporation +// https://www.iana.org/domains/root/db/microsoft.html +microsoft + +// mini : Bayerische Motoren Werke Aktiengesellschaft +// https://www.iana.org/domains/root/db/mini.html +mini + +// mint : Intuit Administrative Services, Inc. +// https://www.iana.org/domains/root/db/mint.html +mint + +// mit : Massachusetts Institute of Technology +// https://www.iana.org/domains/root/db/mit.html +mit + +// mitsubishi : Mitsubishi Corporation +// https://www.iana.org/domains/root/db/mitsubishi.html +mitsubishi + +// mlb : MLB Advanced Media DH, LLC +// https://www.iana.org/domains/root/db/mlb.html +mlb + +// mls : The Canadian Real Estate Association +// https://www.iana.org/domains/root/db/mls.html +mls + +// mma : MMA IARD +// https://www.iana.org/domains/root/db/mma.html +mma + +// mobile : Dish DBS Corporation +// https://www.iana.org/domains/root/db/mobile.html +mobile + +// moda : Dog Beach, LLC +// https://www.iana.org/domains/root/db/moda.html +moda + +// moe : Interlink Systems Innovation Institute K.K. +// https://www.iana.org/domains/root/db/moe.html +moe + +// moi : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/moi.html +moi + +// mom : XYZ.COM LLC +// https://www.iana.org/domains/root/db/mom.html +mom + +// monash : Monash University +// https://www.iana.org/domains/root/db/monash.html +monash + +// money : Binky Moon, LLC +// https://www.iana.org/domains/root/db/money.html +money + +// monster : XYZ.COM LLC +// https://www.iana.org/domains/root/db/monster.html +monster + +// mormon : IRI Domain Management, LLC +// https://www.iana.org/domains/root/db/mormon.html +mormon + +// mortgage : Dog Beach, LLC +// https://www.iana.org/domains/root/db/mortgage.html +mortgage + +// moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// https://www.iana.org/domains/root/db/moscow.html +moscow + +// moto : Motorola Trademark Holdings, LLC +// https://www.iana.org/domains/root/db/moto.html +moto + +// motorcycles : XYZ.COM LLC +// https://www.iana.org/domains/root/db/motorcycles.html +motorcycles + +// mov : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/mov.html +mov + +// movie : Binky Moon, LLC +// https://www.iana.org/domains/root/db/movie.html +movie + +// msd : MSD Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/msd.html +msd + +// mtn : MTN Dubai Limited +// https://www.iana.org/domains/root/db/mtn.html +mtn + +// mtr : MTR Corporation Limited +// https://www.iana.org/domains/root/db/mtr.html +mtr + +// music : DotMusic Limited +// https://www.iana.org/domains/root/db/music.html +music + +// nab : National Australia Bank Limited +// https://www.iana.org/domains/root/db/nab.html +nab + +// nagoya : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/nagoya.html +nagoya + +// navy : Dog Beach, LLC +// https://www.iana.org/domains/root/db/navy.html +navy + +// nba : NBA REGISTRY, LLC +// https://www.iana.org/domains/root/db/nba.html +nba + +// nec : NEC Corporation +// https://www.iana.org/domains/root/db/nec.html +nec + +// netbank : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/netbank.html +netbank + +// netflix : Netflix, Inc. +// https://www.iana.org/domains/root/db/netflix.html +netflix + +// network : Binky Moon, LLC +// https://www.iana.org/domains/root/db/network.html +network + +// neustar : NeuStar, Inc. +// https://www.iana.org/domains/root/db/neustar.html +neustar + +// new : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/new.html +new + +// news : Dog Beach, LLC +// https://www.iana.org/domains/root/db/news.html +news + +// next : Next plc +// https://www.iana.org/domains/root/db/next.html +next + +// nextdirect : Next plc +// https://www.iana.org/domains/root/db/nextdirect.html +nextdirect + +// nexus : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/nexus.html +nexus + +// nfl : NFL Reg Ops LLC +// https://www.iana.org/domains/root/db/nfl.html +nfl + +// ngo : Public Interest Registry +// https://www.iana.org/domains/root/db/ngo.html +ngo + +// nhk : Japan Broadcasting Corporation (NHK) +// https://www.iana.org/domains/root/db/nhk.html +nhk + +// nico : DWANGO Co., Ltd. +// https://www.iana.org/domains/root/db/nico.html +nico + +// nike : NIKE, Inc. +// https://www.iana.org/domains/root/db/nike.html +nike + +// nikon : NIKON CORPORATION +// https://www.iana.org/domains/root/db/nikon.html +nikon + +// ninja : Dog Beach, LLC +// https://www.iana.org/domains/root/db/ninja.html +ninja + +// nissan : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/nissan.html +nissan + +// nissay : Nippon Life Insurance Company +// https://www.iana.org/domains/root/db/nissay.html +nissay + +// nokia : Nokia Corporation +// https://www.iana.org/domains/root/db/nokia.html +nokia + +// norton : Gen Digital Inc. +// https://www.iana.org/domains/root/db/norton.html +norton + +// now : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/now.html +now + +// nowruz +// https://www.iana.org/domains/root/db/nowruz.html +nowruz + +// nowtv : Starbucks (HK) Limited +// https://www.iana.org/domains/root/db/nowtv.html +nowtv + +// nra : National Rifle Association of America +// https://www.iana.org/domains/root/db/nra.html +nra + +// nrw : Minds + Machines GmbH +// https://www.iana.org/domains/root/db/nrw.html +nrw + +// ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION +// https://www.iana.org/domains/root/db/ntt.html +ntt + +// nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications +// https://www.iana.org/domains/root/db/nyc.html +nyc + +// obi : OBI Group Holding SE & Co. KGaA +// https://www.iana.org/domains/root/db/obi.html +obi + +// observer : Fegistry, LLC +// https://www.iana.org/domains/root/db/observer.html +observer + +// office : Microsoft Corporation +// https://www.iana.org/domains/root/db/office.html +office + +// okinawa : BRregistry, Inc. +// https://www.iana.org/domains/root/db/okinawa.html +okinawa + +// olayan : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/olayan.html +olayan + +// olayangroup : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/olayangroup.html +olayangroup + +// ollo : Dish DBS Corporation +// https://www.iana.org/domains/root/db/ollo.html +ollo + +// omega : The Swatch Group Ltd +// https://www.iana.org/domains/root/db/omega.html +omega + +// one : One.com A/S +// https://www.iana.org/domains/root/db/one.html +one + +// ong : Public Interest Registry +// https://www.iana.org/domains/root/db/ong.html +ong + +// onl : Jolly Host, LLC +// https://www.iana.org/domains/root/db/onl.html +onl + +// online : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/online.html +online + +// ooo : INFIBEAM AVENUES LIMITED +// https://www.iana.org/domains/root/db/ooo.html +ooo + +// open : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/open.html +open + +// oracle : Oracle Corporation +// https://www.iana.org/domains/root/db/oracle.html +oracle + +// orange : Orange Brand Services Limited +// https://www.iana.org/domains/root/db/orange.html +orange + +// organic : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/organic.html +organic + +// origins : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/origins.html +origins + +// osaka : Osaka Registry Co., Ltd. +// https://www.iana.org/domains/root/db/osaka.html +osaka + +// otsuka : Otsuka Holdings Co., Ltd. +// https://www.iana.org/domains/root/db/otsuka.html +otsuka + +// ott : Dish DBS Corporation +// https://www.iana.org/domains/root/db/ott.html +ott + +// ovh : MédiaBC +// https://www.iana.org/domains/root/db/ovh.html +ovh + +// page : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/page.html +page + +// panasonic : Panasonic Holdings Corporation +// https://www.iana.org/domains/root/db/panasonic.html +panasonic + +// paris : City of Paris +// https://www.iana.org/domains/root/db/paris.html +paris + +// pars +// https://www.iana.org/domains/root/db/pars.html +pars + +// partners : Binky Moon, LLC +// https://www.iana.org/domains/root/db/partners.html +partners + +// parts : Binky Moon, LLC +// https://www.iana.org/domains/root/db/parts.html +parts + +// party : Blue Sky Registry Limited +// https://www.iana.org/domains/root/db/party.html +party + +// pay : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/pay.html +pay + +// pccw : PCCW Enterprises Limited +// https://www.iana.org/domains/root/db/pccw.html +pccw + +// pet : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/pet.html +pet + +// pfizer : Pfizer Inc. +// https://www.iana.org/domains/root/db/pfizer.html +pfizer + +// pharmacy : National Association of Boards of Pharmacy +// https://www.iana.org/domains/root/db/pharmacy.html +pharmacy + +// phd : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/phd.html +phd + +// philips : Koninklijke Philips N.V. +// https://www.iana.org/domains/root/db/philips.html +philips + +// phone : Dish DBS Corporation +// https://www.iana.org/domains/root/db/phone.html +phone + +// photo : Registry Services, LLC +// https://www.iana.org/domains/root/db/photo.html +photo + +// photography : Binky Moon, LLC +// https://www.iana.org/domains/root/db/photography.html +photography + +// photos : Binky Moon, LLC +// https://www.iana.org/domains/root/db/photos.html +photos + +// physio : PhysBiz Pty Ltd +// https://www.iana.org/domains/root/db/physio.html +physio + +// pics : XYZ.COM LLC +// https://www.iana.org/domains/root/db/pics.html +pics + +// pictet : Banque Pictet & Cie SA +// https://www.iana.org/domains/root/db/pictet.html +pictet + +// pictures : Binky Moon, LLC +// https://www.iana.org/domains/root/db/pictures.html +pictures + +// pid : Top Level Spectrum, Inc. +// https://www.iana.org/domains/root/db/pid.html +pid + +// pin : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/pin.html +pin + +// ping : Ping Registry Provider, Inc. +// https://www.iana.org/domains/root/db/ping.html +ping + +// pink : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/pink.html +pink + +// pioneer : Pioneer Corporation +// https://www.iana.org/domains/root/db/pioneer.html +pioneer + +// pizza : Binky Moon, LLC +// https://www.iana.org/domains/root/db/pizza.html +pizza + +// place : Binky Moon, LLC +// https://www.iana.org/domains/root/db/place.html +place + +// play : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/play.html +play + +// playstation : Sony Interactive Entertainment Inc. +// https://www.iana.org/domains/root/db/playstation.html +playstation + +// plumbing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/plumbing.html +plumbing + +// plus : Binky Moon, LLC +// https://www.iana.org/domains/root/db/plus.html +plus + +// pnc : PNC Domain Co., LLC +// https://www.iana.org/domains/root/db/pnc.html +pnc + +// pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/pohl.html +pohl + +// poker : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/poker.html +poker + +// politie : Politie Nederland +// https://www.iana.org/domains/root/db/politie.html +politie + +// porn : ICM Registry PN LLC +// https://www.iana.org/domains/root/db/porn.html +porn + +// praxi : Praxi S.p.A. +// https://www.iana.org/domains/root/db/praxi.html +praxi + +// press : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/press.html +press + +// prime : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/prime.html +prime + +// prod : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/prod.html +prod + +// productions : Binky Moon, LLC +// https://www.iana.org/domains/root/db/productions.html +productions + +// prof : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/prof.html +prof + +// progressive : Progressive Casualty Insurance Company +// https://www.iana.org/domains/root/db/progressive.html +progressive + +// promo : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/promo.html +promo + +// properties : Binky Moon, LLC +// https://www.iana.org/domains/root/db/properties.html +properties + +// property : Digital Property Infrastructure Limited +// https://www.iana.org/domains/root/db/property.html +property + +// protection : XYZ.COM LLC +// https://www.iana.org/domains/root/db/protection.html +protection + +// pru : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/pru.html +pru + +// prudential : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/prudential.html +prudential + +// pub : Dog Beach, LLC +// https://www.iana.org/domains/root/db/pub.html +pub + +// pwc : PricewaterhouseCoopers LLP +// https://www.iana.org/domains/root/db/pwc.html +pwc + +// qpon : dotQPON LLC +// https://www.iana.org/domains/root/db/qpon.html +qpon + +// quebec : PointQuébec Inc +// https://www.iana.org/domains/root/db/quebec.html +quebec + +// quest : XYZ.COM LLC +// https://www.iana.org/domains/root/db/quest.html +quest + +// racing : Premier Registry Limited +// https://www.iana.org/domains/root/db/racing.html +racing + +// radio : Digity, LLC +// https://www.iana.org/domains/root/db/radio.html +radio + +// read : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/read.html +read + +// realestate : dotRealEstate LLC +// https://www.iana.org/domains/root/db/realestate.html +realestate + +// realtor : Real Estate Domains LLC +// https://www.iana.org/domains/root/db/realtor.html +realtor + +// realty : Waterford Limited +// https://www.iana.org/domains/root/db/realty.html +realty + +// recipes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/recipes.html +recipes + +// red : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/red.html +red + +// redumbrella : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/redumbrella.html +redumbrella + +// rehab : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rehab.html +rehab + +// reise : Binky Moon, LLC +// https://www.iana.org/domains/root/db/reise.html +reise + +// reisen : Binky Moon, LLC +// https://www.iana.org/domains/root/db/reisen.html +reisen + +// reit : National Association of Real Estate Investment Trusts, Inc. +// https://www.iana.org/domains/root/db/reit.html +reit + +// reliance : Reliance Industries Limited +// https://www.iana.org/domains/root/db/reliance.html +reliance + +// ren : ZDNS International Limited +// https://www.iana.org/domains/root/db/ren.html +ren + +// rent : XYZ.COM LLC +// https://www.iana.org/domains/root/db/rent.html +rent + +// rentals : Binky Moon, LLC +// https://www.iana.org/domains/root/db/rentals.html +rentals + +// repair : Binky Moon, LLC +// https://www.iana.org/domains/root/db/repair.html +repair + +// report : Binky Moon, LLC +// https://www.iana.org/domains/root/db/report.html +report + +// republican : Dog Beach, LLC +// https://www.iana.org/domains/root/db/republican.html +republican + +// rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// https://www.iana.org/domains/root/db/rest.html +rest + +// restaurant : Binky Moon, LLC +// https://www.iana.org/domains/root/db/restaurant.html +restaurant + +// review : dot Review Limited +// https://www.iana.org/domains/root/db/review.html +review + +// reviews : Dog Beach, LLC +// https://www.iana.org/domains/root/db/reviews.html +reviews + +// rexroth : Robert Bosch GMBH +// https://www.iana.org/domains/root/db/rexroth.html +rexroth + +// rich : iRegistry GmbH +// https://www.iana.org/domains/root/db/rich.html +rich + +// richardli : Pacific Century Asset Management (HK) Limited +// https://www.iana.org/domains/root/db/richardli.html +richardli + +// ricoh : Ricoh Company, Ltd. +// https://www.iana.org/domains/root/db/ricoh.html +ricoh + +// ril : Reliance Industries Limited +// https://www.iana.org/domains/root/db/ril.html +ril + +// rio : Empresa Municipal de Informática SA - IPLANRIO +// https://www.iana.org/domains/root/db/rio.html +rio + +// rip : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rip.html +rip + +// rocks : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rocks.html +rocks + +// rodeo : Registry Services, LLC +// https://www.iana.org/domains/root/db/rodeo.html +rodeo + +// rogers : Rogers Communications Canada Inc. +// https://www.iana.org/domains/root/db/rogers.html +rogers + +// room : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/room.html +room + +// rsvp : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/rsvp.html +rsvp + +// rugby : World Rugby Strategic Developments Limited +// https://www.iana.org/domains/root/db/rugby.html +rugby + +// ruhr : dotSaarland GmbH +// https://www.iana.org/domains/root/db/ruhr.html +ruhr + +// run : Binky Moon, LLC +// https://www.iana.org/domains/root/db/run.html +run + +// rwe : RWE AG +// https://www.iana.org/domains/root/db/rwe.html +rwe + +// ryukyu : BRregistry, Inc. +// https://www.iana.org/domains/root/db/ryukyu.html +ryukyu + +// saarland : dotSaarland GmbH +// https://www.iana.org/domains/root/db/saarland.html +saarland + +// safe : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/safe.html +safe + +// safety : Safety Registry Services, LLC. +// https://www.iana.org/domains/root/db/safety.html +safety + +// sakura : SAKURA Internet Inc. +// https://www.iana.org/domains/root/db/sakura.html +sakura + +// sale : Dog Beach, LLC +// https://www.iana.org/domains/root/db/sale.html +sale + +// salon : Binky Moon, LLC +// https://www.iana.org/domains/root/db/salon.html +salon + +// samsclub : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/samsclub.html +samsclub + +// samsung : SAMSUNG SDS CO., LTD +// https://www.iana.org/domains/root/db/samsung.html +samsung + +// sandvik : Sandvik AB +// https://www.iana.org/domains/root/db/sandvik.html +sandvik + +// sandvikcoromant : Sandvik AB +// https://www.iana.org/domains/root/db/sandvikcoromant.html +sandvikcoromant + +// sanofi : Sanofi +// https://www.iana.org/domains/root/db/sanofi.html +sanofi + +// sap : SAP AG +// https://www.iana.org/domains/root/db/sap.html +sap + +// sarl : Binky Moon, LLC +// https://www.iana.org/domains/root/db/sarl.html +sarl + +// sas : Research IP LLC +// https://www.iana.org/domains/root/db/sas.html +sas + +// save : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/save.html +save + +// saxo : Saxo Bank A/S +// https://www.iana.org/domains/root/db/saxo.html +saxo + +// sbi : STATE BANK OF INDIA +// https://www.iana.org/domains/root/db/sbi.html +sbi + +// sbs : ShortDot SA +// https://www.iana.org/domains/root/db/sbs.html +sbs + +// scb : The Siam Commercial Bank Public Company Limited ("SCB") +// https://www.iana.org/domains/root/db/scb.html +scb + +// schaeffler : Schaeffler Technologies AG & Co. KG +// https://www.iana.org/domains/root/db/schaeffler.html +schaeffler + +// schmidt : SCHMIDT GROUPE S.A.S. +// https://www.iana.org/domains/root/db/schmidt.html +schmidt + +// scholarships : Scholarships.com, LLC +// https://www.iana.org/domains/root/db/scholarships.html +scholarships + +// school : Binky Moon, LLC +// https://www.iana.org/domains/root/db/school.html +school + +// schule : Binky Moon, LLC +// https://www.iana.org/domains/root/db/schule.html +schule + +// schwarz : Schwarz Domains und Services GmbH & Co. KG +// https://www.iana.org/domains/root/db/schwarz.html +schwarz + +// science : dot Science Limited +// https://www.iana.org/domains/root/db/science.html +science + +// scot : Dot Scot Registry Limited +// https://www.iana.org/domains/root/db/scot.html +scot + +// search : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/search.html +search + +// seat : SEAT, S.A. (Sociedad Unipersonal) +// https://www.iana.org/domains/root/db/seat.html +seat + +// secure : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/secure.html +secure + +// security : XYZ.COM LLC +// https://www.iana.org/domains/root/db/security.html +security + +// seek : Seek Limited +// https://www.iana.org/domains/root/db/seek.html +seek + +// select : Registry Services, LLC +// https://www.iana.org/domains/root/db/select.html +select + +// sener : Sener Ingeniería y Sistemas, S.A. +// https://www.iana.org/domains/root/db/sener.html +sener + +// services : Binky Moon, LLC +// https://www.iana.org/domains/root/db/services.html +services + +// seven : Seven West Media Ltd +// https://www.iana.org/domains/root/db/seven.html +seven + +// sew : SEW-EURODRIVE GmbH & Co KG +// https://www.iana.org/domains/root/db/sew.html +sew + +// sex : ICM Registry SX LLC +// https://www.iana.org/domains/root/db/sex.html +sex + +// sexy : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/sexy.html +sexy + +// sfr : Societe Francaise du Radiotelephone - SFR +// https://www.iana.org/domains/root/db/sfr.html +sfr + +// shangrila : Shangri‐La International Hotel Management Limited +// https://www.iana.org/domains/root/db/shangrila.html +shangrila + +// sharp : Sharp Corporation +// https://www.iana.org/domains/root/db/sharp.html +sharp + +// shell : Shell Information Technology International Inc +// https://www.iana.org/domains/root/db/shell.html +shell + +// shia +// https://www.iana.org/domains/root/db/shia.html +shia + +// shiksha : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/shiksha.html +shiksha + +// shoes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/shoes.html +shoes + +// shop : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/shop.html +shop + +// shopping : Binky Moon, LLC +// https://www.iana.org/domains/root/db/shopping.html +shopping + +// shouji : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/shouji.html +shouji + +// show : Binky Moon, LLC +// https://www.iana.org/domains/root/db/show.html +show + +// silk : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/silk.html +silk + +// sina : Sina Corporation +// https://www.iana.org/domains/root/db/sina.html +sina + +// singles : Binky Moon, LLC +// https://www.iana.org/domains/root/db/singles.html +singles + +// site : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/site.html +site + +// ski : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/ski.html +ski + +// skin : XYZ.COM LLC +// https://www.iana.org/domains/root/db/skin.html +skin + +// sky : Sky UK Limited +// https://www.iana.org/domains/root/db/sky.html +sky + +// skype : Microsoft Corporation +// https://www.iana.org/domains/root/db/skype.html +skype + +// sling : DISH Technologies L.L.C. +// https://www.iana.org/domains/root/db/sling.html +sling + +// smart : Smart Communications, Inc. (SMART) +// https://www.iana.org/domains/root/db/smart.html +smart + +// smile : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/smile.html +smile + +// sncf : Société Nationale SNCF +// https://www.iana.org/domains/root/db/sncf.html +sncf + +// soccer : Binky Moon, LLC +// https://www.iana.org/domains/root/db/soccer.html +soccer + +// social : Dog Beach, LLC +// https://www.iana.org/domains/root/db/social.html +social + +// softbank : SoftBank Group Corp. +// https://www.iana.org/domains/root/db/softbank.html +softbank + +// software : Dog Beach, LLC +// https://www.iana.org/domains/root/db/software.html +software + +// sohu : Sohu.com Limited +// https://www.iana.org/domains/root/db/sohu.html +sohu + +// solar : Binky Moon, LLC +// https://www.iana.org/domains/root/db/solar.html +solar + +// solutions : Binky Moon, LLC +// https://www.iana.org/domains/root/db/solutions.html +solutions + +// song : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/song.html +song + +// sony : Sony Group Corporation +// https://www.iana.org/domains/root/db/sony.html +sony + +// soy : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/soy.html +soy + +// spa : Asia Spa and Wellness Promotion Council Limited +// https://www.iana.org/domains/root/db/spa.html +spa + +// space : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/space.html +space + +// sport : SportAccord +// https://www.iana.org/domains/root/db/sport.html +sport + +// spot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/spot.html +spot + +// srl : InterNetX, Corp +// https://www.iana.org/domains/root/db/srl.html +srl + +// stada : STADA Arzneimittel AG +// https://www.iana.org/domains/root/db/stada.html +stada + +// staples : Staples, Inc. +// https://www.iana.org/domains/root/db/staples.html +staples + +// star : Star India Private Limited +// https://www.iana.org/domains/root/db/star.html +star + +// statebank : STATE BANK OF INDIA +// https://www.iana.org/domains/root/db/statebank.html +statebank + +// statefarm : State Farm Mutual Automobile Insurance Company +// https://www.iana.org/domains/root/db/statefarm.html +statefarm + +// stc : Saudi Telecom Company +// https://www.iana.org/domains/root/db/stc.html +stc + +// stcgroup : Saudi Telecom Company +// https://www.iana.org/domains/root/db/stcgroup.html +stcgroup + +// stockholm : Stockholms kommun +// https://www.iana.org/domains/root/db/stockholm.html +stockholm + +// storage : XYZ.COM LLC +// https://www.iana.org/domains/root/db/storage.html +storage + +// store : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/store.html +store + +// stream : dot Stream Limited +// https://www.iana.org/domains/root/db/stream.html +stream + +// studio : Dog Beach, LLC +// https://www.iana.org/domains/root/db/studio.html +studio + +// study : Registry Services, LLC +// https://www.iana.org/domains/root/db/study.html +study + +// style : Binky Moon, LLC +// https://www.iana.org/domains/root/db/style.html +style + +// sucks : Vox Populi Registry Ltd. +// https://www.iana.org/domains/root/db/sucks.html +sucks + +// supplies : Binky Moon, LLC +// https://www.iana.org/domains/root/db/supplies.html +supplies + +// supply : Binky Moon, LLC +// https://www.iana.org/domains/root/db/supply.html +supply + +// support : Binky Moon, LLC +// https://www.iana.org/domains/root/db/support.html +support + +// surf : Registry Services, LLC +// https://www.iana.org/domains/root/db/surf.html +surf + +// surgery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/surgery.html +surgery + +// suzuki : SUZUKI MOTOR CORPORATION +// https://www.iana.org/domains/root/db/suzuki.html +suzuki + +// swatch : The Swatch Group Ltd +// https://www.iana.org/domains/root/db/swatch.html +swatch + +// swiss : Swiss Confederation +// https://www.iana.org/domains/root/db/swiss.html +swiss + +// sydney : State of New South Wales, Department of Premier and Cabinet +// https://www.iana.org/domains/root/db/sydney.html +sydney + +// systems : Binky Moon, LLC +// https://www.iana.org/domains/root/db/systems.html +systems + +// tab : Tabcorp Holdings Limited +// https://www.iana.org/domains/root/db/tab.html +tab + +// taipei : Taipei City Government +// https://www.iana.org/domains/root/db/taipei.html +taipei + +// talk : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/talk.html +talk + +// taobao : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/taobao.html +taobao + +// target : Target Domain Holdings, LLC +// https://www.iana.org/domains/root/db/target.html +target + +// tatamotors : Tata Motors Ltd +// https://www.iana.org/domains/root/db/tatamotors.html +tatamotors + +// tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" +// https://www.iana.org/domains/root/db/tatar.html +tatar + +// tattoo : Registry Services, LLC +// https://www.iana.org/domains/root/db/tattoo.html +tattoo + +// tax : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tax.html +tax + +// taxi : Binky Moon, LLC +// https://www.iana.org/domains/root/db/taxi.html +taxi + +// tci +// https://www.iana.org/domains/root/db/tci.html +tci + +// tdk : TDK Corporation +// https://www.iana.org/domains/root/db/tdk.html +tdk + +// team : Binky Moon, LLC +// https://www.iana.org/domains/root/db/team.html +team + +// tech : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/tech.html +tech + +// technology : Binky Moon, LLC +// https://www.iana.org/domains/root/db/technology.html +technology + +// temasek : Temasek Holdings (Private) Limited +// https://www.iana.org/domains/root/db/temasek.html +temasek + +// tennis : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tennis.html +tennis + +// teva : Teva Pharmaceutical Industries Limited +// https://www.iana.org/domains/root/db/teva.html +teva + +// thd : Home Depot Product Authority, LLC +// https://www.iana.org/domains/root/db/thd.html +thd + +// theater : Binky Moon, LLC +// https://www.iana.org/domains/root/db/theater.html +theater + +// theatre : XYZ.COM LLC +// https://www.iana.org/domains/root/db/theatre.html +theatre + +// tiaa : Teachers Insurance and Annuity Association of America +// https://www.iana.org/domains/root/db/tiaa.html +tiaa + +// tickets : XYZ.COM LLC +// https://www.iana.org/domains/root/db/tickets.html +tickets + +// tienda : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tienda.html +tienda + +// tips : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tips.html +tips + +// tires : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tires.html +tires + +// tirol : punkt Tirol GmbH +// https://www.iana.org/domains/root/db/tirol.html +tirol + +// tjmaxx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tjmaxx.html +tjmaxx + +// tjx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tjx.html +tjx + +// tkmaxx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tkmaxx.html +tkmaxx + +// tmall : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/tmall.html +tmall + +// today : Binky Moon, LLC +// https://www.iana.org/domains/root/db/today.html +today + +// tokyo : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/tokyo.html +tokyo + +// tools : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tools.html +tools + +// top : Hong Kong Zhongze International Limited +// https://www.iana.org/domains/root/db/top.html +top + +// toray : Toray Industries, Inc. +// https://www.iana.org/domains/root/db/toray.html +toray + +// toshiba : TOSHIBA Corporation +// https://www.iana.org/domains/root/db/toshiba.html +toshiba + +// total : TotalEnergies SE +// https://www.iana.org/domains/root/db/total.html +total + +// tours : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tours.html +tours + +// town : Binky Moon, LLC +// https://www.iana.org/domains/root/db/town.html +town + +// toyota : TOYOTA MOTOR CORPORATION +// https://www.iana.org/domains/root/db/toyota.html +toyota + +// toys : Binky Moon, LLC +// https://www.iana.org/domains/root/db/toys.html +toys + +// trade : Elite Registry Limited +// https://www.iana.org/domains/root/db/trade.html +trade + +// trading : Dog Beach, LLC +// https://www.iana.org/domains/root/db/trading.html +trading + +// training : Binky Moon, LLC +// https://www.iana.org/domains/root/db/training.html +training + +// travel : Dog Beach, LLC +// https://www.iana.org/domains/root/db/travel.html +travel + +// travelers : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/travelers.html +travelers + +// travelersinsurance : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/travelersinsurance.html +travelersinsurance + +// trust : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/trust.html +trust + +// trv : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/trv.html +trv + +// tube : Latin American Telecom LLC +// https://www.iana.org/domains/root/db/tube.html +tube + +// tui : TUI AG +// https://www.iana.org/domains/root/db/tui.html +tui + +// tunes : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/tunes.html +tunes + +// tushu : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/tushu.html +tushu + +// tvs : T V SUNDRAM IYENGAR & SONS LIMITED +// https://www.iana.org/domains/root/db/tvs.html +tvs + +// ubank : National Australia Bank Limited +// https://www.iana.org/domains/root/db/ubank.html +ubank + +// ubs : UBS AG +// https://www.iana.org/domains/root/db/ubs.html +ubs + +// unicom : China United Network Communications Corporation Limited +// https://www.iana.org/domains/root/db/unicom.html +unicom + +// university : Binky Moon, LLC +// https://www.iana.org/domains/root/db/university.html +university + +// uno : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/uno.html +uno + +// uol : UBN INTERNET LTDA. +// https://www.iana.org/domains/root/db/uol.html +uol + +// ups : UPS Market Driver, Inc. +// https://www.iana.org/domains/root/db/ups.html +ups + +// vacations : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vacations.html +vacations + +// vana : D3 Registry LLC +// https://www.iana.org/domains/root/db/vana.html +vana + +// vanguard : The Vanguard Group, Inc. +// https://www.iana.org/domains/root/db/vanguard.html +vanguard + +// vegas : Dot Vegas, Inc. +// https://www.iana.org/domains/root/db/vegas.html +vegas + +// ventures : Binky Moon, LLC +// https://www.iana.org/domains/root/db/ventures.html +ventures + +// verisign : VeriSign, Inc. +// https://www.iana.org/domains/root/db/verisign.html +verisign + +// versicherung : tldbox GmbH +// https://www.iana.org/domains/root/db/versicherung.html +versicherung + +// vet : Dog Beach, LLC +// https://www.iana.org/domains/root/db/vet.html +vet + +// viajes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/viajes.html +viajes + +// video : Dog Beach, LLC +// https://www.iana.org/domains/root/db/video.html +video + +// vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe +// https://www.iana.org/domains/root/db/vig.html +vig + +// viking : Viking River Cruises (Bermuda) Ltd. +// https://www.iana.org/domains/root/db/viking.html +viking + +// villas : Binky Moon, LLC +// https://www.iana.org/domains/root/db/villas.html +villas + +// vin : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vin.html +vin + +// vip : Registry Services, LLC +// https://www.iana.org/domains/root/db/vip.html +vip + +// virgin : Virgin Enterprises Limited +// https://www.iana.org/domains/root/db/virgin.html +virgin + +// visa : Visa Worldwide Pte. Limited +// https://www.iana.org/domains/root/db/visa.html +visa + +// vision : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vision.html +vision + +// viva : Saudi Telecom Company +// https://www.iana.org/domains/root/db/viva.html +viva + +// vivo : Telefonica Brasil S.A. +// https://www.iana.org/domains/root/db/vivo.html +vivo + +// vlaanderen : DNS.be vzw +// https://www.iana.org/domains/root/db/vlaanderen.html +vlaanderen + +// vodka : Registry Services, LLC +// https://www.iana.org/domains/root/db/vodka.html +vodka + +// volvo : Volvo Holding Sverige Aktiebolag +// https://www.iana.org/domains/root/db/volvo.html +volvo + +// vote : Monolith Registry LLC +// https://www.iana.org/domains/root/db/vote.html +vote + +// voting : Valuetainment Corp. +// https://www.iana.org/domains/root/db/voting.html +voting + +// voto : Monolith Registry LLC +// https://www.iana.org/domains/root/db/voto.html +voto + +// voyage : Binky Moon, LLC +// https://www.iana.org/domains/root/db/voyage.html +voyage + +// wales : Nominet UK +// https://www.iana.org/domains/root/db/wales.html +wales + +// walmart : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/walmart.html +walmart + +// walter : Sandvik AB +// https://www.iana.org/domains/root/db/walter.html +walter + +// wang : Zodiac Wang Limited +// https://www.iana.org/domains/root/db/wang.html +wang + +// wanggou : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/wanggou.html +wanggou + +// watch : Binky Moon, LLC +// https://www.iana.org/domains/root/db/watch.html +watch + +// watches : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/watches.html +watches + +// weather : The Weather Company, LLC +// https://www.iana.org/domains/root/db/weather.html +weather + +// weatherchannel : The Weather Company, LLC +// https://www.iana.org/domains/root/db/weatherchannel.html +weatherchannel + +// webcam : dot Webcam Limited +// https://www.iana.org/domains/root/db/webcam.html +webcam + +// weber : Saint-Gobain Weber SA +// https://www.iana.org/domains/root/db/weber.html +weber + +// website : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/website.html +website + +// wed +// https://www.iana.org/domains/root/db/wed.html +wed + +// wedding : Registry Services, LLC +// https://www.iana.org/domains/root/db/wedding.html +wedding + +// weibo : Sina Corporation +// https://www.iana.org/domains/root/db/weibo.html +weibo + +// weir : Weir Group IP Limited +// https://www.iana.org/domains/root/db/weir.html +weir + +// whoswho : Who's Who Registry +// https://www.iana.org/domains/root/db/whoswho.html +whoswho + +// wien : domainworx Service & Management GmbH +// https://www.iana.org/domains/root/db/wien.html +wien + +// wiki : Registry Services, LLC +// https://www.iana.org/domains/root/db/wiki.html +wiki + +// williamhill : William Hill Organization Limited +// https://www.iana.org/domains/root/db/williamhill.html +williamhill + +// win : First Registry Limited +// https://www.iana.org/domains/root/db/win.html +win + +// windows : Microsoft Corporation +// https://www.iana.org/domains/root/db/windows.html +windows + +// wine : Binky Moon, LLC +// https://www.iana.org/domains/root/db/wine.html +wine + +// winners : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/winners.html +winners + +// wme : William Morris Endeavor Entertainment, LLC +// https://www.iana.org/domains/root/db/wme.html +wme + +// woodside : Woodside Petroleum Limited +// https://www.iana.org/domains/root/db/woodside.html +woodside + +// work : Registry Services, LLC +// https://www.iana.org/domains/root/db/work.html +work + +// works : Binky Moon, LLC +// https://www.iana.org/domains/root/db/works.html +works + +// world : Binky Moon, LLC +// https://www.iana.org/domains/root/db/world.html +world + +// wow : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/wow.html +wow + +// wtc : World Trade Centers Association, Inc. +// https://www.iana.org/domains/root/db/wtc.html +wtc + +// wtf : Binky Moon, LLC +// https://www.iana.org/domains/root/db/wtf.html +wtf + +// xbox : Microsoft Corporation +// https://www.iana.org/domains/root/db/xbox.html +xbox + +// xerox : Xerox DNHC LLC +// https://www.iana.org/domains/root/db/xerox.html +xerox + +// xihuan : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/xihuan.html +xihuan + +// xin : Elegant Leader Limited +// https://www.iana.org/domains/root/db/xin.html +xin + +// xn--11b4c3d : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--11b4c3d.html +कॉम + +// xn--1ck2e1b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--1ck2e1b.html +セール + +// xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--1qqw23a.html +佛山 + +// xn--30rr7y : Excellent First Limited +// https://www.iana.org/domains/root/db/xn--30rr7y.html +慈善 + +// xn--3bst00m : Eagle Horizon Limited +// https://www.iana.org/domains/root/db/xn--3bst00m.html +集团 + +// xn--3ds443g : Beijing TLD Registry Technology Limited +// https://www.iana.org/domains/root/db/xn--3ds443g.html +在线 + +// xn--3pxu8k : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--3pxu8k.html +点看 + +// xn--42c2d9a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--42c2d9a.html +คอม + +// xn--45q11c : Zodiac Gemini Ltd +// https://www.iana.org/domains/root/db/xn--45q11c.html +八卦 + +// xn--4gbrim : Helium TLDs Ltd +// https://www.iana.org/domains/root/db/xn--4gbrim.html +موقع + +// xn--55qw42g : China Organizational Name Administration Center +// https://www.iana.org/domains/root/db/xn--55qw42g.html +公益 + +// xn--55qx5d : China Internet Network Information Center (CNNIC) +// https://www.iana.org/domains/root/db/xn--55qx5d.html +公司 + +// xn--5su34j936bgsg : Shangri‐La International Hotel Management Limited +// https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html +香格里拉 + +// xn--5tzm5g : Global Website TLD Asia Limited +// https://www.iana.org/domains/root/db/xn--5tzm5g.html +网站 + +// xn--6frz82g : Identity Digital Domains Limited +// https://www.iana.org/domains/root/db/xn--6frz82g.html +移动 + +// xn--6qq986b3xl : Tycoon Treasure Limited +// https://www.iana.org/domains/root/db/xn--6qq986b3xl.html +我爱你 + +// xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// https://www.iana.org/domains/root/db/xn--80adxhks.html +москва + +// xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--80aqecdr1a.html +католик + +// xn--80asehdb : CORE Association +// https://www.iana.org/domains/root/db/xn--80asehdb.html +онлайн + +// xn--80aswg : CORE Association +// https://www.iana.org/domains/root/db/xn--80aswg.html +сайт + +// xn--8y0a063a : China United Network Communications Corporation Limited +// https://www.iana.org/domains/root/db/xn--8y0a063a.html +联通 + +// xn--9dbq2a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--9dbq2a.html +קום + +// xn--9et52u : RISE VICTORY LIMITED +// https://www.iana.org/domains/root/db/xn--9et52u.html +时尚 + +// xn--9krt00a : Sina Corporation +// https://www.iana.org/domains/root/db/xn--9krt00a.html +微博 + +// xn--b4w605ferd : Temasek Holdings (Private) Limited +// https://www.iana.org/domains/root/db/xn--b4w605ferd.html +淡马锡 + +// xn--bck1b9a5dre4c : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html +ファッション + +// xn--c1avg : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--c1avg.html +орг + +// xn--c2br7g : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--c2br7g.html +नेट + +// xn--cck2b3b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--cck2b3b.html +ストア + +// xn--cckwcxetd : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--cckwcxetd.html +アマゾン + +// xn--cg4bki : SAMSUNG SDS CO., LTD +// https://www.iana.org/domains/root/db/xn--cg4bki.html +삼성 + +// xn--czr694b : Internet DotTrademark Organisation Limited +// https://www.iana.org/domains/root/db/xn--czr694b.html +商标 + +// xn--czrs0t : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--czrs0t.html +商店 + +// xn--czru2d : Zodiac Aquarius Limited +// https://www.iana.org/domains/root/db/xn--czru2d.html +商城 + +// xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet” +// https://www.iana.org/domains/root/db/xn--d1acj3b.html +дети + +// xn--eckvdtc9d : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--eckvdtc9d.html +ポイント + +// xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--efvy88h.html +新闻 + +// xn--fct429k : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--fct429k.html +家電 + +// xn--fhbei : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--fhbei.html +كوم + +// xn--fiq228c5hs : Beijing TLD Registry Technology Limited +// https://www.iana.org/domains/root/db/xn--fiq228c5hs.html +中文网 + +// xn--fiq64b : CITIC Group Corporation +// https://www.iana.org/domains/root/db/xn--fiq64b.html +中信 + +// xn--fjq720a : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--fjq720a.html +娱乐 + +// xn--flw351e : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--flw351e.html +谷歌 + +// xn--fzys8d69uvgm : PCCW Enterprises Limited +// https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html +電訊盈科 + +// xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD. +// https://www.iana.org/domains/root/db/xn--g2xx48c.html +购物 + +// xn--gckr3f0f : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--gckr3f0f.html +クラウド + +// xn--gk3at1e : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--gk3at1e.html +通販 + +// xn--hxt814e : Zodiac Taurus Limited +// https://www.iana.org/domains/root/db/xn--hxt814e.html +网店 + +// xn--i1b6b1a6a2e : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html +संगठन + +// xn--imr513n : Internet DotTrademark Organisation Limited +// https://www.iana.org/domains/root/db/xn--imr513n.html +餐厅 + +// xn--io0a7i : China Internet Network Information Center (CNNIC) +// https://www.iana.org/domains/root/db/xn--io0a7i.html +网络 + +// xn--j1aef : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--j1aef.html +ком + +// xn--jlq480n2rg : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--jlq480n2rg.html +亚马逊 + +// xn--jvr189m : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--jvr189m.html +食品 + +// xn--kcrx77d1x4a : Koninklijke Philips N.V. +// https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html +飞利浦 + +// xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd +// https://www.iana.org/domains/root/db/xn--kput3i.html +手机 + +// xn--mgba3a3ejt : Aramco Services Company +// https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html +ارامكو + +// xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html +العليان + +// xn--mgbab2bd : CORE Association +// https://www.iana.org/domains/root/db/xn--mgbab2bd.html +بازار + +// xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre +// https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html +ابوظبي + +// xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html +كاثوليك + +// xn--mgbt3dhd +// https://www.iana.org/domains/root/db/xn--mgbt3dhd.html +همراه + +// xn--mk1bu44c : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--mk1bu44c.html +닷컴 + +// xn--mxtq1m : Net-Chinese Co., Ltd. +// https://www.iana.org/domains/root/db/xn--mxtq1m.html +政府 + +// xn--ngbc5azd : International Domain Registry Pty. Ltd. +// https://www.iana.org/domains/root/db/xn--ngbc5azd.html +شبكة + +// xn--ngbe9e0a : Kuwait Finance House +// https://www.iana.org/domains/root/db/xn--ngbe9e0a.html +بيتك + +// xn--ngbrx : League of Arab States +// https://www.iana.org/domains/root/db/xn--ngbrx.html +عرب + +// xn--nqv7f : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--nqv7f.html +机构 + +// xn--nqv7fs00ema : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html +组织机构 + +// xn--nyqy26a : Stable Tone Limited +// https://www.iana.org/domains/root/db/xn--nyqy26a.html +健康 + +// xn--otu796d : Jiang Yu Liang Cai Technology Company Limited +// https://www.iana.org/domains/root/db/xn--otu796d.html +招聘 + +// xn--p1acf : Rusnames Limited +// https://www.iana.org/domains/root/db/xn--p1acf.html +рус + +// xn--pssy2u : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--pssy2u.html +大拿 + +// xn--q9jyb4c : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--q9jyb4c.html +みんな + +// xn--qcka1pmc : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--qcka1pmc.html +グーグル + +// xn--rhqv96g : Stable Tone Limited +// https://www.iana.org/domains/root/db/xn--rhqv96g.html +世界 + +// xn--rovu88b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--rovu88b.html +書籍 + +// xn--ses554g : KNET Co., Ltd. +// https://www.iana.org/domains/root/db/xn--ses554g.html +网址 + +// xn--t60b56a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--t60b56a.html +닷넷 + +// xn--tckwe : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--tckwe.html +コム + +// xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--tiq49xqyj.html +天主教 + +// xn--unup4y : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--unup4y.html +游戏 + +// xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html +vermögensberater + +// xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html +vermögensberatung + +// xn--vhquv : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--vhquv.html +企业 + +// xn--vuq861b : Beijing Tele-info Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--vuq861b.html +信息 + +// xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html +嘉里大酒店 + +// xn--w4rs40l : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/xn--w4rs40l.html +嘉里 + +// xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--xhq521b.html +广东 + +// xn--zfr164b : China Organizational Name Administration Center +// https://www.iana.org/domains/root/db/xn--zfr164b.html +政务 + +// xyz : XYZ.COM LLC +// https://www.iana.org/domains/root/db/xyz.html +xyz + +// yachts : XYZ.COM LLC +// https://www.iana.org/domains/root/db/yachts.html +yachts + +// yahoo : Yahoo Inc. +// https://www.iana.org/domains/root/db/yahoo.html +yahoo + +// yamaxun : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/yamaxun.html +yamaxun + +// yandex : YANDEX, LLC +// https://www.iana.org/domains/root/db/yandex.html +yandex + +// yodobashi : YODOBASHI CAMERA CO.,LTD. +// https://www.iana.org/domains/root/db/yodobashi.html +yodobashi + +// yoga : Registry Services, LLC +// https://www.iana.org/domains/root/db/yoga.html +yoga + +// yokohama : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/yokohama.html +yokohama + +// you : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/you.html +you + +// youtube : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/youtube.html +youtube + +// yun : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/yun.html +yun + +// zappos : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/zappos.html +zappos + +// zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.) +// https://www.iana.org/domains/root/db/zara.html +zara + +// zero : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/zero.html +zero + +// zip : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/zip.html +zip + +// zone : Binky Moon, LLC +// https://www.iana.org/domains/root/db/zone.html +zone + +// zuerich : Kanton Zürich (Canton of Zurich) +// https://www.iana.org/domains/root/db/zuerich.html +zuerich + +// ===END ICANN DOMAINS=== + +// ===BEGIN PRIVATE DOMAINS=== + +// (Note: these are in alphabetical order by company name) + +// .KRD : https://nic.krd +co.krd +edu.krd + +// .pl domains (grandfathered) +art.pl +gliwice.pl +krakow.pl +poznan.pl +wroc.pl +zakopane.pl + +// 1GB LLC : https://www.1gb.ua/ +// Submitted by 1GB LLC +cc.ua +inf.ua +ltd.ua + +// 611 blockchain domain name system : https://sixone.one/ +611.to + +// A2 Hosting +// Submitted by Tyler Hall +a2hosted.com +cpserver.com + +// Acorn Labs : https://acorn.io +// Submitted by Craig Jellick +*.on-acorn.io + +// ActiveTrail : https://www.activetrail.biz/ +// Submitted by Ofer Kalaora +activetrail.biz + +// Adaptable.io : https://adaptable.io +// Submitted by Mark Terrel +adaptable.app + +// addr.tools : https://addr.tools/ +// Submitted by Brian Shea +myaddr.dev +myaddr.io +dyn.addr.tools +myaddr.tools + +// Adobe : https://www.adobe.com/ +// Submitted by Ian Boston and Lars Trieloff +adobeaemcloud.com +*.dev.adobeaemcloud.com +aem.live +hlx.live +adobeaemcloud.net +aem.network +aem.page +hlx.page +aem.reviews + +// Adobe Developer Platform : https://developer.adobe.com +// Submitted by Jesse MacFadyen +adobeio-static.net +adobeioruntime.net + +// Africa.com Web Solutions Ltd : https://registry.africa.com +// Submitted by Gavin Brown +africa.com + +// AgentbaseAI Inc. : https://assistant-ui.com +// Submitted by Simon Farshid +*.auiusercontent.com + +// Agnat sp. z o.o. : https://domena.pl +// Submitted by Przemyslaw Plewa +beep.pl + +// Aiven : https://aiven.io/ +// Submitted by Aiven Security Team +aiven.app +aivencloud.com + +// Akamai : https://www.akamai.com/ +// Submitted by Akamai Team +akadns.net +akamai.net +akamai-staging.net +akamaiedge.net +akamaiedge-staging.net +akamaihd.net +akamaihd-staging.net +akamaiorigin.net +akamaiorigin-staging.net +akamaized.net +akamaized-staging.net +edgekey.net +edgekey-staging.net +edgesuite.net +edgesuite-staging.net + +// alboto.ca : http://alboto.ca +// Submitted by Anton Avramov +barsy.ca + +// Alces Software Ltd : http://alces-software.com +// Submitted by Mark J. Titorenko +*.compute.estate +*.alces.network + +// Alibaba Cloud API Gateway +// Submitted by Alibaba Cloud Security +alibabacloudcs.com +ms.fun +ms.show + +// all-inkl.com : https://all-inkl.com +// Submitted by Werner Kaltofen +kasserver.com + +// Altervista : https://www.altervista.org +// Submitted by Carlo Cannas +altervista.org + +// alwaysdata : https://www.alwaysdata.com +// Submitted by Cyril +alwaysdata.net + +// Amaze Software : https://amaze.co +// Submitted by Domain Admin +myamaze.net + +// Amazon : https://www.amazon.com/ +// Submitted by AWS Security +// Subsections of Amazon/subsidiaries will appear until "concludes" tag + +// Amazon API Gateway +// Submitted by AWS Security +// Reference: 6a4f5a95-8c7d-4077-a7af-9cf1abec0a53 +execute-api.cn-north-1.amazonaws.com.cn +execute-api.cn-northwest-1.amazonaws.com.cn +execute-api.af-south-1.amazonaws.com +execute-api.ap-east-1.amazonaws.com +execute-api.ap-northeast-1.amazonaws.com +execute-api.ap-northeast-2.amazonaws.com +execute-api.ap-northeast-3.amazonaws.com +execute-api.ap-south-1.amazonaws.com +execute-api.ap-south-2.amazonaws.com +execute-api.ap-southeast-1.amazonaws.com +execute-api.ap-southeast-2.amazonaws.com +execute-api.ap-southeast-3.amazonaws.com +execute-api.ap-southeast-4.amazonaws.com +execute-api.ap-southeast-5.amazonaws.com +execute-api.ca-central-1.amazonaws.com +execute-api.ca-west-1.amazonaws.com +execute-api.eu-central-1.amazonaws.com +execute-api.eu-central-2.amazonaws.com +execute-api.eu-north-1.amazonaws.com +execute-api.eu-south-1.amazonaws.com +execute-api.eu-south-2.amazonaws.com +execute-api.eu-west-1.amazonaws.com +execute-api.eu-west-2.amazonaws.com +execute-api.eu-west-3.amazonaws.com +execute-api.il-central-1.amazonaws.com +execute-api.me-central-1.amazonaws.com +execute-api.me-south-1.amazonaws.com +execute-api.sa-east-1.amazonaws.com +execute-api.us-east-1.amazonaws.com +execute-api.us-east-2.amazonaws.com +execute-api.us-gov-east-1.amazonaws.com +execute-api.us-gov-west-1.amazonaws.com +execute-api.us-west-1.amazonaws.com +execute-api.us-west-2.amazonaws.com + +// Amazon CloudFront +// Submitted by Donavan Miller +// Reference: 54144616-fd49-4435-8535-19c6a601bdb3 +cloudfront.net + +// Amazon Cognito +// Submitted by AWS Security +// Reference: d7d4a954-976e-403e-a010-de9ed0cfbbd1 +auth.af-south-1.amazoncognito.com +auth.ap-east-1.amazoncognito.com +auth.ap-northeast-1.amazoncognito.com +auth.ap-northeast-2.amazoncognito.com +auth.ap-northeast-3.amazoncognito.com +auth.ap-south-1.amazoncognito.com +auth.ap-south-2.amazoncognito.com +auth.ap-southeast-1.amazoncognito.com +auth.ap-southeast-2.amazoncognito.com +auth.ap-southeast-3.amazoncognito.com +auth.ap-southeast-4.amazoncognito.com +auth.ap-southeast-5.amazoncognito.com +auth.ap-southeast-7.amazoncognito.com +auth.ca-central-1.amazoncognito.com +auth.ca-west-1.amazoncognito.com +auth.eu-central-1.amazoncognito.com +auth.eu-central-2.amazoncognito.com +auth.eu-north-1.amazoncognito.com +auth.eu-south-1.amazoncognito.com +auth.eu-south-2.amazoncognito.com +auth.eu-west-1.amazoncognito.com +auth.eu-west-2.amazoncognito.com +auth.eu-west-3.amazoncognito.com +auth.il-central-1.amazoncognito.com +auth.me-central-1.amazoncognito.com +auth.me-south-1.amazoncognito.com +auth.mx-central-1.amazoncognito.com +auth.sa-east-1.amazoncognito.com +auth.us-east-1.amazoncognito.com +auth-fips.us-east-1.amazoncognito.com +auth.us-east-2.amazoncognito.com +auth-fips.us-east-2.amazoncognito.com +auth-fips.us-gov-east-1.amazoncognito.com +auth-fips.us-gov-west-1.amazoncognito.com +auth.us-west-1.amazoncognito.com +auth-fips.us-west-1.amazoncognito.com +auth.us-west-2.amazoncognito.com +auth-fips.us-west-2.amazoncognito.com +auth.cognito-idp.eusc-de-east-1.on.amazonwebservices.eu + +// Amazon EC2 +// Submitted by Luke Wells +// Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 +*.compute.amazonaws.com.cn +*.compute.amazonaws.com +*.compute-1.amazonaws.com +us-east-1.amazonaws.com + +// Amazon EMR +// Submitted by AWS Security +// Reference: 82f43f9f-bbb8-400e-8349-854f5a62f20d +emrappui-prod.cn-north-1.amazonaws.com.cn +emrnotebooks-prod.cn-north-1.amazonaws.com.cn +emrstudio-prod.cn-north-1.amazonaws.com.cn +emrappui-prod.cn-northwest-1.amazonaws.com.cn +emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn +emrstudio-prod.cn-northwest-1.amazonaws.com.cn +emrappui-prod.af-south-1.amazonaws.com +emrnotebooks-prod.af-south-1.amazonaws.com +emrstudio-prod.af-south-1.amazonaws.com +emrappui-prod.ap-east-1.amazonaws.com +emrnotebooks-prod.ap-east-1.amazonaws.com +emrstudio-prod.ap-east-1.amazonaws.com +emrappui-prod.ap-northeast-1.amazonaws.com +emrnotebooks-prod.ap-northeast-1.amazonaws.com +emrstudio-prod.ap-northeast-1.amazonaws.com +emrappui-prod.ap-northeast-2.amazonaws.com +emrnotebooks-prod.ap-northeast-2.amazonaws.com +emrstudio-prod.ap-northeast-2.amazonaws.com +emrappui-prod.ap-northeast-3.amazonaws.com +emrnotebooks-prod.ap-northeast-3.amazonaws.com +emrstudio-prod.ap-northeast-3.amazonaws.com +emrappui-prod.ap-south-1.amazonaws.com +emrnotebooks-prod.ap-south-1.amazonaws.com +emrstudio-prod.ap-south-1.amazonaws.com +emrappui-prod.ap-south-2.amazonaws.com +emrnotebooks-prod.ap-south-2.amazonaws.com +emrstudio-prod.ap-south-2.amazonaws.com +emrappui-prod.ap-southeast-1.amazonaws.com +emrnotebooks-prod.ap-southeast-1.amazonaws.com +emrstudio-prod.ap-southeast-1.amazonaws.com +emrappui-prod.ap-southeast-2.amazonaws.com +emrnotebooks-prod.ap-southeast-2.amazonaws.com +emrstudio-prod.ap-southeast-2.amazonaws.com +emrappui-prod.ap-southeast-3.amazonaws.com +emrnotebooks-prod.ap-southeast-3.amazonaws.com +emrstudio-prod.ap-southeast-3.amazonaws.com +emrappui-prod.ap-southeast-4.amazonaws.com +emrnotebooks-prod.ap-southeast-4.amazonaws.com +emrstudio-prod.ap-southeast-4.amazonaws.com +emrappui-prod.ca-central-1.amazonaws.com +emrnotebooks-prod.ca-central-1.amazonaws.com +emrstudio-prod.ca-central-1.amazonaws.com +emrappui-prod.ca-west-1.amazonaws.com +emrnotebooks-prod.ca-west-1.amazonaws.com +emrstudio-prod.ca-west-1.amazonaws.com +emrappui-prod.eu-central-1.amazonaws.com +emrnotebooks-prod.eu-central-1.amazonaws.com +emrstudio-prod.eu-central-1.amazonaws.com +emrappui-prod.eu-central-2.amazonaws.com +emrnotebooks-prod.eu-central-2.amazonaws.com +emrstudio-prod.eu-central-2.amazonaws.com +emrappui-prod.eu-north-1.amazonaws.com +emrnotebooks-prod.eu-north-1.amazonaws.com +emrstudio-prod.eu-north-1.amazonaws.com +emrappui-prod.eu-south-1.amazonaws.com +emrnotebooks-prod.eu-south-1.amazonaws.com +emrstudio-prod.eu-south-1.amazonaws.com +emrappui-prod.eu-south-2.amazonaws.com +emrnotebooks-prod.eu-south-2.amazonaws.com +emrstudio-prod.eu-south-2.amazonaws.com +emrappui-prod.eu-west-1.amazonaws.com +emrnotebooks-prod.eu-west-1.amazonaws.com +emrstudio-prod.eu-west-1.amazonaws.com +emrappui-prod.eu-west-2.amazonaws.com +emrnotebooks-prod.eu-west-2.amazonaws.com +emrstudio-prod.eu-west-2.amazonaws.com +emrappui-prod.eu-west-3.amazonaws.com +emrnotebooks-prod.eu-west-3.amazonaws.com +emrstudio-prod.eu-west-3.amazonaws.com +emrappui-prod.il-central-1.amazonaws.com +emrnotebooks-prod.il-central-1.amazonaws.com +emrstudio-prod.il-central-1.amazonaws.com +emrappui-prod.me-central-1.amazonaws.com +emrnotebooks-prod.me-central-1.amazonaws.com +emrstudio-prod.me-central-1.amazonaws.com +emrappui-prod.me-south-1.amazonaws.com +emrnotebooks-prod.me-south-1.amazonaws.com +emrstudio-prod.me-south-1.amazonaws.com +emrappui-prod.sa-east-1.amazonaws.com +emrnotebooks-prod.sa-east-1.amazonaws.com +emrstudio-prod.sa-east-1.amazonaws.com +emrappui-prod.us-east-1.amazonaws.com +emrnotebooks-prod.us-east-1.amazonaws.com +emrstudio-prod.us-east-1.amazonaws.com +emrappui-prod.us-east-2.amazonaws.com +emrnotebooks-prod.us-east-2.amazonaws.com +emrstudio-prod.us-east-2.amazonaws.com +emrappui-prod.us-gov-east-1.amazonaws.com +emrnotebooks-prod.us-gov-east-1.amazonaws.com +emrstudio-prod.us-gov-east-1.amazonaws.com +emrappui-prod.us-gov-west-1.amazonaws.com +emrnotebooks-prod.us-gov-west-1.amazonaws.com +emrstudio-prod.us-gov-west-1.amazonaws.com +emrappui-prod.us-west-1.amazonaws.com +emrnotebooks-prod.us-west-1.amazonaws.com +emrstudio-prod.us-west-1.amazonaws.com +emrappui-prod.us-west-2.amazonaws.com +emrnotebooks-prod.us-west-2.amazonaws.com +emrstudio-prod.us-west-2.amazonaws.com + +// Amazon Managed Workflows for Apache Airflow +// Submitted by AWS Security +// Reference: bfd043cc-2816-451d-894e-612c6b61a438 +*.airflow.af-south-1.on.aws +*.airflow.ap-east-1.on.aws +*.airflow.ap-northeast-1.on.aws +*.airflow.ap-northeast-2.on.aws +*.airflow.ap-northeast-3.on.aws +*.airflow.ap-south-1.on.aws +*.airflow.ap-south-2.on.aws +*.airflow.ap-southeast-1.on.aws +*.airflow.ap-southeast-2.on.aws +*.airflow.ap-southeast-3.on.aws +*.airflow.ap-southeast-4.on.aws +*.airflow.ap-southeast-5.on.aws +*.airflow.ca-central-1.on.aws +*.airflow.ca-west-1.on.aws +*.airflow.eu-central-1.on.aws +*.airflow.eu-central-2.on.aws +*.airflow.eu-north-1.on.aws +*.airflow.eu-south-1.on.aws +*.airflow.eu-south-2.on.aws +*.airflow.eu-west-1.on.aws +*.airflow.eu-west-2.on.aws +*.airflow.eu-west-3.on.aws +*.airflow.il-central-1.on.aws +*.airflow.me-central-1.on.aws +*.airflow.me-south-1.on.aws +*.airflow.sa-east-1.on.aws +*.airflow.us-east-1.on.aws +*.airflow.us-east-2.on.aws +*.airflow.us-west-1.on.aws +*.airflow.us-west-2.on.aws +*.cn-north-1.airflow.amazonaws.com.cn +*.cn-northwest-1.airflow.amazonaws.com.cn +*.airflow.cn-north-1.on.amazonwebservices.com.cn +*.airflow.cn-northwest-1.on.amazonwebservices.com.cn +*.af-south-1.airflow.amazonaws.com +*.ap-east-1.airflow.amazonaws.com +*.ap-northeast-1.airflow.amazonaws.com +*.ap-northeast-2.airflow.amazonaws.com +*.ap-northeast-3.airflow.amazonaws.com +*.ap-south-1.airflow.amazonaws.com +*.ap-south-2.airflow.amazonaws.com +*.ap-southeast-1.airflow.amazonaws.com +*.ap-southeast-2.airflow.amazonaws.com +*.ap-southeast-3.airflow.amazonaws.com +*.ap-southeast-4.airflow.amazonaws.com +*.ap-southeast-5.airflow.amazonaws.com +*.ap-southeast-7.airflow.amazonaws.com +*.ca-central-1.airflow.amazonaws.com +*.ca-west-1.airflow.amazonaws.com +*.eu-central-1.airflow.amazonaws.com +*.eu-central-2.airflow.amazonaws.com +*.eu-north-1.airflow.amazonaws.com +*.eu-south-1.airflow.amazonaws.com +*.eu-south-2.airflow.amazonaws.com +*.eu-west-1.airflow.amazonaws.com +*.eu-west-2.airflow.amazonaws.com +*.eu-west-3.airflow.amazonaws.com +*.il-central-1.airflow.amazonaws.com +*.me-central-1.airflow.amazonaws.com +*.me-south-1.airflow.amazonaws.com +*.sa-east-1.airflow.amazonaws.com +*.us-east-1.airflow.amazonaws.com +*.us-east-2.airflow.amazonaws.com +*.us-west-1.airflow.amazonaws.com +*.us-west-2.airflow.amazonaws.com + +// Amazon Relational Database Service +// Submitted by: AWS Security +// Reference: 5aa87906-fd4f-4831-8727-4ffca6094159 +*.rds.cn-north-1.amazonaws.com.cn +*.rds.cn-northwest-1.amazonaws.com.cn +*.af-south-1.rds.amazonaws.com +*.ap-east-1.rds.amazonaws.com +*.ap-east-2.rds.amazonaws.com +*.ap-northeast-1.rds.amazonaws.com +*.ap-northeast-2.rds.amazonaws.com +*.ap-northeast-3.rds.amazonaws.com +*.ap-south-1.rds.amazonaws.com +*.ap-south-2.rds.amazonaws.com +*.ap-southeast-1.rds.amazonaws.com +*.ap-southeast-2.rds.amazonaws.com +*.ap-southeast-3.rds.amazonaws.com +*.ap-southeast-4.rds.amazonaws.com +*.ap-southeast-5.rds.amazonaws.com +*.ap-southeast-6.rds.amazonaws.com +*.ap-southeast-7.rds.amazonaws.com +*.ca-central-1.rds.amazonaws.com +*.ca-west-1.rds.amazonaws.com +*.eu-central-1.rds.amazonaws.com +*.eu-central-2.rds.amazonaws.com +*.eu-west-1.rds.amazonaws.com +*.eu-west-2.rds.amazonaws.com +*.eu-west-3.rds.amazonaws.com +*.il-central-1.rds.amazonaws.com +*.me-central-1.rds.amazonaws.com +*.me-south-1.rds.amazonaws.com +*.mx-central-1.rds.amazonaws.com +*.sa-east-1.rds.amazonaws.com +*.us-east-1.rds.amazonaws.com +*.us-east-2.rds.amazonaws.com +*.us-gov-east-1.rds.amazonaws.com +*.us-gov-west-1.rds.amazonaws.com +*.us-northeast-1.rds.amazonaws.com +*.us-west-1.rds.amazonaws.com +*.us-west-2.rds.amazonaws.com + +// Amazon S3 +// Submitted by AWS Security +// Reference: 6f374c1c-1cc9-47de-8b2a-69ca56a3a3b6 +s3.dualstack.cn-north-1.amazonaws.com.cn +s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn +s3-website.dualstack.cn-north-1.amazonaws.com.cn +s3.cn-north-1.amazonaws.com.cn +s3-accesspoint.cn-north-1.amazonaws.com.cn +s3-deprecated.cn-north-1.amazonaws.com.cn +s3-object-lambda.cn-north-1.amazonaws.com.cn +s3-website.cn-north-1.amazonaws.com.cn +s3.dualstack.cn-northwest-1.amazonaws.com.cn +s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn +s3.cn-northwest-1.amazonaws.com.cn +s3-accesspoint.cn-northwest-1.amazonaws.com.cn +s3-object-lambda.cn-northwest-1.amazonaws.com.cn +s3-website.cn-northwest-1.amazonaws.com.cn +s3.dualstack.af-south-1.amazonaws.com +s3-accesspoint.dualstack.af-south-1.amazonaws.com +s3-website.dualstack.af-south-1.amazonaws.com +s3.af-south-1.amazonaws.com +s3-accesspoint.af-south-1.amazonaws.com +s3-object-lambda.af-south-1.amazonaws.com +s3-website.af-south-1.amazonaws.com +s3.dualstack.ap-east-1.amazonaws.com +s3-accesspoint.dualstack.ap-east-1.amazonaws.com +s3.ap-east-1.amazonaws.com +s3-accesspoint.ap-east-1.amazonaws.com +s3-object-lambda.ap-east-1.amazonaws.com +s3-website.ap-east-1.amazonaws.com +s3.dualstack.ap-northeast-1.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com +s3-website.dualstack.ap-northeast-1.amazonaws.com +s3.ap-northeast-1.amazonaws.com +s3-accesspoint.ap-northeast-1.amazonaws.com +s3-object-lambda.ap-northeast-1.amazonaws.com +s3-website.ap-northeast-1.amazonaws.com +s3.dualstack.ap-northeast-2.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com +s3-website.dualstack.ap-northeast-2.amazonaws.com +s3.ap-northeast-2.amazonaws.com +s3-accesspoint.ap-northeast-2.amazonaws.com +s3-object-lambda.ap-northeast-2.amazonaws.com +s3-website.ap-northeast-2.amazonaws.com +s3.dualstack.ap-northeast-3.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com +s3-website.dualstack.ap-northeast-3.amazonaws.com +s3.ap-northeast-3.amazonaws.com +s3-accesspoint.ap-northeast-3.amazonaws.com +s3-object-lambda.ap-northeast-3.amazonaws.com +s3-website.ap-northeast-3.amazonaws.com +s3.dualstack.ap-south-1.amazonaws.com +s3-accesspoint.dualstack.ap-south-1.amazonaws.com +s3-website.dualstack.ap-south-1.amazonaws.com +s3.ap-south-1.amazonaws.com +s3-accesspoint.ap-south-1.amazonaws.com +s3-object-lambda.ap-south-1.amazonaws.com +s3-website.ap-south-1.amazonaws.com +s3.dualstack.ap-south-2.amazonaws.com +s3-accesspoint.dualstack.ap-south-2.amazonaws.com +s3-website.dualstack.ap-south-2.amazonaws.com +s3.ap-south-2.amazonaws.com +s3-accesspoint.ap-south-2.amazonaws.com +s3-object-lambda.ap-south-2.amazonaws.com +s3-website.ap-south-2.amazonaws.com +s3.dualstack.ap-southeast-1.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com +s3-website.dualstack.ap-southeast-1.amazonaws.com +s3.ap-southeast-1.amazonaws.com +s3-accesspoint.ap-southeast-1.amazonaws.com +s3-object-lambda.ap-southeast-1.amazonaws.com +s3-website.ap-southeast-1.amazonaws.com +s3.dualstack.ap-southeast-2.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com +s3-website.dualstack.ap-southeast-2.amazonaws.com +s3.ap-southeast-2.amazonaws.com +s3-accesspoint.ap-southeast-2.amazonaws.com +s3-object-lambda.ap-southeast-2.amazonaws.com +s3-website.ap-southeast-2.amazonaws.com +s3.dualstack.ap-southeast-3.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com +s3-website.dualstack.ap-southeast-3.amazonaws.com +s3.ap-southeast-3.amazonaws.com +s3-accesspoint.ap-southeast-3.amazonaws.com +s3-object-lambda.ap-southeast-3.amazonaws.com +s3-website.ap-southeast-3.amazonaws.com +s3.dualstack.ap-southeast-4.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com +s3-website.dualstack.ap-southeast-4.amazonaws.com +s3.ap-southeast-4.amazonaws.com +s3-accesspoint.ap-southeast-4.amazonaws.com +s3-object-lambda.ap-southeast-4.amazonaws.com +s3-website.ap-southeast-4.amazonaws.com +s3.dualstack.ap-southeast-5.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-5.amazonaws.com +s3-website.dualstack.ap-southeast-5.amazonaws.com +s3.ap-southeast-5.amazonaws.com +s3-accesspoint.ap-southeast-5.amazonaws.com +s3-deprecated.ap-southeast-5.amazonaws.com +s3-object-lambda.ap-southeast-5.amazonaws.com +s3-website.ap-southeast-5.amazonaws.com +s3.dualstack.ca-central-1.amazonaws.com +s3-accesspoint.dualstack.ca-central-1.amazonaws.com +s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com +s3-fips.dualstack.ca-central-1.amazonaws.com +s3-website.dualstack.ca-central-1.amazonaws.com +s3.ca-central-1.amazonaws.com +s3-accesspoint.ca-central-1.amazonaws.com +s3-accesspoint-fips.ca-central-1.amazonaws.com +s3-fips.ca-central-1.amazonaws.com +s3-object-lambda.ca-central-1.amazonaws.com +s3-website.ca-central-1.amazonaws.com +s3.dualstack.ca-west-1.amazonaws.com +s3-accesspoint.dualstack.ca-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.ca-west-1.amazonaws.com +s3-fips.dualstack.ca-west-1.amazonaws.com +s3-website.dualstack.ca-west-1.amazonaws.com +s3.ca-west-1.amazonaws.com +s3-accesspoint.ca-west-1.amazonaws.com +s3-accesspoint-fips.ca-west-1.amazonaws.com +s3-fips.ca-west-1.amazonaws.com +s3-object-lambda.ca-west-1.amazonaws.com +s3-website.ca-west-1.amazonaws.com +s3.dualstack.eu-central-1.amazonaws.com +s3-accesspoint.dualstack.eu-central-1.amazonaws.com +s3-website.dualstack.eu-central-1.amazonaws.com +s3.eu-central-1.amazonaws.com +s3-accesspoint.eu-central-1.amazonaws.com +s3-object-lambda.eu-central-1.amazonaws.com +s3-website.eu-central-1.amazonaws.com +s3.dualstack.eu-central-2.amazonaws.com +s3-accesspoint.dualstack.eu-central-2.amazonaws.com +s3-website.dualstack.eu-central-2.amazonaws.com +s3.eu-central-2.amazonaws.com +s3-accesspoint.eu-central-2.amazonaws.com +s3-object-lambda.eu-central-2.amazonaws.com +s3-website.eu-central-2.amazonaws.com +s3.dualstack.eu-north-1.amazonaws.com +s3-accesspoint.dualstack.eu-north-1.amazonaws.com +s3.eu-north-1.amazonaws.com +s3-accesspoint.eu-north-1.amazonaws.com +s3-object-lambda.eu-north-1.amazonaws.com +s3-website.eu-north-1.amazonaws.com +s3.dualstack.eu-south-1.amazonaws.com +s3-accesspoint.dualstack.eu-south-1.amazonaws.com +s3-website.dualstack.eu-south-1.amazonaws.com +s3.eu-south-1.amazonaws.com +s3-accesspoint.eu-south-1.amazonaws.com +s3-object-lambda.eu-south-1.amazonaws.com +s3-website.eu-south-1.amazonaws.com +s3.dualstack.eu-south-2.amazonaws.com +s3-accesspoint.dualstack.eu-south-2.amazonaws.com +s3-website.dualstack.eu-south-2.amazonaws.com +s3.eu-south-2.amazonaws.com +s3-accesspoint.eu-south-2.amazonaws.com +s3-object-lambda.eu-south-2.amazonaws.com +s3-website.eu-south-2.amazonaws.com +s3.dualstack.eu-west-1.amazonaws.com +s3-accesspoint.dualstack.eu-west-1.amazonaws.com +s3-website.dualstack.eu-west-1.amazonaws.com +s3.eu-west-1.amazonaws.com +s3-accesspoint.eu-west-1.amazonaws.com +s3-deprecated.eu-west-1.amazonaws.com +s3-object-lambda.eu-west-1.amazonaws.com +s3-website.eu-west-1.amazonaws.com +s3.dualstack.eu-west-2.amazonaws.com +s3-accesspoint.dualstack.eu-west-2.amazonaws.com +s3.eu-west-2.amazonaws.com +s3-accesspoint.eu-west-2.amazonaws.com +s3-object-lambda.eu-west-2.amazonaws.com +s3-website.eu-west-2.amazonaws.com +s3.dualstack.eu-west-3.amazonaws.com +s3-accesspoint.dualstack.eu-west-3.amazonaws.com +s3-website.dualstack.eu-west-3.amazonaws.com +s3.eu-west-3.amazonaws.com +s3-accesspoint.eu-west-3.amazonaws.com +s3-object-lambda.eu-west-3.amazonaws.com +s3-website.eu-west-3.amazonaws.com +s3.dualstack.il-central-1.amazonaws.com +s3-accesspoint.dualstack.il-central-1.amazonaws.com +s3-website.dualstack.il-central-1.amazonaws.com +s3.il-central-1.amazonaws.com +s3-accesspoint.il-central-1.amazonaws.com +s3-object-lambda.il-central-1.amazonaws.com +s3-website.il-central-1.amazonaws.com +s3.dualstack.me-central-1.amazonaws.com +s3-accesspoint.dualstack.me-central-1.amazonaws.com +s3-website.dualstack.me-central-1.amazonaws.com +s3.me-central-1.amazonaws.com +s3-accesspoint.me-central-1.amazonaws.com +s3-object-lambda.me-central-1.amazonaws.com +s3-website.me-central-1.amazonaws.com +s3.dualstack.me-south-1.amazonaws.com +s3-accesspoint.dualstack.me-south-1.amazonaws.com +s3.me-south-1.amazonaws.com +s3-accesspoint.me-south-1.amazonaws.com +s3-object-lambda.me-south-1.amazonaws.com +s3-website.me-south-1.amazonaws.com +s3.amazonaws.com +s3-1.amazonaws.com +s3-ap-east-1.amazonaws.com +s3-ap-northeast-1.amazonaws.com +s3-ap-northeast-2.amazonaws.com +s3-ap-northeast-3.amazonaws.com +s3-ap-south-1.amazonaws.com +s3-ap-southeast-1.amazonaws.com +s3-ap-southeast-2.amazonaws.com +s3-ca-central-1.amazonaws.com +s3-eu-central-1.amazonaws.com +s3-eu-north-1.amazonaws.com +s3-eu-west-1.amazonaws.com +s3-eu-west-2.amazonaws.com +s3-eu-west-3.amazonaws.com +s3-external-1.amazonaws.com +s3-fips-us-gov-east-1.amazonaws.com +s3-fips-us-gov-west-1.amazonaws.com +mrap.accesspoint.s3-global.amazonaws.com +s3-me-south-1.amazonaws.com +s3-sa-east-1.amazonaws.com +s3-us-east-2.amazonaws.com +s3-us-gov-east-1.amazonaws.com +s3-us-gov-west-1.amazonaws.com +s3-us-west-1.amazonaws.com +s3-us-west-2.amazonaws.com +s3-website-ap-northeast-1.amazonaws.com +s3-website-ap-southeast-1.amazonaws.com +s3-website-ap-southeast-2.amazonaws.com +s3-website-eu-west-1.amazonaws.com +s3-website-sa-east-1.amazonaws.com +s3-website-us-east-1.amazonaws.com +s3-website-us-gov-west-1.amazonaws.com +s3-website-us-west-1.amazonaws.com +s3-website-us-west-2.amazonaws.com +s3.dualstack.sa-east-1.amazonaws.com +s3-accesspoint.dualstack.sa-east-1.amazonaws.com +s3-website.dualstack.sa-east-1.amazonaws.com +s3.sa-east-1.amazonaws.com +s3-accesspoint.sa-east-1.amazonaws.com +s3-object-lambda.sa-east-1.amazonaws.com +s3-website.sa-east-1.amazonaws.com +s3.dualstack.us-east-1.amazonaws.com +s3-accesspoint.dualstack.us-east-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com +s3-fips.dualstack.us-east-1.amazonaws.com +s3-website.dualstack.us-east-1.amazonaws.com +s3.us-east-1.amazonaws.com +s3-accesspoint.us-east-1.amazonaws.com +s3-accesspoint-fips.us-east-1.amazonaws.com +s3-deprecated.us-east-1.amazonaws.com +s3-fips.us-east-1.amazonaws.com +s3-object-lambda.us-east-1.amazonaws.com +s3-website.us-east-1.amazonaws.com +s3.dualstack.us-east-2.amazonaws.com +s3-accesspoint.dualstack.us-east-2.amazonaws.com +s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com +s3-fips.dualstack.us-east-2.amazonaws.com +s3-website.dualstack.us-east-2.amazonaws.com +s3.us-east-2.amazonaws.com +s3-accesspoint.us-east-2.amazonaws.com +s3-accesspoint-fips.us-east-2.amazonaws.com +s3-deprecated.us-east-2.amazonaws.com +s3-fips.us-east-2.amazonaws.com +s3-object-lambda.us-east-2.amazonaws.com +s3-website.us-east-2.amazonaws.com +s3.dualstack.us-gov-east-1.amazonaws.com +s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com +s3-fips.dualstack.us-gov-east-1.amazonaws.com +s3-website.dualstack.us-gov-east-1.amazonaws.com +s3.us-gov-east-1.amazonaws.com +s3-accesspoint.us-gov-east-1.amazonaws.com +s3-accesspoint-fips.us-gov-east-1.amazonaws.com +s3-fips.us-gov-east-1.amazonaws.com +s3-object-lambda.us-gov-east-1.amazonaws.com +s3-website.us-gov-east-1.amazonaws.com +s3.dualstack.us-gov-west-1.amazonaws.com +s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com +s3-fips.dualstack.us-gov-west-1.amazonaws.com +s3-website.dualstack.us-gov-west-1.amazonaws.com +s3.us-gov-west-1.amazonaws.com +s3-accesspoint.us-gov-west-1.amazonaws.com +s3-accesspoint-fips.us-gov-west-1.amazonaws.com +s3-fips.us-gov-west-1.amazonaws.com +s3-object-lambda.us-gov-west-1.amazonaws.com +s3-website.us-gov-west-1.amazonaws.com +s3.dualstack.us-west-1.amazonaws.com +s3-accesspoint.dualstack.us-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com +s3-fips.dualstack.us-west-1.amazonaws.com +s3-website.dualstack.us-west-1.amazonaws.com +s3.us-west-1.amazonaws.com +s3-accesspoint.us-west-1.amazonaws.com +s3-accesspoint-fips.us-west-1.amazonaws.com +s3-fips.us-west-1.amazonaws.com +s3-object-lambda.us-west-1.amazonaws.com +s3-website.us-west-1.amazonaws.com +s3.dualstack.us-west-2.amazonaws.com +s3-accesspoint.dualstack.us-west-2.amazonaws.com +s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com +s3-fips.dualstack.us-west-2.amazonaws.com +s3-website.dualstack.us-west-2.amazonaws.com +s3.us-west-2.amazonaws.com +s3-accesspoint.us-west-2.amazonaws.com +s3-accesspoint-fips.us-west-2.amazonaws.com +s3-deprecated.us-west-2.amazonaws.com +s3-fips.us-west-2.amazonaws.com +s3-object-lambda.us-west-2.amazonaws.com +s3-website.us-west-2.amazonaws.com + +// Amazon SageMaker Ground Truth +// Submitted by AWS Security +// Reference: 98dbfde4-7802-48c3-8751-b60f204e0d9c +labeling.ap-northeast-1.sagemaker.aws +labeling.ap-northeast-2.sagemaker.aws +labeling.ap-south-1.sagemaker.aws +labeling.ap-southeast-1.sagemaker.aws +labeling.ap-southeast-2.sagemaker.aws +labeling.ca-central-1.sagemaker.aws +labeling.eu-central-1.sagemaker.aws +labeling.eu-west-1.sagemaker.aws +labeling.eu-west-2.sagemaker.aws +labeling.us-east-1.sagemaker.aws +labeling.us-east-2.sagemaker.aws +labeling.us-west-2.sagemaker.aws + +// Amazon SageMaker Notebook Instances +// Submitted by AWS Security +// Reference: b5ea56df-669e-43cc-9537-14aa172f5dfc +notebook.af-south-1.sagemaker.aws +notebook.ap-east-1.sagemaker.aws +notebook.ap-northeast-1.sagemaker.aws +notebook.ap-northeast-2.sagemaker.aws +notebook.ap-northeast-3.sagemaker.aws +notebook.ap-south-1.sagemaker.aws +notebook.ap-south-2.sagemaker.aws +notebook.ap-southeast-1.sagemaker.aws +notebook.ap-southeast-2.sagemaker.aws +notebook.ap-southeast-3.sagemaker.aws +notebook.ap-southeast-4.sagemaker.aws +notebook.ca-central-1.sagemaker.aws +notebook-fips.ca-central-1.sagemaker.aws +notebook.ca-west-1.sagemaker.aws +notebook-fips.ca-west-1.sagemaker.aws +notebook.eu-central-1.sagemaker.aws +notebook.eu-central-2.sagemaker.aws +notebook.eu-north-1.sagemaker.aws +notebook.eu-south-1.sagemaker.aws +notebook.eu-south-2.sagemaker.aws +notebook.eu-west-1.sagemaker.aws +notebook.eu-west-2.sagemaker.aws +notebook.eu-west-3.sagemaker.aws +notebook.il-central-1.sagemaker.aws +notebook.me-central-1.sagemaker.aws +notebook.me-south-1.sagemaker.aws +notebook.sa-east-1.sagemaker.aws +notebook.us-east-1.sagemaker.aws +notebook-fips.us-east-1.sagemaker.aws +notebook.us-east-2.sagemaker.aws +notebook-fips.us-east-2.sagemaker.aws +notebook.us-gov-east-1.sagemaker.aws +notebook-fips.us-gov-east-1.sagemaker.aws +notebook.us-gov-west-1.sagemaker.aws +notebook-fips.us-gov-west-1.sagemaker.aws +notebook.us-west-1.sagemaker.aws +notebook-fips.us-west-1.sagemaker.aws +notebook.us-west-2.sagemaker.aws +notebook-fips.us-west-2.sagemaker.aws +notebook.cn-north-1.sagemaker.com.cn +notebook.cn-northwest-1.sagemaker.com.cn + +// Amazon SageMaker Studio +// Submitted by AWS Security +// Reference: 475f237e-ab88-4041-9f41-7cfccdf66aeb +studio.af-south-1.sagemaker.aws +studio.ap-east-1.sagemaker.aws +studio.ap-northeast-1.sagemaker.aws +studio.ap-northeast-2.sagemaker.aws +studio.ap-northeast-3.sagemaker.aws +studio.ap-south-1.sagemaker.aws +studio.ap-southeast-1.sagemaker.aws +studio.ap-southeast-2.sagemaker.aws +studio.ap-southeast-3.sagemaker.aws +studio.ca-central-1.sagemaker.aws +studio.eu-central-1.sagemaker.aws +studio.eu-central-2.sagemaker.aws +studio.eu-north-1.sagemaker.aws +studio.eu-south-1.sagemaker.aws +studio.eu-south-2.sagemaker.aws +studio.eu-west-1.sagemaker.aws +studio.eu-west-2.sagemaker.aws +studio.eu-west-3.sagemaker.aws +studio.il-central-1.sagemaker.aws +studio.me-central-1.sagemaker.aws +studio.me-south-1.sagemaker.aws +studio.sa-east-1.sagemaker.aws +studio.us-east-1.sagemaker.aws +studio.us-east-2.sagemaker.aws +studio.us-gov-east-1.sagemaker.aws +studio-fips.us-gov-east-1.sagemaker.aws +studio.us-gov-west-1.sagemaker.aws +studio-fips.us-gov-west-1.sagemaker.aws +studio.us-west-1.sagemaker.aws +studio.us-west-2.sagemaker.aws +studio.cn-north-1.sagemaker.com.cn +studio.cn-northwest-1.sagemaker.com.cn + +// Amazon SageMaker with MLflow +// Submited by: AWS Security +// Reference: c19f92b3-a82a-452d-8189-831b572eea7e +*.experiments.sagemaker.aws + +// Analytics on AWS +// Submitted by AWS Security +// Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd +analytics-gateway.ap-northeast-1.amazonaws.com +analytics-gateway.ap-northeast-2.amazonaws.com +analytics-gateway.ap-south-1.amazonaws.com +analytics-gateway.ap-southeast-1.amazonaws.com +analytics-gateway.ap-southeast-2.amazonaws.com +analytics-gateway.eu-central-1.amazonaws.com +analytics-gateway.eu-west-1.amazonaws.com +analytics-gateway.us-east-1.amazonaws.com +analytics-gateway.us-east-2.amazonaws.com +analytics-gateway.us-west-2.amazonaws.com + +// AWS Amplify +// Submitted by AWS Security +// Reference: c35bed18-6f4f-424f-9298-5756f2f7d72b +amplifyapp.com + +// AWS App Runner +// Submitted by AWS Security +// Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316 +*.awsapprunner.com + +// AWS Cloud9 +// Submitted by: AWS Security +// Reference: 30717f72-4007-4f0f-8ed4-864c6f2efec9 +webview-assets.aws-cloud9.af-south-1.amazonaws.com +vfs.cloud9.af-south-1.amazonaws.com +webview-assets.cloud9.af-south-1.amazonaws.com +webview-assets.aws-cloud9.ap-east-1.amazonaws.com +vfs.cloud9.ap-east-1.amazonaws.com +webview-assets.cloud9.ap-east-1.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com +vfs.cloud9.ap-northeast-1.amazonaws.com +webview-assets.cloud9.ap-northeast-1.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com +vfs.cloud9.ap-northeast-2.amazonaws.com +webview-assets.cloud9.ap-northeast-2.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com +vfs.cloud9.ap-northeast-3.amazonaws.com +webview-assets.cloud9.ap-northeast-3.amazonaws.com +webview-assets.aws-cloud9.ap-south-1.amazonaws.com +vfs.cloud9.ap-south-1.amazonaws.com +webview-assets.cloud9.ap-south-1.amazonaws.com +webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com +vfs.cloud9.ap-southeast-1.amazonaws.com +webview-assets.cloud9.ap-southeast-1.amazonaws.com +webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com +vfs.cloud9.ap-southeast-2.amazonaws.com +webview-assets.cloud9.ap-southeast-2.amazonaws.com +webview-assets.aws-cloud9.ca-central-1.amazonaws.com +vfs.cloud9.ca-central-1.amazonaws.com +webview-assets.cloud9.ca-central-1.amazonaws.com +webview-assets.aws-cloud9.eu-central-1.amazonaws.com +vfs.cloud9.eu-central-1.amazonaws.com +webview-assets.cloud9.eu-central-1.amazonaws.com +webview-assets.aws-cloud9.eu-north-1.amazonaws.com +vfs.cloud9.eu-north-1.amazonaws.com +webview-assets.cloud9.eu-north-1.amazonaws.com +webview-assets.aws-cloud9.eu-south-1.amazonaws.com +vfs.cloud9.eu-south-1.amazonaws.com +webview-assets.cloud9.eu-south-1.amazonaws.com +webview-assets.aws-cloud9.eu-west-1.amazonaws.com +vfs.cloud9.eu-west-1.amazonaws.com +webview-assets.cloud9.eu-west-1.amazonaws.com +webview-assets.aws-cloud9.eu-west-2.amazonaws.com +vfs.cloud9.eu-west-2.amazonaws.com +webview-assets.cloud9.eu-west-2.amazonaws.com +webview-assets.aws-cloud9.eu-west-3.amazonaws.com +vfs.cloud9.eu-west-3.amazonaws.com +webview-assets.cloud9.eu-west-3.amazonaws.com +webview-assets.aws-cloud9.il-central-1.amazonaws.com +vfs.cloud9.il-central-1.amazonaws.com +webview-assets.aws-cloud9.me-south-1.amazonaws.com +vfs.cloud9.me-south-1.amazonaws.com +webview-assets.cloud9.me-south-1.amazonaws.com +webview-assets.aws-cloud9.sa-east-1.amazonaws.com +vfs.cloud9.sa-east-1.amazonaws.com +webview-assets.cloud9.sa-east-1.amazonaws.com +webview-assets.aws-cloud9.us-east-1.amazonaws.com +vfs.cloud9.us-east-1.amazonaws.com +webview-assets.cloud9.us-east-1.amazonaws.com +webview-assets.aws-cloud9.us-east-2.amazonaws.com +vfs.cloud9.us-east-2.amazonaws.com +webview-assets.cloud9.us-east-2.amazonaws.com +webview-assets.aws-cloud9.us-west-1.amazonaws.com +vfs.cloud9.us-west-1.amazonaws.com +webview-assets.cloud9.us-west-1.amazonaws.com +webview-assets.aws-cloud9.us-west-2.amazonaws.com +vfs.cloud9.us-west-2.amazonaws.com +webview-assets.cloud9.us-west-2.amazonaws.com + +// AWS Directory Service +// Submitted by AWS Security +// Reference: a13203e8-42dc-4045-a0d2-2ee67bed1068 +awsapps.com + +// AWS Elastic Beanstalk +// Submitted by AWS Security +// Reference: e4e02a54-eaf9-4fe7-b662-39ccbc011a04 +cn-north-1.eb.amazonaws.com.cn +cn-northwest-1.eb.amazonaws.com.cn +elasticbeanstalk.com +af-south-1.elasticbeanstalk.com +ap-east-1.elasticbeanstalk.com +ap-northeast-1.elasticbeanstalk.com +ap-northeast-2.elasticbeanstalk.com +ap-northeast-3.elasticbeanstalk.com +ap-south-1.elasticbeanstalk.com +ap-southeast-1.elasticbeanstalk.com +ap-southeast-2.elasticbeanstalk.com +ap-southeast-3.elasticbeanstalk.com +ap-southeast-5.elasticbeanstalk.com +ap-southeast-7.elasticbeanstalk.com +ca-central-1.elasticbeanstalk.com +eu-central-1.elasticbeanstalk.com +eu-north-1.elasticbeanstalk.com +eu-south-1.elasticbeanstalk.com +eu-south-2.elasticbeanstalk.com +eu-west-1.elasticbeanstalk.com +eu-west-2.elasticbeanstalk.com +eu-west-3.elasticbeanstalk.com +il-central-1.elasticbeanstalk.com +me-central-1.elasticbeanstalk.com +me-south-1.elasticbeanstalk.com +sa-east-1.elasticbeanstalk.com +us-east-1.elasticbeanstalk.com +us-east-2.elasticbeanstalk.com +us-gov-east-1.elasticbeanstalk.com +us-gov-west-1.elasticbeanstalk.com +us-west-1.elasticbeanstalk.com +us-west-2.elasticbeanstalk.com + +// (AWS) Elastic Load Balancing +// Submitted by Luke Wells +// Reference: 12a3d528-1bac-4433-a359-a395867ffed2 +*.elb.amazonaws.com.cn +*.elb.amazonaws.com + +// AWS Global Accelerator +// Submitted by Daniel Massaguer +// Reference: d916759d-a08b-4241-b536-4db887383a6a +awsglobalaccelerator.com + +// AWS Lambda Function URLs +// Submitted by AWS Security +// Reference: 57df74ca-0820-46a5-89ea-0f0d0c4714b7 +lambda-url.af-south-1.on.aws +lambda-url.ap-east-1.on.aws +lambda-url.ap-northeast-1.on.aws +lambda-url.ap-northeast-2.on.aws +lambda-url.ap-northeast-3.on.aws +lambda-url.ap-south-1.on.aws +lambda-url.ap-southeast-1.on.aws +lambda-url.ap-southeast-2.on.aws +lambda-url.ap-southeast-3.on.aws +lambda-url.ca-central-1.on.aws +lambda-url.eu-central-1.on.aws +lambda-url.eu-north-1.on.aws +lambda-url.eu-south-1.on.aws +lambda-url.eu-west-1.on.aws +lambda-url.eu-west-2.on.aws +lambda-url.eu-west-3.on.aws +lambda-url.me-south-1.on.aws +lambda-url.sa-east-1.on.aws +lambda-url.us-east-1.on.aws +lambda-url.us-east-2.on.aws +lambda-url.us-west-1.on.aws +lambda-url.us-west-2.on.aws + +// AWS re:Post Private +// Submitted by AWS Security +// Reference: 83385945-225f-416e-9aa0-ad0632bfdcee +*.private.repost.aws + +// AWS Transfer Family web apps +// Submitted by AWS Security +// Reference: 9265cdd3-f017-42ab-98bb-08bf427d3fc9 +transfer-webapp.af-south-1.on.aws +transfer-webapp.ap-east-1.on.aws +transfer-webapp.ap-northeast-1.on.aws +transfer-webapp.ap-northeast-2.on.aws +transfer-webapp.ap-northeast-3.on.aws +transfer-webapp.ap-south-1.on.aws +transfer-webapp.ap-south-2.on.aws +transfer-webapp.ap-southeast-1.on.aws +transfer-webapp.ap-southeast-2.on.aws +transfer-webapp.ap-southeast-3.on.aws +transfer-webapp.ap-southeast-4.on.aws +transfer-webapp.ap-southeast-5.on.aws +transfer-webapp.ap-southeast-7.on.aws +transfer-webapp.ca-central-1.on.aws +transfer-webapp.ca-west-1.on.aws +transfer-webapp.eu-central-1.on.aws +transfer-webapp.eu-central-2.on.aws +transfer-webapp.eu-north-1.on.aws +transfer-webapp.eu-south-1.on.aws +transfer-webapp.eu-south-2.on.aws +transfer-webapp.eu-west-1.on.aws +transfer-webapp.eu-west-2.on.aws +transfer-webapp.eu-west-3.on.aws +transfer-webapp.il-central-1.on.aws +transfer-webapp.me-central-1.on.aws +transfer-webapp.me-south-1.on.aws +transfer-webapp.mx-central-1.on.aws +transfer-webapp.sa-east-1.on.aws +transfer-webapp.us-east-1.on.aws +transfer-webapp.us-east-2.on.aws +transfer-webapp.us-gov-east-1.on.aws +transfer-webapp-fips.us-gov-east-1.on.aws +transfer-webapp.us-gov-west-1.on.aws +transfer-webapp-fips.us-gov-west-1.on.aws +transfer-webapp.us-west-1.on.aws +transfer-webapp.us-west-2.on.aws +transfer-webapp.cn-north-1.on.amazonwebservices.com.cn +transfer-webapp.cn-northwest-1.on.amazonwebservices.com.cn + +// eero +// Submitted by Yue Kang +// Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 +eero.online +eero-stage.online + +// concludes Amazon + +// Antagonist B.V. : https://www.antagonist.nl/ +// Submitted by Sander Hoentjen +antagonist.cloud + +// Apigee : https://apigee.com/ +// Submitted by Apigee Security Team +apigee.io + +// Apis Networks : https://apisnetworks.com +// Submitted by Matt Saladna +panel.dev + +// Apphud : https://apphud.com +// Submitted by Alexander Selivanov +siiites.com + +// Apple : https://www.apple.com +// Submitted by Apple DNS +int.apple +*.cloud.int.apple +*.r.cloud.int.apple +*.ap-north-1.r.cloud.int.apple +*.ap-south-1.r.cloud.int.apple +*.ap-south-2.r.cloud.int.apple +*.eu-central-1.r.cloud.int.apple +*.eu-north-1.r.cloud.int.apple +*.us-central-1.r.cloud.int.apple +*.us-central-2.r.cloud.int.apple +*.us-east-1.r.cloud.int.apple +*.us-east-2.r.cloud.int.apple +*.us-west-1.r.cloud.int.apple +*.us-west-2.r.cloud.int.apple +*.us-west-3.r.cloud.int.apple + +// Appspace : https://www.appspace.com +// Submitted by Appspace Security Team +appspacehosted.com +appspaceusercontent.com + +// Appudo UG (haftungsbeschränkt) : https://www.appudo.com +// Submitted by Alexander Hochbaum +appudo.net + +// Appwrite : https://appwrite.io +// Submitted by Steven Nguyen +appwrite.global +appwrite.network +*.appwrite.run + +// Aptible : https://www.aptible.com/ +// Submitted by Thomas Orozco +on-aptible.com + +// Aquapal : https://aquapal.net/ +// Submitted by Aki Ueno +f5.si + +// ArvanCloud EdgeCompute +// Submitted by ArvanCloud CDN +arvanedge.ir + +// ASEINet : https://www.aseinet.com/ +// Submitted by Asei SEKIGUCHI +user.aseinet.ne.jp +gv.vc +d.gv.vc + +// Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/ +// Submitted by Hector Martin +user.party.eus + +// Association potager.org : https://potager.org/ +// Submitted by Lunar +pimienta.org +poivron.org +potager.org +sweetpepper.org + +// ASUSTOR Inc. : http://www.asustor.com +// Submitted by Vincent Tseng +myasustor.com + +// Atlassian : https://atlassian.com +// Submitted by Sam Smyth +cdn.prod.atlassian-dev.net + +// AVM : https://avm.de +// Submitted by Andreas Weise +myfritz.link +myfritz.net + +// AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com +// Submitted by James Kennedy +*.awdev.ca +*.advisor.ws + +// AZ.pl sp. z.o.o : https://az.pl +// Submitted by Krzysztof Wolski +ecommerce-shop.pl + +// b-data GmbH : https://www.b-data.io +// Submitted by Olivier Benz +b-data.io + +// Balena : https://www.balena.io +// Submitted by Petros Angelatos +balena-devices.com + +// BASE, Inc. : https://binc.jp +// Submitted by Yuya NAGASAWA +base.ec +official.ec +buyshop.jp +fashionstore.jp +handcrafted.jp +kawaiishop.jp +supersale.jp +theshop.jp +shopselect.net +base.shop + +// BeagleBoard.org Foundation : https://beagleboard.org +// Submitted by Jason Kridner +beagleboard.io + +// Bear Blog : https://bearblog.dev +// Submitted by Herman Martinus +bearblog.dev + +// Beget LLC : https://beget.com +// Submitted by Lev Nekrasov & Nikita Radchenko +*.beget.app +*.begetcdn.cloud + +// Besties : https://besties.house +// Submitted by Hazel Cora +pages.gay + +// BinaryLane : http://www.binarylane.com +// Submitted by Nathan O'Sullivan +bnr.la + +// Bitbucket : http://bitbucket.org +// Submitted by Andy Ortlieb +bitbucket.io + +// Blackbaud, Inc. : https://www.blackbaud.com +// Submitted by Paul Crowder +blackbaudcdn.net + +// Blatech : http://www.blatech.net +// Submitted by Luke Bratch +of.je + +// Block, Inc. : https://block.xyz +// Submitted by Jonathan Boice +square.site + +// Blue Bite, LLC : https://bluebite.com +// Submitted by Joshua Weiss +bluebite.io + +// Boomla : https://boomla.com +// Submitted by Tibor Halter +boomla.net + +// Boutir : https://www.boutir.com +// Submitted by Eric Ng Ka Ka +boutir.com + +// Boxfuse : https://boxfuse.com +// Submitted by Axel Fontaine +boxfuse.io + +// bplaced : https://www.bplaced.net/ +// Submitted by Miroslav Bozic +square7.ch +bplaced.com +bplaced.de +square7.de +bplaced.net +square7.net + +// Brave : https://brave.com +// Submitted by Andrea Brancaleoni +brave.app +*.s.brave.app +brave.dev +*.s.brave.dev +brave.io +*.s.brave.io + +// Brendly : https://brendly.rs +// Submitted by Dusan Radovanovic +shop.brendly.ba +shop.brendly.hr +shop.brendly.rs + +// BrowserSafetyMark +// Submitted by Dave Tharp +browsersafetymark.io + +// BRS Media : https://brsmedia.com/ +// Submitted by Gavin Brown +radio.am +radio.fm + +// Bubble : https://bubble.io/ +// Submitted by Merlin Zhao +cdn.bubble.io +bubbleapps.io + +// bwCloud-OS : https://bwcloud-os.de/ +// Submitted by Klara Mall +*.bwcloud-os-instance.de + +// Bytemark Hosting : https://www.bytemark.co.uk +// Submitted by Paul Cammish +uk0.bigv.io +dh.bytemark.co.uk +vm.bytemark.co.uk + +// Caf.js Labs LLC : https://www.cafjs.com +// Submitted by Antonio Lain +cafjs.com + +// Canva Pty Ltd : https://canva.com/ +// Submitted by Joel Aquilina +canva-apps.cn +my.canvasite.cn +canva-apps.com +canva-hosted-embed.com +canvacode.com +rice-labs.com +canva.run +my.canva.site + +// Carrd : https://carrd.co +// Submitted by AJ +drr.ac +uwu.ai +carrd.co +crd.co +ju.mp + +// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk +// Submitted by Jamie Tanna +api.gov.uk + +// CDN77.com : http://www.cdn77.com +// Submitted by Jan Krpes +cdn77-storage.com +rsc.contentproxy9.cz +r.cdn77.net +cdn77-ssl.net +c.cdn77.org +rsc.cdn77.org +ssl.origin.cdn77-secure.org + +// CentralNic : https://teaminternet.com/ +// Submitted by registry +za.bz +br.com +cn.com +de.com +eu.com +jpn.com +mex.com +ru.com +sa.com +uk.com +us.com +za.com +com.de +gb.net +hu.net +jp.net +se.net +uk.net +ae.org +com.se + +// Cityhost LLC : https://cityhost.ua +// Submitted by Maksym Rivtin +cx.ua + +// Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/ +// Submitted by Rishabh Nambiar, Michael Brown, Rafael dos Santos Silva +discourse.diy +discourse.group +discourse.team + +// Clerk : https://www.clerk.dev +// Submitted by Colin Sidoti +clerk.app +clerkstage.app +*.lcl.dev +*.lclstage.dev +*.stg.dev +*.stgstage.dev + +// Clever Cloud : https://www.clever-cloud.com/ +// Submitted by Quentin Adam +cleverapps.cc +*.services.clever-cloud.com +cleverapps.io +cleverapps.tech + +// ClickRising : https://clickrising.com/ +// Submitted by Umut Gumeli +clickrising.net + +// Cloud DNS Ltd : http://www.cloudns.net +// Submitted by Aleksander Hristov & Boyan Peychev +cloudns.asia +cloudns.be +cloud-ip.biz +cloudns.biz +cloud-ip.cc +cloudns.cc +cloudns.ch +cloudns.cl +cloudns.club +abrdns.com +dnsabr.com +ip-ddns.com +cloudns.cx +cloudns.eu +cloudns.in +cloudns.info +ddns-ip.net +dns-cloud.net +dns-dynamic.net +cloudns.nz +cloudns.org +ip-dynamic.org +cloudns.ph +cloudns.pro +cloudns.pw +cloudns.us + +// Cloud66 : https://www.cloud66.com/ +// Submitted by Khash Sajadi +c66.me +cloud66.ws + +// CloudAccess.net : https://www.cloudaccess.net/ +// Submitted by Pawel Panek +jdevcloud.com +wpdevcloud.com +cloudaccess.host +freesite.host +cloudaccess.net + +// Cloudbees, Inc. : https://www.cloudbees.com/ +// Submitted by Mohideen Shajith +cloudbeesusercontent.io + +// Cloudera, Inc. : https://www.cloudera.com/ +// Submitted by Kedarnath Waikar +*.cloudera.site + +// Cloudflare, Inc. : https://www.cloudflare.com/ +// Submitted by Cloudflare Team +cloudflare.app +cf-ipfs.com +cloudflare-ipfs.com +trycloudflare.com +pages.dev +r2.dev +workers.dev +cloudflare.net +cdn.cloudflare.net +cdn.cloudflareanycast.net +cdn.cloudflarecn.net +cdn.cloudflareglobal.net + +// cloudscale.ch AG : https://www.cloudscale.ch/ +// Submitted by Gaudenz Steinlin +cust.cloudscale.ch +objects.lpg.cloudscale.ch +objects.rma.cloudscale.ch +lpg.objectstorage.ch +rma.objectstorage.ch + +// Clovyr : https://clovyr.io +// Submitted by Patrick Nielsen +wnext.app + +// CNPY : https://cnpy.gdn +// Submitted by Angelo Gladding +cnpy.gdn + +// Co & Co : https://co-co.nl/ +// Submitted by Govert Versluis +*.otap.co + +// co.ca : http://registry.co.ca/ +co.ca + +// co.com Registry, LLC : https://registry.co.com +// Submitted by Gavin Brown +co.com + +// Codeberg e. V. : https://codeberg.org +// Submitted by Moritz Marquardt +codeberg.page + +// CodeSandbox B.V. : https://codesandbox.io +// Submitted by Ives van Hoorne +csb.app +preview.csb.app + +// CoDNS B.V. +co.nl +co.no + +// Cognition AI, Inc. : https://cognition.ai +// Submitted by Philip Papurt +*.devinapps.com + +// Combell.com : https://www.combell.com +// Submitted by Combell Team +webhosting.be +prvw.eu +hosting-cluster.nl + +// Contentful GmbH : https://www.contentful.com +// Submitted by Contentful Developer Experience Team +ctfcloud.net + +// Convex : https://convex.dev/ +// Submitted by James Cowling +convex.app +convex.cloud +eu-west-1.convex.cloud +us-east-1.convex.cloud +convex.site +eu-west-1.convex.site +us-east-1.convex.site + +// Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/ +// Submitted by George Georgievsky +ac.ru +edu.ru +gov.ru +int.ru +mil.ru + +// CoreSpeed, Inc. : https://corespeed.io +// Submitted by CoreSpeed Team +corespeed.app + +// COSIMO GmbH : http://www.cosimo.de +// Submitted by Rene Marticke +dyn.cosidns.de +dnsupdater.de +dynamisches-dns.de +internet-dns.de +l-o-g-i-n.de +dynamic-dns.info +feste-ip.net +knx-server.net +static-access.net + +// Craft Docs Ltd : https://www.craft.do/ +// Submitted by Zsombor Fuszenecker +craft.me + +// Craynic, s.r.o. : http://www.craynic.com/ +// Submitted by Ales Krajnik +realm.cz + +// Crisp IM SAS : https://crisp.chat/ +// Submitted by Baptiste Jamin +on.crisp.email + +// Cryptonomic : https://cryptonomic.net/ +// Submitted by Andrew Cady +*.cryptonomic.net + +// cyber_Folks S.A. : https://cyberfolks.pl +// Submitted by Bartlomiej Kida +cfolks.pl + +// cyon GmbH : https://www.cyon.ch/ +// Submitted by Dominic Luechinger +cyon.link +cyon.site + +// Dansk.net : http://www.dansk.net/ +// Submitted by Anani Voule +biz.dk +co.dk +firm.dk +reg.dk +store.dk + +// dappnode.io : https://dappnode.io/ +// Submitted by Abel Boldu / DAppNode Team +dyndns.dappnode.io + +// Dark, Inc. : https://darklang.com +// Submitted by Paul Biggar +builtwithdark.com +darklang.io + +// DataDetect, LLC. : https://datadetect.com +// Submitted by Andrew Banchich +demo.datadetect.com +instance.datadetect.com + +// Datawire, Inc : https://www.datawire.io +// Submitted by Richard Li +edgestack.me + +// Datto, Inc. : https://www.datto.com/ +// Submitted by Philipp Heckel +dattolocal.com +dattorelay.com +dattoweb.com +mydatto.com +dattolocal.net +mydatto.net + +// ddnss.de : https://www.ddnss.de/ +// Submitted by Robert Niedziela +ddnss.de +dyn.ddnss.de +dyndns.ddnss.de +dyn-ip24.de +dyndns1.de +home-webserver.de +dyn.home-webserver.de +myhome-server.de +ddnss.org + +// Debian : https://www.debian.org/ +// Submitted by Peter Palfrader / Debian Sysadmin Team +debian.net + +// Definima : http://www.definima.com/ +// Submitted by Maxence Bitterli +definima.io +definima.net + +// Deno Land Inc : https://deno.com/ +// Submitted by Luca Casonato +deno.dev +deno-staging.dev +deno.net +sandbox.deno.net + +// deSEC : https://desec.io/ +// Submitted by Peter Thomassen +dedyn.io + +// Deta : https://www.deta.sh/ +// Submitted by Aavash Shrestha +deta.app +deta.dev + +// Deuxfleurs : https://deuxfleurs.fr +// Submitted by Aeddis Desauw +deuxfleurs.eu +deuxfleurs.page + +// Developed Methods LLC : https://methods.dev +// Submitted by Patrick Lorio +*.at.ply.gg +d6.ply.gg +joinmc.link +playit.plus +*.at.playit.plus +with.playit.plus + +// Dfinity Foundation: https://dfinity.org/ +// Submitted by Dfinity Team +icp0.io +*.raw.icp0.io +icp1.io +*.raw.icp1.io +*.icp.net +caffeine.site +caffeine.xyz + +// dhosting.pl Sp. z o.o. : https://dhosting.pl/ +// Submitted by Szczepan Redzioch +mybox.company +intouch.email +mybox.me +mybox.page +dfirma.pl +dkonto.pl +you2.pl + +// DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ +// Submitted by Braxton Huggins +ondigitalocean.app + +// DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ +// Submitted by Robin H. Johnson +*.digitaloceanspaces.com + +// DigitalPlat : https://www.digitalplat.org/ +// Submitted by Edward Hsing +qzz.io +us.kg +xx.kg +dpdns.org + +// Discord Inc : https://discord.com +// Submitted by Sahn Lam +discordsays.com +discordsez.com + +// DNS Africa Ltd : https://dns.business +// Submitted by Calvin Browne +jozi.biz + +// DNSHE : https://www.dnshe.com +// Submitted by DNSHE Team +ccwu.cc +cc.cd +us.ci +de5.net + +// DNShome : https://www.dnshome.de/ +// Submitted by Norbert Auler +dnshome.de + +// DotArai : https://www.dotarai.com/ +// Submitted by Atsadawat Netcharadsang +online.th +shop.th + +// dotScot Domains : https://domains.scot/ +// Submitted by DNS Team +co.scot +me.scot +org.scot + +// DrayTek Corp. : https://www.draytek.com/ +// Submitted by Paul Fang +drayddns.com + +// DreamCommerce : https://shoper.pl/ +// Submitted by Konrad Kotarba +shoparena.pl + +// DreamHost : http://www.dreamhost.com/ +// Submitted by Andrew Farmer +dreamhosters.com + +// Dreamyoungs, Inc. : https://durumis.com +// Submitted by Infra Team +durumis.com + +// DuckDNS : http://www.duckdns.org/ +// Submitted by Richard Harper +duckdns.org + +// dy.fi : http://dy.fi/ +// Submitted by Heikki Hannikainen +dy.fi +tunk.org + +// DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ +dyndns.biz +for-better.biz +for-more.biz +for-some.biz +for-the.biz +selfip.biz +webhop.biz +ftpaccess.cc +game-server.cc +myphotos.cc +scrapping.cc +blogdns.com +cechire.com +dnsalias.com +dnsdojo.com +doesntexist.com +dontexist.com +doomdns.com +dyn-o-saur.com +dynalias.com +dyndns-at-home.com +dyndns-at-work.com +dyndns-blog.com +dyndns-free.com +dyndns-home.com +dyndns-ip.com +dyndns-mail.com +dyndns-office.com +dyndns-pics.com +dyndns-remote.com +dyndns-server.com +dyndns-web.com +dyndns-wiki.com +dyndns-work.com +est-a-la-maison.com +est-a-la-masion.com +est-le-patron.com +est-mon-blogueur.com +from-ak.com +from-al.com +from-ar.com +from-ca.com +from-ct.com +from-dc.com +from-de.com +from-fl.com +from-ga.com +from-hi.com +from-ia.com +from-id.com +from-il.com +from-in.com +from-ks.com +from-ky.com +from-ma.com +from-md.com +from-mi.com +from-mn.com +from-mo.com +from-ms.com +from-mt.com +from-nc.com +from-nd.com +from-ne.com +from-nh.com +from-nj.com +from-nm.com +from-nv.com +from-oh.com +from-ok.com +from-or.com +from-pa.com +from-pr.com +from-ri.com +from-sc.com +from-sd.com +from-tn.com +from-tx.com +from-ut.com +from-va.com +from-vt.com +from-wa.com +from-wi.com +from-wv.com +from-wy.com +getmyip.com +gotdns.com +hobby-site.com +homelinux.com +homeunix.com +iamallama.com +is-a-anarchist.com +is-a-blogger.com +is-a-bookkeeper.com +is-a-bulls-fan.com +is-a-caterer.com +is-a-chef.com +is-a-conservative.com +is-a-cpa.com +is-a-cubicle-slave.com +is-a-democrat.com +is-a-designer.com +is-a-doctor.com +is-a-financialadvisor.com +is-a-geek.com +is-a-green.com +is-a-guru.com +is-a-hard-worker.com +is-a-hunter.com +is-a-landscaper.com +is-a-lawyer.com +is-a-liberal.com +is-a-libertarian.com +is-a-llama.com +is-a-musician.com +is-a-nascarfan.com +is-a-nurse.com +is-a-painter.com +is-a-personaltrainer.com +is-a-photographer.com +is-a-player.com +is-a-republican.com +is-a-rockstar.com +is-a-socialist.com +is-a-student.com +is-a-teacher.com +is-a-techie.com +is-a-therapist.com +is-an-accountant.com +is-an-actor.com +is-an-actress.com +is-an-anarchist.com +is-an-artist.com +is-an-engineer.com +is-an-entertainer.com +is-certified.com +is-gone.com +is-into-anime.com +is-into-cars.com +is-into-cartoons.com +is-into-games.com +is-leet.com +is-not-certified.com +is-slick.com +is-uberleet.com +is-with-theband.com +isa-geek.com +isa-hockeynut.com +issmarterthanyou.com +likes-pie.com +likescandy.com +neat-url.com +saves-the-whales.com +selfip.com +sells-for-less.com +sells-for-u.com +servebbs.com +simple-url.com +space-to-rent.com +teaches-yoga.com +writesthisblog.com +ath.cx +fuettertdasnetz.de +isteingeek.de +istmein.de +lebtimnetz.de +leitungsen.de +traeumtgerade.de +barrel-of-knowledge.info +barrell-of-knowledge.info +dyndns.info +for-our.info +groks-the.info +groks-this.info +here-for-more.info +knowsitall.info +selfip.info +webhop.info +forgot.her.name +forgot.his.name +at-band-camp.net +blogdns.net +broke-it.net +buyshouses.net +dnsalias.net +dnsdojo.net +does-it.net +dontexist.net +dynalias.net +dynathome.net +endofinternet.net +from-az.net +from-co.net +from-la.net +from-ny.net +gets-it.net +ham-radio-op.net +homeftp.net +homeip.net +homelinux.net +homeunix.net +in-the-band.net +is-a-chef.net +is-a-geek.net +isa-geek.net +kicks-ass.net +office-on-the.net +podzone.net +scrapper-site.net +selfip.net +sells-it.net +servebbs.net +serveftp.net +thruhere.net +webhop.net +merseine.nu +mine.nu +shacknet.nu +blogdns.org +blogsite.org +boldlygoingnowhere.org +dnsalias.org +dnsdojo.org +doesntexist.org +dontexist.org +doomdns.org +dvrdns.org +dynalias.org +dyndns.org +go.dyndns.org +home.dyndns.org +endofinternet.org +endoftheinternet.org +from-me.org +game-host.org +gotdns.org +hobby-site.org +homedns.org +homeftp.org +homelinux.org +homeunix.org +is-a-bruinsfan.org +is-a-candidate.org +is-a-celticsfan.org +is-a-chef.org +is-a-geek.org +is-a-knight.org +is-a-linux-user.org +is-a-patsfan.org +is-a-soxfan.org +is-found.org +is-lost.org +is-saved.org +is-very-bad.org +is-very-evil.org +is-very-good.org +is-very-nice.org +is-very-sweet.org +isa-geek.org +kicks-ass.org +misconfused.org +podzone.org +readmyblog.org +selfip.org +sellsyourhome.org +servebbs.org +serveftp.org +servegame.org +stuff-4-sale.org +webhop.org +better-than.tv +dyndns.tv +on-the-web.tv +worse-than.tv +is-by.us +land-4-sale.us +stuff-4-sale.us +dyndns.ws +mypets.ws + +// Dynu.com : https://www.dynu.com/ +// Submitted by Sue Ye +1cooldns.com +bumbleshrimp.com +ddnsfree.com +ddnsgeek.com +ddnsguru.com +dynuddns.com +dynuhosting.com +giize.com +gleeze.com +kozow.com +loseyourip.com +ooguy.com +pivohosting.com +theworkpc.com +wiredbladehosting.com +casacam.net +dynu.net +dynuddns.net +mysynology.net +opik.net +spryt.net +accesscam.org +camdvr.org +freeddns.org +mywire.org +roxa.org +webredirect.org +myddns.rocks + +// dynv6 : https://dynv6.com +// Submitted by Dominik Menke +dynv6.net + +// E4YOU spol. s.r.o. : https://e4you.cz/ +// Submitted by Vladimir Dudr +e4.cz + +// Easypanel : https://easypanel.io +// Submitted by Andrei Canta +easypanel.app +easypanel.host + +// EasyWP : https://www.easywp.com +// Submitted by +*.ewp.live + +// eDirect Corp. : https://hosting.url.com.tw/ +// Submitted by C.S. chang +twmail.cc +twmail.net +twmail.org +mymailer.com.tw +url.tw + +// Electromagnetic Field : https://www.emfcamp.org +// Submitted by +at.emf.camp + +// Elefunc, Inc. : https://elefunc.com +// Submitted by Cetin Sert +rt.ht + +// Elementor : Elementor Ltd. +// Submitted by Anton Barkan +elementor.cloud +elementor.cool + +// Emergent : https://emergent.sh +// Submitted by Emergent Security Team +emergent.cloud +preview.emergentagent.com +emergent.host + +// Enalean SAS : https://www.enalean.com +// Submitted by Enalean Security Team +mytuleap.com +tuleap-partners.com + +// Encoretivity AB : https://encore.cloud +// Submitted by André Eriksson +encr.app +frontend.encr.app +encoreapi.com +lp.dev +api.lp.dev +objects.lp.dev + +// encoway GmbH : https://www.encoway.de +// Submitted by Marcel Daus +eu.encoway.cloud + +// EU.org : https://eu.org/ +// Submitted by Pierre Beyssac +eu.org +al.eu.org +asso.eu.org +at.eu.org +au.eu.org +be.eu.org +bg.eu.org +ca.eu.org +cd.eu.org +ch.eu.org +cn.eu.org +cy.eu.org +cz.eu.org +de.eu.org +dk.eu.org +edu.eu.org +ee.eu.org +es.eu.org +fi.eu.org +fr.eu.org +gr.eu.org +hr.eu.org +hu.eu.org +ie.eu.org +il.eu.org +in.eu.org +int.eu.org +is.eu.org +it.eu.org +jp.eu.org +kr.eu.org +lt.eu.org +lu.eu.org +lv.eu.org +me.eu.org +mk.eu.org +mt.eu.org +my.eu.org +net.eu.org +ng.eu.org +nl.eu.org +no.eu.org +nz.eu.org +pl.eu.org +pt.eu.org +ro.eu.org +ru.eu.org +se.eu.org +si.eu.org +sk.eu.org +tr.eu.org +uk.eu.org +us.eu.org + +// Eurobyte : https://eurobyte.ru +// Submitted by Evgeniy Subbotin +eurodir.ru + +// Evennode : http://www.evennode.com/ +// Submitted by Michal Kralik +eu-1.evennode.com +eu-2.evennode.com +eu-3.evennode.com +eu-4.evennode.com +us-1.evennode.com +us-2.evennode.com +us-3.evennode.com +us-4.evennode.com + +// Evervault : https://evervault.com +// Submitted by Hannah Neary +relay.evervault.app +relay.evervault.dev + +// Expo : https://expo.dev/ +// Submitted by James Ide +expo.app +staging.expo.app + +// Fabrica Technologies, Inc. : https://www.fabrica.dev/ +// Submitted by Eric Jiang +onfabrica.com + +// FAITID : https://faitid.org/ +// Submitted by Maxim Alzoba +// https://www.flexireg.net/stat_info +ru.net +adygeya.ru +bashkiria.ru +bir.ru +cbg.ru +com.ru +dagestan.ru +grozny.ru +kalmykia.ru +kustanai.ru +marine.ru +mordovia.ru +msk.ru +mytis.ru +nalchik.ru +nov.ru +pyatigorsk.ru +spb.ru +vladikavkaz.ru +vladimir.ru +abkhazia.su +adygeya.su +aktyubinsk.su +arkhangelsk.su +armenia.su +ashgabad.su +azerbaijan.su +balashov.su +bashkiria.su +bryansk.su +bukhara.su +chimkent.su +dagestan.su +east-kazakhstan.su +exnet.su +georgia.su +grozny.su +ivanovo.su +jambyl.su +kalmykia.su +kaluga.su +karacol.su +karaganda.su +karelia.su +khakassia.su +krasnodar.su +kurgan.su +kustanai.su +lenug.su +mangyshlak.su +mordovia.su +msk.su +murmansk.su +nalchik.su +navoi.su +north-kazakhstan.su +nov.su +obninsk.su +penza.su +pokrovsk.su +sochi.su +spb.su +tashkent.su +termez.su +togliatti.su +troitsk.su +tselinograd.su +tula.su +tuva.su +vladikavkaz.su +vladimir.su +vologda.su + +// Fancy Bits, LLC : http://getchannels.com +// Submitted by Aman Gupta +channelsdvr.net +u.channelsdvr.net + +// Fastly Inc. : http://www.fastly.com/ +// Submitted by Fastly Security +edgecompute.app +fastly-edge.com +fastly-terrarium.com +freetls.fastly.net +map.fastly.net +a.prod.fastly.net +global.prod.fastly.net +a.ssl.fastly.net +b.ssl.fastly.net +global.ssl.fastly.net +fastlylb.net +map.fastlylb.net + +// Fastmail : https://www.fastmail.com/ +// Submitted by Marc Bradshaw +*.user.fm + +// FASTVPS EESTI OU : https://fastvps.ru/ +// Submitted by Likhachev Vasiliy +fastvps-server.com +fastvps.host +myfast.host +fastvps.site +myfast.space + +// FearWorks Media Ltd. : https://fearworksmedia.co.uk +// Submitted by Keith Fairley +conn.uk +copro.uk +hosp.uk + +// Fedora : https://fedoraproject.org/ +// Submitted by Patrick Uiterwijk +fedorainfracloud.org +fedorapeople.org +cloud.fedoraproject.org +app.os.fedoraproject.org +app.os.stg.fedoraproject.org + +// Fermax : https://fermax.com/ +// Submitted by Koen Van Isterdael +mydobiss.com + +// FH Muenster : https://www.fh-muenster.de +// Submitted by Robin Naundorf +fh-muenster.io + +// Figma : https://www.figma.com +// Submitted by Nick Frost +figma.site +figma-gov.site +preview.site + +// Filegear Inc. : https://www.filegear.com +// Submitted by Jason Zhu +filegear.me + +// Firebase, Inc. +// Submitted by Chris Raynor +firebaseapp.com + +// FlashDrive : https://flashdrive.io +// Submitted by Eric Chan +fldrv.com + +// Fleek Labs Inc : https://fleek.xyz +// Submitted by Parsa Ghadimi +on-fleek.app + +// FlutterFlow : https://flutterflow.io +// Submitted by Anton Emelyanov +flutterflow.app + +// fly.io : https://fly.io +// Submitted by Kurt Mackey +sprites.app +fly.dev + +// FoundryLabs, Inc : https://e2b.dev/ +// Submitted by Jiri Sveceny +e2b.app + +// Framer : https://www.framer.com +// Submitted by Koen Rouwhorst +framer.ai +framer.app +framercanvas.com +framer.media +framer.photos +framer.website +framer.wiki + +// Frederik Braun : https://frederik-braun.com +// Submitted by Frederik Braun +*.0e.vc + +// Freebox : http://www.freebox.fr +// Submitted by Romain Fliedel +freebox-os.com +freeboxos.com +fbx-os.fr +fbxos.fr +freebox-os.fr +freeboxos.fr + +// freedesktop.org : https://www.freedesktop.org +// Submitted by Daniel Stone +freedesktop.org + +// freemyip.com : https://freemyip.com +// Submitted by Cadence +freemyip.com + +// Frusky MEDIA&PR : https://www.frusky.de +// Submitted by Victor Pupynin +*.frusky.de + +// FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at +// Submitted by Daniel A. Maierhofer +wien.funkfeuer.at + +// Future Versatile Group. : https://www.fvg-on.net/ +// T.Kabu +daemon.asia +dix.asia +mydns.bz +0am.jp +0g0.jp +0j0.jp +0t0.jp +mydns.jp +pgw.jp +wjg.jp +keyword-on.net +live-on.net +server-on.net +mydns.tw +mydns.vc + +// Futureweb GmbH : https://www.futureweb.at +// Submitted by Andreas Schnederle-Wagner +*.futurecms.at +*.ex.futurecms.at +*.in.futurecms.at +futurehosting.at +futuremailing.at +*.ex.ortsinfo.at +*.kunden.ortsinfo.at +*.statics.cloud + +// Gadget Software Inc. : https://gadget.dev +// Submitted by Harry Brundage +gadget.app +gadget.host + +// GCom Internet : https://www.gcom.net.au +// Submitted by Leo Julius +aliases121.com + +// GDS : https://www.gov.uk/service-manual/technology/managing-domain-names +// Submitted by Stephen Ford +campaign.gov.uk +service.gov.uk +independent-commission.uk +independent-inquest.uk +independent-inquiry.uk +independent-panel.uk +independent-review.uk +public-inquiry.uk +royal-commission.uk + +// Gehirn Inc. : https://www.gehirn.co.jp/ +// Submitted by Kohei YOSHIDA +gehirn.ne.jp +usercontent.jp + +// Gentlent, Inc. : https://www.gentlent.com +// Submitted by Tom Klein +gentapps.com +gentlentapis.com +cdn-edges.net + +// GignoSystemJapan : http://gsj.bz +// Submitted by GignoSystemJapan +gsj.bz + +// GitBook Inc. : https://www.gitbook.com/ +// Submitted by Samy Pesse +gitbook.io + +// GitHub, Inc. +// Submitted by Patrick Toomey +github.app +githubusercontent.com +githubpreview.dev +github.io + +// GitLab, Inc. : https://about.gitlab.com/ +// Submitted by Alex Hanselka +gitlab.io + +// Gitplac.si : https://gitplac.si +// Submitted by Aljaž Starc +gitapp.si +gitpage.si + +// Global NOG Alliance : https://nogalliance.org/ +// Submitted by Sander Steffann +nog.community + +// Globe Hosting SRL : https://www.globehosting.com/ +// Submitted by Gavin Brown +co.ro +shop.ro + +// GMO Pepabo, Inc. : https://pepabo.com/ +// Submitted by Hosting Div +lolipop.io +angry.jp +babyblue.jp +babymilk.jp +backdrop.jp +bambina.jp +bitter.jp +blush.jp +boo.jp +boy.jp +boyfriend.jp +but.jp +candypop.jp +capoo.jp +catfood.jp +cheap.jp +chicappa.jp +chillout.jp +chips.jp +chowder.jp +chu.jp +ciao.jp +cocotte.jp +coolblog.jp +cranky.jp +cutegirl.jp +daa.jp +deca.jp +deci.jp +digick.jp +egoism.jp +fakefur.jp +fem.jp +flier.jp +floppy.jp +fool.jp +frenchkiss.jp +girlfriend.jp +girly.jp +gloomy.jp +gonna.jp +greater.jp +hacca.jp +heavy.jp +her.jp +hiho.jp +hippy.jp +holy.jp +hungry.jp +icurus.jp +itigo.jp +jellybean.jp +kikirara.jp +kill.jp +kilo.jp +kuron.jp +littlestar.jp +lolipopmc.jp +lolitapunk.jp +lomo.jp +lovepop.jp +lovesick.jp +main.jp +mods.jp +mond.jp +mongolian.jp +moo.jp +namaste.jp +nikita.jp +nobushi.jp +noor.jp +oops.jp +parallel.jp +parasite.jp +pecori.jp +peewee.jp +penne.jp +pepper.jp +perma.jp +pigboat.jp +pinoko.jp +punyu.jp +pupu.jp +pussycat.jp +pya.jp +raindrop.jp +readymade.jp +sadist.jp +schoolbus.jp +secret.jp +staba.jp +stripper.jp +sub.jp +sunnyday.jp +thick.jp +tonkotsu.jp +under.jp +upper.jp +velvet.jp +verse.jp +versus.jp +vivian.jp +watson.jp +weblike.jp +whitesnow.jp +zombie.jp +heteml.net + +// GoDaddy Registry : https://registry.godaddy +// Submitted by Rohan Durrant +graphic.design + +// GoIP DNS Services : http://www.goip.de +// Submitted by Christian Poulter +goip.de + +// Google, Inc. +// Submitted by Shannon McCabe +*.hosted.app +*.run.app +*.mtls.run.app +web.app +*.0emm.com +appspot.com +*.r.appspot.com +blogspot.com +codespot.com +googleapis.com +googlecode.com +pagespeedmobilizer.com +withgoogle.com +withyoutube.com +*.gateway.dev +cloud.goog +translate.goog +*.usercontent.goog +cloudfunctions.net + +// Goupile : https://goupile.fr +// Submitted by Niels Martignene +goupile.fr + +// GOV.UK Pay : https://www.payments.service.gov.uk/ +// Submitted by Richard Baker +pymnt.uk + +// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ +// Submitted by Tom Whitwell +cloudapps.digital +london.cloudapps.digital + +// Government of the Netherlands : https://www.government.nl +// Submitted by +gov.nl + +// Grafana Labs : https://grafana.com/ +// Submitted by Platform Engineering +grafana-dev.net + +// GrayJay Web Solutions Inc. : https://grayjaysports.ca +// Submitted by Matt Yamkowy +grayjayleagues.com + +// Grebedoc : https://grebedoc.dev +// Submitted by Catherine Zotova +grebedoc.dev + +// GünstigBestellen : https://günstigbestellen.de +// Submitted by Furkan Akkoc +günstigbestellen.de +günstigliefern.de + +// GV.UY : https://nic.gv.uy +// Submitted by cheng +gv.uy + +// Hackclub Nest : https://hackclub.app +// Submitted by Cyteon +hackclub.app + +// Häkkinen.fi : https://www.häkkinen.fi/ +// Submitted by Eero Häkkinen +häkkinen.fi + +// Hashbang : https://hashbang.sh +hashbang.sh + +// Hasura : https://hasura.io +// Submitted by Shahidh K Muhammed +hasura.app +hasura-app.io + +// Hatena Co., Ltd. : https://hatena.co.jp +// Submitted by Masato Nakamura +hatenablog.com +hatenadiary.com +hateblo.jp +hatenablog.jp +hatenadiary.jp +hatenadiary.org + +// Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages) : https://www.hs-heilbronn.de +// Submitted by Richard Zowalla +pages.it.hs-heilbronn.de +pages-research.it.hs-heilbronn.de + +// HeiyuSpace : https://lazycat.cloud +// Submitted by Xia Bin +heiyu.space + +// Helio Networks : https://heliohost.org +// Submitted by Ben Frede +helioho.st +heliohost.us + +// Hepforge : https://www.hepforge.org +// Submitted by David Grellscheid +hepforge.org + +// Hercules : https://hercules.app +// Submitted by Brendan Falk +onhercules.app +hercules-app.com +hercules-dev.com + +// Heroku : https://www.heroku.com/ +// Submitted by Shumon Huque +herokuapp.com + +// Heyflow : https://www.heyflow.com +// Submitted by Mirko Nitschke +heyflow.page +heyflow.site + +// Hibernating Rhinos +// Submitted by Oren Eini +ravendb.cloud +ravendb.community +development.run +ravendb.run + +// HiDNS : https://www.hidoha.net +// Submitted by ifeng +hidns.co +hidns.vip + +// home.pl S.A. : https://home.pl +// Submitted by Krzysztof Wolski +homesklep.pl + +// Homebase : https://homebase.id/ +// Submitted by Jason Babo +*.kin.one +*.id.pub +*.kin.pub + +// Hoplix : https://www.hoplix.com +// Submitted by Danilo De Franco +hoplix.shop + +// HOSTBIP REGISTRY : https://www.hostbip.com/ +// Submitted by Atanunu Igbunuroghene +orx.biz +biz.ng +co.biz.ng +dl.biz.ng +go.biz.ng +lg.biz.ng +on.biz.ng +col.ng +firm.ng +gen.ng +ltd.ng +ngo.ng +plc.ng + +// HostyHosting : https://hostyhosting.com +hostyhosting.io + +// Hugging Face : https://huggingface.co +// Submitted by Eliott Coyac +hf.space +static.hf.space + +// Hypernode B.V. : https://www.hypernode.com/ +// Submitted by Cipriano Groenendal +hypernode.io + +// I-O DATA DEVICE, INC. : http://www.iodata.com/ +// Submitted by Yuji Minagawa +iobb.net + +// i-registry s.r.o. : http://www.i-registry.cz/ +// Submitted by Martin Semrad +co.cz + +// Ici la Lune : http://www.icilalune.com/ +// Submitted by Simon Morvan +*.moonscale.io +moonscale.net + +// iDOT Services Limited : http://www.domain.gr.com +// Submitted by Gavin Brown +gr.com + +// iki.fi +// Submitted by Hannu Aronsson +iki.fi + +// iliad italia : https://www.iliad.it +// Submitted by Marios Makassikis +ibxos.it +iliadboxos.it + +// Imagine : https://imagine.dev +// Submitted by Steven Nguyen +imagine.diy +imagine-proxy.work + +// Incsub, LLC : https://incsub.com/ +// Submitted by Aaron Edwards +smushcdn.com +wphostedmail.com +wpmucdn.com +tempurl.host +wpmudev.host + +// Individual Network Berlin e.V. : https://www.in-berlin.de/ +// Submitted by Christian Seitz +dyn-berlin.de +in-berlin.de +in-brb.de +in-butter.de +in-dsl.de +in-vpn.de +in-dsl.net +in-vpn.net +in-dsl.org +in-vpn.org + +// Inferno Communications : https://inferno.co.uk +// Submitted by Connor McFarlane +oninferno.net + +// info.at : http://www.info.at/ +biz.at +info.at + +// info.cx : http://info.cx +// Submitted by June Slater +info.cx + +// Interlegis : http://www.interlegis.leg.br +// Submitted by Gabriel Ferreira +ac.leg.br +al.leg.br +am.leg.br +ap.leg.br +ba.leg.br +ce.leg.br +df.leg.br +es.leg.br +go.leg.br +ma.leg.br +mg.leg.br +ms.leg.br +mt.leg.br +pa.leg.br +pb.leg.br +pe.leg.br +pi.leg.br +pr.leg.br +rj.leg.br +rn.leg.br +ro.leg.br +rr.leg.br +rs.leg.br +sc.leg.br +se.leg.br +sp.leg.br +to.leg.br + +// intermetrics GmbH : https://pixolino.com/ +// Submitted by Wolfgang Schwarz +pixolino.com + +// Internet-Pro, LLP : https://netangels.ru/ +// Submitted by Vasiliy Sheredeko +na4u.ru + +// Inventor Services : https://inventor.gg/ +// Submitted by Inventor Team +botdash.app +botdash.dev +botdash.gg +botdash.net +botda.sh +botdash.xyz + +// IONOS SE : https://www.ionos.com/ +// IONOS Group SE : https://www.ionos-group.com/ +// Submitted by Henrik Willert +apps-1and1.com +live-website.com +webspace-host.com +apps-1and1.net +websitebuilder.online +app-ionos.space + +// iopsys software solutions AB : https://iopsys.eu/ +// Submitted by Roman Azarenko +iopsys.se + +// IPFS Project : https://ipfs.tech/ +// Submitted by Interplanetary Shipyard +*.inbrowser.dev +*.dweb.link +*.inbrowser.link + +// IPiFony Systems, Inc. : https://www.ipifony.com/ +// Submitted by Matthew Hardeman +ipifony.net + +// ir.md : https://nic.ir.md +// Submitted by Ali Soizi +ir.md + +// is-a-good.dev : https://is-a-good.dev +// Submitted by William Harrison +is-a-good.dev + +// IServ GmbH : https://iserv.de +// Submitted by Kim Brodowski +iservschule.de +mein-iserv.de +schuldock.de +schulplattform.de +schulserver.de +test-iserv.de +iserv.dev +iserv.host + +// Ispmanager : https://www.ispmanager.com/ +// Submitted by Ispmanager infrastructure team +ispmanager.name + +// Jelastic, Inc. : https://jelastic.com/ +// Submitted by Ihor Kolodyuk +mel.cloudlets.com.au +cloud.interhostsolutions.be +alp1.ae.flow.ch +appengine.flow.ch +es-1.axarnet.cloud +diadem.cloud +vip.jelastic.cloud +jele.cloud +it1.eur.aruba.jenv-aruba.cloud +it1.jenv-aruba.cloud +keliweb.cloud +cs.keliweb.cloud +oxa.cloud +tn.oxa.cloud +uk.oxa.cloud +primetel.cloud +uk.primetel.cloud +ca.reclaim.cloud +uk.reclaim.cloud +us.reclaim.cloud +ch.trendhosting.cloud +de.trendhosting.cloud +jele.club +dopaas.com +paas.hosted-by-previder.com +rag-cloud.hosteur.com +rag-cloud-ch.hosteur.com +jcloud.ik-server.com +jcloud-ver-jpc.ik-server.com +demo.jelastic.com +paas.massivegrid.com +jed.wafaicloud.com +ryd.wafaicloud.com +j.scaleforce.com.cy +jelastic.dogado.eu +fi.cloudplatform.fi +demo.datacenter.fi +paas.datacenter.fi +jele.host +mircloud.host +paas.beebyte.io +sekd1.beebyteapp.io +jele.io +jc.neen.it +jcloud.kz +cloudjiffy.net +fra1-de.cloudjiffy.net +west1-us.cloudjiffy.net +jls-sto1.elastx.net +jls-sto2.elastx.net +jls-sto3.elastx.net +fr-1.paas.massivegrid.net +lon-1.paas.massivegrid.net +lon-2.paas.massivegrid.net +ny-1.paas.massivegrid.net +ny-2.paas.massivegrid.net +sg-1.paas.massivegrid.net +jelastic.saveincloud.net +nordeste-idc.saveincloud.net +j.scaleforce.net +sdscloud.pl +unicloud.pl +mircloud.ru +enscaled.sg +jele.site +jelastic.team +orangecloud.tn +j.layershift.co.uk +phx.enscaled.us +mircloud.us + +// Jino : https://www.jino.ru +// Submitted by Sergey Ulyashin +myjino.ru +*.hosting.myjino.ru +*.landing.myjino.ru +*.spectrum.myjino.ru +*.vps.myjino.ru + +// Jotelulu S.L. : https://jotelulu.com +// Submitted by Daniel Fariña +jote.cloud +jotelulu.cloud +eu1-plenit.com +la1-plenit.com +us1-plenit.com + +// JouwWeb B.V. : https://www.jouwweb.nl +// Submitted by Camilo Sperberg +webadorsite.com +jouwweb.site + +// Joyent : https://www.joyent.com/ +// Submitted by Brian Bennett +*.triton.zone + +// JS.ORG : http://dns.js.org +// Submitted by Stefan Keim +js.org + +// KaasHosting : http://www.kaashosting.nl/ +// Submitted by Wouter Bakker +kaas.gg +khplay.nl + +// Kapsi : https://kapsi.fi +// Submitted by Tomi Juntunen +kapsi.fi + +// KataBump : https://katabump.com +// Submitted by Thibault Lapeyre +kdns.fr + +// Katholieke Universiteit Leuven : https://www.kuleuven.be +// Submitted by Abuse KU Leuven +ezproxy.kuleuven.be +kuleuven.cloud + +// Keenetic : https://keenetic.com +// Submitted by Alexey Nikitin +keenetic.io +keenetic.link +keenetic.name +keenetic.pro + +// Kevin Service : https://kevsrv.me +// Submitted by Kevin Service Team +ae.kg + +// Keyweb AG : https://www.keyweb.de +// Submitted by Martin Dannehl +keymachine.de + +// Kilo Code, Inc. : https://kilo.ai +// Submitted by Remon Oldenbeuving +kiloapps.ai +kiloapps.io + +// KingHost : https://king.host +// Submitted by Felipe Keller Braz +kinghost.net +uni5.net + +// KnightPoint Systems, LLC : http://www.knightpoint.com/ +// Submitted by Roy Keene +knightpoint.systems + +// KoobinEvent, SL : https://www.koobin.com +// Submitted by Iván Oliva +koobin.events + +// Krellian Ltd. : https://krellian.com +// Submitted by Ben Francis +webthings.io +krellian.net + +// KUROKU LTD : https://kuroku.ltd/ +// Submitted by DisposaBoy +oya.to + +// KV GmbH : https://www.nic.co.de +// Submitted by KV GmbH +// Abuse reports to +co.de + +// Laravel Holdings, Inc. : https://laravel.com +// Submitted by André Valentin & James Brooks +shiptoday.app +shiptoday.build +laravel.cloud +on-forge.com +on-vapor.com + +// LCube - Professional hosting e.K. : https://www.lcube-webhosting.de +// Submitted by Lars Laehn +git-repos.de +lcube-server.de +svn-repos.de + +// Leadpages : https://www.leadpages.net +// Submitted by Greg Dallavalle +leadpages.co +lpages.co +lpusercontent.com + +// Leapcell : https://leapcell.io/ +// Submitted by Leapcell Team +leapcell.app +leapcell.dev +leapcell.online + +// Liara : https://liara.ir +// Submitted by Amirhossein Badinloo +liara.run +iran.liara.run + +// libp2p project : https://libp2p.io +// Submitted by Interplanetary Shipyard +libp2p.direct + +// Libre IT Ltd : https://libre.nz +// Submitted by Tomas Maggio +runcontainers.dev + +// Lifetime Hosting : https://Lifetime.Hosting/ +// Submitted by Mike Fillator +co.business +co.education +co.events +co.financial +co.network +co.place +co.technology + +// linkyard ldt : https://www.linkyard.ch/ +// Submitted by Mario Siegenthaler +linkyard-cloud.ch +linkyard.cloud + +// Linode : https://linode.com +// Submitted by +members.linode.com +*.nodebalancer.linode.com +*.linodeobjects.com +ip.linodeusercontent.com + +// LiquidNet Ltd : http://www.liquidnetlimited.com/ +// Submitted by Victor Velchev +we.bs + +// Listen53 : https://www.l53.net +// Submitted by Gerry Keh +filegear-sg.me +ggff.net + +// Localcert : https://localcert.dev +// Submitted by Lann Martin +*.user.localcert.dev + +// Localtonet : https://localtonet.com/ +// Submitted by Burak Isleyici +localtonet.com +*.localto.net + +// Lodz University of Technology LODMAN regional domains : https://www.man.lodz.pl/dns +// Submitted by Piotr Wilk +lodz.pl +pabianice.pl +plock.pl +sieradz.pl +skierniewice.pl +zgierz.pl + +// Log'in Line : https://www.loginline.com/ +// Submitted by Rémi Mach +loginline.app +loginline.dev +loginline.io +loginline.services +loginline.site + +// Lõhmus Family, The : https://lohmus.me/ +// Submitted by Heiki Lõhmus +lohmus.me + +// Lovable : https://lovable.dev +// Submitted by Fabian Hedin +lovable.app +lovableproject.com +lovable.run +lovable.sh + +// LubMAN UMCS Sp. z o.o : https://lubman.pl/ +// Submitted by Ireneusz Maliszewski +krasnik.pl +leczna.pl +lubartow.pl +lublin.pl +poniatowa.pl +swidnik.pl + +// Lug.org.uk : https://lug.org.uk +// Submitted by Jon Spriggs +glug.org.uk +lug.org.uk +lugs.org.uk + +// Lukanet Ltd : https://lukanet.com +// Submitted by Anton Avramov +barsy.bg +barsy.club +barsycenter.com +barsyonline.com +barsy.de +barsy.dev +barsy.eu +barsy.gr +barsy.in +barsy.info +barsy.io +barsy.me +barsy.menu +barsyonline.menu +barsy.mobi +barsy.net +barsy.online +barsy.org +barsy.pro +barsy.pub +barsy.ro +barsy.rs +barsy.shop +barsyonline.shop +barsy.site +barsy.store +barsy.support +barsy.uk +barsy.co.uk +barsyonline.co.uk + +// Lutra : https://lutra.ai +// Submitted by Joshua Newman +*.lutrausercontent.com + +// Luyani Inc. : https://luyani.com/ +// Submitted by Umut Gumeli +luyani.app +luyani.net + +// Magento Commerce +// Submitted by Damien Tournoud +*.magentosite.cloud + +// Magic Patterns : https://www.magicpatterns.com +// Submitted by Teddy Ni +magicpatterns.app +magicpatternsapp.com + +// Mail.Ru Group : https://hb.cldmail.ru +// Submitted by Ilya Zaretskiy +hb.cldmail.ru + +// MathWorks : https://www.mathworks.com/ +// Submitted by Emily Reed +matlab.cloud +modelscape.com +mwcloudnonprod.com +polyspace.com + +// May First - People Link : https://mayfirst.org/ +// Submitted by Jamie McClelland +mayfirst.info +mayfirst.org + +// Maze Play : https://www.mazeplay.com +// Submitted by Adam Humpherys +mazeplay.com + +// McHost : https://mchost.ru +// Submitted by Evgeniy Subbotin +mcdir.me +mcdir.ru +vps.mcdir.ru +mcpre.ru + +// Mediatech : https://mediatech.by +// Submitted by Evgeniy Kozhuhovskiy +mediatech.by +mediatech.dev + +// Medicom Health : https://medicomhealth.com +// Submitted by Michael Olson +hra.health + +// MedusaJS, Inc : https://medusajs.com/ +// Submitted by Stevche Radevski +medusajs.app + +// Memset hosting : https://www.memset.com +// Submitted by Tom Whitwell +miniserver.com +memset.net + +// Messerli Informatik AG : https://www.messerli.ch/ +// Submitted by Ruben Schmidmeister +messerli.app + +// Meta Platforms, Inc. : https://meta.com/ +// Submitted by Jacob Cordero +atmeta.com +apps.fbsbx.com + +// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ +// Submitted by Zdeněk Šustr and Radim Janča +*.cloud.metacentrum.cz +custom.metacentrum.cz +flt.cloud.muni.cz +usr.cloud.muni.cz + +// Meteor Development Group : https://www.meteor.com/hosting +// Submitted by Pierre Carrier +meteorapp.com +eu.meteorapp.com + +// Michau Enterprises Limited : http://www.co.pl/ +co.pl + +// Microsoft Corporation : http://microsoft.com +// Submitted by Public Suffix List Admin +// Managed by Corporate Domains +// Microsoft Azure : https://home.azure +*.azurecontainer.io +azure-api.net +azure-mobile.net +azureedge.net +azurefd.net +azurestaticapps.net +1.azurestaticapps.net +2.azurestaticapps.net +3.azurestaticapps.net +4.azurestaticapps.net +5.azurestaticapps.net +6.azurestaticapps.net +7.azurestaticapps.net +centralus.azurestaticapps.net +eastasia.azurestaticapps.net +eastus2.azurestaticapps.net +westeurope.azurestaticapps.net +westus2.azurestaticapps.net +azurewebsites.net +cloudapp.net +trafficmanager.net +blob.core.usgovcloudapi.net +file.core.usgovcloudapi.net +web.core.usgovcloudapi.net +servicebus.usgovcloudapi.net +usgovcloudapp.net +usgovtrafficmanager.net +blob.core.windows.net +file.core.windows.net +web.core.windows.net +servicebus.windows.net +azure-api.us +azurewebsites.us + +// MikroTik : https://mikrotik.com +// Submitted by MikroTik SysAdmin Team +routingthecloud.com +sn.mynetname.net +routingthecloud.net +routingthecloud.org + +// Million Software, Inc : https://million.dev/ +// Submitted by Rayhan Noufal Arayilakath +same-app.com +same-preview.com + +// minion.systems : http://minion.systems +// Submitted by Robert Böttinger +csx.cc + +// Miren, Inc. : https://miren.dev +// Submitted by Miren Product Team +miren.app +miren.systems + +// Mittwald CM Service GmbH & Co. KG : https://mittwald.de +// Submitted by Marco Rieger +mydbserver.com +webspaceconfig.de +mittwald.info +mittwaldserver.info +typo3server.info +project.space + +// Mocha : https://getmocha.com +// Submitted by Ben Reinhart +mocha.app +mochausercontent.com +mocha-sandbox.dev + +// MODX Systems LLC : https://modx.com +// Submitted by Elizabeth Southwell +modx.dev + +// Mozilla Foundation : https://mozilla.org/ +// Submitted by glob +bmoattachments.org + +// MSK-IX : https://www.msk-ix.ru/ +// Submitted by Khannanov Roman +net.ru +org.ru +pp.ru + +// MyOwn srl : https://www.myown.eu/ +// Submitted by Stephane Bouvard +my.be + +// Mythic Beasts : https://www.mythic-beasts.com +// Submitted by Paul Cammish +hostedpi.com +caracal.mythic-beasts.com +customer.mythic-beasts.com +fentiger.mythic-beasts.com +lynx.mythic-beasts.com +ocelot.mythic-beasts.com +oncilla.mythic-beasts.com +onza.mythic-beasts.com +sphinx.mythic-beasts.com +vs.mythic-beasts.com +x.mythic-beasts.com +yali.mythic-beasts.com +cust.retrosnub.co.uk + +// Nabu Casa : https://www.nabucasa.com +// Submitted by Paulus Schoutsen +ui.nabu.casa + +// Needle Tools GmbH : https://needle.tools +// Submitted by Felix Herbst +needle.run + +// Neo : https://www.neo.space +// Submitted by Ankit Kulkarni +co.site + +// Net at Work Gmbh : https://www.netatwork.de +// Submitted by Jan Jaeschke +cloud.nospamproxy.com +o365.cloud.nospamproxy.com + +// Net libre : https://www.netlib.re +// Submitted by Philippe PITTOLI +netlib.re + +// Netlify : https://www.netlify.com +// Submitted by Jessica Parsons +netlify.app + +// Neustar Inc. +// Submitted by Trung Tran +4u.com + +// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ +// Submitted by Jeff Wheelhouse +nfshost.com + +// NFT.Storage : https://nft.storage/ +// Submitted by Vasco Santos or +ipfs.nftstorage.link + +// NGO.US Registry : https://nic.ngo.us +// Submitted by Alstra Solutions Ltd. Networking Team +ngo.us + +// ngrok : https://ngrok.com/ +// Submitted by Alan Shreve +ngrok.app +ngrok-free.app +ngrok.dev +ngrok-free.dev +ngrok.io +ap.ngrok.io +au.ngrok.io +eu.ngrok.io +in.ngrok.io +jp.ngrok.io +sa.ngrok.io +us.ngrok.io +ngrok.pizza +ngrok.pro + +// Nicolaus Copernicus University in Torun - MSK TORMAN : https://www.man.torun.pl +torun.pl + +// Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ +// Submitted by Nicholas Ford +nh-serv.co.uk +nimsite.uk + +// No-IP.com : https://noip.com/ +// Submitted by Deven Reza +mmafan.biz +myftp.biz +no-ip.biz +no-ip.ca +fantasyleague.cc +gotdns.ch +3utilities.com +blogsyte.com +ciscofreak.com +damnserver.com +ddnsking.com +ditchyourip.com +dnsiskinky.com +dynns.com +geekgalaxy.com +health-carereform.com +homesecuritymac.com +homesecuritypc.com +myactivedirectory.com +mysecuritycamera.com +myvnc.com +net-freaks.com +onthewifi.com +point2this.com +quicksytes.com +securitytactics.com +servebeer.com +servecounterstrike.com +serveexchange.com +serveftp.com +servegame.com +servehalflife.com +servehttp.com +servehumour.com +serveirc.com +servemp3.com +servep2p.com +servepics.com +servequake.com +servesarcasm.com +stufftoread.com +unusualperson.com +workisboring.com +dvrcam.info +ilovecollege.info +no-ip.info +brasilia.me +ddns.me +dnsfor.me +hopto.me +loginto.me +noip.me +webhop.me +bounceme.net +ddns.net +eating-organic.net +mydissent.net +myeffect.net +mymediapc.net +mypsx.net +mysecuritycamera.net +nhlfan.net +no-ip.net +pgafan.net +privatizehealthinsurance.net +redirectme.net +serveblog.net +serveminecraft.net +sytes.net +cable-modem.org +collegefan.org +couchpotatofries.org +hopto.org +mlbfan.org +myftp.org +mysecuritycamera.org +nflfan.org +no-ip.org +read-books.org +ufcfan.org +zapto.org +no-ip.co.uk +golffan.us +noip.us +pointto.us + +// NodeArt : https://nodeart.io +// Submitted by Konstantin Nosov +stage.nodeart.io + +// Noop : https://noop.app +// Submitted by Nathaniel Schweinberg +*.developer.app +noop.app + +// Northflank Ltd. : https://northflank.com/ +// Submitted by Marco Suter +*.northflank.app +*.build.run +*.code.run +*.database.run +*.migration.run + +// Noticeable : https://noticeable.io +// Submitted by Laurent Pellegrino +noticeable.news + +// Notion Labs, Inc : https://www.notion.so/ +// Submitted by Jess Yao +notion.site + +// Now-DNS : https://now-dns.com +// Submitted by Steve Russell +dnsking.ch +mypi.co +myiphost.com +forumz.info +soundcast.me +tcp4.me +dnsup.net +hicam.net +now-dns.net +ownip.net +vpndns.net +dynserv.org +now-dns.org +x443.pw +ntdll.top +freeddns.us + +// nsupdate.info : https://www.nsupdate.info/ +// Submitted by Thomas Waldmann +nsupdate.info +nerdpol.ovh + +// O3O.Foundation : https://o3o.foundation/ +// Submitted by the prvcy.page Registry Team +prvcy.page + +// Observable, Inc. : https://observablehq.com +// Submitted by Mike Bostock +observablehq.cloud +static.observableusercontent.com + +// OMG.LOL : https://omg.lol +// Submitted by Adam Newbold +omg.lol + +// Omnibond Systems, LLC. : https://www.omnibond.com +// Submitted by Cole Estep +cloudycluster.net + +// OmniWe Limited : https://omniwe.com +// Submitted by Vicary Archangel +omniwe.site + +// One.com : https://www.one.com/ +// Submitted by Jacob Bunk Nielsen +123webseite.at +123website.be +simplesite.com.br +123website.ch +simplesite.com +123webseite.de +123hjemmeside.dk +123miweb.es +123kotisivu.fi +123siteweb.fr +simplesite.gr +123homepage.it +123website.lu +123website.nl +123hjemmeside.no +service.one +website.one +simplesite.pl +123paginaweb.pt +123minsida.se + +// ONID : https://get.onid.ca +// Submitted by ONID Engineering Team +onid.ca + +// Open Domains : https://open-domains.net +// Submitted by William Harrison +is-a-fullstack.dev +is-cool.dev +is-not-a.dev +localplayer.dev +is-local.org + +// Open Social : https://www.getopensocial.com/ +// Submitted by Alexander Varwijk +opensocial.site + +// OpenAI : https://openai.com +// Submitted by Thomas Shadwell +*.oaiusercontent.com + +// OpenCraft GmbH : http://opencraft.com/ +// Submitted by Sven Marnach +opencraft.hosting + +// OpenHost : https://registry.openhost.uk +// Submitted by OpenHost Registry Team +16-b.it +32-b.it +64-b.it + +// OpenResearch GmbH : https://openresearch.com/ +// Submitted by Philipp Schmid +orsites.com + +// Opera Software, A.S.A. +// Submitted by Yngve Pettersen +operaunite.com + +// Oracle Dyn : https://cloud.oracle.com/home https://dyn.com/dns/ +// Submitted by Gregory Drake +// Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label +*.customer-oci.com +*.oci.customer-oci.com +*.ocp.customer-oci.com +*.ocs.customer-oci.com +*.oraclecloudapps.com +*.oraclegovcloudapps.com +*.oraclegovcloudapps.uk + +// Orange : https://www.orange.com +// Submitted by Alexandre Linte +tech.orange + +// OsSav Technology Ltd. : https://ossav.com/ +// Submitted by OsSav Technology Ltd. +// https://nic.can.re +can.re + +// Oursky Limited : https://authgear.com/ +// Submitted by Authgear Team & Skygear Developer +authgear-staging.com +authgearapps.com + +// OutSystems +// Submitted by Duarte Santos +outsystemscloud.com + +// OVHcloud : https://ovhcloud.com +// Submitted by Vincent Cassé +*.hosting.ovh.net +*.webpaas.ovh.net + +// OwnProvider GmbH : http://www.ownprovider.com +// Submitted by Jan Moennich +ownprovider.com +own.pm + +// OwO : https://whats-th.is/ +// Submitted by Dean Sheather +*.owo.codes + +// OX : http://www.ox.rs +// Submitted by Adam Grand +ox.rs + +// oy.lc +// Submitted by Charly Coste +oy.lc + +// Pagefog : https://pagefog.com/ +// Submitted by Derek Myers +pgfog.com + +// PageXL : https://pagexl.com +// Submitted by Yann Guichard +pagexl.com + +// Pantheon Systems, Inc. : https://pantheon.io/ +// Submitted by Gary Dylina +gotpantheon.com +pantheonsite.io + +// Paywhirl, Inc : https://paywhirl.com/ +// Submitted by Daniel Netzer +*.paywhirl.com + +// pcarrier.ca Software Inc : https://pcarrier.ca/ +// Submitted by Pierre Carrier +*.xmit.co +xmit.dev +madethis.site +srv.us +gh.srv.us +gl.srv.us + +// Peplink | Pepwave : http://peplink.com/ +// Submitted by Steve Leung +mypep.link + +// Perspecta : https://perspecta.com/ +// Submitted by Kenneth Van Alstyne +perspecta.cloud + +// Ping Identity : https://www.pingidentity.com +// Submitted by Ping Identity +forgeblocks.com +id.forgerock.io + +// Plain : https://www.plain.com/ +// Submitted by Jesús Hernández +support.site + +// Planet-Work : https://www.planet-work.com/ +// Submitted by Frédéric VANNIÈRE +on-web.fr + +// Platform.sh : https://platform.sh +// Submitted by Nikola Kotur +*.upsun.app +upsunapp.com +ent.platform.sh +eu.platform.sh +us.platform.sh +*.platformsh.site +*.tst.site + +// Pley AB : https://www.pley.com/ +// Submitted by Henning Pohl +pley.games + +// Porter : https://porter.run/ +// Submitted by Rudraksh MK +onporter.run + +// Positive Codes Technology Company : http://co.bn/faq.html +// Submitted by Zulfais +co.bn + +// Postman, Inc : https://postman.com +// Submitted by Rahul Dhawan +postman-echo.com +pstmn.io +mock.pstmn.io +httpbin.org + +// prequalifyme.today : https://prequalifyme.today +// Submitted by DeepakTiwari deepak@ivylead.io +prequalifyme.today + +// prgmr.com : https://prgmr.com/ +// Submitted by Sarah Newman +xen.prgmr.com + +// priv.at : http://www.nic.priv.at/ +// Submitted by registry +priv.at + +// PROJECT ELIV : https://eliv.kr/ +// Submitted by PROJECT ELIV DomainName Team +c01.kr +eliv-api.kr +eliv-cdn.kr +eliv-dns.kr +mmv.kr +vki.kr + +// project-study : https://project-study.com +// Submitted by yumenewa +dev.project-study.com + +// Protonet GmbH : http://protonet.io +// Submitted by Martin Meier +protonet.io + +// PSL Sandbox : https://github.com/groundcat/PSL-Sandbox +// Submitted by groundcat +platter-app.dev + +// PT Ekossistim Indo Digital : https://e.id +// Submitted by Eid Team +e.id + +// Publication Presse Communication SARL : https://ppcom.fr +// Submitted by Yaacov Akiba Slama +chirurgiens-dentistes-en-france.fr +byen.site + +// PublicZone : https://publiczone.org/ +// Submitted by PublicZone NOC Team +nyc.mn +*.cn.st + +// pubtls.org : https://www.pubtls.org +// Submitted by Kor Nielsen +pubtls.org + +// PythonAnywhere LLP : https://www.pythonanywhere.com +// Submitted by Giles Thomas +pythonanywhere.com +eu.pythonanywhere.com + +// QA2 +// Submitted by Daniel Dent : https://www.danieldent.com/ +qa2.com + +// QCX +// Submitted by Cassandra Beelen +qcx.io +*.sys.qcx.io + +// QNAP System Inc : https://www.qnap.com +// Submitted by Nick Chang +myqnapcloud.cn +alpha-myqnapcloud.com +dev-myqnapcloud.com +mycloudnas.com +mynascloud.com +myqnapcloud.com + +// QOTO, Org. +// Submitted by Jeffrey Phillips Freeman +qoto.io + +// Qualifio : https://qualifio.com/ +// Submitted by Xavier De Cock +qualifioapp.com + +// Quality Unit : https://qualityunit.com +// Submitted by Vasyl Tsalko +ladesk.com + +// Qualy : https://qualyhq.com +// Submitted by Raphael Arias +*.qualyhqpartner.com +*.qualyhqportal.com + +// QuickBackend : https://www.quickbackend.com +// Submitted by Dani Biro +qbuser.com + +// Quip : https://quip.com +// Submitted by Patrick Linehan +*.quipelements.com + +// Qutheory LLC : http://qutheory.io +// Submitted by Jonas Schwartz +vapor.cloud +vaporcloud.io + +// Rackmaze LLC : https://www.rackmaze.com +// Submitted by Kirill Pertsev +rackmaze.com +rackmaze.net + +// Rad Web Hosting : https://radwebhosting.com +// Submitted by Scott Claeys +cloudsite.builders +myradweb.net +servername.us + +// Radix FZC : http://domains.in.net +// Submitted by Gavin Brown +web.in +in.net + +// Raidboxes GmbH : https://raidboxes.de +// Submitted by Auke Tembrink +myrdbx.io +site.rb-hosting.io + +// Railway Corporation : https://railway.com +// Submitted by Phineas Walton +up.railway.app + +// Rancher Labs, Inc : https://rancher.com +// Submitted by Vincent Fiduccia +*.on-rancher.cloud +*.on-k3s.io +*.on-rio.io + +// RavPage : https://www.ravpage.co.il +// Submitted by Roni Horowitz +ravpage.co.il + +// Read The Docs, Inc : https://www.readthedocs.org +// Submitted by David Fischer +readthedocs-hosted.com +readthedocs.io + +// Red Hat, Inc. OpenShift : https://openshift.redhat.com/ +// Submitted by Tim Kramer +rhcloud.com + +// Redgate Software : https://red-gate.com +// Submitted by Andrew Farries +instances.spawn.cc + +// Redpanda Data : https://redpanda.com +// Submitted by Infrastructure Team +*.clusters.rdpa.co +*.srvrless.rdpa.co + +// Render : https://render.com +// Submitted by Anurag Goel +onrender.com +app.render.com + +// Repl.it : https://repl.it +// Submitted by Lincoln Bergeson +replit.app +id.replit.app +firewalledreplit.co +id.firewalledreplit.co +repl.co +id.repl.co +replit.dev +archer.replit.dev +bones.replit.dev +canary.replit.dev +global.replit.dev +hacker.replit.dev +id.replit.dev +janeway.replit.dev +kim.replit.dev +kira.replit.dev +kirk.replit.dev +odo.replit.dev +paris.replit.dev +picard.replit.dev +pike.replit.dev +prerelease.replit.dev +reed.replit.dev +riker.replit.dev +sisko.replit.dev +spock.replit.dev +staging.replit.dev +sulu.replit.dev +tarpit.replit.dev +teams.replit.dev +tucker.replit.dev +wesley.replit.dev +worf.replit.dev +repl.run + +// Resin.io : https://resin.io +// Submitted by Tim Perry +resindevice.io +devices.resinstaging.io + +// RethinkDB : https://www.rethinkdb.com/ +// Submitted by Chris Kastorff +hzc.io + +// Rico Developments Limited : https://adimo.co +// Submitted by Colin Brown +adimo.co.uk + +// Riseup Networks : https://riseup.net +// Submitted by Micah Anderson +itcouldbewor.se + +// Roar Domains LLC : https://roar.basketball/ +// Submitted by Gavin Brown +aus.basketball +nz.basketball + +// ROBOT PAYMENT INC. : https://www.robotpayment.co.jp/ +// Submitted by Kentaro Takamori +subsc-pay.com +subsc-pay.net + +// Rochester Institute of Technology : http://www.rit.edu/ +// Submitted by Jennifer Herting +git-pages.rit.edu + +// Rocky Enterprise Software Foundation : https://resf.org +// Submitted by Neil Hanlon +rocky.page + +// Ruhr University Bochum : https://www.ruhr-uni-bochum.de/ +// Submitted by Andreas Jobs +rub.de +ruhr-uni-bochum.de +io.noc.ruhr-uni-bochum.de + +// Rusnames Limited : http://rusnames.ru/ +// Submitted by Sergey Zotov +биз.рус +ком.рус +крым.рус +мир.рус +мск.рус +орг.рус +самара.рус +сочи.рус +спб.рус +я.рус + +// Russian Academy of Sciences +// Submitted by Tech Support +ras.ru + +// Sakura Frp : https://www.natfrp.com +// Submitted by Bobo Liu +nyat.app + +// SAKURA Internet Inc. : https://www.sakura.ad.jp/ +// Submitted by Internet Service Department +180r.com +dojin.com +sakuratan.com +sakuraweb.com +x0.com +2-d.jp +bona.jp +crap.jp +daynight.jp +eek.jp +flop.jp +halfmoon.jp +jeez.jp +matrix.jp +mimoza.jp +ivory.ne.jp +mail-box.ne.jp +mints.ne.jp +mokuren.ne.jp +opal.ne.jp +sakura.ne.jp +sumomo.ne.jp +topaz.ne.jp +netgamers.jp +nyanta.jp +o0o0.jp +rdy.jp +rgr.jp +rulez.jp +s3.isk01.sakurastorage.jp +s3.isk02.sakurastorage.jp +saloon.jp +sblo.jp +skr.jp +tank.jp +uh-oh.jp +undo.jp +rs.webaccel.jp +user.webaccel.jp +websozai.jp +xii.jp +squares.net +jpn.org +kirara.st +x0.to +from.tv +sakura.tv + +// Salesforce.com, Inc. : https://salesforce.com/ +// Submitted by Salesforce Public Suffix List Team +*.builder.code.com +*.dev-builder.code.com +*.stg-builder.code.com +*.001.test.code-builder-stg.platform.salesforce.com +*.aa.crm.dev +*.ab.crm.dev +*.ac.crm.dev +*.ad.crm.dev +*.ae.crm.dev +*.af.crm.dev +*.ci.crm.dev +*.d.crm.dev +*.pa.crm.dev +*.pb.crm.dev +*.pc.crm.dev +*.pd.crm.dev +*.pe.crm.dev +*.pf.crm.dev +*.w.crm.dev +*.wa.crm.dev +*.wb.crm.dev +*.wc.crm.dev +*.wd.crm.dev +*.we.crm.dev +*.wf.crm.dev + +// Sandstorm Development Group, Inc. : https://sandcats.io/ +// Submitted by Asheesh Laroia +sandcats.io + +// Sav.com, LLC : https://marketing.sav.com/ +// Submitted by Mukul Kudegave +sav.case + +// SBE network solutions GmbH : https://www.sbe.de/ +// Submitted by Norman Meilick +logoip.com +logoip.de + +// Scaleway : https://www.scaleway.com/ +// Submitted by Scaleway PSL Maintainer +fr-par-1.baremetal.scw.cloud +fr-par-2.baremetal.scw.cloud +nl-ams-1.baremetal.scw.cloud +cockpit.fr-par.scw.cloud +ddl.fr-par.scw.cloud +dtwh.fr-par.scw.cloud +fnc.fr-par.scw.cloud +functions.fnc.fr-par.scw.cloud +ifr.fr-par.scw.cloud +k8s.fr-par.scw.cloud +nodes.k8s.fr-par.scw.cloud +kafk.fr-par.scw.cloud +mgdb.fr-par.scw.cloud +rdb.fr-par.scw.cloud +s3.fr-par.scw.cloud +s3-website.fr-par.scw.cloud +scbl.fr-par.scw.cloud +whm.fr-par.scw.cloud +priv.instances.scw.cloud +pub.instances.scw.cloud +k8s.scw.cloud +cockpit.nl-ams.scw.cloud +ddl.nl-ams.scw.cloud +dtwh.nl-ams.scw.cloud +ifr.nl-ams.scw.cloud +k8s.nl-ams.scw.cloud +nodes.k8s.nl-ams.scw.cloud +kafk.nl-ams.scw.cloud +mgdb.nl-ams.scw.cloud +rdb.nl-ams.scw.cloud +s3.nl-ams.scw.cloud +s3-website.nl-ams.scw.cloud +scbl.nl-ams.scw.cloud +whm.nl-ams.scw.cloud +cockpit.pl-waw.scw.cloud +ddl.pl-waw.scw.cloud +dtwh.pl-waw.scw.cloud +ifr.pl-waw.scw.cloud +k8s.pl-waw.scw.cloud +nodes.k8s.pl-waw.scw.cloud +kafk.pl-waw.scw.cloud +mgdb.pl-waw.scw.cloud +rdb.pl-waw.scw.cloud +s3.pl-waw.scw.cloud +s3-website.pl-waw.scw.cloud +scbl.pl-waw.scw.cloud +scalebook.scw.cloud +smartlabeling.scw.cloud +dedibox.fr + +// schokokeks.org GbR : https://schokokeks.org/ +// Submitted by Hanno Böck +schokokeks.net + +// Scottish Government : https://www.gov.scot +// Submitted by Martin Ellis +gov.scot +service.gov.scot + +// Scry Security : http://www.scrysec.com +// Submitted by Shante Adam +scrysec.com + +// Scrypted : https://scrypted.app +// Submitted by Koushik Dutta +client.scrypted.io + +// Securepoint GmbH : https://www.securepoint.de +// Submitted by Erik Anders +firewall-gateway.com +firewall-gateway.de +my-gateway.de +my-router.de +spdns.de +spdns.eu +firewall-gateway.net +my-firewall.org +myfirewall.org +spdns.org + +// Seidat : https://www.seidat.com +// Submitted by Artem Kondratev +seidat.net + +// Sellfy : https://sellfy.com +// Submitted by Yuriy Romadin +sellfy.store + +// Sendmsg : https://www.sendmsg.co.il +// Submitted by Assaf Stern +minisite.ms + +// Senseering GmbH : https://www.senseering.de +// Submitted by Felix Mönckemeyer +senseering.net + +// Servebolt AS : https://servebolt.com +// Submitted by Daniel Kjeserud +servebolt.cloud + +// Service Online LLC : http://drs.ua/ +// Submitted by Serhii Bulakh +biz.ua +co.ua +pp.ua + +// Shanghai Accounting Society : https://www.sasf.org.cn +// Submitted by Information Administration +as.sh.cn + +// Sheezy.Art : https://sheezy.art +// Submitted by Nyoom +sheezy.games + +// Shopblocks : http://www.shopblocks.com/ +// Submitted by Alex Bowers +myshopblocks.com + +// Shopify : https://www.shopify.com +// Submitted by Alex Richter +myshopify.com + +// Shopit : https://www.shopitcommerce.com/ +// Submitted by Craig McMahon +shopitsite.com + +// shopware AG : https://shopware.com +// Submitted by Jens Küper +shopware.shop +shopware.store + +// Siemens Mobility GmbH +// Submitted by Oliver Graebner +mo-siemens.io + +// SinaAppEngine : http://sae.sina.com.cn/ +// Submitted by SinaAppEngine +1kapp.com +appchizi.com +applinzi.com +sinaapp.com +vipsinaapp.com + +// Siteleaf : https://www.siteleaf.com/ +// Submitted by Skylar Challand +siteleaf.net + +// Small Technology Foundation : https://small-tech.org +// Submitted by Aral Balkan +small-web.org + +// Smallregistry by Promopixel SARL : https://www.smallregistry.net +// Former AFNIC's SLDs +// Submitted by Jérôme Lipowicz +aeroport.fr +avocat.fr +chambagri.fr +chirurgiens-dentistes.fr +experts-comptables.fr +medecin.fr +notaires.fr +pharmacien.fr +port.fr +veterinaire.fr + +// Smoove.io : https://www.smoove.io/ +// Submitted by Dan Kozak +vp4.me + +// Snowflake Inc : https://www.snowflake.com/ +// Submitted by Sam Haar +*.snowflake.app +*.privatelink.snowflake.app +streamlit.app +streamlitapp.com + +// Snowplow Analytics : https://snowplowanalytics.com/ +// Submitted by Ian Streeter +try-snowplow.com + +// Software Consulting Michal Zalewski : https://www.mafelo.com +// Submitted by Michal Zalewski +mafelo.net + +// Solana Name Service : https://sns.id +// Submitted by Solana Name Service +sol.site + +// Sony Interactive Entertainment LLC : https://sie.com/ +// Submitted by David Coles +playstation-cloud.com + +// SourceHut : https://sourcehut.org +// Submitted by Drew DeVault +srht.site + +// SourceLair PC : https://www.sourcelair.com +// Submitted by Antonis Kalipetis +apps.lair.io +*.stolos.io + +// sourceWAY GmbH : https://sourceway.de +// Submitted by Richard Reiber +4.at +my.at +my.de +*.nxa.eu +nx.gw + +// Spawnbase : https://spawnbase.ai +// Submitted by Alexander Zuev +spawnbase.app + +// SpeedPartner GmbH : https://www.speedpartner.de/ +// Submitted by Stefan Neufeind +customer.speedpartner.de + +// Spreadshop (sprd.net AG) : https://www.spreadshop.com/ +// Submitted by Martin Breest +myspreadshop.at +myspreadshop.com.au +myspreadshop.be +myspreadshop.ca +myspreadshop.ch +myspreadshop.com +myspreadshop.de +myspreadshop.dk +myspreadshop.es +myspreadshop.fi +myspreadshop.fr +myspreadshop.ie +myspreadshop.it +myspreadshop.net +myspreadshop.nl +myspreadshop.no +myspreadshop.pl +myspreadshop.se +myspreadshop.co.uk + +// StackBlitz : https://stackblitz.com +// Submitted by Dominic Elm & Albert Pai +w-corp-staticblitz.com +w-credentialless-staticblitz.com +w-staticblitz.com +bolt.host + +// Stackhero : https://www.stackhero.io +// Submitted by Adrien Gillon +stackhero-network.com + +// STACKIT GmbH & Co. KG : https://www.stackit.de/en/ +// Submitted by STACKIT-DNS Team (Simon Stier) +runs.onstackit.cloud +stackit.gg +stackit.rocks +stackit.run +stackit.zone + +// Stackryze : https://stackryze.com +// Submitted by Sudheer Bhuvana +indevs.in + +// Staclar : https://staclar.com +// Submitted by Q Misell +// Submitted by Matthias Merkel +musician.io +novecore.site + +// Standard Library : https://stdlib.com +// Submitted by Jacob Lee +api.stdlib.com + +// statichost.eu : https://www.statichost.eu +// Submitted by Eric Selin +statichost.page + +// stereosense GmbH : https://www.involve.me +// Submitted by Florian Burmann +feedback.ac +forms.ac +assessments.cx +calculators.cx +funnels.cx +paynow.cx +quizzes.cx +researched.cx +tests.cx +surveys.so + +// Storacha Network : https://storacha.network +// Submitted by Alan Shaw +ipfs.storacha.link +ipfs.w3s.link + +// Storebase : https://www.storebase.io +// Submitted by Tony Schirmer +storebase.store + +// Storj Labs Inc. : https://storj.io/ +// Submitted by Philip Hutchins +storj.farm + +// Strapi : https://strapi.io/ +// Submitted by Florent Baldino +strapiapp.com +media.strapiapp.com + +// Strategic System Consulting (eApps Hosting) : https://www.eapps.com/ +// Submitted by Alex Oancea +vps-host.net +atl.jelastic.vps-host.net +njs.jelastic.vps-host.net +ric.jelastic.vps-host.net + +// Streak : https://streak.com +// Submitted by Blake Kadatz +streak-link.com +streaklinks.com +streakusercontent.com + +// Student-Run Computing Facility : https://www.srcf.net/ +// Submitted by Edwin Balani +soc.srcf.net +user.srcf.net + +// Studenten Net Twente : http://www.snt.utwente.nl/ +// Submitted by Silke Hofstra +utwente.io + +// Sub 6 Limited : http://www.sub6.com +// Submitted by Dan Miller +temp-dns.com + +// Supabase : https://supabase.io +// Submitted by Supabase Security +supabase.co +realtime.supabase.co +storage.supabase.co +supabase.in +supabase.net + +// Syncloud : https://syncloud.org +// Submitted by Boris Rybalkin +syncloud.it + +// Synology, Inc. : https://www.synology.com/ +// Submitted by Rony Weng +dscloud.biz +direct.quickconnect.cn +dsmynas.com +familyds.com +diskstation.me +dscloud.me +i234.me +myds.me +synology.me +dscloud.mobi +dsmynas.net +familyds.net +dsmynas.org +familyds.org +direct.quickconnect.to +vpnplus.to + +// Tabit Technologies Ltd. : https://tabit.cloud/ +// Submitted by Oren Agiv +mytabit.com +mytabit.co.il +tabitorder.co.il + +// TAIFUN Software AG : http://taifun-software.de +// Submitted by Bjoern Henke +taifun-dns.de + +// Tailor Inc. : https://www.tailor.tech +// Submitted by Ryuzo Yamamoto +erp.dev +web.erp.dev + +// Tailscale Inc. : https://www.tailscale.com +// Submitted by David Anderson +ts.net +*.c.ts.net + +// TASK geographical domains : https://task.gda.pl/en/services/for-entrepreneurs/ +gda.pl +gdansk.pl +gdynia.pl +med.pl +sopot.pl + +// Tave Creative Corp : https://tave.com/ +// Submitted by Adrian Ziemkowski +taveusercontent.com + +// tawk.to, Inc : https://www.tawk.to +// Submitted by tawk.to developer team +p.tawk.email +p.tawkto.email + +// Tche.br : https://tche.br +// Submitted by Bruno Lorensi +tche.br + +// team.blue : https://team.blue +// Submitted by Cedric Dubois +site.tb-hosting.com +directwp.eu + +// TechEdge Limited: https://www.nic.uk.cc/ +// Submitted by TechEdge Developer +ec.cc +eu.cc +gu.cc +uk.cc +us.cc + +// Teckids e.V. : https://www.teckids.org +// Submitted by Dominik George +edugit.io +s3.teckids.org + +// Telebit : https://telebit.cloud +// Submitted by AJ ONeal +telebit.app +telebit.io +*.telebit.xyz + +// Teleport : https://goteleport.com +// Submitted by Rob Picard +teleport.sh + +// Thingdust AG : https://thingdust.com/ +// Submitted by Adrian Imboden +*.firenet.ch +*.svc.firenet.ch +reservd.com +thingdustdata.com +cust.dev.thingdust.io +reservd.dev.thingdust.io +cust.disrec.thingdust.io +reservd.disrec.thingdust.io +cust.prod.thingdust.io +cust.testing.thingdust.io +reservd.testing.thingdust.io + +// ticket i/O GmbH : https://ticket.io +// Submitted by Christian Franke +tickets.io + +// Tlon.io : https://tlon.io +// Submitted by Mark Staarink +arvo.network +azimuth.network +tlon.network + +// Tor Project, Inc. : https://torproject.org +// Submitted by Antoine Beaupré +torproject.net +pages.torproject.net + +// TownNews.com : http://www.townnews.com +// Submitted by Dustin Ward +townnews-staging.com + +// TrafficPlex GmbH : https://www.trafficplex.de/ +// Submitted by Phillipp Röll +12hp.at +2ix.at +4lima.at +lima-city.at +12hp.ch +2ix.ch +4lima.ch +lima-city.ch +trafficplex.cloud +de.cool +12hp.de +2ix.de +4lima.de +lima-city.de +1337.pictures +clan.rip +lima-city.rocks +webspace.rocks +lima.zone + +// TransIP : https://www.transip.nl +// Submitted by Rory Breuk and Cedric Dubois +*.transurl.be +*.transurl.eu +site.transip.me +*.transurl.nl + +// Tunnelmole: https://tunnelmole.com +// Submitted by Robbie Cahill +tunnelmole.net + +// TuxFamily : http://tuxfamily.org +// Submitted by TuxFamily administrators +tuxfamily.org + +// Typedream : https://typedream.com +// Submitted by Putri Karunia +typedream.app + +// Typeform : https://www.typeform.com +// Submitted by Typeform +pro.typeform.com + +// Uberspace : https://uberspace.de +// Submitted by Moritz Werner +uber.space + +// UDR Limited : http://www.udr.hk.com +// Submitted by registry +hk.com +inc.hk +ltd.hk +hk.org + +// UK Intis Telecom LTD : https://it.com +// Submitted by ITComdomains +it.com + +// Umso Software Inc. : https://www.umso.com +// Submitted by Alexis Taylor +umso.co + +// Unison Computing, PBC : https://unison.cloud +// Submitted by Simon Højberg +unison-services.cloud + +// United Gameserver GmbH : https://united-gameserver.de +// Submitted by Stefan Schwarz +virtual-user.de +virtualuser.de + +// United States Writing Corporation : https://uswriting.co +// Submitted by Andrew Sampson +obj.ag + +// UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ +// see also: whois -h whois.udr.org.yt help +// Submitted by Atanunu Igbunuroghene +name.pm +sch.tf +biz.wf +sch.wf +org.yt + +// University of Banja Luka : https://unibl.org +// Domains for Republic of Srpska administrative entity. +// Submitted by Marko Ivanovic +rs.ba + +// University of Bielsko-Biala regional domain : http://dns.bielsko.pl/ +// Submitted by Marcin +bielsko.pl + +// urown.net : https://urown.net +// Submitted by Hostmaster +urown.cloud +dnsupdate.info + +// US REGISTRY LLC : http://us.org +// Submitted by Gavin Brown +us.org + +// V.UA Domain Registry: https://www.v.ua/ +// Submitted by Serhii Rostilo +v.ua + +// Val Town, Inc : https://val.town/ +// Submitted by Tom MacWright +val.run +web.val.run + +// Vercel, Inc : https://vercel.com/ +// Submitted by Laurens Duijvesteijn +vercel.app +v0.build +vercel.dev +vusercontent.net +vercel.run +now.sh + +// VeryPositive SIA : http://very.lv +// Submitted by Danko Aleksejevs +2038.io + +// Virtual-Info : https://www.virtual-info.info/ +// Submitted by Adnan RIHAN +v-info.info + +// VistaBlog : https://vistablog.ir/ +// Submitted by Hossein Piri +vistablog.ir + +// Viva Republica, Inc. : https://toss.im/ +// Submitted by Deus Team +deus-canvas.com + +// Voorloper.com : https://voorloper.com +// Submitted by Nathan van Bakel +voorloper.cloud + +// Vultr Objects : https://www.vultr.com/products/object-storage/ +// Submitted by Niels Maumenee +*.vultrobjects.com + +// Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com +// Submitted by Masayuki Note +wafflecell.com + +// Walrus : https://walrus.xyz +// Submitted by Max Spector +wal.app + +// Wasmer: https://wasmer.io +// Submitted by Lorentz Kinde +wasmer.app + +// Webflow, Inc. : https://www.webflow.com +// Submitted by Webflow Security Team +webflow.io +webflowtest.io + +// WebHare bv : https://www.webhare.com/ +// Submitted by Arnold Hendriks +*.webhare.dev + +// WebHotelier Technologies Ltd : https://www.webhotelier.net/ +// Submitted by Apostolos Tsakpinis +bookonline.app +hotelwithflight.com +reserve-online.com +reserve-online.net + +// WebPros International, LLC : https://webpros.com/ +// Submitted by Nicolas Rochelemagne +cprapid.com +pleskns.com +wp2.host +pdns.page +plesk.page +cpanel.site +wpsquared.site + +// WebWaddle Ltd : https://webwaddle.com/ +// Submitted by Merlin Glander +*.wadl.top + +// Western Digital Technologies, Inc : https://www.wdc.com +// Submitted by Jung Jin +remotewd.com + +// Whatbox Inc. : https://whatbox.ca/ +// Submitted by Anthony Ryan +box.ca + +// WIARD Enterprises : https://wiardweb.com +// Submitted by Kidd Hustle +pages.wiardweb.com + +// Wikimedia Foundation : https://wikitech.wikimedia.org +// Submitted by Timo Tijhof +toolforge.org +wmcloud.org +beta.wmcloud.org +wmflabs.org + +// William Harrison : https://wharrison.com.au +// Submitted by William Harrison +vps.hrsn.au +hrsn.dev +is-a.dev +localcert.net + +// Windsurf : https://windsurf.com +// Submitted by Douglas Chen +windsurf.app +windsurf.build + +// WirelessCar : https://wirelesscar.com +// Submitted by Martin Lindberg +drive-platform.com +drive-platform.io + +// WISP : https://wisp.gg +// Submitted by Stepan Fedotov +panel.gg +daemon.panel.gg + +// Wix.com, Inc. : https://www.wix.com +// Submitted by Shahar Talmi / Alon Kochba +base44.app +base44-sandbox.com +wixsite.com +wixstudio.com +editorx.io +wixstudio.io +wix.run + +// Wizard Zines : https://wizardzines.com +// Submitted by Julia Evans +messwithdns.com + +// WoltLab GmbH : https://www.woltlab.com +// Submitted by Tim Düsterhus +woltlab-demo.com +myforum.community +community-pro.de +diskussionsbereich.de +community-pro.net +meinforum.net + +// Woods Valldata : https://www.woodsvalldata.co.uk/ +// Submitted by Chris Whittle +affinitylottery.org.uk +raffleentry.org.uk +weeklylottery.org.uk + +// WP Engine : https://wpengine.com/ +// Submitted by Michael Smith +// Submitted by Brandon DuRette +wpenginepowered.com +js.wpenginepowered.com + +// XenonCloud GbR : https://xenoncloud.net +// Submitted by Julian Uphoff +*.xenonconnect.de +half.host + +// XnBay Technology : http://www.xnbay.com/ +// Submitted by XnBay Developer +xnbay.com +u2.xnbay.com +u2-local.xnbay.com + +// XS4ALL Internet bv : https://www.xs4all.nl/ +// Submitted by Daniel Mostertman +cistron.nl +demon.nl +xs4all.space + +// xTool : https://xtool.com +// Submitted by Echo +xtooldevice.com + +// Yandex.Cloud LLC : https://cloud.yandex.com +// Submitted by Alexander Lodin +yandexcloud.net +storage.yandexcloud.net +website.yandexcloud.net +sourcecraft.site + +// YesCourse Pty Ltd : https://yescourse.com +// Submitted by Atul Bhouraskar +official.academy + +// Yola : https://www.yola.com/ +// Submitted by Stefano Rivera +yolasite.com + +// Yunohost : https://yunohost.org +// Submitted by Valentin Grimaud +ynh.fr +nohost.me +noho.st + +// ZaNiC : http://www.za.net/ +// Submitted by registry +za.net +za.org + +// ZAP-Hosting GmbH & Co. KG : https://zap-hosting.com +// Submitted by Julian Alker +zap.cloud + +// Zeabur : https://zeabur.com/ +// Submitted by Zeabur Team +zeabur.app + +// Zerops : https://zerops.io/ +// Submitted by Zerops Team +*.zerops.app + +// Zine EOOD : https://zine.bg/ +// Submitted by Martin Angelov +bss.design + +// Zitcom A/S : https://www.zitcom.dk +// Submitted by Emil Stahl +basicserver.io +virtualserver.io +enterprisecloud.nu + +// Zone.ID: https://zone.id +// Submitted by Gx1.org +zone.id +nett.to + +// ZoneABC : https://zoneabc.net +// Submitted by ZoneABC Team +zabc.net + +// ===END PRIVATE DOMAINS=== diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix.rb new file mode 100644 index 0000000..cf303ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix.rb @@ -0,0 +1,177 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2026 Simone Carletti + +require_relative "public_suffix/domain" +require_relative "public_suffix/version" +require_relative "public_suffix/errors" +require_relative "public_suffix/rule" +require_relative "public_suffix/list" + +# PublicSuffix is a Ruby domain name parser based on the Public Suffix List. +# +# The [Public Suffix List](https://publicsuffix.org) is a cross-vendor initiative +# to provide an accurate list of domain name suffixes. +# +# The Public Suffix List is an initiative of the Mozilla Project, +# but is maintained as a community resource. It is available for use in any software, +# but was originally created to meet the needs of browser manufacturers. +module PublicSuffix + + DOT = "." + BANG = "!" + STAR = "*" + + # Parses +name+ and returns the {PublicSuffix::Domain} instance. + # + # @example Parse a valid domain + # PublicSuffix.parse("google.com") + # # => # + # + # @example Parse a valid subdomain + # PublicSuffix.parse("www.google.com") + # # => # + # + # @example Parse a fully qualified domain + # PublicSuffix.parse("google.com.") + # # => # + # + # @example Parse a fully qualified domain (subdomain) + # PublicSuffix.parse("www.google.com.") + # # => # + # + # @example Parse an invalid (unlisted) domain + # PublicSuffix.parse("x.yz") + # # => # + # + # @example Parse an invalid (unlisted) domain with strict checking (without applying the default * rule) + # PublicSuffix.parse("x.yz", default_rule: nil) + # # => PublicSuffix::DomainInvalid: `x.yz` is not a valid domain + # + # @example Parse an URL (not supported, only domains) + # PublicSuffix.parse("http://www.google.com") + # # => PublicSuffix::DomainInvalid: http://www.google.com is not expected to contain a scheme + # + # + # @param name [#to_s] The domain name or fully qualified domain name to parse. + # @param list [PublicSuffix::List] The rule list to search, defaults to the default {PublicSuffix::List} + # @param ignore_private [Boolean] + # @return [PublicSuffix::Domain] + # + # @raise [PublicSuffix::DomainInvalid] If domain is not a valid domain. + # @raise [PublicSuffix::DomainNotAllowed] If a rule for +domain+ is found, but the rule doesn't allow +domain+. + def self.parse(name, list: List.default, default_rule: list.default_rule, ignore_private: false) + what = normalize(name) + raise what if what.is_a?(DomainInvalid) + + rule = list.find(what, default: default_rule, ignore_private: ignore_private) + + # rubocop:disable Style/IfUnlessModifier + if rule.nil? + raise DomainInvalid, "`#{what}` is not a valid domain" + end + if rule.decompose(what).last.nil? + raise DomainNotAllowed, "`#{what}` is not allowed according to Registry policy" + end + + # rubocop:enable Style/IfUnlessModifier + + decompose(what, rule) + end + + # Checks whether +domain+ is assigned and allowed, without actually parsing it. + # + # This method doesn't care whether domain is a domain or subdomain. + # The validation is performed using the default {PublicSuffix::List}. + # + # @example Validate a valid domain + # PublicSuffix.valid?("example.com") + # # => true + # + # @example Validate a valid subdomain + # PublicSuffix.valid?("www.example.com") + # # => true + # + # @example Validate a not-listed domain + # PublicSuffix.valid?("example.tldnotlisted") + # # => true + # + # @example Validate a not-listed domain with strict checking (without applying the default * rule) + # PublicSuffix.valid?("example.tldnotlisted") + # # => true + # PublicSuffix.valid?("example.tldnotlisted", default_rule: nil) + # # => false + # + # @example Validate a fully qualified domain + # PublicSuffix.valid?("google.com.") + # # => true + # PublicSuffix.valid?("www.google.com.") + # # => true + # + # @example Check an URL (which is not a valid domain) + # PublicSuffix.valid?("http://www.example.com") + # # => false + # + # + # @param name [#to_s] The domain name or fully qualified domain name to validate. + # @param ignore_private [Boolean] + # @return [Boolean] + def self.valid?(name, list: List.default, default_rule: list.default_rule, ignore_private: false) + what = normalize(name) + return false if what.is_a?(DomainInvalid) + + rule = list.find(what, default: default_rule, ignore_private: ignore_private) + + !rule.nil? && !rule.decompose(what).last.nil? + end + + # Attempt to parse the name and returns the domain, if valid. + # + # This method doesn't raise. Instead, it returns nil if the domain is not valid for whatever reason. + # + # @param name [#to_s] The domain name or fully qualified domain name to parse. + # @param list [PublicSuffix::List] The rule list to search, defaults to the default {PublicSuffix::List} + # @param ignore_private [Boolean] + # @return [String] + def self.domain(name, **options) + parse(name, **options).domain + rescue PublicSuffix::Error + nil + end + + + # private + + def self.decompose(name, rule) + left, right = rule.decompose(name) + + parts = left.split(DOT) + # If we have 0 parts left, there is just a tld and no domain or subdomain + # If we have 1 part left, there is just a tld, domain and not subdomain + # If we have 2 parts left, the last part is the domain, the other parts (combined) are the subdomain + tld = right + sld = parts.empty? ? nil : parts.pop + trd = parts.empty? ? nil : parts.join(DOT) + + Domain.new(tld, sld, trd) + end + + # Pretend we know how to deal with user input. + def self.normalize(name) + name = name.to_s.dup + name.strip! + name.chomp!(DOT) + name.downcase! + + return DomainInvalid.new("Name is blank") if name.empty? + return DomainInvalid.new("Name starts with a dot") if name.start_with?(DOT) + return DomainInvalid.new(format("%s is not expected to contain a scheme", name)) if name.include?("://") + + name + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/domain.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/domain.rb new file mode 100644 index 0000000..f7ca556 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/domain.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2026 Simone Carletti + +module PublicSuffix + + # Domain represents a domain name, composed by a TLD, SLD and TRD. + class Domain + + # Splits a string into the labels, that is the dot-separated parts. + # + # The input is not validated, but it is assumed to be a valid domain name. + # + # @example + # + # name_to_labels('example.com') + # # => ['example', 'com'] + # + # name_to_labels('example.co.uk') + # # => ['example', 'co', 'uk'] + # + # @param name [String, #to_s] The domain name to split. + # @return [Array] + def self.name_to_labels(name) + name.to_s.split(DOT) + end + + + attr_reader :tld, :sld, :trd + + # Creates and returns a new {PublicSuffix::Domain} instance. + # + # @overload initialize(tld) + # Initializes with a +tld+. + # @param [String] tld The TLD (extension) + # @overload initialize(tld, sld) + # Initializes with a +tld+ and +sld+. + # @param [String] tld The TLD (extension) + # @param [String] sld The TRD (domain) + # @overload initialize(tld, sld, trd) + # Initializes with a +tld+, +sld+ and +trd+. + # @param [String] tld The TLD (extension) + # @param [String] sld The SLD (domain) + # @param [String] trd The TRD (subdomain) + # + # @yield [self] Yields on self. + # @yieldparam [PublicSuffix::Domain] self The newly creates instance + # + # @example Initialize with a TLD + # PublicSuffix::Domain.new("com") + # # => # + # + # @example Initialize with a TLD and SLD + # PublicSuffix::Domain.new("com", "example") + # # => # + # + # @example Initialize with a TLD, SLD and TRD + # PublicSuffix::Domain.new("com", "example", "wwww") + # # => # + # + def initialize(*args) + @tld, @sld, @trd = args + yield(self) if block_given? + end + + # Returns a string representation of this object. + # + # @return [String] + def to_s + name + end + + # Returns an array containing the domain parts. + # + # @return [Array] + # + # @example + # + # PublicSuffix::Domain.new("google.com").to_a + # # => [nil, "google", "com"] + # + # PublicSuffix::Domain.new("www.google.com").to_a + # # => [nil, "google", "com"] + # + def to_a + [@trd, @sld, @tld] + end + + # Returns the full domain name. + # + # @return [String] + # + # @example Gets the domain name of a domain + # PublicSuffix::Domain.new("com", "google").name + # # => "google.com" + # + # @example Gets the domain name of a subdomain + # PublicSuffix::Domain.new("com", "google", "www").name + # # => "www.google.com" + # + def name + [@trd, @sld, @tld].compact.join(DOT) + end + + # Returns a domain-like representation of this object + # if the object is a {#domain?}, nil otherwise. + # + # PublicSuffix::Domain.new("com").domain + # # => nil + # + # PublicSuffix::Domain.new("com", "google").domain + # # => "google.com" + # + # PublicSuffix::Domain.new("com", "google", "www").domain + # # => "www.google.com" + # + # This method doesn't validate the input. It handles the domain + # as a valid domain name and simply applies the necessary transformations. + # + # This method returns a FQD, not just the domain part. + # To get the domain part, use #sld (aka second level domain). + # + # PublicSuffix::Domain.new("com", "google", "www").domain + # # => "google.com" + # + # PublicSuffix::Domain.new("com", "google", "www").sld + # # => "google" + # + # @see #domain? + # @see #subdomain + # + # @return [String] + def domain + [@sld, @tld].join(DOT) if domain? + end + + # Returns a subdomain-like representation of this object + # if the object is a {#subdomain?}, nil otherwise. + # + # PublicSuffix::Domain.new("com").subdomain + # # => nil + # + # PublicSuffix::Domain.new("com", "google").subdomain + # # => nil + # + # PublicSuffix::Domain.new("com", "google", "www").subdomain + # # => "www.google.com" + # + # This method doesn't validate the input. It handles the domain + # as a valid domain name and simply applies the necessary transformations. + # + # This method returns a FQD, not just the subdomain part. + # To get the subdomain part, use #trd (aka third level domain). + # + # PublicSuffix::Domain.new("com", "google", "www").subdomain + # # => "www.google.com" + # + # PublicSuffix::Domain.new("com", "google", "www").trd + # # => "www" + # + # @see #subdomain? + # @see #domain + # + # @return [String] + def subdomain + [@trd, @sld, @tld].join(DOT) if subdomain? + end + + # Checks whether self looks like a domain. + # + # This method doesn't actually validate the domain. + # It only checks whether the instance contains + # a value for the {#tld} and {#sld} attributes. + # + # @example + # + # PublicSuffix::Domain.new("com").domain? + # # => false + # + # PublicSuffix::Domain.new("com", "google").domain? + # # => true + # + # PublicSuffix::Domain.new("com", "google", "www").domain? + # # => true + # + # # This is an invalid domain, but returns true + # # because this method doesn't validate the content. + # PublicSuffix::Domain.new("com", nil).domain? + # # => true + # + # @see #subdomain? + # + # @return [Boolean] + def domain? + !(@tld.nil? || @sld.nil?) + end + + # Checks whether self looks like a subdomain. + # + # This method doesn't actually validate the subdomain. + # It only checks whether the instance contains + # a value for the {#tld}, {#sld} and {#trd} attributes. + # If you also want to validate the domain, + # use {#valid_subdomain?} instead. + # + # @example + # + # PublicSuffix::Domain.new("com").subdomain? + # # => false + # + # PublicSuffix::Domain.new("com", "google").subdomain? + # # => false + # + # PublicSuffix::Domain.new("com", "google", "www").subdomain? + # # => true + # + # # This is an invalid domain, but returns true + # # because this method doesn't validate the content. + # PublicSuffix::Domain.new("com", "example", nil).subdomain? + # # => true + # + # @see #domain? + # + # @return [Boolean] + def subdomain? + !(@tld.nil? || @sld.nil? || @trd.nil?) + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/errors.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/errors.rb new file mode 100644 index 0000000..a5d8653 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/errors.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2026 Simone Carletti + +module PublicSuffix + + class Error < StandardError + end + + # Raised when trying to parse an invalid name. + # A name is considered invalid when no rule is found in the definition list. + # + # @example + # + # PublicSuffix.parse("nic.test") + # # => PublicSuffix::DomainInvalid + # + # PublicSuffix.parse("http://www.nic.it") + # # => PublicSuffix::DomainInvalid + # + class DomainInvalid < Error + end + + # Raised when trying to parse a name that matches a suffix. + # + # @example + # + # PublicSuffix.parse("nic.do") + # # => PublicSuffix::DomainNotAllowed + # + # PublicSuffix.parse("www.nic.do") + # # => PublicSuffix::Domain + # + class DomainNotAllowed < DomainInvalid + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/list.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/list.rb new file mode 100644 index 0000000..f3ec170 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/list.rb @@ -0,0 +1,247 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2026 Simone Carletti + +module PublicSuffix + + # A {PublicSuffix::List} is a collection of one + # or more {PublicSuffix::Rule}. + # + # Given a {PublicSuffix::List}, + # you can add or remove {PublicSuffix::Rule}, + # iterate all items in the list or search for the first rule + # which matches a specific domain name. + # + # # Create a new list + # list = PublicSuffix::List.new + # + # # Push two rules to the list + # list << PublicSuffix::Rule.factory("it") + # list << PublicSuffix::Rule.factory("com") + # + # # Get the size of the list + # list.size + # # => 2 + # + # # Search for the rule matching given domain + # list.find("example.com") + # # => # + # list.find("example.org") + # # => nil + # + # You can create as many {PublicSuffix::List} you want. + # The {PublicSuffix::List.default} rule list is used + # to tokenize and validate a domain. + # + class List + + DEFAULT_LIST_PATH = File.expand_path("../../data/list.txt", __dir__) + + # Gets the default rule list. + # + # Initializes a new {PublicSuffix::List} parsing the content + # of {PublicSuffix::List.default_list_content}, if required. + # + # @return [PublicSuffix::List] + def self.default(**options) + @default ||= parse(File.read(DEFAULT_LIST_PATH), **options) + end + + # Sets the default rule list to +value+. + # + # @param value [PublicSuffix::List] the new list + # @return [PublicSuffix::List] + def self.default=(value) + @default = value + end + + # Parse given +input+ treating the content as Public Suffix List. + # + # See http://publicsuffix.org/format/ for more details about input format. + # + # @param input [#each_line] the list to parse + # @param private_domains [Boolean] whether to ignore the private domains section + # @return [PublicSuffix::List] + def self.parse(input, private_domains: true) + comment_token = "//" + private_token = "===BEGIN PRIVATE DOMAINS===" + section = nil # 1 == ICANN, 2 == PRIVATE + + new do |list| + input.each_line do |line| + line.strip! + case # rubocop:disable Style/EmptyCaseCondition + + # skip blank lines + when line.empty? + next + + # include private domains or stop scanner + when line.include?(private_token) + break if !private_domains + + section = 2 + + # skip comments + when line.start_with?(comment_token) # rubocop:disable Lint/DuplicateBranch + next + + else + list.add(Rule.factory(line, private: section == 2)) + + end + end + end + end + + + # Initializes an empty {PublicSuffix::List}. + # + # @yield [self] Yields on self. + # @yieldparam [PublicSuffix::List] self The newly created instance. + def initialize + @rules = {} + yield(self) if block_given? + end + + + # Checks whether two lists are equal. + # + # List one is equal to two, if two is an instance of + # {PublicSuffix::List} and each +PublicSuffix::Rule::*+ + # in list one is available in list two, in the same order. + # + # @param other [PublicSuffix::List] the List to compare + # @return [Boolean] + def ==(other) + return false unless other.is_a?(List) + + equal?(other) || @rules == other.rules + end + alias eql? == + + # Iterates each rule in the list. + def each(&block) + Enumerator.new do |y| + @rules.each do |key, node| + y << entry_to_rule(node, key) + end + end.each(&block) + end + + + # Adds the given object to the list and optionally refreshes the rule index. + # + # @param rule [PublicSuffix::Rule::*] the rule to add to the list + # @return [self] + def add(rule) + @rules[rule.value] = rule_to_entry(rule) + self + end + alias << add + + # Gets the number of rules in the list. + # + # @return [Integer] + def size + @rules.size + end + + # Checks whether the list is empty. + # + # @return [Boolean] + def empty? + @rules.empty? + end + + # Removes all rules. + # + # @return [self] + def clear + @rules.clear + self + end + + # Finds and returns the rule corresponding to the longest public suffix for the hostname. + # + # @param name [#to_s] the hostname + # @param default [PublicSuffix::Rule::*] the default rule to return in case no rule matches + # @return [PublicSuffix::Rule::*] + def find(name, default: default_rule, **options) + rule = select(name, **options).inject do |l, r| + return r if r.instance_of?(Rule::Exception) + + l.length > r.length ? l : r + end + rule || default + end + + # Selects all the rules matching given hostame. + # + # If `ignore_private` is set to true, the algorithm will skip the rules that are flagged as + # private domain. Note that the rules will still be part of the loop. + # If you frequently need to access lists ignoring the private domains, + # you should create a list that doesn't include these domains setting the + # `private_domains: false` option when calling {.parse}. + # + # Note that this method is currently private, as you should not rely on it. Instead, + # the public interface is {#find}. The current internal algorithm allows to return all + # matching rules, but different data structures may not be able to do it, and instead would + # return only the match. For this reason, you should rely on {#find}. + # + # @param name [#to_s] the hostname + # @param ignore_private [Boolean] + # @return [Array] + def select(name, ignore_private: false) + name = name.to_s + + parts = name.split(DOT).reverse! + index = 0 + query = parts[index] + rules = [] + + loop do + match = @rules[query] + rules << entry_to_rule(match, query) if !match.nil? && (ignore_private == false || match.private == false) + + index += 1 + break if index >= parts.size + + query = parts[index] + DOT + query + end + + rules + end + private :select + + # Gets the default rule. + # + # @see PublicSuffix::Rule.default_rule + # + # @return [PublicSuffix::Rule::*] + def default_rule + PublicSuffix::Rule.default + end + + + protected + + attr_reader :rules + + + private + + def entry_to_rule(entry, value) + entry.type.new(value: value, length: entry.length, private: entry.private) + end + + def rule_to_entry(rule) + Rule::Entry.new(rule.class, rule.length, rule.private) + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/rule.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/rule.rb new file mode 100644 index 0000000..27c04ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/rule.rb @@ -0,0 +1,350 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2026 Simone Carletti + +module PublicSuffix + + # A Rule is a special object which holds a single definition + # of the Public Suffix List. + # + # There are 3 types of rules, each one represented by a specific + # subclass within the +PublicSuffix::Rule+ namespace. + # + # To create a new Rule, use the {PublicSuffix::Rule#factory} method. + # + # PublicSuffix::Rule.factory("ar") + # # => # + # + module Rule + + # @api internal + Entry = Struct.new(:type, :length, :private) # rubocop:disable Lint/StructNewOverride + + # = Abstract rule class + # + # This represent the base class for a Rule definition + # in the {Public Suffix List}[https://publicsuffix.org]. + # + # This is intended to be an Abstract class + # and you shouldn't create a direct instance. The only purpose + # of this class is to expose a common interface + # for all the available subclasses. + # + # * {PublicSuffix::Rule::Normal} + # * {PublicSuffix::Rule::Exception} + # * {PublicSuffix::Rule::Wildcard} + # + # ## Properties + # + # A rule is composed by 4 properties: + # + # value - A normalized version of the rule name. + # The normalization process depends on rule tpe. + # + # Here's an example + # + # PublicSuffix::Rule.factory("*.google.com") + # # + # + # ## Rule Creation + # + # The best way to create a new rule is passing the rule name + # to the PublicSuffix::Rule.factory method. + # + # PublicSuffix::Rule.factory("com") + # # => PublicSuffix::Rule::Normal + # + # PublicSuffix::Rule.factory("*.com") + # # => PublicSuffix::Rule::Wildcard + # + # This method will detect the rule type and create an instance + # from the proper rule class. + # + # ## Rule Usage + # + # A rule describes the composition of a domain name and explains how to tokenize + # the name into tld, sld and trd. + # + # To use a rule, you first need to be sure the name you want to tokenize + # can be handled by the current rule. + # You can use the #match? method. + # + # rule = PublicSuffix::Rule.factory("com") + # + # rule.match?("google.com") + # # => true + # + # rule.match?("google.com") + # # => false + # + # Rule order is significant. A name can match more than one rule. + # See the {Public Suffix Documentation}[http://publicsuffix.org/format/] + # to learn more about rule priority. + # + # When you have the right rule, you can use it to tokenize the domain name. + # + # rule = PublicSuffix::Rule.factory("com") + # + # rule.decompose("google.com") + # # => ["google", "com"] + # + # rule.decompose("www.google.com") + # # => ["www.google", "com"] + # + # @abstract + # + class Base + + # @return [String] the rule definition + attr_reader :value + + # @return [String] the length of the rule + attr_reader :length + + # @return [Boolean] true if the rule is a private domain + attr_reader :private + + + # Initializes a new rule from the content. + # + # @param content [String] the content of the rule + # @param private [Boolean] + def self.build(content, private: false) + new(value: content, private: private) + end + + # Initializes a new rule. + # + # @param value [String] + # @param private [Boolean] + def initialize(value:, length: nil, private: false) + @value = value.to_s + @length = length || (@value.count(DOT) + 1) + @private = private + end + + # Checks whether this rule is equal to other. + # + # @param other [PublicSuffix::Rule::*] The rule to compare + # @return [Boolean] true if this rule and other are instances of the same class + # and has the same value, false otherwise. + def ==(other) + equal?(other) || (self.class == other.class && value == other.value) + end + alias eql? == + + # Checks if this rule matches +name+. + # + # A domain name is said to match a rule if and only if + # all of the following conditions are met: + # + # - When the domain and rule are split into corresponding labels, + # that the domain contains as many or more labels than the rule. + # - Beginning with the right-most labels of both the domain and the rule, + # and continuing for all labels in the rule, one finds that for every pair, + # either they are identical, or that the label from the rule is "*". + # + # @see https://publicsuffix.org/list/ + # + # @example + # PublicSuffix::Rule.factory("com").match?("example.com") + # # => true + # PublicSuffix::Rule.factory("com").match?("example.net") + # # => false + # + # @param name [String] the domain name to check + # @return [Boolean] + def match?(name) + # NOTE: it works because of the assumption there are no + # rules like foo.*.com. If the assumption is incorrect, + # we need to properly walk the input and skip parts according + # to wildcard component. + diff = name.chomp(value) + diff.empty? || diff.end_with?(DOT) + end + + # @abstract + def parts + raise NotImplementedError + end + + # @abstract + # @param domain [#to_s] The domain name to decompose + # @return [Array] + def decompose(*) + raise NotImplementedError + end + + end + + # Normal represents a standard rule (e.g. com). + class Normal < Base + + # Gets the original rule definition. + # + # @return [String] The rule definition. + def rule + value + end + + # Decomposes the domain name according to rule properties. + # + # @param domain [#to_s] The domain name to decompose + # @return [Array] The array with [trd + sld, tld]. + def decompose(domain) + suffix = parts.join('\.') + matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) + matches ? matches[1..2] : [nil, nil] + end + + # dot-split rule value and returns all rule parts + # in the order they appear in the value. + # + # @return [Array] + def parts + @value.split(DOT) + end + + end + + # Wildcard represents a wildcard rule (e.g. *.co.uk). + class Wildcard < Base + + # Initializes a new rule from the content. + # + # @param content [String] the content of the rule + # @param private [Boolean] + def self.build(content, private: false) + new(value: content.to_s[2..], private: private) + end + + # Initializes a new rule. + # + # @param value [String] + # @param length [Integer] + # @param private [Boolean] + def initialize(value:, length: nil, private: false) + super + length or @length += 1 # * counts as 1 + end + + # Gets the original rule definition. + # + # @return [String] The rule definition. + def rule + value == "" ? STAR : STAR + DOT + value + end + + # Decomposes the domain name according to rule properties. + # + # @param domain [#to_s] The domain name to decompose + # @return [Array] The array with [trd + sld, tld]. + def decompose(domain) + suffix = ([".*?"] + parts).join('\.') + matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) + matches ? matches[1..2] : [nil, nil] + end + + # dot-split rule value and returns all rule parts + # in the order they appear in the value. + # + # @return [Array] + def parts + @value.split(DOT) + end + + end + + # Exception represents an exception rule (e.g. !parliament.uk). + class Exception < Base + + # Initializes a new rule from the content. + # + # @param content [#to_s] the content of the rule + # @param private [Boolean] + def self.build(content, private: false) + new(value: content.to_s[1..], private: private) + end + + # Gets the original rule definition. + # + # @return [String] The rule definition. + def rule + BANG + value + end + + # Decomposes the domain name according to rule properties. + # + # @param domain [#to_s] The domain name to decompose + # @return [Array] The array with [trd + sld, tld]. + def decompose(domain) + suffix = parts.join('\.') + matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) + matches ? matches[1..2] : [nil, nil] + end + + # dot-split rule value and returns all rule parts + # in the order they appear in the value. + # The leftmost label is not considered a label. + # + # See http://publicsuffix.org/format/: + # If the prevailing rule is a exception rule, + # modify it by removing the leftmost label. + # + # @return [Array] + def parts + @value.split(DOT)[1..] + end + + end + + + # Takes the +name+ of the rule, detects the specific rule class + # and creates a new instance of that class. + # The +name+ becomes the rule +value+. + # + # @example Creates a Normal rule + # PublicSuffix::Rule.factory("ar") + # # => # + # + # @example Creates a Wildcard rule + # PublicSuffix::Rule.factory("*.ar") + # # => # + # + # @example Creates an Exception rule + # PublicSuffix::Rule.factory("!congresodelalengua3.ar") + # # => # + # + # @param content [#to_s] the content of the rule + # @return [PublicSuffix::Rule::*] A rule instance. + def self.factory(content, private: false) + case content.to_s[0, 1] + when STAR + Wildcard + when BANG + Exception + else + Normal + end.build(content, private: private) + end + + # The default rule to use if no rule match. + # + # The default rule is "*". From https://publicsuffix.org/list/: + # + # > If no rules match, the prevailing rule is "*". + # + # @return [PublicSuffix::Rule::Wildcard] The default rule. + def self.default + factory(STAR) + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/version.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/version.rb new file mode 100644 index 0000000..2ceedc6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-7.0.5/lib/public_suffix/version.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2026 Simone Carletti + +module PublicSuffix + + # @return [String] the current library version + VERSION = "7.0.5" + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/History.rdoc b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/History.rdoc new file mode 100644 index 0000000..51e9f71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/History.rdoc @@ -0,0 +1,2454 @@ +=== 13.2.1 + +* Suppressed "internal:array:52:in 'Array#each'" from backtrace by @hsbt in #554 +* Bump actions/configure-pages from 4 to 5 by @dependabot in #553 + +=== 13.2.0 + +* Fix rule example to be correct by @zenspider in #525 +* Switch to use test-unit by @hsbt in #536 +* Removed redundant block by @hsbt in #537 +* Use Struct instead of OpenStruct. by @hsbt in #545 +* Accept FileList object as directory task's target by @gemmaro in #530 +* Fix exception when exception has nil backtrace by @janbiedermann in #451 +* Add TruffleRuby on CI by @andrykonchin in #551 + +=== 13.1.0 + +* Added dependabot.yml for actions by @hsbt in #416 +* Add Ruby 3.1 to the CI matrix by @petergoldstein in #415 +* (Performance) Remove unnecessary I/O syscalls for FileTasks by @da2x in #393 +* Skip test failure with JRuby by @hsbt in #418 +* Remove bin/rdoc by @tnir in #421 +* Remove bin/rake by @tnir in #422 +* Remove bin/bundle by @tnir in #425 +* Apply RuboCop linting for Ruby 2.3 by @tnir in #423 +* Update rubocop to work with Ruby 2.4 compatible by @tnir in #424 +* chore: fix typo in comments by @tnir in #429 +* Use 'test' as workflow name on Actions by @tnir in #427 +* docs: update CONTRIBUTING.rdoc by @tnir in #428 +* Add RuboCop job to Actions by @tnir in #426 +* Lock minitest-5.15.0 for Ruby 2.2 by @hsbt in #442 +* Eagerly require set in thread_pool.rb by @jeremyevans in #440 +* Avoid creating an unnecessary thread pool by @jeremyevans in #441 +* Add credit for maintenance in Rake 12/13 by @tnir in #443 +* Sh fully echoes commands which error exit by @MarkDBlackwell in #147 +* Correct RuboCop offenses by @deivid-rodriguez in #444 +* [StepSecurity] ci: Harden GitHub Actions by @step-security-bot in #450 +* Add ruby 3.2 to test matrix by @hanneskaeufler in #458 +* Missing 'do' on example by @zzak in #467 +* Try to use dependabot automerge by @hsbt in #470 +* Rewrite auto-merge feature for dependabot by @hsbt in #471 +* Update bundler in Dependabot by @ono-max in #472 +* Fix grammar in help text by @mebezac in #381 +* Try to use ruby/ruby/.github/workflows/ruby_versions.yml@master by @hsbt in #475 +* Use GitHub Pages Action for generating rdoc page by @hsbt in #477 +* Support #detailed_message when task failed by @ksss in #486 +* Debug at stop when task fail by @ksss in #489 +* Drop to support Ruby 2.2 by @hsbt in #492 +* Bump up setup-ruby by @hsbt in #497 +* Update development dependencies by @hsbt in #505 + +=== 13.0.6 + +* Additional fix for #389 + Pull request #390 by hsbt + +=== 13.0.5 + +* Fixed the regression of #388 + Pull request #389 by hsbt + +=== 13.0.4 + +* Fix rake test loader swallowing useful error information. + Pull request #367 by deivid-rodriguez +* Add -C/--directory option the same as GNU make. + Pull request #376 by nobu + +=== 13.0.3 + +* Fix breaking change of execution order on TestTask. + Pull request #368 by ysakasin + +=== 13.0.2 + +==== Enhancements + +* Fix tests to work with current FileUtils + Pull Request #358 by jeremyevans +* Simplify default rake test loader + Pull Request #357 by deivid-rodriguez +* Update rdoc + Pull Request #366 by bahasalien +* Update broken links to rake articles from Avdi in README + Pull Request #360 by svl7 + +=== 13.0.1 + +==== Bug fixes + +* Fixed bug: Reenabled task raises previous exception on second invokation + Pull Request #271 by thorsteneckel +* Fix an incorrectly resolved arg pattern + Pull Request #327 by mjbellantoni + +=== 13.0.0 + +==== Enhancements + +* Follows recent changes on keyword arguments in ruby 2.7. + Pull Request #326 by nobu +* Make `PackageTask` be able to omit parent directory while packing files + Pull Request #310 by tonytonyjan +* Add order only dependency + Pull Request #269 by take-cheeze + +==== Compatibility changes + +* Drop old ruby versions(< 2.2) + +=== 12.3.3 + +==== Bug fixes + +* Use the application's name in error message if a task is not found. + Pull Request #303 by tmatilai + +==== Enhancements: + +* Use File.open explicitly. + +=== 12.3.2 + +==== Bug fixes + +* Fixed test fails caused by 2.6 warnings. + Pull Request #297 by hsbt + +==== Enhancements: + +* Rdoc improvements. + Pull Request #293 by colby-swandale +* Improve multitask performance. + Pull Request #273 by jsm +* Add alias `prereqs`. + Pull Request #268 by take-cheeze + +=== 12.3.1 + +==== Bug fixes + +* Support did_you_mean >= v1.2.0 which has a breaking change on formatters. + Pull request #262 by FUJI Goro. + +==== Enhancements: + +* Don't run task if it depends on already invoked but failed task. + Pull request #252 by Gonzalo Rodriguez. +* Make space trimming consistent for all task arguments. + Pull request #259 by Gonzalo Rodriguez. +* Removes duplicated inclusion of Rake::DSL in tests. + Pull request #254 by Gonzalo Rodriguez. +* Re-raise a LoadError that didn't come from require in the test loader. + Pull request #250 by Dylan Thacker-Smith. + +=== 12.3.0 + +==== Compatibility Changes + +* Bump `required_ruby_version` to Ruby 2.0.0. Rake has already + removed support for Ruby 1.9.x. + +==== Enhancements: + +* Support `test-bundled-gems` task on ruby core. + +=== 12.2.1 + +==== Bug fixes + +* Fixed to break Capistrano::Application on capistrano3. + +=== 12.2.0 + +==== Enhancements: + +* Make rake easier to use as a library + Pull request #211 by @drbrain +* Fix quadratic performance in FileTask#out_of_date? + Pull request #224 by @doudou +* Clarify output when printing nested exception traces + Pull request #232 by @urbanautomaton + +==== Bug fixes + +* Account for a file that match 2 or more patterns. + Pull request #231 by @styd + +=== 12.1.0 + +==== Enhancements: + +* Added did_you_mean feature for invalid rake task. + Pull request #221 by @xtina-starr +* Enabled to dependency chained by extensions. Pull request #39 by Petr Skocik. +* Make all of string literals to frozen objects on Ruby 2.4 or later. + +==== Bug fixes + +* Typo fixes in rakefile.rdoc. Pull request #180 by Yuta Kurotaki. +* Fix unexpected behavior of file task with dryrun option. + Pull request #183 by @aycabta. +* Make LoadError from running tests more obvious. Pull request #195 + by Eric Hodel. +* Fix unexpected TypeError with hash style option. Pull request #202 + by Kuniaki IGARASHI. + +=== 12.0.0 + +==== Compatibility Changes + +* Removed arguments on clear #157 by Jesse Bowes +* Removed `rake/contrib` packages. These are extracted to `rake-contrib` gem. +* Removed deprecated method named `last\_comment`. + +==== Enhancements: + +* Re-use trace option on `cleanup` task. #164 by Brian Henderson +* Actions adore keyword arguments #174 by Josh Cheek +* Rake::TaskArguments#key? alias of #has_key? #175 by Paul Annesley + +=== 11.3.0 / 2016-09-20 + +==== Enhancements: + +* Remove to reference `Fixnum` constant. Pull request #160 by nobu + +=== 11.2.2 / 2016-06-12 + +==== Bug fixes + +* Fix unexpected behavior with multiple dependencies on Rake::TestTask + +=== 11.2.1 / 2016-06-12 + +==== Bug fixes + +* Fix regression of dependencies handling on Rake::TestTask. Report #139 + +=== 11.2.0 / 2016-06-11 + +==== Bug fixes + +* Fix unexpected cut-out behavior on task description using triple dots + and exclamation. Report #106 from Stephan Kämper and Pull request #134 by Lee +* Fix empty argument assignment with `with_defaults` option. Pull request #135 + by bakunyo +* Ignore to use `hwprefs` on Darwin platform. Use sysctl now. Report #128 + +==== Enhancements + +* Spawn options for sh Pull equest #138 by Eric Hodel. +* Allow to specify dependencies(prerequisites) for Rake::TestTask + Pull request #117 by Tim Maslyuchenko +* Use Bundler task instead of hoe for gem release. +* Remove explicitly load to rubygems for Ruby 1.8. +* Unify to declare `Rake::VERSION`. +* Support xz format for PackageTask. + +=== 11.1.2 / 2016-03-28 + +==== Bug fixes + +* Remove `-W` option when Rake::TestTask#verbose enabled. It's misunderstanding + specification change with Rake 11. Partly revert #67 + +=== 11.1.1 / 2016-03-14 + +==== Bug fixes + +* Use `-W` instead of `--verbose` when Rake::TestTask#verbose enabled. + JRuby doesn't have `--verbose` option. + +=== 11.1.0 / 2016-03-11 + +==== Compatibility Changes + +* Revert to remove `last\_comment`. It will remove Rake 12. + +=== 11.0.1 / 2016-03-09 + +==== Bug fixes + +* Fixed packaging manifest. + +=== 11.0.0 / 2016-03-09 + +==== Bug fixes + +* Correctly handle bad encoding in exception messages. Pull request #113 + by Tomer Brisker +* Fix verbose option at TestTask. Pull request #67 by Mike Blumtritt + +==== Enhancements + +* Make FileList#exclude more analogous to FileList#include. +* Use IO.open instead of Open3.popen3 for CPU counter. +* Make Rake::Task#already_invoked publicly accessible. + Pull request #93 by Joe Rafaniello +* Lookup prerequisites with same name outside of scope instead of + matching self. Pull request #96 by Sandy Vanderbleek +* Make FileList#pathmap behave like String#pathmap. + Pull request #61 by Daniel Tamai +* Add fetch method to task arguments. + Pull request #12 by Chris Keathley +* Use ruby warnings by default. Pull request #97 by Harold Giménez + +==== Compatibility Changes + +* Removed to support Ruby 1.8.x +* Removed constant named `RAKEVERSION` +* Removed Rake::AltSystem +* Removed Rake::RubyForgePublisher +* Removed Rake::TaskManager#last\_comment. Use last\_description. +* Removed Rake::TaskLib#paste +* Removed Top-level SshDirPublisher, SshFreshDirPublisher, SshFilePublisher + and CompositePublisher from lib/rake/contrib/publisher.rb +* Removed "rake/runtest.rb" + +=== 10.5.0 / 2016-01-13 + +==== Enhancements + +* Removed monkey patching for Ruby 1.8. Pull request #46 by Pablo Herrero. +* Inheritance class of Rake::FileList returns always self class. + Pull request #74 by Thomas Scholz + +=== 10.4.2 / 2014-12-02 + +==== Bug fixes + +* Rake no longer edits ARGV. This allows you to re-exec rake from a rake + task. Pull requset #9 by Matt Palmer. +* Documented how Rake::DSL#desc handles sentences in task descriptions. + Issue #7 by Raza Sayed. +* Fixed test error on 1.9.3 with legacy RubyGems. Issue #8 by Matt Palmer. +* Deleted duplicated History entry. Pull request #10 by Yuji Yamamoto. + +=== 10.4.1 / 2014-12-01 + +==== Bug fixes + +* Reverted fix for #277 as it caused numerous issues for rake users. + rails/spring issue #366 by Gustavo Dutra. + +=== 10.4.0 / 2014-11-22 + +==== Enhancements + +* Upgraded to minitest 5. Pull request #292 by Teo Ljungberg. +* Added support for Pathname in rake tasks. Pull request #271 by Randy + Coulman. +* Rake now ignores falsy dependencies which allows for easier programmatic + creation of tasks. Pull request #273 by Manav. +* Rake no longer edits ARGV. This allows you to re-exec rake from a rake + task. Issue #277 by Matt Palmer. +* Etc.nprocessors is used for counting the number of CPUs. + +==== Bug fixes + +* Updated rake manpage. Issue #283 by Nathan Long, pull request #291 by + skittleys. +* Add Rake::LATE to allow rebuilding of files that depend on deleted files. + Bug #286, pull request #287 by David Grayson. +* Fix relinking of files when repackaging. Bug #276 by Muenze. +* Fixed some typos. Pull request #280 by Jed Northridge. +* Try counting CPUs via cpuinfo if host_os was not matched. Pull request + #282 by Edouard B. + +=== 10.3.2 / 2014-05-15 + +==== Bug fixes + +* Rake no longer infinitely loops when showing exception causes that refer to + each other. Bug #272 by Chris Bandy. +* Fixed documentation typos. Bug #275 by Jake Worth. + +=== 10.3.1 / 2014-04-17 + +==== Bug fixes + +* Really stop reporting an error when cleaning already-deleted files. Pull + request #269 by Randy Coulman +* Fixed infinite loop when cleaning already-deleted files on windows. + +=== 10.3 / 2014-04-15 + +==== Enhancements + +* Added --build-all option to rake which treats all file prerequisites as + out-of-date. Pull request #254 by Andrew Gilbert. +* Added Rake::NameSpace#scope. Issue #263 by Jon San Miguel. + +==== Bug fixes + +* Suppress org.jruby package files in rake error messages for JRuby users. + Issue #213 by Charles Nutter. +* Fixed typo, removed extra "h". Pull request #267 by Hsing-Hui Hsu. +* Rake no longer reports an error when cleaning already-deleted files. Pull + request #266 by Randy Coulman. +* Consume stderr while determining CPU count to avoid hang. Issue #268 by + Albert Sun. + +=== 10.2.2 / 2014-03-27 + +==== Bug fixes + +* Restored Ruby 1.8.7 compatibility + +=== 10.2.1 / 2014-03-25 + +==== Bug fixes + +* File tasks including a ':' are now top-level tasks again. Issue #262 by + Josh Holtrop. +* Use sysctl for CPU count for all BSDs. Pull request #261 by Joshua Stein. +* Fixed CPU detection for unknown platforms. + +=== 10.2.0 / 2014-03-24 + +==== Enhancements + +* Rake now requires Ruby 1.9 or newer. For me, this is a breaking change, but + it seems that Jim planned to release it with Rake 10.2. See also pull + request #247 by Philip Arndt. +* Rake now allows you to declare tasks under a namespace like: + + task 'a:b' do ... end + + Pull request #232 by Judson Lester. +* Task#source defaults to the first prerequisite in non-rule tasks. Pull + request #215 by Avdi Grimm. +* Rake now automatically rebuilds and reloads imported files. Pull request + #209 by Randy Coulman. +* The rake task arguments can contain escaped commas. Pull request #214 by + Filip Hrbek. +* Rake now prints the exception class on errors. Patch #251 by David Cornu. + +==== Bug fixes + +* Fixed typos. Pull request #256 by Valera Rozuvan, #250 via Jake Worth, #260 + by Zachary Scott. +* Fixed documentation for calling tasks with arguments. Pull request #235 by + John Varghese. +* Clarified `rake -f` usage message. Pull request #252 by Marco Pfatschbacher. +* Fixed a test failure on windows. Pull request #231 by Hiroshi Shirosaki. +* Fixed corrupted rake.1.gz. Pull request #225 by Michel Boaventura. +* Fixed bug in can\_detect\_signals? in test. Patch from #243 by Alexey + Borzenkov. + +=== 10.1.1 + +* Use http://github.com/jimweirich/rake instead of http://rake.rubyforge.org for + canonical project url. + +=== 10.1.0 + +==== Changes + +===== New Features + +* Add support for variable length task argument lists. If more actual + arguments are supplied than named arguments, then the extra + arguments values will be in args.extras. + +* Application name is not displayed in the help banner. (Previously + "rake" was hardcoded, now rake-based applications can display their + own names). + +===== Bug Fixes + +Bug fixes include: + +* Fix backtrace suppression issues. + +* Rules now explicit get task arguments passed to them. + +* Rename FileList#exclude? to FileList#exclude\_from\_list? to avoid + conflict with new Rails method. + +* Clean / Clobber tasks now report failure to remove files. + +* Plus heaps of internal code cleanup. + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. +The following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Michael Nikitochkin (general code cleanup) +* Vipul A M (general code cleanup) +* Dennis Bell (variable length task argument lists) +* Jacob Swanner (rules arguments) +* Rafael Rosa Fu (documentation typo) +* Stuart Nelson (install.rb fixes) +* Lee Hambley (application name in help banner) + +-- Jim Weirich + +=== 10.0.3 + + "Jim, when will Rake reach version 1.0?" + +Over the past several years I've been asked that question at +conferences, panels and over twitter. Due to historical reasons (or +maybe just plain laziness) Rake has (incorrectly) been treating the +second digit of the version as the major release number. So in my head +Rake was already at version 9. + +Well, it's time to fix things. This next version of Rake drops old, +crufty, backwards compatibility hacks such as top level constants, DSL +methods defined in Object and numerous other features that are just no +longer desired. It's also time to drop the leading zero from the +version number as well and call this new version of rake what it +really is: Version 10. + +So, welcome to Rake 10.0! + +Rake 10 is actually feature identical to the latest version of Rake 9 +(that would be the version spelled 0.9.3), *except* that Rake 10 drops +all the sundry deprecated features that have accumulated over the years. + +If your Rakefile is up to date and current with all the new features +of Rake 10, you are ready to go. If your Rakefile still uses a few +deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same +feature set. Just be aware that future features will be in Rake 10 +family line. + +==== Changes + +As mentioned above, there are no new features in Rake 10. However, +there are a number of features missing: + +* Classic namespaces are now gone. Rake is no longer able to reflect + the options settings in the global variables ($rakefile, $show\_tasks, + $show\_prereqs, $trace, $dryrun and $silent). The + --classic-namespace option is no longer supported. + +* Global constants are no longer supported. This includes + Task, FileTask, FileCreationTask and + RakeApp). The constant missing hook to warn about using + global rake constants has been removed. + +* The Rake DSL methods (task, file, directory, etc) are in their own + module (Rake::DSL). The stub versions of these methods (that printed + warnings) in Object have been removed. However, the DSL methods are + added to the top-level main object. Since main is + not in the inheritance tree, the presence of the DSL methods in main + should be low impact on other libraries. + + If you want to use the Rake DSL commands from your own code, just + include Rake::DSL into your own classes and modules. + +* The deprecated syntax for task arguments (the one using + :needs) has been removed. + +* The --reduce-compat flag has been removed (it's not needed + anymore). + +* The deprecated rake/sys.rb library has been removed. + +* The deprecated rake/rdoctask.rb library has been removed. + RDoc supplies its own rake task now. + +* The deprecated rake/gempackagetask.rb library has been + removed. Gem supplies its own package task now. + +There is one small behavioral change: + +* Non-file tasks now always report the current time as their time + stamp. This is different from the previous behavior where non-file + tasks reported current time only if there were no prerequisites, and + the max prerequisite timestamp otherwise. This lead to inconsistent + and surprising behavior when adding prerequisites to tasks that in + turn were prequisites to file tasks. The new behavior is more + consistent and predictable. + +==== Changes (from 0.9.3, 0.9.4, 0.9.5) + +Since Rake 10 includes the changes from the last version of Rake 9, +we'll repeat the changes for versions 0.9.3 through 0.9.5 here. + +===== New Features (in 0.9.3) + +* Multitask tasks now use a thread pool. Use -j to limit the number of + available threads. + +* Use -m to turn regular tasks into multitasks (use at your own risk). + +* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to + programatically add rake task libraries. + +* You can specific backtrace suppression patterns (see + --suppress-backtrace) + +* Directory tasks can now take prerequisites and actions + +* Use --backtrace to request a full backtrace without the task trace. + +* You can say "--backtrace=stdout" and "--trace=stdout" to route trace + output to standard output rather than standard error. + +* Optional 'phony' target (enable with 'require 'rake/phony'") for + special purpose builds. + +* Task#clear now clears task comments as well as actions and + prerequisites. Task#clear_comment will specifically target comments. + +* The --all option will force -T and -D to consider all the tasks, + with and without descriptions. + +===== Bug Fixes (in 0.9.3) + +* Semi-colons in windows rakefile paths now work. + +* Improved Control-C support when invoking multiple test suites. + +* egrep method now reads files in text mode (better support for + Windows) + +* Better deprecation line number reporting. + +* The -W option now works with all tasks, whether they have a + description or not. + +* File globs in rake should not be sorted alphabetically, independent + of file system and platform. + +* Numerous internal improvements. + +* Documentation typos and fixes. + +===== Bug Fixes (in 0.9.4) + +* Exit status with failing tests is not correctly set to non-zero. + +* Simplified syntax for phony task (for older versions of RDoc). + +* Stand alone FileList usage gets glob function (without loading in + extra dependencies) + +===== Bug Fixes (in 0.9.5) + +* --trace and --backtrace no longer swallow following task names. + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 10.0.2 + +==== Changes + +===== Bug Fixes + +* --trace and --backtrace no longer swallow following task names. + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 10.0.1 + +==== Changes + +===== Bug Fixes + +* Exit status with failing tests is not correctly set to non-zero. + +* Simplified syntax for phony task (for older versions of RDoc). + +* Stand alone FileList usage gets glob function (without loading in + extra dependencies) + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 10.0.0 + + "Jim, when will Rake reach version 1.0?" + +Over the past several years I've been asked that question at +conferences, panels and over twitter. Due to historical reasons (or +maybe just plain laziness) Rake has (incorrectly) been treating the +second digit of the version as the major release number. So in my head +Rake was already at version 9. + +Well, it's time to fix things. This next version of Rake drops old, +crufty, backwards compatibility hacks such as top level constants, DSL +methods defined in Object and numerous other features that are just no +longer desired. It's also time to drop the leading zero from the +version number as well and call this new version of rake what it +really is: Version 10. + +So, welcome to Rake 10.0! + +Rake 10 is actually feature identical to the latest version of Rake 9 +(that would be the version spelled 0.9.3), *except* that Rake 10 drops +all the sundry deprecated features that have accumulated over the years. + +If your Rakefile is up to date and current with all the new features +of Rake 10, you are ready to go. If your Rakefile still uses a few +deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same +feature set. Just be aware that future features will be in Rake 10 +family line. + +==== Changes in 10.0 + +As mentioned above, there are no new features in Rake 10. However, +there are a number of features missing: + +* Classic namespaces are now gone. Rake is no longer able to reflect + the options settings in the global variables ($rakefile, $show\_tasks, + $show\_prereqs, $trace, $dryrun and $silent). The + --classic-namespace option is no longer supported. + +* Global constants are no longer supported. This includes + Task, FileTask, FileCreationTask and + RakeApp). The constant missing hook to warn about using + global rake constants has been removed. + +* The Rake DSL methods (task, file, directory, etc) are in their own + module (Rake::DSL). The stub versions of these methods (that printed + warnings) in Object have been removed. However, the DSL methods are + added to the top-level main object. Since main is + not in the inheritance tree, the presence of the DSL methods in main + should be low impact on other libraries. + + If you want to use the Rake DSL commands from your own code, just + include Rake::DSL into your own classes and modules. + +* The deprecated syntax for task arguments (the one using + :needs) has been removed. + +* The --reduce-compat flag has been removed (it's not needed + anymore). + +* The deprecated rake/sys.rb library has been removed. + +* The deprecated rake/rdoctask.rb library has been removed. + RDoc supplies its own rake task now. + +* The deprecated rake/gempackagetask.rb library has been + removed. Gem supplies its own package task now. + +There is one small behavioral change: + +* Non-file tasks now always report the current time as their time + stamp. This is different from the previous behavior where non-file + tasks reported current time only if there were no prerequisites, and + the max prerequisite timestamp otherwise. This lead to inconsistent + and surprising behavior when adding prerequisites to tasks that in + turn were prequisites to file tasks. The new behavior is more + consistent and predictable. + +==== Changes (from 0.9.3) + +Since Rake 10 includes the changes from the last version of Rake 9, +we'll repeat the changes for version 0.9.3 here. + +===== New Features + +* Multitask tasks now use a thread pool. Use -j to limit the number of + available threads. + +* Use -m to turn regular tasks into multitasks (use at your own risk). + +* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to + programatically add rake task libraries. + +* You can specific backtrace suppression patterns (see + --suppress-backtrace) + +* Directory tasks can now take prerequisites and actions + +* Use --backtrace to request a full backtrace without the task trace. + +* You can say "--backtrace=stdout" and "--trace=stdout" to route trace + output to standard output rather than standard error. + +* Optional 'phony' target (enable with 'require 'rake/phony'") for + special purpose builds. + +* Task#clear now clears task comments as well as actions and + prerequisites. Task#clear_comment will specifically target comments. + +* The --all option will force -T and -D to consider all the tasks, + with and without descriptions. + +===== Bug Fixes + +* Semi-colons in windows rakefile paths now work. + +* Improved Control-C support when invoking multiple test suites. + +* egrep method now reads files in text mode (better support for + Windows) + +* Better deprecation line number reporting. + +* The -W option now works with all tasks, whether they have a + description or not. + +* File globs in rake should not be sorted alphabetically, independent + of file system and platform. + +* Numerous internal improvements. + +* Documentation typos and fixes. + + +==== Thanks + +As usual, it was input from users that drove a lot of these changes. The +following people contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.6 + +Rake version 0.9.6 contains a number of fixes mainly for merging +Rake into the Ruby source tree and fixing tests. + +==== Changes + +===== Bug Fixes (0.9.6) + +* Better trace output when using a multi-threaded Rakefile. +* Arg parsing is now consistent for tasks and multitasks. +* Skip exit code test in versions of Ruby that don't support it well. + +Changes for better integration with the Ruby source tree: + +* Fix version literal for Ruby source tree build. +* Better loading of libraries for testing in Ruby build. +* Use the ruby version provided by Ruby's tests. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.5 + +Rake version 0.9.5 contains a number of bug fixes. + +==== Changes + +===== Bug Fixes (0.9.5) + +* --trace and --backtrace no longer swallow following task names. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.4 + +Rake version 0.9.4 contains a number of bug fixes. + +==== Changes + +===== Bug Fixes (0.9.4) + +* Exit status with failing tests is not correctly set to non-zero. + +* Simplified syntax for phony task (for older versions of RDoc). + +* Stand alone FileList usage gets glob function (without loading in + extra dependencies) + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== 0.9.3 + +Rake version 0.9.3 contains some new, backwards compatible features and +a number of bug fixes. + +==== Changes + +===== New Features + +* Multitask tasks now use a thread pool. Use -j to limit the number of + available threads. + +* Use -m to turn regular tasks into multitasks (use at your own risk). + +* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to + programatically add rake task libraries. + +* You can specific backtrace suppression patterns (see + --suppress-backtrace) + +* Directory tasks can now take prerequisites and actions + +* Use --backtrace to request a full backtrace without the task trace. + +* You can say "--backtrace=stdout" and "--trace=stdout" to route trace + output to standard output rather than standard error. + +* Optional 'phony' target (enable with 'require 'rake/phony'") for + special purpose builds. + +* Task#clear now clears task comments as well as actions and + prerequisites. Task#clear_comment will specifically target comments. + +* The --all option will force -T and -D to consider all the tasks, + with and without descriptions. + +===== Bug Fixes + +* Semi-colons in windows rakefile paths now work. + +* Improved Control-C support when invoking multiple test suites. + +* egrep method now reads files in text mode (better support for + Windows) + +* Better deprecation line number reporting. + +* The -W option now works with all tasks, whether they have a + description or not. + +* File globs in rake should not be sorted alphabetically, independent + of file system and platform. + +* Numerous internal improvements. + +* Documentation typos and fixes. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Aaron Patterson +* Dylan Smith +* Jo Liss +* Jonas Pfenniger +* Kazuki Tsujimoto +* Michael Bishop +* Michael Elufimov +* NAKAMURA Usaku +* Ryan Davis +* Sam Grönblom +* Sam Phippen +* Sergio Wong +* Tay Ray Chuan +* grosser +* quix + +Also, many thanks to Eric Hodel for assisting with getting this release +out the door. + +-- Jim Weirich + +=== Rake 0.9.2.2 + +Rake version 0.9.2.2 is mainly bug fixes. + +==== Changes + +* The rake test loader now removes arguments it has processed. Issue #51 +* Rake::TaskArguments now responds to #values\_at +* RakeFileUtils.verbose_flag = nil silences output the same as 0.8.7 +* Rake tests are now directory-independent +* Rake tests are no longer require flexmock +* Commands constant is no longer polluting top level namespace. +* Show only the interesting portion of the backtrace by default (James M. Lawrence). +* Added --reduce-compat option to remove backward compatible DSL hacks (James M. Lawrence). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + +=== 0.9.2 + +Rake version 0.9.2 has a few small fixes. See below for details. + +==== Changes + +* Support for Ruby 1.8.6 was fixed. +* Global DSL warnings now honor --no-deprecate + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + +=== 0.9.1 + +Rake version 0.9.1 has a number of bug fixes and enhancments (see +below for more details). Additionally, the internals have be slightly +restructured and improved. + +==== Changes + +Rake 0.9.1 adds back the global DSL methods, but with deprecation +messages. This allows Rake 0.9.1 to be used with older rakefiles with +warning messages. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + +=== 0.9.0 + +Rake version 0.9.0 has a number of bug fixes and enhancments (see +below for more details). Additionally, the internals have be slightly +restructured and improved. + +==== Changes + +===== New Features / Enhancements / Bug Fixes in Version 0.9.0 + +* Rake now warns when the deprecated :needs syntax used (and suggests + the proper syntax in the warning). + +* Moved Rake DSL commands to top level ruby object 'main'. Rake DSL + commands are no longer private methods in Object. (Suggested by + James M. Lawrence/quix) + +* Rake now uses case-insensitive comparisons to find the Rakefile on Windows. + Based on patch by Roger Pack. + +* Rake now requires (instead of loads) files in the test task. Patch by Cezary + Baginski. + +* Fixed typos. Patches by Sean Scot August Moon and R.T. Lechow. + +* Rake now prints the Rakefile directory only when it's different from the + current directory. Patch by Alex Chaffee. + +* Improved rakefile_location discovery on Windows. Patch by James Tucker. + +* Rake now recognizes "Windows Server" as a windows system. Patch by Matthias + Lüdtke + +* Rake::RDocTask is deprecated. Use RDoc::Task from RDoc 2.4.2+ (require + 'rdoc/task') + +* Rake::GemPackageTask is deprecated. Use Gem::PackageTask (require + 'rubygems/package\_task') + +* Rake now outputs various messages to $stderr instead of $stdout. + +* Rake no longer emits warnings for Config. Patch by Santiago Pastorino. + +* Removed Rake's DSL methods from the top level scope. If you need to + call 'task :xzy' in your code, include Rake::DSL into your class, or + put the code in a Rake::DSL.environment do ... end block. + +* Split rake.rb into individual files. + +* Support for the --where (-W) flag for showing where a task is defined. + +* Fixed quoting in test task. + (http://onestepback.org/redmine/issues/show/44, + http://www.pivotaltracker.com/story/show/1223138) + +* Fixed the silent option parsing problem. + (http://onestepback.org/redmine/issues/show/47) + +* Fixed :verbose=>false flag on sh and ruby commands. + +* Rake command line options may be given by default in a RAKEOPT + environment variable. + +* Errors in Rake will now display the task invocation chain in effect + at the time of the error. + +* Accepted change by warnickr to not expand test patterns in shell + (allowing more files in the test suite). + +* Fixed that file tasks did not perform prereq lookups in scope + (Redmine #57). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence (quix) +* Roger Pack +* Cezary Baginski +* Sean Scot August Moon +* R.T. Lechow +* Alex Chaffee +* James Tucker +* Matthias Lüdtke +* Santiago Pastorino + +Also, bit thanks to Eric Hodel for assisting with getting this release +out the door (where "assisting" includes, but is not by any means +limited to, "pushing" me to get it done). + +-- Jim Weirich + + +=== 0.8.7 + +Rake version 0.8.5 introduced greatly improved support for executing +commands on Windows. The "sh" command now has the same semantics on +Windows that it has on Unix based platforms. + +Rake version 0.8.6 includes minor fixes the the RDoc generation. +Rake version 0.8.7 includes a minor fix for JRuby running on windows. + +==== Changes + +===== New Features / Enhancements in Version 0.8.5 + +* Improved implementation of the Rake system command for Windows. + (patch from James M. Lawrence/quix) + +* Support for Ruby 1.9's improved system command. (patch from James + M. Lawrence/quix) + +* Rake now includes the configured extension when invoking an + executable (Config::CONFIG['EXEEXT]) + +===== Bug Fixes in Version 0.8.5 + +* Environment variable keys are now correctly cased (it matters in + some implementations). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Charles Nutter + +-- Jim Weirich + +=== 0.8.6 + +Rake version 0.8.5 introduced greatly improved support for executing +commands on Windows. The "sh" command now has the same semantics on +Windows that it has on Unix based platforms. + +Rake version 0.8.5 includes minor fixes the the RDoc generation. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence/quix +* Luis Lavena + +-- Jim Weirich + +=== 0.8.5 + +Rake version 0.8.5 is a new release of Rake with greatly improved +support for executing commands on Windows. The "sh" command now has +the same semantics on Windows that it has on Unix based platforms. + +==== Changes + +===== New Features / Enhancements in Version 0.8.5 + +* Improved implementation of the Rake system command for Windows. + (patch from James M. Lawrence/quix) + +* Support for Ruby 1.9's improved system command. (patch from James + M. Lawrence/quix) + +* Rake now includes the configured extension when invoking an + executable (Config::CONFIG['EXEEXT]) + +===== Bug Fixes in Version 0.8.5 + +* Environment variable keys are now correctly cased (it matters in + some implementations). + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence/quix +* Luis Lavena + +-- Jim Weirich + +=== 0.8.4 + +Rake version 0.8.4 is a bug-fix release of rake. + +NOTE: The version of Rake that comes with Ruby 1.9 has diverged + slightly from the core Rake code base. Rake 0.8.4 will work + with Ruby 1.9, but is not a strict upgrade for the Rake that + comes with Ruby 1.9. A (near) future release of Rake will unify + those two codebases. + +==== Letter Writing Campaign + +Thanks to Aaron Patterson (@tenderlove) and Eric Hodel (@drbrain) for +their encouraging support in organizing a letter writing campaign to +lobby for the "Warning Free" release of rake 0.8.4. A special callout +goes to Jonathan D. Lord, Sr (Dr. Wingnut) whose postcard was the +first to actually reach me. (see +http://tenderlovemaking.com/2009/02/26/we-need-a-new-version-of-rake/ +for details) + +==== Changes + +===== New Features / Enhancements in Version 0.8.4 + +* Case is preserved on rakefile names. (patch from James + M. Lawrence/quix) + +* Improved Rakefile case insensitivity testing (patch from Luis + Lavena). + +* Windows system dir search order is now: HOME, HOMEDRIVE + HOMEPATH, + APPDATA, USERPROFILE (patch from Luis Lavena) + +* MingGW is now recognized as a windows platform. (patch from Luis + Lavena) + +===== Bug Fixes in Version 0.8.4 + +* Removed reference to manage_gem to fix the warning produced by the + gem package task. + +* Fixed stray ARGV option problem that was interfering with + Test::Unit::Runner. (patch from Pivotal Labs) + +===== Infrastructure Improvements in Version 0.8.4 + +* Numerous fixes to the windows test suite (patch from Luis Lavena). + +* Improved Rakefile case insensitivity testing (patch from Luis + Lavena). + +* Better support for windows paths in the test task (patch from Simon + Chiang/bahuvrihi) + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* James M. Lawrence/quix +* Luis Lavena +* Pivotal Labs +* Simon Chiang/bahuvrihi + +-- Jim Weirich + +=== 0.8.3 + +Rake version 0.8.3 is a bug-fix release of rake. + +==== Changes + +===== Bug Fixes in Version 0.8.3 + +* Enhanced the system directory detection in windows. We now check + HOMEDRIVE/HOMEPATH and USERPROFILE if APPDATA isn't found. (Patch + supplied by James Tucker). Rake no long aborts if it can't find the + directory. + +* Added fix to handle ruby installations in directories with spaces in + their name. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Edwin Pratomo +* Gavin Stark +* Adam Q. Salter +* Adam Majer +* Emanuel Indermühle +* Ittay Dror +* Bheeshmar Redheendran (for spending an afternoon with me debugging + windows issues) + +-- Jim Weirich + + +=== 0.8.2 + +Rake version 0.8.2 is a new release of rake that includes a number of +new features and numerous bug fixes. + +==== Changes + +===== New Features in Version 0.8.2 + +* Switched from getoptlong to optparse (patches supplied by Edwin + Pratomo). + +* The -T option will now attempt to dynamically sense the size of the + terminal. The -T output will only self-truncate if the output is a + tty. However, if RAKE_COLUMNS is explicitly set, it will be honored + in any case. (Patch provided by Gavin Stark). + +* The following public methods have been added to rake task objects: + + * task.clear -- Clear both the prerequisites and actions of the + target rake task. + * task.clear_prerequisites -- Clear all the existing prerequisites + from the target rake task. + * task.clear_actions -- Clear all the existing actions from the + target rake task. + * task.reenable -- Re-enable a task, allowing its actions to be + executed again if the task is invoked. + +* Changed RDoc test task to have no default template. This makes it + easier for the tempate to pick up the template from the environment. + +* Default values for task arguments can easily be specified with the + :with_defaults method. (Idea for default argument merging supplied + by (Adam Q. Salter) + +===== Bug Fixes in Version 0.8.2 + +* Fixed bug in package task so that it will include the subdir + directory in the package for testing. (Bug found by Adam Majer) + +* Fixed filename dependency order bug in test\_inspect\_pending and + test\_to\_s\_pending. (Bug found by Adam Majer) + +* Fixed check for file utils options to make them immune to the + symbol/string differences. (Patch supplied by Edwin Pratomo) + +* Fixed bug with rules involving multiple source, where only the first + dependency of a rule has any effect (Patch supplied by Emanuel + Indermühle) + +* FileList#clone and FileList#dup have better sematics w.r.t. taint + and freeze. + +* Changed from using Mutex to Monitor. Evidently Mutex causes thread + join errors when Ruby is compiled with -disable-pthreads. (Patch + supplied by Ittay Dror) + +* Fixed bug in makefile parser that had problems with extra spaces in + file task names. (Patch supplied by Ittay Dror) + +==== Other changes in Version 0.8.2 + +* Added ENV var to rake's own Rakefile to prevent OS X from including + extended attribute junk in the rake package tar file. (Bug found by + Adam Majer) + +* Added a performance patch for reading large makefile dependency + files. (Patch supplied by Ittay Dror) + +==== Task Argument Examples + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.2] + +And the string "0.8.2" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +===== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, :first_name, :last_name + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name (:first_name and :last_name in the example). + +To access the values of the parameters, the block defining the task +behaviour can now accept a second parameter: + + task :name, :first_name, :last_name do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Edwin Pratomo +* Gavin Stark +* Adam Q. Salter +* Adam Majer +* Emanuel Indermühle +* Ittay Dror +* Bheeshmar Redheendran (for spending an afternoon with me debugging + windows issues) + +-- Jim Weirich + +=== 0.8.0/0.8.1 + +Rake version 0.8.0 is a new release of rake that includes serveral new +features. + +==== Changes + +===== New Features in Version 0.8.0 + +* Tasks can now receive command line parameters. See the examples + below for more details. + +* Comments are limited to 80 columns on output, but full comments can + be seen by using the -D parameter. (feature suggested by Jamis + Buck). + +* Explicit exit(n) calls will now set the exit status to n. (patch + provided by Stephen Touset). + +* Rake is now compatible with Ruby 1.9. + +Version 0.8.1 is a minor update that includes additional Ruby 1.9 +compatibility fixes. + +==== Task Argument Examples + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.0] + +And the string "0.8.0" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +===== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, :first_name, :last_name + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name (:first_name and :last_name in the example). + +To access the values of the parameters, the block defining the task +behaviour can now accept a second parameter: + + task :name, :first_name, :last_name do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Jamis Buck (for comment formatting suggestions) +* Stephen Touset (for exit status patch). + +-- Jim Weirich + + +=== 0.7.3 + +Rake version 0.7.3 is a minor release that includes some refactoring to better +support custom Rake applications. + +==== Changes + +===== New Features in Version 0.7.3 + +* Added the +init+ and +top_level+ methods to make the creation of custom Rake applications a bit easier. E.g. + + gem 'rake', ">= 0.7.3" + require 'rake' + + Rake.application.init('myrake') + + task :default do + something_interesting + end + + Rake.application.top_level + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +-- Jim Weirich + + +=== 0.7.2 + + +Version 0.7.2 supplies a bug fix and a few minor enhancements. In +particular, the new version fixes an incompatibility with the soon to +be released Ruby 1.8.6. We strongly recommend upgrading to Rake 0.7.2 +in order to be compatible with the new version of Ruby. + +==== Changes + +===== Bug Fixes in 0.7.2 + +There are quite a number of bug fixes in the new 0.7.2 version of +Rake: + +* Removed dependency on internal fu_xxx functions from FileUtils. + +* Error messages are now send to stderr rather than stdout (from + Payton Quackenbush). + +* Better error handling on invalid command line arguments (from Payton + Quackenbush). + +* Fixed some bugs where the application object was going to the global + appliation instead of using its own data. + +* Fixed the method name leak from FileUtils (bug found by Glenn + Vanderburg). + +* Added test for noop, bad_option and verbose flags to sh command. + +* Added a description to the gem task in GemPackageTask. + +* Fixed a bug when rules have multiple prerequisites (patch by Joel + VanderWerf) + +* Added the handful of RakeFileUtils to the private method as well. + +===== New Features in 0.7.2 + +The following new features are available in Rake version 0.7.2: + +* Added square and curly bracket patterns to FileList#include (Tilman + Sauerbeck). + +* FileLists can now pass a block to FileList#exclude to exclude files + based on calculated values. + +* Added plain filename support to rule dependents (suggested by Nobu + Nakada). + +* Added pathmap support to rule dependents. In other words, if a + pathmap format (beginning with a '%') is given as a Rake rule + dependent, then the name of the depend will be the name of the + target with the pathmap format applied. + +* Added a 'tasks' method to a namespace to get a list of tasks + associated with the namespace. + +* Added tar_command and zip_command options to the Package task. + +* The clean task will no longer delete 'core' if it is a directory. + +===== Internal Rake Improvements + +The following changes will are mainly internal improvements and +refactorings and have little effect on the end user. But they may be +of interest to the general public. + +* Added rcov task and updated unit testing for better code coverage. + +* Added a 'shame' task to the Rakefile. + +* Added rake_extension to handle detection of extension collisions. + +* Added a protected 'require "rubygems"' to test/test_application to + unbreak cruisecontrol.rb. + +* Removed rake\_dup. Now we just simply rescue a bad dup. + +* Refactored the FileList reject logic to remove duplication. + +* Removed if \_\_FILE\_\_ at the end of the rake.rb file. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Payton Quackenbush -- For several error handling improvements. + +* Glenn Vanderburg -- For finding and fixing the method name leak from + FileUtils. + +* Joel VanderWerf -- for finding and fixing a bug in the handling of + multiple prerequisites. + +* Tilman Sauerbeck -- For some enhancing FileList to support more + advanced file globbing. + +* Nobu Nakada -- For suggesting plain file name support to rule dependents. + +-- Jim Weirich + +=== 0.7.1 + +Version 0.7.1 supplies a bug fix and a few minor enhancements. + +==== Changes + +===== Bug Fixes in 0.7.1 + +* Changes in the exception reported for the FileUtils.ln caused + safe_ln to fail with a NotImplementedError. Rake 0.7.1 will now + catch that error or any StandardError and properly fall back to + using +cp+. + +===== New Features in 0.7.1 + +* You can filter the results of the --task option by supplying an + optional regular expression. This allows the user to easily find a + particular task name in a long list of possible names. + +* Transforming procs in a rule may now return a list of prerequisites. + This allows more flexible rule formation. + +* FileList and String now support a +pathmap+ melthod that makes the + transforming paths a bit easier. See the API docs for +pathmap+ for + details. + +* The -f option without a value will disable the search for a + Rakefile. This allows the Rakefile to be defined entirely in a + library (and loaded with the -r option). The current working + directory is not changed when this is done. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* James Britt and Assaph Mehr for reporting and helping to debug the + safe_ln issue. + +-- Jim Weirich + + +=== 0.7.0 + +These changes for Rake have been brewing for a long time. Here they +are, I hope you enjoy them. + +==== Changes + +===== New Features + +* Name space support for task names (see below). +* Prerequisites can be executed in parallel (see below). +* Added safe_ln support for openAFS (via Ludvig Omholt). +* RDoc defaults to internal (in-process) invocation. The old behavior + is still available by setting the +external+ flag to true. +* Rakefiles are now loaded with the expanded path to prevent + accidental pollution from the Ruby load path. +* Task objects my now be used in prerequisite lists directly. +* Task objects (in addition to task names) may now be included in the + prerequisite list of a task. +* Internals cleanup and refactoring. + +===== Bug Fixes + +* Compatibility fixes for Ruby 1.8.4 FileUtils changes. + +===== Namespaces + +Tasks can now be nested inside their own namespaces. Tasks within one +namespace will not accidentally interfer with tasks named in a different +namespace. + +For example: + + namespace "main" do + task :build do + # Build the main program + end + end + + namespace "samples" do + task :build do + # Build the sample programs + end + end + + task :build_all => ["main:build", "samples:build"] + +Even though both tasks are named :build, they are separate tasks in +their own namespaces. The :build_all task (defined in the toplevel +namespace) references both build tasks in its prerequisites. + +You may invoke each of the individual build tasks with the following +commands: + + rake main:build + rake samples:build + +Or invoke both via the :build_all command: + + rake build_all + +Namespaces may be nested arbitrarily. Since the name of file tasks +correspond to the name of a file in the external file system, +FileTasks are not affected by the namespaces. + +See the Rakefile format documentation (in the Rake API documents) for +more information. + +===== Parallel Tasks + +Sometimes you have several tasks that can be executed in parallel. By +specifying these tasks as prerequisites to a +multitask+ task. + +In the following example the tasks copy\_src, copy\_doc and copy\_bin +will all execute in parallel in their own thread. + + multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do + puts "All Copies Complete" + end + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Doug Young (inspiration for the parallel task) +* David Heinemeier Hansson (for --trace message enhancement and for + pushing for namespace support). +* Ludvig Omholt (for the openAFS fix) + +-- Jim Weirich + +=== 0.6.1 + +* Rebuilt 0.6.0 gem without signing. + +=== 0.6.0 + +Its time for some long requested enhancements and lots of bug fixes +... And a whole new web page. + +==== New Web Page + +The primary documentation for rake has moved from the RubyForge based +wiki to its own Hieraki based web site. Constant spam on the wiki +made it a difficult to keep clean. The new site will be easier to +update and organize. + +Check out the new documentation at: http://docs.rubyrake.org + +We will be adding new documentation to the site as time goes on. + +In addition to the new docs page, make sure you check out Martin +Fowlers article on rake at http://martinfowler.com/articles/rake.html + +==== Changes + +===== New Features + +* Multiple prerequisites on Rake rules now allowed. However, keep the + following in mind: + + 1. All the prerequisites of a rule must be available before a rule + is triggered, where "enabled" means (a) an existing file, (b) a + defined rule, or (c) another rule which also must be + trigger-able. + 2. Rules are checked in order of definition, so it is important to + order your rules properly. If a file can be created by two + different rules, put the more specific rule first (otherwise the + more general rule will trigger first and the specific one will + never be triggered). + 3. The source method now returns the name of the first + prerequisite listed in the rule. sources returns the + names of all the rule prerequisites, ordered as they are defined + in the rule. If the task has other prerequisites not defined in + the rule (but defined in an explicit task definition), then they + will _not_ be included in the sources list. + +* FileLists may now use the egrep command. This popular enhancement + is now a core part of the FileList object. If you want to get a + list of all your to-dos, fixmes and TBD comments, add the following + to your Rakefile. + + desc "Look for TODO and FIXME tags in the code" + task :todo do + FileList['**/*.rb'].egrep /#.*(FIXME|TODO|TBD)/ + end + +* The investigation method was added to task object to dump + out some important values. This makes it a bit easier to debug Rake + tasks. + + For example, if you are having problems with a particular task, just + print it out: + + task :huh do + puts Rake::Task['huh'].investigation + end + +* The Rake::TestTask class now supports a "ruby\_opts" option to pass + arbitrary ruby options to a test subprocess. + +===== Some Incompatibilities + +* When using the ruby command to start a Ruby subprocess, the + Ruby interpreter that is currently running rake is used by default. + This makes it easier to use rake in an environment with multiple + ruby installation. (Previously, the first ruby command found in the + PATH was used). + + If you wish to chose a different Ruby interpreter, you can + explicitly choose the interpreter via the sh command. + +* The major rake classes (Task, FileTask, FileCreationTask, RakeApp) + have been moved out of the toplevel scope and are now accessible as + Rake::Task, Rake::FileTask, Rake::FileCreationTask and + Rake::Application. If your Rakefile + directly references any one of these tasks, you may: + + 1. Update your Rakefile to use the new classnames + 2. Use the --classic-namespace option on the rake command to get the + old behavior, + 3. Add require 'rake/classic_namespace' to the + Rakefile to get the old behavior. + + rake will print a rather annoying warning whenever a + deprecated class name is referenced without enabling classic + namespace. + +===== Bug Fixes + +* Several unit tests and functional tests were fixed to run better + under windows. + +* Directory tasks are now a specialized version of a File task. A + directory task will only be triggered if it doesn't exist. It will + not be triggered if it is out of date w.r.t. any of its + prerequisites. + +* Fixed a bug in the Rake::GemPackageTask class so that the gem now + properly contains the platform name. + +* Fixed a bug where a prerequisite on a file task would cause + an exception if the prerequisite did not exist. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Greg Fast (better ruby_opt test options) +* Kelly Felkins (requested by better namespace support) +* Martin Fowler (suggested Task.investigation) +* Stuart Jansen (send initial patch for multiple prerequisites). +* Masao Mutch (better support for non-ruby Gem platforms) +* Philipp Neubeck (patch for file task exception fix) + +-- Jim Weirich + +=== 0.5.4 + +Time for some minor bug fixes and small enhancements + +==== Changes + +Here are the changes for version 0.5.4 ... + +* Added double quotes to the test runner. This allows the location of + the tests (and runner) to be in a directory path that contains + spaces (e.g. "C:/Program Files/ruby/bin"). +* Added .svn to default ignore list. Now subversion project metadata + is automatically ignored by Rake's FileList. +* Updated FileList#include to support nested arrays and filelists. + FileLists are flat lists of file names. Using a FileList in an + include will flatten out the nested file names. + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +Thanks to ... + +* Tilman Sauerbeck for the nested FileList suggestion. +* Josh Knowles for pointing out the spaces in directory name problem. + +-- Jim Weirich + +=== 0.5.3 + +Although it has only been two weeks since the last release, we have +enough updates to the Rake program to make it time for another +release. + +==== Changes + +Here are the changes for version 0.5.3 ... + +* FileLists have been extensively changed so that they mimic the + behavior of real arrays even more closely. In particular, + operations on FileLists that return a new collection (e.g. collect, + reject) will now return a FileList rather than an array. In + addition, several places where FileLists were not properly expanded + before use have been fixed. +* A method (+ext+) to simplify the handling of file extensions was + added to String and to Array. +* The 'testrb' script in test/unit tends to silently swallow syntax + errors in test suites. Because of that, the default test loader is + now a rake-provided script. You can still use 'testrb' by setting + the loader flag in the test task to :testrb. (See the API documents + for TestTask for all the loader flag values). +* FileUtil methods (e.g. cp, mv, install) are now declared to be + private. This will cut down on the interference with user defined + methods of the same name. +* Fixed the verbose flag in the TestTask so that the test code is + controlled by the flag. Also shortened up some failure messages. + (Thanks to Tobias Luetke for the suggestion). +* Rules will now properly detect a task that can generate a source + file. Previously rules would only consider source files that were + already present. +* Added an +import+ command that allows Rake to dynamically import + dependendencies into a running Rake session. The +import+ command + can run tasks to update the dependency file before loading them. + Dependency files can be in rake or make format, allowing rake to + work with tools designed to generate dependencies for make. + +==== Thanks + +As usual, it was input from users that drove a alot of these changes. +Thanks to ... + +* Brian Gernhardt for the rules fix (especially for the patience to + explain the problem to me until I got what he was talking about). +* Stefan Lang for pointing out problems in the dark corners of the + FileList implementation. +* Alexey Verkhovsky pointing out the silently swallows syntax errors + in tests. +* Tobias Luetke for beautifying the test task output. +* Sam Roberts for some of the ideas behind dependency loading. + +-- Jim Weirich + + +=== 0.5.0 + +It has been a long time in coming, but we finally have a new version +of Rake available. + +==== Changes + +* Fixed documentation that was lacking the Rake module name (Tilman + Sauerbeck). +* Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck). +* Recursive rules are now supported (Tilman Sauerbeck). +* Added warning option for the Test Task (requested by Eric Hodel). +* The jamis rdoc template is only used if it exists. +* Added fix for Ruby 1.8.2 test/unit and rails problem. +* Added contributed rake man file (Jani Monoses). +* Added Brian Candler's fix for problems in --trace and --dry-run + mode. + +==== Thanks + +Lots of people provided input to this release. Thanks to Tilman +Sauerbeck for numerous patches, documentation fixes and suggestions. +And for also pushing me to get this release out. Also, thanks to +Brian Candler for the finding and fixing --trace/dry-run fix. That +was an obscure bug. Also to Eric Hodel for some good suggestions. + +-- Jim Weirich + +=== 0.4.15 + +==== Changes + +Version 0.4.15 is a bug fix update for the Ruby 1.8.2 compatibility +changes. This release includes: + +* Fixed a bug that prevented the TESTOPTS flag from working with the + revised for 1.8.2 test task. +* Updated the docs on --trace to indicate that it also enables a full + backtrace on errors. +* Several fixes for new warnings generated. + +==== Mini-Roadmap + +I will continue to issue Rake updates in the 0.4.xx series as new +Ruby-1.8.2 issues become manifest. Once the codebase stabilizes, I +will release a 0.5.0 version incorporating all the changes. If you +are not using Ruby-1.8.2 and wish to avoid version churn, I recommend +staying with a release prior to Rake-0.4.14. + +=== 0.4.14 + +Version 0.4.14 is a compatibility fix to allow Rake's test task to +work under Ruby 1.8.2. A change in the Test::Unit autorun feature +prevented Rake from running any tests. This release fixes the +problem. + +Rake 0.4.14 is the recommended release for anyone using Ruby 1.8.2. + +=== 0.4.13 + +* Fixed the dry-run flag so it is operating again. +* Multiple arguments to sh and ruby commands will not be interpreted + by the shell (patch provided by Jonathan Paisley). + +=== 0.4.12 + +* Added --silent (-s) to suppress the (in directory) rake message. + +=== 0.4.11 + +* Changed the "don't know how to rake" message (finally) +* Changes references to a literal "Rakefile" to reference the global + variable $rakefile (which contains the actual name of the rakefile). + +=== 0.4.10 + +* Added block support to the "sh" command, allowing users to take + special actions on the result of the system call. E.g. + + sh "shell_command" do |ok, res| + puts "Program returned #{res.exitstatus}" if ! ok + end + +=== 0.4.9 + +* Switched to Jamis Buck's RDoc template. +* Removed autorequire from Rake's gem spec. This prevents the Rake + libraries from loading while using rails. + +=== 0.4.8 + +* Added support for .rb versions of Rakefile. +* Removed \\\n's from test task. +* Fixed Ruby 1.9 compatibility issue with FileList. + +=== 0.4.7 + +* Fixed problem in FileList that caused Ruby 1.9 to go into infinite + recursion. Since to_a was removed from Object, it does not need to + added back into the list of methods to rewrite in FileList. (Thanks + to Kent Sibilev for pointing this out). + +=== 0.4.6 +* Removed test version of ln in FileUtils that prevented safe_ln from + using ln. + +=== 0.4.5 +* Upgraded comments in TestTask. +* FileList to_s and inspect now automatically resolve pending changes. +* FileList#exclude properly returns the FileList. + +=== 0.4.4 +* Fixed initialization problem with @comment. +* Now using multi -r technique in TestTask. Switch Rakefile back to + using the built-in test task macros because the rake runtime is no + longer needed. +* Added 'TEST=filename' and 'TESTOPTS=options' to the Test Task + macros. +* Allow a +test_files+ attribute in test tasks. This allows more + flexibility in specifying test files. + +=== 0.4.3 +* Fixed Comment leakage. + +=== 0.4.2 +* Added safe_ln that falls back to a copy if a file link is not supported. +* Package builder now uses safe\_ln. + +=== 0.4.1 +* Task comments are now additive, combined with "/". +* Works with (soon to be released) rubygems 0.6.2 (or 0.7.0) + +=== 0.4.0 +* FileList now uses deferred loading. The file system is not searched + until the first call that needs the file names. +* VAR=VALUE options are now accepted on the command line and are + treated like environment variables. The values may be tested in a + Rakefile by referencing ENV['VAR']. +* File.mtime is now used (instead of File.new().mtime). + +=== 0.3.2.x + +* Removed some hidden dependencies on rubygems. Tests now will test + gems only if they are installed. +* Removed Sys from some example files. I believe that is that last + reference to Sys outside of the contrib area. +* Updated all copyright notices to include 2004. + +=== 0.3.2 + +* GEM Installation now works with the application stub. + +=== 0.3.1 + +* FileLists now automatically ignore CVS, .bak, ! +* GEM Installation now works. + +=== 0.3.0 + +Promoted 0.2.10. + +=== 0.2.10 +General + +* Added title to Rake's rdocs +* Contrib packages are no longer included in the documentation. + +RDoc Issues + +* Removed default for the '--main' option +* Fixed rendering of the rdoc options +* Fixed clean/clobber confusion with rerdoc +* 'title' attribute added + +Package Task Library Issues + +* Version (or explicit :noversion) is required. +* +package_file+ attribute is now writable + +FileList Issues + +* Dropped bang version of exclude. Now using ant-like include/exclude semantics. +* Enabled the "yield self" idiom in FileList#initialize. + +=== 0.2.9 + +This version contains numerous changes as the RubyConf.new(2003) +presentation was being prepared. The changes include: + +* The monolithic rubyapp task library is in the process of being + dropped in favor of lighter weight task libraries. + +=== 0.2.7 + +* Added "desc" for task descriptions. +* -T will now display tasks with descriptions. +* -P will display tasks and prerequisites. +* Dropped the Sys module in favor of the 1.8.x FileUtils module. Sys + is still supported in the contrib area. + +=== 0.2.6 + +* Moved to RubyForge + +=== 0.2.5 + +* Switched to standard ruby app builder. +* Added no_match option to file matcher. + +=== 0.2.4 + +* Fixed indir, which neglected to actually change directories. + +=== 0.2.3 + +* Added rake module for a help target +* Added 'for\_files' to Sys +* Added a $rakefile constant +* Added test for selecting proper rule with multiple targets. diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/MIT-LICENSE b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/MIT-LICENSE new file mode 100644 index 0000000..4292f3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) Jim Weirich + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/README.rdoc b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/README.rdoc new file mode 100644 index 0000000..b31fe37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/README.rdoc @@ -0,0 +1,155 @@ += RAKE -- Ruby Make + +home :: https://github.com/ruby/rake +bugs :: https://github.com/ruby/rake/issues +docs :: https://ruby.github.io/rake + +== Description + +Rake is a Make-like program implemented in Ruby. Tasks and dependencies are +specified in standard Ruby syntax. + +Rake has the following features: + +* Rakefiles (rake's version of Makefiles) are completely defined in + standard Ruby syntax. No XML files to edit. No quirky Makefile + syntax to worry about (is that a tab or a space?) + +* Users can specify tasks with prerequisites. + +* Rake supports rule patterns to synthesize implicit tasks. + +* Flexible FileLists that act like arrays but know about manipulating + file names and paths. + +* A library of prepackaged tasks to make building rakefiles easier. For example, + tasks for building tarballs. (Formerly + tasks for building RDoc, Gems, and publishing to FTP were included in rake but they're now + available in RDoc, RubyGems, and rake-contrib respectively.) + +* Supports parallel execution of tasks. + +== Installation + +=== Gem Installation + +Download and install rake with the following. + + gem install rake + +== Usage + +=== Simple Example + +First, you must write a "Rakefile" file which contains the build rules. Here's +a simple example: + + task default: %w[test] + + task :test do + ruby "test/unittest.rb" + end + +This Rakefile has two tasks: + +* A task named "test", which -- upon invocation -- will run a unit test file + in Ruby. +* A task named "default". This task does nothing by itself, but it has exactly + one dependency, namely the "test" task. Invoking the "default" task will + cause Rake to invoke the "test" task as well. + +Running the "rake" command without any options will cause it to run the +"default" task in the Rakefile: + + % ls + Rakefile test/ + % rake + (in /home/some_user/Projects/rake) + ruby test/unittest.rb + ....unit test output here... + +Type "rake --help" for all available options. + +== Resources + +=== Rake Information + +* {Rake command-line}[rdoc-ref:doc/command_line_usage.rdoc] +* {Writing Rakefiles}[rdoc-ref:doc/rakefile.rdoc] +* The original {Rake announcement}[rdoc-ref:doc/rational.rdoc] +* Rake {glossary}[rdoc-ref:doc/glossary.rdoc] + +=== Presentations and Articles about Rake + +* Avdi Grimm's rake series: + 1. {Rake Basics}[https://avdi.codes/rake-part-1-basics/] + 2. {Rake File Lists}[https://avdi.codes/rake-part-2-file-lists-2/] + 3. {Rake Rules}[https://avdi.codes/rake-part-3-rules/] + 4. {Rake Pathmap}[https://avdi.codes/rake-part-4-pathmap/] + 5. {File Operations}[https://avdi.codes/rake-part-5-file-operations/] + 6. {Clean and Clobber}[https://avdi.codes/rake-part-6-clean-and-clobber/] + 7. {MultiTask}[https://avdi.codes/rake-part-7-multitask/] +* {Jim Weirich's 2003 RubyConf presentation}[https://web.archive.org/web/20140221123354/http://onestepback.org/articles/buildingwithrake/] +* Martin Fowler's article on Rake: https://martinfowler.com/articles/rake.html + +== Other Make Re-envisionings ... + +Rake is a late entry in the make replacement field. Here are links to +other projects with similar (and not so similar) goals. + +* https://directory.fsf.org/wiki/Bras -- Bras, one of earliest + implementations of "make in a scripting language". +* http://www.a-a-p.org -- Make in Python +* https://ant.apache.org -- The Ant project +* https://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System +* https://www.rubydoc.info/gems/rant/0.5.7/frames -- Rant, another Ruby make tool. + +== Credits + +[Jim Weirich] Who originally created Rake. + +[Ryan Dlugosz] For the initial conversation that sparked Rake. + +[Nobuyoshi Nakada ] For the initial patch for rule support. + +[Tilman Sauerbeck ] For the recursive rule patch. + +[Eric Hodel] For aid in maintaining rake. + +[Hiroshi SHIBATA] Maintainer of Rake 10 and later + +== License + +Rake is available under an MIT-style license. + +:include: MIT-LICENSE + +--- + += Other stuff + +Author:: Jim Weirich +Requires:: Ruby 2.0.0 or later +License:: Copyright Jim Weirich. + Released under an MIT-style license. See the MIT-LICENSE + file included in the distribution. + +== Warranty + +This software is provided "as is" and without any express or implied +warranties, including, without limitation, the implied warranties of +merchantability and fitness for a particular purpose. + +== Historical + +Rake was originally created by Jim Weirich, who unfortunately passed away in +February 2014. This repository was originally hosted at +{github.com/jimweirich/rake}[https://github.com/jimweirich/rake/], however +with his passing, has been moved to {ruby/rake}[https://github.com/ruby/rake]. + +You can view Jim's last commit here: +https://github.com/jimweirich/rake/commit/336559f28f55bce418e2ebcc0a57548dcbac4025 + +You can {read more about Jim}[https://en.wikipedia.org/wiki/Jim_Weirich] at Wikipedia. + +Thank you for this great tool, Jim. We'll remember you. diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/command_line_usage.rdoc b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/command_line_usage.rdoc new file mode 100644 index 0000000..a4a0bd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/command_line_usage.rdoc @@ -0,0 +1,171 @@ += Rake Command Line Usage + +Rake is invoked from the command line using: + + % rake [options ...] [VAR=VALUE ...] [targets ...] + +Options are: + +[name=value] + Set the environment variable name to value + during the execution of the rake command. You can access + the value by using ENV['name']. + +[--all (-A)] + Used in combination with the -T and -D options, will force + those options to show all the tasks, even the ones without comments. + +[--backtrace{=_output_} (-n)] + Enable a full backtrace (i.e. like --trace, but without the task + tracing details). The _output_ parameter is optional, but if + specified it controls where the backtrace output is sent. If + _output_ is stdout, then backtrace output is directed to + standard output. If _output_ is stderr, or if it is + missing, then the backtrace output is sent to standard error. + +[--comments] + Used in combination with the -W options to force the output to + contain commented options only. This is the reverse of + --all. + +[--describe _pattern_ (-D)] + Describe the tasks (matching optional PATTERN), then exit. + +[--dry-run (-n)] + Do a dry run. Print the tasks invoked and executed, but do not + actually execute any of the actions. + +[--execute _code_ (-e)] + Execute some Ruby code and exit. + +[--execute-print _code_ (-p)] + Execute some Ruby code, print the result, and exit. + +[--execute-continue _code_ (-E)] + Execute some Ruby code, then continue with normal task processing. + +[--help (-H)] + Display some help text and exit. + +[--jobs _number_ (-j)] + + Specifies the maximum number of concurrent threads allowed. Rake + will allocate threads as needed up to this maximum number. + + If omitted, Rake will attempt to estimate the number of CPUs on + the system and add 4 to that number. + + The concurrent threads are used to execute the multitask + prerequisites. Also see the -m option which turns all + tasks into multitasks. + + Sample values: + (no -j) : Allow up to (# of CPUs + 4) number of threads + --jobs : Allow unlimited number of threads + --jobs=1 : Allow only one thread (the main thread) + --jobs=16 : Allow up to 16 concurrent threads + +[--job-stats _level_] + + Display job statistics at the completion of the run. By default, + this will display the requested number of active threads (from the + -j options) and the maximum number of threads in play at any given + time. + + If the optional _level_ is history, then a complete trace + of task history will be displayed on standard output. + +[--libdir _directory_ (-I)] + Add _directory_ to the list of directories searched for require. + +[--multitask (-m)] + Treat all tasks as multitasks. ('make/drake' semantics) + +[--nosearch (-N)] + Do not search for a Rakefile in parent directories. + +[--prereqs (-P)] + Display a list of all tasks and their immediate prerequisites. + +[--quiet (-q)] + Do not echo commands from FileUtils. + +[--rakefile _filename_ (-f)] + Use _filename_ as the name of the rakefile. The default rakefile + names are +rakefile+ and +Rakefile+ (with +rakefile+ taking + precedence). If the rakefile is not found in the current + directory, +rake+ will search parent directories for a match. The + directory where the Rakefile is found will become the current + directory for the actions executed in the Rakefile. + +[--rakelibdir _rakelibdir_ (-R)] + Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') + +[--require _name_ (-r)] + Require _name_ before executing the Rakefile. + +[--rules] + Trace the resolution of rules used to create tasks. + +[--silent (-s)] + Like --quiet, but also suppresses the 'in directory' announcement. + +[--suppress-backtrace _pattern_] + Line matching the regular expression _pattern_ will be removed + from the backtrace output. Note that the --backtrace option is the + full backtrace without these lines suppressed. + +[--system (-g)] + Use the system wide (global) rakefiles. The project Rakefile is + ignored. By default, the system wide rakefiles are used only if no + project Rakefile is found. On Unix-like system, the system wide + rake files are located in $HOME/.rake. On a windows system they + are stored in $APPDATA/Rake. + +[--no-system (-G)] + Use the project level Rakefile, ignoring the system-wide (global) + rakefiles. + +[--tasks pattern (-T)] + Display a list of the major tasks and their comments. Comments + are defined using the "desc" command. If a pattern is given, then + only tasks matching the pattern are displayed. + +[--trace{=_output_} (-t)] + Turn on invoke/execute tracing. Also enable full backtrace on + errors. The _output_ parameter is optional, but if specified it + controls where the trace output is sent. If _output_ is + stdout, then trace output is directed to standard output. + If _output_ is stderr, or if it is missing, then trace + output is sent to standard error. + +[--verbose (-v)] + Echo the Sys commands to standard output. + +[--version (-V)] + Display the program version and exit. + +[--where pattern (-W)] + Display tasks that match pattern and the file and line + number where the task is defined. By default this option will + display all tasks, not just the tasks that have descriptions. + +[--no-deprecation-warnings (-X)] + Do not display the deprecation warnings. + +== Environment Variables + +[RAKEOPT] + Command line options can be specified in the RAKEOPT + environment variable. These options will be processed as if they + were given on the command line. This is useful for setting default + options that you want to use with every rake invocation. + + For example, setting: + export RAKEOPT="-s --trace" + + would cause rake to run silently with tracing enabled by default. + +In addition, any command line option of the form +VAR=VALUE will be added to the environment hash +ENV and may be tested in the Rakefile. diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile1 b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile1 new file mode 100644 index 0000000..39f8bcc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile1 @@ -0,0 +1,38 @@ +# Example Rakefile -*- ruby -*- + +task :default => [:main] + +file "a.o" => ["a.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +file "b.o" => ["b.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +file "main.o" => ["main.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +OBJFILES = ["a.o", "b.o", "main.o"] +task :obj => OBJFILES + +file "main" => OBJFILES do |t| + sh "gcc -o #{t.name} main.o a.o b.o" +end + +task :clean do + rm_f FileList['*.o'] + Dir['*~'].each { |fn| rm_f fn } +end + +task :clobber => [:clean] do + rm_f "main" +end + +task :run => ["main"] do + sh "./main" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile2 b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile2 new file mode 100644 index 0000000..35310ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile2 @@ -0,0 +1,35 @@ +# Example Rakefile -*- ruby -*- +# Using the power of Ruby + +task :default => [:main] + +def ext(fn, newext) + fn.sub(/\.[^.]+$/, newext) +end + +SRCFILES = Dir['*.c'] +OBJFILES = SRCFILES.collect { |fn| ext(fn,".o") } + +OBJFILES.each do |objfile| + srcfile = ext(objfile, ".c") + file objfile => [srcfile] do |t| + sh "gcc #{srcfile} -c -o #{t.name}" + end +end + +file "main" => OBJFILES do |t| + sh "gcc -o #{t.name} main.o a.o b.o" +end + +task :clean do + rm_f FileList['*.o'] + Dir['*~'].each { |fn| rm_f fn } +end + +task :clobber => [:clean] do + rm_f "main" +end + +task :run => ["main"] do + sh "./main" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/a.c b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/a.c new file mode 100644 index 0000000..620e6f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/a.c @@ -0,0 +1,6 @@ +#include + +void a() +{ + printf ("In function a\n"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/b.c b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/b.c new file mode 100644 index 0000000..9b24aa1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/b.c @@ -0,0 +1,6 @@ +#include + +void b() +{ + printf ("In function b\n"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/main.c b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/main.c new file mode 100644 index 0000000..a04558a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/main.c @@ -0,0 +1,11 @@ +#include + +extern void a(); +extern void b(); + +int main () +{ + a(); + b(); + return 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/glossary.rdoc b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/glossary.rdoc new file mode 100644 index 0000000..9d592b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/glossary.rdoc @@ -0,0 +1,42 @@ += Glossary + +action :: + Code to be executed in order to perform a task. Actions in a Rakefile are + specified in a code block. (Usually delimited by +do+/+end+ pairs.) + +execute :: + When a task is executed, all of its actions are performed in the order they + were defined. Note that, unlike invoke, execute always + executes the actions (without invoking or executing the prerequisites). + +file task (Rake::FileTask) :: + A file task is a task whose purpose is to create a file (which has the same + name as the task). When invoked, a file task will only execute if one or + more of the following conditions are true. + + 1. The associated file does not exist. + 2. A prerequisite has a later time stamp than the existing file. + + Because normal Tasks always have the current time as timestamp, a FileTask + that has a normal Task prerequisite will always execute. + +invoke :: + When a task is invoked, first we check to see if it has been invoked before. + If it has been, then nothing else is done. If this is the first time it has + been invoked, then we invoke each of its prerequisites. Finally, we check + to see if we need to execute the actions of this task by calling + Rake::Task#needed?. If the task is needed, we execute its actions. + + NOTE: Prerequisites are still invoked even if the task is not needed. + +prerequisites :: + Every task has a (possibly empty) set of prerequisites. A prerequisite P to + Task T is itself a task that must be invoked before Task T. + +rule :: + A rule is a recipe for synthesizing a task when no task is explicitly + defined. Rules generally synthesize file tasks. + +task (Rake::Task) :: + The basic unit of work in a Rakefile. A task has a name, a set of + prerequisites, and a list of actions to be performed. diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/jamis.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/jamis.rb new file mode 100644 index 0000000..531aa75 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/jamis.rb @@ -0,0 +1,592 @@ +# frozen_string_literal: true +module RDoc +module Page + +FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif" + +STYLE = < pre { + padding: 0.5em; + border: 1px dotted black; + background: #FFE; +} + +CSS + +XHTML_PREAMBLE = %{ + +} + +HEADER = XHTML_PREAMBLE + < + + %title% + + + + + + + +ENDHEADER + +FILE_PAGE = < + + + + +
File
%short_name%
+ + + + + + + + + +
Path:%full_path% +IF:cvsurl +  (CVS) +ENDIF:cvsurl +
Modified:%dtm_modified%
+
+ +
+HTML + +################################################################### + +CLASS_PAGE = < + %classmod%
%full_name% + + + + + + +IF:parent + + + + +ENDIF:parent +
In: +START:infiles +HREF:full_path_url:full_path: +IF:cvsurl + (CVS) +ENDIF:cvsurl +END:infiles +
Parent: +IF:par_url + +ENDIF:par_url +%parent% +IF:par_url + +ENDIF:par_url +
+ + + +HTML + +################################################################### + +METHOD_LIST = < +IF:diagram +
+ %diagram% +
+ENDIF:diagram + +IF:description +
%description%
+ENDIF:description + +IF:requires +
Required Files
+
    +START:requires +
  • HREF:aref:name:
  • +END:requires +
+ENDIF:requires + +IF:toc +
Contents
+ +ENDIF:toc + +IF:methods +
Methods
+
    +START:methods +
  • HREF:aref:name:
  • +END:methods +
+ENDIF:methods + +IF:includes +
Included Modules
+
    +START:includes +
  • HREF:aref:name:
  • +END:includes +
+ENDIF:includes + +START:sections +IF:sectitle + +IF:seccomment +
+%seccomment% +
+ENDIF:seccomment +ENDIF:sectitle + +IF:classlist +
Classes and Modules
+ %classlist% +ENDIF:classlist + +IF:constants +
Constants
+ +START:constants + + + + + +IF:desc + + + + +ENDIF:desc +END:constants +
%name%=%value%
 %desc%
+ENDIF:constants + +IF:attributes +
Attributes
+ +START:attributes + + + + + +END:attributes +
+IF:rw +[%rw%] +ENDIF:rw + %name%%a_desc%
+ENDIF:attributes + +IF:method_list +START:method_list +IF:methods +
%type% %category% methods
+START:methods +
+
+IF:callseq + %callseq% +ENDIF:callseq +IFNOT:callseq + %name%%params% +ENDIF:callseq +IF:codeurl +[ source ] +ENDIF:codeurl +
+IF:m_desc +
+ %m_desc% +
+ENDIF:m_desc +IF:aka +
+ This method is also aliased as +START:aka + %name% +END:aka +
+ENDIF:aka +IF:sourcecode +
+ +
+
+%sourcecode%
+
+
+
+ENDIF:sourcecode +
+END:methods +ENDIF:methods +END:method_list +ENDIF:method_list +END:sections +
+HTML + +FOOTER = < + +ENDFOOTER + +BODY = HEADER + < + +
+ #{METHOD_LIST} +
+ + #{FOOTER} +ENDBODY + +########################## Source code ########################## + +SRC_PAGE = XHTML_PREAMBLE + < +%title% + + + + +
%code%
+ + +HTML + +########################## Index ################################ + +FR_INDEX_BODY = < + + + + + + + +
+START:entries +%name%
+END:entries +
+ +HTML + +CLASS_INDEX = FILE_INDEX +METHOD_INDEX = FILE_INDEX + +INDEX = XHTML_PREAMBLE + < + + %title% + + + + + + + + + +IF:inline_source + +ENDIF:inline_source +IFNOT:inline_source + + + + +ENDIF:inline_source + + <body bgcolor="white"> + Click <a href="html/index.html">here</a> for a non-frames + version of this page. + </body> + + + + +HTML + +end +end + + diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/proto_rake.rdoc b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/proto_rake.rdoc new file mode 100644 index 0000000..a9e33d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/proto_rake.rdoc @@ -0,0 +1,127 @@ += Original Prototype Rake + +This is the original 100 line prototype rake program. + +--- + #!/usr/bin/env ruby + + require 'ftools' + + class Task + TASKS = Hash.new + + attr_reader :prerequisites + + def initialize(task_name) + @name = task_name + @prerequisites = [] + @actions = [] + end + + def enhance(deps=nil, &block) + @prerequisites |= deps if deps + @actions << block if block_given? + self + end + + def name + @name.to_s + end + + def invoke + @prerequisites.each { |n| Task[n].invoke } + execute if needed? + end + + def execute + return if @triggered + @triggered = true + @actions.collect { |act| result = act.call(self) }.last + end + + def needed? + true + end + + def timestamp + Time.now + end + + class << self + def [](task_name) + TASKS[intern(task_name)] or fail "Don't know how to rake #{task_name}" + end + + def define_task(args, &block) + case args + when Hash + fail "Too Many Target Names: #{args.keys.join(' ')}" if args.size > 1 + fail "No Task Name Given" if args.size < 1 + task_name = args.keys[0] + deps = args[task_name] + else + task_name = args + deps = [] + end + deps = deps.collect {|d| intern(d) } + get(task_name).enhance(deps, &block) + end + + def get(task_name) + name = intern(task_name) + TASKS[name] ||= self.new(name) + end + + def intern(task_name) + (Symbol === task_name) ? task_name : task_name.intern + end + end + end + + class FileTask < Task + def needed? + return true unless File.exist?(name) + latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max + return false if latest_prereq.nil? + timestamp < latest_prereq + end + + def timestamp + File.new(name.to_s).mtime + end + end + + def task(args, &block) + Task.define_task(args, &block) + end + + def file(args, &block) + FileTask.define_task(args, &block) + end + + def sys(cmd) + puts cmd + system(cmd) or fail "Command Failed: [#{cmd}]" + end + + def rake + begin + here = Dir.pwd + while ! File.exist?("Rakefile") + Dir.chdir("..") + fail "No Rakefile found" if Dir.pwd == here + here = Dir.pwd + end + puts "(in #{Dir.pwd})" + load "./Rakefile" + ARGV.push("default") if ARGV.size == 0 + ARGV.each { |task_name| Task[task_name].invoke } + rescue Exception => ex + puts "rake aborted ... #{ex.message}" + puts ex.backtrace.find {|str| str =~ /Rakefile/ } || "" + end + end + + if __FILE__ == $0 then + rake + end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rake.1 b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rake.1 new file mode 100644 index 0000000..c6bfa25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rake.1 @@ -0,0 +1,156 @@ +.Dd June 12, 2016 +.Dt RAKE 1 +.Os rake 11.2.2 +.Sh NAME +.Nm rake +.Nd make-like build utility for Ruby +.Sh SYNOPSIS +.Nm +.Op Fl f Ar rakefile +.Op Ar options +.Ar targets ... +.Sh DESCRIPTION +.Nm +is a +.Xr make 1 Ns -like +build utility for Ruby. +Tasks and dependencies are specified in standard Ruby syntax. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl m , Fl -multitask +Treat all tasks as multitasks. +.It Fl B , Fl -build-all +Build all prerequisites, including those which are up\-to\-date. +.It Fl j , Fl -jobs Ar num_jobs +Specifies the maximum number of tasks to execute in parallel (default is number of CPU cores + 4). +.El +.Ss Modules +.Bl -tag -width Ds +.It Fl I , Fl -libdir Ar libdir +Include +.Ar libdir +in the search path for required modules. +.It Fl r , Fl -require Ar module +Require +.Ar module +before executing +.Pa rakefile . +.El +.Ss Rakefile location +.Bl -tag -width Ds +.It Fl f , Fl -rakefile Ar filename +Use +.Ar filename +as the rakefile to search for. +.It Fl N , Fl -no-search , Fl -nosearch +Do not search parent directories for the Rakefile. +.It Fl G , Fl -no-system , Fl -nosystem +Use standard project Rakefile search paths, ignore system wide rakefiles. +.It Fl R , Fl -rakelib Ar rakelibdir , Fl -rakelibdir Ar rakelibdir +Auto-import any .rake files in +.Ar rakelibdir +(default is +.Sq rakelib ) +.It Fl g , Fl -system +Use system-wide (global) rakefiles (usually +.Pa ~/.rake/*.rake ) . +.El +.Ss Debugging +.Bl -tag -width Ds +.It Fl -backtrace Ns = Ns Ar out +Enable full backtrace. +.Ar out +can be +.Dv stderr +(default) or +.Dv stdout . +.It Fl t , Fl -trace Ns = Ns Ar out +Turn on invoke/execute tracing, enable full backtrace. +.Ar out +can be +.Dv stderr +(default) or +.Dv stdout . +.It Fl -suppress-backtrace Ar pattern +Suppress backtrace lines matching regexp +.Ar pattern . +Ignored if +.Fl -trace +is on. +.It Fl -rules +Trace the rules resolution. +.It Fl n , Fl -dry-run +Do a dry run without executing actions. +.It Fl T , Fl -tasks Op Ar pattern +Display the tasks (matching optional +.Ar pattern ) +with descriptions, then exit. +.It Fl D , Fl -describe Op Ar pattern +Describe the tasks (matching optional +.Ar pattern ) , +then exit. +.It Fl W , Fl -where Op Ar pattern +Describe the tasks (matching optional +.Ar pattern ) , +then exit. +.It Fl P , Fl -prereqs +Display the tasks and dependencies, then exit. +.It Fl e , Fl -execute Ar code +Execute some Ruby code and exit. +.It Fl p , Fl -execute-print Ar code +Execute some Ruby code, print the result, then exit. +.It Fl E , Fl -execute-continue Ar code +Execute some Ruby code, then continue with normal task processing. +.El +.Ss Information +.Bl -tag -width Ds +.It Fl v , Fl -verbose +Log message to standard output. +.It Fl q , Fl -quiet +Do not log messages to standard output. +.It Fl s , Fl -silent +Like +.Fl -quiet , +but also suppresses the +.Sq in directory +announcement. +.It Fl X , Fl -no-deprecation-warnings +Disable the deprecation warnings. +.It Fl -comments +Show commented tasks only +.It Fl A , Fl -all +Show all tasks, even uncommented ones (in combination with +.Fl T +or +.Fl D ) +.It Fl -job-stats Op Ar level +Display job statistics. +If +.Ar level +is +.Sq history , +displays a complete job list. +.It Fl V , Fl -version +Display the program version. +.It Fl h , Fl H , Fl -help +Display a help message. +.El +.Sh SEE ALSO +The complete documentation for +.Nm rake +has been installed at +.Pa /usr/share/doc/rake-doc/html/index.html . +It is also available online at +.Lk https://ruby.github.io/rake . +.Sh AUTHORS +.An -nosplit +.Nm +was written by +.An Jim Weirich Aq Mt jim@weirichhouse.org . +.Pp +This manual was created by +.An Caitlin Matos Aq Mt caitlin.matos@zoho.com +for the Debian project (but may be used by others). +It was inspired by the manual by +.An Jani Monoses Aq Mt jani@iv.ro +for the Ubuntu project. diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rakefile.rdoc b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rakefile.rdoc new file mode 100644 index 0000000..bf2f5d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rakefile.rdoc @@ -0,0 +1,635 @@ += Rakefile Format + +First of all, there is no special format for a Rakefile. A Rakefile +contains executable Ruby code. Anything legal in a ruby script is +allowed in a Rakefile. + +Now that we understand there is no special syntax in a Rakefile, there +are some conventions that are used in a Rakefile that are a little +unusual in a typical Ruby program. Since a Rakefile is tailored to +specifying tasks and actions, the idioms used in a Rakefile are +designed to support that. + +So, what goes into a Rakefile? + +== Tasks + +Tasks are the main unit of work in a Rakefile. Tasks have a name +(usually given as a symbol or a string), a list of prerequisites (more +symbols or strings) and a list of actions (given as a block). + +=== Simple Tasks + +A task is declared by using the +task+ method. +task+ takes a single +parameter that is the name of the task. + + task :name + +=== Tasks with Prerequisites + +Any prerequisites are given as a list (enclosed in square brackets) +following the name and an arrow (=>). + + task :name => [:prereq1, :prereq2] + +*NOTE:* Although this syntax looks a little funky, it is legal +Ruby. We are constructing a hash where the key is :name and the value +for that key is the list of prerequisites. It is equivalent to the +following ... + + hash = Hash.new + hash[:name] = [:prereq1, :prereq2] + task(hash) + +You can also use strings for task names and prerequisites, rake doesn't care. +This is the same task definition: + + task 'name' => %w[prereq1 prereq2] + +As is this: + + task name: %w[prereq1 prereq2] + +We'll prefer this style for regular tasks with prerequisites throughout the +rest of the document. Using an array of strings for the prerequisites means +you will need to make fewer changes if you need to move tasks into namespaces +or perform other refactorings. + +=== Tasks with Actions + +Actions are defined by passing a block to the +task+ method. Any Ruby +code can be placed in the block. The block may reference the task +object via the block parameter. + + task name: [:prereq1, :prereq2] do |t| + # actions (may reference t) + end + +=== Multiple Definitions + +A task may be specified more than once. Each specification adds its +prerequisites and actions to the existing definition. This allows one +part of a rakefile to specify the actions and a different rakefile +(perhaps separately generated) to specify the dependencies. + +For example, the following is equivalent to the single task +specification given above. + + task :name + task name: :prereq1 + task name: %w[prereq2] + task :name do |t| + # actions + end + +== File Tasks + +Some tasks are designed to create a file from one or more other files. +Tasks that generate these files may be skipped if the file already +exists. File tasks are used to specify file creation tasks. + +File tasks are declared using the +file+ method (instead of the +task+ +method). In addition, file tasks are usually named with a string +rather than a symbol. + +The following file task creates a executable program (named +prog+) +given two object files named +a.o+ and +b.o+. The tasks +for creating +a.o+ and +b.o+ are not shown. + + file "prog" => ["a.o", "b.o"] do |t| + sh "cc -o #{t.name} #{t.prerequisites.join(' ')}" + end + +== Directory Tasks + +It is common to need to create directories upon demand. The ++directory+ convenience method is a short-hand for creating a FileTask +that creates the directory. For example, the following declaration +... + + directory "testdata/examples/doc" + +is equivalent to ... + + file "testdata" do |t| mkdir t.name end + file "testdata/examples" => ["testdata"] do |t| mkdir t.name end + file "testdata/examples/doc" => ["testdata/examples"] do |t| mkdir t.name end + +The +directory+ method does not accept prerequisites or actions, but +both prerequisites and actions can be added later. For example ... + + directory "testdata" + file "testdata" => ["otherdata"] + file "testdata" do + cp Dir["standard_data/*.data"], "testdata" + end + +== Tasks with Parallel Prerequisites + +Rake allows parallel execution of prerequisites using the following syntax: + + multitask copy_files: %w[copy_src copy_doc copy_bin] do + puts "All Copies Complete" + end + +In this example, +copy_files+ is a normal rake task. Its actions are +executed whenever all of its prerequisites are done. The big +difference is that the prerequisites (+copy_src+, +copy_bin+ and ++copy_doc+) are executed in parallel. Each of the prerequisites are +run in their own Ruby thread, possibly allowing faster overall runtime. + +=== Secondary Prerequisites + +If any of the primary prerequisites of a multitask have common secondary +prerequisites, all of the primary/parallel prerequisites will wait +until the common prerequisites have been run. + +For example, if the copy_xxx tasks have the +following prerequisites: + + task copy_src: :prep_for_copy + task copy_bin: :prep_for_copy + task copy_doc: :prep_for_copy + +Then the +prep_for_copy+ task is run before starting all the copies in +parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+, +and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is +run only once, even though it is referenced in multiple threads. + +=== Thread Safety + +The Rake internal data structures are thread-safe with respect +to the multitask parallel execution, so there is no need for the user +to do extra synchronization for Rake's benefit. However, if there are +user data structures shared between the parallel prerequisites, the +user must do whatever is necessary to prevent race conditions. + +== Tasks with Arguments + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.2] + +And the string "0.8.2" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire name + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +=== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, [:first_name, :last_name] + +The first argument is still the name of the task (:name in this case). +The next two arguments are the names of the parameters expected by +:name in an array (:first_name and :last_name in the example). + +To access the values of the parameters, the block defining the task +behaviour can now accept a second parameter: + + task :name, [:first_name, :last_name] do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. + +If you wish to specify default values for the arguments, you can use +the with_defaults method in the task body. Here is the above example +where we specify default values for the first and last names: + + task :name, [:first_name, :last_name] do |t, args| + args.with_defaults(:first_name => "John", :last_name => "Dough") + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +=== Tasks that Expect Parameters and Have Prerequisites + +Tasks that use parameters have a slightly different format for +prerequisites. Use the arrow notation to indicate the prerequisites +for tasks with arguments. For example: + + task :name, [:first_name, :last_name] => [:pre_name] do |t, args| + args.with_defaults(:first_name => "John", :last_name => "Dough") + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +=== Tasks that take Variable-length Parameters + +Tasks that need to handle a list of values as a parameter can use the +extras method of the args variable. This allows for tasks that can +loop over a variable number of values, and its compatible with named +parameters as well: + + task :email, [:message] do |t, args| + mail = Mail.new(args.message) + recipients = args.extras + recipients.each do |target| + mail.send_to(target) + end + end + +There is also the convenience method to_a that returns all parameters +in the sequential order they were given, including those associated +with named parameters. + +=== Deprecated Task Parameters Format + +There is an older format for declaring task parameters that omitted +the task argument array and used the :needs keyword to introduce the +dependencies. That format is still supported for compatibility, but +is not recommended for use. The older format may be dropped in future +versions of rake. + +== Accessing Task Programmatically + +Sometimes it is useful to manipulate tasks programmatically in a +Rakefile. To find a task object use Rake::Task.[]. + +=== Programmatic Task Example + +For example, the following Rakefile defines two tasks. The :doit task +simply prints a simple "DONE" message. The :dont class will lookup +the doit class and remove (clear) all of its prerequisites and +actions. + + task :doit do + puts "DONE" + end + + task :dont do + Rake::Task[:doit].clear + end + +Running this example: + + $ rake doit + (in /Users/jim/working/git/rake/x) + DONE + $ rake dont doit + (in /Users/jim/working/git/rake/x) + $ + +The ability to programmatically manipulate tasks gives rake very +powerful meta-programming capabilities w.r.t. task execution, but +should be used with caution. + +== Rules + +When a file is named as a prerequisite, but does not have a file task +defined for it, Rake will attempt to synthesize a task by looking at a +list of rules supplied in the Rakefile. + +Suppose we were trying to invoke task "mycode.o", but no task is +defined for it. But the rakefile has a rule that look like this ... + + rule '.o' => ['.c'] do |t| + sh "cc #{t.source} -c -o #{t.name}" + end + +This rule will synthesize any task that ends in ".o". It has a +prerequisite a source file with an extension of ".c" must exist. If +Rake is able to find a file named "mycode.c", it will automatically +create a task that builds "mycode.o" from "mycode.c". + +If the file "mycode.c" does not exist, rake will attempt +to recursively synthesize a rule for it. + +When a task is synthesized from a rule, the +source+ attribute of the +task is set to the matching source file. This allows us to write +rules with actions that reference the source file. + +=== Advanced Rules + +Any regular expression may be used as the rule pattern. Additionally, +a proc may be used to calculate the name of the source file. This +allows for complex patterns and sources. + +The following rule is equivalent to the example above. + + rule( /\.o$/ => [ + proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') } + ]) do |t| + sh "cc #{t.source} -c -o #{t.name}" + end + +*NOTE:* Because of a _quirk_ in Ruby syntax, parenthesis are +required on *rule* when the first argument is a regular expression. + +The following rule might be used for Java files ... + + rule '.class' => [ + proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') } + ] do |t| + java_compile(t.source, t.name) + end + +*NOTE:* +java_compile+ is a hypothetical method that invokes the +java compiler. + +=== Implicit File Tasks + +When a task is not defined but a file with that name exists, Rake +automatically creates an implicit file task for it. For example: + + $ rake hello_world # Error: task not found + $ touch hello_world # Create a file with the same name + $ rake hello_world # Now succeeds automatically + +Use the --rules command line option to trace how rules are +resolved when searching for tasks; note that creation of implicit file +tasks is not traced. + +== Importing Dependencies + +Any ruby file (including other rakefiles) can be included with a +standard Ruby +require+ command. The rules and declarations in the +required file are just added to the definitions already accumulated. + +Because the files are loaded _before_ the rake targets are evaluated, +the loaded files must be "ready to go" when the rake command is +invoked. This makes generated dependency files difficult to use. By +the time rake gets around to updating the dependencies file, it is too +late to load it. + +The +import+ command addresses this by specifying a file to be loaded +_after_ the main rakefile is loaded, but _before_ any targets on the +command line are invoked. In addition, if the file name matches an +explicit task, that task is invoked before loading the file. This +allows dependency files to be generated and used in a single rake +command invocation. + +Example: + + require 'rake/loaders/makefile' + + file ".depends.mf" => [SRC_LIST] do |t| + sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" + end + + import ".depends.mf" + +If ".depends" does not exist, or is out of date w.r.t. the source +files, a new ".depends" file is generated using +makedepend+ before +loading. + +== Comments + +Standard Ruby comments (beginning with "#") can be used anywhere it is +legal in Ruby source code, including comments for tasks and rules. +However, if you wish a task to be described using the "-T" switch, +then you need to use the +desc+ command to describe the task. + +Example: + + desc "Create a distribution package" + task package: %w[ ... ] do ... end + +The "-T" switch (or "--tasks" if you like to spell things out) will +display a list of tasks that have a description. If you use +desc+ to +describe your major tasks, you have a semi-automatic way of generating +a summary of your Rake file. + + $ rake -T + (in /home/.../rake) + rake clean # Remove any temporary products. + rake clobber # Remove any generated file. + rake clobber_rdoc # Remove rdoc products + rake contrib_test # Run tests for contrib_test + rake default # Default Task + rake install # Install the application + rake lines # Count lines in the main rake file + rake rdoc # Build the rdoc HTML Files + rake rerdoc # Force a rebuild of the RDOC files + rake test # Run tests + rake testall # Run all test targets + +Only tasks with descriptions will be displayed with the "-T" switch. +Use "-P" (or "--prereqs") to get a list of all tasks and their +prerequisites. + +== Namespaces + +As projects grow (and along with it, the number of tasks), it is +common for task names to begin to clash. For example, if you might +have a main program and a set of sample programs built by a single +Rakefile. By placing the tasks related to the main program in one +namespace, and the tasks for building the sample programs in a +different namespace, the task names will not interfere with each other. + +For example: + + namespace "main" do + task :build do + # Build the main program + end + end + + namespace "samples" do + task :build do + # Build the sample programs + end + end + + task build: %w[main:build samples:build] + +Referencing a task in a separate namespace can be achieved by +prefixing the task name with the namespace and a colon +(e.g. "main:build" refers to the :build task in the +main+ namespace). +Nested namespaces are supported. + +Note that the name given in the +task+ command is always the unadorned +task name without any namespace prefixes. The +task+ command always +defines a task in the current namespace. + +=== FileTasks + +File task names are not scoped by the namespace command. Since the +name of a file task is the name of an actual file in the file system, +it makes little sense to include file task names in name space. +Directory tasks (created by the +directory+ command) are a type of +file task and are also not affected by namespaces. + +=== Name Resolution + +When looking up a task name, rake will start with the current +namespace and attempt to find the name there. If it fails to find a +name in the current namespace, it will search the parent namespaces +until a match is found (or an error occurs if there is no match). + +The "rake" namespace is a special implicit namespace that refers to +the toplevel names. + +If a task name begins with a "^" character, the name resolution will +start in the parent namespace. Multiple "^" characters are allowed. + +Here is an example file with multiple :run tasks and how various names +resolve in different locations. + + task :run + + namespace "one" do + task :run + + namespace "two" do + task :run + + # :run => "one:two:run" + # "two:run" => "one:two:run" + # "one:two:run" => "one:two:run" + # "one:run" => "one:run" + # "^run" => "one:run" + # "^^run" => "rake:run" (the top level task) + # "rake:run" => "rake:run" (the top level task) + end + + # :run => "one:run" + # "two:run" => "one:two:run" + # "^run" => "rake:run" + end + + # :run => "rake:run" + # "one:run" => "one:run" + # "one:two:run" => "one:two:run" + +== FileLists + +FileLists are the way Rake manages lists of files. You can treat a +FileList as an array of strings for the most part, but FileLists +support some additional operations. + +=== Creating a FileList + +Creating a file list is easy. Just give it the list of file names: + + fl = FileList['file1.rb', file2.rb'] + +Or give it a glob pattern: + + fl = FileList['*.rb'] + +== Odds and Ends + +=== do/end versus { } + +Blocks may be specified with either a +do+/+end+ pair, or with curly +braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the +actions for tasks and rules. Because the rakefile idiom tends to +leave off parentheses on the task/file/rule methods, unusual +ambiguities can arise when using curly braces. + +For example, suppose that the method +object_files+ returns a list of +object files in a project. Now we use +object_files+ as the +prerequisites in a rule specified with actions in curly braces. + + # DON'T DO THIS! + file "prog" => object_files { + # Actions are expected here (but it doesn't work)! + } + +Because curly braces have a higher precedence than +do+/+end+, the +block is associated with the +object_files+ method rather than the ++file+ method. + +This is the proper way to specify the task ... + + # THIS IS FINE + file "prog" => object_files do + # Actions go here + end + +== Rakefile Path + +When issuing the +rake+ command in a terminal, Rake will look +for a Rakefile in the current directory. If a Rakefile is not found, +it will search parent directories until one is found. + +For example, if a Rakefile resides in the +project/+ directory, +moving deeper into the project's directory tree will not have an adverse +effect on rake tasks: + + $ pwd + /home/user/project + + $ cd lib/foo/bar + $ pwd + /home/user/project/lib/foo/bar + + $ rake run_pwd + /home/user/project + +As far as rake is concerned, all tasks are run from the directory in +which the Rakefile resides. + +=== Multiple Rake Files + +Not all tasks need to be included in a single Rakefile. Additional +rake files (with the file extension "+.rake+") may be placed in ++rakelib+ directory located at the top level of a project (i.e. +the same directory that contains the main +Rakefile+). + +Also, rails projects may include additional rake files in the ++lib/tasks+ directory. + +=== Clean and Clobber Tasks + +Through require 'rake/clean' Rake provides +clean+ and +clobber+ +tasks: + ++clean+ :: + Clean up the project by deleting scratch files and backup files. Add files + to the +CLEAN+ FileList to have the +clean+ target handle them. + ++clobber+ :: + Clobber all generated and non-source files in a project. The task depends + on +clean+, so all the +CLEAN+ files will be deleted as well as files in the + +CLOBBER+ FileList. The intent of this task is to return a project to its + pristine, just unpacked state. + +You can add file names or glob patterns to both the +CLEAN+ and +CLOBBER+ +lists. + +=== Phony Task + +The phony task can be used as a dependency to allow file-based tasks to use +non-file-based-tasks as prerequisites without forcing them to rebuild. You +can require 'rake/phony' to add the +phony+ task. + +---- + +== See + +* README.rdoc -- Main documentation for Rake. diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rational.rdoc b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rational.rdoc new file mode 100644 index 0000000..0e1c338 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rational.rdoc @@ -0,0 +1,151 @@ += Why rake? + +Ok, let me state from the beginning that I never intended to write this +code. I'm not convinced it is useful, and I'm not convinced anyone +would even be interested in it. All I can say is that Why's onion truck +must by been passing through the Ohio valley. + +What am I talking about? ... A Ruby version of Make. + +See, I can sense you cringing already, and I agree. The world certainly +doesn't need yet another reworking of the "make" program. I mean, we +already have "ant". Isn't that enough? + +It started yesterday. I was helping a coworker fix a problem in one of +the Makefiles we use in our project. Not a particularly tough problem, +but during the course of the conversation I began lamenting some of the +shortcomings of make. In particular, in one of my makefiles I wanted to +determine the name of a file dynamically and had to resort to some +simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you +could just use Ruby inside a Makefile" I said. + +My coworker (a recent convert to Ruby) agreed, but wondered what it +would look like. So I sketched the following on the whiteboard... + + "What if you could specify the make tasks in Ruby, like this ..." + + task "build" do + java_compile(...args, etc ...) + end + + "The task function would register "build" as a target to be made, + and the block would be the action executed whenever the build + system determined that it was time to do the build target." + +We agreed that would be cool, but writing make from scratch would be WAY +too much work. And that was the end of that! + +... Except I couldn't get the thought out of my head. What exactly +would be needed to make the about syntax work as a make file? Hmmm, you +would need to register the tasks, you need some way of specifying +dependencies between tasks, and some way of kicking off the process. +Hey! What if we did ... and fifteen minutes later I had a working +prototype of Ruby make, complete with dependencies and actions. + +I showed the code to my coworker and we had a good laugh. It was just +about a page worth of code that reproduced an amazing amount of the +functionality of make. We were both truly stunned with the power of +Ruby. + +But it didn't do everything make did. In particular, it didn't have +timestamp based file dependencies (where a file is rebuilt if any of its +prerequisite files have a later timestamp). Obviously THAT would be a +pain to add and so Ruby Make would remain an interesting experiment. + +... Except as I walked back to my desk, I started thinking about what +file based dependencies would really need. Rats! I was hooked again, +and by adding a new class and two new methods, file/timestamp +dependencies were implemented. + +Ok, now I was really hooked. Last night (during CSI!) I massaged the +code and cleaned it up a bit. The result is a bare-bones replacement +for make in exactly 100 lines of code. + +For the curious, you can see it at ... +* doc/proto_rake.rdoc + +Oh, about the name. When I wrote the example Ruby Make task on my +whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ... +Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves +and Rake would clean them up ... or something like that. Anyways, the +name stuck. + +Some quick examples ... + +A simple task to delete backup files ... + + task :clean do + Dir['*~'].each {|fn| rm fn rescue nil} + end + +Note that task names are symbols (they are slightly easier to type +than quoted strings ... but you may use quoted string if you would +rather). Rake makes the methods of the FileUtils module directly +available, so we take advantage of the rm command. Also note +the use of "rescue nil" to trap and ignore errors in the rm +command. + +To run it, just type "rake clean". Rake will automatically find a +Rakefile in the current directory (or above!) and will invoke the +targets named on the command line. If there are no targets explicitly +named, rake will invoke the task "default". + +Here's another task with dependencies ... + + task :clobber => [:clean] do + rm_r "tempdir" + end + +Task :clobber depends upon task :clean, so :clean will be run before +:clobber is executed. + +Files are specified by using the "file" command. It is similar to the +task command, except that the task name represents a file, and the task +will be run only if the file doesn't exist, or if its modification time +is earlier than any of its prerequisites. + +Here is a file based dependency that will compile "hello.cc" to +"hello.o". + + file "hello.cc" + file "hello.o" => ["hello.cc"] do |t| + srcfile = t.name.sub(/\.o$/, ".cc") + sh %{g++ #{srcfile} -c -o #{t.name}} + end + +I normally specify file tasks with string (rather than symbols). Some +file names can't be represented by symbols. Plus it makes the +distinction between them more clear to the casual reader. + +Currently writing a task for each and every file in the project would be +tedious at best. I envision a set of libraries to make this job +easier. For instance, perhaps something like this ... + + require 'rake/ctools' + Dir['*.c'].each do |fn| + c_source_file(fn) + end + +where "c_source_file" will create all the tasks need to compile all the +C source files in a directory. Any number of useful libraries could be +created for rake. + +That's it. There's no documentation (other than whats in this +message). Does this sound interesting to anyone? If so, I'll continue +to clean it up and write it up and publish it on RAA. Otherwise, I'll +leave it as an interesting exercise and a tribute to the power of Ruby. + +Why /might/ rake be interesting to Ruby programmers. I don't know, +perhaps ... + +* No weird make syntax (only weird Ruby syntax :-) +* No need to edit or read XML (a la ant) +* Platform independent build scripts. +* Will run anywhere Ruby exists, so no need to have "make" installed. + If you stay away from the "sys" command and use things like + 'ftools', you can have a perfectly platform independent + build script. Also rake is only 100 lines of code, so it can + easily be packaged along with the rest of your code. + +So ... Sorry for the long rambling message. Like I said, I never +intended to write this code at all. diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake new file mode 100755 index 0000000..a00975f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby + +#-- +# Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +#++ + +require "rake" + +Rake.application.run diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake.rb new file mode 100644 index 0000000..f1c6f29 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true +#-- +# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +#++ + +module Rake; end + +require_relative "rake/version" + +require "rbconfig" +require "fileutils" +require "singleton" +require "monitor" +require "optparse" + +require_relative "rake/ext/string" + +require_relative "rake/win32" + +require_relative "rake/linked_list" +require_relative "rake/cpu_counter" +require_relative "rake/scope" +require_relative "rake/task_argument_error" +require_relative "rake/rule_recursion_overflow_error" +require_relative "rake/rake_module" +require_relative "rake/trace_output" +require_relative "rake/pseudo_status" +require_relative "rake/options" +require_relative "rake/task_arguments" +require_relative "rake/invocation_chain" +require_relative "rake/task" +require_relative "rake/file_task" +require_relative "rake/file_creation_task" +require_relative "rake/multi_task" +require_relative "rake/dsl_definition" +require_relative "rake/file_utils_ext" +require_relative "rake/file_list" +require_relative "rake/default_loader" +require_relative "rake/early_time" +require_relative "rake/late_time" +require_relative "rake/name_space" +require_relative "rake/task_manager" +require_relative "rake/application" +require_relative "rake/backtrace" + +# :stopdoc: +# +# Some top level Constants. + +FileList = Rake::FileList +RakeFileUtils = Rake::FileUtilsExt diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb new file mode 100644 index 0000000..39ee5e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb @@ -0,0 +1,847 @@ +# frozen_string_literal: true +require "optparse" + +require_relative "options" +require_relative "task_manager" +require_relative "file_list" +require_relative "thread_pool" +require_relative "thread_history_display" +require_relative "trace_output" +require_relative "win32" + +module Rake + + CommandLineOptionError = Class.new(StandardError) + + ## + # Rake main application object. When invoking +rake+ from the + # command line, a Rake::Application object is created and run. + + class Application + include TaskManager + include TraceOutput + + # The name of the application (typically 'rake') + attr_reader :name + + # The original directory where rake was invoked. + attr_reader :original_dir + + # Name of the actual rakefile used. + attr_reader :rakefile + + # Number of columns on the terminal + attr_accessor :terminal_columns + + # List of the top level task names (task names from the command line). + attr_reader :top_level_tasks + + # Override the detected TTY output state (mostly for testing) + attr_writer :tty_output + + DEFAULT_RAKEFILES = [ + "rakefile", + "Rakefile", + "rakefile.rb", + "Rakefile.rb" + ].freeze + + # Initialize a Rake::Application object. + def initialize + super + @name = "rake" + @rakefiles = DEFAULT_RAKEFILES.dup + @rakefile = nil + @pending_imports = [] + @imported = [] + @loaders = {} + @default_loader = Rake::DefaultLoader.new + @original_dir = Dir.pwd + @top_level_tasks = [] + add_loader("rb", DefaultLoader.new) + add_loader("rf", DefaultLoader.new) + add_loader("rake", DefaultLoader.new) + @tty_output = STDOUT.tty? + @terminal_columns = ENV["RAKE_COLUMNS"].to_i + + set_default_options + end + + # Run the Rake application. The run method performs the following + # three steps: + # + # * Initialize the command line options (+init+). + # * Define the tasks (+load_rakefile+). + # * Run the top level tasks (+top_level+). + # + # If you wish to build a custom rake command, you should call + # +init+ on your application. Then define any tasks. Finally, + # call +top_level+ to run your top level tasks. + def run(argv = ARGV) + standard_exception_handling do + init "rake", argv + load_rakefile + top_level + end + end + + # Initialize the command line parameters and app name. + def init(app_name="rake", argv = ARGV) + standard_exception_handling do + @name = app_name + begin + args = handle_options argv + rescue ArgumentError + # Backward compatibility for capistrano + args = handle_options + end + load_debug_at_stop_feature + collect_command_line_tasks(args) + end + end + + def load_debug_at_stop_feature + return unless ENV["RAKE_DEBUG"] + require "debug/session" + DEBUGGER__::start no_sigint_hook: true, nonstop: true + Rake::Task.prepend Module.new { + def execute(*) + exception = DEBUGGER__::SESSION.capture_exception_frames(/(exe|bin|lib)\/rake/) do + super + end + + if exception + STDERR.puts exception.message + DEBUGGER__::SESSION.enter_postmortem_session exception + raise exception + end + end + } + rescue LoadError + end + private :load_debug_at_stop_feature + + # Find the rakefile and then load it and any pending imports. + def load_rakefile + standard_exception_handling do + raw_load_rakefile + end + end + + # Run the top level tasks of a Rake application. + def top_level + run_with_threads do + if options.show_tasks + display_tasks_and_comments + elsif options.show_prereqs + display_prerequisites + else + top_level_tasks.each { |task_name| invoke_task(task_name) } + end + end + end + + # Run the given block with the thread startup and shutdown. + def run_with_threads + thread_pool.gather_history if options.job_stats == :history + + yield + ensure + thread_pool.join if defined?(@thread_pool) + if options.job_stats + stats = thread_pool.statistics + puts "Maximum active threads: #{stats[:max_active_threads]} + main" + puts "Total threads in play: #{stats[:total_threads_in_play]} + main" + end + ThreadHistoryDisplay.new(thread_pool.history).show if + options.job_stats == :history + end + + # Add a loader to handle imported files ending in the extension + # +ext+. + def add_loader(ext, loader) + ext = ".#{ext}" unless ext =~ /^\./ + @loaders[ext] = loader + end + + # Application options from the command line + def options + @options ||= Options.new + end + + # Return the thread pool used for multithreaded processing. + def thread_pool # :nodoc: + @thread_pool ||= ThreadPool.new(options.thread_pool_size || Rake.suggested_thread_count-1) + end + + # internal ---------------------------------------------------------------- + + # Invokes a task with arguments that are extracted from +task_string+ + def invoke_task(task_string) # :nodoc: + name, args = parse_task_string(task_string) + t = self[name] + t.invoke(*args) + end + + def parse_task_string(string) # :nodoc: + /^([^\[]+)(?:\[(.*)\])$/ =~ string.to_s + + name = $1 + remaining_args = $2 + + return string, [] unless name + return name, [] if remaining_args.empty? + + args = [] + + begin + /\s*((?:[^\\,]|\\.)*?)\s*(?:,\s*(.*))?$/ =~ remaining_args + + remaining_args = $2 + args << $1.gsub(/\\(.)/, '\1') + end while remaining_args + + return name, args + end + + # Provide standard exception handling for the given block. + def standard_exception_handling # :nodoc: + yield + rescue SystemExit + # Exit silently with current status + raise + rescue OptionParser::InvalidOption => ex + $stderr.puts ex.message + exit(false) + rescue Exception => ex + # Exit with error message + display_error_message(ex) + exit_because_of_exception(ex) + end + + # Exit the program because of an unhandled exception. + # (may be overridden by subclasses) + def exit_because_of_exception(ex) # :nodoc: + exit(false) + end + + # Display the error message that caused the exception. + def display_error_message(ex) # :nodoc: + trace "#{name} aborted!" + display_exception_details(ex) + trace "Tasks: #{ex.chain}" if has_chain?(ex) + trace "(See full trace by running task with --trace)" unless + options.backtrace + end + + def display_exception_details(ex) # :nodoc: + display_exception_details_seen << ex + + display_exception_message_details(ex) + display_exception_backtrace(ex) if ex.backtrace + display_cause_details(ex.cause) if has_cause?(ex) + end + + def display_cause_details(ex) # :nodoc: + return if display_exception_details_seen.include? ex + + trace "\nCaused by:" + display_exception_details(ex) + end + + def display_exception_details_seen # :nodoc: + Thread.current[:rake_display_exception_details_seen] ||= [] + end + + def has_cause?(ex) # :nodoc: + ex.respond_to?(:cause) && ex.cause + end + + def display_exception_message_details(ex) # :nodoc: + if ex.instance_of?(RuntimeError) + trace ex.message + elsif ex.respond_to?(:detailed_message) + trace "#{ex.class.name}: #{ex.detailed_message(highlight: false)}" + else + trace "#{ex.class.name}: #{ex.message}" + end + end + + def display_exception_backtrace(ex) # :nodoc: + if options.backtrace + trace ex.backtrace.join("\n") + else + trace Backtrace.collapse(ex.backtrace).join("\n") + end + end + + # Warn about deprecated usage. + # + # Example: + # Rake.application.deprecate("import", "Rake.import", caller.first) + # + def deprecate(old_usage, new_usage, call_site) # :nodoc: + unless options.ignore_deprecate + $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + + "Please use '#{new_usage}' instead.\n" + + " at #{call_site}" + end + end + + # Does the exception have a task invocation chain? + def has_chain?(exception) # :nodoc: + exception.respond_to?(:chain) && exception.chain + end + private :has_chain? + + # True if one of the files in RAKEFILES is in the current directory. + # If a match is found, it is copied into @rakefile. + def have_rakefile # :nodoc: + @rakefiles.each do |fn| + if File.exist?(fn) + others = FileList.glob(fn, File::FNM_CASEFOLD) + return others.size == 1 ? others.first : fn + elsif fn == "" + return fn + end + end + return nil + end + + # True if we are outputting to TTY, false otherwise + def tty_output? # :nodoc: + @tty_output + end + + # We will truncate output if we are outputting to a TTY or if we've been + # given an explicit column width to honor + def truncate_output? # :nodoc: + tty_output? || @terminal_columns.nonzero? + end + + # Display the tasks and comments. + def display_tasks_and_comments # :nodoc: + displayable_tasks = tasks.select { |t| + (options.show_all_tasks || t.comment) && + t.name =~ options.show_task_pattern + } + case options.show_tasks + when :tasks + width = displayable_tasks.map { |t| t.name_with_args.length }.max || 10 + if truncate_output? + max_column = terminal_width - name.size - width - 7 + else + max_column = nil + end + + displayable_tasks.each do |t| + printf("#{name} %-#{width}s # %s\n", + t.name_with_args, + max_column ? truncate(t.comment, max_column) : t.comment) + end + when :describe + displayable_tasks.each do |t| + puts "#{name} #{t.name_with_args}" + comment = t.full_comment || "" + comment.split("\n").each do |line| + puts " #{line}" + end + puts + end + when :lines + displayable_tasks.each do |t| + t.locations.each do |loc| + printf "#{name} %-30s %s\n", t.name_with_args, loc + end + end + else + fail "Unknown show task mode: '#{options.show_tasks}'" + end + end + + def terminal_width # :nodoc: + if @terminal_columns.nonzero? + result = @terminal_columns + else + result = unix? ? dynamic_width : 80 + end + (result < 10) ? 80 : result + rescue + 80 + end + + # Calculate the dynamic width of the + def dynamic_width # :nodoc: + @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) + end + + def dynamic_width_stty # :nodoc: + %x{stty size 2>/dev/null}.split[1].to_i + end + + def dynamic_width_tput # :nodoc: + %x{tput cols 2>/dev/null}.to_i + end + + def unix? # :nodoc: + RbConfig::CONFIG["host_os"] =~ + /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i + end + + def windows? # :nodoc: + Win32.windows? + end + + def truncate(string, width) # :nodoc: + if string.nil? + "" + elsif string.length <= width + string + else + (string[0, width - 3] || "") + "..." + end + end + + # Display the tasks and prerequisites + def display_prerequisites # :nodoc: + tasks.each do |t| + puts "#{name} #{t.name}" + t.prerequisites.each { |pre| puts " #{pre}" } + end + end + + def trace(*strings) # :nodoc: + options.trace_output ||= $stderr + trace_on(options.trace_output, *strings) + end + + def sort_options(options) # :nodoc: + options.sort_by { |opt| + opt.select { |o| o.is_a?(String) && o =~ /^-/ }.map(&:downcase).sort.reverse + } + end + private :sort_options + + # A list of all the standard options used in rake, suitable for + # passing to OptionParser. + def standard_rake_options # :nodoc: + sort_options( + [ + ["--all", "-A", + "Show all tasks, even uncommented ones (in combination with -T or -D)", + lambda { |value| + options.show_all_tasks = value + } + ], + ["--backtrace=[OUT]", + "Enable full backtrace. OUT can be stderr (default) or stdout.", + lambda { |value| + options.backtrace = true + select_trace_output(options, "backtrace", value) + } + ], + ["--build-all", "-B", + "Build all prerequisites, including those which are up-to-date.", + lambda { |value| + options.build_all = true + } + ], + ["--comments", + "Show commented tasks only", + lambda { |value| + options.show_all_tasks = !value + } + ], + ["--describe", "-D [PATTERN]", + "Describe the tasks (matching optional PATTERN), then exit.", + lambda { |value| + select_tasks_to_show(options, :describe, value) + } + ], + ["--directory", "-C [DIRECTORY]", + "Change to DIRECTORY before doing anything.", + lambda { |value| + Dir.chdir value + @original_dir = Dir.pwd + } + ], + ["--dry-run", "-n", + "Do a dry run without executing actions.", + lambda { |value| + Rake.verbose(true) + Rake.nowrite(true) + options.dryrun = true + options.trace = true + } + ], + ["--execute", "-e CODE", + "Execute some Ruby code and exit.", + lambda { |value| + eval(value) + exit + } + ], + ["--execute-print", "-p CODE", + "Execute some Ruby code, print the result, then exit.", + lambda { |value| + puts eval(value) + exit + } + ], + ["--execute-continue", "-E CODE", + "Execute some Ruby code, " + + "then continue with normal task processing.", + lambda { |value| eval(value) } + ], + ["--jobs", "-j [NUMBER]", + "Specifies the maximum number of tasks to execute in parallel. " + + "(default is number of CPU cores + 4)", + lambda { |value| + if value.nil? || value == "" + value = Float::INFINITY + elsif value =~ /^\d+$/ + value = value.to_i + else + value = Rake.suggested_thread_count + end + value = 1 if value < 1 + options.thread_pool_size = value - 1 + } + ], + ["--job-stats [LEVEL]", + "Display job statistics. " + + "LEVEL=history displays a complete job list", + lambda { |value| + if value =~ /^history/i + options.job_stats = :history + else + options.job_stats = true + end + } + ], + ["--libdir", "-I LIBDIR", + "Include LIBDIR in the search path for required modules.", + lambda { |value| $:.push(value) } + ], + ["--multitask", "-m", + "Treat all tasks as multitasks.", + lambda { |value| options.always_multitask = true } + ], + ["--no-search", "--nosearch", + "-N", "Do not search parent directories for the Rakefile.", + lambda { |value| options.nosearch = true } + ], + ["--prereqs", "-P", + "Display the tasks and dependencies, then exit.", + lambda { |value| options.show_prereqs = true } + ], + ["--quiet", "-q", + "Do not log messages to standard output.", + lambda { |value| Rake.verbose(false) } + ], + ["--rakefile", "-f [FILENAME]", + "Use FILENAME as the rakefile to search for.", + lambda { |value| + value ||= "" + @rakefiles.clear + @rakefiles << value + } + ], + ["--rakelibdir", "--rakelib", "-R RAKELIBDIR", + "Auto-import any .rake files in RAKELIBDIR. " + + "(default is 'rakelib')", + lambda { |value| + options.rakelib = value.split(File::PATH_SEPARATOR) + } + ], + ["--require", "-r MODULE", + "Require MODULE before executing rakefile.", + lambda { |value| + begin + require value + rescue LoadError => ex + begin + rake_require value + rescue LoadError + raise ex + end + end + } + ], + ["--rules", + "Trace the rules resolution.", + lambda { |value| options.trace_rules = true } + ], + ["--silent", "-s", + "Like --quiet, but also suppresses the " + + "'in directory' announcement.", + lambda { |value| + Rake.verbose(false) + options.silent = true + } + ], + ["--suppress-backtrace PATTERN", + "Suppress backtrace lines matching regexp PATTERN. " + + "Ignored if --trace is on.", + lambda { |value| + options.suppress_backtrace_pattern = Regexp.new(value) + } + ], + ["--system", "-g", + "Using system wide (global) rakefiles " + + "(usually '~/.rake/*.rake').", + lambda { |value| options.load_system = true } + ], + ["--no-system", "--nosystem", "-G", + "Use standard project Rakefile search paths, " + + "ignore system wide rakefiles.", + lambda { |value| options.ignore_system = true } + ], + ["--tasks", "-T [PATTERN]", + "Display the tasks (matching optional PATTERN) " + + "with descriptions, then exit. " + + "-AT combination displays all the tasks, including those without descriptions.", + lambda { |value| + select_tasks_to_show(options, :tasks, value) + } + ], + ["--trace=[OUT]", "-t", + "Turn on invoke/execute tracing, enable full backtrace. " + + "OUT can be stderr (default) or stdout.", + lambda { |value| + options.trace = true + options.backtrace = true + select_trace_output(options, "trace", value) + Rake.verbose(true) + } + ], + ["--verbose", "-v", + "Log message to standard output.", + lambda { |value| Rake.verbose(true) } + ], + ["--version", "-V", + "Display the program version.", + lambda { |value| + puts "rake, version #{Rake::VERSION}" + exit + } + ], + ["--where", "-W [PATTERN]", + "Describe the tasks (matching optional PATTERN), then exit.", + lambda { |value| + select_tasks_to_show(options, :lines, value) + options.show_all_tasks = true + } + ], + ["--no-deprecation-warnings", "-X", + "Disable the deprecation warnings.", + lambda { |value| + options.ignore_deprecate = true + } + ], + ]) + end + + def select_tasks_to_show(options, show_tasks, value) # :nodoc: + options.show_tasks = show_tasks + options.show_task_pattern = Regexp.new(value || "") + Rake::TaskManager.record_task_metadata = true + end + private :select_tasks_to_show + + def select_trace_output(options, trace_option, value) # :nodoc: + value = value.strip unless value.nil? + case value + when "stdout" + options.trace_output = $stdout + when "stderr", nil + options.trace_output = $stderr + else + fail CommandLineOptionError, + "Unrecognized --#{trace_option} option '#{value}'" + end + end + private :select_trace_output + + # Read and handle the command line options. Returns the command line + # arguments that we didn't understand, which should (in theory) be just + # task names and env vars. + def handle_options(argv) # :nodoc: + set_default_options + + OptionParser.new do |opts| + opts.banner = "#{Rake.application.name} [-f rakefile] {options} targets..." + opts.separator "" + opts.separator "Options are ..." + + opts.on_tail("-h", "--help", "-H", "Display this help message.") do + puts opts + exit + end + + standard_rake_options.each { |args| opts.on(*args) } + opts.environment("RAKEOPT") + end.parse(argv) + end + + # Similar to the regular Ruby +require+ command, but will check + # for *.rake files in addition to *.rb files. + def rake_require(file_name, paths=$LOAD_PATH, loaded=$LOADED_FEATURES) # :nodoc: + fn = file_name + ".rake" + return false if loaded.include?(fn) + paths.each do |path| + full_path = File.join(path, fn) + if File.exist?(full_path) + Rake.load_rakefile(full_path) + loaded << fn + return true + end + end + fail LoadError, "Can't find #{file_name}" + end + + def find_rakefile_location # :nodoc: + here = Dir.pwd + until (fn = have_rakefile) + Dir.chdir("..") + return nil if Dir.pwd == here || options.nosearch + here = Dir.pwd + end + [fn, here] + ensure + Dir.chdir(Rake.original_dir) + end + + def print_rakefile_directory(location) # :nodoc: + $stderr.puts "(in #{Dir.pwd})" unless + options.silent or original_dir == location + end + + def raw_load_rakefile # :nodoc: + rakefile, location = find_rakefile_location + if (!options.ignore_system) && + (options.load_system || rakefile.nil?) && + system_dir && File.directory?(system_dir) + print_rakefile_directory(location) + glob("#{system_dir}/*.rake") do |name| + add_import name + end + else + fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if + rakefile.nil? + @rakefile = rakefile + Dir.chdir(location) + print_rakefile_directory(location) + Rake.load_rakefile(File.expand_path(@rakefile)) if + @rakefile && @rakefile != "" + options.rakelib.each do |rlib| + glob("#{rlib}/*.rake") do |name| + add_import name + end + end + end + load_imports + end + + def glob(path, &block) # :nodoc: + FileList.glob(path.tr("\\", "/")).each(&block) + end + private :glob + + # The directory path containing the system wide rakefiles. + def system_dir # :nodoc: + @system_dir ||= ENV["RAKE_SYSTEM"] || standard_system_dir + end + + # The standard directory containing system wide rake files. + def standard_system_dir #:nodoc: + if windows? + File.join(Dir.home, "Rake") + else + File.join(Dir.home, ".rake") + end + end + private :standard_system_dir + + # Collect the list of tasks on the command line. If no tasks are + # given, return a list containing only the default task. + # Environmental assignments are processed at this time as well. + # + # `args` is the list of arguments to peruse to get the list of tasks. + # It should be the command line that was given to rake, less any + # recognised command-line options, which OptionParser.parse will + # have taken care of already. + def collect_command_line_tasks(args) # :nodoc: + @top_level_tasks = [] + args.each do |arg| + if arg =~ /^(\w+)=(.*)$/m + ENV[$1] = $2 + else + @top_level_tasks << arg unless arg =~ /^-/ + end + end + @top_level_tasks.push(default_task_name) if @top_level_tasks.empty? + end + + # Default task name ("default"). + # (May be overridden by subclasses) + def default_task_name # :nodoc: + "default" + end + + # Add a file to the list of files to be imported. + def add_import(fn) # :nodoc: + @pending_imports << fn + end + + # Load the pending list of imported files. + def load_imports # :nodoc: + while fn = @pending_imports.shift + next if @imported.member?(fn) + fn_task = lookup(fn) and fn_task.invoke + ext = File.extname(fn) + loader = @loaders[ext] || @default_loader + loader.load(fn) + if fn_task = lookup(fn) and fn_task.needed? + fn_task.reenable + fn_task.invoke + loader.load(fn) + end + @imported << fn + end + end + + def rakefile_location(backtrace=caller) # :nodoc: + backtrace.map { |t| t[/([^:]+):/, 1] } + + re = /^#{@rakefile}$/ + re = /#{re.source}/i if windows? + + backtrace.find { |str| str =~ re } || "" + end + + def set_default_options # :nodoc: + options.always_multitask = false + options.backtrace = false + options.build_all = false + options.dryrun = false + options.ignore_deprecate = false + options.ignore_system = false + options.job_stats = false + options.load_system = false + options.nosearch = false + options.rakelib = %w[rakelib] + options.show_all_tasks = false + options.show_prereqs = false + options.show_task_pattern = nil + options.show_tasks = nil + options.silent = false + options.suppress_backtrace_pattern = nil + options.thread_pool_size = Rake.suggested_thread_count + options.trace = false + options.trace_output = $stderr + options.trace_rules = false + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/backtrace.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/backtrace.rb new file mode 100644 index 0000000..c87f2f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/backtrace.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +module Rake + module Backtrace # :nodoc: all + SYS_KEYS = RbConfig::CONFIG.keys.grep(/(?:[a-z]prefix|libdir)\z/) + SYS_PATHS = RbConfig::CONFIG.values_at(*SYS_KEYS).uniq + + [ File.join(File.dirname(__FILE__), "..") ] + + SUPPRESSED_PATHS = SYS_PATHS. + map { |s| s.tr("\\", "/") }. + map { |f| File.expand_path(f) }. + reject { |s| s.nil? || s =~ /^ *$/ } + SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|") + SUPPRESSED_PATHS_RE << "|^" + SUPPRESSED_PATHS_RE << "|^org\\/jruby\\/\\w+\\.java" if + Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == "jruby" + + SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i + + def self.collapse(backtrace) + pattern = Rake.application.options.suppress_backtrace_pattern || + SUPPRESS_PATTERN + backtrace.reject { |elem| elem =~ pattern } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/clean.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/clean.rb new file mode 100644 index 0000000..c49adf9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/clean.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true +# The 'rake/clean' file defines two file lists (CLEAN and CLOBBER) and +# two rake tasks (:clean and :clobber). +# +# [:clean] Clean up the project by deleting scratch files and backup +# files. Add files to the CLEAN file list to have the :clean +# target handle them. +# +# [:clobber] Clobber all generated and non-source files in a project. +# The task depends on :clean, so all the clean files will +# be deleted as well as files in the CLOBBER file list. +# The intent of this task is to return a project to its +# pristine, just unpacked state. + +require_relative "../rake" + +# :stopdoc: + +module Rake + module Cleaner + extend FileUtils + + module_function + + def cleanup_files(file_names) + file_names.each do |file_name| + cleanup(file_name) + end + end + + def cleanup(file_name, **opts) + begin + opts = { verbose: Rake.application.options.trace }.merge(opts) + rm_r file_name, **opts + rescue StandardError => ex + puts "Failed to remove #{file_name}: #{ex}" unless file_already_gone?(file_name) + end + end + + def file_already_gone?(file_name) + return false if File.exist?(file_name) + + path = file_name + prev = nil + + while path = File.dirname(path) + return false if cant_be_deleted?(path) + break if [prev, "."].include?(path) + prev = path + end + true + end + private_class_method :file_already_gone? + + def cant_be_deleted?(path_name) + File.exist?(path_name) && + (!File.readable?(path_name) || !File.executable?(path_name)) + end + private_class_method :cant_be_deleted? + end +end + +CLEAN = ::Rake::FileList["**/*~", "**/*.bak", "**/core"] +CLEAN.clear_exclude.exclude { |fn| + fn.pathmap("%f").downcase == "core" && File.directory?(fn) +} + +desc "Remove any temporary products." +task :clean do + Rake::Cleaner.cleanup_files(CLEAN) +end + +CLOBBER = ::Rake::FileList.new + +desc "Remove any generated files." +task clobber: [:clean] do + Rake::Cleaner.cleanup_files(CLOBBER) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cloneable.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cloneable.rb new file mode 100644 index 0000000..eddb77e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cloneable.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +module Rake + ## + # Mixin for creating easily cloned objects. + + module Cloneable # :nodoc: + # The hook that is invoked by 'clone' and 'dup' methods. + def initialize_copy(source) + super + source.instance_variables.each do |var| + src_value = source.instance_variable_get(var) + value = src_value.clone rescue src_value + instance_variable_set(var, value) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb new file mode 100644 index 0000000..75cc0d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true +module Rake + + # Based on a script at: + # http://stackoverflow.com/questions/891537/ruby-detect-number-of-cpus-installed + class CpuCounter # :nodoc: all + def self.count + new.count_with_default + end + + def count_with_default(default=4) + count || default + rescue StandardError + default + end + + begin + require "etc" + rescue LoadError + else + if Etc.respond_to?(:nprocessors) + def count + return Etc.nprocessors + end + end + end + end +end + +unless Rake::CpuCounter.method_defined?(:count) + Rake::CpuCounter.class_eval <<-'end;', __FILE__, __LINE__+1 + require 'rbconfig' + + def count + if RUBY_PLATFORM == 'java' + count_via_java_runtime + else + case RbConfig::CONFIG['host_os'] + when /linux/ + count_via_cpuinfo + when /darwin|bsd/ + count_via_sysctl + when /mswin|mingw/ + count_via_win32 + else + # Try everything + count_via_win32 || + count_via_sysctl || + count_via_cpuinfo + end + end + end + + def count_via_java_runtime + Java::Java.lang.Runtime.getRuntime.availableProcessors + rescue StandardError + nil + end + + def count_via_win32 + # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0 + result = run_win32( + 'powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores ' \ + '| Select-Object -Property NumberOfCores"' + ) + if !result || $?.exitstatus != 0 + # fallback to deprecated wmic for older systems + result = run_win32("wmic cpu get NumberOfCores") + end + + # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n" + # wmic: "NumberOfCores \n\n4 \n\n\n\n" + result.scan(/\d+/).map(&:to_i).reduce(:+) if result + rescue StandardError + nil + end + + def count_via_cpuinfo + open('/proc/cpuinfo') { |f| f.readlines }.grep(/processor/).size + rescue StandardError + nil + end + + def count_via_sysctl + run 'sysctl', '-n', 'hw.ncpu' + end + + def run(command, *args) + cmd = resolve_command(command) + if cmd + IO.popen [cmd, *args] do |io| + io.read.to_i + end + else + nil + end + end + + def run_win32(command, *args) + IO.popen(command, &:read) + rescue Errno::ENOENT + nil + end + + def resolve_command(command) + look_for_command("/usr/sbin", command) || + look_for_command("/sbin", command) || + in_path_command(command) + end + + def look_for_command(dir, command) + path = File.join(dir, command) + File.exist?(path) ? path : nil + end + + def in_path_command(command) + IO.popen ['which', command] do |io| + io.eof? ? nil : command + end + end + end; +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/default_loader.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/default_loader.rb new file mode 100644 index 0000000..d3b4650 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/default_loader.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +module Rake + + # Default Rakefile loader used by +import+. + class DefaultLoader + + ## + # Loads a rakefile into the current application from +fn+ + + def load(fn) + Rake.load_rakefile(File.expand_path(fn)) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb new file mode 100644 index 0000000..3799068 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb @@ -0,0 +1,196 @@ +# frozen_string_literal: true +# Rake DSL functions. +require_relative "file_utils_ext" + +module Rake + + ## + # DSL is a module that provides #task, #desc, #namespace, etc. Use this + # when you'd like to use rake outside the top level scope. + # + # For a Rakefile you run from the command line this module is automatically + # included. + + module DSL + + #-- + # Include the FileUtils file manipulation functions in the top + # level module, but mark them private so that they don't + # unintentionally define methods on other objects. + #++ + + include FileUtilsExt + private(*FileUtils.instance_methods(false)) + private(*FileUtilsExt.instance_methods(false)) + + private + + # :call-seq: + # task(task_name) + # task(task_name: dependencies) + # task(task_name, arguments => dependencies) + # + # Declare a basic task. The +task_name+ is always the first argument. If + # the task name contains a ":" it is defined in that namespace. + # + # The +dependencies+ may be a single task name or an Array of task names. + # The +argument+ (a single name) or +arguments+ (an Array of names) define + # the arguments provided to the task. + # + # The task, argument and dependency names may be either symbols or + # strings. + # + # A task with a single dependency: + # + # task clobber: %w[clean] do + # rm_rf "html" + # end + # + # A task with an argument and a dependency: + # + # task :package, [:version] => :test do |t, args| + # # ... + # end + # + # To invoke this task from the command line: + # + # $ rake package[1.2.3] + # + def task(*args, &block) # :doc: + Rake::Task.define_task(*args, &block) + end + + # Declare a file task. + # + # Example: + # file "config.cfg" => ["config.template"] do + # open("config.cfg", "w") do |outfile| + # open("config.template") do |infile| + # while line = infile.gets + # outfile.puts line + # end + # end + # end + # end + # + def file(*args, &block) # :doc: + Rake::FileTask.define_task(*args, &block) + end + + # Declare a file creation task. + # (Mainly used for the directory command). + def file_create(*args, &block) + Rake::FileCreationTask.define_task(*args, &block) + end + + # Declare a set of files tasks to create the given directories on + # demand. + # + # Example: + # directory "testdata/doc" + # + def directory(*args, &block) # :doc: + args = args.flat_map { |arg| arg.is_a?(FileList) ? arg.to_a.flatten : arg } + result = file_create(*args, &block) + dir, _ = *Rake.application.resolve_args(args) + dir = Rake.from_pathname(dir) + Rake.each_dir_parent(dir) do |d| + file_create d do |t| + mkdir_p t.name unless File.exist?(t.name) + end + end + result + end + + # Declare a task that performs its prerequisites in + # parallel. Multitasks does *not* guarantee that its prerequisites + # will execute in any given order (which is obvious when you think + # about it) + # + # Example: + # multitask deploy: %w[deploy_gem deploy_rdoc] + # + def multitask(*args, &block) # :doc: + Rake::MultiTask.define_task(*args, &block) + end + + # Create a new rake namespace and use it for evaluating the given + # block. Returns a NameSpace object that can be used to lookup + # tasks defined in the namespace. + # + # Example: + # + # ns = namespace "nested" do + # # the "nested:run" task + # task :run + # end + # task_run = ns[:run] # find :run in the given namespace. + # + # Tasks can also be defined in a namespace by using a ":" in the task + # name: + # + # task "nested:test" do + # # ... + # end + # + def namespace(name=nil, &block) # :doc: + name = name.to_s if name.kind_of?(Symbol) + name = name.to_str if name.respond_to?(:to_str) + unless name.kind_of?(String) || name.nil? + raise ArgumentError, "Expected a String or Symbol for a namespace name" + end + Rake.application.in_namespace(name, &block) + end + + # Declare a rule for auto-tasks. + # + # Example: + # rule '.o' => '.c' do |t| + # sh 'cc', '-c', '-o', t.name, t.source + # end + # + def rule(*args, &block) # :doc: + Rake::Task.create_rule(*args, &block) + end + + # Describes the next rake task. Duplicate descriptions are discarded. + # Descriptions are shown with rake -T (up to the first + # sentence) and rake -D (the entire description). + # + # Example: + # desc "Run the Unit Tests" + # task test: [:build] do + # # ... run tests + # end + # + def desc(description) # :doc: + Rake.application.last_description = description + end + + # Import the partial Rakefiles +fn+. Imported files are loaded + # _after_ the current file is completely loaded. This allows the + # import statement to appear anywhere in the importing file, and yet + # allowing the imported files to depend on objects defined in the + # importing file. + # + # A common use of the import statement is to include files + # containing dependency declarations. + # + # See also the --rakelibdir command line option. + # + # Example: + # import ".depend", "my_rules" + # + def import(*fns) # :doc: + fns.each do |fn| + Rake.application.add_import(fn) + end + end + end + extend FileUtilsExt +end + +# Extend the main object with the DSL commands. This allows top-level +# calls to task, etc. to work from a Rakefile without polluting the +# object inheritance tree. +self.extend Rake::DSL diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/early_time.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/early_time.rb new file mode 100644 index 0000000..80cc6bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/early_time.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +module Rake + + # EarlyTime is a fake timestamp that occurs _before_ any other time value. + class EarlyTime + include Comparable + include Singleton + + ## + # The EarlyTime always comes before +other+! + + def <=>(other) + -1 + end + + def to_s # :nodoc: + "" + end + end + + EARLY = EarlyTime.instance +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/core.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/core.rb new file mode 100644 index 0000000..226f212 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/core.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true +class Module + # Check for an existing method in the current class before extending. If + # the method already exists, then a warning is printed and the extension is + # not added. Otherwise the block is yielded and any definitions in the + # block will take effect. + # + # Usage: + # + # class String + # rake_extension("xyz") do + # def xyz + # ... + # end + # end + # end + # + def rake_extension(method) # :nodoc: + if method_defined?(method) + $stderr.puts "WARNING: Possible conflict with Rake extension: " + + "#{self}##{method} already exists" + else + yield + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/string.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/string.rb new file mode 100644 index 0000000..c82f532 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/string.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true +require_relative "core" + +class String + + rake_extension("ext") do + # Replace the file extension with +newext+. If there is no extension on + # the string, append the new extension to the end. If the new extension + # is not given, or is the empty string, remove any existing extension. + # + # +ext+ is a user added method for the String class. + # + # This String extension comes from Rake + def ext(newext="") + return self.dup if [".", ".."].include? self + if newext != "" + newext = "." + newext unless newext =~ /^\./ + end + self.chomp(File.extname(self)) << newext + end + end + + rake_extension("pathmap") do + # Explode a path into individual components. Used by +pathmap+. + # + # This String extension comes from Rake + def pathmap_explode + head, tail = File.split(self) + return [self] if head == self + return [tail] if head == "." || tail == "/" + return [head, tail] if head == "/" + return head.pathmap_explode + [tail] + end + protected :pathmap_explode + + # Extract a partial path from the path. Include +n+ directories from the + # front end (left hand side) if +n+ is positive. Include |+n+| + # directories from the back end (right hand side) if +n+ is negative. + # + # This String extension comes from Rake + def pathmap_partial(n) + dirs = File.dirname(self).pathmap_explode + partial_dirs = + if n > 0 + dirs[0...n] + elsif n < 0 + dirs.reverse[0...-n].reverse + else + "." + end + File.join(partial_dirs) + end + protected :pathmap_partial + + # Perform the pathmap replacement operations on the given path. The + # patterns take the form 'pat1,rep1;pat2,rep2...'. + # + # This String extension comes from Rake + def pathmap_replace(patterns, &block) + result = self + patterns.split(";").each do |pair| + pattern, replacement = pair.split(",") + pattern = Regexp.new(pattern) + if replacement == "*" && block_given? + result = result.sub(pattern, &block) + elsif replacement + result = result.sub(pattern, replacement) + else + result = result.sub(pattern, "") + end + end + result + end + protected :pathmap_replace + + # Map the path according to the given specification. The specification + # controls the details of the mapping. The following special patterns are + # recognized: + # + # %p :: The complete path. + # %f :: The base file name of the path, with its file extension, + # but without any directories. + # %n :: The file name of the path without its file extension. + # %d :: The directory list of the path. + # %x :: The file extension of the path. An empty string if there + # is no extension. + # %X :: Everything *but* the file extension. + # %s :: The alternate file separator if defined, otherwise use # + # the standard file separator. + # %% :: A percent sign. + # + # The %d specifier can also have a numeric prefix (e.g. '%2d'). + # If the number is positive, only return (up to) +n+ directories in the + # path, starting from the left hand side. If +n+ is negative, return (up + # to) +n+ directories from the right hand side of the path. + # + # Examples: + # + # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b' + # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d' + # + # Also the %d, %p, %f, %n, + # %x, and %X operators can take a pattern/replacement + # argument to perform simple string substitutions on a particular part of + # the path. The pattern and replacement are separated by a comma and are + # enclosed by curly braces. The replacement spec comes after the % + # character but before the operator letter. (e.g. "%{old,new}d"). + # Multiple replacement specs should be separated by semi-colons (e.g. + # "%{old,new;src,bin}d"). + # + # Regular expressions may be used for the pattern, and back refs may be + # used in the replacement text. Curly braces, commas and semi-colons are + # excluded from both the pattern and replacement text (let's keep parsing + # reasonable). + # + # For example: + # + # "src/org/onestepback/proj/A.java".pathmap("%{^src,class}X.class") + # + # returns: + # + # "class/org/onestepback/proj/A.class" + # + # If the replacement text is '*', then a block may be provided to perform + # some arbitrary calculation for the replacement. + # + # For example: + # + # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext| + # ext.downcase + # } + # + # Returns: + # + # "/path/to/file.txt" + # + # This String extension comes from Rake + def pathmap(spec=nil, &block) + return self if spec.nil? + result = "".dup + spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| + case frag + when "%f" + result << File.basename(self) + when "%n" + result << File.basename(self).ext + when "%d" + result << File.dirname(self) + when "%x" + result << File.extname(self) + when "%X" + result << self.ext + when "%p" + result << self + when "%s" + result << (File::ALT_SEPARATOR || File::SEPARATOR) + when "%-" + # do nothing + when "%%" + result << "%" + when /%(-?\d+)d/ + result << pathmap_partial($1.to_i) + when /^%\{([^}]*)\}(\d*[dpfnxX])/ + patterns, operator = $1, $2 + result << pathmap("%" + operator).pathmap_replace(patterns, &block) + when /^%/ + fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" + else + result << frag + end + end + result + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb new file mode 100644 index 0000000..3df254c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +require_relative "file_task" +require_relative "early_time" + +module Rake + + # A FileCreationTask is a file task that when used as a dependency will be + # needed if and only if the file has not been created. Once created, it is + # not re-triggered if any of its dependencies are newer, nor does trigger + # any rebuilds of tasks that depend on it whenever it is updated. + # + class FileCreationTask < FileTask + # Is this file task needed? Yes if it doesn't exist. + def needed? + !File.exist?(name) + end + + # Time stamp for file creation task. This time stamp is earlier + # than any other time stamp. + def timestamp + Rake::EARLY + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_list.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_list.rb new file mode 100644 index 0000000..76078d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_list.rb @@ -0,0 +1,435 @@ +# frozen_string_literal: true +require_relative "cloneable" +require_relative "file_utils_ext" +require_relative "ext/string" + +module Rake + + ## + # A FileList is essentially an array with a few helper methods defined to + # make file manipulation a bit easier. + # + # FileLists are lazy. When given a list of glob patterns for possible files + # to be included in the file list, instead of searching the file structures + # to find the files, a FileList holds the pattern for latter use. + # + # This allows us to define a number of FileList to match any number of + # files, but only search out the actual files when then FileList itself is + # actually used. The key is that the first time an element of the + # FileList/Array is requested, the pending patterns are resolved into a real + # list of file names. + # + class FileList + + include Cloneable + + # == Method Delegation + # + # The lazy evaluation magic of FileLists happens by implementing all the + # array specific methods to call +resolve+ before delegating the heavy + # lifting to an embedded array object (@items). + # + # In addition, there are two kinds of delegation calls. The regular kind + # delegates to the @items array and returns the result directly. Well, + # almost directly. It checks if the returned value is the @items object + # itself, and if so will return the FileList object instead. + # + # The second kind of delegation call is used in methods that normally + # return a new Array object. We want to capture the return value of these + # methods and wrap them in a new FileList object. We enumerate these + # methods in the +SPECIAL_RETURN+ list below. + + # List of array methods (that are not in +Object+) that need to be + # delegated. + ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map(&:to_s) + + # List of additional methods that must be delegated. + MUST_DEFINE = %w[inspect <=>] + + # List of methods that should not be delegated here (we define special + # versions of them explicitly below). + MUST_NOT_DEFINE = %w[to_a to_ary partition * <<] + + # List of delegated methods that return new array values which need + # wrapping. + SPECIAL_RETURN = %w[ + map collect sort sort_by select find_all reject grep + compact flatten uniq values_at + + - & | + ] + + DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).map(&:to_s).sort.uniq + + # Now do the delegation. + DELEGATING_METHODS.each do |sym| + if SPECIAL_RETURN.include?(sym) + ln = __LINE__ + 1 + class_eval %{ + def #{sym}(*args, &block) + resolve + result = @items.send(:#{sym}, *args, &block) + self.class.new.import(result) + end + }, __FILE__, ln + else + ln = __LINE__ + 1 + class_eval %{ + def #{sym}(*args, &block) + resolve + result = @items.send(:#{sym}, *args, &block) + result.object_id == @items.object_id ? self : result + end + }, __FILE__, ln + end + end + + GLOB_PATTERN = %r{[*?\[\{]} + + # Create a file list from the globbable patterns given. If you wish to + # perform multiple includes or excludes at object build time, use the + # "yield self" pattern. + # + # Example: + # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb') + # + # pkg_files = FileList.new('lib/**/*') do |fl| + # fl.exclude(/\bCVS\b/) + # end + # + def initialize(*patterns) + @pending_add = [] + @pending = false + @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup + @exclude_procs = DEFAULT_IGNORE_PROCS.dup + @items = [] + patterns.each { |pattern| include(pattern) } + yield self if block_given? + end + + # Add file names defined by glob patterns to the file list. If an array + # is given, add each element of the array. + # + # Example: + # file_list.include("*.java", "*.cfg") + # file_list.include %w( math.c lib.h *.o ) + # + def include(*filenames) + # TODO: check for pending + filenames.each do |fn| + if fn.respond_to? :to_ary + include(*fn.to_ary) + else + @pending_add << Rake.from_pathname(fn) + end + end + @pending = true + self + end + alias :add :include + + # Register a list of file name patterns that should be excluded from the + # list. Patterns may be regular expressions, glob patterns or regular + # strings. In addition, a block given to exclude will remove entries that + # return true when given to the block. + # + # Note that glob patterns are expanded against the file system. If a file + # is explicitly added to a file list, but does not exist in the file + # system, then an glob pattern in the exclude list will not exclude the + # file. + # + # Examples: + # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c'] + # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c'] + # + # If "a.c" is a file, then ... + # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c'] + # + # If "a.c" is not a file, then ... + # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c'] + # + def exclude(*patterns, &block) + patterns.each do |pat| + if pat.respond_to? :to_ary + exclude(*pat.to_ary) + else + @exclude_patterns << Rake.from_pathname(pat) + end + end + @exclude_procs << block if block_given? + resolve_exclude unless @pending + self + end + + # Clear all the exclude patterns so that we exclude nothing. + def clear_exclude + @exclude_patterns = [] + @exclude_procs = [] + self + end + + # A FileList is equal through array equality. + def ==(array) + to_ary == array + end + + # Return the internal array object. + def to_a + resolve + @items + end + + # Return the internal array object. + def to_ary + to_a + end + + # Lie about our class. + def is_a?(klass) + klass == Array || super(klass) + end + alias kind_of? is_a? + + # Redefine * to return either a string or a new file list. + def *(other) + result = @items * other + case result + when Array + self.class.new.import(result) + else + result + end + end + + def <<(obj) + resolve + @items << Rake.from_pathname(obj) + self + end + + # Resolve all the pending adds now. + def resolve + if @pending + @pending = false + @pending_add.each do |fn| resolve_add(fn) end + @pending_add = [] + resolve_exclude + end + self + end + + def resolve_add(fn) # :nodoc: + case fn + when GLOB_PATTERN + add_matching(fn) + else + self << fn + end + end + private :resolve_add + + def resolve_exclude # :nodoc: + reject! { |fn| excluded_from_list?(fn) } + self + end + private :resolve_exclude + + # Return a new FileList with the results of running +sub+ against each + # element of the original list. + # + # Example: + # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o'] + # + def sub(pat, rep) + inject(self.class.new) { |res, fn| res << fn.sub(pat, rep) } + end + + # Return a new FileList with the results of running +gsub+ against each + # element of the original list. + # + # Example: + # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\") + # => ['lib\\test\\file', 'x\\y'] + # + def gsub(pat, rep) + inject(self.class.new) { |res, fn| res << fn.gsub(pat, rep) } + end + + # Same as +sub+ except that the original file list is modified. + def sub!(pat, rep) + each_with_index { |fn, i| self[i] = fn.sub(pat, rep) } + self + end + + # Same as +gsub+ except that the original file list is modified. + def gsub!(pat, rep) + each_with_index { |fn, i| self[i] = fn.gsub(pat, rep) } + self + end + + # Apply the pathmap spec to each of the included file names, returning a + # new file list with the modified paths. (See String#pathmap for + # details.) + def pathmap(spec=nil, &block) + collect { |fn| fn.pathmap(spec, &block) } + end + + # Return a new FileList with String#ext method applied to + # each member of the array. + # + # This method is a shortcut for: + # + # array.collect { |item| item.ext(newext) } + # + # +ext+ is a user added method for the Array class. + def ext(newext="") + collect { |fn| fn.ext(newext) } + end + + # Grep each of the files in the filelist using the given pattern. If a + # block is given, call the block on each matching line, passing the file + # name, line number, and the matching line of text. If no block is given, + # a standard emacs style file:linenumber:line message will be printed to + # standard out. Returns the number of matched items. + def egrep(pattern, *options) + matched = 0 + each do |fn| + begin + File.open(fn, "r", *options) do |inf| + count = 0 + inf.each do |line| + count += 1 + if pattern.match(line) + matched += 1 + if block_given? + yield fn, count, line + else + puts "#{fn}:#{count}:#{line}" + end + end + end + end + rescue StandardError => ex + $stderr.puts "Error while processing '#{fn}': #{ex}" + end + end + matched + end + + # Return a new file list that only contains file names from the current + # file list that exist on the file system. + def existing + select { |fn| File.exist?(fn) }.uniq + end + + # Modify the current file list so that it contains only file name that + # exist on the file system. + def existing! + resolve + @items = @items.select { |fn| File.exist?(fn) }.uniq + self + end + + # FileList version of partition. Needed because the nested arrays should + # be FileLists in this version. + def partition(&block) # :nodoc: + resolve + result = @items.partition(&block) + [ + self.class.new.import(result[0]), + self.class.new.import(result[1]), + ] + end + + # Convert a FileList to a string by joining all elements with a space. + def to_s + resolve + self.join(" ") + end + + # Add matching glob patterns. + def add_matching(pattern) + self.class.glob(pattern).each do |fn| + self << fn unless excluded_from_list?(fn) + end + end + private :add_matching + + # Should the given file name be excluded from the list? + # + # NOTE: This method was formerly named "exclude?", but Rails + # introduced an exclude? method as an array method and setup a + # conflict with file list. We renamed the method to avoid + # confusion. If you were using "FileList#exclude?" in your user + # code, you will need to update. + def excluded_from_list?(fn) + return true if @exclude_patterns.any? do |pat| + case pat + when Regexp + fn =~ pat + when GLOB_PATTERN + flags = File::FNM_PATHNAME + # Ruby <= 1.9.3 does not support File::FNM_EXTGLOB + flags |= File::FNM_EXTGLOB if defined? File::FNM_EXTGLOB + File.fnmatch?(pat, fn, flags) + else + fn == pat + end + end + @exclude_procs.any? { |p| p.call(fn) } + end + + DEFAULT_IGNORE_PATTERNS = [ + /(^|[\/\\])CVS([\/\\]|$)/, + /(^|[\/\\])\.svn([\/\\]|$)/, + /\.bak$/, + /~$/ + ] + DEFAULT_IGNORE_PROCS = [ + proc { |fn| fn =~ /(^|[\/\\])core$/ && !File.directory?(fn) } + ] + + def import(array) # :nodoc: + @items = array + self + end + + class << self + # Create a new file list including the files listed. Similar to: + # + # FileList.new(*args) + def [](*args) + new(*args) + end + + # Get a sorted list of files matching the pattern. This method + # should be preferred to Dir[pattern] and Dir.glob(pattern) because + # the files returned are guaranteed to be sorted. + def glob(pattern, *args) + Dir.glob(pattern, *args).sort + end + end + end +end + +module Rake + class << self + + # Yield each file or directory component. + def each_dir_parent(dir) # :nodoc: + old_length = nil + while dir != "." && dir.length != old_length + yield(dir) + old_length = dir.length + dir = File.dirname(dir) + end + end + + # Convert Pathname and Pathname-like objects to strings; + # leave everything else alone + def from_pathname(path) # :nodoc: + path = path.to_path if path.respond_to?(:to_path) + path = path.to_str if path.respond_to?(:to_str) + path + end + end +end # module Rake diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_task.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_task.rb new file mode 100644 index 0000000..8c398bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_task.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +require_relative "task" +require_relative "early_time" + +module Rake + + # A FileTask is a task that includes time based dependencies. If any of a + # FileTask's prerequisites have a timestamp that is later than the file + # represented by this task, then the file must be rebuilt (using the + # supplied actions). + # + class FileTask < Task + + # Is this file task needed? Yes if it doesn't exist, or if its time stamp + # is out of date. + def needed? + begin + out_of_date?(File.mtime(name)) || @application.options.build_all + rescue Errno::ENOENT + true + end + end + + # Time stamp for file task. + def timestamp + begin + File.mtime(name) + rescue Errno::ENOENT + Rake::LATE + end + end + + private + + # Are there any prerequisites with a later time than the given time stamp? + def out_of_date?(stamp) + all_prerequisite_tasks.any? { |prereq| + prereq_task = application[prereq, @scope] + if prereq_task.instance_of?(Rake::FileTask) + prereq_task.timestamp > stamp || @application.options.build_all + else + prereq_task.timestamp > stamp + end + } + end + + # ---------------------------------------------------------------- + # Task class methods. + # + class << self + # Apply the scope to the task name according to the rules for this kind + # of task. File based tasks ignore the scope when creating the name. + def scope_name(scope, task_name) + Rake.from_pathname(task_name) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils.rb new file mode 100644 index 0000000..c520917 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true +require "rbconfig" +require "fileutils" + +#-- +# This a FileUtils extension that defines several additional commands to be +# added to the FileUtils utility functions. +module FileUtils + # Path to the currently running Ruby program + RUBY = ENV["RUBY"] || File.join( + RbConfig::CONFIG["bindir"], + RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]). + sub(/.*\s.*/m, '"\&"') + + # Run the system command +cmd+. If multiple arguments are given the command + # is run directly (without the shell, same semantics as Kernel::exec and + # Kernel::system). + # + # It is recommended you use the multiple argument form over interpolating + # user input for both usability and security reasons. With the multiple + # argument form you can easily process files with spaces or other shell + # reserved characters in them. With the multiple argument form your rake + # tasks are not vulnerable to users providing an argument like + # ; rm # -rf /. + # + # If a block is given, upon command completion the block is called with an + # OK flag (true on a zero exit status) and a Process::Status object. + # Without a block a RuntimeError is raised when the command exits non-zero. + # + # Examples: + # + # sh 'ls -ltr' + # + # sh 'ls', 'file with spaces' + # + # # check exit status after command runs + # sh %{grep pattern file} do |ok, res| + # if !ok + # puts "pattern not found (status = #{res.exitstatus})" + # end + # end + # + def sh(*cmd, &block) + options = (Hash === cmd.last) ? cmd.pop : {} + shell_runner = block_given? ? block : create_shell_runner(cmd) + + set_verbose_option(options) + verbose = options.delete :verbose + noop = options.delete(:noop) || Rake::FileUtilsExt.nowrite_flag + + Rake.rake_output_message sh_show_command(cmd, options) if verbose + + unless noop + res = (Hash === cmd.last) ? system(*cmd) : system(*cmd, options) + status = $? + status = Rake::PseudoStatus.new(1) if !res && status.nil? + shell_runner.call(res, status) + end + end + + def create_shell_runner(cmd) # :nodoc: + show_command = sh_show_command cmd + lambda do |ok, status| + ok or + fail "Command failed with status (#{status.exitstatus}): " + + "[#{show_command}]" + end + end + private :create_shell_runner + + def sh_show_command(cmd, options = nil) # :nodoc: + cmd = cmd.dup + + if Hash === cmd.first + env = cmd.first + env = env.map { |name, value| "#{name}=#{value}" }.join " " + cmd[0] = env + end + + cmd = cmd.join " " + if options and chdir = options[:chdir] + "(cd #{chdir} && #{cmd})" + else + cmd + end + end + private :sh_show_command + + def set_verbose_option(options) # :nodoc: + unless options.key? :verbose + options[:verbose] = + (Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT) || + Rake::FileUtilsExt.verbose_flag + end + end + private :set_verbose_option + + # Run a Ruby interpreter with the given arguments. + # + # Example: + # ruby %{-pe '$_.upcase!' 1 + sh(RUBY, *args, **options, &block) + else + sh("#{RUBY} #{args.first}", **options, &block) + end + end + + LN_SUPPORTED = [true] + + # Attempt to do a normal file link, but fall back to a copy if the link + # fails. + def safe_ln(*args, **options) + if LN_SUPPORTED[0] + begin + return options.empty? ? ln(*args) : ln(*args, **options) + rescue StandardError, NotImplementedError + LN_SUPPORTED[0] = false + end + end + options.empty? ? cp(*args) : cp(*args, **options) + end + + # Split a file path into individual directory names. + # + # Example: + # split_all("a/b/c") => ['a', 'b', 'c'] + # + def split_all(path) + head, tail = File.split(path) + return [tail] if head == "." || tail == "/" + return [head, tail] if head == "/" + return split_all(head) + [tail] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb new file mode 100644 index 0000000..58d1c21 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true +require_relative "file_utils" + +module Rake + # + # FileUtilsExt provides a custom version of the FileUtils methods + # that respond to the verbose and nowrite + # commands. + # + module FileUtilsExt + include FileUtils + + class << self + attr_accessor :verbose_flag, :nowrite_flag + end + + DEFAULT = Object.new + + FileUtilsExt.verbose_flag = DEFAULT + FileUtilsExt.nowrite_flag = false + + FileUtils.commands.each do |name| + opts = FileUtils.options_of name + default_options = [] + if opts.include?("verbose") + default_options << "verbose: FileUtilsExt.verbose_flag" + end + if opts.include?("noop") + default_options << "noop: FileUtilsExt.nowrite_flag" + end + + next if default_options.empty? + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}(*args, **options, &block) + super(*args, + #{default_options.join(', ')}, + **options, &block) + end + EOS + end + + # Get/set the verbose flag controlling output from the FileUtils + # utilities. If verbose is true, then the utility method is + # echoed to standard output. + # + # Examples: + # verbose # return the current value of the + # # verbose flag + # verbose(v) # set the verbose flag to _v_. + # verbose(v) { code } # Execute code with the verbose flag set + # # temporarily to _v_. Return to the + # # original value when code is done. + def verbose(value=nil) + oldvalue = FileUtilsExt.verbose_flag + FileUtilsExt.verbose_flag = value unless value.nil? + + if block_given? + begin + yield + ensure + FileUtilsExt.verbose_flag = oldvalue + end + end + FileUtilsExt.verbose_flag + end + + # Get/set the nowrite flag controlling output from the FileUtils + # utilities. If verbose is true, then the utility method is + # echoed to standard output. + # + # Examples: + # nowrite # return the current value of the + # # nowrite flag + # nowrite(v) # set the nowrite flag to _v_. + # nowrite(v) { code } # Execute code with the nowrite flag set + # # temporarily to _v_. Return to the + # # original value when code is done. + def nowrite(value=nil) + oldvalue = FileUtilsExt.nowrite_flag + FileUtilsExt.nowrite_flag = value unless value.nil? + if block_given? + begin + yield + ensure + FileUtilsExt.nowrite_flag = oldvalue + end + end + oldvalue + end + + # Use this function to prevent potentially destructive ruby code + # from running when the :nowrite flag is set. + # + # Example: + # + # when_writing("Building Project") do + # project.build + # end + # + # The following code will build the project under normal + # conditions. If the nowrite(true) flag is set, then the example + # will print: + # + # DRYRUN: Building Project + # + # instead of actually building the project. + # + def when_writing(msg=nil) + if FileUtilsExt.nowrite_flag + $stderr.puts "DRYRUN: #{msg}" if msg + else + yield + end + end + + # Send the message to the default rake output (which is $stderr). + def rake_output_message(message) + $stderr.puts(message) + end + + # Check that the options do not contain options not listed in + # +optdecl+. An ArgumentError exception is thrown if non-declared + # options are found. + def rake_check_options(options, *optdecl) + h = options.dup + optdecl.each do |name| + h.delete name + end + raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless + h.empty? + end + + extend self + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb new file mode 100644 index 0000000..44a9954 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true +module Rake + + # InvocationChain tracks the chain of task invocations to detect + # circular dependencies. + class InvocationChain < LinkedList + + # Is the invocation already in the chain? + def member?(invocation) + head == invocation || tail.member?(invocation) + end + + # Append an invocation to the chain of invocations. It is an error + # if the invocation already listed. + def append(invocation) + if member?(invocation) + fail RuntimeError, "Circular dependency detected: #{to_s} => #{invocation}" + end + conj(invocation) + end + + # Convert to string, ie: TOP => invocation => invocation + def to_s + "#{prefix}#{head}" + end + + # Class level append. + def self.append(invocation, chain) + chain.append(invocation) + end + + private + + def prefix + "#{tail} => " + end + + # Null object for an empty chain. + class EmptyInvocationChain < LinkedList::EmptyLinkedList + @parent = InvocationChain + + def member?(obj) + false + end + + def append(invocation) + conj(invocation) + end + + def to_s + "TOP" + end + end + + EMPTY = EmptyInvocationChain.new + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb new file mode 100644 index 0000000..b0d307a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +module Rake + module InvocationExceptionMixin + # Return the invocation chain (list of Rake tasks) that were in + # effect when this exception was detected by rake. May be null if + # no tasks were active. + def chain + @rake_invocation_chain ||= nil + end + + # Set the invocation chain in effect when this exception was + # detected. + def chain=(value) + @rake_invocation_chain = value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/late_time.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/late_time.rb new file mode 100644 index 0000000..8fe0249 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/late_time.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +module Rake + # LateTime is a fake timestamp that occurs _after_ any other time value. + class LateTime + include Comparable + include Singleton + + def <=>(other) + 1 + end + + def to_s + "" + end + end + + LATE = LateTime.instance +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/linked_list.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/linked_list.rb new file mode 100644 index 0000000..11fa46f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/linked_list.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true +module Rake + + # Polylithic linked list structure used to implement several data + # structures in Rake. + class LinkedList + include Enumerable + attr_reader :head, :tail + + # Polymorphically add a new element to the head of a list. The + # type of head node will be the same list type as the tail. + def conj(item) + self.class.cons(item, self) + end + + # Is the list empty? + # .make guards against a list being empty making any instantiated LinkedList + # object not empty by default + # You should consider overriding this method if you implement your own .make method + def empty? + false + end + + # Lists are structurally equivalent. + def ==(other) + current = self + while !current.empty? && !other.empty? + return false if current.head != other.head + current = current.tail + other = other.tail + end + current.empty? && other.empty? + end + + # Convert to string: LL(item, item...) + def to_s + items = map(&:to_s).join(", ") + "LL(#{items})" + end + + # Same as +to_s+, but with inspected items. + def inspect + items = map(&:inspect).join(", ") + "LL(#{items})" + end + + # For each item in the list. + def each + current = self + while !current.empty? + yield(current.head) + current = current.tail + end + self + end + + # Make a list out of the given arguments. This method is + # polymorphic + def self.make(*args) + # return an EmptyLinkedList if there are no arguments + return empty if !args || args.empty? + + # build a LinkedList by starting at the tail and iterating + # through each argument + # inject takes an EmptyLinkedList to start + args.reverse.inject(empty) do |list, item| + list = cons(item, list) + list # return the newly created list for each item in the block + end + end + + # Cons a new head onto the tail list. + def self.cons(head, tail) + new(head, tail) + end + + # The standard empty list class for the given LinkedList class. + def self.empty + self::EMPTY + end + + protected + + def initialize(head, tail=EMPTY) + @head = head + @tail = tail + end + + # Represent an empty list, using the Null Object Pattern. + # + # When inheriting from the LinkedList class, you should implement + # a type specific Empty class as well. Make sure you set the class + # instance variable @parent to the associated list class (this + # allows conj, cons and make to work polymorphically). + class EmptyLinkedList < LinkedList + @parent = LinkedList + + def initialize + end + + def empty? + true + end + + def self.cons(head, tail) + @parent.cons(head, tail) + end + end + + EMPTY = EmptyLinkedList.new + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb new file mode 100644 index 0000000..46f4bea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +module Rake + + # Makefile loader to be used with the import file loader. Use this to + # import dependencies from make dependency tools: + # + # require 'rake/loaders/makefile' + # + # file ".depends.mf" => [SRC_LIST] do |t| + # sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" + # end + # + # import ".depends.mf" + # + # See {Importing Dependencies}[link:doc/rakefile_rdoc.html#label-Importing+Dependencies] + # for further details. + + class MakefileLoader + include Rake::DSL + + SPACE_MARK = "\0" # :nodoc: + + # Load the makefile dependencies in +fn+. + def load(fn) # :nodoc: + lines = File.read fn + lines.gsub!(/\\ /, SPACE_MARK) + lines.gsub!(/#[^\n]*\n/m, "") + lines.gsub!(/\\\n/, " ") + lines.each_line do |line| + process_line(line) + end + end + + private + + # Process one logical line of makefile data. + def process_line(line) # :nodoc: + file_tasks, args = line.split(":", 2) + return if args.nil? + dependents = args.split.map { |d| respace(d) } + file_tasks.scan(/\S+/) do |file_task| + file_task = respace(file_task) + file file_task => dependents + end + end + + def respace(str) # :nodoc: + str.tr SPACE_MARK, " " + end + end + + # Install the handler + Rake.application.add_loader("mf", MakefileLoader.new) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/multi_task.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/multi_task.rb new file mode 100644 index 0000000..3ae363c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/multi_task.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +module Rake + + # Same as a regular task, but the immediate prerequisites are done in + # parallel using Ruby threads. + # + class MultiTask < Task + private + + def invoke_prerequisites(task_args, invocation_chain) # :nodoc: + invoke_prerequisites_concurrently(task_args, invocation_chain) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/name_space.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/name_space.rb new file mode 100644 index 0000000..32f8139 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/name_space.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true +## +# The NameSpace class will lookup task names in the scope defined by a +# +namespace+ command. + +class Rake::NameSpace + + ## + # Create a namespace lookup object using the given task manager + # and the list of scopes. + + def initialize(task_manager, scope_list) + @task_manager = task_manager + @scope = scope_list.dup + end + + ## + # Lookup a task named +name+ in the namespace. + + def [](name) + @task_manager.lookup(name, @scope) + end + + ## + # The scope of the namespace (a LinkedList) + + def scope + @scope.dup + end + + ## + # Return the list of tasks defined in this and nested namespaces. + + def tasks + @task_manager.tasks_in_scope(@scope) + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/options.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/options.rb new file mode 100644 index 0000000..01974c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/options.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Rake + + ## + # Options used by the Rake command line application. + # + class Options + attr_accessor :always_multitask + attr_accessor :backtrace + attr_accessor :build_all + attr_accessor :dryrun + attr_accessor :ignore_deprecate + attr_accessor :ignore_system + attr_accessor :job_stats + attr_accessor :load_system + attr_accessor :nosearch + attr_accessor :rakelib + attr_accessor :show_all_tasks + attr_accessor :show_prereqs + attr_accessor :show_task_pattern + attr_accessor :show_tasks + attr_accessor :silent + attr_accessor :suppress_backtrace_pattern + attr_accessor :thread_pool_size + attr_accessor :trace + attr_accessor :trace_output + attr_accessor :trace_rules + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/packagetask.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/packagetask.rb new file mode 100644 index 0000000..80a4acf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/packagetask.rb @@ -0,0 +1,222 @@ +# frozen_string_literal: true +# Define a package task library to aid in the definition of +# redistributable package files. + +require_relative "../rake" +require_relative "tasklib" + +module Rake + + # Create a packaging task that will package the project into + # distributable files (e.g zip archive or tar files). + # + # The PackageTask will create the following targets: + # + # +:package+ :: + # Create all the requested package files. + # + # +:clobber_package+ :: + # Delete all the package files. This target is automatically + # added to the main clobber target. + # + # +:repackage+ :: + # Rebuild the package files from scratch, even if they are not out + # of date. + # + # "package_dir/name-version.tgz" :: + # Create a gzipped tar package (if need_tar is true). + # + # "package_dir/name-version.tar.gz" :: + # Create a gzipped tar package (if need_tar_gz is true). + # + # "package_dir/name-version.tar.bz2" :: + # Create a bzip2'd tar package (if need_tar_bz2 is true). + # + # "package_dir/name-version.zip" :: + # Create a zip package archive (if need_zip is true). + # + # Example: + # + # Rake::PackageTask.new("rake", "1.2.3") do |p| + # p.need_tar = true + # p.package_files.include("lib/**/*.rb") + # end + # + class PackageTask < TaskLib + # Name of the package (from the GEM Spec). + attr_accessor :name + + # Version of the package (e.g. '1.3.2'). + attr_accessor :version + + # Directory used to store the package files (default is 'pkg'). + attr_accessor :package_dir + + # True if a gzipped tar file (tgz) should be produced (default is + # false). + attr_accessor :need_tar + + # True if a gzipped tar file (tar.gz) should be produced (default + # is false). + attr_accessor :need_tar_gz + + # True if a bzip2'd tar file (tar.bz2) should be produced (default + # is false). + attr_accessor :need_tar_bz2 + + # True if a xz'd tar file (tar.xz) should be produced (default is false) + attr_accessor :need_tar_xz + + # True if a zip file should be produced (default is false) + attr_accessor :need_zip + + # List of files to be included in the package. + attr_accessor :package_files + + # Tar command for gzipped or bzip2ed archives. The default is 'tar'. + attr_accessor :tar_command + + # Zip command for zipped archives. The default is 'zip'. + attr_accessor :zip_command + + # True if parent directory should be omitted (default is false) + attr_accessor :without_parent_dir + + # Create a Package Task with the given name and version. Use +:noversion+ + # as the version to build a package without a version or to provide a + # fully-versioned package name. + + def initialize(name=nil, version=nil) + init(name, version) + yield self if block_given? + define unless name.nil? + end + + # Initialization that bypasses the "yield self" and "define" step. + def init(name, version) + @name = name + @version = version + @package_files = Rake::FileList.new + @package_dir = "pkg" + @need_tar = false + @need_tar_gz = false + @need_tar_bz2 = false + @need_tar_xz = false + @need_zip = false + @tar_command = "tar" + @zip_command = "zip" + @without_parent_dir = false + end + + # Create the tasks defined by this task library. + def define + fail "Version required (or :noversion)" if @version.nil? + @version = nil if :noversion == @version + + desc "Build all the packages" + task :package + + desc "Force a rebuild of the package files" + task repackage: [:clobber_package, :package] + + desc "Remove package products" + task :clobber_package do + rm_r package_dir rescue nil + end + + task clobber: [:clobber_package] + + [ + [need_tar, tgz_file, "z"], + [need_tar_gz, tar_gz_file, "z"], + [need_tar_bz2, tar_bz2_file, "j"], + [need_tar_xz, tar_xz_file, "J"] + ].each do |need, file, flag| + if need + task package: ["#{package_dir}/#{file}"] + file "#{package_dir}/#{file}" => + [package_dir_path] + package_files do + chdir(working_dir) { sh @tar_command, "#{flag}cvf", file, target_dir } + mv "#{package_dir_path}/#{target_dir}", package_dir if without_parent_dir + end + end + end + + if need_zip + task package: ["#{package_dir}/#{zip_file}"] + file "#{package_dir}/#{zip_file}" => + [package_dir_path] + package_files do + chdir(working_dir) { sh @zip_command, "-r", zip_file, target_dir } + mv "#{package_dir_path}/#{zip_file}", package_dir if without_parent_dir + end + end + + directory package_dir_path => @package_files do + @package_files.each do |fn| + f = File.join(package_dir_path, fn) + fdir = File.dirname(f) + mkdir_p(fdir) unless File.exist?(fdir) + if File.directory?(fn) + mkdir_p(f) + else + rm_f f + safe_ln(fn, f) + end + end + end + self + end + + # The name of this package + + def package_name + @version ? "#{@name}-#{@version}" : @name + end + + # The directory this package will be built in + + def package_dir_path + "#{package_dir}/#{package_name}" + end + + # The package name with .tgz added + + def tgz_file + "#{package_name}.tgz" + end + + # The package name with .tar.gz added + + def tar_gz_file + "#{package_name}.tar.gz" + end + + # The package name with .tar.bz2 added + + def tar_bz2_file + "#{package_name}.tar.bz2" + end + + # The package name with .tar.xz added + + def tar_xz_file + "#{package_name}.tar.xz" + end + + # The package name with .zip added + + def zip_file + "#{package_name}.zip" + end + + def working_dir + without_parent_dir ? package_dir_path : package_dir + end + + # target directory relative to working_dir + def target_dir + without_parent_dir ? "." : package_name + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/phony.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/phony.rb new file mode 100644 index 0000000..8f62b7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/phony.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +# Defines a :phony task that you can use as a dependency. This allows +# file-based tasks to use non-file-based tasks as prerequisites +# without forcing them to rebuild. +# +# See FileTask#out_of_date? and Task#timestamp for more info. + +require_relative "../rake" + +task :phony + +Rake::Task[:phony].tap do |task| + def task.timestamp # :nodoc: + Time.at 0 + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/private_reader.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/private_reader.rb new file mode 100644 index 0000000..2815ce6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/private_reader.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +module Rake + + # Include PrivateReader to use +private_reader+. + module PrivateReader # :nodoc: all + + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + + # Declare a list of private accessors + def private_reader(*names) + attr_reader(*names) + private(*names) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/promise.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/promise.rb new file mode 100644 index 0000000..f45af4f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/promise.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true +module Rake + + # A Promise object represents a promise to do work (a chore) in the + # future. The promise is created with a block and a list of + # arguments for the block. Calling value will return the value of + # the promised chore. + # + # Used by ThreadPool. + # + class Promise # :nodoc: all + NOT_SET = Object.new.freeze # :nodoc: + + attr_accessor :recorder + + # Create a promise to do the chore specified by the block. + def initialize(args, &block) + @mutex = Mutex.new + @result = NOT_SET + @error = NOT_SET + @args = args + @block = block + end + + # Return the value of this promise. + # + # If the promised chore is not yet complete, then do the work + # synchronously. We will wait. + def value + unless complete? + stat :sleeping_on, item_id: object_id + @mutex.synchronize do + stat :has_lock_on, item_id: object_id + chore + stat :releasing_lock_on, item_id: object_id + end + end + error? ? raise(@error) : @result + end + + # If no one else is working this promise, go ahead and do the chore. + def work + stat :attempting_lock_on, item_id: object_id + if @mutex.try_lock + stat :has_lock_on, item_id: object_id + chore + stat :releasing_lock_on, item_id: object_id + @mutex.unlock + else + stat :bailed_on, item_id: object_id + end + end + + private + + # Perform the chore promised + def chore + if complete? + stat :found_completed, item_id: object_id + return + end + stat :will_execute, item_id: object_id + begin + @result = @block.call(*@args) + rescue Exception => e + @error = e + end + stat :did_execute, item_id: object_id + discard + end + + # Do we have a result for the promise + def result? + !@result.equal?(NOT_SET) + end + + # Did the promise throw an error + def error? + !@error.equal?(NOT_SET) + end + + # Are we done with the promise + def complete? + result? || error? + end + + # free up these items for the GC + def discard + @args = nil + @block = nil + end + + # Record execution statistics if there is a recorder + def stat(*args) + @recorder.call(*args) if @recorder + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb new file mode 100644 index 0000000..8b3c989 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +module Rake + + ## + # Exit status class for times the system just gives us a nil. + class PseudoStatus # :nodoc: all + attr_reader :exitstatus + + def initialize(code=0) + @exitstatus = code + end + + def to_i + @exitstatus << 8 + end + + def >>(n) + to_i >> n + end + + def stopped? + false + end + + def exited? + true + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_module.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_module.rb new file mode 100644 index 0000000..03c2956 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_module.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +require "rake/application" + +module Rake + + class << self + # Current Rake Application + def application + @application ||= Rake::Application.new + end + + # Set the current Rake application object. + def application=(app) + @application = app + end + + def suggested_thread_count # :nodoc: + @cpu_count ||= Rake::CpuCounter.count + @cpu_count + 4 + end + + # Return the original directory where the Rake application was started. + def original_dir + application.original_dir + end + + # Load a rakefile. + def load_rakefile(path) + load(path) + end + + # Add files to the rakelib list + def add_rakelib(*files) + application.options.rakelib ||= [] + application.options.rakelib.concat(files) + end + + # Make +block_application+ the default rake application inside a block so + # you can load rakefiles into a different application. + # + # This is useful when you want to run rake tasks inside a library without + # running rake in a sub-shell. + # + # Example: + # + # Dir.chdir 'other/directory' + # + # other_rake = Rake.with_application do |rake| + # rake.load_rakefile + # end + # + # puts other_rake.tasks + + def with_application(block_application = Rake::Application.new) + orig_application = Rake.application + + Rake.application = block_application + + yield block_application + + block_application + ensure + Rake.application = orig_application + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb new file mode 100644 index 0000000..05d89fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require_relative "file_list" + +# Load the test files from the command line. +argv = ARGV.select do |argument| + case argument + when /^-/ then + argument + when /\*/ then + Rake::FileList[argument].to_a.each do |file| + require File.expand_path file + end + + false + else + path = File.expand_path argument + + abort "\nFile does not exist: #{path}\n\n" unless File.exist?(path) + + require path + + false + end +end + +ARGV.replace argv diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb new file mode 100644 index 0000000..a51e774 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +module Rake + + # Error indicating a recursion overflow error in task selection. + class RuleRecursionOverflowError < StandardError + def initialize(*args) + super + @targets = [] + end + + def add_target(target) + @targets << target + end + + def message + super + ": [" + @targets.reverse.join(" => ") + "]" + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/scope.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/scope.rb new file mode 100644 index 0000000..fc1eb6c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/scope.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true +module Rake + class Scope < LinkedList # :nodoc: all + + # Path for the scope. + def path + map(&:to_s).reverse.join(":") + end + + # Path for the scope + the named path. + def path_with_task_name(task_name) + "#{path}:#{task_name}" + end + + # Trim +n+ innermost scope levels from the scope. In no case will + # this trim beyond the toplevel scope. + def trim(n) + result = self + while n > 0 && !result.empty? + result = result.tail + n -= 1 + end + result + end + + # Scope lists always end with an EmptyScope object. See Null + # Object Pattern) + class EmptyScope < EmptyLinkedList + @parent = Scope + + def path + "" + end + + def path_with_task_name(task_name) + task_name + end + end + + # Singleton null object for an empty scope. + EMPTY = EmptyScope.new + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb new file mode 100644 index 0000000..e61ccb6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb @@ -0,0 +1,434 @@ +# frozen_string_literal: true +require_relative "invocation_exception_mixin" + +module Rake + + ## + # A Task is the basic unit of work in a Rakefile. Tasks have associated + # actions (possibly more than one) and a list of prerequisites. When + # invoked, a task will first ensure that all of its prerequisites have an + # opportunity to run and then it will execute its own actions. + # + # Tasks are not usually created directly using the new method, but rather + # use the +file+ and +task+ convenience methods. + # + class Task + # List of prerequisites for a task. + attr_reader :prerequisites + alias prereqs prerequisites + + # List of order only prerequisites for a task. + attr_reader :order_only_prerequisites + + # List of actions attached to a task. + attr_reader :actions + + # Application owning this task. + attr_accessor :application + + # Array of nested namespaces names used for task lookup by this task. + attr_reader :scope + + # File/Line locations of each of the task definitions for this + # task (only valid if the task was defined with the detect + # location option set). + attr_reader :locations + + # Has this task already been invoked? Already invoked tasks + # will be skipped unless you reenable them. + attr_reader :already_invoked + + # Return task name + def to_s + name + end + + def inspect # :nodoc: + "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>" + end + + # List of sources for task. + attr_writer :sources + def sources + if defined?(@sources) + @sources + else + prerequisites + end + end + + # List of prerequisite tasks + def prerequisite_tasks + (prerequisites + order_only_prerequisites).map { |pre| lookup_prerequisite(pre) } + end + + def lookup_prerequisite(prerequisite_name) # :nodoc: + scoped_prerequisite_task = application[prerequisite_name, @scope] + if scoped_prerequisite_task == self + unscoped_prerequisite_task = application[prerequisite_name] + end + unscoped_prerequisite_task || scoped_prerequisite_task + end + private :lookup_prerequisite + + # List of all unique prerequisite tasks including prerequisite tasks' + # prerequisites. + # Includes self when cyclic dependencies are found. + def all_prerequisite_tasks + seen = {} + collect_prerequisites(seen) + seen.values + end + + def collect_prerequisites(seen) # :nodoc: + prerequisite_tasks.each do |pre| + next if seen[pre.name] + seen[pre.name] = pre + pre.collect_prerequisites(seen) + end + end + protected :collect_prerequisites + + # First source from a rule (nil if no sources) + def source + sources.first + end + + # Create a task named +task_name+ with no actions or prerequisites. Use + # +enhance+ to add actions and prerequisites. + def initialize(task_name, app) + @name = task_name.to_s + @prerequisites = [] + @actions = [] + @already_invoked = false + @comments = [] + @lock = Monitor.new + @application = app + @scope = app.current_scope + @arg_names = nil + @locations = [] + @invocation_exception = nil + @order_only_prerequisites = [] + end + + # Enhance a task with prerequisites or actions. Returns self. + def enhance(deps=nil, &block) + @prerequisites |= deps if deps + @actions << block if block_given? + self + end + + # Name of the task, including any namespace qualifiers. + def name + @name.to_s + end + + # Name of task with argument list description. + def name_with_args # :nodoc: + if arg_description + "#{name}#{arg_description}" + else + name + end + end + + # Argument description (nil if none). + def arg_description # :nodoc: + @arg_names ? "[#{arg_names.join(',')}]" : nil + end + + # Name of arguments for this task. + def arg_names + @arg_names || [] + end + + # Reenable the task, allowing its tasks to be executed if the task + # is invoked again. + def reenable + @already_invoked = false + @invocation_exception = nil + end + + # Clear the existing prerequisites, actions, comments, and arguments of a rake task. + def clear + clear_prerequisites + clear_actions + clear_comments + clear_args + self + end + + # Clear the existing prerequisites of a rake task. + def clear_prerequisites + prerequisites.clear + self + end + + # Clear the existing actions on a rake task. + def clear_actions + actions.clear + self + end + + # Clear the existing comments on a rake task. + def clear_comments + @comments = [] + self + end + + # Clear the existing arguments on a rake task. + def clear_args + @arg_names = nil + self + end + + # Invoke the task if it is needed. Prerequisites are invoked first. + def invoke(*args) + task_args = TaskArguments.new(arg_names, args) + invoke_with_call_chain(task_args, InvocationChain::EMPTY) + end + + # Same as invoke, but explicitly pass a call chain to detect + # circular dependencies. + # + # If multiple tasks depend on this + # one in parallel, they will all fail if the first execution of + # this task fails. + def invoke_with_call_chain(task_args, invocation_chain) + new_chain = Rake::InvocationChain.append(self, invocation_chain) + @lock.synchronize do + begin + if application.options.trace + application.trace "** Invoke #{name} #{format_trace_flags}" + end + + if @already_invoked + if @invocation_exception + if application.options.trace + application.trace "** Previous invocation of #{name} failed #{format_trace_flags}" + end + raise @invocation_exception + else + return + end + end + + @already_invoked = true + + invoke_prerequisites(task_args, new_chain) + execute(task_args) if needed? + rescue Exception => ex + add_chain_to(ex, new_chain) + @invocation_exception = ex + raise ex + end + end + end + protected :invoke_with_call_chain + + def add_chain_to(exception, new_chain) # :nodoc: + exception.extend(InvocationExceptionMixin) unless + exception.respond_to?(:chain) + exception.chain = new_chain if exception.chain.nil? + end + private :add_chain_to + + # Invoke all the prerequisites of a task. + def invoke_prerequisites(task_args, invocation_chain) # :nodoc: + if application.options.always_multitask + invoke_prerequisites_concurrently(task_args, invocation_chain) + else + prerequisite_tasks.each { |p| + prereq_args = task_args.new_scope(p.arg_names) + p.invoke_with_call_chain(prereq_args, invocation_chain) + } + end + end + + # Invoke all the prerequisites of a task in parallel. + def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc: + futures = prerequisite_tasks.map do |p| + prereq_args = task_args.new_scope(p.arg_names) + application.thread_pool.future(p) do |r| + r.invoke_with_call_chain(prereq_args, invocation_chain) + end + end + # Iterate in reverse to improve performance related to thread waiting and switching + futures.reverse_each(&:value) + end + + # Format the trace flags for display. + def format_trace_flags + flags = [] + flags << "first_time" unless @already_invoked + flags << "not_needed" unless needed? + flags.empty? ? "" : "(" + flags.join(", ") + ")" + end + private :format_trace_flags + + # Execute the actions associated with this task. + def execute(args=nil) + args ||= EMPTY_TASK_ARGS + if application.options.dryrun + application.trace "** Execute (dry run) #{name}" + return + end + application.trace "** Execute #{name}" if application.options.trace + application.enhance_with_matching_rule(name) if @actions.empty? + if opts = Hash.try_convert(args) and !opts.empty? + @actions.each { |act| act.call(self, args, **opts) } + else + @actions.each { |act| act.call(self, args) } + end + end + + # Is this task needed? + def needed? + true + end + + # Timestamp for this task. Basic tasks return the current time for their + # time stamp. Other tasks can be more sophisticated. + def timestamp + Time.now + end + + # Add a description to the task. The description can consist of an option + # argument list (enclosed brackets) and an optional comment. + def add_description(description) + return unless description + comment = description.strip + add_comment(comment) if comment && !comment.empty? + end + + def comment=(comment) # :nodoc: + add_comment(comment) + end + + def add_comment(comment) # :nodoc: + return if comment.nil? + @comments << comment unless @comments.include?(comment) + end + private :add_comment + + # Full collection of comments. Multiple comments are separated by + # newlines. + def full_comment + transform_comments("\n") + end + + # First line (or sentence) of all comments. Multiple comments are + # separated by a "/". + def comment + transform_comments(" / ") { |c| first_sentence(c) } + end + + # Transform the list of comments as specified by the block and + # join with the separator. + def transform_comments(separator, &block) + if @comments.empty? + nil + else + block ||= lambda { |c| c } + @comments.map(&block).join(separator) + end + end + private :transform_comments + + # Get the first sentence in a string. The sentence is terminated + # by the first period, exclamation mark, or the end of the line. + # Decimal points do not count as periods. + def first_sentence(string) + string.split(/(?<=\w)(\.|!)[ \t]|(\.$|!)|\n/).first + end + private :first_sentence + + # Set the names of the arguments for this task. +args+ should be + # an array of symbols, one for each argument name. + def set_arg_names(args) + @arg_names = args.map(&:to_sym) + end + + # Return a string describing the internal state of a task. Useful for + # debugging. + def investigation + result = "------------------------------\n".dup + result << "Investigating #{name}\n" + result << "class: #{self.class}\n" + result << "task needed: #{needed?}\n" + result << "timestamp: #{timestamp}\n" + result << "pre-requisites: \n" + prereqs = prerequisite_tasks + prereqs.sort! { |a, b| a.timestamp <=> b.timestamp } + prereqs.each do |p| + result << "--#{p.name} (#{p.timestamp})\n" + end + latest_prereq = prerequisite_tasks.map(&:timestamp).max + result << "latest-prerequisite time: #{latest_prereq}\n" + result << "................................\n\n" + return result + end + + # Format dependencies parameter to pass to task. + def self.format_deps(deps) + deps = [deps] unless deps.respond_to?(:to_ary) + deps.map { |d| Rake.from_pathname(d).to_s } + end + + # Add order only dependencies. + def |(deps) + @order_only_prerequisites |= Task.format_deps(deps) - @prerequisites + self + end + + # ---------------------------------------------------------------- + # Rake Module Methods + # + class << self + + # Clear the task list. This cause rake to immediately forget all the + # tasks that have been assigned. (Normally used in the unit tests.) + def clear + Rake.application.clear + end + + # List of all defined tasks. + def tasks + Rake.application.tasks + end + + # Return a task with the given name. If the task is not currently + # known, try to synthesize one from the defined rules. If no rules are + # found, but an existing file matches the task name, assume it is a file + # task with no dependencies or actions. + def [](task_name) + Rake.application[task_name] + end + + # TRUE if the task name is already defined. + def task_defined?(task_name) + Rake.application.lookup(task_name) != nil + end + + # Define a task given +args+ and an option block. If a rule with the + # given name already exists, the prerequisites and actions are added to + # the existing task. Returns the defined task. + def define_task(*args, &block) + Rake.application.define_task(self, *args, &block) + end + + # Define a rule for synthesizing tasks. + def create_rule(*args, &block) + Rake.application.create_rule(*args, &block) + end + + # Apply the scope to the task name according to the rules for + # this kind of task. Generic tasks will accept the scope as + # part of the name. + def scope_name(scope, task_name) + scope.path_with_task_name(task_name) + end + + end # class << Rake::Task + end # class Rake::Task +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb new file mode 100644 index 0000000..ef20076 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +module Rake + + # Error indicating an ill-formed task declaration. + class TaskArgumentError < ArgumentError + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_arguments.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_arguments.rb new file mode 100644 index 0000000..24abebc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_arguments.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true +module Rake + + ## + # TaskArguments manage the arguments passed to a task. + # + class TaskArguments + include Enumerable + + # Argument names + attr_reader :names + + # Create a TaskArgument object with a list of argument +names+ and a set + # of associated +values+. +parent+ is the parent argument object. + def initialize(names, values, parent=nil) + @names = names + @parent = parent + @hash = {} + @values = values + names.each_with_index { |name, i| + next if values[i].nil? || values[i] == "" + @hash[name.to_sym] = values[i] + } + end + + # Retrieve the complete array of sequential values + def to_a + @values.dup + end + + # Retrieve the list of values not associated with named arguments + def extras + @values[@names.length..-1] || [] + end + + # Create a new argument scope using the prerequisite argument + # names. + def new_scope(names) + values = names.map { |n| self[n] } + self.class.new(names, values + extras, self) + end + + # Find an argument value by name or index. + def [](index) + lookup(index.to_sym) + end + + # Specify a hash of default values for task arguments. Use the + # defaults only if there is no specific value for the given + # argument. + def with_defaults(defaults) + @hash = defaults.merge(@hash) + end + + # Enumerates the arguments and their values + def each(&block) + @hash.each(&block) + end + + # Extracts the argument values at +keys+ + def values_at(*keys) + keys.map { |k| lookup(k) } + end + + # Returns the value of the given argument via method_missing + def method_missing(sym, *args) + lookup(sym.to_sym) + end + + # Returns a Hash of arguments and their values + def to_hash + @hash.dup + end + + def to_s # :nodoc: + inspect + end + + def inspect # :nodoc: + inspection = @hash.map do |k,v| + "#{k.to_s}: #{v.to_s}" + end.join(", ") + + "#<#{self.class} #{inspection}>" + end + + # Returns true if +key+ is one of the arguments + def has_key?(key) + @hash.has_key?(key) + end + alias key? has_key? + + def fetch(*args, &block) + @hash.fetch(*args, &block) + end + + def deconstruct_keys(keys) + keys ? @hash.slice(*keys) : to_hash + end + + protected + + def lookup(name) # :nodoc: + if @hash.has_key?(name) + @hash[name] + elsif @parent + @parent.lookup(name) + end + end + end + + EMPTY_TASK_ARGS = TaskArguments.new([], []) # :nodoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_manager.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_manager.rb new file mode 100644 index 0000000..90bc0d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_manager.rb @@ -0,0 +1,333 @@ +# frozen_string_literal: true +module Rake + + # The TaskManager module is a mixin for managing tasks. + module TaskManager + # Track the last comment made in the Rakefile. + attr_accessor :last_description + + def initialize # :nodoc: + super + @tasks = Hash.new + @rules = Array.new + @scope = Scope.make + @last_description = nil + end + + def create_rule(*args, &block) # :nodoc: + pattern, args, deps, order_only = resolve_args(args) + pattern = Regexp.new(Regexp.quote(pattern) + "$") if String === pattern + @rules << [pattern, args, deps, order_only, block] + end + + def define_task(task_class, *args, &block) # :nodoc: + task_name, arg_names, deps, order_only = resolve_args(args) + + original_scope = @scope + if String === task_name and + not task_class.ancestors.include? Rake::FileTask + task_name, *definition_scope = *(task_name.split(":").reverse) + @scope = Scope.make(*(definition_scope + @scope.to_a)) + end + + task_name = task_class.scope_name(@scope, task_name) + task = intern(task_class, task_name) + task.set_arg_names(arg_names) unless arg_names.empty? + if Rake::TaskManager.record_task_metadata + add_location(task) + task.add_description(get_description) + end + task.enhance(Task.format_deps(deps), &block) + task | order_only unless order_only.nil? + task + ensure + @scope = original_scope + end + + # Lookup a task. Return an existing task if found, otherwise + # create a task of the current type. + def intern(task_class, task_name) + @tasks[task_name.to_s] ||= task_class.new(task_name, self) + end + + # Find a matching task for +task_name+. + def [](task_name, scopes=nil) + task_name = task_name.to_s + self.lookup(task_name, scopes) or + enhance_with_matching_rule(task_name) or + synthesize_file_task(task_name) or + fail generate_message_for_undefined_task(task_name) + end + + def generate_message_for_undefined_task(task_name) + message = "Don't know how to build task '#{task_name}' "\ + "(See the list of available tasks with `#{Rake.application.name} --tasks`)" + message + generate_did_you_mean_suggestions(task_name) + end + + def generate_did_you_mean_suggestions(task_name) + return "" unless defined?(::DidYouMean::SpellChecker) + + suggestions = ::DidYouMean::SpellChecker.new(dictionary: @tasks.keys).correct(task_name.to_s) + if ::DidYouMean.respond_to?(:formatter)# did_you_mean v1.2.0 or later + ::DidYouMean.formatter.message_for(suggestions) + elsif defined?(::DidYouMean::Formatter) # before did_you_mean v1.2.0 + ::DidYouMean::Formatter.new(suggestions).to_s + else + "" + end + end + + def synthesize_file_task(task_name) # :nodoc: + return nil unless File.exist?(task_name) + define_task(Rake::FileTask, task_name) + end + + # Resolve the arguments for a task/rule. Returns a tuple of + # [task_name, arg_name_list, prerequisites, order_only_prerequisites]. + def resolve_args(args) + if args.last.is_a?(Hash) + deps = args.pop + resolve_args_with_dependencies(args, deps) + else + resolve_args_without_dependencies(args) + end + end + + # Resolve task arguments for a task or rule when there are no + # dependencies declared. + # + # The patterns recognized by this argument resolving function are: + # + # task :t + # task :t, [:a] + # + def resolve_args_without_dependencies(args) + task_name = args.shift + if args.size == 1 && args.first.respond_to?(:to_ary) + arg_names = args.first.to_ary + else + arg_names = args + end + [task_name, arg_names, [], nil] + end + private :resolve_args_without_dependencies + + # Resolve task arguments for a task or rule when there are + # dependencies declared. + # + # The patterns recognized by this argument resolving function are: + # + # task :t, order_only: [:e] + # task :t => [:d] + # task :t => [:d], order_only: [:e] + # task :t, [a] => [:d] + # task :t, [a] => [:d], order_only: [:e] + # + def resolve_args_with_dependencies(args, hash) # :nodoc: + fail "Task Argument Error" if + hash.size != 1 && + (hash.size != 2 || !hash.key?(:order_only)) + order_only = hash.delete(:order_only) + key, value = hash.map { |k, v| [k, v] }.first + if args.empty? + task_name = key + arg_names = [] + deps = value || [] + else + task_name = args.shift + arg_names = key || args.shift|| [] + deps = value || [] + end + deps = [deps] unless deps.respond_to?(:to_ary) + [task_name, arg_names, deps, order_only] + end + private :resolve_args_with_dependencies + + # If a rule can be found that matches the task name, enhance the + # task with the prerequisites and actions from the rule. Set the + # source attribute of the task appropriately for the rule. Return + # the enhanced task or nil of no rule was found. + def enhance_with_matching_rule(task_name, level=0) + fail Rake::RuleRecursionOverflowError, + "Rule Recursion Too Deep" if level >= 16 + @rules.each do |pattern, args, extensions, order_only, block| + if pattern && pattern.match(task_name) + task = attempt_rule(task_name, pattern, args, extensions, block, level) + task | order_only unless order_only.nil? + return task if task + end + end + nil + rescue Rake::RuleRecursionOverflowError => ex + ex.add_target(task_name) + fail ex + end + + # List of all defined tasks in this application. + def tasks + @tasks.values.sort_by { |t| t.name } + end + + # List of all the tasks defined in the given scope (and its + # sub-scopes). + def tasks_in_scope(scope) + prefix = scope.path + tasks.select { |t| + /^#{prefix}:/ =~ t.name + } + end + + # Clear all tasks in this application. + def clear + @tasks.clear + @rules.clear + end + + # Lookup a task, using scope and the scope hints in the task name. + # This method performs straight lookups without trying to + # synthesize file tasks or rules. Special scope names (e.g. '^') + # are recognized. If no scope argument is supplied, use the + # current scope. Return nil if the task cannot be found. + def lookup(task_name, initial_scope=nil) + initial_scope ||= @scope + task_name = task_name.to_s + if task_name =~ /^rake:/ + scopes = Scope.make + task_name = task_name.sub(/^rake:/, "") + elsif task_name =~ /^(\^+)/ + scopes = initial_scope.trim($1.size) + task_name = task_name.sub(/^(\^+)/, "") + else + scopes = initial_scope + end + lookup_in_scope(task_name, scopes) + end + + # Lookup the task name + def lookup_in_scope(name, scope) + loop do + tn = scope.path_with_task_name(name) + task = @tasks[tn] + return task if task + break if scope.empty? + scope = scope.tail + end + nil + end + private :lookup_in_scope + + # Return the list of scope names currently active in the task + # manager. + def current_scope + @scope + end + + # Evaluate the block in a nested namespace named +name+. Create + # an anonymous namespace if +name+ is nil. + def in_namespace(name) + name ||= generate_name + @scope = Scope.new(name, @scope) + ns = NameSpace.new(self, @scope) + yield(ns) + ns + ensure + @scope = @scope.tail + end + + private + + # Add a location to the locations field of the given task. + def add_location(task) + loc = find_location + task.locations << loc if loc + task + end + + # Find the location that called into the dsl layer. + def find_location + locations = caller + i = 0 + while locations[i] + return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/ + i += 1 + end + nil + end + + # Generate an anonymous namespace name. + def generate_name + @seed ||= 0 + @seed += 1 + "_anon_#{@seed}" + end + + def trace_rule(level, message) # :nodoc: + options.trace_output.puts "#{" " * level}#{message}" if + Rake.application.options.trace_rules + end + + # Attempt to create a rule given the list of prerequisites. + def attempt_rule(task_name, task_pattern, args, extensions, block, level) + sources = make_sources(task_name, task_pattern, extensions) + prereqs = sources.map { |source| + trace_rule level, "Attempting Rule #{task_name} => #{source}" + if File.exist?(source) || Rake::Task.task_defined?(source) + trace_rule level, "(#{task_name} => #{source} ... EXIST)" + source + elsif parent = enhance_with_matching_rule(source, level + 1) + trace_rule level, "(#{task_name} => #{source} ... ENHANCE)" + parent.name + else + trace_rule level, "(#{task_name} => #{source} ... FAIL)" + return nil + end + } + task = FileTask.define_task(task_name, { args => prereqs }, &block) + task.sources = prereqs + task + end + + # Make a list of sources from the list of file name extensions / + # translation procs. + def make_sources(task_name, task_pattern, extensions) + result = extensions.map { |ext| + case ext + when /%/ + task_name.pathmap(ext) + when %r{/} + ext + when /^\./ + source = task_name.sub(task_pattern, ext) + source == ext ? task_name.ext(ext) : source + when String, Symbol + ext.to_s + when Pathname + Rake.from_pathname(ext) + when Proc, Method + if ext.arity == 1 + ext.call(task_name) + else + ext.call + end + else + fail "Don't know how to handle rule dependent: #{ext.inspect}" + end + } + result.flatten + end + + # Return the current description, clearing it in the process. + def get_description + desc = @last_description + @last_description = nil + desc + end + + class << self + attr_accessor :record_task_metadata # :nodoc: + TaskManager.record_task_metadata = false + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/tasklib.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/tasklib.rb new file mode 100644 index 0000000..597a2d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/tasklib.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +require_relative "../rake" + +module Rake + + # Base class for Task Libraries. + class TaskLib + include Cloneable + include Rake::DSL + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/testtask.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/testtask.rb new file mode 100644 index 0000000..b1737cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/testtask.rb @@ -0,0 +1,192 @@ +# frozen_string_literal: true +require_relative "../rake" +require_relative "tasklib" + +module Rake + + # Create a task that runs a set of tests. + # + # Example: + # require "rake/testtask" + # + # Rake::TestTask.new do |t| + # t.libs << "test" + # t.test_files = FileList['test/test*.rb'] + # t.verbose = true + # end + # + # If rake is invoked with a "TEST=filename" command line option, + # then the list of test files will be overridden to include only the + # filename specified on the command line. This provides an easy way + # to run just one test. + # + # If rake is invoked with a "TESTOPTS=options" command line option, + # then the given options are passed to the test process after a + # '--'. This allows Test::Unit options to be passed to the test + # suite. + # + # Examples: + # + # rake test # run tests normally + # rake test TEST=just_one_file.rb # run just one test file. + # rake test TESTOPTS="-v" # run in verbose mode + # rake test TESTOPTS="--runner=fox" # use the fox test runner + # + class TestTask < TaskLib + + # Name of test task. (default is :test) + attr_accessor :name + + # List of directories added to $LOAD_PATH before running the + # tests. (default is 'lib') + attr_accessor :libs + + # True if verbose test output desired. (default is false) + attr_accessor :verbose + + # Test options passed to the test suite. An explicit + # TESTOPTS=opts on the command line will override this. (default + # is NONE) + attr_accessor :options + + # Request that the tests be run with the warning flag set. + # E.g. warning=true implies "ruby -w" used to run the tests. + # (default is true) + attr_accessor :warning + + # Glob pattern to match test files. (default is 'test/test*.rb') + attr_accessor :pattern + + # Style of test loader to use. Options are: + # + # * :rake -- Rake provided test loading script (default). + # * :testrb -- Ruby provided test loading script. + # * :direct -- Load tests using command line loader. + # + attr_accessor :loader + + # Array of command line options to pass to ruby when running test loader. + attr_accessor :ruby_opts + + # Description of the test task. (default is 'Run tests') + attr_accessor :description + + # Task prerequisites. + attr_accessor :deps + + # Explicitly define the list of test files to be included in a + # test. +list+ is expected to be an array of file names (a + # FileList is acceptable). If both +pattern+ and +test_files+ are + # used, then the list of test files is the union of the two. + def test_files=(list) + @test_files = list + end + + # Create a testing task. + def initialize(name=:test) + @name = name + @libs = ["lib"] + @pattern = nil + @options = nil + @test_files = nil + @verbose = false + @warning = true + @loader = :rake + @ruby_opts = [] + @description = "Run tests" + (@name == :test ? "" : " for #{@name}") + @deps = [] + if @name.is_a?(Hash) + @deps = @name.values.first + @name = @name.keys.first + end + yield self if block_given? + @pattern = "test/test*.rb" if @pattern.nil? && @test_files.nil? + define + end + + # Create the tasks defined by this task lib. + def define + desc @description + task @name => Array(deps) do + effective_verbose = @verbose || FileUtilsExt.verbose_flag == true + FileUtilsExt.verbose(effective_verbose) do + args = + "#{ruby_opts_string} #{run_code} " + + "#{file_list_string} #{option_list(verbose: effective_verbose)}" + ruby args do |ok, status| + if !ok && status.respond_to?(:signaled?) && status.signaled? + raise SignalException.new(status.termsig) + elsif !ok + status = "Command failed with status (#{status.exitstatus})" + details = ": [ruby #{args}]" + message = + if Rake.application.options.trace or @verbose + status + details + else + status + end + + fail message + end + end + end + end + self + end + + def option_list(verbose: @verbose) # :nodoc: + opts = ENV["TESTOPTS"] || + ENV["TESTOPT"] || + ENV["TEST_OPTS"] || + ENV["TEST_OPT"] || + @options || + "" + if verbose && !opts.split.include?("-v") + opts = opts.empty? ? "-v" : "#{opts} -v" + end + opts + end + + def ruby_opts_string # :nodoc: + opts = @ruby_opts.dup + opts.unshift("-I\"#{lib_path}\"") unless @libs.empty? + opts.unshift("-w") if @warning + opts.join(" ") + end + + def lib_path # :nodoc: + @libs.join(File::PATH_SEPARATOR) + end + + def file_list_string # :nodoc: + file_list.map { |fn| "\"#{fn}\"" }.join(" ") + end + + def file_list # :nodoc: + if ENV["TEST"] + FileList[ENV["TEST"].split(",")] + else + result = [] + result += @test_files.to_a if @test_files + result += FileList[@pattern].to_a if @pattern + result + end + end + + def ruby_version # :nodoc: + RUBY_VERSION + end + + def run_code # :nodoc: + case @loader + when :direct + "-e \"ARGV.each{|f| require f}\"" + when :testrb + "-S testrb" + when :rake + "#{__dir__}/rake_test_loader.rb" + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb new file mode 100644 index 0000000..50e2bc8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +require_relative "private_reader" + +module Rake + + class ThreadHistoryDisplay # :nodoc: all + include Rake::PrivateReader + + private_reader :stats, :items, :threads + + def initialize(stats) + @stats = stats + @items = { _seq_: 1 } + @threads = { _seq_: "A" } + end + + def show + puts "Job History:" + stats.each do |stat| + stat[:data] ||= {} + rename(stat, :thread, threads) + rename(stat[:data], :item_id, items) + rename(stat[:data], :new_thread, threads) + rename(stat[:data], :deleted_thread, threads) + printf("%8d %2s %-20s %s\n", + (stat[:time] * 1_000_000).round, + stat[:thread], + stat[:event], + stat[:data].map do |k, v| "#{k}:#{v}" end.join(" ")) + end + end + + private + + def rename(hash, key, renames) + if hash && hash[key] + original = hash[key] + value = renames[original] + unless value + value = renames[:_seq_] + renames[:_seq_] = renames[:_seq_].succ + renames[original] = value + end + hash[key] = value + end + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_pool.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_pool.rb new file mode 100644 index 0000000..ea9c0ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_pool.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +require_relative "promise" +require "set" + +module Rake + + class ThreadPool # :nodoc: all + + # Creates a ThreadPool object. The +thread_count+ parameter is the size + # of the pool. + def initialize(thread_count) + @max_active_threads = [thread_count, 0].max + @threads = Set.new + @threads_mon = Monitor.new + @queue = Queue.new + @join_cond = @threads_mon.new_cond + + @history_start_time = nil + @history = [] + @history_mon = Monitor.new + @total_threads_in_play = 0 + end + + # Creates a future executed by the +ThreadPool+. + # + # The args are passed to the block when executing (similarly to + # Thread#new) The return value is an object representing + # a future which has been created and added to the queue in the + # pool. Sending #value to the object will sleep the + # current thread until the future is finished and will return the + # result (or raise an exception thrown from the future) + def future(*args, &block) + promise = Promise.new(args, &block) + promise.recorder = lambda { |*stats| stat(*stats) } + + @queue.enq promise + stat :queued, item_id: promise.object_id + start_thread + promise + end + + # Waits until the queue of futures is empty and all threads have exited. + def join + @threads_mon.synchronize do + begin + stat :joining + @join_cond.wait unless @threads.empty? + stat :joined + rescue Exception => e + stat :joined + $stderr.puts e + $stderr.print "Queue contains #{@queue.size} items. " + + "Thread pool contains #{@threads.count} threads\n" + $stderr.print "Current Thread #{Thread.current} status = " + + "#{Thread.current.status}\n" + $stderr.puts e.backtrace.join("\n") + @threads.each do |t| + $stderr.print "Thread #{t} status = #{t.status}\n" + $stderr.puts t.backtrace.join("\n") + end + raise e + end + end + end + + # Enable the gathering of history events. + def gather_history #:nodoc: + @history_start_time = Time.now if @history_start_time.nil? + end + + # Return a array of history events for the thread pool. + # + # History gathering must be enabled to be able to see the events + # (see #gather_history). Best to call this when the job is + # complete (i.e. after ThreadPool#join is called). + def history # :nodoc: + @history_mon.synchronize { @history.dup }. + sort_by { |i| i[:time] }. + each { |i| i[:time] -= @history_start_time } + end + + # Return a hash of always collected statistics for the thread pool. + def statistics # :nodoc: + { + total_threads_in_play: @total_threads_in_play, + max_active_threads: @max_active_threads, + } + end + + private + + # processes one item on the queue. Returns true if there was an + # item to process, false if there was no item + def process_queue_item #:nodoc: + return false if @queue.empty? + + # Even though we just asked if the queue was empty, it + # still could have had an item which by this statement + # is now gone. For this reason we pass true to Queue#deq + # because we will sleep indefinitely if it is empty. + promise = @queue.deq(true) + stat :dequeued, item_id: promise.object_id + promise.work + return true + + rescue ThreadError # this means the queue is empty + false + end + + def start_thread # :nodoc: + @threads_mon.synchronize do + next unless @threads.count < @max_active_threads + + t = Thread.new do + begin + loop do + break unless process_queue_item + end + ensure + @threads_mon.synchronize do + @threads.delete Thread.current + stat :ended, thread_count: @threads.count + @join_cond.broadcast if @threads.empty? + end + end + end + + @threads << t + stat( + :spawned, + new_thread: t.object_id, + thread_count: @threads.count) + @total_threads_in_play = @threads.count if + @threads.count > @total_threads_in_play + end + end + + def stat(event, data=nil) # :nodoc: + return if @history_start_time.nil? + info = { + event: event, + data: data, + time: Time.now, + thread: Thread.current.object_id, + } + @history_mon.synchronize { @history << info } + end + + # for testing only + + def __queue__ # :nodoc: + @queue + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/trace_output.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/trace_output.rb new file mode 100644 index 0000000..d713a09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/trace_output.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +module Rake + module TraceOutput # :nodoc: all + + # Write trace output to output stream +out+. + # + # The write is done as a single IO call (to print) to lessen the + # chance that the trace output is interrupted by other tasks also + # producing output. + def trace_on(out, *strings) + sep = $\ || "\n" + if strings.empty? + output = sep + else + output = strings.map { |s| + next if s.nil? + s.end_with?(sep) ? s : s + sep + }.join + end + out.print(output) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/version.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/version.rb new file mode 100644 index 0000000..3527270 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/version.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +module Rake + VERSION = "13.4.2" + + module Version # :nodoc: all + MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split "." + + NUMBERS = [MAJOR, MINOR, BUILD, *OTHER] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/win32.rb b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/win32.rb new file mode 100644 index 0000000..5cccbde --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/win32.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +require "rbconfig" + +module Rake + # Win 32 interface methods for Rake. Windows specific functionality + # will be placed here to collect that knowledge in one spot. + module Win32 # :nodoc: all + + class << self + # True if running on a windows system. + def windows? + RbConfig::CONFIG["host_os"] =~ %r!(msdos|mswin|djgpp|mingw|[Ww]indows)! + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/rake.gemspec b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/rake.gemspec new file mode 100644 index 0000000..dbc1794 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/rake.gemspec @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require_relative "lib/rake/version" + +Gem::Specification.new do |s| + s.name = "rake" + s.version = Rake::VERSION + s.authors = ["Hiroshi SHIBATA", "Eric Hodel", "Jim Weirich"] + s.email = ["hsbt@ruby-lang.org", "drbrain@segment7.net", ""] + + s.summary = "Rake is a Make-like program implemented in Ruby" + s.description = <<~DESCRIPTION + Rake is a Make-like program implemented in Ruby. Tasks and dependencies are + specified in standard Ruby syntax. + Rake has the following features: + * Rakefiles (rake's version of Makefiles) are completely defined in standard Ruby syntax. + No XML files to edit. No quirky Makefile syntax to worry about (is that a tab or a space?) + * Users can specify tasks with prerequisites. + * Rake supports rule patterns to synthesize implicit tasks. + * Flexible FileLists that act like arrays but know about manipulating file names and paths. + * Supports parallel execution of tasks. + DESCRIPTION + s.homepage = "https://github.com/ruby/rake" + s.licenses = ["MIT"] + + s.metadata = { + "bug_tracker_uri" => "https://github.com/ruby/rake/issues", + "changelog_uri" => "https://github.com/ruby/rake/releases", + "documentation_uri" => "https://ruby.github.io/rake", + "source_code_uri" => s.homepage + } + + s.files = [ + "History.rdoc", + "MIT-LICENSE", + "README.rdoc", + "doc/command_line_usage.rdoc", + "doc/example/Rakefile1", + "doc/example/Rakefile2", + "doc/example/a.c", + "doc/example/b.c", + "doc/example/main.c", + "doc/glossary.rdoc", + "doc/jamis.rb", + "doc/proto_rake.rdoc", + "doc/rake.1", + "doc/rakefile.rdoc", + "doc/rational.rdoc", + "exe/rake", + "lib/rake.rb", + "lib/rake/application.rb", + "lib/rake/backtrace.rb", + "lib/rake/clean.rb", + "lib/rake/cloneable.rb", + "lib/rake/cpu_counter.rb", + "lib/rake/default_loader.rb", + "lib/rake/dsl_definition.rb", + "lib/rake/early_time.rb", + "lib/rake/ext/core.rb", + "lib/rake/ext/string.rb", + "lib/rake/file_creation_task.rb", + "lib/rake/file_list.rb", + "lib/rake/file_task.rb", + "lib/rake/file_utils.rb", + "lib/rake/file_utils_ext.rb", + "lib/rake/invocation_chain.rb", + "lib/rake/invocation_exception_mixin.rb", + "lib/rake/late_time.rb", + "lib/rake/linked_list.rb", + "lib/rake/loaders/makefile.rb", + "lib/rake/multi_task.rb", + "lib/rake/name_space.rb", + "lib/rake/options.rb", + "lib/rake/packagetask.rb", + "lib/rake/phony.rb", + "lib/rake/private_reader.rb", + "lib/rake/promise.rb", + "lib/rake/pseudo_status.rb", + "lib/rake/rake_module.rb", + "lib/rake/rake_test_loader.rb", + "lib/rake/rule_recursion_overflow_error.rb", + "lib/rake/scope.rb", + "lib/rake/task.rb", + "lib/rake/task_argument_error.rb", + "lib/rake/task_arguments.rb", + "lib/rake/task_manager.rb", + "lib/rake/tasklib.rb", + "lib/rake/testtask.rb", + "lib/rake/thread_history_display.rb", + "lib/rake/thread_pool.rb", + "lib/rake/trace_output.rb", + "lib/rake/version.rb", + "lib/rake/win32.rb", + "rake.gemspec" + ] + s.bindir = "exe" + s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) } + s.require_paths = ["lib"] + + s.required_ruby_version = Gem::Requirement.new(">= 2.3") + s.rdoc_options = ["--main", "README.rdoc"] +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/LICENSE.txt new file mode 100644 index 0000000..a009cae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/NEWS.md b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/NEWS.md new file mode 100644 index 0000000..1462712 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/NEWS.md @@ -0,0 +1,843 @@ +# News + +## 3.4.4 - 2025-09-10 {#version-3-4-4} + +### Improvement + + * Accept `REXML::Document.new("")` for backward compatibility + * GH-296 + * GH-295 + * Patch by NAITOH Jun + * Reported by Joe Rafaniello + +### Thanks + + * NAITOH Jun + + * Joe Rafaniello + +## 3.4.3 - 2025-09-07 {#version-3-4-3} + +### Improvement + + * Reject no root element XML as an invalid XML + * GH-289 + * GH-291 + * Patch by NAITOH Jun + * Reported by Sutou Kouhei + +### Fixes + + * Fixed an issue with `IOSource#read_until` when reaching the end of a file + * GH-287 + * GH-288 + * Patch by NAITOH Jun + * Reported by Jason Thomas + +### Thanks + + * NAITOH Jun + + * Sutou Kouhei + + * Jason Thomas + +## 3.4.2 - 2025-08-26 {#version-3-4-2} + +### Improvement + + * Improved performance. + * GH-244 + * GH-245 + * GH-246 + * GH-249 + * GH-256 + * Patch by NAITOH Jun + + * Raise appropriate exception when failing to match start tag in DOCTYPE + * GH-247 + * Patch by NAITOH Jun + + * Deprecate accepting array as an element in XPath.match, first and each + * GH-252 + * Patch by tomoya ishida + + * Don't call needless encoding_updated + * GH-259 + * Patch by Sutou Kouhei + + * Reuse XPath::match + * GH-263 + * Patch by pboling + + * Cache redundant calls for doctype + * GH-264 + * Patch by pboling + + * Use Safe Navigation (&.) from Ruby 2.3 + * GH-265 + * Patch by pboling + + * Remove redundant return statements + * GH-266 + * Patch by pboling + + * Added XML declaration check & Source#skip_spaces method + * GH-282 + * Patch by NAITOH Jun + * Reported by Sofi Aberegg + +### Fixes + + * Fix docs typo + * GH-248 + * Patch by James Coleman + + * Fix reverse sort in xpath_parser + * GH-251 + * Patch by tomoya ishida + + * Fix duplicate responses in XPath following, following-sibling, preceding, preceding-sibling + * GH-255 + * Patch by NAITOH Jun + + * Fix wrong Encoding resolution + * GH-258 + * Patch by Sutou Kouhei + + * Handle nil when parsing fragment + * GH-267 + * GH-268 + * Patch by pboling + + * [Documentation] Use # to reference instance methods + * GH-269 + * GH-270 + * Patch by pboling + + * Fix & Deprecate REXML::Text#text_indent + * GH-273 + * GH-275 + * Patch by pboling + + * remove bundler from dev deps + * GH-276 + * GH-277 + * Patch by pboling + + * remove ostruct from dev deps + * GH-280 + * GH-281 + * Patch by pboling + +### Thanks + + * NAITOH Jun + + * tomoya ishida + + * James Coleman + + * pboling + + * Sutou Kouhei + + * Sofi Aberegg + +## 3.4.1 - 2025-02-16 {#version-3-4-1} + +### Improvement + + * Improved performance. + * GH-226 + * GH-227 + * GH-237 + * Patch by NAITOH Jun + +### Fixes + + * Fix serialization of ATTLIST is incorrect + * GH-233 + * GH-234 + * Patch by OlofKalufs + * Reported by OlofKalufs + +### Thanks + + * NAITOH Jun + + * OlofKalufs + +## 3.4.0 - 2024-12-15 {#version-3-4-0} + +### Improvement + + * Improved performance. + * GH-216 + * Patch by NAITOH Jun + + * JRuby: Improved parse performance. + * GH-219 + * Patch by João Duarte + + * Added support for reusing pull parser. + * GH-214 + * GH-220 + * Patch by Dmitry Pogrebnoy + + * Improved error handling when source is `IO`. + * GH-221 + * Patch by NAITOH Jun + +### Thanks + + * NAITOH Jun + + * João Duarte + + * Dmitry Pogrebnoy + +## 3.3.9 - 2024-10-24 {#version-3-3-9} + +### Improvements + + * Improved performance. + * GH-210 + * Patch by NAITOH Jun. + +### Fixes + + * Fixed a parse bug for text only invalid XML. + * GH-215 + * Patch by NAITOH Jun. + + * Fixed a parse bug that `�x...;` is accepted as a character + reference. + +### Thanks + + * NAITOH Jun + +## 3.3.8 - 2024-09-29 {#version-3-3-8} + +### Improvements + + * SAX2: Improve parse performance. + * GH-207 + * Patch by NAITOH Jun. + +### Fixes + + * Fixed a bug that unexpected attribute namespace conflict error for + the predefined "xml" namespace is reported. + * GH-208 + * Patch by KITAITI Makoto + +### Thanks + + * NAITOH Jun + + * KITAITI Makoto + +## 3.3.7 - 2024-09-04 {#version-3-3-7} + +### Improvements + + * Added local entity expansion limit methods + * GH-192 + * GH-202 + * Reported by takuya kodama. + * Patch by NAITOH Jun. + + * Removed explicit strscan dependency + * GH-204 + * Patch by Bo Anderson. + +### Thanks + + * takuya kodama + + * NAITOH Jun + + * Bo Anderson + +## 3.3.6 - 2024-08-22 {#version-3-3-6} + +### Improvements + + * Removed duplicated entity expansions for performance. + * GH-194 + * Patch by Viktor Ivarsson. + + * Improved namespace conflicted attribute check performance. It was + too slow for deep elements. + * Reported by l33thaxor. + +### Fixes + + * Fixed a bug that default entity expansions are counted for + security check. Default entity expansions should not be counted + because they don't have a security risk. + * GH-198 + * GH-199 + * Patch Viktor Ivarsson + + * Fixed a parser bug that parameter entity references in internal + subsets are expanded. It's not allowed in the XML specification. + * GH-191 + * Patch by NAITOH Jun. + + * Fixed a stream parser bug that user-defined entity references in + text aren't expanded. + * GH-200 + * Patch by NAITOH Jun. + +### Thanks + + * Viktor Ivarsson + + * NAITOH Jun + + * l33thaxor + +## 3.3.5 - 2024-08-12 {#version-3-3-5} + +### Fixes + + * Fixed a bug that `REXML::Security.entity_expansion_text_limit` + check has wrong text size calculation in SAX and pull parsers. + * GH-193 + * GH-195 + * Reported by Viktor Ivarsson. + * Patch by NAITOH Jun. + +### Thanks + + * Viktor Ivarsson + + * NAITOH Jun + +## 3.3.4 - 2024-08-01 {#version-3-3-4} + +### Fixes + + * Fixed a bug that `REXML::Security` isn't defined when + `REXML::Parsers::StreamParser` is used and + `rexml/parsers/streamparser` is only required. + * GH-189 + * Patch by takuya kodama. + +### Thanks + + * takuya kodama + +## 3.3.3 - 2024-08-01 {#version-3-3-3} + +### Improvements + + * Added support for detecting invalid XML that has unsupported + content before root element + * GH-184 + * Patch by NAITOH Jun. + + * Added support for `REXML::Security.entity_expansion_limit=` and + `REXML::Security.entity_expansion_text_limit=` in SAX2 and pull + parsers + * GH-187 + * Patch by NAITOH Jun. + + * Added more tests for invalid XMLs. + * GH-183 + * Patch by Watson. + + * Added more performance tests. + * Patch by Watson. + + * Improved parse performance. + * GH-186 + * Patch by tomoya ishida. + +### Thanks + + * NAITOH Jun + + * Watson + + * tomoya ishida + +## 3.3.2 - 2024-07-16 {#version-3-3-2} + +### Improvements + + * Improved parse performance. + * GH-160 + * Patch by NAITOH Jun. + + * Improved parse performance. + * GH-169 + * GH-170 + * GH-171 + * GH-172 + * GH-173 + * GH-174 + * GH-175 + * GH-176 + * GH-177 + * Patch by Watson. + + * Added support for raising a parse exception when an XML has extra + content after the root element. + * GH-161 + * Patch by NAITOH Jun. + + * Added support for raising a parse exception when an XML + declaration exists in wrong position. + * GH-162 + * Patch by NAITOH Jun. + + * Removed needless a space after XML declaration in pretty print mode. + * GH-164 + * Patch by NAITOH Jun. + + * Stopped to emit `:text` event after the root element. + * GH-167 + * Patch by NAITOH Jun. + +### Fixes + + * Fixed a bug that SAX2 parser doesn't expand predefined entities for + `characters` callback. + * GH-168 + * Patch by NAITOH Jun. + +### Thanks + + * NAITOH Jun + + * Watson + +## 3.3.1 - 2024-06-25 {#version-3-3-1} + +### Improvements + + * Added support for detecting malformed top-level comments. + * GH-145 + * Patch by Hiroya Fujinami. + + * Improved `REXML::Element#attribute` performance. + * GH-146 + * Patch by Hiroya Fujinami. + + * Added support for detecting malformed `` comments. + * GH-147 + * Patch by Hiroya Fujinami. + + * Added support for detecting unclosed `DOCTYPE`. + * GH-152 + * Patch by Hiroya Fujinami. + + * Added `changlog_uri` metadata to gemspec. + * GH-156 + * Patch by fynsta. + + * Improved parse performance. + * GH-157 + * GH-158 + * Patch by NAITOH Jun. + +### Fixes + + * Fixed a bug that large XML can't be parsed. + * GH-154 + * Patch by NAITOH Jun. + + * Fixed a bug that private constants are visible. + * GH-155 + * Patch by NAITOH Jun. + +### Thanks + + * Hiroya Fujinami + + * NAITOH Jun + + * fynsta + +## 3.3.0 - 2024-06-11 {#version-3-3-0} + +### Improvements + + * Added support for strscan 0.7.0 installed with Ruby 2.6. + * GH-142 + * Reported by Fernando Trigoso. + +### Thanks + + * Fernando Trigoso + +## 3.2.9 - 2024-06-09 {#version-3-2-9} + +### Improvements + + * Added support for old strscan. + * GH-132 + * Reported by Adam. + + * Improved attribute value parse performance. + * GH-135 + * Patch by NAITOH Jun. + + * Improved `REXML::Node#each_recursive` performance. + * GH-134 + * GH-139 + * Patch by Hiroya Fujinami. + + * Improved text parse performance. + * Reported by mprogrammer. + +### Thanks + + * Adam + * NAITOH Jun + * Hiroya Fujinami + * mprogrammer + +## 3.2.8 - 2024-05-16 {#version-3-2-8} + +### Fixes + + * Suppressed a warning + +## 3.2.7 - 2024-05-16 {#version-3-2-7} + +### Improvements + + * Improve parse performance by using `StringScanner`. + + * GH-106 + * GH-107 + * GH-108 + * GH-109 + * GH-112 + * GH-113 + * GH-114 + * GH-115 + * GH-116 + * GH-117 + * GH-118 + * GH-119 + * GH-121 + + * Patch by NAITOH Jun. + + * Improved parse performance when an attribute has many `>`s. + + * GH-126 + +### Fixes + + * XPath: Fixed a bug of `normalize_space(array)`. + + * GH-110 + * GH-111 + + * Patch by flatisland. + + * XPath: Fixed a bug that wrong position is used with nested path. + + * GH-110 + * GH-122 + + * Reported by jcavalieri. + * Patch by NAITOH Jun. + + * Fixed a bug that an exception message can't be generated for + invalid encoding XML. + + * GH-29 + * GH-123 + + * Reported by DuKewu. + * Patch by NAITOH Jun. + +### Thanks + + * NAITOH Jun + * flatisland + * jcavalieri + * DuKewu + +## 3.2.6 - 2023-07-27 {#version-3-2-6} + +### Improvements + + * Required Ruby 2.5 or later explicitly. + [GH-69][gh-69] + [Patch by Ivo Anjo] + + * Added documentation for maintenance cycle. + [GH-71][gh-71] + [Patch by Ivo Anjo] + + * Added tutorial. + [GH-77][gh-77] + [GH-78][gh-78] + [Patch by Burdette Lamar] + + * Improved performance and memory usage. + [GH-94][gh-94] + [Patch by fatkodima] + + * `REXML::Parsers::XPathParser#abbreviate`: Added support for + function arguments. + [GH-95][gh-95] + [Reported by pulver] + + * `REXML::Parsers::XPathParser#abbreviate`: Added support for string + literal that contains double-quote. + [GH-96][gh-96] + [Patch by pulver] + + * `REXML::Parsers::XPathParser#abbreviate`: Added missing `/` to + `:descendant_or_self/:self/:parent`. + [GH-97][gh-97] + [Reported by pulver] + + * `REXML::Parsers::XPathParser#abbreviate`: Added support for more patterns. + [GH-97][gh-97] + [Reported by pulver] + +### Fixes + + * Fixed a typo in NEWS. + [GH-72][gh-72] + [Patch by Spencer Goodman] + + * Fixed a typo in NEWS. + [GH-75][gh-75] + [Patch by Andrew Bromwich] + + * Fixed documents. + [GH-87][gh-87] + [Patch by Alexander Ilyin] + + * Fixed a bug that `Attriute` convert `'` and `'` even when + `attribute_quote: :quote` is used. + [GH-92][gh-92] + [Reported by Edouard Brière] + + * Fixed links in tutorial. + [GH-99][gh-99] + [Patch by gemmaro] + + +### Thanks + + * Ivo Anjo + + * Spencer Goodman + + * Andrew Bromwich + + * Burdette Lamar + + * Alexander Ilyin + + * Edouard Brière + + * fatkodima + + * pulver + + * gemmaro + +[gh-69]:https://github.com/ruby/rexml/issues/69 +[gh-71]:https://github.com/ruby/rexml/issues/71 +[gh-72]:https://github.com/ruby/rexml/issues/72 +[gh-75]:https://github.com/ruby/rexml/issues/75 +[gh-77]:https://github.com/ruby/rexml/issues/77 +[gh-87]:https://github.com/ruby/rexml/issues/87 +[gh-92]:https://github.com/ruby/rexml/issues/92 +[gh-94]:https://github.com/ruby/rexml/issues/94 +[gh-95]:https://github.com/ruby/rexml/issues/95 +[gh-96]:https://github.com/ruby/rexml/issues/96 +[gh-97]:https://github.com/ruby/rexml/issues/97 +[gh-98]:https://github.com/ruby/rexml/issues/98 +[gh-99]:https://github.com/ruby/rexml/issues/99 + +## 3.2.5 - 2021-04-05 {#version-3-2-5} + +### Improvements + + * Add more validations to XPath parser. + + * `require "rexml/document"` by default. + [GitHub#36][Patch by Koichi ITO] + + * Don't add `#dclone` method to core classes globally. + [GitHub#37][Patch by Akira Matsuda] + + * Add more documentations. + [Patch by Burdette Lamar] + + * Added `REXML::Elements#parent`. + [GitHub#52][Patch by Burdette Lamar] + +### Fixes + + * Fixed a bug that `REXML::DocType#clone` doesn't copy external ID + information. + + * Fixed round-trip vulnerability bugs. + See also: https://www.ruby-lang.org/en/news/2021/04/05/xml-round-trip-vulnerability-in-rexml-cve-2021-28965/ + [HackerOne#1104077][CVE-2021-28965][Reported by Juho Nurminen] + +### Thanks + + * Koichi ITO + + * Akira Matsuda + + * Burdette Lamar + + * Juho Nurminen + +## 3.2.4 - 2020-01-31 {#version-3-2-4} + +### Improvements + + * Don't use `taint` with Ruby 2.7 or later. + [GitHub#21][Patch by Jeremy Evans] + +### Fixes + + * Fixed a `elsif` typo. + [GitHub#22][Patch by Nobuyoshi Nakada] + +### Thanks + + * Jeremy Evans + + * Nobuyoshi Nakada + +## 3.2.3 - 2019-10-12 {#version-3-2-3} + +### Fixes + + * Fixed a bug that `REXML::XMLDecl#close` doesn't copy `@writethis`. + [GitHub#20][Patch by hirura] + +### Thanks + + * hirura + +## 3.2.2 - 2019-06-03 {#version-3-2-2} + +### Fixes + + * xpath: Fixed a bug for equality and relational expressions. + [GitHub#17][Reported by Mirko Budszuhn] + + * xpath: Fixed `boolean()` implementation. + + * xpath: Fixed `local_name()` with nonexistent node. + + * xpath: Fixed `number()` implementation with node set. + [GitHub#18][Reported by Mirko Budszuhn] + +### Thanks + + * Mirko Budszuhn + +## 3.2.1 - 2019-05-04 {#version-3-2-1} + +### Improvements + + * Improved error message. + [GitHub#12][Patch by FUJI Goro] + + * Improved error message. + [GitHub#16][Patch by ujihisa] + + * Improved documentation markup. + [GitHub#14][Patch by Alyssa Ross] + +### Fixes + + * Fixed a bug that `nil` variable value raises an unexpected exception. + [GitHub#13][Patch by Alyssa Ross] + +### Thanks + + * FUJI Goro + + * Alyssa Ross + + * ujihisa + +## 3.2.0 - 2019-01-01 {#version-3-2-0} + +### Fixes + + * Fixed a bug that no namespace attribute isn't matched with prefix. + + [ruby-list:50731][Reported by Yasuhiro KIMURA] + + * Fixed a bug that the default namespace is applied to attribute names. + + NOTE: It's a backward incompatible change. If your program has any + problem with this change, please report it. We may revert this fix. + + * `REXML::Attribute#prefix` returns `""` for no namespace attribute. + + * `REXML::Attribute#namespace` returns `""` for no namespace attribute. + +### Thanks + + * Yasuhiro KIMURA + +## 3.1.9 - 2018-12-20 {#version-3-1-9} + +### Improvements + + * Improved backward compatibility. + + Restored `REXML::Parsers::BaseParser::UNQME_STR` because it's used + by kramdown. + +## 3.1.8 - 2018-12-20 {#version-3-1-8} + +### Improvements + + * Added support for customizing quote character in prologue. + [GitHub#8][Bug #9367][Reported by Takashi Oguma] + + * You can use `"` as quote character by specifying `:quote` to + `REXML::Document#context[:prologue_quote]`. + + * You can use `'` as quote character by specifying `:apostrophe` + to `REXML::Document#context[:prologue_quote]`. + + * Added processing instruction target check. The target must not nil. + [GitHub#7][Reported by Ariel Zelivansky] + + * Added name check for element and attribute. + [GitHub#7][Reported by Ariel Zelivansky] + + * Stopped to use `Exception`. + [GitHub#9][Patch by Jean Boussier] + +### Fixes + + * Fixed a bug that `REXML::Text#clone` escapes value twice. + [ruby-dev:50626][Bug #15058][Reported by Ryosuke Nanba] + +### Thanks + + * Takashi Oguma + + * Ariel Zelivansky + + * Jean Boussier + + * Ryosuke Nanba diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/README.md b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/README.md new file mode 100644 index 0000000..e8ab508 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/README.md @@ -0,0 +1,57 @@ +# REXML + +REXML was inspired by the Electric XML library for Java, which features an easy-to-use API, small size, and speed. Hopefully, REXML, designed with the same philosophy, has these same features. I've tried to keep the API as intuitive as possible, and have followed the Ruby methodology for method naming and code flow, rather than mirroring the Java API. + +REXML supports both tree and stream document parsing. Stream parsing is faster (about 1.5 times as fast). However, with stream parsing, you don't get access to features such as XPath. + +## API + +See the [API documentation](https://ruby.github.io/rexml/). + +## Usage + +We'll start with parsing an XML document + +```ruby +require "rexml/document" +file = File.new( "mydoc.xml" ) +doc = REXML::Document.new file +``` + +Line 3 creates a new document and parses the supplied file. You can also do the following + +```ruby +require "rexml/document" +include REXML # so that we don't have to prefix everything with REXML::... +string = < + Text, text, text + +EOF +doc = Document.new string +``` + +So parsing a string is just as easy as parsing a file. + +## Support + +REXML support follows the same maintenance cycle as Ruby releases, as shown on . + +If you are running on an end-of-life Ruby, do not expect modern REXML releases to be compatible with it; in fact, it's recommended that you DO NOT use this gem, and instead use the REXML version that came bundled with your end-of-life Ruby version. + +The `required_ruby_version` on the gemspec is kept updated on a [best-effort basis](https://github.com/ruby/rexml/pull/70) by the community. +Up to version 3.2.5, this information was not set. That version [is known broken with at least Ruby < 2.3](https://github.com/ruby/rexml/issues/69). + +## Development + +After checking out the repo, run `rake test` to run the tests. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/rexml. + +## License + +The gem is available as open source under the terms of the [BSD-2-Clause](LICENSE.txt). diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/context.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/context.rdoc new file mode 100644 index 0000000..7ef01f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/context.rdoc @@ -0,0 +1,143 @@ +== Element Context + +Notes: +- All code on this page presupposes that the following has been executed: + + require 'rexml/document' + +- For convenience, examples on this page use +REXML::Document.new+, not +REXML::Element.new+. + This is completely valid, because REXML::Document is a subclass of REXML::Element. + +The context for an element is a hash of processing directives +that influence the way \XML is read, stored, and written. +The context entries are: + +- +:respect_whitespace+: controls treatment of whitespace. +- +:compress_whitespace+: determines whether whitespace is compressed. +- +:ignore_whitespace_nodes+: determines whether whitespace-only nodes are to be ignored. +- +:raw+: controls treatment of special characters and entities. + +The default context for a new element is {}. +You can set the context at element-creation time: + + d = REXML::Document.new('', {compress_whitespace: :all, raw: :all}) + d.context # => {:compress_whitespace=>:all, :raw=>:all} + +You can reset the entire context by assigning a new hash: + + d.context = {ignore_whitespace_nodes: :all} + d.context # => {:ignore_whitespace_nodes=>:all} + +Or you can create or modify an individual entry: + + d.context[:raw] = :all + d.context # => {:ignore_whitespace_nodes=>:all, :raw=>:all} + +=== +:respect_whitespace+ + +Affects: +REXML::Element.new+, +REXML::Element.text=+. + +By default, all parsed whitespace is respected (that is, stored whitespace not compressed): + + xml_string = 'a b c d e f' + d = REXML::Document.new(xml_string) + d.to_s # => "a b c d e f" + +Use +:respect_whitespace+ with an array of element names +to specify the elements that _are_ to have their whitespace respected; +other elements' whitespace, and whitespace between elements, will be compressed. + +In this example: +foo+ and +baz+ will have their whitespace respected; ++bar+ and the space between elements will have their whitespace compressed: + + d = REXML::Document.new(xml_string, {respect_whitespace: ['foo', 'baz']}) + d.to_s # => "a b c d e f" + bar = d.root[2] # => ... + bar.text = 'X Y' + d.to_s # => "a b X Y e f" + +=== +:compress_whitespace+ + +Affects: +REXML::Element.new+, +REXML::Element.text=+. + +Use compress_whitespace: :all +to compress whitespace both within and between elements: + + xml_string = 'a b c d e f' + d = REXML::Document.new(xml_string, {compress_whitespace: :all}) + d.to_s # => "a b c d e f" + +Use +:compress_whitespace+ with an array of element names +to compress whitespace in those elements, +but not in other elements nor between elements. + +In this example, +foo+ and +baz+ will have their whitespace compressed; ++bar+ and the space between elements will not: + + d = REXML::Document.new(xml_string, {compress_whitespace: ['foo', 'baz']}) + d.to_s # => "a b c d e f" + foo = d.root[0] # => ... + foo.text= 'X Y' + d.to_s # => "X Y c d e f" + +=== +:ignore_whitespace_nodes+ + +Affects: +REXML::Element.new+. + +Use ignore_whitespace_nodes: :all to omit all whitespace-only elements. + +In this example, +bar+ has a text node, while nodes +foo+ and +baz+ do not: + + xml_string = ' BAR ' + d = REXML::Document.new(xml_string, {ignore_whitespace_nodes: :all}) + d.to_s # => " FOO BAZ " + root = d.root # => ... + foo = root[0] # => + bar = root[1] # => ... + baz = root[2] # => + foo.first.class # => NilClass + bar.first.class # => REXML::Text + baz.first.class # => NilClass + +Use +:ignore_whitespace_nodes+ with an array of element names +to specify the elements that are to have whitespace nodes ignored. + +In this example, +bar+ and +baz+ have text nodes, while node +foo+ does not. + + xml_string = ' BAR ' + d = REXML::Document.new(xml_string, {ignore_whitespace_nodes: ['foo']}) + d.to_s # => " BAR " + root = d.root # => ... + foo = root[0] # => + bar = root[1] # => ... + baz = root[2] # => ... + foo.first.class # => NilClass + bar.first.class # => REXML::Text + baz.first.class # => REXML::Text + +=== +:raw+ + +Affects: +Element.text=+, +Element.add_text+, +Text.to_s+. + +Parsing of +a+ elements is not affected by +raw+: + + xml_string = '0 < 11 > 0' + d = REXML::Document.new(xml_string, {:raw => ['a']}) + d.root.to_s # => "0 < 11 > 0" + a, b = *d.root.elements + a.to_s # => "0 < 1" + b.to_s # => "1 > 0" + +But Element#text= is affected: + + a.text = '0 < 1' + b.text = '1 > 0' + a.to_s # => "0 < 1" + b.to_s # => "1 &gt; 0" + +As is Element.add_text: + + a.add_text(' so 1 > 0') + b.add_text(' so 0 < 1') + a.to_s # => "0 < 1 so 1 > 0" + b.to_s # => "1 &gt; 0 so 0 &lt; 1" diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/child.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/child.rdoc new file mode 100644 index 0000000..8953638 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/child.rdoc @@ -0,0 +1,87 @@ +== Class Child + +Class Child includes module Node; +see {Tasks for Node}[node_rdoc.html]. + +:include: ../tocs/child_toc.rdoc + +=== Relationships + +==== Task: Set the Parent + +Use method {Child#parent=}[../../../../REXML/Parent.html#method-i-parent-3D] +to set the parent: + + e0 = REXML::Element.new('foo') + e1 = REXML::Element.new('bar') + e1.parent # => nil + e1.parent = e0 + e1.parent # => + +==== Task: Insert Previous Sibling + +Use method {Child#previous_sibling=}[../../../../REXML/Parent.html#method-i-previous_sibling-3D] +to insert a previous sibling: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.to_a # => [, ] + c = d.root[1] # => + b = REXML::Element.new('b') + c.previous_sibling = b + d.root.to_a # => [, , ] + +==== Task: Insert Next Sibling + +Use method {Child#next_sibling=}[../../../../REXML/Parent.html#method-i-next-sibling-3D] +to insert a previous sibling: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.to_a # => [, ] + a = d.root[0] # => + b = REXML::Element.new('b') + a.next_sibling = b + d.root.to_a # => [, , ] + +=== Removal or Replacement + +==== Task: Remove Child from Parent + +Use method {Child#remove}[../../../../REXML/Parent.html#method-i-remove] +to remove a child from its parent; returns the removed child: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.to_a # => [, , ] + b = d.root[1] # => + b.remove # => + d.root.to_a # => [, ] + +==== Task: Replace Child + +Use method {Child#replace_with}[../../../../REXML/Parent.html#method-i-replace] +to replace a child; +returns the replaced child: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.to_a # => [, , ] + b = d.root[1] # => + d = REXML::Element.new('d') + b.replace_with(d) # => + d.root.to_a # => [, , ] + +=== Document + +==== Task: Get the Document + +Use method {Child#document}[../../../../REXML/Parent.html#method-i-document] +to get the document for the child: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.to_a # => [, , ] + b = d.root[1] # => + b.document == d # => true + REXML::Child.new.document # => nil diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/document.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/document.rdoc new file mode 100644 index 0000000..96d0335 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/document.rdoc @@ -0,0 +1,276 @@ +== Class Document + +Class Document has methods from its superclasses and included modules; +see: + +- {Tasks for Element}[element_rdoc.html]. +- {Tasks for Parent}[parent_rdoc.html]. +- {Tasks for Child}[child_rdoc.html]. +- {Tasks for Node}[node_rdoc.html]. +- {Module Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html]. + +:include: ../tocs/document_toc.rdoc + +=== New Document + +==== Task: Create an Empty Document + +Use method {Document::new}[../../../../REXML/Document.html#method-c-new] +to create an empty document. + + d = REXML::Document.new + +==== Task: Parse a \String into a New Document + +Use method {Document::new}[../../../../REXML/Document.html#method-c-new] +to parse an XML string into a new document: + + xml_string = 'textmore' + d = REXML::Document.new(xml_string) + d.root # => ... + +==== Task: Parse an \IO Stream into a New Document + +Use method {Document::new}[../../../../REXML/Document.html#method-c-new] +to parse an XML \IO stream into a new document: + + xml_string = 'textmore' + File.write('t.xml', xml_string) + d = File.open('t.xml', 'r') do |file| + REXML::Document.new(file) + end + d.root # => ... + +==== Task: Create a Document from an Existing Document + +Use method {Document::new}[../../../../REXML/Document.html#method-c-new] +to create a document from an existing document. +The context and attributes are copied to the new document, +but not the children: + + xml_string = 'textmore' + d = REXML::Document.new(xml_string) + d.children # => [ ... ] + d.context = {raw: :all, compress_whitespace: :all} + d.add_attributes({'bar' => 0, 'baz' => 1}) + d1 = REXML::Document.new(d) + d1.context # => {:raw=>:all, :compress_whitespace=>:all} + d1.attributes # => {"bar"=>bar='0', "baz"=>baz='1'} + d1.children # => [] + +==== Task: Clone a Document + +Use method {Document#clone}[../../../../REXML/Document.html#method-i-clone] +to clone a document. +The context and attributes are copied to the new document, +but not the children: + + xml_string = 'textmore' + d = REXML::Document.new(xml_string) + d.children # => [ ... ] + d.context = {raw: :all, compress_whitespace: :all} + d.add_attributes({'bar' => 0, 'baz' => 1}) + d1 = d.clone # => < bar='0' baz='1'/> + d1.context # => {:raw=>:all, :compress_whitespace=>:all} + d1.attributes # => {"bar"=>bar='0', "baz"=>baz='1'} + d1.children # => [] + +=== Document Type + +==== Task: Get the Document Type + +Use method {Document#doctype}[../../../../REXML/Document.html#method-i-doctype] +to get the document type: + + d = REXML::Document.new('') + d.doctype.class # => REXML::DocType + d = REXML::Document.new('') + d.doctype.class # => nil + +==== Task: Set the Document Type + +Use method {document#add}[../../../../REXML/Document.html#method-i-add] +to add or replace the document type: + + d = REXML::Document.new('') + d.doctype.class # => nil + d.add(REXML::DocType.new('foo')) + d.doctype.class # => REXML::DocType + +=== XML Declaration + +==== Task: Get the XML Declaration + +Use method {document#xml_decl}[../../../../REXML/Document.html#method-i-xml_decl] +to get the XML declaration: + + d = REXML::Document.new('') + d.xml_decl.class # => REXML::XMLDecl + d.xml_decl # => + d = REXML::Document.new('') + d.xml_decl.class # => REXML::XMLDecl + d.xml_decl # => + +==== Task: Set the XML Declaration + +Use method {document#add}[../../../../REXML/Document.html#method-i-add] +to replace the XML declaration: + + d = REXML::Document.new('') + d.add(REXML::XMLDecl.new) + +=== Children + +==== Task: Add an Element Child + +Use method +{document#add_element}[../../../../REXML/Document.html#method-i-add_element] +to add an element to the document: + + d = REXML::Document.new('') + d.add_element(REXML::Element.new('root')) + d.children # => [] + +==== Task: Add a Non-Element Child + +Use method +{document#add}[../../../../REXML/Document.html#method-i-add] +to add a non-element to the document: + + xml_string = 'textmore' + d = REXML::Document.new(xml_string) + d.add(REXML::Text.new('foo')) + d.children # => [ ... , "foo"] + +=== Writing + +==== Task: Write to $stdout + +Use method +{document#write}[../../../../REXML/Document.html#method-i-write] +to write the document to $stdout: + + xml_string = 'textmore' + d = REXML::Document.new(xml_string) + d.write + +Output: + + textmore + +==== Task: Write to IO Stream + +Use method +{document#write}[../../../../REXML/Document.html#method-i-write] +to write the document to $stdout: + + xml_string = 'textmore' + d = REXML::Document.new(xml_string) + File.open('t.xml', 'w') do |file| + d.write(file) + end + p File.read('t.xml') + +Output: + + "textmore" + +==== Task: Write with No Indentation + +Use method +{document#write}[../../../../REXML/Document.html#method-i-write] +to write the document with no indentation: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.write({indent: 0}) + +Output: + + + + + + + + + +==== Task: Write with Specified Indentation + +Use method +{document#write}[../../../../REXML/Document.html#method-i-write] +to write the document with a specified indentation: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.write({indent: 2}) + +Output: + + + + + + + + + +=== Querying + +==== Task: Get the Document + +Use method +{document#document}[../../../../REXML/Document.html#method-i-document] +to get the document (+self+); overrides Element#document: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.document == d # => true + +==== Task: Get the Encoding + +Use method +{document#document}[../../../../REXML/Document.html#method-i-document] +to get the document (+self+); overrides Element#document: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.encoding # => "UTF-8" + +==== Task: Get the Node Type + +Use method +{document#node_type}[../../../../REXML/Document.html#method-i-node_type] +to get the node type (+:document+); overrides Element#node_type: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.node_type # => :document + +==== Task: Get the Root Element + +Use method +{document#root}[../../../../REXML/Document.html#method-i-root] +to get the root element: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root # => ... + +==== Task: Determine Whether Stand-Alone + +Use method +{document#stand_alone?}[../../../../REXML/Document.html#method-i-stand_alone-3F] +to get the stand-alone value: + + d = REXML::Document.new('') + d.stand_alone? # => "yes" + +==== Task: Get the Version + +Use method +{document#version}[../../../../REXML/Document.html#method-i-version] +to get the version: + + d = REXML::Document.new('') + d.version # => "2.0" diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/element.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/element.rdoc new file mode 100644 index 0000000..4b3609b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/element.rdoc @@ -0,0 +1,602 @@ +== Class Element + +Class Element has methods from its superclasses and included modules; +see: + +- {Tasks for Parent}[parent_rdoc.html]. +- {Tasks for Child}[child_rdoc.html]. +- {Tasks for Node}[node_rdoc.html]. +- {Module Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html]. + +:include: ../tocs/element_toc.rdoc + +=== New Element + +==== Task: Create a Default Element + +Use method +{Element::new}[../../../../REXML/Element.html#method-c-new] +with no arguments to create a default element: + + e = REXML::Element.new + e.name # => "UNDEFINED" + e.parent # => nil + e.context # => nil + +==== Task: Create a Named Element + +Use method +{Element::new}[../../../../REXML/Element.html#method-c-new] +with a string name argument +to create a named element: + + e = REXML::Element.new('foo') + e.name # => "foo" + e.parent # => nil + e.context # => nil + +==== Task: Create an Element with Name and Parent + +Use method +{Element::new}[../../../../REXML/Element.html#method-c-new] +with name and parent arguments +to create an element with name and parent: + + p = REXML::Parent.new + e = REXML::Element.new('foo', p) + e.name # => "foo" + e.parent # => #]> + e.context # => nil + +==== Task: Create an Element with Name, Parent, and Context + +Use method +{Element::new}[../../../../REXML/Element.html#method-c-new] +with name, parent, and context arguments +to create an element with name, parent, and context: + + p = REXML::Parent.new + e = REXML::Element.new('foo', p, {compress_whitespace: :all}) + e.name # => "foo" + e.parent # => #]> + e.context # => {:compress_whitespace=>:all} + +==== Task: Create a Shallow Clone + +Use method +{Element#clone}[../../../../REXML/Element.html#method-i-clone] +to create a shallow clone of an element, +copying only the name, attributes, and context: + + e0 = REXML::Element.new('foo', nil, {compress_whitespace: :all}) + e0.add_attribute(REXML::Attribute.new('bar', 'baz')) + e0.context = {compress_whitespace: :all} + e1 = e0.clone # => + e1.name # => "foo" + e1.context # => {:compress_whitespace=>:all} + +=== Attributes + +==== Task: Create and Add an Attribute + +Use method +{Element#add_attribute}[../../../../REXML/Element.html#method-i-add_attribute] +to create and add an attribute: + + e = REXML::Element.new + e.add_attribute('attr', 'value') # => "value" + e['attr'] # => "value" + e.add_attribute('attr', 'VALUE') # => "VALUE" + e['attr'] # => "VALUE" + +==== Task: Add an Existing Attribute + +Use method +{Element#add_attribute}[../../../../REXML/Element.html#method-i-add_attribute] +to add an existing attribute: + + e = REXML::Element.new + a = REXML::Attribute.new('attr', 'value') + e.add_attribute(a) + e['attr'] # => "value" + a = REXML::Attribute.new('attr', 'VALUE') + e.add_attribute(a) + e['attr'] # => "VALUE" + +==== Task: Add Multiple Attributes from a Hash + +Use method +{Element#add_attributes}[../../../../REXML/Element.html#method-i-add_attributes] +to add multiple attributes from a hash: + + e = REXML::Element.new + h = {'foo' => 0, 'bar' => 1} + e.add_attributes(h) + e['foo'] # => "0" + e['bar'] # => "1" + +==== Task: Add Multiple Attributes from an Array + +Use method +{Element#add_attributes}[../../../../REXML/Element.html#method-i-add_attributes] +to add multiple attributes from an array: + + e = REXML::Element.new + a = [['foo', 0], ['bar', 1]] + e.add_attributes(a) + e['foo'] # => "0" + e['bar'] # => "1" + +==== Task: Retrieve the Value for an Attribute Name + +Use method +{Element#[]}[../../../../REXML/Element.html#method-i-5B-5D] +to retrieve the value for an attribute name: + + e = REXML::Element.new + e.add_attribute('attr', 'value') # => "value" + e['attr'] # => "value" + +==== Task: Retrieve the Attribute Value for a Name and Namespace + +Use method +{Element#attribute}[../../../../REXML/Element.html#method-i-attribute] +to retrieve the value for an attribute name: + + xml_string = "" + d = REXML::Document.new(xml_string) + e = d.root + e.attribute("x") # => x='x' + e.attribute("x", "a") # => a:x='a:x' + +==== Task: Delete an Attribute + +Use method +{Element#delete_attribute}[../../../../REXML/Element.html#method-i-delete_attribute] +to remove an attribute: + + e = REXML::Element.new('foo') + e.add_attribute('bar', 'baz') + e.delete_attribute('bar') + e.delete_attribute('bar') + e['bar'] # => nil + +==== Task: Determine Whether the Element Has Attributes + +Use method +{Element#has_attributes?}[../../../../REXML/Element.html#method-i-has_attributes-3F] +to determine whether the element has attributes: + + e = REXML::Element.new('foo') + e.has_attributes? # => false + e.add_attribute('bar', 'baz') + e.has_attributes? # => true + +=== Children + +Element Children + +==== Task: Create and Add an Element + +Use method +{Element#add_element}[../../../../REXML/Element.html#method-i-add_element] +to create a new element and add it to this element: + + e0 = REXML::Element.new('foo') + e0.add_element('bar') + e0.children # => [] + +==== Task: Add an Existing Element + +Use method +{Element#add_element}[../../../../REXML/Element.html#method-i-add_element] +to add an element to this element: + + e0 = REXML::Element.new('foo') + e1 = REXML::Element.new('bar') + e0.add_element(e1) + e0.children # => [] + +==== Task: Create and Add an Element with Attributes + +Use method +{Element#add_element}[../../../../REXML/Element.html#method-i-add_element] +to create a new element with attributes, and add it to this element: + + e0 = REXML::Element.new('foo') + e0.add_element('bar', {'name' => 'value'}) + e0.children # => [] + +==== Task: Add an Existing Element with Added Attributes + +Use method +{Element#add_element}[../../../../REXML/Element.html#method-i-add_element] +to add an element to this element: + + e0 = REXML::Element.new('foo') + e1 = REXML::Element.new('bar') + e0.add_element(e1, {'name' => 'value'}) + e0.children # => [] + +==== Task: Delete a Specified Element + +Use method +{Element#delete_element}[../../../../REXML/Element.html#method-i-delete_element] +to remove a specified element from this element: + + e0 = REXML::Element.new('foo') + e1 = REXML::Element.new('bar') + e0.add_element(e1) + e0.children # => [] + e0.delete_element(e1) + e0.children # => [] + +==== Task: Delete an Element by Index + +Use method +{Element#delete_element}[../../../../REXML/Element.html#method-i-delete_element] +to remove an element from this element by index: + + e0 = REXML::Element.new('foo') + e1 = REXML::Element.new('bar') + e0.add_element(e1) + e0.children # => [] + e0.delete_element(1) + e0.children # => [] + +==== Task: Delete an Element by XPath + +Use method +{Element#delete_element}[../../../../REXML/Element.html#method-i-delete_element] +to remove an element from this element by XPath: + + e0 = REXML::Element.new('foo') + e1 = REXML::Element.new('bar') + e0.add_element(e1) + e0.children # => [] + e0.delete_element('//bar/') + e0.children # => [] + +==== Task: Determine Whether Element Children + +Use method +{Element#has_elements?}[../../../../REXML/Element.html#method-i-has_elements-3F] +to determine whether the element has element children: + + e0 = REXML::Element.new('foo') + e0.has_elements? # => false + e0.add_element(REXML::Element.new('bar')) + e0.has_elements? # => true + +==== Task: Get Element Descendants by XPath + +Use method +{Element#get_elements}[../../../../REXML/Element.html#method-i-get_elements] +to fetch all element descendant children by XPath: + + xml_string = <<-EOT + + + + + + EOT + d = REXML::Document.new(xml_string) + d.root.get_elements('//a') # => [ ... , ] + +==== Task: Get Next Element Sibling + +Use method +{Element#next_element}[../../../../REXML/Element.html#method-i-next_element] +to retrieve the next element sibling: + + d = REXML::Document.new 'text' + d.root.elements['b'].next_element #-> + d.root.elements['c'].next_element #-> nil + +==== Task: Get Previous Element Sibling + +Use method +{Element#previous_element}[../../../../REXML/Element.html#method-i-previous_element] +to retrieve the previous element sibling: + + d = REXML::Document.new 'text' + d.root.elements['c'].previous_element #-> + d.root.elements['b'].previous_element #-> nil + +Text Children + +==== Task: Add a Text Node + +Use method +{Element#add_text}[../../../../REXML/Element.html#method-i-add_text] +to add a text node to the element: + + d = REXML::Document.new('foobar') + e = d.root + e.add_text(REXML::Text.new('baz')) + e.to_a # => ["foo", , "bar", "baz"] + e.add_text(REXML::Text.new('baz')) + e.to_a # => ["foo", , "bar", "baz", "baz"] + +==== Task: Replace the First Text Node + +Use method +{Element#text=}[../../../../REXML/Element.html#method-i-text-3D] +to replace the first text node in the element: + + d = REXML::Document.new('textmore') + e = d.root + e.to_a # => [, "text", , "more", ] + e.text = 'oops' + e.to_a # => [, "oops", , "more", ] + +==== Task: Remove the First Text Node + +Use method +{Element#text=}[../../../../REXML/Element.html#method-i-text-3D] +to remove the first text node in the element: + + d = REXML::Document.new('textmore') + e = d.root + e.to_a # => [, "text", , "more", ] + e.text = nil + e.to_a # => [, , "more", ] + +==== Task: Retrieve the First Text Node + +Use method +{Element#get_text}[../../../../REXML/Element.html#method-i-get_text] +to retrieve the first text node in the element: + + d = REXML::Document.new('textmore') + e = d.root + e.to_a # => [, "text", , "more", ] + e.get_text # => "text" + +==== Task: Retrieve a Specific Text Node + +Use method +{Element#get_text}[../../../../REXML/Element.html#method-i-get_text] +to retrieve the first text node in a specified element: + + d = REXML::Document.new "some text this is bold! more text" + e = d.root + e.get_text('//root') # => "some text " + e.get_text('//b') # => "this is bold!" + +==== Task: Determine Whether the Element has Text Nodes + +Use method +{Element#has_text?}[../../../../REXML/Element.html#method-i-has_text-3F] +to determine whether the element has text: + + e = REXML::Element.new('foo') + e.has_text? # => false + e.add_text('bar') + e.has_text? # => true + +Other Children + +==== Task: Get the Child at a Given Index + +Use method +{Element#[]}[../../../../REXML/Element.html#method-i-5B-5D] +to retrieve the child at a given index: + + d = REXML::Document.new '>textmore' + e = d.root + e[0] # => + e[1] # => "text" + e[2] # => + +==== Task: Get All CDATA Children + +Use method +{Element#cdatas}[../../../../REXML/Element.html#method-i-cdatas] +to retrieve all CDATA children: + + xml_string = <<-EOT + + + + + EOT + d = REXML::Document.new(xml_string) + d.root.cdatas # => ["foo", "bar"] + +==== Task: Get All Comment Children + +Use method +{Element#comments}[../../../../REXML/Element.html#method-i-comments] +to retrieve all comment children: + + xml_string = <<-EOT + + + + + EOT + d = REXML::Document.new(xml_string) + d.root.comments.map {|comment| comment.to_s } # => ["foo", "bar"] + +==== Task: Get All Processing Instruction Children + +Use method +{Element#instructions}[../../../../REXML/Element.html#method-i-instructions] +to retrieve all processing instruction children: + + xml_string = <<-EOT + + + + + EOT + d = REXML::Document.new(xml_string) + instructions = d.root.instructions.map {|instruction| instruction.to_s } + instructions # => ["", ""] + +==== Task: Get All Text Children + +Use method +{Element#texts}[../../../../REXML/Element.html#method-i-texts] +to retrieve all text children: + + xml_string = 'textmore' + d = REXML::Document.new(xml_string) + d.root.texts # => ["text", "more"] + +=== Namespaces + +==== Task: Add a Namespace + +Use method +{Element#add_namespace}[../../../../REXML/Element.html#method-i-add_namespace] +to add a namespace to the element: + + e = REXML::Element.new('foo') + e.add_namespace('bar') + e.namespaces # => {"xmlns"=>"bar"} + +==== Task: Delete the Default Namespace + +Use method +{Element#delete_namespace}[../../../../REXML/Element.html#method-i-delete_namespace] +to remove the default namespace from the element: + + d = REXML::Document.new "" + d.to_s # => "" + d.root.delete_namespace # => + d.to_s # => "" + +==== Task: Delete a Specific Namespace + +Use method +{Element#delete_namespace}[../../../../REXML/Element.html#method-i-delete_namespace] +to remove a specific namespace from the element: + + d = REXML::Document.new "" + d.to_s # => "" + d.root.delete_namespace # => + d.to_s # => "" + d.root.delete_namespace('foo') + d.to_s # => "" + +==== Task: Get a Namespace URI + +Use method +{Element#namespace}[../../../../REXML/Element.html#method-i-namespace] +to retrieve a specific namespace URI for the element: + + xml_string = <<-EOT + + + + + + + EOT + d = REXML::Document.new(xml_string) + b = d.elements['//b'] + b.namespace # => "1" + b.namespace('y') # => "2" + +==== Task: Retrieve Namespaces + +Use method +{Element#namespaces}[../../../../REXML/Element.html#method-i-namespaces] +to retrieve all namespaces for the element: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.attributes.namespaces # => {"xmlns"=>"foo", "x"=>"bar", "y"=>"twee"} + +==== Task: Retrieve Namespace Prefixes + +Use method +{Element#prefixes}[../../../../REXML/Element.html#method-i-prefixes] +to retrieve all prefixes (namespace names) for the element: + + xml_string = <<-EOT + + + + + + + EOT + d = REXML::Document.new(xml_string, {compress_whitespace: :all}) + d.elements['//a'].prefixes # => ["x", "y"] + d.elements['//b'].prefixes # => ["x", "y"] + d.elements['//c'].prefixes # => ["x", "y", "z"] + +=== Iteration + +==== Task: Iterate Over Elements + +Use method +{Element#each_element}[../../../../REXML/Element.html#method-i-each_element] +to iterate over element children: + + d = REXML::Document.new 'bbd' + d.root.each_element {|e| p e } + +Output: + + ... + ... + ... + + +==== Task: Iterate Over Elements Having a Specified Attribute + +Use method +{Element#each_element_with_attribute}[../../../../REXML/Element.html#method-i-each_element_with_attribute] +to iterate over element children that have a specified attribute: + + d = REXML::Document.new '' + a = d.root + a.each_element_with_attribute('id') {|e| p e } + +Output: + + + + + +==== Task: Iterate Over Elements Having a Specified Attribute and Value + +Use method +{Element#each_element_with_attribute}[../../../../REXML/Element.html#method-i-each_element_with_attribute] +to iterate over element children that have a specified attribute and value: + + d = REXML::Document.new '' + a = d.root + a.each_element_with_attribute('id', '1') {|e| p e } + +Output: + + + + +==== Task: Iterate Over Elements Having Specified Text + +Use method +{Element#each_element_with_text}[../../../../REXML/Element.html#method-i-each_element_with_text] +to iterate over element children that have specified text: + + +=== Context + +#whitespace +#ignore_whitespace_nodes +#raw + +=== Other Getters + +#document +#root +#root_node +#node_type +#xpath +#inspect diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/node.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/node.rdoc new file mode 100644 index 0000000..d5d2e12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/node.rdoc @@ -0,0 +1,97 @@ +== Module Node + +:include: ../tocs/node_toc.rdoc + +=== Siblings + +==== Task: Find Previous Sibling + +Use method +{Node.previous_sibling_node}[../../../../REXML/Node.html#method-i-previous_sibling] +to retrieve the previous sibling: + + d = REXML::Document.new('') + b = d.root[1] # => + b.previous_sibling_node # => + +==== Task: Find Next Sibling + +Use method +{Node.next_sibling_node}[../../../../REXML/Node.html#method-i-next_sibling] +to retrieve the next sibling: + + d = REXML::Document.new('') + b = d.root[1] # => + b.next_sibling_node # => + +=== Position + +==== Task: Find Own Index Among Siblings + +Use method +{Node.index_in_parent}[../../../../REXML/Node.html#method-i-index_in_parent] +to retrieve the 1-based index of this node among its siblings: + + d = REXML::Document.new('') + b = d.root[1] # => + b.index_in_parent # => 2 + +=== Recursive Traversal + +==== Task: Traverse Each Recursively + +Use method +{Node.each_recursive}[../../../../REXML/Node.html#method-i-each_recursive] +to traverse a tree of nodes recursively: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.each_recursive {|node| p node } + +Output: + + ... + ... + + ... + + +=== Recursive Search + +==== Task: Traverse Each Recursively + +Use method +{Node.find_first_recursive}[../../../../REXML/Node.html#method-i-find_first_recursive] +to search a tree of nodes recursively: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.find_first_recursive {|node| node.name == 'c' } # => + +=== Representation + +==== Task: Represent a String + +Use method {Node.to_s}[../../../../REXML/Node.html#method-i-to_s] +to represent the node as a string: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.to_s # => "" + +=== Parent? + +==== Task: Determine Whether the Node is a Parent + +Use method {Node.parent?}[../../../../REXML/Node.html#method-i-parent-3F] +to determine whether the node is a parent; +class Text derives from Node: + + d = REXML::Document.new('textmore') + t = d.root[1] # => "text" + t.parent? # => false + +Class Parent also derives from Node, but overrides this method: + + p = REXML::Parent.new + p.parent? # => true diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/parent.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/parent.rdoc new file mode 100644 index 0000000..54f1dbe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/rdoc/parent.rdoc @@ -0,0 +1,267 @@ +== Class Parent + +Class Parent has methods from its superclasses and included modules; +see: + +- {Tasks for Child}[child_rdoc.html]. +- {Tasks for Node}[node_rdoc.html]. +- {Module Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html]. + +:include: ../tocs/parent_toc.rdoc + +=== Queries + +==== Task: Get the Count of Children + +Use method {Parent#size}[../../../../REXML/Parent.html#method-i-size] +(or its alias +length+) to get the count of the parent's children: + + p = REXML::Parent.new + p.size # => 0 + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.size # => 3 + +==== Task: Get the Child at a Given Index + +Use method {Parent#[]}[../../../../REXML/Parent.html#method-i-5B-5D] +to get the child at a given index: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root[1] # => + d.root[-1] # => + d.root[50] # => nil + +==== Task: Get the Index of a Given Child + +Use method {Parent#index}[../../../../REXML/Parent.html#method-i-index] +to get the index (0-based offset) of a child: + + d = REXML::Document.new('') + root = d.root + e0 = REXML::Element.new('foo') + e1 = REXML::Element.new('bar') + root.add(e0) # => + root.add(e1) # => + root.add(e0) # => + root.add(e1) # => + root.index(e0) # => 0 + root.index(e1) # => 1 + +==== Task: Get the Children + +Use method {Parent#children}[../../../../REXML/Parent.html#method-i-children] +(or its alias +to_a+) to get the parent's children: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + +==== Task: Determine Whether the Node is a Parent + +Use method {Parent#parent?}[../../../../REXML/Parent.html#method-i-parent-3F] +to determine whether the node is a parent; +class Text derives from Node: + + d = REXML::Document.new('textmore') + t = d.root[1] # => "text" + t.parent? # => false + +Class Parent also derives from Node, but overrides this method: + + p = REXML::Parent.new + p.parent? # => true + +=== Additions + +==== Task: Add a Child at the Beginning + +Use method {Parent#unshift}[../../../../REXML/Parent.html#method-i-unshift] +to add a child as at the beginning of the children: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + d.root.unshift REXML::Element.new('d') + d.root.children # => [, , , ] + +==== Task: Add a Child at the End + +Use method {Parent#<<}[../../../../REXML/Parent.html#method-i-3C-3C] +(or an alias +push+ or +add+) to add a child as at the end of the children: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + d.root << REXML::Element.new('d') + d.root.children # => [, , , ] + +==== Task: Replace a Child with Another Child + +Use method {Parent#replace}[../../../../REXML/Parent.html#method-i-replace] + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + b = d.root[1] # => + d.replace_child(b, REXML::Element.new('d')) + d.root.children # => [, ] + +==== Task: Replace Multiple Children with Another Child + +Use method {Parent#[]=}[../../../../REXML/Parent.html#method-i-parent-5B-5D-3D] +to replace multiple consecutive children with another child: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , , ] + d.root[1, 2] = REXML::Element.new('x') + d.root.children # => [, , ] + d.root[1, 5] = REXML::Element.new('x') + d.root.children # => [, ] # BUG? + +==== Task: Insert Child Before a Given Child + +Use method {Parent#insert_before}[../../../../REXML/Parent.html#method-i-insert_before] +to insert a child immediately before a given child: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + b = d.root[1] # => + x = REXML::Element.new('x') + d.root.insert_before(b, x) + d.root.children # => [, , , ] + +==== Task: Insert Child After a Given Child + +Use method {Parent#insert_after}[../../../../REXML/Parent.html#method-i-insert_after] +to insert a child immediately after a given child: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + b = d.root[1] # => + x = REXML::Element.new('x') + d.root.insert_after(b, x) + d.root.children # => [, , , ] + +=== Deletions + +==== Task: Remove a Given Child + +Use method {Parent#delete}[../../../../REXML/Parent.html#method-i-delete] +to remove all occurrences of a given child: + + d = REXML::Document.new('') + a = REXML::Element.new('a') + b = REXML::Element.new('b') + d.root.add(a) + d.root.add(b) + d.root.add(a) + d.root.add(b) + d.root.children # => [, , , ] + d.root.delete(b) + d.root.children # => [, ] + +==== Task: Remove the Child at a Specified Offset + +Use method {Parent#delete_at}[../../../../REXML/Parent.html#method-i-delete_at] +to remove the child at a specified offset: + + d = REXML::Document.new('') + a = REXML::Element.new('a') + b = REXML::Element.new('b') + d.root.add(a) + d.root.add(b) + d.root.add(a) + d.root.add(b) + d.root.children # => [, , , ] + d.root.delete_at(2) + d.root.children # => [, , ] + +==== Task: Remove Children That Meet Specified Criteria + +Use method {Parent#delete_if}[../../../../REXML/Parent.html#method-i-delete_if] +to remove children that meet criteria specified in the given block: + + d = REXML::Document.new('') + d.root.add(REXML::Element.new('x')) + d.root.add(REXML::Element.new('xx')) + d.root.add(REXML::Element.new('xxx')) + d.root.add(REXML::Element.new('xxxx')) + d.root.children # => [, , , ] + d.root.delete_if {|child| child.name.size.odd? } + d.root.children # => [, ] + +=== Iterations + +==== Task: Iterate Over Children + +Use method {Parent#each_child}[../../../../REXML/Parent.html#method-i-each_child] +(or its alias +each+) to iterate over all children: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + d.root.each_child {|child| p child } + +Output: + + + + + +==== Task: Iterate Over Child Indexes + +Use method {Parent#each_index}[../../../../REXML/Parent.html#method-i-each_index] +to iterate over all child indexes: + + xml_string = '' + d = REXML::Document.new(xml_string) + d.root.children # => [, , ] + d.root.each_index {|child| p child } + +Output: + + 0 + 1 + 2 + +=== Clones + +==== Task: Clone Deeply + +Use method {Parent#deep_clone}[../../../../REXML/Parent.html#method-i-deep_clone] +to clone deeply; that is, to clone every nested node that is a Parent object: + + xml_string = <<-EOT + + + + Everyday Italian + Giada De Laurentiis + 2005 + 30.00 + + + Harry Potter + J K. Rowling + 2005 + 29.99 + + + Learning XML + Erik T. Ray + 2003 + 39.95 + + + EOT + d = REXML::Document.new(xml_string) + root = d.root + shallow = root.clone + deep = root.deep_clone + shallow.to_s.size # => 12 + deep.to_s.size # => 590 diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/child_toc.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/child_toc.rdoc new file mode 100644 index 0000000..a2083a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/child_toc.rdoc @@ -0,0 +1,12 @@ +Tasks on this page: + +- {Relationships}[#label-Relationships] + - {Task: Set the Parent}[#label-Task-3A+Set+the+Parent] + - {Task: Insert Previous Sibling}[#label-Task-3A+Insert+Previous+Sibling] + - {Task: Insert Next Sibling}[#label-Task-3A+Insert+Next+Sibling] +- {Removal or Replacement}[#label-Removal+or+Replacement] + - {Task: Remove Child from Parent}[#label-Task-3A+Remove+Child+from+Parent] + - {Task: Replace Child}[#label-Task-3A+Replace+Child] +- {Document}[#label-Document] + - {Task: Get the Document}[#label-Task-3A+Get+the+Document] + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/document_toc.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/document_toc.rdoc new file mode 100644 index 0000000..5db055f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/document_toc.rdoc @@ -0,0 +1,30 @@ +Tasks on this page: + +- {New Document}[#label-New+Document] + - {Task: Create an Empty Document}[#label-Task-3A+Create+an+Empty+Document] + - {Task: Parse a String into a New Document}[#label-Task-3A+Parse+a+String+into+a+New+Document] + - {Task: Parse an IO Stream into a New Document}[#label-Task-3A+Parse+an+IO+Stream+into+a+New+Document] + - {Task: Create a Document from an Existing Document}[#label-Task-3A+Create+a+Document+from+an+Existing+Document] + - {Task: Clone a Document}[#label-Task-3A+Clone+a+Document] +- {Document Type}[#label-Document+Type] + - {Task: Get the Document Type}[#label-Task-3A+Get+the+Document+Type] + - {Task: Set the Document Type}[#label-Task-3A+Set+the+Document+Type] +- {XML Declaration}[#label-XML+Declaration] + - {Task: Get the XML Declaration}[#label-Task-3A+Get+the+XML+Declaration] + - {Task: Set the XML Declaration}[#label-Task-3A+Set+the+XML+Declaration] +- {Children}[#label-Children] + - {Task: Add an Element Child}[#label-Task-3A+Add+an+Element+Child] + - {Task: Add a Non-Element Child}[#label-Task-3A+Add+a+Non-Element+Child] +- {Writing}[#label-Writing] + - {Task: Write to $stdout}[#label-Task-3A+Write+to+-24stdout] + - {Task: Write to IO Stream}[#label-Task-3A+Write+to+IO+Stream] + - {Task: Write with No Indentation}[#label-Task-3A+Write+with+No+Indentation] + - {Task: Write with Specified Indentation}[#label-Task-3A+Write+with+Specified+Indentation] +- {Querying}[#label-Querying] + - {Task: Get the Document}[#label-Task-3A+Get+the+Document] + - {Task: Get the Encoding}[#label-Task-3A+Get+the+Encoding] + - {Task: Get the Node Type}[#label-Task-3A+Get+the+Node+Type] + - {Task: Get the Root Element}[#label-Task-3A+Get+the+Root+Element] + - {Task: Determine Whether Stand-Alone}[#label-Task-3A+Determine+Whether+Stand-Alone] + - {Task: Get the Version}[#label-Task-3A+Get+the+Version] + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/element_toc.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/element_toc.rdoc new file mode 100644 index 0000000..60a504a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/element_toc.rdoc @@ -0,0 +1,55 @@ +Tasks on this page: + +- {New Element}[#label-New+Element] + - {Task: Create a Default Element}[#label-Task-3A+Create+a+Default+Element] + - {Task: Create a Named Element}[#label-Task-3A+Create+a+Named+Element] + - {Task: Create an Element with Name and Parent}[#label-Task-3A+Create+an+Element+with+Name+and+Parent] + - {Task: Create an Element with Name, Parent, and Context}[#label-Task-3A+Create+an+Element+with+Name-2C+Parent-2C+and+Context] + - {Task: Create a Shallow Clone}[#label-Task-3A+Create+a+Shallow+Clone] +- {Attributes}[#label-Attributes] + - {Task: Create and Add an Attribute}[#label-Task-3A+Create+and+Add+an+Attribute] + - {Task: Add an Existing Attribute}[#label-Task-3A+Add+an+Existing+Attribute] + - {Task: Add Multiple Attributes from a Hash}[#label-Task-3A+Add+Multiple+Attributes+from+a+Hash] + - {Task: Add Multiple Attributes from an Array}[#label-Task-3A+Add+Multiple+Attributes+from+an+Array] + - {Task: Retrieve the Value for an Attribute Name}[#label-Task-3A+Retrieve+the+Value+for+an+Attribute+Name] + - {Task: Retrieve the Attribute Value for a Name and Namespace}[#label-Task-3A+Retrieve+the+Attribute+Value+for+a+Name+and+Namespace] + - {Task: Delete an Attribute}[#label-Task-3A+Delete+an+Attribute] + - {Task: Determine Whether the Element Has Attributes}[#label-Task-3A+Determine+Whether+the+Element+Has+Attributes] +- {Children}[#label-Children] + - {Task: Create and Add an Element}[#label-Task-3A+Create+and+Add+an+Element] + - {Task: Add an Existing Element}[#label-Task-3A+Add+an+Existing+Element] + - {Task: Create and Add an Element with Attributes}[#label-Task-3A+Create+and+Add+an+Element+with+Attributes] + - {Task: Add an Existing Element with Added Attributes}[#label-Task-3A+Add+an+Existing+Element+with+Added+Attributes] + - {Task: Delete a Specified Element}[#label-Task-3A+Delete+a+Specified+Element] + - {Task: Delete an Element by Index}[#label-Task-3A+Delete+an+Element+by+Index] + - {Task: Delete an Element by XPath}[#label-Task-3A+Delete+an+Element+by+XPath] + - {Task: Determine Whether Element Children}[#label-Task-3A+Determine+Whether+Element+Children] + - {Task: Get Element Descendants by XPath}[#label-Task-3A+Get+Element+Descendants+by+XPath] + - {Task: Get Next Element Sibling}[#label-Task-3A+Get+Next+Element+Sibling] + - {Task: Get Previous Element Sibling}[#label-Task-3A+Get+Previous+Element+Sibling] + - {Task: Add a Text Node}[#label-Task-3A+Add+a+Text+Node] + - {Task: Replace the First Text Node}[#label-Task-3A+Replace+the+First+Text+Node] + - {Task: Remove the First Text Node}[#label-Task-3A+Remove+the+First+Text+Node] + - {Task: Retrieve the First Text Node}[#label-Task-3A+Retrieve+the+First+Text+Node] + - {Task: Retrieve a Specific Text Node}[#label-Task-3A+Retrieve+a+Specific+Text+Node] + - {Task: Determine Whether the Element has Text Nodes}[#label-Task-3A+Determine+Whether+the+Element+has+Text+Nodes] + - {Task: Get the Child at a Given Index}[#label-Task-3A+Get+the+Child+at+a+Given+Index] + - {Task: Get All CDATA Children}[#label-Task-3A+Get+All+CDATA+Children] + - {Task: Get All Comment Children}[#label-Task-3A+Get+All+Comment+Children] + - {Task: Get All Processing Instruction Children}[#label-Task-3A+Get+All+Processing+Instruction+Children] + - {Task: Get All Text Children}[#label-Task-3A+Get+All+Text+Children] +- {Namespaces}[#label-Namespaces] + - {Task: Add a Namespace}[#label-Task-3A+Add+a+Namespace] + - {Task: Delete the Default Namespace}[#label-Task-3A+Delete+the+Default+Namespace] + - {Task: Delete a Specific Namespace}[#label-Task-3A+Delete+a+Specific+Namespace] + - {Task: Get a Namespace URI}[#label-Task-3A+Get+a+Namespace+URI] + - {Task: Retrieve Namespaces}[#label-Task-3A+Retrieve+Namespaces] + - {Task: Retrieve Namespace Prefixes}[#label-Task-3A+Retrieve+Namespace+Prefixes] +- {Iteration}[#label-Iteration] + - {Task: Iterate Over Elements}[#label-Task-3A+Iterate+Over+Elements] + - {Task: Iterate Over Elements Having a Specified Attribute}[#label-Task-3A+Iterate+Over+Elements+Having+a+Specified+Attribute] + - {Task: Iterate Over Elements Having a Specified Attribute and Value}[#label-Task-3A+Iterate+Over+Elements+Having+a+Specified+Attribute+and+Value] + - {Task: Iterate Over Elements Having Specified Text}[#label-Task-3A+Iterate+Over+Elements+Having+Specified+Text] +- {Context}[#label-Context] +- {Other Getters}[#label-Other+Getters] + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/master_toc.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/master_toc.rdoc new file mode 100644 index 0000000..0214f6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/master_toc.rdoc @@ -0,0 +1,135 @@ +== Tasks + +=== {Child}[../../tasks/rdoc/child_rdoc.html] +- {Relationships}[../../tasks/rdoc/child_rdoc.html#label-Relationships] + - {Task: Set the Parent}[../../tasks/rdoc/child_rdoc.html#label-Task-3A+Set+the+Parent] + - {Task: Insert Previous Sibling}[../../tasks/rdoc/child_rdoc.html#label-Task-3A+Insert+Previous+Sibling] + - {Task: Insert Next Sibling}[../../tasks/rdoc/child_rdoc.html#label-Task-3A+Insert+Next+Sibling] +- {Removal or Replacement}[../../tasks/rdoc/child_rdoc.html#label-Removal+or+Replacement] + - {Task: Remove Child from Parent}[../../tasks/rdoc/child_rdoc.html#label-Task-3A+Remove+Child+from+Parent] + - {Task: Replace Child}[../../tasks/rdoc/child_rdoc.html#label-Task-3A+Replace+Child] +- {Document}[../../tasks/rdoc/child_rdoc.html#label-Document] + - {Task: Get the Document}[../../tasks/rdoc/child_rdoc.html#label-Task-3A+Get+the+Document] + +=== {Document}[../../tasks/rdoc/document_rdoc.html] +- {New Document}[../../tasks/rdoc/document_rdoc.html#label-New+Document] + - {Task: Create an Empty Document}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Create+an+Empty+Document] + - {Task: Parse a String into a New Document}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Parse+a+String+into+a+New+Document] + - {Task: Parse an IO Stream into a New Document}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Parse+an+IO+Stream+into+a+New+Document] + - {Task: Create a Document from an Existing Document}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Create+a+Document+from+an+Existing+Document] + - {Task: Clone a Document}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Clone+a+Document] +- {Document Type}[../../tasks/rdoc/document_rdoc.html#label-Document+Type] + - {Task: Get the Document Type}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Get+the+Document+Type] + - {Task: Set the Document Type}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Set+the+Document+Type] +- {XML Declaration}[../../tasks/rdoc/document_rdoc.html#label-XML+Declaration] + - {Task: Get the XML Declaration}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Get+the+XML+Declaration] + - {Task: Set the XML Declaration}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Set+the+XML+Declaration] +- {Children}[../../tasks/rdoc/document_rdoc.html#label-Children] + - {Task: Add an Element Child}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Add+an+Element+Child] + - {Task: Add a Non-Element Child}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Add+a+Non-Element+Child] +- {Writing}[../../tasks/rdoc/document_rdoc.html#label-Writing] + - {Task: Write to $stdout}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Write+to+-24stdout] + - {Task: Write to IO Stream}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Write+to+IO+Stream] + - {Task: Write with No Indentation}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Write+with+No+Indentation] + - {Task: Write with Specified Indentation}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Write+with+Specified+Indentation] +- {Querying}[../../tasks/rdoc/document_rdoc.html#label-Querying] + - {Task: Get the Document}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Get+the+Document] + - {Task: Get the Encoding}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Get+the+Encoding] + - {Task: Get the Node Type}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Get+the+Node+Type] + - {Task: Get the Root Element}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Get+the+Root+Element] + - {Task: Determine Whether Stand-Alone}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Determine+Whether+Stand-Alone] + - {Task: Get the Version}[../../tasks/rdoc/document_rdoc.html#label-Task-3A+Get+the+Version] + +=== {Element}[../../tasks/rdoc/element_rdoc.html] +- {New Element}[../../tasks/rdoc/element_rdoc.html#label-New+Element] + - {Task: Create a Default Element}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+a+Default+Element] + - {Task: Create a Named Element}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+a+Named+Element] + - {Task: Create an Element with Name and Parent}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+an+Element+with+Name+and+Parent] + - {Task: Create an Element with Name, Parent, and Context}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+an+Element+with+Name-2C+Parent-2C+and+Context] + - {Task: Create a Shallow Clone}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+a+Shallow+Clone] +- {Attributes}[../../tasks/rdoc/element_rdoc.html#label-Attributes] + - {Task: Create and Add an Attribute}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+and+Add+an+Attribute] + - {Task: Add an Existing Attribute}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Add+an+Existing+Attribute] + - {Task: Add Multiple Attributes from a Hash}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Add+Multiple+Attributes+from+a+Hash] + - {Task: Add Multiple Attributes from an Array}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Add+Multiple+Attributes+from+an+Array] + - {Task: Retrieve the Value for an Attribute Name}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Retrieve+the+Value+for+an+Attribute+Name] + - {Task: Retrieve the Attribute Value for a Name and Namespace}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Retrieve+the+Attribute+Value+for+a+Name+and+Namespace] + - {Task: Delete an Attribute}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Delete+an+Attribute] + - {Task: Determine Whether the Element Has Attributes}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Determine+Whether+the+Element+Has+Attributes] +- {Children}[../../tasks/rdoc/element_rdoc.html#label-Children] + - {Task: Create and Add an Element}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+and+Add+an+Element] + - {Task: Add an Existing Element}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Add+an+Existing+Element] + - {Task: Create and Add an Element with Attributes}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Create+and+Add+an+Element+with+Attributes] + - {Task: Add an Existing Element with Added Attributes}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Add+an+Existing+Element+with+Added+Attributes] + - {Task: Delete a Specified Element}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Delete+a+Specified+Element] + - {Task: Delete an Element by Index}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Delete+an+Element+by+Index] + - {Task: Delete an Element by XPath}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Delete+an+Element+by+XPath] + - {Task: Determine Whether Element Children}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Determine+Whether+Element+Children] + - {Task: Get Element Descendants by XPath}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+Element+Descendants+by+XPath] + - {Task: Get Next Element Sibling}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+Next+Element+Sibling] + - {Task: Get Previous Element Sibling}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+Previous+Element+Sibling] + - {Task: Add a Text Node}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Add+a+Text+Node] + - {Task: Replace the First Text Node}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Replace+the+First+Text+Node] + - {Task: Remove the First Text Node}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Remove+the+First+Text+Node] + - {Task: Retrieve the First Text Node}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Retrieve+the+First+Text+Node] + - {Task: Retrieve a Specific Text Node}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Retrieve+a+Specific+Text+Node] + - {Task: Determine Whether the Element has Text Nodes}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Determine+Whether+the+Element+has+Text+Nodes] + - {Task: Get the Child at a Given Index}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+the+Child+at+a+Given+Index] + - {Task: Get All CDATA Children}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+All+CDATA+Children] + - {Task: Get All Comment Children}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+All+Comment+Children] + - {Task: Get All Processing Instruction Children}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+All+Processing+Instruction+Children] + - {Task: Get All Text Children}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+All+Text+Children] +- {Namespaces}[../../tasks/rdoc/element_rdoc.html#label-Namespaces] + - {Task: Add a Namespace}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Add+a+Namespace] + - {Task: Delete the Default Namespace}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Delete+the+Default+Namespace] + - {Task: Delete a Specific Namespace}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Delete+a+Specific+Namespace] + - {Task: Get a Namespace URI}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Get+a+Namespace+URI] + - {Task: Retrieve Namespaces}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Retrieve+Namespaces] + - {Task: Retrieve Namespace Prefixes}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Retrieve+Namespace+Prefixes] +- {Iteration}[../../tasks/rdoc/element_rdoc.html#label-Iteration] + - {Task: Iterate Over Elements}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Iterate+Over+Elements] + - {Task: Iterate Over Elements Having a Specified Attribute}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Iterate+Over+Elements+Having+a+Specified+Attribute] + - {Task: Iterate Over Elements Having a Specified Attribute and Value}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Iterate+Over+Elements+Having+a+Specified+Attribute+and+Value] + - {Task: Iterate Over Elements Having Specified Text}[../../tasks/rdoc/element_rdoc.html#label-Task-3A+Iterate+Over+Elements+Having+Specified+Text] +- {Context}[../../tasks/rdoc/element_rdoc.html#label-Context] +- {Other Getters}[../../tasks/rdoc/element_rdoc.html#label-Other+Getters] + +=== {Node}[../../tasks/rdoc/node_rdoc.html] +- {Siblings}[../../tasks/rdoc/node_rdoc.html#label-Siblings] + - {Task: Find Previous Sibling}[../../tasks/rdoc/node_rdoc.html#label-Task-3A+Find+Previous+Sibling] + - {Task: Find Next Sibling}[../../tasks/rdoc/node_rdoc.html#label-Task-3A+Find+Next+Sibling] +- {Position}[../../tasks/rdoc/node_rdoc.html#label-Position] + - {Task: Find Own Index Among Siblings}[../../tasks/rdoc/node_rdoc.html#label-Task-3A+Find+Own+Index+Among+Siblings] +- {Recursive Traversal}[../../tasks/rdoc/node_rdoc.html#label-Recursive+Traversal] + - {Task: Traverse Each Recursively}[../../tasks/rdoc/node_rdoc.html#label-Task-3A+Traverse+Each+Recursively] +- {Recursive Search}[../../tasks/rdoc/node_rdoc.html#label-Recursive+Search] + - {Task: Traverse Each Recursively}[../../tasks/rdoc/node_rdoc.html#label-Task-3A+Traverse+Each+Recursively] +- {Representation}[../../tasks/rdoc/node_rdoc.html#label-Representation] + - {Task: Represent a String}[../../tasks/rdoc/node_rdoc.html#label-Task-3A+Represent+a+String] +- {Parent?}[../../tasks/rdoc/node_rdoc.html#label-Parent-3F] + - {Task: Determine Whether the Node is a Parent}[../../tasks/rdoc/node_rdoc.html#label-Task-3A+Determine+Whether+the+Node+is+a+Parent] + +=== {Parent}[../../tasks/rdoc/parent_rdoc.html] +- {Queries}[../../tasks/rdoc/parent_rdoc.html#label-Queries] + - {Task: Get the Count of Children}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Get+the+Count+of+Children] + - {Task: Get the Child at a Given Index}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Get+the+Child+at+a+Given+Index] + - {Task: Get the Index of a Given Child}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Get+the+Index+of+a+Given+Child] + - {Task: Get the Children}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Get+the+Children] + - {Task: Determine Whether the Node is a Parent}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Determine+Whether+the+Node+is+a+Parent] +- {Additions}[../../tasks/rdoc/parent_rdoc.html#label-Additions] + - {Task: Add a Child at the Beginning}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Add+a+Child+at+the+Beginning] + - {Task: Add a Child at the End}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Add+a+Child+at+the+End] + - {Task: Replace a Child with Another Child}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Replace+a+Child+with+Another+Child] + - {Task: Replace Multiple Children with Another Child}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Replace+Multiple+Children+with+Another+Child] + - {Task: Insert Child Before a Given Child}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Insert+Child+Before+a+Given+Child] + - {Task: Insert Child After a Given Child}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Insert+Child+After+a+Given+Child] +- {Deletions}[../../tasks/rdoc/parent_rdoc.html#label-Deletions] + - {Task: Remove a Given Child}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Remove+a+Given+Child] + - {Task: Remove the Child at a Specified Offset}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Remove+the+Child+at+a+Specified+Offset] + - {Task: Remove Children That Meet Specified Criteria}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Remove+Children+That+Meet+Specified+Criteria] +- {Iterations}[../../tasks/rdoc/parent_rdoc.html#label-Iterations] + - {Task: Iterate Over Children}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Iterate+Over+Children] + - {Task: Iterate Over Child Indexes}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Iterate+Over+Child+Indexes] +- {Clones}[../../tasks/rdoc/parent_rdoc.html#label-Clones] + - {Task: Clone Deeply}[../../tasks/rdoc/parent_rdoc.html#label-Task-3A+Clone+Deeply] + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/node_toc.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/node_toc.rdoc new file mode 100644 index 0000000..d9114fa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/node_toc.rdoc @@ -0,0 +1,16 @@ +Tasks on this page: + +- {Siblings}[#label-Siblings] + - {Task: Find Previous Sibling}[#label-Task-3A+Find+Previous+Sibling] + - {Task: Find Next Sibling}[#label-Task-3A+Find+Next+Sibling] +- {Position}[#label-Position] + - {Task: Find Own Index Among Siblings}[#label-Task-3A+Find+Own+Index+Among+Siblings] +- {Recursive Traversal}[#label-Recursive+Traversal] + - {Task: Traverse Each Recursively}[#label-Task-3A+Traverse+Each+Recursively] +- {Recursive Search}[#label-Recursive+Search] + - {Task: Traverse Each Recursively}[#label-Task-3A+Traverse+Each+Recursively] +- {Representation}[#label-Representation] + - {Task: Represent a String}[#label-Task-3A+Represent+a+String] +- {Parent?}[#label-Parent-3F] + - {Task: Determine Whether the Node is a Parent}[#label-Task-3A+Determine+Whether+the+Node+is+a+Parent] + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/parent_toc.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/parent_toc.rdoc new file mode 100644 index 0000000..68fc0b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tasks/tocs/parent_toc.rdoc @@ -0,0 +1,25 @@ +Tasks on this page: + +- {Queries}[#label-Queries] + - {Task: Get the Count of Children}[#label-Task-3A+Get+the+Count+of+Children] + - {Task: Get the Child at a Given Index}[#label-Task-3A+Get+the+Child+at+a+Given+Index] + - {Task: Get the Index of a Given Child}[#label-Task-3A+Get+the+Index+of+a+Given+Child] + - {Task: Get the Children}[#label-Task-3A+Get+the+Children] + - {Task: Determine Whether the Node is a Parent}[#label-Task-3A+Determine+Whether+the+Node+is+a+Parent] +- {Additions}[#label-Additions] + - {Task: Add a Child at the Beginning}[#label-Task-3A+Add+a+Child+at+the+Beginning] + - {Task: Add a Child at the End}[#label-Task-3A+Add+a+Child+at+the+End] + - {Task: Replace a Child with Another Child}[#label-Task-3A+Replace+a+Child+with+Another+Child] + - {Task: Replace Multiple Children with Another Child}[#label-Task-3A+Replace+Multiple+Children+with+Another+Child] + - {Task: Insert Child Before a Given Child}[#label-Task-3A+Insert+Child+Before+a+Given+Child] + - {Task: Insert Child After a Given Child}[#label-Task-3A+Insert+Child+After+a+Given+Child] +- {Deletions}[#label-Deletions] + - {Task: Remove a Given Child}[#label-Task-3A+Remove+a+Given+Child] + - {Task: Remove the Child at a Specified Offset}[#label-Task-3A+Remove+the+Child+at+a+Specified+Offset] + - {Task: Remove Children That Meet Specified Criteria}[#label-Task-3A+Remove+Children+That+Meet+Specified+Criteria] +- {Iterations}[#label-Iterations] + - {Task: Iterate Over Children}[#label-Task-3A+Iterate+Over+Children] + - {Task: Iterate Over Child Indexes}[#label-Task-3A+Iterate+Over+Child+Indexes] +- {Clones}[#label-Clones] + - {Task: Clone Deeply}[#label-Task-3A+Clone+Deeply] + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tutorial.rdoc b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tutorial.rdoc new file mode 100644 index 0000000..c85a70d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/doc/rexml/tutorial.rdoc @@ -0,0 +1,1358 @@ += \REXML Tutorial + +== Why \REXML? + +- Ruby's \REXML library is part of the Ruby distribution, + so using it requires no gem installations. +- \REXML is fully maintained. +- \REXML is mature, having been in use for long years. + +== To Include, or Not to Include? + +REXML is a module. +To use it, you must require it: + + require 'rexml' # => true + +If you do not also include it, you must fully qualify references to REXML: + + REXML::Document # => REXML::Document + +If you also include the module, you may optionally omit REXML::: + + include REXML + Document # => REXML::Document + REXML::Document # => REXML::Document + +== Preliminaries + +All examples here assume that the following code has been executed: + + require 'rexml' + include REXML + +The source XML for many examples here is from file +{books.xml}[https://www.w3schools.com/xml/books.xml] at w3schools.com. +You may find it convenient to open that page in a new tab +(Ctrl-click in some browsers). + +Note that your browser may display the XML with modified whitespace +and without the XML declaration, which in this case is: + + + +For convenience, we capture the XML into a string variable: + + require 'open-uri' + source_string = URI.open('https://www.w3schools.com/xml/books.xml').read + +And into a file: + + File.write('source_file.xml', source_string) + +Throughout these examples, variable +doc+ will hold only the document +derived from these sources: + + doc = Document.new(source_string) + +== Parsing \XML \Source + +=== Parsing a Document + +Use method REXML::Document::new to parse XML source. + +The source may be a string: + + doc = Document.new(source_string) + +Or an \IO stream: + + doc = File.open('source_file.xml', 'r') do |io| + Document.new(io) + end + +Method URI.open returns a StringIO object, +so the source can be from a web page: + + require 'open-uri' + io = URI.open("https://www.w3schools.com/xml/books.xml") + io.class # => StringIO + doc = Document.new(io) + +For any of these sources, the returned object is an REXML::Document: + + doc # => ... + doc.class # => REXML::Document + +Note: 'UNDEFINED' is the "name" displayed for a document, +even though doc.name returns an empty string "". + +A parsed document may produce \REXML objects of many classes, +but the two that are likely to be of greatest interest are +REXML::Document and REXML::Element. +These two classes are covered in great detail in this tutorial. + +=== Context (Parsing Options) + +The context for parsing a document is a hash that influences +the way the XML is read and stored. + +The context entries are: + +- +:respect_whitespace+: controls treatment of whitespace. +- +:compress_whitespace+: determines whether whitespace is compressed. +- +:ignore_whitespace_nodes+: determines whether whitespace-only nodes are to be ignored. +- +:raw+: controls treatment of special characters and entities. + +See {Element Context}[../context_rdoc.html]. + +== Exploring the Document + +An REXML::Document object represents an XML document. + +The object inherits from its ancestor classes: + +- REXML::Child (includes module REXML::Node) + - REXML::Parent (includes module {Enumerable}[rdoc-ref:Enumerable]). + - REXML::Element (includes module REXML::Namespace). + - REXML::Document + +This section covers only those properties and methods that are unique to a document +(that is, not inherited or included). + +=== Document Properties + +A document has several properties (other than its children); + +- Document type. +- Node type. +- Name. +- Document. +- XPath + +[Document Type] + + A document may have a document type: + + my_xml = '' + my_doc = Document.new(my_xml) + doc_type = my_doc.doctype + doc_type.class # => REXML::DocType + doc_type.to_s # => "" + +[Node Type] + + A document also has a node type (always +:document+): + + doc.node_type # => :document + +[Name] + + A document has a name (always an empty string): + + doc.name # => "" + +[Document] + + \Method REXML::Document#document returns +self+: + + doc.document == doc # => true + + An object of a different class (\REXML::Element or \REXML::Child) + may have a document, which is the document to which the object belongs; + if so, that document will be an \REXML::Document object. + + doc.root.document.class # => REXML::Document + +[XPath] + + \method REXML::Element#xpath returns the string xpath to the element, + relative to its most distant ancestor: + + doc.root.class # => REXML::Element + doc.root.xpath # => "/bookstore" + doc.root.texts.first # => "\n\n" + doc.root.texts.first.xpath # => "/bookstore/text()" + + If there is no ancestor, returns the expanded name of the element: + + Element.new('foo').xpath # => "foo" + +=== Document Children + +A document may have children of these types: + +- XML declaration. +- Root element. +- Text. +- Processing instructions. +- Comments. +- CDATA. + +[XML Declaration] + + A document may an XML declaration, which is stored as an REXML::XMLDecl object: + + doc.xml_decl # => + doc.xml_decl.class # => REXML::XMLDecl + + Document.new('').xml_decl # => + + my_xml = '"' + my_doc = Document.new(my_xml) + xml_decl = my_doc.xml_decl + xml_decl.to_s # => "" + + The version, encoding, and stand-alone values may be retrieved separately: + + my_doc.version # => "1.0" + my_doc.encoding # => "UTF-8" + my_doc.stand_alone? # => "yes" + +[Root Element] + + A document may have a single element child, called the _root_ _element_, + which is stored as an REXML::Element object; + it may be retrieved with method +root+: + + doc.root # => ... + doc.root.class # => REXML::Element + + Document.new('').root # => nil + +[Text] + + A document may have text passages, each of which is stored + as an REXML::Text object: + + doc.texts.each {|t| p [t.class, t] } + + Output: + + [REXML::Text, "\n"] + +[Processing Instructions] + + A document may have processing instructions, which are stored + as REXML::Instruction objects: + + + + Output: + + [REXML::Instruction, ] + [REXML::Instruction, ] + +[Comments] + + A document may have comments, which are stored + as REXML::Comment objects: + + my_xml = <<-EOT + + + EOT + my_doc = Document.new(my_xml) + my_doc.comments.each {|c| p [c.class, c] } + + Output: + + [REXML::Comment, # ... , @string="foo">] + [REXML::Comment, # ... , @string="bar">] + +[CDATA] + + A document may have CDATA entries, which are stored + as REXML::CData objects: + + my_xml = <<-EOT + + + EOT + my_doc = Document.new(my_xml) + my_doc.cdatas.each {|cd| p [cd.class, cd] } + + Output: + + [REXML::CData, "foo"] + [REXML::CData, "bar"] + +The payload of a document is a tree of nodes, descending from the root element: + + doc.root.children.each do |child| + p [child, child.class] + end + +Output: + + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + +== Exploring an Element + +An REXML::Element object represents an XML element. + +The object inherits from its ancestor classes: + +- REXML::Child (includes module REXML::Node) + - REXML::Parent (includes module {Enumerable}[rdoc-ref:Enumerable]). + - REXML::Element (includes module REXML::Namespace). + +This section covers methods: + +- Defined in REXML::Element itself. +- Inherited from REXML::Parent and REXML::Child. +- Included from REXML::Node. + +=== Inside the Element + +[Brief String Representation] + + Use method REXML::Element#inspect to retrieve a brief string representation. + + doc.root.inspect # => " ... " + + The ellipsis (...) indicates that the element has children. + When there are no children, the ellipsis is omitted: + + Element.new('foo').inspect # => "" + + If the element has attributes, those are also included: + + doc.root.elements.first.inspect # => " ... " + +[Extended String Representation] + + Use inherited method REXML::Child.bytes to retrieve an extended + string representation. + + doc.root.bytes # => "\n\n\n Everyday Italian\n Giada De Laurentiis\n 2005\n 30.00\n\n\n\n Harry Potter\n J K. Rowling\n 2005\n 29.99\n\n\n\n XQuery Kick Start\n James McGovern\n Per Bothner\n Kurt Cagle\n James Linn\n Vaidyanathan Nagarajan\n 2003\n 49.99\n\n\n\n Learning XML\n Erik T. Ray\n 2003\n 39.95\n\n\n" + +[Node Type] + + Use method REXML::Element#node_type to retrieve the node type (always +:element+): + + doc.root.node_type # => :element + +[Raw Mode] + + Use method REXML::Element#raw to retrieve whether (+true+ or +nil+) + raw mode is set. + + doc.root.raw # => nil + +[Context] + + Use method REXML::Element#context to retrieve the context hash + (see {Element Context}[../context_rdoc.html]): + + doc.root.context # => {} + +=== Relationships + +An element may have: + +- Ancestors. +- Siblings. +- Children. + +==== Ancestors + +[Containing Document] + + Use method REXML::Element#document to retrieve the containing document, if any: + + ele = doc.root.elements.first # => ... + ele.document # => ... + ele = Element.new('foo') # => + ele.document # => nil + +[Root Element] + + Use method REXML::Element#root to retrieve the root element: + + ele = doc.root.elements.first # => ... + ele.root # => ... + ele = Element.new('foo') # => + ele.root # => + +[Root Node] + + Use method REXML::Element#root_node to retrieve the most distant ancestor, + which is the containing document, if any, otherwise the root element: + + ele = doc.root.elements.first # => ... + ele.root_node # => ... + ele = Element.new('foo') # => + ele.root_node # => + +[Parent] + + Use inherited method REXML::Child#parent to retrieve the parent + + ele = doc.root # => ... + ele.parent # => ... + ele = doc.root.elements.first # => ... + ele.parent # => ... + + Use included method REXML::Node#index_in_parent to retrieve the index + of the element among all of its parents children (not just the element children). + Note that while the index for doc.root.elements[n] is 1-based, + the returned index is 0-based. + + doc.root.children # => + # ["\n\n", + # ... , + # "\n\n", + # ... , + # "\n\n", + # ... , + # "\n\n", + # ... , + # "\n\n"] + ele = doc.root.elements[1] # => ... + ele.index_in_parent # => 2 + ele = doc.root.elements[2] # => ... + ele.index_in_parent# => 4 + +==== Siblings + +[Next Element] + + Use method REXML::Element#next_element to retrieve the first following + sibling that is itself an element (+nil+ if there is none): + + ele = doc.root.elements[1] + while ele do + p [ele.class, ele] + ele = ele.next_element + end + p ele + + Output: + + [REXML::Element, ... ] + [REXML::Element, ... ] + [REXML::Element, ... ] + [REXML::Element, ... ] + +[Previous Element] + + Use method REXML::Element#previous_element to retrieve the first preceding + sibling that is itself an element (+nil+ if there is none): + + ele = doc.root.elements[4] + while ele do + p [ele.class, ele] + ele = ele.previous_element + end + p ele + + Output: + + [REXML::Element, ... ] + [REXML::Element, ... ] + [REXML::Element, ... ] + [REXML::Element, ... ] + +[Next Node] + + Use included method REXML::Node.next_sibling_node + (or its alias next_sibling) to retrieve the first following node + regardless of its class: + + node = doc.root.children[0] + while node do + p [node.class, node] + node = node.next_sibling + end + p node + + Output: + + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + +[Previous Node] + + Use included method REXML::Node.previous_sibling_node + (or its alias previous_sibling) to retrieve the first preceding node + regardless of its class: + + node = doc.root.children[-1] + while node do + p [node.class, node] + node = node.previous_sibling + end + p node + + Output: + + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + +==== Children + +[Child Count] + + Use inherited method REXML::Parent.size to retrieve the count + of nodes (of all types) in the element: + + doc.root.size # => 9 + +[Child Nodes] + + Use inherited method REXML::Parent.children to retrieve an array + of the child nodes (of all types): + + doc.root.children # => + # ["\n\n", + # ... , + # "\n\n", + # ... , + # "\n\n", + # ... , + # "\n\n", + # ... , + # "\n\n"] + +[Child at Index] + + Use method REXML::Element#[] to retrieve the child at a given numerical index, + or +nil+ if there is no such child: + + doc.root[0] # => "\n\n" + doc.root[1] # => ... + doc.root[7] # => ... + doc.root[8] # => "\n\n" + + doc.root[-1] # => "\n\n" + doc.root[-2] # => ... + + doc.root[50] # => nil + +[Index of Child] + + Use method REXML::Parent#index to retrieve the zero-based child index + of the given object, or #size - 1 if there is no such child: + + ele = doc.root # => ... + ele.index(ele[0]) # => 0 + ele.index(ele[1]) # => 1 + ele.index(ele[7]) # => 7 + ele.index(ele[8]) # => 8 + + ele.index(ele[-1]) # => 8 + ele.index(ele[-2]) # => 7 + + ele.index(ele[50]) # => 8 + +[Element Children] + + Use method REXML::Element#has_elements? to retrieve whether the element + has element children: + + doc.root.has_elements? # => true + REXML::Element.new('foo').has_elements? # => false + + Use method REXML::Element#elements to retrieve the REXML::Elements object + containing the element children: + + eles = doc.root.elements + eles # => # ... > + eles.size # => 4 + eles.each {|e| p [e.class], e } + + Output: + + [ ... , + ... , + ... , + ... + ] + +Note that while in this example, all the element children of the root element are +elements of the same name, 'book', that is not true of all documents; +a root element (or any other element) may have any mixture of child elements. + +[CDATA Children] + + Use method REXML::Element#cdatas to retrieve a frozen array of CDATA children: + + my_xml = <<-EOT + + + + + EOT + my_doc = REXML::Document.new(my_xml) + cdatas my_doc.root.cdatas + cdatas.frozen? # => true + cdatas.map {|cd| cd.class } # => [REXML::CData, REXML::CData] + +[Comment Children] + + Use method REXML::Element#comments to retrieve a frozen array of comment children: + + my_xml = <<-EOT + + + + + EOT + my_doc = REXML::Document.new(my_xml) + comments = my_doc.root.comments + comments.frozen? # => true + comments.map {|c| c.class } # => [REXML::Comment, REXML::Comment] + comments.map {|c| c.to_s } # => ["foo", "bar"] + +[Processing Instruction Children] + + Use method REXML::Element#instructions to retrieve a frozen array + of processing instruction children: + + my_xml = <<-EOT + + + + + EOT + my_doc = REXML::Document.new(my_xml) + instrs = my_doc.root.instructions + instrs.frozen? # => true + instrs.map {|i| i.class } # => [REXML::Instruction, REXML::Instruction] + instrs.map {|i| i.to_s } # => ["", ""] + +[Text Children] + + Use method REXML::Element#has_text? to retrieve whether the element + has text children: + + doc.root.has_text? # => true + REXML::Element.new('foo').has_text? # => false + + Use method REXML::Element#texts to retrieve a frozen array of text children: + + my_xml = 'textmore' + my_doc = REXML::Document.new(my_xml) + texts = my_doc.root.texts + texts.frozen? # => true + texts.map {|t| t.class } # => [REXML::Text, REXML::Text] + texts.map {|t| t.to_s } # => ["text", "more"] + +[Parenthood] + + Use inherited method REXML::Parent.parent? to retrieve whether the element is a parent; + always returns +true+; only REXML::Child#parent returns +false+. + + doc.root.parent? # => true + +=== Element Attributes + +Use method REXML::Element#has_attributes? to return whether the element +has attributes: + + ele = doc.root # => ... + ele.has_attributes? # => false + ele = ele.elements.first # => ... + ele.has_attributes? # => true + +Use method REXML::Element#attributes to return the hash +containing the attributes for the element. +Each hash key is a string attribute name; +each hash value is an REXML::Attribute object. + + ele = doc.root # => ... + attrs = ele.attributes # => {} + + ele = ele.elements.first # => ... + attrs = ele.attributes # => {"category"=>category='cooking'} + attrs.size # => 1 + attr_name = attrs.keys.first # => "category" + attr_name.class # => String + attr_value = attrs.values.first # => category='cooking' + attr_value.class # => REXML::Attribute + +Use method REXML::Element#[] to retrieve the string value for a given attribute, +which may be given as either a string or a symbol: + + ele = doc.root.elements.first # => ... + attr_value = ele['category'] # => "cooking" + attr_value.class # => String + ele['nosuch'] # => nil + +Use method REXML::Element#attribute to retrieve the value of a named attribute: + + my_xml = "" + my_doc = REXML::Document.new(my_xml) + my_doc.root.attribute("x") # => x='x' + my_doc.root.attribute("x", "a") # => a:x='a:x' + +== Whitespace + +Use method REXML::Element#ignore_whitespace_nodes to determine whether +whitespace nodes were ignored when the XML was parsed; +returns +true+ if so, +nil+ otherwise. + +Use method REXML::Element#whitespace to determine whether whitespace +is respected for the element; returns +true+ if so, +false+ otherwise. + +== Namespaces + +Use method REXML::Element#namespace to retrieve the string namespace URI +for the element, which may derive from one of its ancestors: + + xml_string = <<-EOT + + + + + + + EOT + d = Document.new(xml_string) + b = d.elements['//b'] + b.namespace # => "1" + b.namespace('y') # => "2" + b.namespace('nosuch') # => nil + +Use method REXML::Element#namespaces to retrieve a hash of all defined namespaces +in the element and its ancestors: + + xml_string = <<-EOT + + + + + + + EOT + d = Document.new(xml_string) + d.elements['//a'].namespaces # => {"x"=>"1", "y"=>"2"} + d.elements['//b'].namespaces # => {"x"=>"1", "y"=>"2"} + d.elements['//c'].namespaces # => {"x"=>"1", "y"=>"2", "z"=>"3"} + +Use method REXML::Element#prefixes to retrieve an array of the string prefixes (names) +of all defined namespaces in the element and its ancestors: + + xml_string = <<-EOT + + + + + + + EOT + d = Document.new(xml_string, {compress_whitespace: :all}) + d.elements['//a'].prefixes # => ["x", "y"] + d.elements['//b'].prefixes # => ["x", "y"] + d.elements['//c'].prefixes # => ["x", "y", "z"] + +== Traversing + +You can use certain methods to traverse children of the element. +Each child that meets given criteria is yielded to the given block. + +[Traverse All Children] + + Use inherited method REXML::Parent#each (or its alias #each_child) to traverse + all children of the element: + + doc.root.each {|child| p [child.class, child] } + + Output: + + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + [REXML::Element, ... ] + [REXML::Text, "\n\n"] + +[Traverse Element Children] + + Use method REXML::Element#each_element to traverse only the element children + of the element: + + doc.root.each_element {|e| p [e.class, e] } + + Output: + + [REXML::Element, ... ] + [REXML::Element, ... ] + [REXML::Element, ... ] + [REXML::Element, ... ] + +[Traverse Element Children with Attribute] + + Use method REXML::Element#each_element_with_attribute with the single argument + +attr_name+ to traverse each element child that has the given attribute: + + my_doc = Document.new '' + my_doc.root.each_element_with_attribute('id') {|e| p [e.class, e] } + + Output: + + [REXML::Element, ] + [REXML::Element, ] + [REXML::Element, ] + + Use the same method with a second argument +value+ to traverse + each element child element that has the given attribute and value: + + my_doc.root.each_element_with_attribute('id', '1') {|e| p [e.class, e] } + + Output: + + [REXML::Element, ] + [REXML::Element, ] + + Use the same method with a third argument +max+ to traverse + no more than the given number of element children: + + my_doc.root.each_element_with_attribute('id', '1', 1) {|e| p [e.class, e] } + + Output: + + [REXML::Element, ] + + Use the same method with a fourth argument +xpath+ to traverse + only those element children that match the given xpath: + + my_doc.root.each_element_with_attribute('id', '1', 2, '//d') {|e| p [e.class, e] } + + Output: + + [REXML::Element, ] + +[Traverse Element Children with Text] + + Use method REXML::Element#each_element_with_text with no arguments + to traverse those element children that have text: + + my_doc = Document.new 'bbd' + my_doc.root.each_element_with_text {|e| p [e.class, e] } + + Output: + + [REXML::Element, ... ] + [REXML::Element, ... ] + [REXML::Element, ... ] + + Use the same method with the single argument +text+ to traverse + those element children that have exactly that text: + + my_doc.root.each_element_with_text('b') {|e| p [e.class, e] } + + Output: + + [REXML::Element, ... ] + [REXML::Element, ... ] + + Use the same method with additional second argument +max+ to traverse + no more than the given number of element children: + + my_doc.root.each_element_with_text('b', 1) {|e| p [e.class, e] } + + Output: + + [REXML::Element, ... ] + + Use the same method with additional third argument +xpath+ to traverse + only those element children that also match the given xpath: + + my_doc.root.each_element_with_text('b', 2, '//c') {|e| p [e.class, e] } + + Output: + + [REXML::Element, ... ] + +[Traverse Element Children's Indexes] + + Use inherited method REXML::Parent#each_index to traverse all children's indexes + (not just those of element children): + + doc.root.each_index {|i| print i } + + Output: + + 012345678 + +[Traverse Children Recursively] + + Use included method REXML::Node#each_recursive to traverse all children recursively: + + doc.root.each_recursive {|child| p [child.class, child] } + + Output: + + [REXML::Element, ... ] + [REXML::Element, ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <year> ... </>] + [REXML::Element, <price> ... </>] + [REXML::Element, <book category='children'> ... </>] + [REXML::Element, <title lang='en'> ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <year> ... </>] + [REXML::Element, <price> ... </>] + [REXML::Element, <book category='web'> ... </>] + [REXML::Element, <title lang='en'> ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <year> ... </>] + [REXML::Element, <price> ... </>] + [REXML::Element, <book category='web' cover='paperback'> ... </>] + [REXML::Element, <title lang='en'> ... </>] + [REXML::Element, <author> ... </>] + [REXML::Element, <year> ... </>] + [REXML::Element, <price> ... </>] + +== Searching + +You can use certain methods to search among the descendants of an element. + +Use method REXML::Element#get_elements to retrieve all element children of the element +that match the given +xpath+: + + xml_string = <<-EOT + <root> + <a level='1'> + <a level='2'/> + </a> + </root> + EOT + d = Document.new(xml_string) + d.root.get_elements('//a') # => [<a level='1'> ... </>, <a level='2'/>] + +Use method REXML::Element#get_text with no argument to retrieve the first text node +in the first child: + + my_doc = Document.new "<p>some text <b>this is bold!</b> more text</p>" + text_node = my_doc.root.get_text + text_node.class # => REXML::Text + text_node.to_s # => "some text " + +Use the same method with argument +xpath+ to retrieve the first text node +in the first child that matches the xpath: + + my_doc.root.get_text(1) # => "this is bold!" + +Use method REXML::Element#text with no argument to retrieve the text +from the first text node in the first child: + + my_doc = Document.new "<p>some text <b>this is bold!</b> more text</p>" + text_node = my_doc.root.text + text_node.class # => String + text_node # => "some text " + +Use the same method with argument +xpath+ to retrieve the text from the first text node +in the first child that matches the xpath: + + my_doc.root.text(1) # => "this is bold!" + +Use included method REXML::Node#find_first_recursive +to retrieve the first descendant element +for which the given block returns a truthy value, or +nil+ if none: + + doc.root.find_first_recursive do |ele| + ele.name == 'price' + end # => <price> ... </> + doc.root.find_first_recursive do |ele| + ele.name == 'nosuch' + end # => nil + +== Editing + +=== Editing a Document + +[Creating a Document] + + Create a new document with method REXML::Document::new: + + doc = Document.new(source_string) + empty_doc = REXML::Document.new + +[Adding to the Document] + + Add an XML declaration with method REXML::Document#add + and an argument of type REXML::XMLDecl: + + my_doc = Document.new + my_doc.xml_decl.to_s # => "" + my_doc.add(XMLDecl.new('2.0')) + my_doc.xml_decl.to_s # => "<?xml version='2.0'?>" + + Add a document type with method REXML::Document#add + and an argument of type REXML::DocType: + + my_doc = Document.new + my_doc.doctype.to_s # => "" + my_doc.add(DocType.new('foo')) + my_doc.doctype.to_s # => "<!DOCTYPE foo>" + + Add a node of any other REXML type with method REXML::Document#add and an argument + that is not of type REXML::XMLDecl or REXML::DocType: + + my_doc = Document.new + my_doc.add(Element.new('foo')) + my_doc.to_s # => "<foo/>" + + Add an existing element as the root element with method REXML::Document#add_element: + + ele = Element.new('foo') + my_doc = Document.new + my_doc.add_element(ele) + my_doc.root # => <foo/> + + Create and add an element as the root element with method REXML::Document#add_element: + + my_doc = Document.new + my_doc.add_element('foo') + my_doc.root # => <foo/> + +=== Editing an Element + +==== Creating an Element + +Create a new element with method REXML::Element::new: + + ele = Element.new('foo') # => <foo/> + +==== Setting Element Properties + +Set the context for an element with method REXML::Element#context= +(see {Element Context}[../context_rdoc.html]): + + ele.context # => nil + ele.context = {ignore_whitespace_nodes: :all} + ele.context # => {:ignore_whitespace_nodes=>:all} + +Set the parent for an element with inherited method REXML::Child#parent= + + ele.parent # => nil + ele.parent = Element.new('bar') + ele.parent # => <bar/> + +Set the text for an element with method REXML::Element#text=: + + ele.text # => nil + ele.text = 'bar' + ele.text # => "bar" + +==== Adding to an Element + +Add a node as the last child with inherited method REXML::Parent#add (or its alias #push): + + ele = Element.new('foo') # => <foo/> + ele.push(Text.new('bar')) + ele.push(Element.new('baz')) + ele.children # => ["bar", <baz/>] + +Add a node as the first child with inherited method REXML::Parent#unshift: + + ele = Element.new('foo') # => <foo/> + ele.unshift(Element.new('bar')) + ele.unshift(Text.new('baz')) + ele.children # => ["bar", <baz/>] + +Add an element as the last child with method REXML::Element#add_element: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_element(Element.new('baz')) + ele.children # => [<bar/>, <baz/>] + +Add a text node as the last child with method REXML::Element#add_text: + + ele = Element.new('foo') # => <foo/> + ele.add_text('bar') + ele.add_text(Text.new('baz')) + ele.children # => ["bar", "baz"] + +Insert a node before a given node with method REXML::Parent#insert_before: + + ele = Element.new('foo') # => <foo/> + ele.add_text('bar') + ele.add_text(Text.new('baz')) + ele.children # => ["bar", "baz"] + target = ele[1] # => "baz" + ele.insert_before(target, Text.new('bat')) + ele.children # => ["bar", "bat", "baz"] + +Insert a node after a given node with method REXML::Parent#insert_after: + + ele = Element.new('foo') # => <foo/> + ele.add_text('bar') + ele.add_text(Text.new('baz')) + ele.children # => ["bar", "baz"] + target = ele[0] # => "bar" + ele.insert_after(target, Text.new('bat')) + ele.children # => ["bar", "bat", "baz"] + +Add an attribute with method REXML::Element#add_attribute: + + ele = Element.new('foo') # => <foo/> + ele.add_attribute('bar', 'baz') + ele.add_attribute(Attribute.new('bat', 'bam')) + ele.attributes # => {"bar"=>bar='baz', "bat"=>bat='bam'} + +Add multiple attributes with method REXML::Element#add_attributes: + + ele = Element.new('foo') # => <foo/> + ele.add_attributes({'bar' => 'baz', 'bat' => 'bam'}) + ele.add_attributes([['ban', 'bap'], ['bah', 'bad']]) + ele.attributes # => {"bar"=>bar='baz', "bat"=>bat='bam', "ban"=>ban='bap', "bah"=>bah='bad'} + +Add a namespace with method REXML::Element#add_namespace: + + ele = Element.new('foo') # => <foo/> + ele.add_namespace('bar') + ele.add_namespace('baz', 'bat') + ele.namespaces # => {"xmlns"=>"bar", "baz"=>"bat"} + +==== Deleting from an Element + +Delete a specific child object with inherited method REXML::Parent#delete: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.children # => [<bar/>, "baz"] + target = ele[1] # => "baz" + ele.delete(target) # => "baz" + ele.children # => [<bar/>] + target = ele[0] # => <baz/> + ele.delete(target) # => <baz/> + ele.children # => [] + +Delete a child at a specific index with inherited method REXML::Parent#delete_at: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.children # => [<bar/>, "baz"] + ele.delete_at(1) + ele.children # => [<bar/>] + ele.delete_at(0) + ele.children # => [] + +Delete all children meeting a specified criterion with inherited method +REXML::Parent#delete_if: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.add_element('bat') + ele.add_text('bam') + ele.children # => [<bar/>, "baz", <bat/>, "bam"] + ele.delete_if {|child| child.instance_of?(Text) } + ele.children # => [<bar/>, <bat/>] + +Delete an element at a specific 1-based index with method REXML::Element#delete_element: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.add_element('bat') + ele.add_text('bam') + ele.children # => [<bar/>, "baz", <bat/>, "bam"] + ele.delete_element(2) # => <bat/> + ele.children # => [<bar/>, "baz", "bam"] + ele.delete_element(1) # => <bar/> + ele.children # => ["baz", "bam"] + +Delete a specific element with the same method: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.add_element('bat') + ele.add_text('bam') + ele.children # => [<bar/>, "baz", <bat/>, "bam"] + target = ele.elements[2] # => <bat/> + ele.delete_element(target) # => <bat/> + ele.children # => [<bar/>, "baz", "bam"] + +Delete an element matching an xpath using the same method: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.add_element('bat') + ele.add_text('bam') + ele.children # => [<bar/>, "baz", <bat/>, "bam"] + ele.delete_element('./bat') # => <bat/> + ele.children # => [<bar/>, "baz", "bam"] + ele.delete_element('./bar') # => <bar/> + ele.children # => ["baz", "bam"] + +Delete an attribute by name with method REXML::Element#delete_attribute: + + ele = Element.new('foo') # => <foo/> + ele.add_attributes({'bar' => 'baz', 'bam' => 'bat'}) + ele.attributes # => {"bar"=>bar='baz', "bam"=>bam='bat'} + ele.delete_attribute('bam') + ele.attributes # => {"bar"=>bar='baz'} + +Delete a namespace with method REXML::Element#delete_namespace: + + ele = Element.new('foo') # => <foo/> + ele.add_namespace('bar') + ele.add_namespace('baz', 'bat') + ele.namespaces # => {"xmlns"=>"bar", "baz"=>"bat"} + ele.delete_namespace('xmlns') + ele.namespaces # => {} # => {"baz"=>"bat"} + ele.delete_namespace('baz') + ele.namespaces # => {} # => {} + +Remove an element from its parent with inherited method REXML::Child#remove: + + ele = Element.new('foo') # => <foo/> + parent = Element.new('bar') # => <bar/> + parent.add_element(ele) # => <foo/> + parent.children.size # => 1 + ele.remove # => <foo/> + parent.children.size # => 0 + +==== Replacing Nodes + +Replace the node at a given 0-based index with inherited method REXML::Parent#[]=: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.add_element('bat') + ele.add_text('bam') + ele.children # => [<bar/>, "baz", <bat/>, "bam"] + ele[2] = Text.new('bad') # => "bad" + ele.children # => [<bar/>, "baz", "bad", "bam"] + +Replace a given node with another node with inherited method REXML::Parent#replace_child: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.add_element('bat') + ele.add_text('bam') + ele.children # => [<bar/>, "baz", <bat/>, "bam"] + target = ele[2] # => <bat/> + ele.replace_child(target, Text.new('bah')) + ele.children # => [<bar/>, "baz", "bah", "bam"] + +Replace +self+ with a given node with inherited method REXML::Child#replace_with: + + ele = Element.new('foo') # => <foo/> + ele.add_element('bar') + ele.add_text('baz') + ele.add_element('bat') + ele.add_text('bam') + ele.children # => [<bar/>, "baz", <bat/>, "bam"] + target = ele[2] # => <bat/> + target.replace_with(Text.new('bah')) + ele.children # => [<bar/>, "baz", "bah", "bam"] + +=== Cloning + +Create a shallow clone of an element with method REXML::Element#clone. +The clone contains the name and attributes, but not the parent or children: + + ele = Element.new('foo') + ele.add_attributes({'bar' => 0, 'baz' => 1}) + ele.clone # => <foo bar='0' baz='1'/> + +Create a shallow clone of a document with method REXML::Document#clone. +The XML declaration is copied; the document type and root element are not cloned: + + my_xml = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo><root/>' + my_doc = Document.new(my_xml) + clone_doc = my_doc.clone + + my_doc.xml_decl # => <?xml ... ?> + clone_doc.xml_decl # => <?xml ... ?> + + my_doc.doctype.to_s # => "<?xml version='1.0' encoding='UTF-8'?>" + clone_doc.doctype.to_s # => "" + + my_doc.root # => <root/> + clone_doc.root # => nil + +Create a deep clone of an element with inherited method REXML::Parent#deep_clone. +All nodes and attributes are copied: + + doc.to_s.size # => 825 + clone = doc.deep_clone + clone.to_s.size # => 825 + +== Writing the Document + +Write a document to an \IO stream (defaults to <tt>$stdout</tt>) +with method REXML::Document#write: + + doc.write + +Output: + + <?xml version='1.0' encoding='UTF-8'?> + <bookstore> + + <book category='cooking'> + <title lang='en'>Everyday Italian + Giada De Laurentiis + 2005 + 30.00 + + + + Harry Potter + J K. Rowling + 2005 + 29.99 + + + + XQuery Kick Start + James McGovern + Per Bothner + Kurt Cagle + James Linn + Vaidyanathan Nagarajan + 2003 + 49.99 + + + + Learning XML + Erik T. Ray + 2003 + 39.95 + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml.rb new file mode 100644 index 0000000..eee246e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require_relative "rexml/document" diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attlistdecl.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attlistdecl.rb new file mode 100644 index 0000000..44a91d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attlistdecl.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: false +#vim:ts=2 sw=2 noexpandtab: +require_relative 'child' +require_relative 'source' + +module REXML + # This class needs: + # * Documentation + # * Work! Not all types of attlists are intelligently parsed, so we just + # spew back out what we get in. This works, but it would be better if + # we formatted the output ourselves. + # + # AttlistDecls provide *just* enough support to allow namespace + # declarations. If you need some sort of generalized support, or have an + # interesting idea about how to map the hideous, terrible design of DTD + # AttlistDecls onto an intuitive Ruby interface, let me know. I'm desperate + # for anything to make DTDs more palateable. + class AttlistDecl < Child + include Enumerable + + # What is this? Got me. + attr_reader :element_name + + # Create an AttlistDecl, pulling the information from a Source. Notice + # that this isn't very convenient; to create an AttlistDecl, you basically + # have to format it yourself, and then have the initializer parse it. + # Sorry, but for the foreseeable future, DTD support in REXML is pretty + # weak on convenience. Have I mentioned how much I hate DTDs? + def initialize(source) + super() + if (source.kind_of? Array) + @element_name, @pairs, @contents = *source + end + end + + # Access the attlist attribute/value pairs. + # value = attlist_decl[ attribute_name ] + def [](key) + @pairs[key] + end + + # Whether an attlist declaration includes the given attribute definition + # if attlist_decl.include? "xmlns:foobar" + def include?(key) + @pairs.keys.include? key + end + + # Iterate over the key/value pairs: + # attlist_decl.each { |attribute_name, attribute_value| ... } + def each(&block) + @pairs.each(&block) + end + + # Write out exactly what we got in. + def write out, indent=-1 + out << @contents + end + + def node_type + :attlistdecl + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attribute.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attribute.rb new file mode 100644 index 0000000..c567324 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/attribute.rb @@ -0,0 +1,210 @@ +# frozen_string_literal: true +require_relative "namespace" +require_relative 'text' + +module REXML + # Defines an Element Attribute; IE, a attribute=value pair, as in: + # . Attributes can be in their own + # namespaces. General users of REXML will not interact with the + # Attribute class much. + class Attribute + include Node + include Namespace + + # The element to which this attribute belongs + attr_reader :element + PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um + + NEEDS_A_SECOND_CHECK = /(<|&((#{Entity::NAME});|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));)?)/um + + # Constructor. + # FIXME: The parser doesn't catch illegal characters in attributes + # + # first:: + # Either: an Attribute, which this new attribute will become a + # clone of; or a String, which is the name of this attribute + # second:: + # If +first+ is an Attribute, then this may be an Element, or nil. + # If nil, then the Element parent of this attribute is the parent + # of the +first+ Attribute. If the first argument is a String, + # then this must also be a String, and is the content of the attribute. + # If this is the content, it must be fully normalized (contain no + # illegal characters). + # parent:: + # Ignored unless +first+ is a String; otherwise, may be the Element + # parent of this attribute, or nil. + # + # + # Attribute.new( attribute_to_clone ) + # Attribute.new( attribute_to_clone, parent_element ) + # Attribute.new( "attr", "attr_value" ) + # Attribute.new( "attr", "attr_value", parent_element ) + def initialize( first, second=nil, parent=nil ) + @normalized = @unnormalized = @element = nil + if first.kind_of? Attribute + self.name = first.expanded_name + @unnormalized = first.value + if second.kind_of? Element + @element = second + else + @element = first.element + end + elsif first.kind_of? String + @element = parent + self.name = first + @normalized = second.to_s + else + raise "illegal argument #{first.class.name} to Attribute constructor" + end + end + + # Returns the namespace of the attribute. + # + # e = Element.new( "elns:myelement" ) + # e.add_attribute( "nsa:a", "aval" ) + # e.add_attribute( "b", "bval" ) + # e.attributes.get_attribute( "a" ).prefix # -> "nsa" + # e.attributes.get_attribute( "b" ).prefix # -> "" + # a = Attribute.new( "x", "y" ) + # a.prefix # -> "" + def prefix + super + end + + # Returns the namespace URL, if defined, or nil otherwise + # + # e = Element.new("el") + # e.add_namespace("ns", "http://url") + # e.add_attribute("ns:a", "b") + # e.add_attribute("nsx:a", "c") + # e.attribute("ns:a").namespace # => "http://url" + # e.attribute("nsx:a").namespace # => nil + # + # This method always returns "" for no namespace attribute. Because + # the default namespace doesn't apply to attribute names. + # + # From https://www.w3.org/TR/xml-names/#uniqAttrs + # + # > the default namespace does not apply to attribute names + # + # e = REXML::Element.new("el") + # e.add_namespace("", "http://example.com/") + # e.namespace # => "http://example.com/" + # e.add_attribute("a", "b") + # e.attribute("a").namespace # => "" + def namespace arg=nil + arg = prefix if arg.nil? + if arg == "" + "" + else + @element.namespace(arg) + end + end + + # Returns true if other is an Attribute and has the same name and value, + # false otherwise. + def ==( other ) + other.kind_of?(Attribute) and other.name==name and other.value==value + end + + # Creates (and returns) a hash from both the name and value + def hash + name.hash + value.hash + end + + # Returns this attribute out as XML source, expanding the name + # + # a = Attribute.new( "x", "y" ) + # a.to_string # -> "x='y'" + # b = Attribute.new( "ns:x", "y" ) + # b.to_string # -> "ns:x='y'" + def to_string + value = to_s + if @element and @element.context and @element.context[:attribute_quote] == :quote + value = value.gsub('"', '"') if value.include?('"') + %Q^#@expanded_name="#{value}"^ + else + value = value.gsub("'", ''') if value.include?("'") + "#@expanded_name='#{value}'" + end + end + + def doctype + @element&.document&.doctype + end + + # Returns the attribute value, with entities replaced + def to_s + return @normalized if @normalized + + @normalized = Text::normalize( @unnormalized, doctype ) + @normalized + end + + # Returns the UNNORMALIZED value of this attribute. That is, entities + # have been expanded to their values + def value + return @unnormalized if @unnormalized + + @unnormalized = Text::unnormalize(@normalized, doctype, + entity_expansion_text_limit: @element&.document&.entity_expansion_text_limit) + end + + # The normalized value of this attribute. That is, the attribute with + # entities intact. + def normalized=(new_normalized) + @normalized = new_normalized + @unnormalized = nil + end + + # Returns a copy of this attribute + def clone + Attribute.new self + end + + # Sets the element of which this object is an attribute. Normally, this + # is not directly called. + # + # Returns this attribute + def element=( element ) + @element = element + + if @normalized + Text.check( @normalized, NEEDS_A_SECOND_CHECK ) + end + + self + end + + # Removes this Attribute from the tree, and returns true if successful + # + # This method is usually not called directly. + def remove + @element.attributes.delete self.name unless @element.nil? + end + + # Writes this attribute (EG, puts 'key="value"' to the output) + def write( output, indent=-1 ) + output << to_string + end + + def node_type + :attribute + end + + def inspect + rv = +"" + write( rv ) + rv + end + + def xpath + @element.xpath + "/@#{self.expanded_name}" + end + + def document + @element&.document + end + end +end +#vim:ts=2 sw=2 noexpandtab: diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/cdata.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/cdata.rb new file mode 100644 index 0000000..264ad64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/cdata.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: false +require_relative "text" + +module REXML + class CData < Text + START = '' + ILLEGAL = /(\]\]>)/ + + # Constructor. CData is data between + # + # _Examples_ + # CData.new( source ) + # CData.new( "Here is some CDATA" ) + # CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element ) + def initialize( first, whitespace=true, parent=nil ) + super( first, whitespace, parent, false, true, ILLEGAL ) + end + + # Make a copy of this object + # + # _Examples_ + # c = CData.new( "Some text" ) + # d = c.clone + # d.to_s # -> "Some text" + def clone + CData.new self + end + + # Returns the content of this CData object + # + # _Examples_ + # c = CData.new( "Some text" ) + # c.to_s # -> "Some text" + def to_s + @string + end + + def value + @string + end + + # == DEPRECATED + # See the rexml/formatters package + # + # Generates XML output of this object + # + # output:: + # Where to write the string. Defaults to $stdout + # indent:: + # The amount to indent this node by + # transitive:: + # Ignored + # ie_hack:: + # Ignored + # + # _Examples_ + # c = CData.new( " Some text " ) + # c.write( $stdout ) #-> + def write( output=$stdout, indent=-1, transitive=false, ie_hack=false ) + Kernel.warn( "#{self.class.name}#write is deprecated", uplevel: 1) + indent( output, indent ) + output << START + output << @string + output << STOP + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/child.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/child.rb new file mode 100644 index 0000000..2718040 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/child.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: false +require_relative "node" + +module REXML + ## + # A Child object is something contained by a parent, and this class + # contains methods to support that. Most user code will not use this + # class directly. + class Child + include Node + attr_reader :parent # The Parent of this object + + # Constructor. Any inheritors of this class should call super to make + # sure this method is called. + # parent:: + # if supplied, the parent of this child will be set to the + # supplied value, and self will be added to the parent + def initialize( parent = nil ) + @parent = nil + # Declare @parent, but don't define it. The next line sets the + # parent. + parent.add( self ) if parent + end + + # Replaces this object with another object. Basically, calls + # Parent.replace_child + # + # Returns:: self + def replace_with( child ) + @parent.replace_child( self, child ) + self + end + + # Removes this child from the parent. + # + # Returns:: self + def remove + unless @parent.nil? + @parent.delete self + end + self + end + + # Sets the parent of this child to the supplied argument. + # + # other:: + # Must be a Parent object. If this object is the same object as the + # existing parent of this child, no action is taken. Otherwise, this + # child is removed from the current parent (if one exists), and is added + # to the new parent. + # Returns:: The parent added + def parent=( other ) + return @parent if @parent == other + @parent.delete self if defined? @parent and @parent + @parent = other + end + + alias :next_sibling :next_sibling_node + alias :previous_sibling :previous_sibling_node + + # Sets the next sibling of this child. This can be used to insert a child + # after some other child. + # a = Element.new("a") + # b = a.add_element("b") + # c = Element.new("c") + # b.next_sibling = c + # # => + def next_sibling=( other ) + parent.insert_after self, other + end + + # Sets the previous sibling of this child. This can be used to insert a + # child before some other child. + # a = Element.new("a") + # b = a.add_element("b") + # c = Element.new("c") + # b.previous_sibling = c + # # => + def previous_sibling=(other) + parent.insert_before self, other + end + + # Returns:: the document this child belongs to, or nil if this child + # belongs to no document + def document + parent&.document + end + + # This doesn't yet handle encodings + def bytes + document&.encoding + + to_s + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/comment.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/comment.rb new file mode 100644 index 0000000..e7e104d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/comment.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: false +require_relative "child" + +module REXML + ## + # Represents an XML comment; that is, text between \ + class Comment < Child + include Comparable + START = "" + + # The content text + + attr_accessor :string + + ## + # Constructor. The first argument can be one of three types: + # @param first If String, the contents of this comment are set to the + # argument. If Comment, the argument is duplicated. If + # Source, the argument is scanned for a comment. + # @param second If the first argument is a Source, this argument + # should be nil, not supplied, or a Parent to be set as the parent + # of this object + def initialize( first, second = nil ) + super(second) + if first.kind_of? String + @string = first + elsif first.kind_of? Comment + @string = first.string + end + end + + def clone + Comment.new self + end + + # == DEPRECATED + # See REXML::Formatters + # + # output:: + # Where to write the string + # indent:: + # An integer. If -1, no indenting will be used; otherwise, the + # indentation will be this number of spaces, and children will be + # indented an additional amount. + # transitive:: + # Ignored by this class. The contents of comments are never modified. + # ie_hack:: + # Needed for conformity to the child API, but not used by this class. + def write( output, indent=-1, transitive=false, ie_hack=false ) + Kernel.warn("#{self.class.name}#write is deprecated. See REXML::Formatters", uplevel: 1) + indent( output, indent ) + output << START + output << @string + output << STOP + end + + alias :to_s :string + + ## + # Compares this Comment to another; the contents of the comment are used + # in the comparison. + def <=>(other) + other.to_s <=> @string + end + + ## + # Compares this Comment to another; the contents of the comment are used + # in the comparison. + def ==( other ) + other.kind_of? Comment and + (other <=> self) == 0 + end + + def node_type + :comment + end + end +end +#vim:ts=2 sw=2 noexpandtab: diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/doctype.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/doctype.rb new file mode 100644 index 0000000..a9cf9f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/doctype.rb @@ -0,0 +1,306 @@ +# frozen_string_literal: false +require_relative "parent" +require_relative "parseexception" +require_relative "namespace" +require_relative 'entity' +require_relative 'attlistdecl' +require_relative 'xmltokens' + +module REXML + class ReferenceWriter + def initialize(id_type, + public_id_literal, + system_literal, + context=nil) + @id_type = id_type + @public_id_literal = public_id_literal + @system_literal = system_literal + if context and context[:prologue_quote] == :apostrophe + @default_quote = "'" + else + @default_quote = "\"" + end + end + + def write(output) + output << " #{@id_type}" + if @public_id_literal + if @public_id_literal.include?("'") + quote = "\"" + else + quote = @default_quote + end + output << " #{quote}#{@public_id_literal}#{quote}" + end + if @system_literal + if @system_literal.include?("'") + quote = "\"" + elsif @system_literal.include?("\"") + quote = "'" + else + quote = @default_quote + end + output << " #{quote}#{@system_literal}#{quote}" + end + end + end + + # Represents an XML DOCTYPE declaration; that is, the contents of . DOCTYPES can be used to declare the DTD of a document, as well as + # being used to declare entities used in the document. + class DocType < Parent + include XMLTokens + START = "" + SYSTEM = "SYSTEM" + PUBLIC = "PUBLIC" + DEFAULT_ENTITIES = { + 'gt'=>EntityConst::GT, + 'lt'=>EntityConst::LT, + 'quot'=>EntityConst::QUOT, + "apos"=>EntityConst::APOS + } + + # name is the name of the doctype + # external_id is the referenced DTD, if given + attr_reader :name, :external_id, :entities, :namespaces + + # Constructor + # + # dt = DocType.new( 'foo', '-//I/Hate/External/IDs' ) + # # + # dt = DocType.new( doctype_to_clone ) + # # Incomplete. Shallow clone of doctype + # + # +Note+ that the constructor: + # + # Doctype.new( Source.new( "" ) ) + # + # is _deprecated_. Do not use it. It will probably disappear. + def initialize( first, parent=nil ) + @entities = DEFAULT_ENTITIES + @long_name = @uri = nil + if first.kind_of? String + super() + @name = first + @external_id = parent + elsif first.kind_of? DocType + super( parent ) + @name = first.name + @external_id = first.external_id + @long_name = first.instance_variable_get(:@long_name) + @uri = first.instance_variable_get(:@uri) + elsif first.kind_of? Array + super( parent ) + @name = first[0] + @external_id = first[1] + @long_name = first[2] + @uri = first[3] + elsif first.kind_of? Source + super( parent ) + parser = Parsers::BaseParser.new( first ) + event = parser.pull + if event[0] == :start_doctype + @name, @external_id, @long_name, @uri, = event[1..-1] + end + else + super() + end + end + + def node_type + :doctype + end + + def attributes_of element + rv = [] + each do |child| + child.each do |key,val| + rv << Attribute.new(key,val) + end if child.kind_of? AttlistDecl and child.element_name == element + end + rv + end + + def attribute_of element, attribute + att_decl = find do |child| + child.kind_of? AttlistDecl and + child.element_name == element and + child.include? attribute + end + return nil unless att_decl + att_decl[attribute] + end + + def clone + DocType.new self + end + + # output:: + # Where to write the string + # indent:: + # An integer. If -1, no indentation will be used; otherwise, the + # indentation will be this number of spaces, and children will be + # indented an additional amount. + # transitive:: + # Ignored + # ie_hack:: + # Ignored + def write( output, indent=0, transitive=false, ie_hack=false ) + f = REXML::Formatters::Default.new + indent( output, indent ) + output << START + output << ' ' + output << @name + if @external_id + reference_writer = ReferenceWriter.new(@external_id, + @long_name, + @uri, + context) + reference_writer.write(output) + end + unless @children.empty? + output << ' [' + @children.each { |child| + output << "\n" + f.write( child, output ) + } + output << "\n]" + end + output << STOP + end + + def context + @parent&.context + end + + def entity( name ) + @entities[name]&.unnormalized + end + + def add child + super(child) + @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES + @entities[ child.name ] = child if child.kind_of? Entity + end + + # This method retrieves the public identifier identifying the document's + # DTD. + # + # Method contributed by Henrik Martensson + def public + case @external_id + when "SYSTEM" + nil + when "PUBLIC" + @long_name + end + end + + # This method retrieves the system identifier identifying the document's DTD + # + # Method contributed by Henrik Martensson + def system + case @external_id + when "SYSTEM" + @long_name + when "PUBLIC" + @uri.kind_of?(String) ? @uri : nil + end + end + + # This method returns a list of notations that have been declared in the + # _internal_ DTD subset. Notations in the external DTD subset are not + # listed. + # + # Method contributed by Henrik Martensson + def notations + children().select {|node| node.kind_of?(REXML::NotationDecl)} + end + + # Retrieves a named notation. Only notations declared in the internal + # DTD subset can be retrieved. + # + # Method contributed by Henrik Martensson + def notation(name) + notations.find { |notation_decl| + notation_decl.name == name + } + end + end + + # We don't really handle any of these since we're not a validating + # parser, so we can be pretty dumb about them. All we need to be able + # to do is spew them back out on a write() + + # This is an abstract class. You never use this directly; it serves as a + # parent class for the specific declarations. + class Declaration < Child + def initialize src + super() + @string = src + end + + def to_s + @string+'>' + end + + # == DEPRECATED + # See REXML::Formatters + # + def write( output, indent ) + output << to_s + end + end + + public + class ElementDecl < Declaration + def initialize( src ) + super + end + end + + class ExternalEntity < Child + def initialize( src ) + super() + @entity = src + end + def to_s + @entity + end + def write( output, indent ) + output << @entity + end + end + + class NotationDecl < Child + attr_accessor :public, :system + def initialize name, middle, pub, sys + super(nil) + @name = name + @middle = middle + @public = pub + @system = sys + end + + def to_s + context = parent&.context + notation = "" + notation + end + + def write( output, indent=-1 ) + output << to_s + end + + # This method retrieves the name of the notation. + # + # Method contributed by Henrik Martensson + def name + @name + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/document.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/document.rb new file mode 100644 index 0000000..bd3a004 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/document.rb @@ -0,0 +1,471 @@ +# frozen_string_literal: false +require_relative "security" +require_relative "element" +require_relative "xmldecl" +require_relative "source" +require_relative "comment" +require_relative "doctype" +require_relative "instruction" +require_relative "rexml" +require_relative "parseexception" +require_relative "output" +require_relative "parsers/baseparser" +require_relative "parsers/streamparser" +require_relative "parsers/treeparser" + +module REXML + # Represents an XML document. + # + # A document may have: + # + # - A single child that may be accessed via method #root. + # - An XML declaration. + # - A document type. + # - Processing instructions. + # + # == In a Hurry? + # + # If you're somewhat familiar with XML + # and have a particular task in mind, + # you may want to see the + # {tasks pages}[../doc/rexml/tasks/tocs/master_toc_rdoc.html], + # and in particular, the + # {tasks page for documents}[../doc/rexml/tasks/tocs/document_toc_rdoc.html]. + # + class Document < Element + # A convenient default XML declaration. Use: + # + # mydoc << XMLDecl.default + # + DECLARATION = XMLDecl.default + + # :call-seq: + # new(string = nil, context = {}) -> new_document + # new(io_stream = nil, context = {}) -> new_document + # new(document = nil, context = {}) -> new_document + # + # Returns a new \REXML::Document object. + # + # When no arguments are given, + # returns an empty document: + # + # d = REXML::Document.new + # d.to_s # => "" + # + # When argument +string+ is given, it must be a string + # containing a valid XML document: + # + # xml_string = 'FooBar' + # d = REXML::Document.new(xml_string) + # d.to_s # => "FooBar" + # + # When argument +io_stream+ is given, it must be an \IO object + # that is opened for reading, and when read must return a valid XML document: + # + # File.write('t.xml', xml_string) + # d = File.open('t.xml', 'r') do |io| + # REXML::Document.new(io) + # end + # d.to_s # => "FooBar" + # + # When argument +document+ is given, it must be an existing + # document object, whose context and attributes (but not children) + # are cloned into the new document: + # + # d = REXML::Document.new(xml_string) + # d.children # => [ ... ] + # d.context = {raw: :all, compress_whitespace: :all} + # d.add_attributes({'bar' => 0, 'baz' => 1}) + # d1 = REXML::Document.new(d) + # d1.children # => [] + # d1.context # => {:raw=>:all, :compress_whitespace=>:all} + # d1.attributes # => {"bar"=>bar='0', "baz"=>baz='1'} + # + # When argument +context+ is given, it must be a hash + # containing context entries for the document; + # see {Element Context}[../doc/rexml/context_rdoc.html]: + # + # context = {raw: :all, compress_whitespace: :all} + # d = REXML::Document.new(xml_string, context) + # d.context # => {:raw=>:all, :compress_whitespace=>:all} + # + def initialize( source = nil, context = {} ) + @entity_expansion_count = 0 + @entity_expansion_limit = Security.entity_expansion_limit + @entity_expansion_text_limit = Security.entity_expansion_text_limit + super() + @context = context + # `source = ""` is an invalid usage because no root element XML is an invalid XML. + # But we accept `""` for backward compatibility. + return if source.nil? or source == "" + if source.kind_of? Document + @context = source.context + super source + else + build( source ) + end + end + + # :call-seq: + # node_type -> :document + # + # Returns the symbol +:document+. + # + def node_type + :document + end + + # :call-seq: + # clone -> new_document + # + # Returns the new document resulting from executing + # Document.new(self). See Document.new. + # + def clone + Document.new self + end + + # :call-seq: + # expanded_name -> empty_string + # + # Returns an empty string. + # + def expanded_name + '' + #d = doc_type + #d ? d.name : "UNDEFINED" + end + alias :name :expanded_name + + # :call-seq: + # add(xml_decl) -> self + # add(doc_type) -> self + # add(object) -> self + # + # Adds an object to the document; returns +self+. + # + # When argument +xml_decl+ is given, + # it must be an REXML::XMLDecl object, + # which becomes the XML declaration for the document, + # replacing the previous XML declaration if any: + # + # d = REXML::Document.new + # d.xml_decl.to_s # => "" + # d.add(REXML::XMLDecl.new('2.0')) + # d.xml_decl.to_s # => "" + # + # When argument +doc_type+ is given, + # it must be an REXML::DocType object, + # which becomes the document type for the document, + # replacing the previous document type, if any: + # + # d = REXML::Document.new + # d.doctype.to_s # => "" + # d.add(REXML::DocType.new('foo')) + # d.doctype.to_s # => "" + # + # When argument +object+ (not an REXML::XMLDecl or REXML::DocType object) + # is given it is added as the last child: + # + # d = REXML::Document.new + # d.add(REXML::Element.new('foo')) + # d.to_s # => "" + # + def add( child ) + if child.kind_of? XMLDecl + if @children[0].kind_of? XMLDecl + @children[0] = child + else + @children.unshift child + end + child.parent = self + elsif child.kind_of? DocType + # Find first Element or DocType node and insert the decl right + # before it. If there is no such node, just insert the child at the + # end. If there is a child and it is an DocType, then replace it. + insert_before_index = @children.find_index { |x| + x.kind_of?(Element) || x.kind_of?(DocType) + } + if insert_before_index # Not null = not end of list + if @children[ insert_before_index ].kind_of? DocType + @children[ insert_before_index ] = child + else + @children[ insert_before_index-1, 0 ] = child + end + else # Insert at end of list + @children << child + end + child.parent = self + else + rv = super + raise "attempted adding second root element to document" if @elements.size > 1 + rv + end + end + alias :<< :add + + # :call-seq: + # add_element(name_or_element = nil, attributes = nil) -> new_element + # + # Adds an element to the document by calling REXML::Element.add_element: + # + # REXML::Element.add_element(name_or_element, attributes) + def add_element(arg=nil, arg2=nil) + rv = super + raise "attempted adding second root element to document" if @elements.size > 1 + rv + end + + # :call-seq: + # root -> root_element or nil + # + # Returns the root element of the document, if it exists, otherwise +nil+: + # + # d = REXML::Document.new('') + # d.root # => + # d = REXML::Document.new('') + # d.root # => nil + # + def root + elements[1] + #self + #@children.find { |item| item.kind_of? Element } + end + + # :call-seq: + # doctype -> doc_type or nil + # + # Returns the DocType object for the document, if it exists, otherwise +nil+: + # + # d = REXML::Document.new('') + # d.doctype.class # => REXML::DocType + # d = REXML::Document.new('') + # d.doctype.class # => nil + # + def doctype + @children.find { |item| item.kind_of? DocType } + end + + # :call-seq: + # xml_decl -> xml_decl + # + # Returns the XMLDecl object for the document, if it exists, + # otherwise the default XMLDecl object: + # + # d = REXML::Document.new('') + # d.xml_decl.class # => REXML::XMLDecl + # d.xml_decl.to_s # => "" + # d = REXML::Document.new('') + # d.xml_decl.class # => REXML::XMLDecl + # d.xml_decl.to_s # => "" + # + def xml_decl + rv = @children[0] + return rv if rv.kind_of? XMLDecl + @children.unshift(XMLDecl.default)[0] + end + + # :call-seq: + # version -> version_string + # + # Returns the XMLDecl version of this document as a string, + # if it has been set, otherwise the default version: + # + # d = REXML::Document.new('') + # d.version # => "2.0" + # d = REXML::Document.new('') + # d.version # => "1.0" + # + def version + xml_decl().version + end + + # :call-seq: + # encoding -> encoding_string + # + # Returns the XMLDecl encoding of the document, + # if it has been set, otherwise the default encoding: + # + # d = REXML::Document.new('') + # d.encoding # => "UTF-16" + # d = REXML::Document.new('') + # d.encoding # => "UTF-8" + # + def encoding + xml_decl().encoding + end + + # :call-seq: + # stand_alone? + # + # Returns the XMLDecl standalone value of the document as a string, + # if it has been set, otherwise the default standalone value: + # + # d = REXML::Document.new('') + # d.stand_alone? # => "yes" + # d = REXML::Document.new('') + # d.stand_alone? # => nil + # + def stand_alone? + xml_decl().stand_alone? + end + + # :call-seq: + # doc.write(output=$stdout, indent=-1, transitive=false, ie_hack=false, encoding=nil) + # doc.write(options={:output => $stdout, :indent => -1, :transitive => false, :ie_hack => false, :encoding => nil}) + # + # Write the XML tree out, optionally with indent. This writes out the + # entire XML document, including XML declarations, doctype declarations, + # and processing instructions (if any are given). + # + # A controversial point is whether Document should always write the XML + # declaration () whether or not one is given by the + # user (or source document). REXML does not write one if one was not + # specified, because it adds unnecessary bandwidth to applications such + # as XML-RPC. + # + # Accept Nth argument style and options Hash style as argument. + # The recommended style is options Hash style for one or more + # arguments case. + # + # _Examples_ + # Document.new("").write + # + # output = "" + # Document.new("").write(output) + # + # output = "" + # Document.new("").write(:output => output, :indent => 2) + # + # See also the classes in the rexml/formatters package for the proper way + # to change the default formatting of XML output. + # + # _Examples_ + # + # output = "" + # tr = Transitive.new + # tr.write(Document.new(""), output) + # + # output:: + # output an object which supports '<< string'; this is where the + # document will be written. + # indent:: + # An integer. If -1, no indenting will be used; otherwise, the + # indentation will be twice this number of spaces, and children will be + # indented an additional amount. For a value of 3, every item will be + # indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1 + # transitive:: + # If transitive is true and indent is >= 0, then the output will be + # pretty-printed in such a way that the added whitespace does not affect + # the absolute *value* of the document -- that is, it leaves the value + # and number of Text nodes in the document unchanged. + # ie_hack:: + # This hack inserts a space before the /> on empty tags to address + # a limitation of Internet Explorer. Defaults to false + # encoding:: + # Encoding name as String. Change output encoding to specified encoding + # instead of encoding in XML declaration. + # Defaults to nil. It means encoding in XML declaration is used. + def write(*arguments) + if arguments.size == 1 and arguments[0].class == Hash + options = arguments[0] + + output = options[:output] + indent = options[:indent] + transitive = options[:transitive] + ie_hack = options[:ie_hack] + encoding = options[:encoding] + else + output, indent, transitive, ie_hack, encoding, = *arguments + end + + output ||= $stdout + indent ||= -1 + transitive = false if transitive.nil? + ie_hack = false if ie_hack.nil? + encoding ||= xml_decl.encoding + + if encoding != 'UTF-8' && !output.kind_of?(Output) + output = Output.new( output, encoding ) + end + formatter = if indent > -1 + if transitive + require_relative "formatters/transitive" + REXML::Formatters::Transitive.new( indent, ie_hack ) + else + REXML::Formatters::Pretty.new( indent, ie_hack ) + end + else + REXML::Formatters::Default.new( ie_hack ) + end + formatter.write( self, output ) + end + + + def Document::parse_stream( source, listener ) + Parsers::StreamParser.new( source, listener ).parse + end + + # Set the entity expansion limit. By default the limit is set to 10000. + # + # Deprecated. Use REXML::Security.entity_expansion_limit= instead. + def Document::entity_expansion_limit=( val ) + Security.entity_expansion_limit = val + end + + # Get the entity expansion limit. By default the limit is set to 10000. + # + # Deprecated. Use REXML::Security.entity_expansion_limit= instead. + def Document::entity_expansion_limit + Security.entity_expansion_limit + end + + # Set the entity expansion limit. By default the limit is set to 10240. + # + # Deprecated. Use REXML::Security.entity_expansion_text_limit= instead. + def Document::entity_expansion_text_limit=( val ) + Security.entity_expansion_text_limit = val + end + + # Get the entity expansion limit. By default the limit is set to 10240. + # + # Deprecated. Use REXML::Security.entity_expansion_text_limit instead. + def Document::entity_expansion_text_limit + Security.entity_expansion_text_limit + end + + attr_reader :entity_expansion_count + attr_writer :entity_expansion_limit + attr_accessor :entity_expansion_text_limit + + def record_entity_expansion + @entity_expansion_count += 1 + if @entity_expansion_count > @entity_expansion_limit + raise "number of entity expansions exceeded, processing aborted." + end + end + + def document + self + end + + private + + attr_accessor :namespaces_cache + + # New document level cache is created and available in this block. + # This API is thread unsafe. Users can't change this document in this block. + def enable_cache + @namespaces_cache = {} + begin + yield + ensure + @namespaces_cache = nil + end + end + + def build( source ) + Parsers::TreeParser.new( source, self ).parse + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/attlistdecl.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/attlistdecl.rb new file mode 100644 index 0000000..1326cb2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/attlistdecl.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: false +require_relative "../child" +module REXML + module DTD + class AttlistDecl < Child + START = ")/um + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/dtd.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/dtd.rb new file mode 100644 index 0000000..8b0f2d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/dtd.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: false +require_relative "elementdecl" +require_relative "entitydecl" +require_relative "../comment" +require_relative "notationdecl" +require_relative "attlistdecl" +require_relative "../parent" + +module REXML + module DTD + class Parser + def Parser.parse( input ) + case input + when String + parse_helper input + when File + parse_helper input.read + end + end + + # Takes a String and parses it out + def Parser.parse_helper( input ) + contents = Parent.new + while input.size > 0 + case input + when ElementDecl.PATTERN_RE + match = $& + contents << ElementDecl.new( match ) + when AttlistDecl.PATTERN_RE + matchdata = $~ + contents << AttlistDecl.new( matchdata ) + when EntityDecl.PATTERN_RE + matchdata = $~ + contents << EntityDecl.new( matchdata ) + when Comment.PATTERN_RE + matchdata = $~ + contents << Comment.new( matchdata ) + when NotationDecl.PATTERN_RE + matchdata = $~ + contents << NotationDecl.new( matchdata ) + end + end + contents + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/elementdecl.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/elementdecl.rb new file mode 100644 index 0000000..20ed023 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/elementdecl.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: false +require_relative "../child" +module REXML + module DTD + class ElementDecl < Child + START = "/um + PATTERN_RE = /^\s*#{START}\s+((?:[:\w][-\.\w]*:)?[-!\*\.\w]*)(.*?)>/ + #\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true) + + def initialize match + @name = match[1] + @rest = match[2] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/entitydecl.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/entitydecl.rb new file mode 100644 index 0000000..312df65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/entitydecl.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: false +require_relative "../child" +module REXML + module DTD + class EntityDecl < Child + START = "/um + SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um + PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um + PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um + # + # + def initialize src + super() + md = nil + if src.match( PUBLIC ) + md = src.match( PUBLIC, true ) + @middle = "PUBLIC" + @content = "#{md[2]} #{md[4]}" + elsif src.match( SYSTEM ) + md = src.match( SYSTEM, true ) + @middle = "SYSTEM" + @content = md[2] + elsif src.match( PLAIN ) + md = src.match( PLAIN, true ) + @middle = "" + @content = md[2] + elsif src.match( PERCENT ) + md = src.match( PERCENT, true ) + @middle = "" + @content = md[2] + end + raise ParseException.new("failed Entity match", src) if md.nil? + @name = md[1] + end + + def to_s + rv = " 0 + rv << @content + rv + end + + def write( output, indent ) + indent( output, indent ) + output << to_s + end + + def EntityDecl.parse_source source, listener + md = source.match( PATTERN_RE, true ) + thing = md[0].squeeze(" \t\n\r") + listener.send inspect.downcase, thing + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/notationdecl.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/notationdecl.rb new file mode 100644 index 0000000..04a9b08 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/dtd/notationdecl.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: false +require_relative "../child" +module REXML + module DTD + class NotationDecl < Child + START = "/um + SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um + def initialize src + super() + if src.match( PUBLIC ) + md = src.match( PUBLIC, true ) + elsif src.match( SYSTEM ) + md = src.match( SYSTEM, true ) + else + raise ParseException.new( "error parsing notation: no matching pattern", src ) + end + @name = md[1] + @middle = md[2] + @rest = md[3] + end + + def to_s + "" + end + + def write( output, indent ) + indent( output, indent ) + output << to_s + end + + def NotationDecl.parse_source source, listener + md = source.match( PATTERN_RE, true ) + thing = md[0].squeeze(" \t\n\r") + listener.send inspect.downcase, thing + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/element.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/element.rb new file mode 100644 index 0000000..0d74811 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/element.rb @@ -0,0 +1,2578 @@ +# frozen_string_literal: false +require_relative "parent" +require_relative "namespace" +require_relative "attribute" +require_relative "cdata" +require_relative "xpath" +require_relative "parseexception" + +module REXML + # An \REXML::Element object represents an XML element. + # + # An element: + # + # - Has a name (string). + # - May have a parent (another element). + # - Has zero or more children + # (other elements, text, CDATA, processing instructions, and comments). + # - Has zero or more siblings + # (other elements, text, CDATA, processing instructions, and comments). + # - Has zero or more named attributes. + # + # == In a Hurry? + # + # If you're somewhat familiar with XML + # and have a particular task in mind, + # you may want to see the + # {tasks pages}[../doc/rexml/tasks/tocs/master_toc_rdoc.html], + # and in particular, the + # {tasks page for elements}[../doc/rexml/tasks/tocs/element_toc_rdoc.html]. + # + # === Name + # + # An element has a name, which is initially set when the element is created: + # + # e = REXML::Element.new('foo') + # e.name # => "foo" + # + # The name may be changed: + # + # e.name = 'bar' + # e.name # => "bar" + # + # + # === \Parent + # + # An element may have a parent. + # + # Its parent may be assigned explicitly when the element is created: + # + # e0 = REXML::Element.new('foo') + # e1 = REXML::Element.new('bar', e0) + # e1.parent # => ... + # + # Note: the representation of an element always shows the element's name. + # If the element has children, the representation indicates that + # by including an ellipsis (...). + # + # The parent may be assigned explicitly at any time: + # + # e2 = REXML::Element.new('baz') + # e1.parent = e2 + # e1.parent # => + # + # When an element is added as a child, its parent is set automatically: + # + # e1.add_element(e0) + # e0.parent # => ... + # + # For an element that has no parent, method +parent+ returns +nil+. + # + # === Children + # + # An element has zero or more children. + # The children are an ordered collection + # of all objects whose parent is the element itself. + # + # The children may include any combination of elements, text, comments, + # processing instructions, and CDATA. + # (This example keeps things clean by controlling whitespace + # via a +context+ setting.) + # + # xml_string = <<-EOT + # + # + # text 0 + # + # + # + # + # text 1 + # + # + # + # + # EOT + # context = {ignore_whitespace_nodes: :all, compress_whitespace: :all} + # d = REXML::Document.new(xml_string, context) + # root = d.root + # root.children.size # => 10 + # root.each {|child| p "#{child.class}: #{child}" } + # + # Output: + # + # "REXML::Element: " + # "REXML::Text: \n text 0\n " + # "REXML::Comment: comment 0" + # "REXML::Instruction: " + # "REXML::CData: cdata 0" + # "REXML::Element: " + # "REXML::Text: \n text 1\n " + # "REXML::Comment: comment 1" + # "REXML::Instruction: " + # "REXML::CData: cdata 1" + # + # A child may be added using inherited methods + # Parent#insert_before or Parent#insert_after: + # + # xml_string = '' + # d = REXML::Document.new(xml_string) + # root = d.root + # c = d.root[1] # => + # root.insert_before(c, REXML::Element.new('b')) + # root.to_a # => [, , , ] + # + # A child may be replaced using Parent#replace_child: + # + # root.replace_child(c, REXML::Element.new('x')) + # root.to_a # => [, , , ] + # + # A child may be removed using Parent#delete: + # + # x = root[2] # => + # root.delete(x) + # root.to_a # => [, , ] + # + # === Siblings + # + # An element has zero or more siblings, + # which are the other children of the element's parent. + # + # In the example above, element +ele_1+ is between a CDATA sibling + # and a text sibling: + # + # ele_1 = root[5] # => + # ele_1.previous_sibling # => "cdata 0" + # ele_1.next_sibling # => "\n text 1\n " + # + # === \Attributes + # + # An element has zero or more named attributes. + # + # A new element has no attributes: + # + # e = REXML::Element.new('foo') + # e.attributes # => {} + # + # Attributes may be added: + # + # e.add_attribute('bar', 'baz') + # e.add_attribute('bat', 'bam') + # e.attributes.size # => 2 + # e['bar'] # => "baz" + # e['bat'] # => "bam" + # + # An existing attribute may be modified: + # + # e.add_attribute('bar', 'bad') + # e.attributes.size # => 2 + # e['bar'] # => "bad" + # + # An existing attribute may be deleted: + # + # e.delete_attribute('bar') + # e.attributes.size # => 1 + # e['bar'] # => nil + # + # == What's Here + # + # To begin with, what's elsewhere? + # + # \Class \REXML::Element inherits from its ancestor classes: + # + # - REXML::Child + # - REXML::Parent + # + # \REXML::Element itself and its ancestors also include modules: + # + # - {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html] + # - REXML::Namespace + # - REXML::Node + # - REXML::XMLTokens + # + # === Methods for Creating an \Element + # + # ::new:: Returns a new empty element. + # #clone:: Returns a clone of another element. + # + # === Methods for Attributes + # + # {[attribute_name]}[#method-i-5B-5D]:: Returns an attribute value. + # #add_attribute:: Adds a new attribute. + # #add_attributes:: Adds multiple new attributes. + # #attribute:: Returns the attribute value for a given name and optional namespace. + # #delete_attribute:: Removes an attribute. + # + # === Methods for Children + # + # {[index]}[#method-i-5B-5D]:: Returns the child at the given offset. + # #add_element:: Adds an element as the last child. + # #delete_element:: Deletes a child element. + # #each_element:: Calls the given block with each child element. + # #each_element_with_attribute:: Calls the given block with each child element + # that meets given criteria, + # which can include the attribute name. + # #each_element_with_text:: Calls the given block with each child element + # that meets given criteria, + # which can include text. + # #get_elements:: Returns an array of element children that match a given xpath. + # + # === Methods for \Text Children + # + # #add_text:: Adds a text node to the element. + # #get_text:: Returns a text node that meets specified criteria. + # #text:: Returns the text string from the first node that meets specified criteria. + # #texts:: Returns an array of the text children of the element. + # #text=:: Adds, removes, or replaces the first text child of the element + # + # === Methods for Other Children + # + # #cdatas:: Returns an array of the cdata children of the element. + # #comments:: Returns an array of the comment children of the element. + # #instructions:: Returns an array of the instruction children of the element. + # + # === Methods for Namespaces + # + # #add_namespace:: Adds a namespace to the element. + # #delete_namespace:: Removes a namespace from the element. + # #namespace:: Returns the string namespace URI for the element. + # #namespaces:: Returns a hash of all defined namespaces in the element. + # #prefixes:: Returns an array of the string prefixes (names) + # of all defined namespaces in the element + # + # === Methods for Querying + # + # #document:: Returns the document, if any, that the element belongs to. + # #root:: Returns the most distant element (not document) ancestor of the element. + # #root_node:: Returns the most distant ancestor of the element. + # #xpath:: Returns the string xpath to the element + # relative to the most distant parent + # #has_attributes?:: Returns whether the element has attributes. + # #has_elements?:: Returns whether the element has elements. + # #has_text?:: Returns whether the element has text. + # #next_element:: Returns the next sibling that is an element. + # #previous_element:: Returns the previous sibling that is an element. + # #raw:: Returns whether raw mode is set for the element. + # #whitespace:: Returns whether whitespace is respected for the element. + # #ignore_whitespace_nodes:: Returns whether whitespace nodes + # are to be ignored for the element. + # #node_type:: Returns symbol :element. + # + # === One More Method + # + # #inspect:: Returns a string representation of the element. + # + # === Accessors + # + # #elements:: Returns the REXML::Elements object for the element. + # #attributes:: Returns the REXML::Attributes object for the element. + # #context:: Returns or sets the context hash for the element. + # + class Element < Parent + include Namespace + + UNDEFINED = "UNDEFINED"; # The default name + + # Mechanisms for accessing attributes and child elements of this + # element. + attr_reader :attributes, :elements + # The context holds information about the processing environment, such as + # whitespace handling. + attr_accessor :context + + # :call-seq: + # Element.new(name = 'UNDEFINED', parent = nil, context = nil) -> new_element + # Element.new(element, parent = nil, context = nil) -> new_element + # + # Returns a new \REXML::Element object. + # + # When no arguments are given, + # returns an element with name 'UNDEFINED': + # + # e = REXML::Element.new # => + # e.class # => REXML::Element + # e.name # => "UNDEFINED" + # + # When only argument +name+ is given, + # returns an element of the given name: + # + # REXML::Element.new('foo') # => + # + # When only argument +element+ is given, it must be an \REXML::Element object; + # returns a shallow copy of the given element: + # + # e0 = REXML::Element.new('foo') + # e1 = REXML::Element.new(e0) # => + # + # When argument +parent+ is also given, it must be an REXML::Parent object: + # + # e = REXML::Element.new('foo', REXML::Parent.new) + # e.parent # => #]> + # + # When argument +context+ is also given, it must be a hash + # representing the context for the element; + # see {Element Context}[../doc/rexml/context_rdoc.html]: + # + # e = REXML::Element.new('foo', nil, {raw: :all}) + # e.context # => {:raw=>:all} + # + def initialize( arg = UNDEFINED, parent=nil, context=nil ) + super(parent) + + @elements = Elements.new(self) + @attributes = Attributes.new(self) + @context = context + + if arg.kind_of? String + self.name = arg + elsif arg.kind_of? Element + self.name = arg.expanded_name + arg.attributes.each_attribute{ |attribute| + @attributes << Attribute.new( attribute ) + } + @context = arg.context + end + end + + # :call-seq: + # inspect -> string + # + # Returns a string representation of the element. + # + # For an element with no attributes and no children, shows the element name: + # + # REXML::Element.new.inspect # => "" + # + # Shows attributes, if any: + # + # e = REXML::Element.new('foo') + # e.add_attributes({'bar' => 0, 'baz' => 1}) + # e.inspect # => "" + # + # Shows an ellipsis (...), if there are child elements: + # + # e.add_element(REXML::Element.new('bar')) + # e.add_element(REXML::Element.new('baz')) + # e.inspect # => " ... " + # + def inspect + rv = "<#@expanded_name" + + @attributes.each_attribute do |attr| + rv << " " + attr.write( rv, 0 ) + end + + if children.size > 0 + rv << "> ... " + else + rv << "/>" + end + end + + # :call-seq: + # clone -> new_element + # + # Returns a shallow copy of the element, containing the name and attributes, + # but not the parent or children: + # + # e = REXML::Element.new('foo') + # e.add_attributes({'bar' => 0, 'baz' => 1}) + # e.clone # => + # + def clone + self.class.new self + end + + # :call-seq: + # root_node -> document or element + # + # Returns the most distant ancestor of +self+. + # + # When the element is part of a document, + # returns the root node of the document. + # Note that the root node is different from the document element; + # in this example +a+ is document element and the root node is its parent: + # + # d = REXML::Document.new('') + # top_element = d.first # => ... + # child = top_element.first # => ... + # d.root_node == d # => true + # top_element.root_node == d # => true + # child.root_node == d # => true + # + # When the element is not part of a document, but does have ancestor elements, + # returns the most distant ancestor element: + # + # e0 = REXML::Element.new('foo') + # e1 = REXML::Element.new('bar') + # e1.parent = e0 + # e2 = REXML::Element.new('baz') + # e2.parent = e1 + # e2.root_node == e0 # => true + # + # When the element has no ancestor elements, + # returns +self+: + # + # e = REXML::Element.new('foo') + # e.root_node == e # => true + # + # Related: #root, #document. + # + def root_node + parent.nil? ? self : parent.root_node + end + + # :call-seq: + # root -> element + # + # Returns the most distant _element_ (not document) ancestor of the element: + # + # d = REXML::Document.new('') + # top_element = d.first + # child = top_element.first + # top_element.root == top_element # => true + # child.root == top_element # => true + # + # For a document, returns the topmost element: + # + # d.root == top_element # => true + # + # Related: #root_node, #document. + # + def root + target = self + while target + return target.elements[1] if target.kind_of? Document + parent = target.parent + return target if parent.kind_of? Document or parent.nil? + target = parent + end + nil + end + + # :call-seq: + # document -> document or nil + # + # If the element is part of a document, returns that document: + # + # d = REXML::Document.new('') + # top_element = d.first + # child = top_element.first + # top_element.document == d # => true + # child.document == d # => true + # + # If the element is not part of a document, returns +nil+: + # + # REXML::Element.new.document # => nil + # + # For a document, returns +self+: + # + # d.document == d # => true + # + # Related: #root, #root_node. + # + def document + root&.parent + end + + # :call-seq: + # whitespace + # + # Returns +true+ if whitespace is respected for this element, + # +false+ otherwise. + # + # See {Element Context}[../doc/rexml/context_rdoc.html]. + # + # The evaluation is tested against the element's +expanded_name+, + # and so is namespace-sensitive. + def whitespace + @whitespace = nil + if @context + if @context[:respect_whitespace] + @whitespace = (@context[:respect_whitespace] == :all or + @context[:respect_whitespace].include? expanded_name) + end + @whitespace = false if (@context[:compress_whitespace] and + (@context[:compress_whitespace] == :all or + @context[:compress_whitespace].include? expanded_name) + ) + end + @whitespace = true unless @whitespace == false + @whitespace + end + + # :call-seq: + # ignore_whitespace_nodes + # + # Returns +true+ if whitespace nodes are ignored for the element. + # + # See {Element Context}[../doc/rexml/context_rdoc.html]. + # + def ignore_whitespace_nodes + @ignore_whitespace_nodes = false + if @context + if @context[:ignore_whitespace_nodes] + @ignore_whitespace_nodes = + (@context[:ignore_whitespace_nodes] == :all or + @context[:ignore_whitespace_nodes].include? expanded_name) + end + end + end + + # :call-seq: + # raw + # + # Returns +true+ if raw mode is set for the element. + # + # See {Element Context}[../doc/rexml/context_rdoc.html]. + # + # The evaluation is tested against +expanded_name+, and so is namespace + # sensitive. + def raw + @raw = (@context and @context[:raw] and + (@context[:raw] == :all or + @context[:raw].include? expanded_name)) + @raw + end + + #once :whitespace, :raw, :ignore_whitespace_nodes + + ################################################# + # Namespaces # + ################################################# + + # :call-seq: + # prefixes -> array_of_namespace_prefixes + # + # Returns an array of the string prefixes (names) of all defined namespaces + # in the element and its ancestors: + # + # xml_string = <<-EOT + # + # + # + # + # + # + # EOT + # d = REXML::Document.new(xml_string, {compress_whitespace: :all}) + # d.elements['//a'].prefixes # => ["x", "y"] + # d.elements['//b'].prefixes # => ["x", "y"] + # d.elements['//c'].prefixes # => ["x", "y", "z"] + # + def prefixes + prefixes = [] + prefixes = parent.prefixes if parent + prefixes |= attributes.prefixes + prefixes + end + + # :call-seq: + # namespaces -> array_of_namespace_names + # + # Returns a hash of all defined namespaces + # in the element and its ancestors: + # + # xml_string = <<-EOT + # + # + # + # + # + # + # EOT + # d = REXML::Document.new(xml_string) + # d.elements['//a'].namespaces # => {"x"=>"1", "y"=>"2"} + # d.elements['//b'].namespaces # => {"x"=>"1", "y"=>"2"} + # d.elements['//c'].namespaces # => {"x"=>"1", "y"=>"2", "z"=>"3"} + # + def namespaces + namespaces_cache = document&.__send__(:namespaces_cache) + if namespaces_cache + namespaces_cache[self] ||= calculate_namespaces + else + calculate_namespaces + end + end + + # :call-seq: + # namespace(prefix = nil) -> string_uri or nil + # + # Returns the string namespace URI for the element, + # possibly deriving from one of its ancestors. + # + # xml_string = <<-EOT + # + # + # + # + # + # + # EOT + # d = REXML::Document.new(xml_string) + # b = d.elements['//b'] + # b.namespace # => "1" + # b.namespace('y') # => "2" + # b.namespace('nosuch') # => nil + # + def namespace(prefix=nil) + if prefix.nil? + prefix = prefix() + end + prefix = (prefix == '') ? 'xmlns' : prefix.delete_prefix("xmlns:") + ns = namespaces[prefix] + + ns = '' if ns.nil? and prefix == 'xmlns' + ns + end + + # :call-seq: + # add_namespace(prefix, uri = nil) -> self + # + # Adds a namespace to the element; returns +self+. + # + # With the single argument +prefix+, + # adds a namespace using the given +prefix+ and the namespace URI: + # + # e = REXML::Element.new('foo') + # e.add_namespace('bar') + # e.namespaces # => {"xmlns"=>"bar"} + # + # With both arguments +prefix+ and +uri+ given, + # adds a namespace using both arguments: + # + # e.add_namespace('baz', 'bat') + # e.namespaces # => {"xmlns"=>"bar", "baz"=>"bat"} + # + def add_namespace( prefix, uri=nil ) + unless uri + @attributes["xmlns"] = prefix + else + prefix = "xmlns:#{prefix}" unless prefix =~ /^xmlns:/ + @attributes[ prefix ] = uri + end + self + end + + # :call-seq: + # delete_namespace(namespace = 'xmlns') -> self + # + # Removes a namespace from the element. + # + # With no argument, removes the default namespace: + # + # d = REXML::Document.new "" + # d.to_s # => "" + # d.root.delete_namespace # => + # d.to_s # => "" + # + # With argument +namespace+, removes the specified namespace: + # + # d.root.delete_namespace('foo') + # d.to_s # => "" + # + # Does nothing if no such namespace is found: + # + # d.root.delete_namespace('nosuch') + # d.to_s # => "" + # + def delete_namespace namespace="xmlns" + namespace = "xmlns:#{namespace}" unless namespace == 'xmlns' + attribute = attributes.get_attribute(namespace) + attribute.remove unless attribute.nil? + self + end + + ################################################# + # Elements # + ################################################# + + # :call-seq: + # add_element(name, attributes = nil) -> new_element + # add_element(element, attributes = nil) -> element + # + # Adds a child element, optionally setting attributes + # on the added element; returns the added element. + # + # With string argument +name+, creates a new element with that name + # and adds the new element as a child: + # + # e0 = REXML::Element.new('foo') + # e0.add_element('bar') + # e0[0] # => + # + # + # With argument +name+ and hash argument +attributes+, + # sets attributes on the new element: + # + # e0.add_element('baz', {'bat' => '0', 'bam' => '1'}) + # e0[1] # => + # + # With element argument +element+, adds that element as a child: + # + # e0 = REXML::Element.new('foo') + # e1 = REXML::Element.new('bar') + # e0.add_element(e1) + # e0[0] # => + # + # With argument +element+ and hash argument +attributes+, + # sets attributes on the added element: + # + # e0.add_element(e1, {'bat' => '0', 'bam' => '1'}) + # e0[1] # => + # + def add_element element, attrs=nil + raise "First argument must be either an element name, or an Element object" if element.nil? + el = @elements.add(element) + attrs.each do |key, value| + el.attributes[key]=value + end if attrs.kind_of? Hash + el + end + + # :call-seq: + # delete_element(index) -> removed_element or nil + # delete_element(element) -> removed_element or nil + # delete_element(xpath) -> removed_element or nil + # + # Deletes a child element. + # + # When 1-based integer argument +index+ is given, + # removes and returns the child element at that offset if it exists; + # indexing does not include text nodes; + # returns +nil+ if the element does not exist: + # + # d = REXML::Document.new 'text' + # a = d.root # => ... + # a.delete_element(1) # => + # a.delete_element(1) # => + # a.delete_element(1) # => nil + # + # When element argument +element+ is given, + # removes and returns that child element if it exists, + # otherwise returns +nil+: + # + # d = REXML::Document.new 'text' + # a = d.root # => ... + # c = a[2] # => + # a.delete_element(c) # => + # a.delete_element(c) # => nil + # + # When xpath argument +xpath+ is given, + # removes and returns the element at xpath if it exists, + # otherwise returns +nil+: + # + # d = REXML::Document.new 'text' + # a = d.root # => ... + # a.delete_element('//c') # => + # a.delete_element('//c') # => nil + # + def delete_element element + @elements.delete element + end + + # :call-seq: + # has_elements? + # + # Returns +true+ if the element has one or more element children, + # +false+ otherwise: + # + # d = REXML::Document.new 'text' + # a = d.root # => ... + # a.has_elements? # => true + # b = a[0] # => + # b.has_elements? # => false + # + def has_elements? + !@elements.empty? + end + + # :call-seq: + # each_element_with_attribute(attr_name, value = nil, max = 0, xpath = nil) {|e| ... } + # + # Calls the given block with each child element that meets given criteria. + # + # When only string argument +attr_name+ is given, + # calls the block with each child element that has that attribute: + # + # d = REXML::Document.new '' + # a = d.root + # a.each_element_with_attribute('id') {|e| p e } + # + # Output: + # + # + # + # + # + # With argument +attr_name+ and string argument +value+ given, + # calls the block with each child element that has that attribute + # with that value: + # + # a.each_element_with_attribute('id', '1') {|e| p e } + # + # Output: + # + # + # + # + # With arguments +attr_name+, +value+, and integer argument +max+ given, + # calls the block with at most +max+ child elements: + # + # a.each_element_with_attribute('id', '1', 1) {|e| p e } + # + # Output: + # + # + # + # With all arguments given, including +xpath+, + # calls the block with only those child elements + # that meet the first three criteria, + # and also match the given +xpath+: + # + # a.each_element_with_attribute('id', '1', 2, '//d') {|e| p e } + # + # Output: + # + # + # + def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element + each_with_something( proc {|child| + if value.nil? + child.attributes[key] != nil + else + child.attributes[key]==value + end + }, max, name, &block ) + end + + # :call-seq: + # each_element_with_text(text = nil, max = 0, xpath = nil) {|e| ... } + # + # Calls the given block with each child element that meets given criteria. + # + # With no arguments, calls the block with each child element that has text: + # + # d = REXML::Document.new 'bbd' + # a = d.root + # a.each_element_with_text {|e| p e } + # + # Output: + # + # ... + # ... + # ... + # + # With the single string argument +text+, + # calls the block with each element that has exactly that text: + # + # a.each_element_with_text('b') {|e| p e } + # + # Output: + # + # ... + # ... + # + # With argument +text+ and integer argument +max+, + # calls the block with at most +max+ elements: + # + # a.each_element_with_text('b', 1) {|e| p e } + # + # Output: + # + # ... + # + # With all arguments given, including +xpath+, + # calls the block with only those child elements + # that meet the first two criteria, + # and also match the given +xpath+: + # + # a.each_element_with_text('b', 2, '//c') {|e| p e } + # + # Output: + # + # ... + # + def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element + each_with_something( proc {|child| + if text.nil? + child.has_text? + else + child.text == text + end + }, max, name, &block ) + end + + # :call-seq: + # each_element {|e| ... } + # + # Calls the given block with each child element: + # + # d = REXML::Document.new 'bbd' + # a = d.root + # a.each_element {|e| p e } + # + # Output: + # + # ... + # ... + # ... + # + # + def each_element( xpath=nil, &block ) # :yields: Element + @elements.each( xpath, &block ) + end + + # :call-seq: + # get_elements(xpath) + # + # Returns an array of the elements that match the given +xpath+: + # + # xml_string = <<-EOT + # + # + # + # + # + # EOT + # d = REXML::Document.new(xml_string) + # d.root.get_elements('//a') # => [ ... , ] + # + def get_elements( xpath ) + @elements.to_a( xpath ) + end + + # :call-seq: + # next_element + # + # Returns the next sibling that is an element if it exists, + # +niL+ otherwise: + # + # d = REXML::Document.new 'text' + # d.root.elements['b'].next_element #-> + # d.root.elements['c'].next_element #-> nil + # + def next_element + element = next_sibling + element = element.next_sibling until element.nil? or element.kind_of? Element + element + end + + # :call-seq: + # previous_element + # + # Returns the previous sibling that is an element if it exists, + # +niL+ otherwise: + # + # d = REXML::Document.new 'text' + # d.root.elements['c'].previous_element #-> + # d.root.elements['b'].previous_element #-> nil + # + def previous_element + element = previous_sibling + element = element.previous_sibling until element.nil? or element.kind_of? Element + element + end + + + ################################################# + # Text # + ################################################# + + # :call-seq: + # has_text? -> true or false + # + # Returns +true+ if the element has one or more text noded, + # +false+ otherwise: + # + # d = REXML::Document.new 'text' + # a = d.root + # a.has_text? # => true + # b = a[0] + # b.has_text? # => false + # + def has_text? + not text().nil? + end + + # :call-seq: + # text(xpath = nil) -> text_string or nil + # + # Returns the text string from the first text node child + # in a specified element, if it exists, +nil+ otherwise. + # + # With no argument, returns the text from the first text node in +self+: + # + # d = REXML::Document.new "

some text this is bold! more text

" + # d.root.text.class # => String + # d.root.text # => "some text " + # + # With argument +xpath+, returns text from the first text node + # in the element that matches +xpath+: + # + # d.root.text(1) # => "this is bold!" + # + # Note that an element may have multiple text nodes, + # possibly separated by other non-text children, as above. + # Even so, the returned value is the string text from the first such node. + # + # Note also that the text note is retrieved by method get_text, + # and so is always normalized text. + # + def text( path = nil ) + rv = get_text(path) + rv&.value + end + + # :call-seq: + # get_text(xpath = nil) -> text_node or nil + # + # Returns the first text node child in a specified element, if it exists, + # +nil+ otherwise. + # + # With no argument, returns the first text node from +self+: + # + # d = REXML::Document.new "

some text this is bold! more text

" + # d.root.get_text.class # => REXML::Text + # d.root.get_text # => "some text " + # + # With argument +xpath+, returns the first text node from the element + # that matches +xpath+: + # + # d.root.get_text(1) # => "this is bold!" + # + def get_text path = nil + rv = nil + if path + element = @elements[ path ] + rv = element.get_text unless element.nil? + else + rv = @children.find { |node| node.kind_of? Text } + end + rv + end + + # :call-seq: + # text = string -> string + # text = nil -> nil + # + # Adds, replaces, or removes the first text node child in the element. + # + # With string argument +string+, + # creates a new \REXML::Text node containing that string, + # honoring the current settings for whitespace and row, + # then places the node as the first text child in the element; + # returns +string+. + # + # If the element has no text child, the text node is added: + # + # d = REXML::Document.new '' + # d.root.text = 'foo' #-> 'foo' + # + # If the element has a text child, it is replaced: + # + # d.root.text = 'bar' #-> 'bar' + # + # With argument +nil+, removes the first text child: + # + # d.root.text = nil #-> '' + # + def text=( text ) + if text.kind_of? String + text = Text.new( text, whitespace(), nil, raw() ) + elsif !text.nil? and !text.kind_of? Text + text = Text.new( text.to_s, whitespace(), nil, raw() ) + end + old_text = get_text + if text.nil? + old_text.remove unless old_text.nil? + else + if old_text.nil? + self << text + else + old_text.replace_with( text ) + end + end + self + end + + # :call-seq: + # add_text(string) -> nil + # add_text(text_node) -> self + # + # Adds text to the element. + # + # When string argument +string+ is given, returns +nil+. + # + # If the element has no child text node, + # creates a \REXML::Text object using the string, + # honoring the current settings for whitespace and raw, + # then adds that node to the element: + # + # d = REXML::Document.new('') + # a = d.root + # a.add_text('foo') + # a.to_a # => [, "foo"] + # + # If the element has child text nodes, + # appends the string to the _last_ text node: + # + # d = REXML::Document.new('foobar') + # a = d.root + # a.add_text('baz') + # a.to_a # => ["foo", , "barbaz"] + # a.add_text('baz') + # a.to_a # => ["foo", , "barbazbaz"] + # + # When text node argument +text_node+ is given, + # appends the node as the last text node in the element; + # returns +self+: + # + # d = REXML::Document.new('foobar') + # a = d.root + # a.add_text(REXML::Text.new('baz')) + # a.to_a # => ["foo", , "bar", "baz"] + # a.add_text(REXML::Text.new('baz')) + # a.to_a # => ["foo", , "bar", "baz", "baz"] + # + def add_text( text ) + if text.kind_of? String + if @children[-1].kind_of? Text + @children[-1] << text + return + end + text = Text.new( text, whitespace(), nil, raw() ) + end + self << text unless text.nil? + self + end + + # :call-seq: + # node_type -> :element + # + # Returns symbol :element: + # + # d = REXML::Document.new('') + # a = d.root # => + # a.node_type # => :element + # + def node_type + :element + end + + # :call-seq: + # xpath -> string_xpath + # + # Returns the string xpath to the element + # relative to the most distant parent: + # + # d = REXML::Document.new('') + # a = d.root # => ... + # b = a[0] # => ... + # c = b[0] # => + # d.xpath # => "" + # a.xpath # => "/a" + # b.xpath # => "/a/b" + # c.xpath # => "/a/b/c" + # + # If there is no parent, returns the expanded name of the element: + # + # e = REXML::Element.new('foo') + # e.xpath # => "foo" + # + def xpath + path_elements = [] + cur = self + path_elements << __to_xpath_helper( self ) + while cur.parent + cur = cur.parent + path_elements << __to_xpath_helper( cur ) + end + path_elements.reverse.join( "/" ) + end + + ################################################# + # Attributes # + ################################################# + + # :call-seq: + # [index] -> object + # [attr_name] -> attr_value + # [attr_sym] -> attr_value + # + # With integer argument +index+ given, + # returns the child at offset +index+, or +nil+ if none: + # + # d = REXML::Document.new '>textmore
' + # root = d.root + # (0..root.size).each do |index| + # node = root[index] + # p "#{index}: #{node} (#{node.class})" + # end + # + # Output: + # + # "0: (REXML::Element)" + # "1: text (REXML::Text)" + # "2: (REXML::Element)" + # "3: more (REXML::Text)" + # "4: (REXML::Element)" + # "5: (NilClass)" + # + # With string argument +attr_name+ given, + # returns the string value for the given attribute name if it exists, + # otherwise +nil+: + # + # d = REXML::Document.new('') + # root = d.root + # root['attr'] # => "value" + # root['nosuch'] # => nil + # + # With symbol argument +attr_sym+ given, + # returns [attr_sym.to_s]: + # + # root[:attr] # => "value" + # root[:nosuch] # => nil + # + def [](name_or_index) + case name_or_index + when String + attributes[name_or_index] + when Symbol + attributes[name_or_index.to_s] + else + super + end + end + + + # :call-seq: + # attribute(name, namespace = nil) + # + # Returns the string value for the given attribute name. + # + # With only argument +name+ given, + # returns the value of the named attribute if it exists, otherwise +nil+: + # + # xml_string = <<-EOT + # + # + # + # + #
+ # EOT + # d = REXML::Document.new(xml_string) + # root = d.root + # a = root[1] # => + # a.attribute('attr') # => attr='value' + # a.attribute('nope') # => nil + # + # With arguments +name+ and +namespace+ given, + # returns the value of the named attribute if it exists, otherwise +nil+: + # + # xml_string = "" + # document = REXML::Document.new(xml_string) + # document.root.attribute("x") # => x='x' + # document.root.attribute("x", "a") # => a:x='a:x' + # + def attribute( name, namespace=nil ) + prefix = namespaces.key(namespace) if namespace + prefix = nil if prefix == 'xmlns' + + ret_val = + attributes.get_attribute( prefix ? "#{prefix}:#{name}" : name ) + + return ret_val unless ret_val.nil? + return nil if prefix.nil? + + # now check that prefix'es namespace is not the same as the + # default namespace + return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] ) + + attributes.get_attribute( name ) + end + + # :call-seq: + # has_attributes? -> true or false + # + # Returns +true+ if the element has attributes, +false+ otherwise: + # + # d = REXML::Document.new('') + # a, b = *d.root + # a.has_attributes? # => true + # b.has_attributes? # => false + # + def has_attributes? + !@attributes.empty? + end + + # :call-seq: + # add_attribute(name, value) -> value + # add_attribute(attribute) -> attribute + # + # Adds an attribute to this element, overwriting any existing attribute + # by the same name. + # + # With string argument +name+ and object +value+ are given, + # adds the attribute created with that name and value: + # + # e = REXML::Element.new + # e.add_attribute('attr', 'value') # => "value" + # e['attr'] # => "value" + # e.add_attribute('attr', 'VALUE') # => "VALUE" + # e['attr'] # => "VALUE" + # + # With only attribute object +attribute+ given, + # adds the given attribute: + # + # a = REXML::Attribute.new('attr', 'value') + # e.add_attribute(a) # => attr='value' + # e['attr'] # => "value" + # a = REXML::Attribute.new('attr', 'VALUE') + # e.add_attribute(a) # => attr='VALUE' + # e['attr'] # => "VALUE" + # + def add_attribute( key, value=nil ) + if key.kind_of? Attribute + @attributes << key + else + @attributes[key] = value + end + end + + # :call-seq: + # add_attributes(hash) -> hash + # add_attributes(array) + # + # Adds zero or more attributes to the element; + # returns the argument. + # + # If hash argument +hash+ is given, + # each key must be a string; + # adds each attribute created with the key/value pair: + # + # e = REXML::Element.new + # h = {'foo' => 'bar', 'baz' => 'bat'} + # e.add_attributes(h) + # + # If argument +array+ is given, + # each array member must be a 2-element array [name, value]; + # each name must be a string: + # + # e = REXML::Element.new + # a = [['foo' => 'bar'], ['baz' => 'bat']] + # e.add_attributes(a) + # + def add_attributes hash + if hash.kind_of? Hash + hash.each_pair {|key, value| @attributes[key] = value } + elsif hash.kind_of? Array + hash.each { |value| @attributes[ value[0] ] = value[1] } + end + end + + # :call-seq: + # delete_attribute(name) -> removed_attribute or nil + # + # Removes a named attribute if it exists; + # returns the removed attribute if found, otherwise +nil+: + # + # e = REXML::Element.new('foo') + # e.add_attribute('bar', 'baz') + # e.delete_attribute('bar') # => + # e.delete_attribute('bar') # => nil + # + def delete_attribute(key) + attr = @attributes.get_attribute(key) + attr.remove unless attr.nil? + end + + ################################################# + # Other Utilities # + ################################################# + + # :call-seq: + # cdatas -> array_of_cdata_children + # + # Returns a frozen array of the REXML::CData children of the element: + # + # xml_string = <<-EOT + # + # + # + # + # EOT + # d = REXML::Document.new(xml_string) + # cds = d.root.cdatas # => ["foo", "bar"] + # cds.frozen? # => true + # cds.map {|cd| cd.class } # => [REXML::CData, REXML::CData] + # + def cdatas + find_all { |child| child.kind_of? CData }.freeze + end + + # :call-seq: + # comments -> array_of_comment_children + # + # Returns a frozen array of the REXML::Comment children of the element: + # + # xml_string = <<-EOT + # + # + # + # + # EOT + # d = REXML::Document.new(xml_string) + # cs = d.root.comments + # cs.frozen? # => true + # cs.map {|c| c.class } # => [REXML::Comment, REXML::Comment] + # cs.map {|c| c.to_s } # => ["foo", "bar"] + # + def comments + find_all { |child| child.kind_of? Comment }.freeze + end + + # :call-seq: + # instructions -> array_of_instruction_children + # + # Returns a frozen array of the REXML::Instruction children of the element: + # + # xml_string = <<-EOT + # + # + # + # + # EOT + # d = REXML::Document.new(xml_string) + # is = d.root.instructions + # is.frozen? # => true + # is.map {|i| i.class } # => [REXML::Instruction, REXML::Instruction] + # is.map {|i| i.to_s } # => ["", ""] + # + def instructions + find_all { |child| child.kind_of? Instruction }.freeze + end + + # :call-seq: + # texts -> array_of_text_children + # + # Returns a frozen array of the REXML::Text children of the element: + # + # xml_string = 'textmore' + # d = REXML::Document.new(xml_string) + # ts = d.root.texts + # ts.frozen? # => true + # ts.map {|t| t.class } # => [REXML::Text, REXML::Text] + # ts.map {|t| t.to_s } # => ["text", "more"] + # + def texts + find_all { |child| child.kind_of? Text }.freeze + end + + # == DEPRECATED + # See REXML::Formatters + # + # Writes out this element, and recursively, all children. + # output:: + # output an object which supports '<< string'; this is where the + # document will be written. + # indent:: + # An integer. If -1, no indenting will be used; otherwise, the + # indentation will be this number of spaces, and children will be + # indented an additional amount. Defaults to -1 + # transitive:: + # If transitive is true and indent is >= 0, then the output will be + # pretty-printed in such a way that the added whitespace does not affect + # the parse tree of the document + # ie_hack:: + # This hack inserts a space before the /> on empty tags to address + # a limitation of Internet Explorer. Defaults to false + # + # out = '' + # doc.write( out ) #-> doc is written to the string 'out' + # doc.write( $stdout ) #-> doc written to the console + def write(output=$stdout, indent=-1, transitive=false, ie_hack=false) + Kernel.warn("#{self.class.name}#write is deprecated. See REXML::Formatters", uplevel: 1) + formatter = if indent > -1 + if transitive + require_relative "formatters/transitive" + REXML::Formatters::Transitive.new( indent, ie_hack ) + else + REXML::Formatters::Pretty.new( indent, ie_hack ) + end + else + REXML::Formatters::Default.new( ie_hack ) + end + formatter.write( self, output ) + end + + private + def calculate_namespaces + if parent + parent.namespaces.merge(attributes.namespaces) + else + attributes.namespaces + end + end + + def __to_xpath_helper node + rv = node.expanded_name.clone + if node.parent + results = node.parent.find_all {|n| + n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name + } + if results.length > 1 + idx = results.index( node ) + rv << "[#{idx+1}]" + end + end + rv + end + + # A private helper method + def each_with_something( test, max=0, name=nil ) + num = 0 + @elements.each( name ){ |child| + yield child if test.call(child) and num += 1 + return if max>0 and num == max + } + end + end + + ######################################################################## + # ELEMENTS # + ######################################################################## + + # A class which provides filtering of children for Elements, and + # XPath search support. You are expected to only encounter this class as + # the element.elements object. Therefore, you are + # _not_ expected to instantiate this yourself. + # + # xml_string = <<-EOT + # + # + # + # Everyday Italian + # Giada De Laurentiis + # 2005 + # 30.00 + # + # + # Harry Potter + # J K. Rowling + # 2005 + # 29.99 + # + # + # XQuery Kick Start + # James McGovern + # Per Bothner + # Kurt Cagle + # James Linn + # Vaidyanathan Nagarajan + # 2003 + # 49.99 + # + # + # Learning XML + # Erik T. Ray + # 2003 + # 39.95 + # + # + # EOT + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements # => # ... > + # + class Elements + include Enumerable + # :call-seq: + # new(parent) -> new_elements_object + # + # Returns a new \Elements object with the given +parent+. + # Does _not_ assign parent.elements = self: + # + # d = REXML::Document.new(xml_string) + # eles = REXML::Elements.new(d.root) + # eles # => # ... > + # eles == d.root.elements # => false + # + def initialize parent + @element = parent + end + + # :call-seq: + # parent + # + # Returns the parent element cited in creating the \Elements object. + # This element is also the default starting point for searching + # in the \Elements object. + # + # d = REXML::Document.new(xml_string) + # elements = REXML::Elements.new(d.root) + # elements.parent == d.root # => true + # + def parent + @element + end + + # :call-seq: + # elements[index] -> element or nil + # elements[xpath] -> element or nil + # elements[n, name] -> element or nil + # + # Returns the first \Element object selected by the arguments, + # if any found, or +nil+ if none found. + # + # Notes: + # - The +index+ is 1-based, not 0-based, so that: + # - The first element has index 1 + # - The _nth_ element has index +n+. + # - The selection ignores non-\Element nodes. + # + # When the single argument +index+ is given, + # returns the element given by the index, if any; otherwise, +nil+: + # + # d = REXML::Document.new(xml_string) + # eles = d.root.elements + # eles # => # ... > + # eles[1] # => ... + # eles.size # => 4 + # eles[4] # => ... + # eles[5] # => nil + # + # The node at this index is not an \Element, and so is not returned: + # + # eles = d.root.first.first # => ... </> + # eles.to_a # => ["Everyday Italian"] + # eles[1] # => nil + # + # When the single argument +xpath+ is given, + # returns the first element found via that +xpath+, if any; otherwise, +nil+: + # + # eles = d.root.elements # => #<REXML::Elements @element=<bookstore> ... </>> + # eles['/bookstore'] # => <bookstore> ... </> + # eles['//book'] # => <book category='cooking'> ... </> + # eles['//book [@category="children"]'] # => <book category='children'> ... </> + # eles['/nosuch'] # => nil + # eles['//nosuch'] # => nil + # eles['//book [@category="nosuch"]'] # => nil + # eles['.'] # => <bookstore> ... </> + # eles['..'].class # => REXML::Document + # + # With arguments +n+ and +name+ given, + # returns the _nth_ found element that has the given +name+, + # or +nil+ if there is no such _nth_ element: + # + # eles = d.root.elements # => #<REXML::Elements @element=<bookstore> ... </>> + # eles[1, 'book'] # => <book category='cooking'> ... </> + # eles[4, 'book'] # => <book category='web' cover='paperback'> ... </> + # eles[5, 'book'] # => nil + # + def []( index, name=nil) + if index.kind_of? Integer + raise "index (#{index}) must be >= 1" if index < 1 + name = literalize(name) if name + num = 0 + @element.find { |child| + child.kind_of? Element and + (name.nil? ? true : child.has_name?( name )) and + (num += 1) == index + } + else + XPath::first( @element, index ) + end + end + + # :call-seq: + # elements[] = index, replacement_element -> replacement_element or nil + # + # Replaces or adds an element. + # + # When <tt>eles[index]</tt> exists, replaces it with +replacement_element+ + # and returns +replacement_element+: + # + # d = REXML::Document.new(xml_string) + # eles = d.root.elements # => #<REXML::Elements @element=<bookstore> ... </>> + # eles[1] # => <book category='cooking'> ... </> + # eles[1] = REXML::Element.new('foo') + # eles[1] # => <foo/> + # + # Does nothing (or raises an exception) + # if +replacement_element+ is not an \Element: + # eles[2] # => <book category='web' cover='paperback'> ... </> + # eles[2] = REXML::Text.new('bar') + # eles[2] # => <book category='web' cover='paperback'> ... </> + # + # When <tt>eles[index]</tt> does not exist, + # adds +replacement_element+ to the element and returns + # + # d = REXML::Document.new(xml_string) + # eles = d.root.elements # => #<REXML::Elements @element=<bookstore> ... </>> + # eles.size # => 4 + # eles[50] = REXML::Element.new('foo') # => <foo/> + # eles.size # => 5 + # eles[5] # => <foo/> + # + # Does nothing (or raises an exception) + # if +replacement_element+ is not an \Element: + # + # eles[50] = REXML::Text.new('bar') # => "bar" + # eles.size # => 5 + # + def []=( index, element ) + previous = self[index] + if previous.nil? + @element.add element + else + previous.replace_with element + end + previous + end + + # :call-seq: + # empty? -> true or false + # + # Returns +true+ if there are no children, +false+ otherwise. + # + # d = REXML::Document.new('') + # d.elements.empty? # => true + # d = REXML::Document.new(xml_string) + # d.elements.empty? # => false + # + def empty? + @element.find{ |child| child.kind_of? Element}.nil? + end + + # :call-seq: + # index(element) + # + # Returns the 1-based index of the given +element+, if found; + # otherwise, returns -1: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # ele_1, ele_2, ele_3, ele_4 = *elements + # elements.index(ele_4) # => 4 + # elements.delete(ele_3) + # elements.index(ele_4) # => 3 + # elements.index(ele_3) # => -1 + # + def index element + rv = 0 + found = @element.find do |child| + child.kind_of? Element and + (rv += 1) and + child == element + end + return rv if found == element + -1 + end + + # :call-seq: + # delete(index) -> removed_element or nil + # delete(element) -> removed_element or nil + # delete(xpath) -> removed_element or nil + # + # Removes an element; returns the removed element, or +nil+ if none removed. + # + # With integer argument +index+ given, + # removes the child element at that offset: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements.size # => 4 + # elements[2] # => <book category='children'> ... </> + # elements.delete(2) # => <book category='children'> ... </> + # elements.size # => 3 + # elements[2] # => <book category='web'> ... </> + # elements.delete(50) # => nil + # + # With element argument +element+ given, + # removes that child element: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # ele_1, ele_2, ele_3, ele_4 = *elements + # elements.size # => 4 + # elements[2] # => <book category='children'> ... </> + # elements.delete(ele_2) # => <book category='children'> ... </> + # elements.size # => 3 + # elements[2] # => <book category='web'> ... </> + # elements.delete(ele_2) # => nil + # + # With string argument +xpath+ given, + # removes the first element found via that xpath: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements.delete('//book') # => <book category='cooking'> ... </> + # elements.delete('//book [@category="children"]') # => <book category='children'> ... </> + # elements.delete('//nosuch') # => nil + # + def delete element + if element.kind_of? Element + @element.delete element + else + el = self[element] + el.remove if el + end + end + + # :call-seq: + # delete_all(xpath) + # + # Removes all elements found via the given +xpath+; + # returns the array of removed elements, if any, else +nil+. + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements.size # => 4 + # deleted_elements = elements.delete_all('//book [@category="web"]') + # deleted_elements.size # => 2 + # elements.size # => 2 + # deleted_elements = elements.delete_all('//book') + # deleted_elements.size # => 2 + # elements.size # => 0 + # elements.delete_all('//book') # => [] + # + def delete_all( xpath ) + rv = [] + XPath::each( @element, xpath) {|element| + rv << element if element.kind_of? Element + } + rv.each do |element| + @element.delete element + element.remove + end + rv + end + + # :call-seq: + # add -> new_element + # add(name) -> new_element + # add(element) -> element + # + # Adds an element; returns the element added. + # + # With no argument, creates and adds a new element. + # The new element has: + # + # - No name. + # - \Parent from the \Elements object. + # - Context from the that parent. + # + # Example: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # parent = elements.parent # => <bookstore> ... </> + # parent.context = {raw: :all} + # elements.size # => 4 + # new_element = elements.add # => </> + # elements.size # => 5 + # new_element.name # => nil + # new_element.parent # => <bookstore> ... </> + # new_element.context # => {:raw=>:all} + # + # With string argument +name+, creates and adds a new element. + # The new element has: + # + # - Name +name+. + # - \Parent from the \Elements object. + # - Context from the that parent. + # + # Example: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # parent = elements.parent # => <bookstore> ... </> + # parent.context = {raw: :all} + # elements.size # => 4 + # new_element = elements.add('foo') # => <foo/> + # elements.size # => 5 + # new_element.name # => "foo" + # new_element.parent # => <bookstore> ... </> + # new_element.context # => {:raw=>:all} + # + # With argument +element+, + # creates and adds a clone of the given +element+. + # The new element has name, parent, and context from the given +element+. + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements.size # => 4 + # e0 = REXML::Element.new('foo') + # e1 = REXML::Element.new('bar', e0, {raw: :all}) + # element = elements.add(e1) # => <bar/> + # elements.size # => 5 + # element.name # => "bar" + # element.parent # => <bookstore> ... </> + # element.context # => {:raw=>:all} + # + def add element=nil + if element.nil? + Element.new("", self, @element.context) + elsif not element.kind_of?(Element) + Element.new(element, self, @element.context) + else + @element << element + element.context = @element.context + element + end + end + + alias :<< :add + + # :call-seq: + # each(xpath = nil) {|element| ... } -> self + # + # Iterates over the elements. + # + # With no argument, calls the block with each element: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements.each {|element| p element } + # + # Output: + # + # <book category='cooking'> ... </> + # <book category='children'> ... </> + # <book category='web'> ... </> + # <book category='web' cover='paperback'> ... </> + # + # With argument +xpath+, calls the block with each element + # that matches the given +xpath+: + # + # elements.each('//book [@category="web"]') {|element| p element } + # + # Output: + # + # <book category='web'> ... </> + # <book category='web' cover='paperback'> ... </> + # + def each( xpath=nil ) + XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element } + end + + # :call-seq: + # collect(xpath = nil) {|element| ... } -> array + # + # Iterates over the elements; returns the array of block return values. + # + # With no argument, iterates over all elements: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements.collect {|element| element.size } # => [9, 9, 17, 9] + # + # With argument +xpath+, iterates over elements that match + # the given +xpath+: + # + # xpath = '//book [@category="web"]' + # elements.collect(xpath) {|element| element.size } # => [17, 9] + # + def collect( xpath=nil ) + collection = [] + XPath::each( @element, xpath ) {|e| + collection << yield(e) if e.kind_of?(Element) + } + collection + end + + # :call-seq: + # inject(xpath = nil, initial = nil) -> object + # + # Calls the block with elements; returns the last block return value. + # + # With no argument, iterates over the elements, calling the block + # <tt>elements.size - 1</tt> times. + # + # - The first call passes the first and second elements. + # - The second call passes the first block return value and the third element. + # - The third call passes the second block return value and the fourth element. + # - And so on. + # + # In this example, the block returns the passed element, + # which is then the object argument to the next call: + # + # d = REXML::Document.new(xml_string) + # elements = d.root.elements + # elements.inject do |object, element| + # p [elements.index(object), elements.index(element)] + # element + # end + # + # Output: + # + # [1, 2] + # [2, 3] + # [3, 4] + # + # With the single argument +xpath+, calls the block only with + # elements matching that xpath: + # + # elements.inject('//book [@category="web"]') do |object, element| + # p [elements.index(object), elements.index(element)] + # element + # end + # + # Output: + # + # [3, 4] + # + # With argument +xpath+ given as +nil+ + # and argument +initial+ also given, + # calls the block once for each element. + # + # - The first call passes the +initial+ and the first element. + # - The second call passes the first block return value and the second element. + # - The third call passes the second block return value and the third element. + # - And so on. + # + # In this example, the first object index is <tt>-1</tt> + # + # elements.inject(nil, 'Initial') do |object, element| + # p [elements.index(object), elements.index(element)] + # element + # end + # + # Output: + # + # [-1, 1] + # [1, 2] + # [2, 3] + # [3, 4] + # + # In this form the passed object can be used as an accumulator: + # + # elements.inject(nil, 0) do |total, element| + # total += element.size + # end # => 44 + # + # With both arguments +xpath+ and +initial+ are given, + # calls the block only with elements matching that xpath: + # + # elements.inject('//book [@category="web"]', 0) do |total, element| + # total += element.size + # end # => 26 + # + def inject( xpath=nil, initial=nil ) + first = true + XPath::each( @element, xpath ) {|e| + if (e.kind_of? Element) + if (first and initial == nil) + initial = e + first = false + else + initial = yield( initial, e ) if e.kind_of? Element + end + end + } + initial + end + + # :call-seq: + # size -> integer + # + # Returns the count of \Element children: + # + # d = REXML::Document.new '<a>sean<b/>elliott<b/>russell<b/></a>' + # d.root.elements.size # => 3 # Three elements. + # d.root.size # => 6 # Three elements plus three text nodes.. + # + def size + count = 0 + @element.each {|child| count+=1 if child.kind_of? Element } + count + end + + # :call-seq: + # to_a(xpath = nil) -> array_of_elements + # + # Returns an array of element children (not including non-element children). + # + # With no argument, returns an array of all element children: + # + # d = REXML::Document.new '<a>sean<b/>elliott<c/></a>' + # elements = d.root.elements + # elements.to_a # => [<b/>, <c/>] # Omits non-element children. + # children = d.root.children + # children # => ["sean", <b/>, "elliott", <c/>] # Includes non-element children. + # + # With argument +xpath+, returns an array of element children + # that match the xpath: + # + # elements.to_a('//c') # => [<c/>] + # + def to_a( xpath=nil ) + rv = XPath.match( @element, xpath ) + return rv.find_all{|e| e.kind_of? Element} if xpath + rv + end + + private + # Private helper class. Removes quotes from quoted strings + def literalize name + name = name[1..-2] if name[0] == ?' or name[0] == ?" #' + name + end + end + + ######################################################################## + # ATTRIBUTES # + ######################################################################## + + # A class that defines the set of Attributes of an Element and provides + # operations for accessing elements in that set. + class Attributes < Hash + + # :call-seq: + # new(element) + # + # Creates and returns a new \REXML::Attributes object. + # The element given by argument +element+ is stored, + # but its own attributes are not modified: + # + # ele = REXML::Element.new('foo') + # attrs = REXML::Attributes.new(ele) + # attrs.object_id == ele.attributes.object_id # => false + # + # Other instance methods in class \REXML::Attributes may refer to: + # + # - +element.document+. + # - +element.prefix+. + # - +element.expanded_name+. + # + def initialize element + @element = element + end + + # :call-seq: + # [name] -> attribute_value or nil + # + # Returns the value for the attribute given by +name+, + # if it exists; otherwise +nil+. + # The value returned is the unnormalized attribute value, + # with entities expanded: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # ele.attributes['att'] # => "<" + # ele.attributes['bar:att'] # => "2" + # ele.attributes['nosuch'] # => nil + # + # Related: get_attribute (returns an \Attribute object). + # + def [](name) + attr = get_attribute(name) + attr&.value + end + + # :call-seq: + # to_a -> array_of_attribute_objects + # + # Returns an array of \REXML::Attribute objects representing + # the attributes: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # attrs = ele.attributes.to_a # => [foo:att='1', bar:att='2', att='<'] + # attrs.first.class # => REXML::Attribute + # + def to_a + enum_for(:each_attribute).to_a + end + + # :call-seq: + # length + # + # Returns the count of attributes: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # ele.attributes.length # => 3 + # + def length + c = 0 + each_attribute { c+=1 } + c + end + alias :size :length + + # :call-seq: + # each_attribute {|attr| ... } + # + # Calls the given block with each \REXML::Attribute object: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # ele.attributes.each_attribute do |attr| + # p [attr.class, attr] + # end + # + # Output: + # + # [REXML::Attribute, foo:att='1'] + # [REXML::Attribute, bar:att='2'] + # [REXML::Attribute, att='<'] + # + def each_attribute # :yields: attribute + return to_enum(__method__) unless block_given? + each_value do |val| + if val.kind_of? Attribute + yield val + else + val.each_value { |atr| yield atr } + end + end + end + + # :call-seq: + # each {|expanded_name, value| ... } + # + # Calls the given block with each expanded-name/value pair: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # ele.attributes.each do |expanded_name, value| + # p [expanded_name, value] + # end + # + # Output: + # + # ["foo:att", "1"] + # ["bar:att", "2"] + # ["att", "<"] + # + def each + return to_enum(__method__) unless block_given? + each_attribute do |attr| + yield [attr.expanded_name, attr.value] + end + end + + # :call-seq: + # get_attribute(name) -> attribute_object or nil + # + # Returns the \REXML::Attribute object for the given +name+: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # attrs = ele.attributes + # attrs.get_attribute('foo:att') # => foo:att='1' + # attrs.get_attribute('foo:att').class # => REXML::Attribute + # attrs.get_attribute('bar:att') # => bar:att='2' + # attrs.get_attribute('att') # => att='<' + # attrs.get_attribute('nosuch') # => nil + # + def get_attribute( name ) + attr = fetch( name, nil ) + if attr.nil? + return nil if name.nil? + # Look for prefix + name =~ Namespace::NAMESPLIT + prefix, n = $1, $2 + if prefix + attr = fetch( n, nil ) + # check prefix + if attr == nil + elsif attr.kind_of? Attribute + return attr if prefix == attr.prefix + else + attr = attr[ prefix ] + return attr + end + end + doctype = @element.document&.doctype + if doctype + expn = @element.expanded_name + expn = doctype.name if expn.size == 0 + attr_val = doctype.attribute_of(expn, name) + return Attribute.new( name, attr_val ) if attr_val + end + return nil + end + if attr.kind_of? Hash + attr = attr[ @element.prefix ] + end + attr + end + + # :call-seq: + # [name] = value -> value + # + # When +value+ is non-+nil+, + # assigns that to the attribute for the given +name+, + # overwriting the previous value if it exists: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # attrs = ele.attributes + # attrs['foo:att'] = '2' # => "2" + # attrs['baz:att'] = '3' # => "3" + # + # When +value+ is +nil+, deletes the attribute if it exists: + # + # attrs['baz:att'] = nil + # attrs.include?('baz:att') # => false + # + def []=( name, value ) + if value.nil? # Delete the named attribute + attr = get_attribute(name) + delete attr + return + end + + unless value.kind_of? Attribute + doctype = @element.document&.doctype + if doctype + value = Text::normalize( value, doctype ) + else + value = Text::normalize( value, nil ) + end + value = Attribute.new(name, value) + end + value.element = @element + old_attr = fetch(value.name, nil) + if old_attr.nil? + store(value.name, value) + elsif old_attr.kind_of? Hash + old_attr[value.prefix] = value + elsif old_attr.prefix != value.prefix + store value.name, {old_attr.prefix => old_attr, + value.prefix => value} + else + store value.name, value + end + @element + end + + # :call-seq: + # prefixes -> array_of_prefix_strings + # + # Returns an array of prefix strings in the attributes. + # The array does not include the default + # namespace declaration, if one exists. + # + # xml_string = '<a xmlns="foo" xmlns:x="bar" xmlns:y="twee" z="glorp"/>' + # d = REXML::Document.new(xml_string) + # d.root.attributes.prefixes # => ["x", "y"] + # + def prefixes + ns = [] + each_attribute do |attribute| + ns << attribute.name if attribute.prefix == 'xmlns' + end + doctype = @element.document&.doctype + if doctype + expn = @element.expanded_name + expn = doctype.name if expn.size == 0 + doctype.attributes_of(expn).each { + |attribute| + ns << attribute.name if attribute.prefix == 'xmlns' + } + end + ns + end + + # :call-seq: + # namespaces + # + # Returns a hash of name/value pairs for the namespaces: + # + # xml_string = '<a xmlns="foo" xmlns:x="bar" xmlns:y="twee" z="glorp"/>' + # d = REXML::Document.new(xml_string) + # d.root.attributes.namespaces # => {"xmlns"=>"foo", "x"=>"bar", "y"=>"twee"} + # + def namespaces + namespaces = {} + each_attribute do |attribute| + namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns' + end + doctype = @element.document&.doctype + if doctype + expn = @element.expanded_name + expn = doctype.name if expn.size == 0 + doctype.attributes_of(expn).each { + |attribute| + namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns' + } + end + namespaces + end + + # :call-seq: + # delete(name) -> element + # delete(attribute) -> element + # + # Removes a specified attribute if it exists; + # returns the attributes' element. + # + # When string argument +name+ is given, + # removes the attribute of that name if it exists: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # attrs = ele.attributes + # attrs.delete('foo:att') # => <ele bar:att='2' att='<'/> + # attrs.delete('foo:att') # => <ele bar:att='2' att='<'/> + # + # When attribute argument +attribute+ is given, + # removes that attribute if it exists: + # + # attr = REXML::Attribute.new('bar:att', '2') + # attrs.delete(attr) # => <ele att='<'/> # => <ele att='<'/> + # attrs.delete(attr) # => <ele att='<'/> # => <ele/> + # + def delete( attribute ) + name = nil + prefix = nil + if attribute.kind_of? Attribute + name = attribute.name + prefix = attribute.prefix + else + attribute =~ Namespace::NAMESPLIT + prefix, name = $1, $2 + prefix = '' unless prefix + end + old = fetch(name, nil) + if old.kind_of? Hash # the supplied attribute is one of many + old.delete(prefix) + if old.size == 1 + repl = nil + old.each_value{|v| repl = v} + store name, repl + end + elsif old # the supplied attribute is a top-level one + super(name) + end + @element + end + + # :call-seq: + # add(attribute) -> attribute + # + # Adds attribute +attribute+, replacing the previous + # attribute of the same name if it exists; + # returns +attribute+: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # attrs = ele.attributes + # attrs # => {"att"=>{"foo"=>foo:att='1', "bar"=>bar:att='2', ""=>att='<'}} + # attrs.add(REXML::Attribute.new('foo:att', '2')) # => foo:att='2' + # attrs.add(REXML::Attribute.new('baz', '3')) # => baz='3' + # attrs.include?('baz') # => true + # + def add( attribute ) + self[attribute.name] = attribute + end + + alias :<< :add + + # :call-seq: + # delete_all(name) -> array_of_removed_attributes + # + # Removes all attributes matching the given +name+; + # returns an array of the removed attributes: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # attrs = ele.attributes + # attrs.delete_all('att') # => [att='<'] + # + def delete_all( name ) + rv = [] + each_attribute { |attribute| + rv << attribute if attribute.expanded_name == name + } + rv.each{ |attr| attr.remove } + rv + end + + # :call-seq: + # get_attribute_ns(namespace, name) + # + # Returns the \REXML::Attribute object among the attributes + # that matches the given +namespace+ and +name+: + # + # xml_string = <<-EOT + # <root xmlns:foo="http://foo" xmlns:bar="http://bar"> + # <ele foo:att='1' bar:att='2' att='<'/> + # </root> + # EOT + # d = REXML::Document.new(xml_string) + # ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> + # attrs = ele.attributes + # attrs.get_attribute_ns('http://foo', 'att') # => foo:att='1' + # attrs.get_attribute_ns('http://foo', 'nosuch') # => nil + # + def get_attribute_ns(namespace, name) + result = nil + each_attribute() { |attribute| + if name == attribute.name && + namespace == attribute.namespace() && + ( !namespace.empty? || !attribute.fully_expanded_name.index(':') ) + # foo will match xmlns:foo, but only if foo isn't also an attribute + result = attribute if !result or !namespace.empty? or + !attribute.fully_expanded_name.index(':') + end + } + result + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/encoding.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/encoding.rb new file mode 100644 index 0000000..7eb05f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/encoding.rb @@ -0,0 +1,48 @@ +# coding: US-ASCII +# frozen_string_literal: false +module REXML + module Encoding + # ID ---> Encoding name + attr_reader :encoding + def encoding=(encoding) + encoding = encoding.name if encoding.is_a?(::Encoding) + if encoding.is_a?(String) + original_encoding = encoding + encoding = find_encoding(encoding) + unless encoding + raise ArgumentError, "Bad encoding name #{original_encoding}" + end + end + encoding = encoding.upcase if encoding + return false if defined?(@encoding) and encoding == @encoding + @encoding = encoding || "UTF-8" + true + end + + def encode(string) + string.encode(@encoding) + end + + def decode(string) + string.encode(::Encoding::UTF_8, @encoding) + end + + private + def find_encoding(name) + case name + when /\Ashift-jis\z/i + return "SHIFT_JIS" + when /\ACP-(\d+)\z/ + name = "CP#{$1}" + when /\AUTF-8\z/i + return name + end + begin + ::Encoding::Converter.search_convpath(name, 'UTF-8') + rescue ::Encoding::ConverterNotFoundError + return nil + end + name + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/entity.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/entity.rb new file mode 100644 index 0000000..1ba5a7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/entity.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: false +require_relative 'child' +require_relative 'source' +require_relative 'xmltokens' + +module REXML + class Entity < Child + include XMLTokens + PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#" + SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))} + PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')} + EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))" + NDATADECL = "\\s+NDATA\\s+#{NAME}" + PEREFERENCE = "%#{NAME};" + PEREFERENCE_RE = /#{PEREFERENCE}/um + ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))} + PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})" + ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))" + PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>" + GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>" + ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um + + attr_reader :name, :external, :ref, :ndata, :pubid, :value + + # Create a new entity. Simple entities can be constructed by passing a + # name, value to the constructor; this creates a generic, plain entity + # reference. For anything more complicated, you have to pass a Source to + # the constructor with the entity definition, or use the accessor methods. + # +WARNING+: There is no validation of entity state except when the entity + # is read from a stream. If you start poking around with the accessors, + # you can easily create a non-conformant Entity. + # + # e = Entity.new( 'amp', '&' ) + def initialize stream, value=nil, parent=nil, reference=false + super(parent) + @ndata = @pubid = @value = @external = nil + if stream.kind_of? Array + @name = stream[1] + if stream[-1] == '%' + @reference = true + stream.pop + else + @reference = false + end + if stream[2] =~ /SYSTEM|PUBLIC/ + @external = stream[2] + if @external == 'SYSTEM' + @ref = stream[3] + @ndata = stream[4] if stream.size == 5 + else + @pubid = stream[3] + @ref = stream[4] + end + else + @value = stream[2] + end + else + @reference = reference + @external = nil + @name = stream + @value = value + end + end + + # Evaluates whether the given string matches an entity definition, + # returning true if so, and false otherwise. + def Entity::matches? string + (ENTITYDECL =~ string) == 0 + end + + # Evaluates to the unnormalized value of this entity; that is, replacing + # &ent; entities. + def unnormalized + document&.record_entity_expansion + + return nil if @value.nil? + + @unnormalized = Text::unnormalize(@value, parent, + entity_expansion_text_limit: document&.entity_expansion_text_limit) + end + + #once :unnormalized + + # Returns the value of this entity unprocessed -- raw. This is the + # normalized value; that is, with all %ent; and &ent; entities intact + def normalized + @value + end + + # Write out a fully formed, correct entity definition (assuming the Entity + # object itself is valid.) + # + # out:: + # An object implementing <TT><<</TT> to which the entity will be + # output + # indent:: + # *DEPRECATED* and ignored + def write out, indent=-1 + out << '<!ENTITY ' + out << '% ' if @reference + out << @name + out << ' ' + if @external + out << @external << ' ' + if @pubid + q = @pubid.include?('"')?"'":'"' + out << q << @pubid << q << ' ' + end + q = @ref.include?('"')?"'":'"' + out << q << @ref << q + out << ' NDATA ' << @ndata if @ndata + else + q = @value.include?('"')?"'":'"' + out << q << @value << q + end + out << '>' + end + + # Returns this entity as a string. See write(). + def to_s + rv = '' + write rv + rv + end + end + + # This is a set of entity constants -- the ones defined in the XML + # specification. These are +gt+, +lt+, +amp+, +quot+ and +apos+. + # CAUTION: these entities does not have parent and document + module EntityConst + # +>+ + GT = Entity.new( 'gt', '>' ) + # +<+ + LT = Entity.new( 'lt', '<' ) + # +&+ + AMP = Entity.new( 'amp', '&' ) + # +"+ + QUOT = Entity.new( 'quot', '"' ) + # +'+ + APOS = Entity.new( 'apos', "'" ) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/default.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/default.rb new file mode 100644 index 0000000..811b2ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/default.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: false + +module REXML + module Formatters + class Default + # Prints out the XML document with no formatting -- except if ie_hack is + # set. + # + # ie_hack:: + # If set to true, then inserts whitespace before the close of an empty + # tag, so that IE's bad XML parser doesn't choke. + def initialize( ie_hack=false ) + @ie_hack = ie_hack + end + + # Writes the node to some output. + # + # node:: + # The node to write + # output:: + # A class implementing <TT><<</TT>. Pass in an Output object to + # change the output encoding. + def write( node, output ) + case node + + when Document + if node.xml_decl.encoding != 'UTF-8' && !output.kind_of?(Output) + output = Output.new( output, node.xml_decl.encoding ) + end + write_document( node, output ) + + when Element + write_element( node, output ) + + when Declaration, ElementDecl, NotationDecl, ExternalEntity, Entity, + Attribute, AttlistDecl + node.write( output,-1 ) + + when Instruction + write_instruction( node, output ) + + when DocType, XMLDecl + node.write( output ) + + when Comment + write_comment( node, output ) + + when CData + write_cdata( node, output ) + + when Text + write_text( node, output ) + + else + raise Exception.new("XML FORMATTING ERROR") + + end + end + + protected + def write_document( node, output ) + node.children.each { |child| write( child, output ) } + end + + def write_element( node, output ) + output << "<#{node.expanded_name}" + + node.attributes.to_a.map { |a| + Hash === a ? a.values : a + }.flatten.sort_by {|attr| attr.name}.each do |attr| + output << " " + attr.write( output ) + end unless node.attributes.empty? + + if node.children.empty? + output << " " if @ie_hack + output << "/" + else + output << ">" + node.children.each { |child| + write( child, output ) + } + output << "</#{node.expanded_name}" + end + output << ">" + end + + def write_text( node, output ) + output << node.to_s() + end + + def write_comment( node, output ) + output << Comment::START + output << node.to_s + output << Comment::STOP + end + + def write_cdata( node, output ) + output << CData::START + output << node.to_s + output << CData::STOP + end + + def write_instruction( node, output ) + output << Instruction::START + output << node.target + content = node.content + if content + output << ' ' + output << content + end + output << Instruction::STOP + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/pretty.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/pretty.rb new file mode 100644 index 0000000..a838d83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/pretty.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true +require_relative 'default' + +module REXML + module Formatters + # Pretty-prints an XML document. This destroys whitespace in text nodes + # and will insert carriage returns and indentations. + # + # TODO: Add an option to print attributes on new lines + class Pretty < Default + + # If compact is set to true, then the formatter will attempt to use as + # little space as possible + attr_accessor :compact + # The width of a page. Used for formatting text + attr_accessor :width + + # Create a new pretty printer. + # + # output:: + # An object implementing '<<(String)', to which the output will be written. + # indentation:: + # An integer greater than 0. The indentation of each level will be + # this number of spaces. If this is < 1, the behavior of this object + # is undefined. Defaults to 2. + # ie_hack:: + # If true, the printer will insert whitespace before closing empty + # tags, thereby allowing Internet Explorer's XML parser to + # function. Defaults to false. + def initialize( indentation=2, ie_hack=false ) + @indentation = indentation + @level = 0 + @ie_hack = ie_hack + @width = 80 + @compact = false + end + + protected + def write_element(node, output) + output << ' '*@level + output << "<#{node.expanded_name}" + + node.attributes.each_attribute do |attr| + output << " " + attr.write( output ) + end unless node.attributes.empty? + + if node.children.empty? + if @ie_hack + output << " " + end + output << "/" + else + output << ">" + # If compact and all children are text, and if the formatted output + # is less than the specified width, then try to print everything on + # one line + skip = false + if compact + if node.children.inject(true) {|s,c| s & c.kind_of?(Text)} + string = +"" + old_level = @level + @level = 0 + node.children.each { |child| write( child, string ) } + @level = old_level + if string.length < @width + output << string + skip = true + end + end + end + unless skip + output << "\n" + @level += @indentation + node.children.each { |child| + next if child.kind_of?(Text) and child.to_s.strip.length == 0 + write( child, output ) + output << "\n" + } + @level -= @indentation + output << ' '*@level + end + output << "</#{node.expanded_name}" + end + output << ">" + end + + def write_text( node, output ) + s = node.to_s() + s.gsub!(/\s/,' ') + s.squeeze!(" ") + s = wrap(s, @width - @level) + s = indent_text(s, @level, " ", true) + output << (' '*@level + s) + end + + def write_comment( node, output) + output << ' ' * @level + super + end + + def write_cdata( node, output) + output << ' ' * @level + super + end + + def write_document( node, output ) + # Ok, this is a bit odd. All XML documents have an XML declaration, + # but it may not write itself if the user didn't specifically add it, + # either through the API or in the input document. If it doesn't write + # itself, then we don't need a carriage return... which makes this + # logic more complex. + node.children.each { |child| + next if child.instance_of?(Text) + unless child == node.children[0] or child.instance_of?(Text) or + (child == node.children[1] and !node.children[0].writethis) + output << "\n" + end + write( child, output ) + } + end + + private + def indent_text(string, level=1, style="\t", indentfirstline=true) + return string if level < 0 + string.gsub(/\n/, "\n#{style*level}") + end + + def wrap(string, width) + parts = [] + while string.length > width and place = string.rindex(' ', width) + parts << string[0...place] + string = string[place+1..-1] + end + parts << string + parts.join("\n") + end + + end + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/transitive.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/transitive.rb new file mode 100644 index 0000000..5ff51e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/formatters/transitive.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: false +require_relative 'pretty' + +module REXML + module Formatters + # The Transitive formatter writes an XML document that parses to an + # identical document as the source document. This means that no extra + # whitespace nodes are inserted, and whitespace within text nodes is + # preserved. Within these constraints, the document is pretty-printed, + # with whitespace inserted into the metadata to introduce formatting. + # + # Note that this is only useful if the original XML is not already + # formatted. Since this formatter does not alter whitespace nodes, the + # results of formatting already formatted XML will be odd. + class Transitive < Default + def initialize( indentation=2, ie_hack=false ) + @indentation = indentation + @level = 0 + @ie_hack = ie_hack + end + + protected + def write_element( node, output ) + output << "<#{node.expanded_name}" + + node.attributes.each_attribute do |attr| + output << " " + attr.write( output ) + end unless node.attributes.empty? + + output << "\n" + output << ' '*@level + if node.children.empty? + output << " " if @ie_hack + output << "/" + else + output << ">" + # If compact and all children are text, and if the formatted output + # is less than the specified width, then try to print everything on + # one line + @level += @indentation + node.children.each { |child| + write( child, output ) + } + @level -= @indentation + output << "</#{node.expanded_name}" + output << "\n" + output << ' '*@level + end + output << ">" + end + + def write_text( node, output ) + output << node.to_s() + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/functions.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/functions.rb new file mode 100644 index 0000000..60ae34e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/functions.rb @@ -0,0 +1,446 @@ +# frozen_string_literal: false +module REXML + # If you add a method, keep in mind two things: + # (1) the first argument will always be a list of nodes from which to + # filter. In the case of context methods (such as position), the function + # should return an array with a value for each child in the array. + # (2) all method calls from XML will have "-" replaced with "_". + # Therefore, in XML, "local-name()" is identical (and actually becomes) + # "local_name()" + module Functions + @@available_functions = {} + @@context = nil + @@namespace_context = {} + @@variables = {} + + INTERNAL_METHODS = [ + :namespace_context, + :namespace_context=, + :variables, + :variables=, + :context=, + :get_namespace, + :send, + ] + class << self + def singleton_method_added(name) + unless INTERNAL_METHODS.include?(name) + @@available_functions[name] = true + end + end + end + + def Functions::namespace_context=(x) ; @@namespace_context=x ; end + def Functions::variables=(x) ; @@variables=x ; end + def Functions::namespace_context ; @@namespace_context ; end + def Functions::variables ; @@variables ; end + + def Functions::context=(value); @@context = value; end + + def Functions::text( ) + if @@context[:node].node_type == :element + @@context[:node].find_all{|n| n.node_type == :text}.collect{|n| n.value} + elsif @@context[:node].node_type == :text + @@context[:node].value + else + false + end + end + + # Returns the last node of the given list of nodes. + def Functions::last( ) + @@context[:size] + end + + def Functions::position( ) + @@context[:index] + end + + # Returns the size of the given list of nodes. + def Functions::count( node_set ) + node_set.size + end + + # Since REXML is non-validating, this method is not implemented as it + # requires a DTD + def Functions::id( object ) + end + + def Functions::local_name(node_set=nil) + get_namespace(node_set) do |node| + return node.local_name + end + "" + end + + def Functions::namespace_uri( node_set=nil ) + get_namespace( node_set ) {|node| node.namespace} + end + + def Functions::name( node_set=nil ) + get_namespace( node_set ) do |node| + node.expanded_name + end + end + + # Helper method. + def Functions::get_namespace( node_set = nil ) + if node_set == nil + yield @@context[:node] if @@context[:node].respond_to?(:namespace) + else + if node_set.respond_to? :each + result = [] + node_set.each do |node| + result << yield(node) if node.respond_to?(:namespace) + end + result + elsif node_set.respond_to? :namespace + yield node_set + end + end + end + + # A node-set is converted to a string by returning the string-value of the + # node in the node-set that is first in document order. If the node-set is + # empty, an empty string is returned. + # + # A number is converted to a string as follows + # + # NaN is converted to the string NaN + # + # positive zero is converted to the string 0 + # + # negative zero is converted to the string 0 + # + # positive infinity is converted to the string Infinity + # + # negative infinity is converted to the string -Infinity + # + # if the number is an integer, the number is represented in decimal form + # as a Number with no decimal point and no leading zeros, preceded by a + # minus sign (-) if the number is negative + # + # otherwise, the number is represented in decimal form as a Number + # including a decimal point with at least one digit before the decimal + # point and at least one digit after the decimal point, preceded by a + # minus sign (-) if the number is negative; there must be no leading zeros + # before the decimal point apart possibly from the one required digit + # immediately before the decimal point; beyond the one required digit + # after the decimal point there must be as many, but only as many, more + # digits as are needed to uniquely distinguish the number from all other + # IEEE 754 numeric values. + # + # The boolean false value is converted to the string false. The boolean + # true value is converted to the string true. + # + # An object of a type other than the four basic types is converted to a + # string in a way that is dependent on that type. + def Functions::string( object=@@context[:node] ) + if object.respond_to?(:node_type) + case object.node_type + when :attribute + object.value + when :element + string_value(object) + when :document + string_value(object.root) + when :processing_instruction + object.content + else + object.to_s + end + else + case object + when Array + string(object[0]) + when Float + if object.nan? + "NaN" + else + integer = object.to_i + if object == integer + "%d" % integer + else + object.to_s + end + end + else + object.to_s + end + end + end + + # A node-set is converted to a string by + # returning the concatenation of the string-value + # of each of the children of the node in the + # node-set that is first in document order. + # If the node-set is empty, an empty string is returned. + def Functions::string_value( o ) + rv = "" + o.children.each { |e| + if e.node_type == :text + rv << e.to_s + elsif e.node_type == :element + rv << string_value( e ) + end + } + rv + end + + def Functions::concat( *objects ) + concatenated = "" + objects.each do |object| + concatenated << string(object) + end + concatenated + end + + # Fixed by Mike Stok + def Functions::starts_with( string, test ) + string(string).index(string(test)) == 0 + end + + # Fixed by Mike Stok + def Functions::contains( string, test ) + string(string).include?(string(test)) + end + + # Kouhei fixed this + def Functions::substring_before( string, test ) + ruby_string = string(string) + ruby_index = ruby_string.index(string(test)) + if ruby_index.nil? + "" + else + ruby_string[ 0...ruby_index ] + end + end + + # Kouhei fixed this too + def Functions::substring_after( string, test ) + ruby_string = string(string) + return $1 if ruby_string =~ /#{test}(.*)/ + "" + end + + # Take equal portions of Mike Stok and Sean Russell; mix + # vigorously, and pour into a tall, chilled glass. Serves 10,000. + def Functions::substring( string, start, length=nil ) + ruby_string = string(string) + ruby_length = if length.nil? + ruby_string.length.to_f + else + number(length) + end + ruby_start = number(start) + + # Handle the special cases + return '' if ( + ruby_length.nan? or + ruby_start.nan? or + ruby_start.infinite? + ) + + infinite_length = ruby_length.infinite? == 1 + ruby_length = ruby_string.length if infinite_length + + # Now, get the bounds. The XPath bounds are 1..length; the ruby bounds + # are 0..length. Therefore, we have to offset the bounds by one. + ruby_start = round(ruby_start) - 1 + ruby_length = round(ruby_length) + + if ruby_start < 0 + ruby_length += ruby_start unless infinite_length + ruby_start = 0 + end + return '' if ruby_length <= 0 + ruby_string[ruby_start,ruby_length] + end + + # UNTESTED + def Functions::string_length( string ) + string(string).length + end + + def Functions::normalize_space( string=nil ) + string = string(@@context[:node]) if string.nil? + if string.kind_of? Array + string.collect{|x| x.to_s.strip.gsub(/\s+/um, ' ') if x} + else + string.to_s.strip.gsub(/\s+/um, ' ') + end + end + + # This is entirely Mike Stok's beast + def Functions::translate( string, tr1, tr2 ) + from = string(tr1) + to = string(tr2) + + # the map is our translation table. + # + # if a character occurs more than once in the + # from string then we ignore the second & + # subsequent mappings + # + # if a character maps to nil then we delete it + # in the output. This happens if the from + # string is longer than the to string + # + # there's nothing about - or ^ being special in + # http://www.w3.org/TR/xpath#function-translate + # so we don't build ranges or negated classes + + map = Hash.new + 0.upto(from.length - 1) { |pos| + from_char = from[pos] + unless map.has_key? from_char + map[from_char] = + if pos < to.length + to[pos] + else + nil + end + end + } + + if ''.respond_to? :chars + string(string).chars.collect { |c| + if map.has_key? c then map[c] else c end + }.compact.join + else + string(string).unpack('U*').collect { |c| + if map.has_key? c then map[c] else c end + }.compact.pack('U*') + end + end + + def Functions::boolean(object=@@context[:node]) + case object + when true, false + object + when Float + return false if object.zero? + return false if object.nan? + true + when Numeric + not object.zero? + when String + not object.empty? + when Array + not object.empty? + else + object ? true : false + end + end + + # UNTESTED + def Functions::not( object ) + not boolean( object ) + end + + # UNTESTED + def Functions::true( ) + true + end + + # UNTESTED + def Functions::false( ) + false + end + + # UNTESTED + def Functions::lang( language ) + lang = false + node = @@context[:node] + attr = nil + until node.nil? + if node.node_type == :element + attr = node.attributes["xml:lang"] + unless attr.nil? + lang = compare_language(string(language), attr) + break + else + end + end + node = node.parent + end + lang + end + + def Functions::compare_language lang1, lang2 + lang2.downcase.index(lang1.downcase) == 0 + end + + # a string that consists of optional whitespace followed by an optional + # minus sign followed by a Number followed by whitespace is converted to + # the IEEE 754 number that is nearest (according to the IEEE 754 + # round-to-nearest rule) to the mathematical value represented by the + # string; any other string is converted to NaN + # + # boolean true is converted to 1; boolean false is converted to 0 + # + # a node-set is first converted to a string as if by a call to the string + # function and then converted in the same way as a string argument + # + # an object of a type other than the four basic types is converted to a + # number in a way that is dependent on that type + def Functions::number(object=@@context[:node]) + case object + when true + Float(1) + when false + Float(0) + when Array + number(string(object)) + when Numeric + object.to_f + else + str = string(object) + case str.strip + when /\A\s*(-?(?:\d+(?:\.\d*)?|\.\d+))\s*\z/ + $1.to_f + else + Float::NAN + end + end + end + + def Functions::sum( nodes ) + nodes = [nodes] unless nodes.kind_of? Array + nodes.inject(0) { |r,n| r + number(string(n)) } + end + + def Functions::floor( number ) + number(number).floor + end + + def Functions::ceiling( number ) + number(number).ceil + end + + def Functions::round( number ) + number = number(number) + begin + neg = number.negative? + number = number.abs.round + neg ? -number : number + rescue FloatDomainError + number + end + end + + def Functions::processing_instruction( node ) + node.node_type == :processing_instruction + end + + def Functions::send(name, *args) + if @@available_functions[name.to_sym] + super + else + # TODO: Maybe, this is not XPath spec behavior. + # This behavior must be reconsidered. + XPath.match(@@context[:node], name.to_s) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/instruction.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/instruction.rb new file mode 100644 index 0000000..a3dfbbe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/instruction.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: false + +require_relative "child" +require_relative "source" + +module REXML + # Represents an XML Instruction; IE, <? ... ?> + # TODO: Add parent arg (3rd arg) to constructor + class Instruction < Child + START = "<?" + STOP = "?>" + + # target is the "name" of the Instruction; IE, the "tag" in <?tag ...?> + # content is everything else. + attr_accessor :target, :content + + # Constructs a new Instruction + # @param target can be one of a number of things. If String, then + # the target of this instruction is set to this. If an Instruction, + # then the Instruction is shallowly cloned (target and content are + # copied). + # @param content Must be either a String, or a Parent. Can only + # be a Parent if the target argument is a Source. Otherwise, this + # String is set as the content of this instruction. + def initialize(target, content=nil) + case target + when String + super() + @target = target + @content = content + when Instruction + super(content) + @target = target.target + @content = target.content + else + message = + "processing instruction target must be String or REXML::Instruction: " + message << "<#{target.inspect}>" + raise ArgumentError, message + end + @content.strip! if @content + end + + def clone + Instruction.new self + end + + # == DEPRECATED + # See the rexml/formatters package + # + def write writer, indent=-1, transitive=false, ie_hack=false + Kernel.warn( "#{self.class.name}#write is deprecated", uplevel: 1) + indent(writer, indent) + writer << START + writer << @target + if @content + writer << ' ' + writer << @content + end + writer << STOP + end + + # @return true if other is an Instruction, and the content and target + # of the other matches the target and content of this object. + def ==( other ) + other.kind_of? Instruction and + other.target == @target and + other.content == @content + end + + def node_type + :processing_instruction + end + + def inspect + "<?p-i #{target} ...?>" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/light/node.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/light/node.rb new file mode 100644 index 0000000..3dab885 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/light/node.rb @@ -0,0 +1,188 @@ +# frozen_string_literal: false +require_relative '../xmltokens' + +module REXML + module Light + # Represents a tagged XML element. Elements are characterized by + # having children, attributes, and names, and can themselves be + # children. + class Node + NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u + PARENTS = [ :element, :document, :doctype ] + # Create a new element. + def initialize node=nil + @node = node + if node.kind_of? String + node = [ :text, node ] + elsif node.nil? + node = [ :document, nil, nil ] + elsif node[0] == :start_element + node[0] = :element + elsif node[0] == :start_doctype + node[0] = :doctype + elsif node[0] == :start_document + node[0] = :document + end + end + + def size + if PARENTS.include? @node[0] + @node[-1].size + else + 0 + end + end + + def each + size.times { |x| yield( at(x+4) ) } + end + + def name + at(2) + end + + def name=( name_str, ns=nil ) + pfx = '' + pfx = "#{prefix(ns)}:" if ns + _old_put(2, "#{pfx}#{name_str}") + end + + def parent=( node ) + _old_put(1,node) + end + + def local_name + namesplit + @name + end + + def local_name=( name_str ) + _old_put( 1, "#@prefix:#{name_str}" ) + end + + def prefix( namespace=nil ) + prefix_of( self, namespace ) + end + + def namespace( prefix=prefix() ) + namespace_of( self, prefix ) + end + + def namespace=( namespace ) + @prefix = prefix( namespace ) + pfx = '' + pfx = "#@prefix:" if @prefix.size > 0 + _old_put(1, "#{pfx}#@name") + end + + def []( reference, ns=nil ) + if reference.kind_of? String + pfx = '' + pfx = "#{prefix(ns)}:" if ns + at(3)["#{pfx}#{reference}"] + elsif reference.kind_of? Range + _old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) ) + else + _old_get( 4+reference ) + end + end + + def =~( path ) + XPath.match( self, path ) + end + + # Doesn't handle namespaces yet + def []=( reference, ns, value=nil ) + if reference.kind_of? String + value = ns unless value + at( 3 )[reference] = value + elsif reference.kind_of? Range + _old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns ) + else + if value + _old_put( 4+reference, ns, value ) + else + _old_put( 4+reference, ns ) + end + end + end + + # Append a child to this element, optionally under a provided namespace. + # The namespace argument is ignored if the element argument is an Element + # object. Otherwise, the element argument is a string, the namespace (if + # provided) is the namespace the element is created in. + def << element + if node_type() == :text + at(-1) << element + else + newnode = Node.new( element ) + newnode.parent = self + self.push( newnode ) + end + at(-1) + end + + def node_type + _old_get(0) + end + + def text=( foo ) + replace = at(4).kind_of?(String)? 1 : 0 + self._old_put(4,replace, normalizefoo) + end + + def root + context = self + context = context.at(1) while context.at(1) + end + + def has_name?( name, namespace = '' ) + at(3) == name and namespace() == namespace + end + + def children + self + end + + def parent + at(1) + end + + def to_s + + end + + private + + def namesplit + return if @name.defined? + at(2) =~ NAMESPLIT + @prefix = '' || $1 + @name = $2 + end + + def namespace_of( node, prefix=nil ) + if not prefix + name = at(2) + name =~ NAMESPLIT + prefix = $1 + end + to_find = 'xmlns' + to_find = "xmlns:#{prefix}" if not prefix.nil? + ns = at(3)[ to_find ] + ns ? ns : namespace_of( @node[0], prefix ) + end + + def prefix_of( node, namespace=nil ) + if not namespace + name = node.name + name =~ NAMESPLIT + $1 + else + ns = at(3).find { |k,v| v == namespace } + ns ? ns : prefix_of( node.parent, namespace ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/namespace.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/namespace.rb new file mode 100644 index 0000000..232b7ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/namespace.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require_relative 'xmltokens' + +module REXML + # Adds named attributes to an object. + module Namespace + # The name of the object, valid if set + attr_reader :name, :expanded_name + # The expanded name of the object, valid if name is set + attr_accessor :prefix + include XMLTokens + NAME_WITHOUT_NAMESPACE = /\A#{NCNAME_STR}\z/ + NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u + + # Sets the name and the expanded name + def name=( name ) + @expanded_name = name + if name.match?(NAME_WITHOUT_NAMESPACE) + @prefix = "" + @namespace = "" + @name = name + elsif name =~ NAMESPLIT + if $1 + @prefix = $1 + else + @prefix = "" + @namespace = "" + end + @name = $2 + elsif name == "" + @prefix = nil + @namespace = nil + @name = nil + else + message = "name must be \#{PREFIX}:\#{LOCAL_NAME} or \#{LOCAL_NAME}: " + message += "<#{name.inspect}>" + raise ArgumentError, message + end + end + + # Compares names optionally WITH namespaces + def has_name?( other, ns=nil ) + if ns + namespace() == ns and name() == other + elsif other.include? ":" + fully_expanded_name == other + else + name == other + end + end + + alias :local_name :name + + # Fully expand the name, even if the prefix wasn't specified in the + # source file. + def fully_expanded_name + ns = prefix + return "#{ns}:#@name" if ns.size > 0 + @name + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/node.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/node.rb new file mode 100644 index 0000000..bccacc5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/node.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: false +require_relative "parseexception" +require_relative "formatters/pretty" +require_relative "formatters/default" + +module REXML + # Represents a node in the tree. Nodes are never encountered except as + # superclasses of other objects. Nodes have siblings. + module Node + # @return the next sibling (nil if unset) + def next_sibling_node + return nil if @parent.nil? + @parent[ @parent.index(self) + 1 ] + end + + # @return the previous sibling (nil if unset) + def previous_sibling_node + return nil if @parent.nil? + ind = @parent.index(self) + return nil if ind == 0 + @parent[ ind - 1 ] + end + + # indent:: + # *DEPRECATED* This parameter is now ignored. See the formatters in the + # REXML::Formatters package for changing the output style. + def to_s indent=nil + unless indent.nil? + Kernel.warn( "#{self.class.name}#to_s(indent) parameter is deprecated", uplevel: 1) + f = REXML::Formatters::Pretty.new( indent ) + f.write( self, rv = "" ) + else + f = REXML::Formatters::Default.new + f.write( self, rv = "" ) + end + return rv + end + + def indent to, ind + if @parent and @parent.context and not @parent.context[:indentstyle].nil? then + indentstyle = @parent.context[:indentstyle] + else + indentstyle = ' ' + end + to << indentstyle*ind unless ind<1 + end + + def parent? + false; + end + + + # Visit all subnodes of +self+ recursively + def each_recursive(&block) # :yields: node + stack = [] + each { |child| stack.unshift child if child.node_type == :element } + until stack.empty? + child = stack.pop + yield child + n = stack.size + child.each { |grandchild| stack.insert n, grandchild if grandchild.node_type == :element } + end + end + + # Find (and return) first subnode (recursively) for which the block + # evaluates to true. Returns +nil+ if none was found. + def find_first_recursive(&block) # :yields: node + each_recursive {|node| + return node if block.call(node) + } + nil + end + + # Returns the position that +self+ holds in its parent's array, indexed + # from 1. + def index_in_parent + parent.index(self)+1 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/output.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/output.rb new file mode 100644 index 0000000..88a5fb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/output.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: false +require_relative 'encoding' + +module REXML + class Output + include Encoding + + attr_reader :encoding + + def initialize real_IO, encd="iso-8859-1" + @output = real_IO + self.encoding = encd + + @to_utf = encoding != 'UTF-8' + + if encoding == "UTF-16" + @output << "\ufeff".encode("UTF-16BE") + self.encoding = "UTF-16BE" + end + end + + def <<( content ) + @output << (@to_utf ? self.encode(content) : content) + end + + def to_s + "Output[#{encoding}]" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parent.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parent.rb new file mode 100644 index 0000000..6a53b37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parent.rb @@ -0,0 +1,166 @@ +# frozen_string_literal: false +require_relative "child" + +module REXML + # A parent has children, and has methods for accessing them. The Parent + # class is never encountered except as the superclass for some other + # object. + class Parent < Child + include Enumerable + + # Constructor + # @param parent if supplied, will be set as the parent of this object + def initialize parent=nil + super(parent) + @children = [] + end + + def add( object ) + object.parent = self + @children << object + object + end + + alias :push :add + alias :<< :push + + def unshift( object ) + object.parent = self + @children.unshift object + end + + def delete( object ) + found = false + @children.delete_if {|c| c.equal?(object) and found = true } + object.parent = nil if found + found ? object : nil + end + + def each(&block) + @children.each(&block) + end + + def delete_if( &block ) + @children.delete_if(&block) + end + + def delete_at( index ) + @children.delete_at index + end + + def each_index( &block ) + @children.each_index(&block) + end + + # Fetches a child at a given index + # @param index the Integer index of the child to fetch + def []( index ) + @children[index] + end + + alias :each_child :each + + + + # Set an index entry. See Array.[]= + # @param index the index of the element to set + # @param opt either the object to set, or an Integer length + # @param child if opt is an Integer, this is the child to set + # @return the parent (self) + def []=( *args ) + args[-1].parent = self + @children[*args[0..-2]] = args[-1] + end + + # Inserts an child before another child + # @param child1 this is either an xpath or an Element. If an Element, + # child2 will be inserted before child1 in the child list of the parent. + # If an xpath, child2 will be inserted before the first child to match + # the xpath. + # @param child2 the child to insert + # @return the parent (self) + def insert_before( child1, child2 ) + if child1.kind_of? String + child1 = XPath.first( self, child1 ) + child1.parent.insert_before child1, child2 + else + ind = index(child1) + child2.parent.delete(child2) if child2.parent + @children[ind,0] = child2 + child2.parent = self + end + self + end + + # Inserts an child after another child + # @param child1 this is either an xpath or an Element. If an Element, + # child2 will be inserted after child1 in the child list of the parent. + # If an xpath, child2 will be inserted after the first child to match + # the xpath. + # @param child2 the child to insert + # @return the parent (self) + def insert_after( child1, child2 ) + if child1.kind_of? String + child1 = XPath.first( self, child1 ) + child1.parent.insert_after child1, child2 + else + ind = index(child1)+1 + child2.parent.delete(child2) if child2.parent + @children[ind,0] = child2 + child2.parent = self + end + self + end + + def to_a + @children.dup + end + + # Fetches the index of a given child + # @param child the child to get the index of + # @return the index of the child, or nil if the object is not a child + # of this parent. + def index( child ) + count = -1 + @children.find { |i| count += 1 ; i.hash == child.hash } + count + end + + # @return the number of children of this parent + def size + @children.size + end + + alias :length :size + + # Replaces one child with another, making sure the nodelist is correct + # @param to_replace the child to replace (must be a Child) + # @param replacement the child to insert into the nodelist (must be a + # Child) + def replace_child( to_replace, replacement ) + @children.map! {|c| c.equal?( to_replace ) ? replacement : c } + to_replace.parent = nil + replacement.parent = self + end + + # Deeply clones this object. This creates a complete duplicate of this + # Parent, including all descendants. + def deep_clone + cl = clone() + each do |child| + if child.kind_of? Parent + cl << child.deep_clone + else + cl << child.clone + end + end + cl + end + + alias :children :to_a + + def parent? + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parseexception.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parseexception.rb new file mode 100644 index 0000000..e57d05f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parseexception.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: false +module REXML + class ParseException < RuntimeError + attr_accessor :source, :parser, :continued_exception + + def initialize( message, source=nil, parser=nil, exception=nil ) + super(message) + @source = source + @parser = parser + @continued_exception = exception + end + + def to_s + # Quote the original exception, if there was one + if @continued_exception + err = @continued_exception.inspect + err << "\n" + err << @continued_exception.backtrace.join("\n") + err << "\n...\n" + else + err = "" + end + + # Get the stack trace and error message + err << super + + # Add contextual information + if @source + err << "\nLine: #{line}\n" + err << "Position: #{position}\n" + err << "Last 80 unconsumed characters:\n" + err.force_encoding("ASCII-8BIT") + err << @source.buffer[0..80].force_encoding("ASCII-8BIT").gsub(/\n/, ' ') + end + + err + end + + def position + @source.current_line[0] if @source and defined? @source.current_line and + @source.current_line + end + + def line + @source.current_line[2] if @source and defined? @source.current_line and + @source.current_line + end + + def context + @source.current_line + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb new file mode 100644 index 0000000..8fe287a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb @@ -0,0 +1,949 @@ +# frozen_string_literal: true +require_relative '../parseexception' +require_relative '../undefinednamespaceexception' +require_relative '../security' +require_relative '../source' +require 'set' +require "strscan" + +module REXML + module Parsers + unless [].respond_to?(:tally) + module EnumerableTally + refine Enumerable do + def tally + counts = {} + each do |item| + counts[item] ||= 0 + counts[item] += 1 + end + counts + end + end + end + using EnumerableTally + end + + if StringScanner::Version < "3.0.8" + module StringScannerCaptures + refine StringScanner do + def captures + values_at(*(1...size)) + end + end + end + using StringScannerCaptures + end + + # = Using the Pull Parser + # <em>This API is experimental, and subject to change.</em> + # parser = PullParser.new( "<a>text<b att='val'/>txet</a>" ) + # while parser.has_next? + # res = parser.next + # puts res[1]['att'] if res.start_tag? and res[0] == 'b' + # end + # See the PullEvent class for information on the content of the results. + # The data is identical to the arguments passed for the various events to + # the StreamListener API. + # + # Notice that: + # parser = PullParser.new( "<a>BAD DOCUMENT" ) + # while parser.has_next? + # res = parser.next + # raise res[1] if res.error? + # end + # + # Nat Price gave me some good ideas for the API. + class BaseParser + LETTER = '[:alpha:]' + DIGIT = '[:digit:]' + + COMBININGCHAR = '' # TODO + EXTENDER = '' # TODO + + NCNAME_STR= "[#{LETTER}_][-[:alnum:]._#{COMBININGCHAR}#{EXTENDER}]*" + QNAME_STR= "(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})" + QNAME = /(#{QNAME_STR})/ + + # Just for backward compatibility. For example, kramdown uses this. + # It's not used in REXML. + UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}" + + NAMECHAR = '[\-\w\.:]' + NAME = "([\\w:]#{NAMECHAR}*)" + NMTOKEN = "(?:#{NAMECHAR})+" + NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*" + REFERENCE = "&(?:#{NAME};|#\\d+;|#x[0-9a-fA-F]+;)" + REFERENCE_RE = /#{REFERENCE}/ + + DOCTYPE_START = /\A\s*<!DOCTYPE\s/um + DOCTYPE_END = /\A\s*\]\s*>/um + ATTRIBUTE_PATTERN = /\s*(#{QNAME_STR})\s*=\s*(["'])(.*?)\4/um + COMMENT_START = /\A<!--/u + COMMENT_PATTERN = /<!--(.*?)-->/um + CDATA_START = /\A<!\[CDATA\[/u + CDATA_END = /\A\s*\]\s*>/um + CDATA_PATTERN = /<!\[CDATA\[(.*?)\]\]>/um + XMLDECL_START = /\A<\?xml\s/u; + XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>/um + INSTRUCTION_START = /\A<\?/u + INSTRUCTION_PATTERN = /<\?#{NAME}(\s+.*?)?\?>/um + TAG_MATCH = /\A<((?>#{QNAME_STR}))/um + CLOSE_MATCH = /\A\s*<\/(#{QNAME_STR})\s*>/um + + VERSION = /\bversion\s*=\s*["'](.*?)['"]/um + ENCODING = /\bencoding\s*=\s*["'](.*?)['"]/um + STANDALONE = /\bstandalone\s*=\s*["'](.*?)['"]/um + + ENTITY_START = /\A\s*<!ENTITY/ + ELEMENTDECL_START = /\A\s*<!ELEMENT/um + ELEMENTDECL_PATTERN = /\A\s*(<!ELEMENT.*?)>/um + SYSTEMENTITY = /\A\s*(%.*?;)\s*$/um + ENUMERATION = "\\(\\s*#{NMTOKEN}(?:\\s*\\|\\s*#{NMTOKEN})*\\s*\\)" + NOTATIONTYPE = "NOTATION\\s+\\(\\s*#{NAME}(?:\\s*\\|\\s*#{NAME})*\\s*\\)" + ENUMERATEDTYPE = "(?:(?:#{NOTATIONTYPE})|(?:#{ENUMERATION}))" + ATTTYPE = "(CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|#{ENUMERATEDTYPE})" + ATTVALUE = "(?:\"((?:[^<&\"]|#{REFERENCE})*)\")|(?:'((?:[^<&']|#{REFERENCE})*)')" + DEFAULTDECL = "(#REQUIRED|#IMPLIED|(?:(#FIXED\\s+)?#{ATTVALUE}))" + ATTDEF = "\\s+#{NAME}\\s+#{ATTTYPE}\\s+#{DEFAULTDECL}" + ATTDEF_RE = /#{ATTDEF}/ + ATTLISTDECL_START = /\A\s*<!ATTLIST/um + ATTLISTDECL_PATTERN = /\A\s*<!ATTLIST\s+#{NAME}(?:#{ATTDEF})*\s*>/um + + TEXT_PATTERN = /\A([^<]*)/um + + # Entity constants + PUBIDCHAR = "\x20\x0D\x0Aa-zA-Z0-9\\-()+,./:=?;!*@$_%#" + SYSTEMLITERAL = %Q{((?:"[^"]*")|(?:'[^']*'))} + PUBIDLITERAL = %Q{("[#{PUBIDCHAR}']*"|'[#{PUBIDCHAR}]*')} + EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))" + NDATADECL = "\\s+NDATA\\s+#{NAME}" + PEREFERENCE = "%#{NAME};" + ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))} + PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})" + ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))" + PEDECL = "<!ENTITY\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>" + GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>" + ENTITYDECL = /\s*(?:#{GEDECL})|\s*(?:#{PEDECL})/um + + NOTATIONDECL_START = /\A\s*<!NOTATION/um + EXTERNAL_ID_PUBLIC = /\A\s*PUBLIC\s+#{PUBIDLITERAL}\s+#{SYSTEMLITERAL}\s*/um + EXTERNAL_ID_SYSTEM = /\A\s*SYSTEM\s+#{SYSTEMLITERAL}\s*/um + PUBLIC_ID = /\A\s*PUBLIC\s+#{PUBIDLITERAL}\s*/um + + EREFERENCE = /&(?!#{NAME};)/ + + DEFAULT_ENTITIES = { + 'gt' => [/>/, '>', '>', />/], + 'lt' => [/</, '<', '<', /</], + 'quot' => [/"/, '"', '"', /"/], + "apos" => [/'/, "'", "'", /'/] + } + + module Private + PEREFERENCE_PATTERN = /#{PEREFERENCE}/um + TAG_PATTERN = /((?>#{QNAME_STR}))\s*/um + CLOSE_PATTERN = /(#{QNAME_STR})\s*>/um + EQUAL_PATTERN = /\s*=\s*/um + ATTLISTDECL_END = /\s+#{NAME}(?:#{ATTDEF})*\s*>/um + NAME_PATTERN = /#{NAME}/um + GEDECL_PATTERN = "\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>" + PEDECL_PATTERN = "\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>" + ENTITYDECL_PATTERN = /(?:#{GEDECL_PATTERN})|(?:#{PEDECL_PATTERN})/um + CARRIAGE_RETURN_NEWLINE_PATTERN = /\r\n?/ + CHARACTER_REFERENCES = /&#((?:\d+)|(?:x[a-fA-F0-9]+));/ + DEFAULT_ENTITIES_PATTERNS = {} + default_entities = ['gt', 'lt', 'quot', 'apos', 'amp'] + default_entities.each do |term| + DEFAULT_ENTITIES_PATTERNS[term] = /&#{term};/ + end + XML_PREFIXED_NAMESPACE = "http://www.w3.org/XML/1998/namespace" + end + private_constant :Private + + def initialize( source ) + self.stream = source + @listeners = [] + @prefixes = Set.new + @entity_expansion_count = 0 + @entity_expansion_limit = Security.entity_expansion_limit + @entity_expansion_text_limit = Security.entity_expansion_text_limit + @source.ensure_buffer + @version = nil + end + + def add_listener( listener ) + @listeners << listener + end + + attr_reader :source + attr_reader :entity_expansion_count + attr_writer :entity_expansion_limit + attr_writer :entity_expansion_text_limit + + def stream=( source ) + @source = SourceFactory.create_from( source ) + reset + end + + def reset + @closed = nil + @have_root = false + @document_status = nil + @tags = [] + @stack = [] + @entities = [] + @namespaces = {"xml" => Private::XML_PREFIXED_NAMESPACE} + @namespaces_restore_stack = [] + end + + def position + if @source.respond_to? :position + @source.position + else + # FIXME + 0 + end + end + + # Returns true if there are no more events + def empty? + (@source.empty? and @stack.empty?) + end + + # Returns true if there are more events. Synonymous with !empty? + def has_next? + !(@source.empty? and @stack.empty?) + end + + # Push an event back on the head of the stream. This method + # has (theoretically) infinite depth. + def unshift token + @stack.unshift(token) + end + + # Peek at the +depth+ event in the stack. The first element on the stack + # is at depth 0. If +depth+ is -1, will parse to the end of the input + # stream and return the last event, which is always :end_document. + # Be aware that this causes the stream to be parsed up to the +depth+ + # event, so you can effectively pre-parse the entire document (pull the + # entire thing into memory) using this method. + def peek depth=0 + raise %Q[Illegal argument "#{depth}"] if depth < -1 + temp = [] + if depth == -1 + temp.push(pull()) until empty? + else + while @stack.size+temp.size < depth+1 + temp.push(pull()) + end + end + @stack += temp if temp.size > 0 + @stack[depth] + end + + # Returns the next event. This is a +PullEvent+ object. + def pull + @source.drop_parsed_content + + pull_event.tap do |event| + @listeners.each do |listener| + listener.receive event + end + end + end + + def pull_event + if @closed + x, @closed = @closed, nil + return [ :end_element, x ] + end + if empty? + if @document_status == :in_doctype + raise ParseException.new("Malformed DOCTYPE: unclosed", @source) + end + unless @tags.empty? + path = "/" + @tags.join("/") + raise ParseException.new("Missing end tag for '#{path}'", @source) + end + + unless @document_status == :in_element + raise ParseException.new("Malformed XML: No root element", @source) + end + + return [ :end_document ] + end + return @stack.shift if @stack.size > 0 + #STDERR.puts @source.encoding + #STDERR.puts "BUFFER = #{@source.buffer.inspect}" + + @source.ensure_buffer + if @document_status == nil + start_position = @source.position + if @source.match?("<?", true) + return process_instruction + elsif @source.match?("<!", true) + if @source.match?("--", true) + return [ :comment, process_comment ] + elsif @source.match?("DOCTYPE", true) + base_error_message = "Malformed DOCTYPE" + unless @source.skip_spaces + if @source.match?(">") + message = "#{base_error_message}: name is missing" + else + message = "#{base_error_message}: invalid name" + end + @source.position = start_position + raise REXML::ParseException.new(message, @source) + end + name = parse_name(base_error_message) + @source.skip_spaces + if @source.match?("[", true) + id = [nil, nil, nil] + @document_status = :in_doctype + elsif @source.match?(">", true) + id = [nil, nil, nil] + @document_status = :after_doctype + @source.ensure_buffer + else + id = parse_id(base_error_message, + accept_external_id: true, + accept_public_id: false) + if id[0] == "SYSTEM" + # For backward compatibility + id[1], id[2] = id[2], nil + end + @source.skip_spaces + if @source.match?("[", true) + @document_status = :in_doctype + elsif @source.match?(">", true) + @document_status = :after_doctype + @source.ensure_buffer + else + message = "#{base_error_message}: garbage after external ID" + raise REXML::ParseException.new(message, @source) + end + end + args = [:start_doctype, name, *id] + if @document_status == :after_doctype + @source.skip_spaces + @stack << [ :end_doctype ] + end + return args + else + message = "Invalid XML" + raise REXML::ParseException.new(message, @source) + end + end + end + if @document_status == :in_doctype + @source.skip_spaces + start_position = @source.position + if @source.match?("<!", true) + if @source.match?("ELEMENT", true) + md = @source.match(/(.*?)>/um, true) + raise REXML::ParseException.new( "Bad ELEMENT declaration!", @source ) if md.nil? + return [ :elementdecl, "<!ELEMENT" + md[1] ] + elsif @source.match?("ENTITY", true) + match_data = @source.match(Private::ENTITYDECL_PATTERN, true) + unless match_data + raise REXML::ParseException.new("Malformed entity declaration", @source) + end + match = [:entitydecl, *match_data.captures.compact] + ref = false + if match[1] == '%' + ref = true + match.delete_at 1 + end + # Now we have to sort out what kind of entity reference this is + if match[2] == 'SYSTEM' + # External reference + match[3] = match[3][1..-2] # PUBID + match.delete_at(4) if match.size > 4 # Chop out NDATA decl + # match is [ :entity, name, SYSTEM, pubid(, ndata)? ] + elsif match[2] == 'PUBLIC' + # External reference + match[3] = match[3][1..-2] # PUBID + match[4] = match[4][1..-2] # HREF + match.delete_at(5) if match.size > 5 # Chop out NDATA decl + # match is [ :entity, name, PUBLIC, pubid, href(, ndata)? ] + elsif Private::PEREFERENCE_PATTERN.match?(match[2]) + raise REXML::ParseException.new("Parameter entity references forbidden in internal subset: #{match[2]}", @source) + else + match[2] = match[2][1..-2] + match.pop if match.size == 4 + # match is [ :entity, name, value ] + end + match << '%' if ref + return match + elsif @source.match?("ATTLIST", true) + md = @source.match(Private::ATTLISTDECL_END, true) + raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil? + element = md[1] + contents = "<!ATTLIST" + md[0] + + pairs = {} + values = md[0].strip.scan( ATTDEF_RE ) + values.each do |attdef| + unless attdef[3] == "#IMPLIED" + attdef.compact! + val = attdef[3] + val = attdef[4] if val == "#FIXED " + pairs[attdef[0]] = val + if attdef[0] =~ /^xmlns:(.*)/ + @namespaces[$1] = val + end + end + end + return [ :attlistdecl, element, pairs, contents ] + elsif @source.match?("NOTATION", true) + base_error_message = "Malformed notation declaration" + unless @source.skip_spaces + if @source.match?(">") + message = "#{base_error_message}: name is missing" + else + message = "#{base_error_message}: invalid name" + end + @source.position = start_position + raise REXML::ParseException.new(message, @source) + end + name = parse_name(base_error_message) + id = parse_id(base_error_message, + accept_external_id: true, + accept_public_id: true) + @source.skip_spaces + unless @source.match?(">", true) + message = "#{base_error_message}: garbage before end >" + raise REXML::ParseException.new(message, @source) + end + return [:notationdecl, name, *id] + elsif @source.match?("--", true) + return [ :comment, process_comment ] + else + raise REXML::ParseException.new("Malformed node: Started with '<!' but not a comment nor ELEMENT,ENTITY,ATTLIST,NOTATION", @source) + end + elsif match = @source.match(/(%.*?;)\s*/um, true) + return [ :externalentity, match[1] ] + elsif @source.match?(/\]\s*>/um, true) + @document_status = :after_doctype + return [ :end_doctype ] + else + raise ParseException.new("Malformed DOCTYPE: invalid declaration", @source) + end + end + if @document_status == :after_doctype + @source.skip_spaces + end + begin + start_position = @source.position + if @source.match?("<", true) + # :text's read_until may remain only "<" in buffer. In the + # case, buffer is empty here. So we need to fill buffer + # here explicitly. + @source.ensure_buffer + if @source.match?("/", true) + @namespaces_restore_stack.pop + last_tag = @tags.pop + md = @source.match(Private::CLOSE_PATTERN, true) + if md and !last_tag + message = "Unexpected top-level end tag (got '#{md[1]}')" + raise REXML::ParseException.new(message, @source) + end + if md.nil? or last_tag != md[1] + message = "Missing end tag for '#{last_tag}'" + message += " (got '#{md[1]}')" if md + @source.position = start_position if md.nil? + raise REXML::ParseException.new(message, @source) + end + return [ :end_element, last_tag ] + elsif @source.match?("!", true) + #STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}" + if @source.match?("--", true) + return [ :comment, process_comment ] + elsif @source.match?("[CDATA[", true) + text = @source.read_until("]]>") + if text.chomp!("]]>") + return [ :cdata, text ] + else + raise REXML::ParseException.new("Malformed CDATA: Missing end ']]>'", @source) + end + else + raise REXML::ParseException.new("Malformed node: Started with '<!' but not a comment nor CDATA", @source) + end + elsif @source.match?("?", true) + return process_instruction + else + # Get the next tag + md = @source.match(Private::TAG_PATTERN, true) + unless md + @source.position = start_position + raise REXML::ParseException.new("malformed XML: missing tag start", @source) + end + tag = md[1] + @document_status = :in_element + @prefixes.clear + @prefixes << md[2] if md[2] + push_namespaces_restore + attributes, closed = parse_attributes(@prefixes) + # Verify that all of the prefixes have been defined + for prefix in @prefixes + unless @namespaces.key?(prefix) + raise UndefinedNamespaceException.new(prefix,@source,self) + end + end + + if closed + @closed = tag + pop_namespaces_restore + else + if @tags.empty? and @have_root + raise ParseException.new("Malformed XML: Extra tag at the end of the document (got '<#{tag}')", @source) + end + @tags.push( tag ) + end + @have_root = true + return [ :start_element, tag, attributes ] + end + else + text = @source.read_until("<") + if text.chomp!("<") + @source.position -= "<".bytesize + end + if @tags.empty? + unless /\A\s*\z/.match?(text) + if @have_root + raise ParseException.new("Malformed XML: Extra content at the end of the document (got '#{text}')", @source) + else + raise ParseException.new("Malformed XML: Content at the start of the document (got '#{text}')", @source) + end + end + return pull_event if @have_root + end + return [ :text, text ] + end + rescue REXML::UndefinedNamespaceException + raise + rescue REXML::ParseException + raise + rescue => error + raise REXML::ParseException.new( "Exception parsing", + @source, self, (error ? error : $!) ) + end + # NOTE: The end of the method never runs, because it is unreachable. + # All branches of code above have explicit unconditional return or raise statements. + end + private :pull_event + + def entity( reference, entities ) + return unless entities + + value = entities[ reference ] + return if value.nil? + + record_entity_expansion + unnormalize( value, entities ) + end + + # Escapes all possible entities + def normalize( input, entities=nil, entity_filter=nil ) + copy = input.clone + # Doing it like this rather than in a loop improves the speed + copy.gsub!( EREFERENCE, '&' ) + entities.each do |key, value| + copy.gsub!( value, "&#{key};" ) unless entity_filter and + entity_filter.include?(entity) + end if entities + copy.gsub!( EREFERENCE, '&' ) + DEFAULT_ENTITIES.each do |key, value| + copy.gsub!( value[3], value[1] ) + end + copy + end + + # Unescapes all possible entities + def unnormalize( string, entities=nil, filter=nil ) + if string.include?("\r") + rv = string.gsub( Private::CARRIAGE_RETURN_NEWLINE_PATTERN, "\n" ) + else + rv = string.dup + end + matches = rv.scan( REFERENCE_RE ) + return rv if matches.size == 0 + rv.gsub!( Private::CHARACTER_REFERENCES ) { + m=$1 + if m.start_with?("x") + code_point = Integer(m[1..-1], 16) + else + code_point = Integer(m, 10) + end + [code_point].pack('U*') + } + matches.collect!{|x|x[0]}.compact! + if filter + matches.reject! do |entity_reference| + filter.include?(entity_reference) + end + end + if matches.size > 0 + matches.tally.each do |entity_reference, n| + entity_expansion_count_before = @entity_expansion_count + entity_value = entity( entity_reference, entities ) + if entity_value + if n > 1 + entity_expansion_count_delta = + @entity_expansion_count - entity_expansion_count_before + record_entity_expansion(entity_expansion_count_delta * (n - 1)) + end + re = Private::DEFAULT_ENTITIES_PATTERNS[entity_reference] || /&#{entity_reference};/ + rv.gsub!( re, entity_value ) + if rv.bytesize > @entity_expansion_text_limit + raise "entity expansion has grown too large" + end + else + er = DEFAULT_ENTITIES[entity_reference] + rv.gsub!( er[0], er[2] ) if er + end + end + rv.gsub!( Private::DEFAULT_ENTITIES_PATTERNS['amp'], '&' ) + end + rv + end + + private + def add_namespace(prefix, uri) + @namespaces_restore_stack.last[prefix] = @namespaces[prefix] + if uri.nil? + @namespaces.delete(prefix) + else + @namespaces[prefix] = uri + end + end + + def push_namespaces_restore + namespaces_restore = {} + @namespaces_restore_stack.push(namespaces_restore) + namespaces_restore + end + + def pop_namespaces_restore + namespaces_restore = @namespaces_restore_stack.pop + namespaces_restore.each do |prefix, uri| + if uri.nil? + @namespaces.delete(prefix) + else + @namespaces[prefix] = uri + end + end + end + + def record_entity_expansion(delta=1) + @entity_expansion_count += delta + if @entity_expansion_count > @entity_expansion_limit + raise "number of entity expansions exceeded, processing aborted." + end + end + + def need_source_encoding_update?(xml_declaration_encoding) + return false if xml_declaration_encoding.nil? + return false if /\AUTF-16\z/i =~ xml_declaration_encoding + true + end + + def normalize_xml_declaration_encoding(xml_declaration_encoding) + /\AUTF-16(?:BE|LE)\z/i.match?(xml_declaration_encoding) ? "UTF-16" : nil + end + + def parse_name(base_error_message) + md = @source.match(Private::NAME_PATTERN, true) + unless md + if @source.match?(/\S/um) + message = "#{base_error_message}: invalid name" + else + message = "#{base_error_message}: name is missing" + end + raise REXML::ParseException.new(message, @source) + end + md[0] + end + + def parse_id(base_error_message, + accept_external_id:, + accept_public_id:) + if accept_external_id and (md = @source.match(EXTERNAL_ID_PUBLIC, true)) + pubid = system = nil + pubid_literal = md[1] + pubid = pubid_literal[1..-2] if pubid_literal # Remove quote + system_literal = md[2] + system = system_literal[1..-2] if system_literal # Remove quote + ["PUBLIC", pubid, system] + elsif accept_public_id and (md = @source.match(PUBLIC_ID, true)) + pubid = system = nil + pubid_literal = md[1] + pubid = pubid_literal[1..-2] if pubid_literal # Remove quote + ["PUBLIC", pubid, nil] + elsif accept_external_id and (md = @source.match(EXTERNAL_ID_SYSTEM, true)) + system = nil + system_literal = md[1] + system = system_literal[1..-2] if system_literal # Remove quote + ["SYSTEM", nil, system] + else + details = parse_id_invalid_details(accept_external_id: accept_external_id, + accept_public_id: accept_public_id) + message = "#{base_error_message}: #{details}" + raise REXML::ParseException.new(message, @source) + end + end + + def parse_id_invalid_details(accept_external_id:, + accept_public_id:) + public = /\A\s*PUBLIC/um + system = /\A\s*SYSTEM/um + if (accept_external_id or accept_public_id) and @source.match?(/#{public}/um) + if @source.match?(/#{public}(?:\s+[^'"]|\s*[\[>])/um) + return "public ID literal is missing" + end + unless @source.match?(/#{public}\s+#{PUBIDLITERAL}/um) + return "invalid public ID literal" + end + if accept_public_id + if @source.match?(/#{public}\s+#{PUBIDLITERAL}\s+[^'"]/um) + return "system ID literal is missing" + end + unless @source.match?(/#{public}\s+#{PUBIDLITERAL}\s+#{SYSTEMLITERAL}/um) + return "invalid system literal" + end + "garbage after system literal" + else + "garbage after public ID literal" + end + elsif accept_external_id and @source.match?(/#{system}/um) + if @source.match?(/#{system}(?:\s+[^'"]|\s*[\[>])/um) + return "system literal is missing" + end + unless @source.match?(/#{system}\s+#{SYSTEMLITERAL}/um) + return "invalid system literal" + end + "garbage after system literal" + else + unless @source.match?(/\A\s*(?:PUBLIC|SYSTEM)\s/um) + return "invalid ID type" + end + "ID type is missing" + end + end + + def process_comment + text = @source.read_until("-->") + unless text.chomp!("-->") + raise REXML::ParseException.new("Unclosed comment: Missing end '-->'", @source) + end + + if text.include? "--" or text.end_with?("-") + raise REXML::ParseException.new("Malformed comment", @source) + end + text + end + + def process_instruction + name = parse_name("Malformed XML: Invalid processing instruction node") + if name == "xml" + xml_declaration + else # PITarget + if @source.skip_spaces # e.g. <?name content?> + start_position = @source.position + content = @source.read_until("?>") + unless content.chomp!("?>") + @source.position = start_position + raise ParseException.new("Malformed XML: Unclosed processing instruction: <#{name}>", @source) + end + else # e.g. <?name?> + content = nil + unless @source.match?("?>", true) + raise ParseException.new("Malformed XML: Unclosed processing instruction: <#{name}>", @source) + end + end + [:processing_instruction, name, content] + end + end + + def xml_declaration + unless @version.nil? + raise ParseException.new("Malformed XML: XML declaration is duplicated", @source) + end + if @document_status + raise ParseException.new("Malformed XML: XML declaration is not at the start", @source) + end + unless @source.skip_spaces + raise ParseException.new("Malformed XML: XML declaration misses spaces before version", @source) + end + unless @source.match?("version", true) + raise ParseException.new("Malformed XML: XML declaration misses version", @source) + end + @version = parse_attribute_value_with_equal("xml") + unless @source.skip_spaces + unless @source.match?("?>", true) + raise ParseException.new("Malformed XML: Unclosed XML declaration", @source) + end + encoding = normalize_xml_declaration_encoding(@source.encoding) + return [ :xmldecl, @version, encoding, nil ] # e.g. <?xml version="1.0"?> + end + + if @source.match?("encoding", true) + encoding = parse_attribute_value_with_equal("xml") + unless @source.skip_spaces + unless @source.match?("?>", true) + raise ParseException.new("Malformed XML: Unclosed XML declaration", @source) + end + if need_source_encoding_update?(encoding) + @source.encoding = encoding + end + encoding ||= normalize_xml_declaration_encoding(@source.encoding) + return [ :xmldecl, @version, encoding, nil ] # e.g. <?xml version="1.1" encoding="UTF-8"?> + end + end + + if @source.match?("standalone", true) + standalone = parse_attribute_value_with_equal("xml") + case standalone + when "yes", "no" + else + raise ParseException.new("Malformed XML: XML declaration standalone is not yes or no : <#{standalone}>", @source) + end + end + @source.skip_spaces + unless @source.match?("?>", true) + raise ParseException.new("Malformed XML: Unclosed XML declaration", @source) + end + + if need_source_encoding_update?(encoding) + @source.encoding = encoding + end + encoding ||= normalize_xml_declaration_encoding(@source.encoding) + + # e.g. <?xml version="1.0" ?> + # <?xml version="1.1" encoding="UTF-8" ?> + # <?xml version="1.1" standalone="yes"?> + # <?xml version="1.1" encoding="UTF-8" standalone="yes" ?> + [ :xmldecl, @version, encoding, standalone ] + end + + if StringScanner::Version < "3.1.1" + def scan_quote + @source.match(/(['"])/, true)&.[](1) + end + else + def scan_quote + case @source.peek_byte + when 34 # '"'.ord + @source.scan_byte + '"' + when 39 # "'".ord + @source.scan_byte + "'" + else + nil + end + end + end + + def parse_attribute_value_with_equal(name) + unless @source.match?(Private::EQUAL_PATTERN, true) + message = "Missing attribute equal: <#{name}>" + raise REXML::ParseException.new(message, @source) + end + unless quote = scan_quote + message = "Missing attribute value start quote: <#{name}>" + raise REXML::ParseException.new(message, @source) + end + start_position = @source.position + value = @source.read_until(quote) + unless value.chomp!(quote) + @source.position = start_position + message = "Missing attribute value end quote: <#{name}>: <#{quote}>" + raise REXML::ParseException.new(message, @source) + end + value + end + + def parse_attributes(prefixes) + attributes = {} + expanded_names = {} + closed = false + while true + if @source.match?(">", true) + return attributes, closed + elsif @source.match?("/>", true) + closed = true + return attributes, closed + elsif match = @source.match(QNAME, true) + name = match[1] + prefix = match[2] + local_part = match[3] + value = parse_attribute_value_with_equal(name) + @source.skip_spaces + if prefix == "xmlns" + if local_part == "xml" + if value != Private::XML_PREFIXED_NAMESPACE + msg = "The 'xml' prefix must not be bound to any other namespace "+ + "(http://www.w3.org/TR/REC-xml-names/#ns-decl)" + raise REXML::ParseException.new( msg, @source, self ) + end + elsif local_part == "xmlns" + msg = "The 'xmlns' prefix must not be declared "+ + "(http://www.w3.org/TR/REC-xml-names/#ns-decl)" + raise REXML::ParseException.new( msg, @source, self) + end + add_namespace(local_part, value) + elsif prefix + prefixes << prefix unless prefix == "xml" + end + + if attributes[name] + msg = "Duplicate attribute #{name.inspect}" + raise REXML::ParseException.new(msg, @source, self) + end + + unless prefix == "xmlns" + uri = @namespaces[prefix] + expanded_name = [uri, local_part] + existing_prefix = expanded_names[expanded_name] + if existing_prefix + message = "Namespace conflict in adding attribute " + + "\"#{local_part}\": " + + "Prefix \"#{existing_prefix}\" = \"#{uri}\" and " + + "prefix \"#{prefix}\" = \"#{uri}\"" + raise REXML::ParseException.new(message, @source, self) + end + expanded_names[expanded_name] = prefix + end + + attributes[name] = value + else + message = "Invalid attribute name: <#{@source.buffer.split(%r{[/>\s]}).first}>" + raise REXML::ParseException.new(message, @source) + end + end + end + end + end +end + +=begin + case event[0] + when :start_element + when :text + when :end_element + when :processing_instruction + when :cdata + when :comment + when :xmldecl + when :start_doctype + when :end_doctype + when :externalentity + when :elementdecl + when :entity + when :attlistdecl + when :notationdecl + when :end_doctype + end +=end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/lightparser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/lightparser.rb new file mode 100644 index 0000000..bdc0827 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/lightparser.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: false +require_relative 'streamparser' +require_relative 'baseparser' +require_relative '../light/node' + +module REXML + module Parsers + class LightParser + def initialize stream + @stream = stream + @parser = REXML::Parsers::BaseParser.new( stream ) + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def rewind + @stream.rewind + @parser.stream = @stream + end + + def parse + root = context = [ :document ] + while true + event = @parser.pull + case event[0] + when :end_document + break + when :start_element, :start_doctype + new_node = event + context << new_node + new_node[1,0] = [context] + context = new_node + when :end_element, :end_doctype + context = context[1] + else + new_node = event + context << new_node + new_node[1,0] = [context] + end + end + root + end + end + + # An element is an array. The array contains: + # 0 The parent element + # 1 The tag name + # 2 A hash of attributes + # 3..-1 The child elements + # An element is an array of size > 3 + # Text is a String + # PIs are [ :processing_instruction, target, data ] + # Comments are [ :comment, data ] + # DocTypes are DocType structs + # The root is an array with XMLDecls, Text, DocType, Array, Text + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/pullparser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/pullparser.rb new file mode 100644 index 0000000..e0b1e94 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/pullparser.rb @@ -0,0 +1,213 @@ +# frozen_string_literal: false +require 'forwardable' + +require_relative '../parseexception' +require_relative 'baseparser' +require_relative '../xmltokens' + +module REXML + module Parsers + # = Using the Pull Parser + # <em>This API is experimental, and subject to change.</em> + # parser = PullParser.new( "<a>text<b att='val'/>txet</a>" ) + # while parser.has_next? + # res = parser.next + # puts res[1]['att'] if res.start_tag? and res[0] == 'b' + # end + # See the PullEvent class for information on the content of the results. + # The data is identical to the arguments passed for the various events to + # the StreamListener API. + # + # Notice that: + # parser = PullParser.new( "<a>BAD DOCUMENT" ) + # while parser.has_next? + # res = parser.next + # raise res[1] if res.error? + # end + # + # Nat Price gave me some good ideas for the API. + class PullParser + include XMLTokens + extend Forwardable + + def_delegators( :@parser, :has_next? ) + def_delegators( :@parser, :entity ) + def_delegators( :@parser, :empty? ) + def_delegators( :@parser, :source ) + + def initialize stream + @entities = {} + @listeners = nil + @parser = BaseParser.new( stream ) + @my_stack = [] + end + + def add_listener( listener ) + @listeners = [] unless @listeners + @listeners << listener + end + + def entity_expansion_count + @parser.entity_expansion_count + end + + def entity_expansion_limit=( limit ) + @parser.entity_expansion_limit = limit + end + + def entity_expansion_text_limit=( limit ) + @parser.entity_expansion_text_limit = limit + end + + def each + while has_next? + yield self.pull + end + end + + def peek depth=0 + if @my_stack.length <= depth + (depth - @my_stack.length + 1).times { + e = PullEvent.new(@parser.pull) + @my_stack.push(e) + } + end + @my_stack[depth] + end + + def pull + return @my_stack.shift if @my_stack.length > 0 + + event = @parser.pull + case event[0] + when :entitydecl + @entities[ event[1] ] = + event[2] unless event[2] =~ /PUBLIC|SYSTEM/ + when :text + unnormalized = @parser.unnormalize( event[1], @entities ) + event << unnormalized + end + PullEvent.new( event ) + end + + def unshift token + @my_stack.unshift token + end + + def reset + @parser.reset + end + end + + # A parsing event. The contents of the event are accessed as an +Array?, + # and the type is given either by the ...? methods, or by accessing the + # +type+ accessor. The contents of this object vary from event to event, + # but are identical to the arguments passed to +StreamListener+s for each + # event. + class PullEvent + # The type of this event. Will be one of :tag_start, :tag_end, :text, + # :processing_instruction, :comment, :doctype, :attlistdecl, :entitydecl, + # :notationdecl, :entity, :cdata, :xmldecl, or :error. + def initialize(arg) + @contents = arg + end + + def []( start, endd=nil) + if start.kind_of? Range + @contents.slice( start.begin+1 .. start.end ) + elsif start.kind_of? Numeric + if endd.nil? + @contents.slice( start+1 ) + else + @contents.slice( start+1, endd ) + end + else + raise "Illegal argument #{start.inspect} (#{start.class})" + end + end + + def event_type + @contents[0] + end + + # Content: [ String tag_name, Hash attributes ] + def start_element? + @contents[0] == :start_element + end + + # Content: [ String tag_name ] + def end_element? + @contents[0] == :end_element + end + + # Content: [ String raw_text, String unnormalized_text ] + def text? + @contents[0] == :text + end + + # Content: [ String text ] + def instruction? + @contents[0] == :processing_instruction + end + + # Content: [ String text ] + def comment? + @contents[0] == :comment + end + + # Content: [ String name, String pub_sys, String long_name, String uri ] + def doctype? + @contents[0] == :start_doctype + end + + # Content: [ String text ] + def attlistdecl? + @contents[0] == :attlistdecl + end + + # Content: [ String text ] + def elementdecl? + @contents[0] == :elementdecl + end + + # Due to the wonders of DTDs, an entity declaration can be just about + # anything. There's no way to normalize it; you'll have to interpret the + # content yourself. However, the following is true: + # + # * If the entity declaration is an internal entity: + # [ String name, String value ] + # Content: [ String text ] + def entitydecl? + @contents[0] == :entitydecl + end + + # Content: [ String text ] + def notationdecl? + @contents[0] == :notationdecl + end + + # Content: [ String text ] + def entity? + @contents[0] == :entity + end + + # Content: [ String text ] + def cdata? + @contents[0] == :cdata + end + + # Content: [ String version, String encoding, String standalone ] + def xmldecl? + @contents[0] == :xmldecl + end + + def error? + @contents[0] == :error + end + + def inspect + @contents[0].to_s + ": " + @contents[1..-1].inspect + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/sax2parser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/sax2parser.rb new file mode 100644 index 0000000..a51477d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/sax2parser.rb @@ -0,0 +1,270 @@ +# frozen_string_literal: false +require_relative 'baseparser' +require_relative '../parseexception' +require_relative '../namespace' +require_relative '../text' + +module REXML + module Parsers + # SAX2Parser + class SAX2Parser + def initialize source + @parser = BaseParser.new(source) + @listeners = [] + @procs = [] + @namespace_stack = [] + @has_listeners = false + @tag_stack = [] + @entities = {} + end + + def source + @parser.source + end + + def entity_expansion_count + @parser.entity_expansion_count + end + + def entity_expansion_limit=( limit ) + @parser.entity_expansion_limit = limit + end + + def entity_expansion_text_limit=( limit ) + @parser.entity_expansion_text_limit = limit + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + # Listen arguments: + # + # Symbol, Array, Block + # Listen to Symbol events on Array elements + # Symbol, Block + # Listen to Symbol events + # Array, Listener + # Listen to all events on Array elements + # Array, Block + # Listen to :start_element events on Array elements + # Listener + # Listen to All events + # + # Symbol can be one of: :start_element, :end_element, + # :start_prefix_mapping, :end_prefix_mapping, :characters, + # :processing_instruction, :doctype, :attlistdecl, :elementdecl, + # :entitydecl, :notationdecl, :cdata, :xmldecl, :comment + # + # There is an additional symbol that can be listened for: :progress. + # This will be called for every event generated, passing in the current + # stream position. + # + # Array contains regular expressions or strings which will be matched + # against fully qualified element names. + # + # Listener must implement the methods in SAX2Listener + # + # Block will be passed the same arguments as a SAX2Listener method would + # be, where the method name is the same as the matched Symbol. + # See the SAX2Listener for more information. + def listen( *args, &blok ) + if args[0].kind_of? Symbol + if args.size == 2 + args[1].each { |match| @procs << [args[0], match, blok] } + else + add( [args[0], nil, blok] ) + end + elsif args[0].kind_of? Array + if args.size == 2 + args[0].each { |match| add( [nil, match, args[1]] ) } + else + args[0].each { |match| add( [ :start_element, match, blok ] ) } + end + else + add([nil, nil, args[0]]) + end + end + + def deafen( listener=nil, &blok ) + if listener + @listeners.delete_if {|item| item[-1] == listener } + @has_listeners = false if @listeners.size == 0 + else + @procs.delete_if {|item| item[-1] == blok } + end + end + + def parse + @procs.each { |sym,match,block| block.call if sym == :start_document } + @listeners.each { |sym,match,block| + block.start_document if sym == :start_document or sym.nil? + } + context = [] + while true + event = @parser.pull + case event[0] + when :end_document + handle( :end_document ) + break + when :start_doctype + handle( :doctype, *event[1..-1]) + when :end_doctype + context = context[1] + when :start_element + @tag_stack.push(event[1]) + # find the observers for namespaces + procs = get_procs( :start_prefix_mapping, event[1] ) + listeners = get_listeners( :start_prefix_mapping, event[1] ) + if procs or listeners + # break out the namespace declarations + # The attributes live in event[2] + event[2].each {|n, v| event[2][n] = @parser.normalize(v)} + nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ } + nsdecl.collect! { |n, value| [ n[6..-1], value ] } + @namespace_stack.push({}) + nsdecl.each do |n,v| + @namespace_stack[-1][n] = v + # notify observers of namespaces + procs.each { |ob| ob.call( n, v ) } if procs + listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners + end + end + event[1] =~ Namespace::NAMESPLIT + prefix = $1 + local = $2 + uri = get_namespace(prefix) + # find the observers for start_element + procs = get_procs( :start_element, event[1] ) + listeners = get_listeners( :start_element, event[1] ) + # notify observers + procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs + listeners.each { |ob| + ob.start_element( uri, local, event[1], event[2] ) + } if listeners + when :end_element + @tag_stack.pop + event[1] =~ Namespace::NAMESPLIT + prefix = $1 + local = $2 + uri = get_namespace(prefix) + # find the observers for start_element + procs = get_procs( :end_element, event[1] ) + listeners = get_listeners( :end_element, event[1] ) + # notify observers + procs.each { |ob| ob.call( uri, local, event[1] ) } if procs + listeners.each { |ob| + ob.end_element( uri, local, event[1] ) + } if listeners + + namespace_mapping = @namespace_stack.pop + # find the observers for namespaces + procs = get_procs( :end_prefix_mapping, event[1] ) + listeners = get_listeners( :end_prefix_mapping, event[1] ) + if procs or listeners + namespace_mapping.each do |ns_prefix, ns_uri| + # notify observers of namespaces + procs.each { |ob| ob.call( ns_prefix ) } if procs + listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners + end + end + when :text + unnormalized = @parser.unnormalize( event[1], @entities ) + handle( :characters, unnormalized ) + when :entitydecl + handle_entitydecl( event ) + when :processing_instruction, :comment, :attlistdecl, + :elementdecl, :cdata, :notationdecl, :xmldecl + handle( *event ) + end + handle( :progress, @parser.position ) + end + end + + private + def handle( symbol, *arguments ) + tag = @tag_stack[-1] + procs = get_procs( symbol, tag ) + listeners = get_listeners( symbol, tag ) + # notify observers + procs.each { |ob| ob.call( *arguments ) } if procs + listeners.each { |l| + l.send( symbol.to_s, *arguments ) + } if listeners + end + + def handle_entitydecl( event ) + @entities[ event[1] ] = event[2] if event.size == 3 + parameter_reference_p = false + case event[2] + when "SYSTEM" + if event.size == 5 + if event.last == "%" + parameter_reference_p = true + else + event[4, 0] = "NDATA" + end + end + when "PUBLIC" + if event.size == 6 + if event.last == "%" + parameter_reference_p = true + else + event[5, 0] = "NDATA" + end + end + else + parameter_reference_p = (event.size == 4) + end + event[1, 0] = event.pop if parameter_reference_p + handle( event[0], event[1..-1] ) + end + + # The following methods are duplicates, but it is faster than using + # a helper + def get_procs( symbol, name ) + return nil if @procs.size == 0 + @procs.find_all do |sym, match, block| + ( + (sym.nil? or symbol == sym) and + ((name.nil? and match.nil?) or match.nil? or ( + (name == match) or + (match.kind_of? Regexp and name =~ match) + ) + ) + ) + end.collect{|x| x[-1]} + end + def get_listeners( symbol, name ) + return nil if @listeners.size == 0 + @listeners.find_all do |sym, match, block| + ( + (sym.nil? or symbol == sym) and + ((name.nil? and match.nil?) or match.nil? or ( + (name == match) or + (match.kind_of? Regexp and name =~ match) + ) + ) + ) + end.collect{|x| x[-1]} + end + + def add( pair ) + if pair[-1].respond_to? :call + @procs << pair unless @procs.include? pair + else + @listeners << pair unless @listeners.include? pair + @has_listeners = true + end + end + + def get_namespace( prefix ) + return nil if @namespace_stack.empty? + + uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) || + (@namespace_stack.find { |ns| not ns[nil].nil? }) + uris[-1][prefix] unless uris.nil? or 0 == uris.size + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/streamparser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/streamparser.rb new file mode 100644 index 0000000..6c64d97 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/streamparser.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: false +require_relative "baseparser" + +module REXML + module Parsers + class StreamParser + def initialize source, listener + @listener = listener + @parser = BaseParser.new( source ) + @entities = {} + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def entity_expansion_count + @parser.entity_expansion_count + end + + def entity_expansion_limit=( limit ) + @parser.entity_expansion_limit = limit + end + + def entity_expansion_text_limit=( limit ) + @parser.entity_expansion_text_limit = limit + end + + def parse + # entity string + while true + event = @parser.pull + case event[0] + when :end_document + return + when :start_element + attrs = event[2].each do |n, v| + event[2][n] = @parser.unnormalize( v ) + end + @listener.tag_start( event[1], attrs ) + when :end_element + @listener.tag_end( event[1] ) + when :text + unnormalized = @parser.unnormalize( event[1], @entities ) + @listener.text( unnormalized ) + when :processing_instruction + @listener.instruction( *event[1,2] ) + when :start_doctype + @listener.doctype( *event[1..-1] ) + when :end_doctype + # FIXME: remove this condition for milestone:3.2 + @listener.doctype_end if @listener.respond_to? :doctype_end + when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl + @listener.send( event[0].to_s, *event[1..-1] ) + when :entitydecl, :notationdecl + @entities[ event[1] ] = event[2] if event.size == 3 + @listener.send( event[0].to_s, event[1..-1] ) + when :externalentity + entity_reference = event[1] + content = entity_reference.gsub(/\A%|;\z/, "") + @listener.entity(content) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb new file mode 100644 index 0000000..4565a40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: false +require_relative '../validation/validationexception' +require_relative '../undefinednamespaceexception' + +module REXML + module Parsers + class TreeParser + def initialize( source, build_context = Document.new ) + @build_context = build_context + @parser = Parsers::BaseParser.new( source ) + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def parse + entities = nil + begin + while true + event = @parser.pull + #STDERR.puts "TREEPARSER GOT #{event.inspect}" + case event[0] + when :end_document + return + when :start_element + el = @build_context = @build_context.add_element( event[1] ) + event[2].each do |key, value| + el.attributes[key]=Attribute.new(key,value,self) + end + when :end_element + @build_context = @build_context.parent + when :text + if @build_context[-1].instance_of? Text + @build_context[-1] << event[1] + else + @build_context.add( + Text.new(event[1], @build_context.whitespace, nil, true) + ) unless ( + @build_context.ignore_whitespace_nodes and + event[1].strip.size==0 + ) + end + when :comment + c = Comment.new( event[1] ) + @build_context.add( c ) + when :cdata + c = CData.new( event[1] ) + @build_context.add( c ) + when :processing_instruction + @build_context.add( Instruction.new( event[1], event[2] ) ) + when :end_doctype + entities.each { |k,v| entities[k] = @build_context.entities[k].value } + @build_context = @build_context.parent + when :start_doctype + doctype = DocType.new( event[1..-1], @build_context ) + @build_context = doctype + entities = {} + when :attlistdecl + n = AttlistDecl.new( event[1..-1] ) + @build_context.add( n ) + when :externalentity + n = ExternalEntity.new( event[1] ) + @build_context.add( n ) + when :elementdecl + n = ElementDecl.new( event[1] ) + @build_context.add(n) + when :entitydecl + entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/ + @build_context.add(Entity.new(event)) + when :notationdecl + n = NotationDecl.new( *event[1..-1] ) + @build_context.add( n ) + when :xmldecl + x = XMLDecl.new( event[1], event[2], event[3] ) + @build_context.add( x ) + end + end + rescue REXML::Validation::ValidationException + raise + rescue REXML::ParseException + raise + rescue + raise ParseException.new( $!.message, @parser.source, @parser, $! ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/ultralightparser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/ultralightparser.rb new file mode 100644 index 0000000..e0029f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/ultralightparser.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: false +require_relative 'streamparser' +require_relative 'baseparser' + +module REXML + module Parsers + class UltraLightParser + def initialize stream + @stream = stream + @parser = REXML::Parsers::BaseParser.new( stream ) + end + + def add_listener( listener ) + @parser.add_listener( listener ) + end + + def rewind + @stream.rewind + @parser.stream = @stream + end + + def parse + root = context = [] + while true + event = @parser.pull + case event[0] + when :end_document + break + when :end_doctype + context = context[1] + when :start_element, :start_doctype + context << event + event[1,0] = [context] + context = event + when :end_element + context = context[1] + else + context << event + end + end + root + end + end + + # An element is an array. The array contains: + # 0 The parent element + # 1 The tag name + # 2 A hash of attributes + # 3..-1 The child elements + # An element is an array of size > 3 + # Text is a String + # PIs are [ :processing_instruction, target, data ] + # Comments are [ :comment, data ] + # DocTypes are DocType structs + # The root is an array with XMLDecls, Text, DocType, Array, Text + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/xpathparser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/xpathparser.rb new file mode 100644 index 0000000..a6d76fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/parsers/xpathparser.rb @@ -0,0 +1,739 @@ +# frozen_string_literal: false + +require_relative '../namespace' +require_relative '../xmltokens' + +module REXML + module Parsers + # You don't want to use this class. Really. Use XPath, which is a wrapper + # for this class. Believe me. You don't want to poke around in here. + # There is strange, dark magic at work in this code. Beware. Go back! Go + # back while you still can! + class XPathParser + include XMLTokens + LITERAL = /^'([^']*)'|^"([^"]*)"/u + + def namespaces=( namespaces ) + Functions::namespace_context = namespaces + @namespaces = namespaces + end + + def parse path + path = path.dup + path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces + path.gsub!( /\s+([\]\)])/, '\1') + parsed = [] + rest = OrExpr(path, parsed) + if rest + unless rest.strip.empty? + raise ParseException.new("Garbage component exists at the end: " + + "<#{rest}>: <#{path}>") + end + end + parsed + end + + def predicate path + parsed = [] + Predicate( "[#{path}]", parsed ) + parsed + end + + def abbreviate(path_or_parsed) + if path_or_parsed.kind_of?(String) + parsed = parse(path_or_parsed) + else + parsed = path_or_parsed + end + components = [] + component = nil + while parsed.size > 0 + op = parsed.shift + case op + when :node + component << "node()" + when :attribute + component = "@" + components << component + when :child + component = "" + components << component + when :descendant_or_self + next_op = parsed[0] + if next_op == :node + parsed.shift + component = "" + components << component + else + component = "descendant-or-self::" + components << component + end + when :self + next_op = parsed[0] + if next_op == :node + parsed.shift + components << "." + else + component = "self::" + components << component + end + when :parent + next_op = parsed[0] + if next_op == :node + parsed.shift + components << ".." + else + component = "parent::" + components << component + end + when :any + component << "*" + when :text + component << "text()" + when :following, :following_sibling, + :ancestor, :ancestor_or_self, :descendant, + :namespace, :preceding, :preceding_sibling + component = op.to_s.tr("_", "-") << "::" + components << component + when :qname + prefix = parsed.shift + name = parsed.shift + component << prefix+":" if prefix.size > 0 + component << name + when :predicate + component << '[' + component << predicate_to_path(parsed.shift) {|x| abbreviate(x)} + component << ']' + when :document + components << "" + when :function + component << parsed.shift + component << "( " + component << predicate_to_path(parsed.shift[0]) {|x| abbreviate(x)} + component << " )" + when :literal + component << quote_literal(parsed.shift) + else + component << "UNKNOWN(" + component << op.inspect + component << ")" + end + end + case components + when [""] + "/" + when ["", ""] + "//" + else + components.join("/") + end + end + + def expand(path_or_parsed) + if path_or_parsed.kind_of?(String) + parsed = parse(path_or_parsed) + else + parsed = path_or_parsed + end + path = "" + document = false + while parsed.size > 0 + op = parsed.shift + case op + when :node + path << "node()" + when :attribute, :child, :following, :following_sibling, + :ancestor, :ancestor_or_self, :descendant, :descendant_or_self, + :namespace, :preceding, :preceding_sibling, :self, :parent + path << "/" unless path.size == 0 + path << op.to_s.tr("_", "-") + path << "::" + when :any + path << "*" + when :qname + prefix = parsed.shift + name = parsed.shift + path << prefix+":" if prefix.size > 0 + path << name + when :predicate + path << '[' + path << predicate_to_path( parsed.shift ) { |x| expand(x) } + path << ']' + when :document + document = true + else + path << "UNKNOWN(" + path << op.inspect + path << ")" + end + end + path = "/"+path if document + path + end + + def predicate_to_path(parsed, &block) + path = "" + case parsed[0] + when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union + op = parsed.shift + case op + when :eq + op = "=" + when :lt + op = "<" + when :gt + op = ">" + when :lteq + op = "<=" + when :gteq + op = ">=" + when :neq + op = "!=" + when :union + op = "|" + end + left = predicate_to_path( parsed.shift, &block ) + right = predicate_to_path( parsed.shift, &block ) + path << left + path << " " + path << op.to_s + path << " " + path << right + when :function + parsed.shift + name = parsed.shift + path << name + path << "(" + parsed.shift.each_with_index do |argument, i| + path << ", " if i > 0 + path << predicate_to_path(argument, &block) + end + path << ")" + when :literal + parsed.shift + path << quote_literal(parsed.shift) + else + path << yield( parsed ) + end + path.squeeze(" ") + end + # For backward compatibility + alias_method :preciate_to_string, :predicate_to_path + + private + def quote_literal( literal ) + case literal + when String + # XPath 1.0 does not support escape characters. + # Assumes literal does not contain both single and double quotes. + if literal.include?("'") + "\"#{literal}\"" + else + "'#{literal}'" + end + else + literal.inspect + end + end + + #LocationPath + # | RelativeLocationPath + # | '/' RelativeLocationPath? + # | '//' RelativeLocationPath + def LocationPath path, parsed + path = path.lstrip + if path[0] == ?/ + parsed << :document + if path[1] == ?/ + parsed << :descendant_or_self + parsed << :node + path = path[2..-1] + else + path = path[1..-1] + end + end + RelativeLocationPath( path, parsed ) if path.size > 0 + end + + #RelativeLocationPath + # | Step + # | (AXIS_NAME '::' | '@' | '') AxisSpecifier + # NodeTest + # Predicate + # | '.' | '..' AbbreviatedStep + # | RelativeLocationPath '/' Step + # | RelativeLocationPath '//' Step + AXIS = /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/ + def RelativeLocationPath path, parsed + loop do + original_path = path + path = path.lstrip + + return original_path if path.empty? + + # (axis or @ or <child::>) nodetest predicate > + # OR > / Step + # (. or ..) > + if path[0] == ?. + if path[1] == ?. + parsed << :parent + parsed << :node + path = path[2..-1] + else + parsed << :self + parsed << :node + path = path[1..-1] + end + else + path_before_axis_specifier = path + parsed_not_abberviated = [] + if path[0] == ?@ + parsed_not_abberviated << :attribute + path = path[1..-1] + # Goto Nodetest + elsif path =~ AXIS + parsed_not_abberviated << $1.tr('-','_').intern + path = $' + # Goto Nodetest + else + parsed_not_abberviated << :child + end + + path_before_node_test = path + path = NodeTest(path, parsed_not_abberviated) + if path == path_before_node_test + return path_before_axis_specifier + end + path = Predicate(path, parsed_not_abberviated) + + parsed.concat(parsed_not_abberviated) + end + + original_path = path + path = path.lstrip + return original_path if path.empty? + + return original_path if path[0] != ?/ + + if path[1] == ?/ + parsed << :descendant_or_self + parsed << :node + path = path[2..-1] + else + path = path[1..-1] + end + end + end + + # Returns a 1-1 map of the nodeset + # The contents of the resulting array are either: + # true/false, if a positive match + # String, if a name match + #NodeTest + # | ('*' | NCNAME ':' '*' | QNAME) NameTest + # | '*' ':' NCNAME NameTest since XPath 2.0 + # | NODE_TYPE '(' ')' NodeType + # | PI '(' LITERAL ')' PI + # | '[' expr ']' Predicate + PREFIX_WILDCARD = /^\*:(#{NCNAME_STR})/u + LOCAL_NAME_WILDCARD = /^(#{NCNAME_STR}):\*/u + QNAME = Namespace::NAMESPLIT + NODE_TYPE = /^(comment|text|node)\(\s*\)/m + PI = /^processing-instruction\(/ + def NodeTest path, parsed + original_path = path + path = path.lstrip + case path + when PREFIX_WILDCARD + prefix = nil + name = $1 + path = $' + parsed << :qname + parsed << prefix + parsed << name + when /^\*/ + path = $' + parsed << :any + when NODE_TYPE + type = $1 + path = $' + parsed << type.tr('-', '_').intern + when PI + path = $' + literal = nil + if path =~ /^\s*\)/ + path = $' + else + path =~ LITERAL + literal = $1 + path = $' + raise ParseException.new("Missing ')' after processing instruction") if path[0] != ?) + path = path[1..-1] + end + parsed << :processing_instruction + parsed << (literal || '') + when LOCAL_NAME_WILDCARD + prefix = $1 + path = $' + parsed << :namespace + parsed << prefix + when QNAME + prefix = $1 + name = $2 + path = $' + prefix = "" unless prefix + parsed << :qname + parsed << prefix + parsed << name + else + path = original_path + end + path + end + + # Filters the supplied nodeset on the predicate(s) + def Predicate path, parsed + original_path = path + path = path.lstrip + return original_path unless path[0] == ?[ + predicates = [] + while path[0] == ?[ + path, expr = get_group(path) + predicates << expr[1..-2] if expr + end + predicates.each{ |pred| + preds = [] + parsed << :predicate + parsed << preds + OrExpr(pred, preds) + } + path + end + + # The following return arrays of true/false, a 1-1 mapping of the + # supplied nodeset, except for axe(), which returns a filtered + # nodeset + + #| OrExpr S 'or' S AndExpr + #| AndExpr + def OrExpr path, parsed + n = [] + rest = AndExpr( path, n ) + if rest != path + while rest =~ /^\s*( or )/ + n = [ :or, n, [] ] + rest = AndExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| AndExpr S 'and' S EqualityExpr + #| EqualityExpr + def AndExpr path, parsed + n = [] + rest = EqualityExpr( path, n ) + if rest != path + while rest =~ /^\s*( and )/ + n = [ :and, n, [] ] + rest = EqualityExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| EqualityExpr ('=' | '!=') RelationalExpr + #| RelationalExpr + def EqualityExpr path, parsed + n = [] + rest = RelationalExpr( path, n ) + if rest != path + while rest =~ /^\s*(!?=)\s*/ + if $1[0] == ?! + n = [ :neq, n, [] ] + else + n = [ :eq, n, [] ] + end + rest = RelationalExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| RelationalExpr ('<' | '>' | '<=' | '>=') AdditiveExpr + #| AdditiveExpr + def RelationalExpr path, parsed + n = [] + rest = AdditiveExpr( path, n ) + if rest != path + while rest =~ /^\s*([<>]=?)\s*/ + if $1[0] == ?< + sym = "lt" + else + sym = "gt" + end + sym << "eq" if $1[-1] == ?= + n = [ sym.intern, n, [] ] + rest = AdditiveExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| AdditiveExpr ('+' | '-') MultiplicativeExpr + #| MultiplicativeExpr + def AdditiveExpr path, parsed + n = [] + rest = MultiplicativeExpr( path, n ) + if rest != path + while rest =~ /^\s*(\+|-)\s*/ + if $1[0] == ?+ + n = [ :plus, n, [] ] + else + n = [ :minus, n, [] ] + end + rest = MultiplicativeExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| MultiplicativeExpr ('*' | S ('div' | 'mod') S) UnaryExpr + #| UnaryExpr + def MultiplicativeExpr path, parsed + n = [] + rest = UnaryExpr( path, n ) + if rest != path + while rest =~ /^\s*(\*| div | mod )\s*/ + if $1[0] == ?* + n = [ :mult, n, [] ] + elsif $1.include?( "div" ) + n = [ :div, n, [] ] + else + n = [ :mod, n, [] ] + end + rest = UnaryExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace(n) + elsif n.size > 0 + parsed << n + end + rest + end + + #| '-' UnaryExpr + #| UnionExpr + def UnaryExpr path, parsed + path =~ /^(\-*)/ + path = $' + if $1 and (($1.size % 2) != 0) + mult = -1 + else + mult = 1 + end + parsed << :neg if mult < 0 + + n = [] + path = UnionExpr( path, n ) + parsed.concat( n ) + path + end + + #| UnionExpr '|' PathExpr + #| PathExpr + def UnionExpr path, parsed + n = [] + rest = PathExpr( path, n ) + if rest != path + while rest =~ /^\s*(\|)\s*/ + n = [ :union, n, [] ] + rest = PathExpr( $', n[-1] ) + end + end + if parsed.size == 0 and n.size != 0 + parsed.replace( n ) + elsif n.size > 0 + parsed << n + end + rest + end + + #| LocationPath + #| FilterExpr ('/' | '//') RelativeLocationPath + def PathExpr path, parsed + path = path.lstrip + n = [] + rest = FilterExpr( path, n ) + if rest != path + if rest and rest[0] == ?/ + rest = RelativeLocationPath(rest, n) + parsed.concat(n) + return rest + end + end + rest = LocationPath(rest, n) if rest =~ /\A[\/\.\@\[\w*]/ + parsed.concat(n) + rest + end + + #| FilterExpr Predicate + #| PrimaryExpr + def FilterExpr path, parsed + n = [] + path_before_primary_expr = path + path = PrimaryExpr(path, n) + return path_before_primary_expr if path == path_before_primary_expr + path = Predicate(path, n) + parsed.concat(n) + path + end + + #| VARIABLE_REFERENCE + #| '(' expr ')' + #| LITERAL + #| NUMBER + #| FunctionCall + VARIABLE_REFERENCE = /^\$(#{NAME_STR})/u + NUMBER = /^(\d*\.?\d+)/ + NT = /^comment|text|processing-instruction|node$/ + def PrimaryExpr path, parsed + case path + when VARIABLE_REFERENCE + varname = $1 + path = $' + parsed << :variable + parsed << varname + #arry << @variables[ varname ] + when /^(\w[-\w]*)(?:\()/ + fname = $1 + tmp = $' + return path if fname =~ NT + path = tmp + parsed << :function + parsed << fname + path = FunctionCall(path, parsed) + when NUMBER + varname = $1.nil? ? $2 : $1 + path = $' + parsed << :literal + parsed << (varname.include?('.') ? varname.to_f : varname.to_i) + when LITERAL + varname = $1.nil? ? $2 : $1 + path = $' + parsed << :literal + parsed << varname + when /^\(/ #/ + path, contents = get_group(path) + contents = contents[1..-2] + n = [] + OrExpr( contents, n ) + parsed.concat(n) + end + path + end + + #| FUNCTION_NAME '(' ( expr ( ',' expr )* )? ')' + def FunctionCall rest, parsed + path, arguments = parse_args(rest) + argset = [] + for argument in arguments + args = [] + OrExpr( argument, args ) + argset << args + end + parsed << argset + path + end + + # get_group( '[foo]bar' ) -> ['bar', '[foo]'] + def get_group string + ind = 0 + depth = 0 + st = string[0,1] + en = (st == "(" ? ")" : "]") + begin + case string[ind,1] + when st + depth += 1 + when en + depth -= 1 + end + ind += 1 + end while depth > 0 and ind < string.length + return nil unless depth==0 + [string[ind..-1], string[0..ind-1]] + end + + def parse_args( string ) + arguments = [] + ind = 0 + inquot = false + inapos = false + depth = 1 + begin + case string[ind] + when ?" + inquot = !inquot unless inapos + when ?' + inapos = !inapos unless inquot + else + unless inquot or inapos + case string[ind] + when ?( + depth += 1 + if depth == 1 + string = string[1..-1] + ind -= 1 + end + when ?) + depth -= 1 + if depth == 0 + s = string[0,ind].strip + arguments << s unless s == "" + string = string[ind+1..-1] + end + when ?, + if depth == 1 + s = string[0,ind].strip + arguments << s unless s == "" + string = string[ind+1..-1] + ind = -1 + end + end + end + end + ind += 1 + end while depth > 0 and ind < string.length + return nil unless depth==0 + [string,arguments] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/quickpath.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/quickpath.rb new file mode 100644 index 0000000..cded06f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/quickpath.rb @@ -0,0 +1,267 @@ +# frozen_string_literal: false +require_relative 'functions' +require_relative 'xmltokens' + +module REXML + class QuickPath + include Functions + include XMLTokens + + # A base Hash object to be used when initializing a + # default empty namespaces set. + EMPTY_HASH = {} + + def QuickPath::first element, path, namespaces=EMPTY_HASH + match(element, path, namespaces)[0] + end + + def QuickPath::each element, path, namespaces=EMPTY_HASH, &block + path = "*" unless path + match(element, path, namespaces).each( &block ) + end + + def QuickPath::match element, path, namespaces=EMPTY_HASH + raise "nil is not a valid xpath" unless path + results = nil + Functions::namespace_context = namespaces + case path + when /^\/([^\/]|$)/u + # match on root + path = path[1..-1] + return [element.root.parent] if path == '' + results = filter([element.root], path) + when /^[-\w]*::/u + results = filter([element], path) + when /^\*/u + results = filter(element.to_a, path) + when /^[\[!\w:]/u + # match on child + children = element.to_a + results = filter(children, path) + else + results = filter([element], path) + end + results + end + + # Given an array of nodes it filters the array based on the path. The + # result is that when this method returns, the array will contain elements + # which match the path + def QuickPath::filter elements, path + return elements if path.nil? or path == '' or elements.size == 0 + case path + when /^\/\//u # Descendant + axe( elements, "descendant-or-self", $' ) + when /^\/?\b(\w[-\w]*)\b::/u # Axe + axe( elements, $1, $' ) + when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child + rest = $' + results = [] + elements.each do |element| + results |= filter( element.to_a, rest ) + end + results + when /^\/?(\w[-\w]*)\(/u # / Function + function( elements, $1, $' ) + when Namespace::NAMESPLIT # Element name + name = $2 + ns = $1 + rest = $' + elements.delete_if do |element| + !(element.kind_of? Element and + (element.expanded_name == name or + (element.name == name and + element.namespace == Functions.namespace_context[ns]))) + end + filter( elements, rest ) + when /^\/\[/u + matches = [] + elements.each do |element| + matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element + end + matches + when /^\[/u # Predicate + predicate( elements, path ) + when /^\/?\.\.\./u # Ancestor + axe( elements, "ancestor", $' ) + when /^\/?\.\./u # Parent + filter( elements.collect{|e|e.parent}, $' ) + when /^\/?\./u # Self + filter( elements, $' ) + when /^\*/u # Any + results = [] + elements.each do |element| + results |= filter( [element], $' ) if element.kind_of? Element + #if element.kind_of? Element + # children = element.to_a + # children.delete_if { |child| !child.kind_of?(Element) } + # results |= filter( children, $' ) + #end + end + results + else + [] + end + end + + def QuickPath::axe( elements, axe_name, rest ) + matches = [] + matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u + case axe_name + when /^descendant/u + elements.each do |element| + matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element + end + when /^ancestor/u + elements.each do |element| + while element.parent + matches << element.parent + element = element.parent + end + end + matches = filter( matches, rest ) + when "self" + matches = filter( elements, rest ) + when "child" + elements.each do |element| + matches |= filter( element.to_a, rest ) if element.kind_of? Element + end + when "attribute" + elements.each do |element| + matches << element.attributes[ rest ] if element.kind_of? Element + end + when "parent" + matches = filter(elements.collect{|element| element.parent}.uniq, rest) + when "following-sibling" + matches = filter(elements.collect{|element| element.next_sibling}.uniq, + rest) + when "previous-sibling" + matches = filter(elements.collect{|element| + element.previous_sibling}.uniq, rest ) + end + matches.uniq + end + + OPERAND_ = '((?=(?:(?!and|or).)*[^\s<>=])[^\s<>=]+)' + # A predicate filters a node-set with respect to an axis to produce a + # new node-set. For each node in the node-set to be filtered, the + # PredicateExpr is evaluated with that node as the context node, with + # the number of nodes in the node-set as the context size, and with the + # proximity position of the node in the node-set with respect to the + # axis as the context position; if PredicateExpr evaluates to true for + # that node, the node is included in the new node-set; otherwise, it is + # not included. + # + # A PredicateExpr is evaluated by evaluating the Expr and converting + # the result to a boolean. If the result is a number, the result will + # be converted to true if the number is equal to the context position + # and will be converted to false otherwise; if the result is not a + # number, then the result will be converted as if by a call to the + # boolean function. Thus a location path para[3] is equivalent to + # para[position()=3]. + def QuickPath::predicate( elements, path ) + ind = 1 + bcount = 1 + while bcount > 0 + bcount += 1 if path[ind] == ?[ + bcount -= 1 if path[ind] == ?] + ind += 1 + end + ind -= 1 + predicate = path[1..ind-1] + rest = path[ind+1..-1] + + # have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c' + # + predicate.gsub!( + /#{OPERAND_}\s*([<>=])\s*#{OPERAND_}\s*([<>=])\s*#{OPERAND_}/u, + '\1 \2 \3 and \3 \4 \5' ) + # Let's do some Ruby trickery to avoid some work: + predicate.gsub!( /&/u, "&&" ) + predicate.gsub!( /=/u, "==" ) + predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' ) + predicate.gsub!( /\bmod\b/u, "%" ) + predicate.gsub!( /\b(\w[-\w.]*\()/u ) { + fname = $1 + fname.gsub( /-/u, "_" ) + } + + Functions.pair = [ 0, elements.size ] + results = [] + elements.each do |element| + Functions.pair[0] += 1 + Functions.node = element + res = eval( predicate ) + case res + when true + results << element + when Integer + results << element if Functions.pair[0] == res + when String + results << element + end + end + filter( results, rest ) + end + + def QuickPath::attribute( name ) + Functions.node.attributes[name] if Functions.node.kind_of? Element + end + + def QuickPath::name() + Functions.node.name if Functions.node.kind_of? Element + end + + def QuickPath::method_missing( id, *args ) + begin + Functions.send( id.id2name, *args ) + rescue Exception + raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}" + end + end + + def QuickPath::function( elements, fname, rest ) + args = parse_args( elements, rest ) + Functions.pair = [0, elements.size] + results = [] + elements.each do |element| + Functions.pair[0] += 1 + Functions.node = element + res = Functions.send( fname, *args ) + case res + when true + results << element + when Integer + results << element if Functions.pair[0] == res + end + end + results + end + + def QuickPath::parse_args( element, string ) + # /.*?(?:\)|,)/ + arguments = [] + buffer = "" + while string and string != "" + c = string[0] + string.sub!(/^./u, "") + case c + when ?, + # if depth = 1, then we start a new argument + arguments << evaluate( buffer ) + #arguments << evaluate( string[0..count] ) + when ?( + # start a new method call + function( element, buffer, string ) + buffer = "" + when ?) + # close the method call and return arguments + return arguments + else + buffer << c + end + end + "" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/rexml.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/rexml.rb new file mode 100644 index 0000000..226e198 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/rexml.rb @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# frozen_string_literal: false +# +# \Module \REXML provides classes and methods for parsing, +# editing, and generating XML. +# +# == Implementation +# +# \REXML: +# - Is pure Ruby. +# - Provides tree, stream, SAX2, pull, and lightweight APIs. +# - Conforms to {XML version 1.0}[https://www.w3.org/TR/REC-xml/]. +# - Fully implements {XPath version 1.0}[http://www.w3c.org/tr/xpath]. +# - Is {non-validating}[https://www.w3.org/TR/xml/]. +# - Passes 100% of the non-validating {Oasis tests}[http://www.oasis-open.org/committees/xml-conformance/xml-test-suite.shtml]. +# +# == In a Hurry? +# +# If you're somewhat familiar with XML +# and have a particular task in mind, +# you may want to see {the tasks pages}[doc/rexml/tasks/tocs/master_toc_rdoc.html]. +# +# == API +# +# Among the most important classes for using \REXML are: +# - REXML::Document. +# - REXML::Element. +# +# There's also an {REXML tutorial}[doc/rexml/tutorial_rdoc.html]. +# +module REXML + COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>" + DATE = "2008/019" + VERSION = "3.4.4" + REVISION = "" + + Copyright = COPYRIGHT + Version = VERSION +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/sax2listener.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/sax2listener.rb new file mode 100644 index 0000000..5afdc80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/sax2listener.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: false +module REXML + # A template for stream parser listeners. + # Note that the declarations (attlistdecl, elementdecl, etc) are trivially + # processed; REXML doesn't yet handle doctype entity declarations, so you + # have to parse them out yourself. + # === Missing methods from SAX2 + # ignorable_whitespace + # === Methods extending SAX2 + # +WARNING+ + # These methods are certainly going to change, until DTDs are fully + # supported. Be aware of this. + # start_document + # end_document + # doctype + # elementdecl + # attlistdecl + # entitydecl + # notationdecl + # cdata + # xmldecl + # comment + module SAX2Listener + def start_document + end + def end_document + end + def start_prefix_mapping prefix, uri + end + def end_prefix_mapping prefix + end + def start_element uri, localname, qname, attributes + end + def end_element uri, localname, qname + end + def characters text + end + def processing_instruction target, data + end + # Handles a doctype declaration. Any attributes of the doctype which are + # not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar"> + # @p name the name of the doctype; EG, "me" + # @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC" + # @p long_name the supplied long name, or nil. EG, "foo" + # @p uri the uri of the doctype, or nil. EG, "bar" + def doctype name, pub_sys, long_name, uri + end + # If a doctype includes an ATTLIST declaration, it will cause this + # method to be called. The content is the declaration itself, unparsed. + # EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el + # attr CDATA #REQUIRED". This is the same for all of the .*decl + # methods. + def attlistdecl(element, pairs, contents) + end + # <!ELEMENT ...> + def elementdecl content + end + # <!ENTITY ...> + # The argument passed to this method is an array of the entity + # declaration. It can be in a number of formats, but in general it + # returns (example, result): + # <!ENTITY % YN '"Yes"'> + # ["%", "YN", "\"Yes\""] + # <!ENTITY % YN 'Yes'> + # ["%", "YN", "Yes"] + # <!ENTITY WhatHeSaid "He said %YN;"> + # ["WhatHeSaid", "He said %YN;"] + # <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml"> + # ["open-hatch", "SYSTEM", "http://www.textuality.com/boilerplate/OpenHatch.xml"] + # <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml"> + # ["open-hatch", "PUBLIC", "-//Textuality//TEXT Standard open-hatch boilerplate//EN", "http://www.textuality.com/boilerplate/OpenHatch.xml"] + # <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif> + # ["hatch-pic", "SYSTEM", "../grafix/OpenHatch.gif", "NDATA", "gif"] + def entitydecl declaration + end + # <!NOTATION ...> + def notationdecl name, public_or_system, public_id, system_id + end + # Called when <![CDATA[ ... ]]> is encountered in a document. + # @p content "..." + def cdata content + end + # Called when an XML PI is encountered in the document. + # EG: <?xml version="1.0" encoding="utf"?> + # @p version the version attribute value. EG, "1.0" + # @p encoding the encoding attribute value, or nil. EG, "utf" + # @p standalone the standalone attribute value, or nil. EG, nil + # @p spaced the declaration is followed by a line break + def xmldecl version, encoding, standalone + end + # Called when a comment is encountered. + # @p comment The content of the comment + def comment comment + end + def progress position + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/security.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/security.rb new file mode 100644 index 0000000..e8e8c6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/security.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: false +module REXML + module Security + @@entity_expansion_limit = 10_000 + + # Set the entity expansion limit. By default the limit is set to 10000. + def self.entity_expansion_limit=( val ) + @@entity_expansion_limit = val + end + + # Get the entity expansion limit. By default the limit is set to 10000. + def self.entity_expansion_limit + @@entity_expansion_limit + end + + @@entity_expansion_text_limit = 10_240 + + # Set the entity expansion limit. By default the limit is set to 10240. + def self.entity_expansion_text_limit=( val ) + @@entity_expansion_text_limit = val + end + + # Get the entity expansion limit. By default the limit is set to 10240. + def self.entity_expansion_text_limit + @@entity_expansion_text_limit + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/source.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/source.rb new file mode 100644 index 0000000..8b8ba0d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/source.rb @@ -0,0 +1,388 @@ +# coding: US-ASCII +# frozen_string_literal: false + +require "stringio" +require "strscan" + +require_relative 'encoding' + +module REXML + if StringScanner::Version < "1.0.0" + module StringScannerCheckScanString + refine StringScanner do + def check(pattern) + pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String) + super(pattern) + end + + def scan(pattern) + pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String) + super(pattern) + end + + def match?(pattern) + pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String) + super(pattern) + end + + def skip(pattern) + pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String) + super(pattern) + end + end + end + using StringScannerCheckScanString + end + + # Generates Source-s. USE THIS CLASS. + class SourceFactory + # Generates a Source object + # @param arg Either a String, or an IO + # @return a Source, or nil if a bad argument was given + def SourceFactory::create_from(arg) + if arg.respond_to? :read and + arg.respond_to? :readline and + arg.respond_to? :nil? and + arg.respond_to? :eof? + IOSource.new(arg) + elsif arg.respond_to? :to_str + IOSource.new(StringIO.new(arg)) + elsif arg.kind_of? Source + arg + else + raise "#{arg.class} is not a valid input stream. It must walk \n"+ + "like either a String, an IO, or a Source." + end + end + end + + # A Source can be searched for patterns, and wraps buffers and other + # objects and provides consumption of text + class Source + include Encoding + # The line number of the last consumed text + attr_reader :line + attr_reader :encoding + + module Private + SPACES_PATTERN = /\s+/um + SCANNER_RESET_SIZE = 100000 + PRE_DEFINED_TERM_PATTERNS = {} + pre_defined_terms = ["'", '"', "<", "]]>", "?>"] + if StringScanner::Version < "3.1.1" + pre_defined_terms.each do |term| + PRE_DEFINED_TERM_PATTERNS[term] = /#{Regexp.escape(term)}/ + end + else + pre_defined_terms.each do |term| + PRE_DEFINED_TERM_PATTERNS[term] = term + end + end + end + private_constant :Private + + # Constructor + # @param arg must be a String, and should be a valid XML document + # @param encoding if non-null, sets the encoding of the source to this + # value, overriding all encoding detection + def initialize(arg, encoding=nil) + @orig = arg + @scanner = StringScanner.new(@orig) + if encoding + self.encoding = encoding + else + detect_encoding + end + @line = 0 + @encoded_terms = {} + end + + # The current buffer (what we're going to read next) + def buffer + @scanner.rest + end + + def drop_parsed_content + if @scanner.pos > Private::SCANNER_RESET_SIZE + @scanner.string = @scanner.rest + end + end + + def buffer_encoding=(encoding) + @scanner.string.force_encoding(encoding) + end + + # Inherited from Encoding + # Overridden to support optimized en/decoding + def encoding=(enc) + return unless super + encoding_updated + end + + def read(term = nil) + end + + def read_until(term) + pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/ + data = @scanner.scan_until(pattern) + unless data + data = @scanner.rest + @scanner.pos = @scanner.string.bytesize + end + data + end + + def ensure_buffer + end + + def match(pattern, cons=false) + if cons + @scanner.scan(pattern).nil? ? nil : @scanner + else + @scanner.check(pattern).nil? ? nil : @scanner + end + end + + def match?(pattern, cons=false) + if cons + !@scanner.skip(pattern).nil? + else + !@scanner.match?(pattern).nil? + end + end + + def skip_spaces + @scanner.skip(Private::SPACES_PATTERN) ? true : false + end + + def position + @scanner.pos + end + + def position=(pos) + @scanner.pos = pos + end + + def peek_byte + @scanner.peek_byte + end + + def scan_byte + @scanner.scan_byte + end + + # @return true if the Source is exhausted + def empty? + @scanner.eos? + end + + # @return the current line in the source + def current_line + lines = @orig.split + res = lines.grep @scanner.rest[0..30] + res = res[-1] if res.kind_of? Array + lines.index( res ) if res + end + + private + + def detect_encoding + scanner_encoding = @scanner.rest.encoding + detected_encoding = "UTF-8" + begin + @scanner.string.force_encoding("ASCII-8BIT") + if @scanner.scan(/\xfe\xff/n) + detected_encoding = "UTF-16BE" + elsif @scanner.scan(/\xff\xfe/n) + detected_encoding = "UTF-16LE" + elsif @scanner.scan(/\xef\xbb\xbf/n) + detected_encoding = "UTF-8" + end + ensure + @scanner.string.force_encoding(scanner_encoding) + end + self.encoding = detected_encoding + end + + def encoding_updated + if @encoding != 'UTF-8' + @scanner.string = decode(@scanner.rest) + @to_utf = true + else + @to_utf = false + @scanner.string.force_encoding(::Encoding::UTF_8) + end + end + end + + # A Source that wraps an IO. See the Source class for method + # documentation + class IOSource < Source + #attr_reader :block_size + + # block_size has been deprecated + def initialize(arg, block_size=500, encoding=nil) + @er_source = @source = arg + @to_utf = false + @pending_buffer = nil + + if encoding + super("", encoding) + else + super(@source.read(3) || "") + end + + if !@to_utf and + @orig.respond_to?(:force_encoding) and + @source.respond_to?(:external_encoding) and + @source.external_encoding != ::Encoding::UTF_8 + @force_utf8 = true + else + @force_utf8 = false + end + end + + def read(term = nil, min_bytes = 1) + term = encode(term) if term + begin + str = readline(term) + @scanner << str + read_bytes = str.bytesize + begin + while read_bytes < min_bytes + str = readline(term) + @scanner << str + read_bytes += str.bytesize + end + rescue IOError + end + true + rescue Exception, NameError + @source = nil + false + end + end + + def read_until(term) + pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/ + term = @encoded_terms[term] ||= encode(term) + until str = @scanner.scan_until(pattern) + break if @source.nil? + break if @source.eof? + @scanner << readline(term) + end + if str + read if @scanner.eos? and @source and !@source.eof? + str + else + rest = @scanner.rest + @scanner.pos = @scanner.string.bytesize + rest + end + end + + def ensure_buffer + read if @scanner.eos? && @source + end + + def match( pattern, cons=false ) + # To avoid performance issue, we need to increase bytes to read per scan + min_bytes = 1 + while true + if cons + md = @scanner.scan(pattern) + else + md = @scanner.check(pattern) + end + break if md + return nil if pattern.is_a?(String) + return nil if @source.nil? + return nil unless read(nil, min_bytes) + min_bytes *= 2 + end + + md.nil? ? nil : @scanner + end + + def match?( pattern, cons=false ) + # To avoid performance issue, we need to increase bytes to read per scan + min_bytes = 1 + while true + if cons + n_matched_bytes = @scanner.skip(pattern) + else + n_matched_bytes = @scanner.match?(pattern) + end + return true if n_matched_bytes + return false if pattern.is_a?(String) + return false if @source.nil? + return false unless read(nil, min_bytes) + min_bytes *= 2 + end + end + + def empty? + super and ( @source.nil? || @source.eof? ) + end + + # @return the current line in the source + def current_line + begin + pos = @er_source.pos # The byte position in the source + lineno = @er_source.lineno # The XML < position in the source + @er_source.rewind + line = 0 # The \r\n position in the source + begin + while @er_source.pos < pos + @er_source.readline + line += 1 + end + rescue + end + @er_source.seek(pos) + rescue IOError, SystemCallError + pos = -1 + line = -1 + end + [pos, lineno, line] + end + + private + def readline(term = nil) + if @pending_buffer + begin + str = @source.readline(term || @line_break) + rescue IOError + end + if str.nil? + str = @pending_buffer + else + str = @pending_buffer + str + end + @pending_buffer = nil + else + str = @source.readline(term || @line_break) + end + return nil if str.nil? + + if @to_utf + decode(str) + else + str.force_encoding(::Encoding::UTF_8) if @force_utf8 + str + end + end + + def encoding_updated + case @encoding + when "UTF-16BE", "UTF-16LE" + @source.binmode + @source.set_encoding(@encoding, @encoding) + end + @line_break = encode(">") + @pending_buffer, @scanner.string = @scanner.rest, "" + @pending_buffer.force_encoding(@encoding) + super + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/streamlistener.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/streamlistener.rb new file mode 100644 index 0000000..30c8945 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/streamlistener.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: false +module REXML + # A template for stream parser listeners. + # Note that the declarations (attlistdecl, elementdecl, etc) are trivially + # processed; REXML doesn't yet handle doctype entity declarations, so you + # have to parse them out yourself. + module StreamListener + # Called when a tag is encountered. + # @p name the tag name + # @p attrs an array of arrays of attribute/value pairs, suitable for + # use with assoc or rassoc. IE, <tag attr1="value1" attr2="value2"> + # will result in + # tag_start( "tag", # [["attr1","value1"],["attr2","value2"]]) + def tag_start name, attrs + end + # Called when the end tag is reached. In the case of <tag/>, tag_end + # will be called immediately after tag_start + # @p the name of the tag + def tag_end name + end + # Called when text is encountered in the document + # @p text the text content. + def text text + end + # Called when an instruction is encountered. EG: <?xsl sheet='foo'?> + # @p name the instruction name; in the example, "xsl" + # @p instruction the rest of the instruction. In the example, + # "sheet='foo'" + def instruction name, instruction + end + # Called when a comment is encountered. + # @p comment The content of the comment + def comment comment + end + # Handles a doctype declaration. Any attributes of the doctype which are + # not supplied will be nil. # EG, <!DOCTYPE me PUBLIC "foo" "bar"> + # @p name the name of the doctype; EG, "me" + # @p pub_sys "PUBLIC", "SYSTEM", or nil. EG, "PUBLIC" + # @p long_name the supplied long name, or nil. EG, "foo" + # @p uri the uri of the doctype, or nil. EG, "bar" + def doctype name, pub_sys, long_name, uri + end + # Called when the doctype is done + def doctype_end + end + # If a doctype includes an ATTLIST declaration, it will cause this + # method to be called. The content is the declaration itself, unparsed. + # EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as "el + # attr CDATA #REQUIRED". This is the same for all of the .*decl + # methods. + def attlistdecl element_name, attributes, raw_content + end + # <!ELEMENT ...> + def elementdecl content + end + # <!ENTITY ...> + # The argument passed to this method is an array of the entity + # declaration. It can be in a number of formats, but in general it + # returns (example, result): + # <!ENTITY % YN '"Yes"'> + # ["YN", "\"Yes\"", "%"] + # <!ENTITY % YN 'Yes'> + # ["YN", "Yes", "%"] + # <!ENTITY WhatHeSaid "He said %YN;"> + # ["WhatHeSaid", "He said %YN;"] + # <!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml"> + # ["open-hatch", "SYSTEM", "http://www.textuality.com/boilerplate/OpenHatch.xml"] + # <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml"> + # ["open-hatch", "PUBLIC", "-//Textuality//TEXT Standard open-hatch boilerplate//EN", "http://www.textuality.com/boilerplate/OpenHatch.xml"] + # <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif> + # ["hatch-pic", "SYSTEM", "../grafix/OpenHatch.gif", "gif"] + def entitydecl content + end + # <!NOTATION ...> + def notationdecl content + end + # Called when %foo; is encountered in a doctype declaration. + # @p content "foo" + def entity content + end + # Called when <![CDATA[ ... ]]> is encountered in a document. + # @p content "..." + def cdata content + end + # Called when an XML PI is encountered in the document. + # EG: <?xml version="1.0" encoding="utf"?> + # @p version the version attribute value. EG, "1.0" + # @p encoding the encoding attribute value, or nil. EG, "utf" + # @p standalone the standalone attribute value, or nil. EG, nil + def xmldecl version, encoding, standalone + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/text.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/text.rb new file mode 100644 index 0000000..8d5281c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/text.rb @@ -0,0 +1,420 @@ +# frozen_string_literal: true +require_relative 'security' +require_relative 'entity' +require_relative 'doctype' +require_relative 'child' +require_relative 'doctype' +require_relative 'parseexception' + +module REXML + # Represents text nodes in an XML document + class Text < Child + include Comparable + # The order in which the substitutions occur + SPECIALS = [ /&(?!#?[\w-]+;)/u, /</u, />/u, /"/u, /'/u, /\r/u ] + SUBSTITUTES = ['&', '<', '>', '"', ''', ' '] + # Characters which are substituted in written strings + SLAICEPS = [ '<', '>', '"', "'", '&' ] + SETUTITSBUS = [ /</u, />/u, /"/u, /'/u, /&/u ] + + # If +raw+ is true, then REXML leaves the value alone + attr_accessor :raw + + NEEDS_A_SECOND_CHECK = /(<|&((#{Entity::NAME});|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));)?)/um + NUMERICENTITY = /�*((?:\d+)|(?:x[a-fA-F0-9]+));/ + VALID_CHAR = [ + 0x9, 0xA, 0xD, + (0x20..0xD7FF), + (0xE000..0xFFFD), + (0x10000..0x10FFFF) + ] + + VALID_XML_CHARS = Regexp.new('^['+ + VALID_CHAR.map { |item| + case item + when Integer + [item].pack('U').force_encoding('utf-8') + when Range + [item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8') + end + }.join + + ']*$') + + # Constructor + # +arg+ if a String, the content is set to the String. If a Text, + # the object is shallowly cloned. + # + # +respect_whitespace+ (boolean, false) if true, whitespace is + # respected + # + # +parent+ (nil) if this is a Parent object, the parent + # will be set to this. + # + # +raw+ (nil) This argument can be given three values. + # If true, then the value of used to construct this object is expected to + # contain no unescaped XML markup, and REXML will not change the text. If + # this value is false, the string may contain any characters, and REXML will + # escape any and all defined entities whose values are contained in the + # text. If this value is nil (the default), then the raw value of the + # parent will be used as the raw value for this node. If there is no raw + # value for the parent, and no value is supplied, the default is false. + # Use this field if you have entities defined for some text, and you don't + # want REXML to escape that text in output. + # Text.new( "<&", false, nil, false ) #-> "<&" + # Text.new( "<&", false, nil, false ) #-> "&lt;&amp;" + # Text.new( "<&", false, nil, true ) #-> Parse exception + # Text.new( "<&", false, nil, true ) #-> "<&" + # # Assume that the entity "s" is defined to be "sean" + # # and that the entity "r" is defined to be "russell" + # Text.new( "sean russell" ) #-> "&s; &r;" + # Text.new( "sean russell", false, nil, true ) #-> "sean russell" + # + # +entity_filter+ (nil) This can be an array of entities to match in the + # supplied text. This argument is only useful if +raw+ is set to false. + # Text.new( "sean russell", false, nil, false, ["s"] ) #-> "&s; russell" + # Text.new( "sean russell", false, nil, true, ["s"] ) #-> "sean russell" + # In the last example, the +entity_filter+ argument is ignored. + # + # +illegal+ INTERNAL USE ONLY + def initialize(arg, respect_whitespace=false, parent=nil, raw=nil, + entity_filter=nil, illegal=NEEDS_A_SECOND_CHECK ) + + @raw = false + @parent = nil + @entity_filter = nil + + if parent + super( parent ) + @raw = parent.raw + end + + if arg.kind_of? String + @string = arg.dup + elsif arg.kind_of? Text + @string = arg.instance_variable_get(:@string).dup + @raw = arg.raw + @entity_filter = arg.instance_variable_get(:@entity_filter) + else + raise "Illegal argument of type #{arg.type} for Text constructor (#{arg})" + end + + @string.squeeze!(" \n\t") unless respect_whitespace + @string.gsub!(/\r\n?/, "\n") + @raw = raw unless raw.nil? + @entity_filter = entity_filter if entity_filter + clear_cache + + Text.check(@string, illegal) if @raw + end + + def parent= parent + super(parent) + Text.check(@string, NEEDS_A_SECOND_CHECK) if @raw and @parent + end + + # check for illegal characters + def Text.check string, pattern, doctype = nil + + # illegal anywhere + if !string.match?(VALID_XML_CHARS) + string.chars.each do |c| + case c.ord + when *VALID_CHAR + else + raise "Illegal character #{c.inspect} in raw string #{string.inspect}" + end + end + end + + pos = 0 + while (index = string.index(/<|&/, pos)) + if string[index] == "<" + raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}" + end + + unless (end_index = string.index(/[^\s];/, index + 1)) + raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}" + end + + value = string[(index + 1)..end_index] + if /\s/.match?(value) + raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}" + end + + if value[0] == "#" + character_reference = value[1..-1] + + unless (/\A(\d+|x[0-9a-fA-F]+)\z/.match?(character_reference)) + if character_reference[0] == "x" || character_reference[-1] == "x" + raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}" + else + raise "Illegal character #{string.inspect} in raw string #{string.inspect}" + end + end + + case (character_reference[0] == "x" ? character_reference[1..-1].to_i(16) : character_reference[0..-1].to_i) + when *VALID_CHAR + else + raise "Illegal character #{string.inspect} in raw string #{string.inspect}" + end + elsif !(/\A#{Entity::NAME}\z/um.match?(value)) + raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}" + end + + pos = end_index + 1 + end + + string + end + + def node_type + :text + end + + def empty? + @string.size==0 + end + + + def clone + Text.new(self, true) + end + + + # Appends text to this text node. The text is appended in the +raw+ mode + # of this text node. + # + # +returns+ the text itself to enable method chain like + # 'text << "XXX" << "YYY"'. + def <<( to_append ) + @string << to_append.gsub( /\r\n?/, "\n" ) + clear_cache + self + end + + + # +other+ a String or a Text + # +returns+ the result of (to_s <=> arg.to_s) + def <=>( other ) + to_s() <=> other.to_s + end + + def doctype + @parent&.document&.doctype + end + + REFERENCE = /#{Entity::REFERENCE}/ + # Returns the string value of this text node. This string is always + # escaped, meaning that it is a valid XML text node string, and all + # entities that can be escaped, have been inserted. This method respects + # the entity filter set in the constructor. + # + # # Assume that the entity "s" is defined to be "sean", and that the + # # entity "r" is defined to be "russell" + # t = Text.new( "< & sean russell", false, nil, false, ['s'] ) + # t.to_s #-> "< & &s; russell" + # t = Text.new( "< & &s; russell", false, nil, false ) + # t.to_s #-> "< & &s; russell" + # u = Text.new( "sean russell", false, nil, true ) + # u.to_s #-> "sean russell" + def to_s + return @string if @raw + @normalized ||= Text::normalize( @string, doctype, @entity_filter ) + end + + def inspect + @string.inspect + end + + # Returns the string value of this text. This is the text without + # entities, as it might be used programmatically, or printed to the + # console. This ignores the 'raw' attribute setting, and any + # entity_filter. + # + # # Assume that the entity "s" is defined to be "sean", and that the + # # entity "r" is defined to be "russell" + # t = Text.new( "< & sean russell", false, nil, false, ['s'] ) + # t.value #-> "< & sean russell" + # t = Text.new( "< & &s; russell", false, nil, false ) + # t.value #-> "< & sean russell" + # u = Text.new( "sean russell", false, nil, true ) + # u.value #-> "sean russell" + def value + @unnormalized ||= Text::unnormalize(@string, doctype, + entity_expansion_text_limit: document&.entity_expansion_text_limit) + end + + # Sets the contents of this text node. This expects the text to be + # unnormalized. It returns self. + # + # e = Element.new( "a" ) + # e.add_text( "foo" ) # <a>foo</a> + # e[0].value = "bar" # <a>bar</a> + # e[0].value = "<a>" # <a><a></a> + def value=( val ) + @string = val.gsub( /\r\n?/, "\n" ) + clear_cache + @raw = false + end + + def wrap(string, width, addnewline=false) + # Recursively wrap string at width. + return string if string.length <= width + place = string.rindex(' ', width) # Position in string with last ' ' before cutoff + if addnewline + "\n" + string[0,place] + "\n" + wrap(string[place+1..-1], width) + else + string[0,place] + "\n" + wrap(string[place+1..-1], width) + end + end + + def indent_text(string, level=1, style="\t", indentfirstline=true) + Kernel.warn("#{self.class.name}#indent_text is deprecated. See REXML::Formatters", uplevel: 1) + return string if level < 0 + + new_string = +'' + string.each_line { |line| + indent_string = style * level + new_line = (indent_string + line).sub(/[\s]+$/,'') + new_string << new_line + } + new_string.strip! unless indentfirstline + new_string + end + + # == DEPRECATED + # See REXML::Formatters + # + def write( writer, indent=-1, transitive=false, ie_hack=false ) + Kernel.warn("#{self.class.name}#write is deprecated. See REXML::Formatters", uplevel: 1) + formatter = if indent > -1 + REXML::Formatters::Pretty.new( indent ) + else + REXML::Formatters::Default.new + end + formatter.write( self, writer ) + end + + # FIXME + # This probably won't work properly + def xpath + @parent.xpath + "/text()" + end + + # Writes out text, substituting special characters beforehand. + # +out+ A String, IO, or any other object supporting <<( String ) + # +input+ the text to substitute and the write out + # + # z=utf8.unpack("U*") + # ascOut="" + # z.each{|r| + # if r < 0x100 + # ascOut.concat(r.chr) + # else + # ascOut.concat(sprintf("&#x%x;", r)) + # end + # } + # puts ascOut + def write_with_substitution out, input + copy = input.clone + # Doing it like this rather than in a loop improves the speed + copy.gsub!( SPECIALS[0], SUBSTITUTES[0] ) + copy.gsub!( SPECIALS[1], SUBSTITUTES[1] ) + copy.gsub!( SPECIALS[2], SUBSTITUTES[2] ) + copy.gsub!( SPECIALS[3], SUBSTITUTES[3] ) + copy.gsub!( SPECIALS[4], SUBSTITUTES[4] ) + copy.gsub!( SPECIALS[5], SUBSTITUTES[5] ) + out << copy + end + + private + def clear_cache + @normalized = nil + @unnormalized = nil + end + + # Reads text, substituting entities + def Text::read_with_substitution( input, illegal=nil ) + copy = input.clone + + if copy =~ illegal + raise ParseException.new( "malformed text: Illegal character #$& in \"#{copy}\"" ) + end if illegal + + copy.gsub!( /\r\n?/, "\n" ) + if copy.include? ?& + copy.gsub!( SETUTITSBUS[0], SLAICEPS[0] ) + copy.gsub!( SETUTITSBUS[1], SLAICEPS[1] ) + copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] ) + copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] ) + copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] ) + copy.gsub!( /�*((?:\d+)|(?:x[a-f0-9]+));/ ) { + m=$1 + #m='0' if m=='' + m = "0#{m}" if m[0] == ?x + [Integer(m)].pack('U*') + } + end + copy + end + + EREFERENCE = /&(?!#{Entity::NAME};)/ + # Escapes all possible entities + def Text::normalize( input, doctype=nil, entity_filter=nil ) + copy = input.to_s + # Doing it like this rather than in a loop improves the speed + #copy = copy.gsub( EREFERENCE, '&' ) + copy = copy.gsub( "&", "&" ) if copy.include?("&") + if doctype + # Replace all ampersands that aren't part of an entity + doctype.entities.each_value do |entity| + copy = copy.gsub( entity.value, + "&#{entity.name};" ) if entity.value and + not( entity_filter and entity_filter.include?(entity.name) ) + end + else + # Replace all ampersands that aren't part of an entity + DocType::DEFAULT_ENTITIES.each_value do |entity| + if copy.include?(entity.value) + copy = copy.gsub(entity.value, "&#{entity.name};" ) + end + end + end + copy + end + + # Unescapes all possible entities + def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil, entity_expansion_text_limit: nil ) + entity_expansion_text_limit ||= Security.entity_expansion_text_limit + sum = 0 + string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) { + s = Text.expand($&, doctype, filter) + if sum + s.bytesize > entity_expansion_text_limit + raise "entity expansion has grown too large" + else + sum += s.bytesize + end + s + } + end + + def Text.expand(ref, doctype, filter) + if ref[1] == ?# + if ref[2] == ?x + [ref[3...-1].to_i(16)].pack('U*') + else + [ref[2...-1].to_i].pack('U*') + end + elsif ref == '&' + '&' + elsif filter and filter.include?( ref[1...-1] ) + ref + elsif doctype + doctype.entity( ref[1...-1] ) or ref + else + entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ] + entity_value ? entity_value.value : ref + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/undefinednamespaceexception.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/undefinednamespaceexception.rb new file mode 100644 index 0000000..492a098 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/undefinednamespaceexception.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: false +require_relative 'parseexception' +module REXML + class UndefinedNamespaceException < ParseException + def initialize( prefix, source, parser ) + super( "Undefined prefix #{prefix} found" ) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/relaxng.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/relaxng.rb new file mode 100644 index 0000000..c6894dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/relaxng.rb @@ -0,0 +1,540 @@ +# frozen_string_literal: false +require_relative "validation" +require_relative "../parsers/baseparser" + +module REXML + module Validation + # Implemented: + # * empty + # * element + # * attribute + # * text + # * optional + # * choice + # * oneOrMore + # * zeroOrMore + # * group + # * value + # * interleave + # * mixed + # * ref + # * grammar + # * start + # * define + # + # Not implemented: + # * data + # * param + # * include + # * externalRef + # * notAllowed + # * anyName + # * nsName + # * except + # * name + class RelaxNG + include Validator + + INFINITY = 1.0 / 0.0 + EMPTY = Event.new( nil ) + TEXT = [:start_element, "text"] + attr_accessor :current + attr_accessor :count + attr_reader :references + + # FIXME: Namespaces + def initialize source + parser = REXML::Parsers::BaseParser.new( source ) + + @count = 0 + @references = {} + @root = @current = Sequence.new(self) + @root.previous = true + states = [ @current ] + begin + event = parser.pull + case event[0] + when :start_element + case event[1] + when "empty" + when "element", "attribute", "text", "value" + states[-1] << event + when "optional" + states << Optional.new( self ) + states[-2] << states[-1] + when "choice" + states << Choice.new( self ) + states[-2] << states[-1] + when "oneOrMore" + states << OneOrMore.new( self ) + states[-2] << states[-1] + when "zeroOrMore" + states << ZeroOrMore.new( self ) + states[-2] << states[-1] + when "group" + states << Sequence.new( self ) + states[-2] << states[-1] + when "interleave" + states << Interleave.new( self ) + states[-2] << states[-1] + when "mixed" + states << Interleave.new( self ) + states[-2] << states[-1] + states[-1] << TEXT + when "define" + states << [ event[2]["name"] ] + when "ref" + states[-1] << Ref.new( event[2]["name"] ) + when "anyName" + states << AnyName.new( self ) + states[-2] << states[-1] + when "nsName" + when "except" + when "name" + when "data" + when "param" + when "include" + when "grammar" + when "start" + when "externalRef" + when "notAllowed" + end + when :end_element + case event[1] + when "element", "attribute" + states[-1] << event + when "zeroOrMore", "oneOrMore", "choice", "optional", + "interleave", "group", "mixed" + states.pop + when "define" + ref = states.pop + @references[ ref.shift ] = ref + #when "empty" + end + when :end_document + states[-1] << event + when :text + states[-1] << event + end + end while event[0] != :end_document + end + + def receive event + validate( event ) + end + end + + class State + def initialize( context ) + @previous = [] + @events = [] + @current = 0 + @count = context.count += 1 + @references = context.references + @value = false + end + + def reset + return if @current == 0 + @current = 0 + @events.each {|s| s.reset if s.kind_of? State } + end + + def previous=( previous ) + @previous << previous + end + + def next( event ) + #print "In next with #{event.inspect}. " + #p @previous + return @previous.pop.next( event ) if @events[@current].nil? + expand_ref_in( @events, @current ) if @events[@current].class == Ref + if ( @events[@current].kind_of? State ) + @current += 1 + @events[@current-1].previous = self + return @events[@current-1].next( event ) + end + if ( @events[@current].matches?(event) ) + @current += 1 + if @events[@current].nil? + @previous.pop + elsif @events[@current].kind_of? State + @current += 1 + @events[@current-1].previous = self + @events[@current-1] + else + self + end + else + nil + end + end + + def to_s + # Abbreviated: + self.class.name =~ /(?:::)(\w)\w+$/ + # Full: + #self.class.name =~ /(?:::)(\w+)$/ + "#$1.#@count" + end + + def inspect + "< #{to_s} #{@events.collect{|e| + pre = e == @events[@current] ? '#' : '' + pre + e.inspect unless self == e + }.join(', ')} >" + end + + def expected + [@events[@current]] + end + + def <<( event ) + add_event_to_arry( @events, event ) + end + + + protected + def expand_ref_in( arry, ind ) + new_events = [] + @references[ arry[ind].to_s ].each{ |evt| + add_event_to_arry(new_events,evt) + } + arry[ind,1] = new_events + end + + def add_event_to_arry( arry, evt ) + evt = generate_event( evt ) + if evt.kind_of? String + arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value + @value = false + else + arry << evt + end + end + + def generate_event( event ) + return event if event.kind_of? State or event.class == Ref + evt = nil + arg = nil + case event[0] + when :start_element + case event[1] + when "element" + evt = :start_element + arg = event[2]["name"] + when "attribute" + evt = :start_attribute + arg = event[2]["name"] + when "text" + evt = :text + when "value" + evt = :text + @value = true + end + when :text + return event[1] + when :end_document + return Event.new( event[0] ) + else # then :end_element + case event[1] + when "element" + evt = :end_element + when "attribute" + evt = :end_attribute + end + end + Event.new( evt, arg ) + end + end + + + class Sequence < State + def matches?(event) + @events[@current].matches?( event ) + end + end + + + class Optional < State + def next( event ) + if @current == 0 + rv = super + return rv if rv + @prior = @previous.pop + @prior.next( event ) + else + super + end + end + + def matches?(event) + @events[@current].matches?(event) || + (@current == 0 and @previous[-1].matches?(event)) + end + + def expected + return [ @prior.expected, @events[0] ].flatten if @current == 0 + [@events[@current]] + end + end + + + class ZeroOrMore < Optional + def next( event ) + expand_ref_in( @events, @current ) if @events[@current].class == Ref + if ( @events[@current].matches?(event) ) + @current += 1 + if @events[@current].nil? + @current = 0 + self + elsif @events[@current].kind_of? State + @current += 1 + @events[@current-1].previous = self + @events[@current-1] + else + self + end + else + @prior = @previous.pop + return @prior.next( event ) if @current == 0 + nil + end + end + + def expected + return [ @prior.expected, @events[0] ].flatten if @current == 0 + [@events[@current]] + end + end + + + class OneOrMore < State + def initialize context + super + @ord = 0 + end + + def reset + super + @ord = 0 + end + + def next( event ) + expand_ref_in( @events, @current ) if @events[@current].class == Ref + if ( @events[@current].matches?(event) ) + @current += 1 + @ord += 1 + if @events[@current].nil? + @current = 0 + self + elsif @events[@current].kind_of? State + @current += 1 + @events[@current-1].previous = self + @events[@current-1] + else + self + end + else + return @previous.pop.next( event ) if @current == 0 and @ord > 0 + nil + end + end + + def matches?( event ) + @events[@current].matches?(event) || + (@current == 0 and @ord > 0 and @previous[-1].matches?(event)) + end + + def expected + if @current == 0 and @ord > 0 + [@previous[-1].expected, @events[0]].flatten + else + [@events[@current]] + end + end + end + + + class Choice < State + def initialize context + super + @choices = [] + end + + def reset + super + @events = [] + @choices.each { |c| c.each { |s| s.reset if s.kind_of? State } } + end + + def <<( event ) + add_event_to_arry( @choices, event ) + end + + def next( event ) + # Make the choice if we haven't + if @events.size == 0 + c = 0 ; max = @choices.size + while c < max + if @choices[c][0].class == Ref + expand_ref_in( @choices[c], 0 ) + @choices += @choices[c] + @choices.delete( @choices[c] ) + max -= 1 + else + c += 1 + end + end + @events = @choices.find { |evt| evt[0].matches? event } + # Remove the references + # Find the events + end + unless @events + @events = [] + return nil + end + super + end + + def matches?( event ) + return @events[@current].matches?( event ) if @events.size > 0 + !@choices.find{|evt| evt[0].matches?(event)}.nil? + end + + def expected + return [@events[@current]] if @events.size > 0 + @choices.collect do |x| + if x[0].kind_of? State + x[0].expected + else + x[0] + end + end.flatten + end + + def inspect + "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' or ')} >" + end + + protected + def add_event_to_arry( arry, evt ) + if evt.kind_of? State or evt.class == Ref + arry << [evt] + elsif evt[0] == :text + if arry[-1] and + arry[-1][-1].kind_of?( Event ) and + arry[-1][-1].event_type == :text and @value + + arry[-1][-1].event_arg = evt[1] + @value = false + end + else + arry << [] if evt[0] == :start_element + arry[-1] << generate_event( evt ) + end + end + end + + + class Interleave < Choice + def initialize context + super + @choice = 0 + end + + def reset + @choice = 0 + end + + def next_current( event ) + # Expand references + c = 0 ; max = @choices.size + while c < max + if @choices[c][0].class == Ref + expand_ref_in( @choices[c], 0 ) + @choices += @choices[c] + @choices.delete( @choices[c] ) + max -= 1 + else + c += 1 + end + end + @events = @choices[@choice..-1].find { |evt| evt[0].matches? event } + @current = 0 + if @events + # reorder the choices + old = @choices[@choice] + idx = @choices.index( @events ) + @choices[@choice] = @events + @choices[idx] = old + @choice += 1 + end + + @events = [] unless @events + end + + + def next( event ) + # Find the next series + next_current(event) unless @events[@current] + return nil unless @events[@current] + + expand_ref_in( @events, @current ) if @events[@current].class == Ref + if ( @events[@current].kind_of? State ) + @current += 1 + @events[@current-1].previous = self + return @events[@current-1].next( event ) + end + return @previous.pop.next( event ) if @events[@current].nil? + if ( @events[@current].matches?(event) ) + @current += 1 + if @events[@current].nil? + return self unless @choices[@choice].nil? + @previous.pop + elsif @events[@current].kind_of? State + @current += 1 + @events[@current-1].previous = self + @events[@current-1] + else + self + end + else + nil + end + end + + def matches?( event ) + return @events[@current].matches?( event ) if @events[@current] + !@choices[@choice..-1].find{|evt| evt[0].matches?(event)}.nil? + end + + def expected + return [@events[@current]] if @events[@current] + @choices[@choice..-1].collect do |x| + if x[0].kind_of? State + x[0].expected + else + x[0] + end + end.flatten + end + + def inspect + "< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' and ')} >" + end + end + + class Ref + def initialize value + @value = value + end + def to_s + @value + end + def inspect + "{#{to_s}}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validation.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validation.rb new file mode 100644 index 0000000..6475c62 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validation.rb @@ -0,0 +1,144 @@ +# frozen_string_literal: false +require_relative 'validationexception' + +module REXML + module Validation + module Validator + NILEVENT = [ nil ] + def reset + @current = @root + @root.reset + @root.previous = true + @attr_stack = [] + self + end + def dump + puts @root.inspect + end + def validate( event ) + @attr_stack = [] unless defined? @attr_stack + match = @current.next(event) + raise ValidationException.new( "Validation error. Expected: "+ + @current.expected.join( " or " )+" from #{@current.inspect} "+ + " but got #{Event.new( event[0], event[1] ).inspect}" ) unless match + @current = match + + # Check for attributes + case event[0] + when :start_element + @attr_stack << event[2] + begin + sattr = [:start_attribute, nil] + eattr = [:end_attribute] + text = [:text, nil] + k, = event[2].find { |key,value| + sattr[1] = key + m = @current.next( sattr ) + if m + # If the state has text children... + if m.matches?( eattr ) + @current = m + else + text[1] = value + m = m.next( text ) + text[1] = nil + return false unless m + @current = m if m + end + m = @current.next( eattr ) + if m + @current = m + true + else + false + end + else + false + end + } + event[2].delete(k) if k + end while k + when :end_element + attrs = @attr_stack.pop + raise ValidationException.new( "Validation error. Illegal "+ + " attributes: #{attrs.inspect}") if attrs.length > 0 + end + end + end + + class Event + def initialize(event_type, event_arg=nil ) + @event_type = event_type + @event_arg = event_arg + end + + attr_reader :event_type + attr_accessor :event_arg + + def done? + @done + end + + def single? + (@event_type != :start_element and @event_type != :start_attribute) + end + + def matches?( event ) + return false unless event[0] == @event_type + case event[0] + when nil + true + when :start_element + event[1] == @event_arg + when :end_element + true + when :start_attribute + event[1] == @event_arg + when :end_attribute + true + when :end_document + true + when :text + @event_arg.nil? || @event_arg == event[1] +=begin + when :processing_instruction + false + when :xmldecl + false + when :start_doctype + false + when :end_doctype + false + when :externalentity + false + when :elementdecl + false + when :entity + false + when :attlistdecl + false + when :notationdecl + false + when :end_doctype + false +=end + else + false + end + end + + def ==( other ) + return false unless other.kind_of? Event + @event_type == other.event_type and @event_arg == other.event_arg + end + + def to_s + inspect + end + + def inspect + "#{@event_type.inspect}( #@event_arg )" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validationexception.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validationexception.rb new file mode 100644 index 0000000..78cd63f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/validation/validationexception.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: false +module REXML + module Validation + class ValidationException < RuntimeError + def initialize msg + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmldecl.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmldecl.rb new file mode 100644 index 0000000..d19407c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmldecl.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: false + +require_relative 'encoding' +require_relative 'source' + +module REXML + # NEEDS DOCUMENTATION + class XMLDecl < Child + include Encoding + + DEFAULT_VERSION = "1.0" + DEFAULT_ENCODING = "UTF-8" + DEFAULT_STANDALONE = "no" + START = "<?xml" + STOP = "?>" + + attr_accessor :version, :standalone + attr_reader :writeencoding, :writethis + + def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil) + @writethis = true + @writeencoding = !encoding.nil? + if version.kind_of? XMLDecl + super() + @version = version.version + self.encoding = version.encoding + @writeencoding = version.writeencoding + @standalone = version.standalone + @writethis = version.writethis + else + super() + @version = version + self.encoding = encoding + @standalone = standalone + end + @version = DEFAULT_VERSION if @version.nil? + end + + def clone + XMLDecl.new(self) + end + + # indent:: + # Ignored. There must be no whitespace before an XML declaration + # transitive:: + # Ignored + # ie_hack:: + # Ignored + def write(writer, indent=-1, transitive=false, ie_hack=false) + return nil unless @writethis or writer.kind_of? Output + writer << START + writer << " #{content encoding}" + writer << STOP + end + + def ==( other ) + other.kind_of?(XMLDecl) and + other.version == @version and + other.encoding == self.encoding and + other.standalone == @standalone + end + + def xmldecl version, encoding, standalone + @version = version + self.encoding = encoding + @standalone = standalone + end + + def node_type + :xmldecl + end + + alias :stand_alone? :standalone + alias :old_enc= :encoding= + + def encoding=( enc ) + if enc.nil? + self.old_enc = "UTF-8" + @writeencoding = false + else + self.old_enc = enc + @writeencoding = true + end + self.dowrite + end + + # Only use this if you do not want the XML declaration to be written; + # this object is ignored by the XML writer. Otherwise, instantiate your + # own XMLDecl and add it to the document. + # + # Note that XML 1.1 documents *must* include an XML declaration + def XMLDecl.default + rv = XMLDecl.new( "1.0" ) + rv.nowrite + rv + end + + def nowrite + @writethis = false + end + + def dowrite + @writethis = true + end + + def inspect + "#{START} ... #{STOP}" + end + + private + def content(enc) + context = nil + context = parent.context if parent + if context and context[:prologue_quote] == :quote + quote = "\"" + else + quote = "'" + end + + rv = "version=#{quote}#{@version}#{quote}" + if @writeencoding or enc !~ /\Autf-8\z/i + rv << " encoding=#{quote}#{enc}#{quote}" + end + if @standalone + rv << " standalone=#{quote}#{@standalone}#{quote}" + end + rv + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmltokens.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmltokens.rb new file mode 100644 index 0000000..392b47b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xmltokens.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: false +module REXML + # Defines a number of tokens used for parsing XML. Not for general + # consumption. + module XMLTokens + # From http://www.w3.org/TR/REC-xml/#sec-common-syn + # + # [4] NameStartChar ::= + # ":" | + # [A-Z] | + # "_" | + # [a-z] | + # [#xC0-#xD6] | + # [#xD8-#xF6] | + # [#xF8-#x2FF] | + # [#x370-#x37D] | + # [#x37F-#x1FFF] | + # [#x200C-#x200D] | + # [#x2070-#x218F] | + # [#x2C00-#x2FEF] | + # [#x3001-#xD7FF] | + # [#xF900-#xFDCF] | + # [#xFDF0-#xFFFD] | + # [#x10000-#xEFFFF] + name_start_chars = [ + ":", + "A-Z", + "_", + "a-z", + "\\u00C0-\\u00D6", + "\\u00D8-\\u00F6", + "\\u00F8-\\u02FF", + "\\u0370-\\u037D", + "\\u037F-\\u1FFF", + "\\u200C-\\u200D", + "\\u2070-\\u218F", + "\\u2C00-\\u2FEF", + "\\u3001-\\uD7FF", + "\\uF900-\\uFDCF", + "\\uFDF0-\\uFFFD", + "\\u{10000}-\\u{EFFFF}", + ] + # From http://www.w3.org/TR/REC-xml/#sec-common-syn + # + # [4a] NameChar ::= + # NameStartChar | + # "-" | + # "." | + # [0-9] | + # #xB7 | + # [#x0300-#x036F] | + # [#x203F-#x2040] + name_chars = name_start_chars + [ + "\\-", + "\\.", + "0-9", + "\\u00B7", + "\\u0300-\\u036F", + "\\u203F-\\u2040", + ] + NAME_START_CHAR = "[#{name_start_chars.join('')}]" + NAME_CHAR = "[#{name_chars.join('')}]" + NAMECHAR = NAME_CHAR # deprecated. Use NAME_CHAR instead. + + # From http://www.w3.org/TR/xml-names11/#NT-NCName + # + # [6] NCNameStartChar ::= NameStartChar - ':' + ncname_start_chars = name_start_chars - [":"] + # From http://www.w3.org/TR/xml-names11/#NT-NCName + # + # [5] NCNameChar ::= NameChar - ':' + ncname_chars = name_chars - [":"] + NCNAME_STR = "[#{ncname_start_chars.join('')}][#{ncname_chars.join('')}]*" + NAME_STR = "(?:#{NCNAME_STR}:)?#{NCNAME_STR}" + + NAME = "(#{NAME_START_CHAR}#{NAME_CHAR}*)" + NMTOKEN = "(?:#{NAME_CHAR})+" + NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*" + REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)" + + #REFERENCE = "(?:#{ENTITYREF}|#{CHARREF})" + #ENTITYREF = "&#{NAME};" + #CHARREF = "&#\\d+;|&#x[0-9a-fA-F]+;" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath.rb new file mode 100644 index 0000000..eed0300 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: false +require_relative 'functions' +require_relative 'xpath_parser' + +module REXML + # Wrapper class. Use this class to access the XPath functions. + class XPath + include Functions + # A base Hash object, supposing to be used when initializing a + # default empty namespaces set, but is currently unused. + # TODO: either set the namespaces=EMPTY_HASH, or deprecate this. + EMPTY_HASH = {} + + # Finds and returns the first node that matches the supplied xpath. + # element:: + # The context element + # path:: + # The xpath to search for. If not supplied or nil, returns the first + # node matching '*'. + # namespaces:: + # If supplied, a Hash which defines a namespace mapping. + # variables:: + # If supplied, a Hash which maps $variables in the query + # to values. This can be used to avoid XPath injection attacks + # or to automatically handle escaping string values. + # + # XPath.first( node ) + # XPath.first( doc, "//b"} ) + # XPath.first( node, "a/x:b", { "x"=>"http://doofus" } ) + # XPath.first( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) + def XPath::first(element, path=nil, namespaces=nil, variables={}, options={}) + raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash) + raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash) + match(element, path, namespaces, variables, options).flatten[0] + end + + # Iterates over nodes that match the given path, calling the supplied + # block with the match. + # element:: + # The context element + # path:: + # The xpath to search for. If not supplied or nil, defaults to '*' + # namespaces:: + # If supplied, a Hash which defines a namespace mapping + # variables:: + # If supplied, a Hash which maps $variables in the query + # to values. This can be used to avoid XPath injection attacks + # or to automatically handle escaping string values. + # + # XPath.each( node ) { |el| ... } + # XPath.each( node, '/*[@attr='v']' ) { |el| ... } + # XPath.each( node, 'ancestor::x' ) { |el| ... } + # XPath.each( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) \ + # {|el| ... } + def XPath::each(element, path=nil, namespaces=nil, variables={}, options={}, &block) + raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash) + raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash) + match(element, path, namespaces, variables, options).each( &block ) + end + + # Returns an array of nodes matching a given XPath. + def XPath::match(element, path=nil, namespaces=nil, variables={}, options={}) + parser = XPathParser.new(**options) + parser.namespaces = namespaces + parser.variables = variables + path = "*" unless path + parser.parse(path,element) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath_parser.rb b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath_parser.rb new file mode 100644 index 0000000..64c8846 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.4/lib/rexml/xpath_parser.rb @@ -0,0 +1,980 @@ +# frozen_string_literal: false + +require "pp" + +require_relative 'namespace' +require_relative 'xmltokens' +require_relative 'attribute' +require_relative 'parsers/xpathparser' + +module REXML + module DClonable + refine Object do + # provides a unified +clone+ operation, for REXML::XPathParser + # to use across multiple Object types + def dclone + clone + end + end + refine Symbol do + # provides a unified +clone+ operation, for REXML::XPathParser + # to use across multiple Object types + def dclone ; self ; end + end + refine Integer do + # provides a unified +clone+ operation, for REXML::XPathParser + # to use across multiple Object types + def dclone ; self ; end + end + refine Float do + # provides a unified +clone+ operation, for REXML::XPathParser + # to use across multiple Object types + def dclone ; self ; end + end + refine Array do + # provides a unified +clone+ operation, for REXML::XPathParser + # to use across multiple Object+ types + def dclone + klone = self.clone + klone.clear + self.each{|v| klone << v.dclone} + klone + end + end + end +end + +using REXML::DClonable + +module REXML + # You don't want to use this class. Really. Use XPath, which is a wrapper + # for this class. Believe me. You don't want to poke around in here. + # There is strange, dark magic at work in this code. Beware. Go back! Go + # back while you still can! + class XPathParser + include XMLTokens + LITERAL = /^'([^']*)'|^"([^"]*)"/u + + DEBUG = (ENV["REXML_XPATH_PARSER_DEBUG"] == "true") + + def initialize(strict: false) + @debug = DEBUG + @parser = REXML::Parsers::XPathParser.new + @namespaces = nil + @variables = {} + @nest = 0 + @strict = strict + end + + def namespaces=( namespaces={} ) + Functions::namespace_context = namespaces + @namespaces = namespaces + end + + def variables=( vars={} ) + Functions::variables = vars + @variables = vars + end + + def parse path, node + path_stack = @parser.parse( path ) + if node.is_a?(Array) + Kernel.warn("REXML::XPath.each, REXML::XPath.first, REXML::XPath.match dropped support for nodeset...", uplevel: 1) + return [] if node.empty? + node = node.first + end + + document = node.document + if document + document.__send__(:enable_cache) do + match( path_stack, node ) + end + else + match( path_stack, node ) + end + end + + def get_first path, node + path_stack = @parser.parse( path ) + first( path_stack, node ) + end + + def predicate path, node + path_stack = @parser.parse( path ) + match( path_stack, node ) + end + + def []=( variable_name, value ) + @variables[ variable_name ] = value + end + + + # Performs a depth-first (document order) XPath search, and returns the + # first match. This is the fastest, lightest way to return a single result. + # + # FIXME: This method is incomplete! + def first( path_stack, node ) + return nil if path.size == 0 + + case path[0] + when :document + # do nothing + first( path[1..-1], node ) + when :child + for c in node.children + r = first( path[1..-1], c ) + return r if r + end + when :qname + name = path[2] + if node.name == name + return node if path.size == 3 + first( path[3..-1], node ) + else + nil + end + when :descendant_or_self + r = first( path[1..-1], node ) + return r if r + for c in node.children + r = first( path, c ) + return r if r + end + when :node + first( path[1..-1], node ) + when :any + first( path[1..-1], node ) + else + nil + end + end + + + def match(path_stack, node) + nodeset = [XPathNode.new(node, position: 1)] + result = expr(path_stack, nodeset) + case result + when Array # nodeset + unnode(result).uniq + else + [result] + end + end + + private + def strict? + @strict + end + + # Returns a String namespace for a node, given a prefix + # The rules are: + # + # 1. Use the supplied namespace mapping first. + # 2. If no mapping was supplied, use the context node to look up the namespace + def get_namespace( node, prefix ) + if @namespaces + @namespaces[prefix] || '' + else + return node.namespace( prefix ) if node.node_type == :element + '' + end + end + + + # Expr takes a stack of path elements and a set of nodes (either a Parent + # or an Array and returns an Array of matching nodes + def expr( path_stack, nodeset, context=nil ) + enter(:expr, path_stack, nodeset) if @debug + return nodeset if path_stack.length == 0 || nodeset.length == 0 + while path_stack.length > 0 + trace(:while, path_stack, nodeset) if @debug + if nodeset.length == 0 + path_stack.clear + return [] + end + op = path_stack.shift + case op + when :document + first_raw_node = nodeset.first.raw_node + nodeset = [XPathNode.new(first_raw_node.root_node, position: 1)] + when :self + nodeset = step(path_stack) do + [nodeset] + end + when :child + nodeset = step(path_stack) do + child(nodeset) + end + when :literal + trace(:literal, path_stack, nodeset) if @debug + return path_stack.shift + when :attribute + nodeset = step(path_stack, any_type: :attribute) do + nodesets = [] + nodeset.each do |node| + raw_node = node.raw_node + next unless raw_node.node_type == :element + attributes = raw_node.attributes + next if attributes.empty? + nodesets << attributes.each_attribute.collect.with_index do |attribute, i| + XPathNode.new(attribute, position: i + 1) + end + end + nodesets + end + when :namespace + pre_defined_namespaces = { + "xml" => "http://www.w3.org/XML/1998/namespace", + } + nodeset = step(path_stack, any_type: :namespace) do + nodesets = [] + nodeset.each do |node| + raw_node = node.raw_node + case raw_node.node_type + when :element + if @namespaces + nodesets << pre_defined_namespaces.merge(@namespaces) + else + nodesets << pre_defined_namespaces.merge(raw_node.namespaces) + end + when :attribute + if @namespaces + nodesets << pre_defined_namespaces.merge(@namespaces) + else + nodesets << pre_defined_namespaces.merge(raw_node.element.namespaces) + end + end + end + nodesets + end + when :parent + nodeset = step(path_stack) do + nodesets = [] + nodeset.each do |node| + raw_node = node.raw_node + if raw_node.node_type == :attribute + parent = raw_node.element + else + parent = raw_node.parent + end + nodesets << [XPathNode.new(parent, position: 1)] if parent + end + nodesets + end + when :ancestor + nodeset = step(path_stack) do + nodesets = [] + # new_nodes = {} + nodeset.each do |node| + raw_node = node.raw_node + new_nodeset = [] + while raw_node.parent + raw_node = raw_node.parent + # next if new_nodes.key?(node) + new_nodeset << XPathNode.new(raw_node, + position: new_nodeset.size + 1) + # new_nodes[node] = true + end + nodesets << new_nodeset unless new_nodeset.empty? + end + nodesets + end + when :ancestor_or_self + nodeset = step(path_stack) do + nodesets = [] + # new_nodes = {} + nodeset.each do |node| + raw_node = node.raw_node + next unless raw_node.node_type == :element + new_nodeset = [XPathNode.new(raw_node, position: 1)] + # new_nodes[node] = true + while raw_node.parent + raw_node = raw_node.parent + # next if new_nodes.key?(node) + new_nodeset << XPathNode.new(raw_node, + position: new_nodeset.size + 1) + # new_nodes[node] = true + end + nodesets << new_nodeset unless new_nodeset.empty? + end + nodesets + end + when :descendant_or_self + nodeset = step(path_stack) do + descendant(nodeset, true) + end + when :descendant + nodeset = step(path_stack) do + descendant(nodeset, false) + end + when :following_sibling + nodeset = step(path_stack) do + nodesets = [] + nodeset.each do |node| + raw_node = node.raw_node + next unless raw_node.respond_to?(:parent) + next if raw_node.parent.nil? + all_siblings = raw_node.parent.children + current_index = all_siblings.index(raw_node) + following_siblings = all_siblings[(current_index + 1)..-1] + next if following_siblings.empty? + nodesets << following_siblings.collect.with_index do |sibling, i| + XPathNode.new(sibling, position: i + 1) + end + end + nodesets + end + when :preceding_sibling + nodeset = step(path_stack, order: :reverse) do + nodesets = [] + nodeset.each do |node| + raw_node = node.raw_node + next unless raw_node.respond_to?(:parent) + next if raw_node.parent.nil? + all_siblings = raw_node.parent.children + current_index = all_siblings.index(raw_node) + preceding_siblings = all_siblings[0, current_index].reverse + next if preceding_siblings.empty? + nodesets << preceding_siblings.collect.with_index do |sibling, i| + XPathNode.new(sibling, position: i + 1) + end + end + nodesets + end + when :preceding + nodeset = step(path_stack, order: :reverse) do + unnode(nodeset) do |node| + preceding(node) + end + end + when :following + nodeset = step(path_stack) do + unnode(nodeset) do |node| + following(node) + end + end + when :variable + var_name = path_stack.shift + return [@variables[var_name]] + + when :eq, :neq, :lt, :lteq, :gt, :gteq + left = expr( path_stack.shift, nodeset.dup, context ) + right = expr( path_stack.shift, nodeset.dup, context ) + res = equality_relational_compare( left, op, right ) + trace(op, left, right, res) if @debug + return res + + when :or + left = expr(path_stack.shift, nodeset.dup, context) + return true if Functions.boolean(left) + right = expr(path_stack.shift, nodeset.dup, context) + return Functions.boolean(right) + + when :and + left = expr(path_stack.shift, nodeset.dup, context) + return false unless Functions.boolean(left) + right = expr(path_stack.shift, nodeset.dup, context) + return Functions.boolean(right) + + when :div, :mod, :mult, :plus, :minus + left = expr(path_stack.shift, nodeset, context) + right = expr(path_stack.shift, nodeset, context) + left = unnode(left) if left.is_a?(Array) + right = unnode(right) if right.is_a?(Array) + left = Functions::number(left) + right = Functions::number(right) + case op + when :div + return left / right + when :mod + return left % right + when :mult + return left * right + when :plus + return left + right + when :minus + return left - right + else + raise "[BUG] Unexpected operator: <#{op.inspect}>" + end + when :union + left = expr( path_stack.shift, nodeset, context ) + right = expr( path_stack.shift, nodeset, context ) + left = unnode(left) if left.is_a?(Array) + right = unnode(right) if right.is_a?(Array) + return (left | right) + when :neg + res = expr( path_stack, nodeset, context ) + res = unnode(res) if res.is_a?(Array) + return -Functions.number(res) + when :not + when :function + func_name = path_stack.shift.tr('-','_') + arguments = path_stack.shift + + if nodeset.size != 1 + message = "[BUG] Node set size must be 1 for function call: " + message += "<#{func_name}>: <#{nodeset.inspect}>: " + message += "<#{arguments.inspect}>" + raise message + end + + node = nodeset.first + if context + target_context = context + else + target_context = {:size => nodeset.size} + if node.is_a?(XPathNode) + target_context[:node] = node.raw_node + target_context[:index] = node.position + else + target_context[:node] = node + target_context[:index] = 1 + end + end + args = arguments.dclone.collect do |arg| + result = expr(arg, nodeset, target_context) + result = unnode(result) if result.is_a?(Array) + result + end + Functions.context = target_context + return Functions.send(func_name, *args) + + else + raise "[BUG] Unexpected path: <#{op.inspect}>: <#{path_stack.inspect}>" + end + end # while + return nodeset + ensure + leave(:expr, path_stack, nodeset) if @debug + end + + def step(path_stack, any_type: :element, order: :forward) + nodesets = yield + begin + enter(:step, path_stack, nodesets) if @debug + nodesets = node_test(path_stack, nodesets, any_type: any_type) + while path_stack[0] == :predicate + path_stack.shift # :predicate + predicate_expression = path_stack.shift.dclone + nodesets = evaluate_predicate(predicate_expression, nodesets) + end + if nodesets.size == 1 + ordered_nodeset = nodesets[0] + else + raw_nodes = [] + nodesets.each do |nodeset| + nodeset.each do |node| + if node.respond_to?(:raw_node) + raw_nodes << node.raw_node + else + raw_nodes << node + end + end + end + ordered_nodeset = sort(raw_nodes, order) + end + new_nodeset = [] + ordered_nodeset.each do |node| + # TODO: Remove duplicated + new_nodeset << XPathNode.new(node, position: new_nodeset.size + 1) + end + new_nodeset + ensure + leave(:step, path_stack, new_nodeset) if @debug + end + end + + def node_test(path_stack, nodesets, any_type: :element) + enter(:node_test, path_stack, nodesets) if @debug + operator = path_stack.shift + case operator + when :qname + prefix = path_stack.shift + name = path_stack.shift + new_nodesets = nodesets.collect do |nodeset| + filter_nodeset(nodeset) do |node| + raw_node = node.raw_node + case raw_node.node_type + when :element + if prefix.nil? + raw_node.name == name + elsif prefix.empty? + if strict? + raw_node.name == name and raw_node.namespace == "" + else + raw_node.name == name and raw_node.namespace == get_namespace(raw_node, prefix) + end + else + raw_node.name == name and raw_node.namespace == get_namespace(raw_node, prefix) + end + when :attribute + if prefix.nil? + raw_node.name == name + elsif prefix.empty? + raw_node.name == name and raw_node.namespace == "" + else + raw_node.name == name and raw_node.namespace == get_namespace(raw_node.element, prefix) + end + else + false + end + end + end + when :namespace + prefix = path_stack.shift + new_nodesets = nodesets.collect do |nodeset| + filter_nodeset(nodeset) do |node| + raw_node = node.raw_node + case raw_node.node_type + when :element + namespaces = @namespaces || raw_node.namespaces + raw_node.namespace == namespaces[prefix] + when :attribute + namespaces = @namespaces || raw_node.element.namespaces + raw_node.namespace == namespaces[prefix] + else + false + end + end + end + when :any + new_nodesets = nodesets.collect do |nodeset| + filter_nodeset(nodeset) do |node| + raw_node = node.raw_node + raw_node.node_type == any_type + end + end + when :comment + new_nodesets = nodesets.collect do |nodeset| + filter_nodeset(nodeset) do |node| + raw_node = node.raw_node + raw_node.node_type == :comment + end + end + when :text + new_nodesets = nodesets.collect do |nodeset| + filter_nodeset(nodeset) do |node| + raw_node = node.raw_node + raw_node.node_type == :text + end + end + when :processing_instruction + target = path_stack.shift + new_nodesets = nodesets.collect do |nodeset| + filter_nodeset(nodeset) do |node| + raw_node = node.raw_node + (raw_node.node_type == :processing_instruction) and + (target.empty? or (raw_node.target == target)) + end + end + when :node + new_nodesets = nodesets.collect do |nodeset| + filter_nodeset(nodeset) do |node| + true + end + end + else + message = "[BUG] Unexpected node test: " + + "<#{operator.inspect}>: <#{path_stack.inspect}>" + raise message + end + new_nodesets + ensure + leave(:node_test, path_stack, new_nodesets) if @debug + end + + def filter_nodeset(nodeset) + new_nodeset = [] + nodeset.each do |node| + next unless yield(node) + new_nodeset << XPathNode.new(node, position: new_nodeset.size + 1) + end + new_nodeset + end + + def evaluate_predicate(expression, nodesets) + enter(:predicate, expression, nodesets) if @debug + new_nodeset_count = 0 + new_nodesets = nodesets.collect do |nodeset| + new_nodeset = [] + subcontext = { :size => nodeset.size } + nodeset.each_with_index do |node, index| + if node.is_a?(XPathNode) + subcontext[:node] = node.raw_node + subcontext[:index] = node.position + else + subcontext[:node] = node + subcontext[:index] = index + 1 + end + result = expr(expression.dclone, [node], subcontext) + trace(:predicate_evaluate, expression, node, subcontext, result) if @debug + result = result[0] if result.kind_of? Array and result.length == 1 + if result.kind_of? Numeric + if result == node.position + new_nodeset_count += 1 + new_nodeset << XPathNode.new(node, position: new_nodeset_count) + end + elsif result.instance_of? Array + if result.size > 0 and result.inject(false) {|k,s| s or k} + if result.size > 0 + new_nodeset_count += 1 + new_nodeset << XPathNode.new(node, position: new_nodeset_count) + end + end + else + if result + new_nodeset_count += 1 + new_nodeset << XPathNode.new(node, position: new_nodeset_count) + end + end + end + new_nodeset + end + new_nodesets + ensure + leave(:predicate, new_nodesets) if @debug + end + + def trace(*args) + indent = " " * @nest + PP.pp(args, "").each_line do |line| + puts("#{indent}#{line}") + end + end + + def enter(tag, *args) + trace(:enter, tag, *args) + @nest += 1 + end + + def leave(tag, *args) + @nest -= 1 + trace(:leave, tag, *args) + end + + # Reorders an array of nodes so that they are in document order + # It tries to do this efficiently. + # + # FIXME: I need to get rid of this, but the issue is that most of the XPath + # interpreter functions as a filter, which means that we lose context going + # in and out of function calls. If I knew what the index of the nodes was, + # I wouldn't have to do this. Maybe add a document IDX for each node? + # Problems with mutable documents. Or, rewrite everything. + def sort(array_of_nodes, order) + new_arry = [] + array_of_nodes.each { |node| + node_idx = [] + np = node.node_type == :attribute ? node.element : node + while np.parent and np.parent.node_type == :element + node_idx << np.parent.index( np ) + np = np.parent + end + new_arry << [ node_idx.reverse, node ] + } + ordered = new_arry.sort_by do |index, node| + if order == :forward + index + else + index.map(&:-@) + end + end + ordered.collect do |_index, node| + node + end + end + + def descendant(nodeset, include_self) + nodesets = [] + nodeset.each do |node| + new_nodeset = [] + new_nodes = {} + descendant_recursive(node.raw_node, new_nodeset, new_nodes, include_self) + nodesets << new_nodeset unless new_nodeset.empty? + end + nodesets + end + + def descendant_recursive(raw_node, new_nodeset, new_nodes, include_self) + if include_self + return if new_nodes.key?(raw_node) + new_nodeset << XPathNode.new(raw_node, position: new_nodeset.size + 1) + new_nodes[raw_node] = true + end + + node_type = raw_node.node_type + if node_type == :element or node_type == :document + raw_node.children.each do |child| + descendant_recursive(child, new_nodeset, new_nodes, true) + end + end + end + + # Builds a nodeset of all of the preceding nodes of the supplied node, + # in reverse document order + # preceding:: includes every element in the document that precedes this node, + # except for ancestors + def preceding(node) + ancestors = [] + parent = node.parent + while parent + ancestors << parent + parent = parent.parent + end + + precedings = [] + preceding_node = preceding_node_of(node) + while preceding_node + if ancestors.include?(preceding_node) + ancestors.delete(preceding_node) + else + precedings << XPathNode.new(preceding_node, + position: precedings.size + 1) + end + preceding_node = preceding_node_of(preceding_node) + end + precedings + end + + def preceding_node_of( node ) + psn = node.previous_sibling_node + if psn.nil? + if node.parent.nil? or node.parent.class == Document + return nil + end + return node.parent + #psn = preceding_node_of( node.parent ) + end + while psn and psn.kind_of? Element and psn.children.size > 0 + psn = psn.children[-1] + end + psn + end + + def following(node) + followings = [] + following_node = next_sibling_node(node) + while following_node + followings << XPathNode.new(following_node, + position: followings.size + 1) + following_node = following_node_of(following_node) + end + followings + end + + def following_node_of( node ) + return node.children[0] if node.kind_of?(Element) and node.children.size > 0 + + next_sibling_node(node) + end + + def next_sibling_node(node) + psn = node.next_sibling_node + while psn.nil? + return nil if node.parent.nil? or node.parent.class == Document + node = node.parent + psn = node.next_sibling_node + end + psn + end + + def child(nodeset) + nodesets = [] + nodeset.each do |node| + raw_node = node.raw_node + node_type = raw_node.node_type + # trace(:child, node_type, node) + case node_type + when :element + nodesets << raw_node.children.collect.with_index do |child_node, i| + XPathNode.new(child_node, position: i + 1) + end + when :document + new_nodeset = [] + raw_node.children.each do |child| + case child + when XMLDecl, Text + # Ignore + else + new_nodeset << XPathNode.new(child, position: new_nodeset.size + 1) + end + end + nodesets << new_nodeset unless new_nodeset.empty? + end + end + nodesets + end + + def norm b + case b + when true, false + b + when 'true', 'false' + Functions::boolean( b ) + when /^\d+(\.\d+)?$/, Numeric + Functions::number( b ) + else + Functions::string( b ) + end + end + + def equality_relational_compare(set1, op, set2) + set1 = unnode(set1) if set1.is_a?(Array) + set2 = unnode(set2) if set2.is_a?(Array) + + if set1.kind_of? Array and set2.kind_of? Array + # If both objects to be compared are node-sets, then the + # comparison will be true if and only if there is a node in the + # first node-set and a node in the second node-set such that the + # result of performing the comparison on the string-values of + # the two nodes is true. + set1.product(set2).any? do |node1, node2| + node_string1 = Functions.string(node1) + node_string2 = Functions.string(node2) + compare(node_string1, op, node_string2) + end + elsif set1.kind_of? Array or set2.kind_of? Array + # If one is nodeset and other is number, compare number to each item + # in nodeset s.t. number op number(string(item)) + # If one is nodeset and other is string, compare string to each item + # in nodeset s.t. string op string(item) + # If one is nodeset and other is boolean, compare boolean to each item + # in nodeset s.t. boolean op boolean(item) + if set1.kind_of? Array + a = set1 + b = set2 + else + a = set2 + b = set1 + end + + case b + when true, false + each_unnode(a).any? do |unnoded| + compare(Functions.boolean(unnoded), op, b) + end + when Numeric + each_unnode(a).any? do |unnoded| + compare(Functions.number(unnoded), op, b) + end + when /\A\d+(\.\d+)?\z/ + b = Functions.number(b) + each_unnode(a).any? do |unnoded| + compare(Functions.number(unnoded), op, b) + end + else + b = Functions::string(b) + each_unnode(a).any? do |unnoded| + compare(Functions::string(unnoded), op, b) + end + end + else + # If neither is nodeset, + # If op is = or != + # If either boolean, convert to boolean + # If either number, convert to number + # Else, convert to string + # Else + # Convert both to numbers and compare + compare(set1, op, set2) + end + end + + def value_type(value) + case value + when true, false + :boolean + when Numeric + :number + when String + :string + else + raise "[BUG] Unexpected value type: <#{value.inspect}>" + end + end + + def normalize_compare_values(a, operator, b) + a_type = value_type(a) + b_type = value_type(b) + case operator + when :eq, :neq + if a_type == :boolean or b_type == :boolean + a = Functions.boolean(a) unless a_type == :boolean + b = Functions.boolean(b) unless b_type == :boolean + elsif a_type == :number or b_type == :number + a = Functions.number(a) unless a_type == :number + b = Functions.number(b) unless b_type == :number + else + a = Functions.string(a) unless a_type == :string + b = Functions.string(b) unless b_type == :string + end + when :lt, :lteq, :gt, :gteq + a = Functions.number(a) unless a_type == :number + b = Functions.number(b) unless b_type == :number + else + message = "[BUG] Unexpected compare operator: " + + "<#{operator.inspect}>: <#{a.inspect}>: <#{b.inspect}>" + raise message + end + [a, b] + end + + def compare(a, operator, b) + a, b = normalize_compare_values(a, operator, b) + case operator + when :eq + a == b + when :neq + a != b + when :lt + a < b + when :lteq + a <= b + when :gt + a > b + when :gteq + a >= b + else + message = "[BUG] Unexpected compare operator: " + + "<#{operator.inspect}>: <#{a.inspect}>: <#{b.inspect}>" + raise message + end + end + + def each_unnode(nodeset) + return to_enum(__method__, nodeset) unless block_given? + nodeset.each do |node| + if node.is_a?(XPathNode) + unnoded = node.raw_node + else + unnoded = node + end + yield(unnoded) + end + end + + def unnode(nodeset) + each_unnode(nodeset).collect do |unnoded| + unnoded = yield(unnoded) if block_given? + unnoded + end + end + end + + # @private + class XPathNode + attr_reader :raw_node, :context + def initialize(node, context=nil) + if node.is_a?(XPathNode) + @raw_node = node.raw_node + else + @raw_node = node + end + @context = context || {} + end + + def position + @context[:position] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/Gemfile b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/Gemfile new file mode 100644 index 0000000..b66851e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/Gemfile @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +source 'http://rubygems.org' + +gemspec + +gem 'rake' + +gem 'minitest', '>= 5.0' +gem 'minitest-power_assert' +gem 'power_assert', '~> 2.0' + +# don't try to install redcarpet under jruby +gem 'redcarpet', platforms: :ruby + +# Profiling +gem 'memory_profiler', require: false + +group :development do + gem 'pry' + + # Needed for a Rake task + gem 'git' + gem 'yard' + + gem 'rubocop', '~> 1.0', '<= 1.11' + gem 'rubocop-performance' + + # docs + gem 'github-markup' + + # for visual tests + gem 'sinatra' + + # Ruby 3 no longer ships with a web server + gem 'puma' if RUBY_VERSION >= '3' + gem 'shotgun' + + gem "mutex_m" if RUBY_VERSION >= '3.4' + gem "base64" if RUBY_VERSION >= '3.4' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/LICENSE new file mode 100644 index 0000000..9dabadc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/LICENSE @@ -0,0 +1,187 @@ +# MIT license. See http://www.opensource.org/licenses/mit-license.php + +Copyright (c) 2012 Jeanine Adkisson. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +# SPECIAL NOTE: + +Many of the lexers in this project are adaptations of those in Pygments +(pygments.org). The license for Pygments is as follows: + +# BEGIN pygments/LICENSE # + +Copyright (c) 2006-2012 by the respective authors (see AUTHORS file). +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# END pygments/LICENSE # + +The contents of the AUTHORS file at the time of porting was: + +# BEGIN pygments/AUTHORS # + +Pygments is written and maintained by Georg Brandl <georg@python.org>. + +Major developers are Tim Hatch <tim@timhatch.com> and Armin Ronacher +<armin.ronacher@active-4.com>. + +Other contributors, listed alphabetically, are: + +* Sam Aaron -- Ioke lexer +* Kumar Appaiah -- Debian control lexer +* Ali Afshar -- image formatter +* Andreas Amann -- AppleScript lexer +* Jeffrey Arnold -- R/S lexer, BUGS lexers +* Jeremy Ashkenas -- CoffeeScript lexer +* Stefan Matthias Aust -- Smalltalk lexer +* Ben Bangert -- Mako lexers +* Max Battcher -- Darcs patch lexer +* Paul Baumgart, 280 North, Inc. -- Objective-J lexer +* Michael Bayer -- Myghty lexers +* John Benediktsson -- Factor lexer +* Christopher Bertels -- Fancy lexer +* Jarrett Billingsley -- MiniD lexer +* Adam Blinkinsop -- Haskell, Redcode lexers +* Frits van Bommel -- assembler lexers +* Pierre Bourdon -- bugfixes +* Hiram Chirino -- Scaml and Jade lexers +* Leaf Corcoran -- MoonScript lexer +* Christopher Creutzig -- MuPAD lexer +* Pete Curry -- bugfixes +* Owen Durni -- haXe lexer +* Nick Efford -- Python 3 lexer +* Sven Efftinge -- Xtend lexer +* Artem Egorkine -- terminal256 formatter +* James H. Fisher -- PostScript lexer +* Carlos Galdino -- Elixir and Elixir Console lexers +* Naveen Garg -- Autohotkey lexer +* Laurent Gautier -- R/S lexer +* Alex Gaynor -- PyPy log lexer +* Bertrand Goetzmann -- Groovy lexer +* Krzysiek Goj -- Scala lexer +* Matt Good -- Genshi, Cheetah lexers +* Patrick Gotthardt -- PHP namespaces support +* Olivier Guibe -- Asymptote lexer +* Martin Harriman -- SNOBOL lexer +* Matthew Harrison -- SVG formatter +* Steven Hazel -- Tcl lexer +* Aslak Hellesøy -- Gherkin lexer +* Greg Hendershott -- Racket lexer +* Jordi Gutiérrez Hermoso -- Octave lexer +* David Hess, Fish Software, Inc. -- Objective-J lexer +* Varun Hiremath -- Debian control lexer +* Doug Hogan -- Mscgen lexer +* Ben Hollis -- Mason lexer +* Tim Howard -- BlitzMax lexer +* Ivan Inozemtsev -- Fantom lexer +* Brian R. Jackson -- Tea lexer +* Dennis Kaarsemaker -- sources.list lexer +* Igor Kalnitsky -- vhdl lexer +* Eric Knibbe -- Lasso lexer +* Adam Koprowski -- Opa lexer +* Benjamin Kowarsch -- Modula-2 lexer +* Alexander Kriegisch -- Kconfig and AspectJ lexers +* Marek Kubica -- Scheme lexer +* Jochen Kupperschmidt -- Markdown processor +* Gerd Kurzbach -- Modelica lexer +* Olov Lassus -- Dart lexer +* Sylvestre Ledru -- Scilab lexer +* Mark Lee -- Vala lexer +* Ben Mabey -- Gherkin lexer +* Simone Margaritelli -- Hybris lexer +* Kirk McDonald -- D lexer +* Gordon McGregor -- SystemVerilog lexer +* Stephen McKamey -- Duel/JBST lexer +* Brian McKenna -- F# lexer +* Lukas Meuser -- BBCode formatter, Lua lexer +* Paul Miller -- LiveScript lexer +* Hong Minhee -- HTTP lexer +* Michael Mior -- Awk lexer +* Jon Morton -- Rust lexer +* Paulo Moura -- Logtalk lexer +* Mher Movsisyan -- DTD lexer +* Ana Nelson -- Ragel, ANTLR, R console lexers +* Nam T. Nguyen -- Monokai style +* Jesper Noehr -- HTML formatter "anchorlinenos" +* Mike Nolta -- Julia lexer +* Jonas Obrist -- BBCode lexer +* David Oliva -- Rebol lexer +* Jon Parise -- Protocol buffers lexer +* Ronny Pfannschmidt -- BBCode lexer +* Benjamin Peterson -- Test suite refactoring +* Dominik Picheta -- Nimrod lexer +* Clément Prévost -- UrbiScript lexer +* Kashif Rasul -- CUDA lexer +* Justin Reidy -- MXML lexer +* Norman Richards -- JSON lexer +* Lubomir Rintel -- GoodData MAQL and CL lexers +* Andre Roberge -- Tango style +* Konrad Rudolph -- LaTeX formatter enhancements +* Mario Ruggier -- Evoque lexers +* Stou Sandalski -- NumPy, FORTRAN, tcsh and XSLT lexers +* Matteo Sasso -- Common Lisp lexer +* Joe Schafer -- Ada lexer +* Ken Schutte -- Matlab lexers +* Tassilo Schweyer -- Io, MOOCode lexers +* Joerg Sieker -- ABAP lexer +* Robert Simmons -- Standard ML lexer +* Kirill Simonov -- YAML lexer +* Steve Spigarelli -- XQuery lexer +* Jerome St-Louis -- eC lexer +* James Strachan -- Kotlin lexer +* Tiberius Teng -- default style overhaul +* Jeremy Thurgood -- Erlang, Squid config lexers +* Erick Tryzelaar -- Felix lexer +* Daniele Varrazzo -- PostgreSQL lexers +* Abe Voelker -- OpenEdge ABL lexer +* Whitney Young -- ObjectiveC lexer +* Matthias Vallentin -- Bro lexer +* Nathan Weizenbaum -- Haml and Sass lexers +* Dietmar Winkler -- Modelica lexer +* Nils Winter -- Smalltalk lexer +* Davy Wybiral -- Clojure lexer +* Diego Zamboni -- CFengine3 lexer +* Alex Zimin -- Nemerle lexer + +Many thanks for all contributions! + +# END pygments/AUTHORS # diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/bin/rougify b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/bin/rougify new file mode 100755 index 0000000..13f2b10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/bin/rougify @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'pathname' +ROOT_DIR = Pathname.new(__FILE__).dirname.parent +Kernel::load ROOT_DIR.join('lib/rouge.rb') +Kernel::load ROOT_DIR.join('lib/rouge/cli.rb') +Signal.trap('PIPE', 'SYSTEM_DEFAULT') if Signal.list.include? 'PIPE' + +begin + Rouge::CLI.parse(ARGV).run +rescue Rouge::CLI::Error => e + puts e.message + exit e.status +rescue Interrupt + $stderr.puts "\nrouge: interrupted" + exit 2 +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge.rb new file mode 100644 index 0000000..f8cffcb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge.rb @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# stdlib +require 'pathname' + +# The containing module for Rouge +module Rouge + # cache value in a constant since `__dir__` allocates a new string + # on every call. + LIB_DIR = __dir__.freeze + + class << self + def reload! + Object::send :remove_const, :Rouge + Kernel::load __FILE__ + end + + # Highlight some text with a given lexer and formatter. + # + # @example + # Rouge.highlight('@foo = 1', 'ruby', 'html') + # Rouge.highlight('var foo = 1;', 'js', 'terminal256') + # + # # streaming - chunks become available as they are lexed + # Rouge.highlight(large_string, 'ruby', 'html') do |chunk| + # $stdout.print chunk + # end + def highlight(text, lexer, formatter, &b) + lexer = Lexer.find(lexer) unless lexer.respond_to? :lex + raise "unknown lexer #{lexer}" unless lexer + + formatter = Formatter.find(formatter) unless formatter.respond_to? :format + raise "unknown formatter #{formatter}" unless formatter + + formatter.format(lexer.lex(text), &b) + end + + # Load a file relative to the `lib/rouge` path. + # + # @api private + def load_file(path) + Kernel::load File.join(LIB_DIR, "rouge/#{path}.rb") + end + + # Load the lexers in the `lib/rouge/lexers` directory. + # + # @api private + def load_lexers + lexer_dir = Pathname.new(LIB_DIR) / "rouge/lexers" + Pathname.glob(lexer_dir / '*.rb').each do |f| + Lexers.load_lexer(f.relative_path_from(lexer_dir)) + end + end + end +end + +Rouge.load_file 'version' +Rouge.load_file 'util' +Rouge.load_file 'text_analyzer' +Rouge.load_file 'token' + +Rouge.load_file 'lexer' +Rouge.load_file 'regex_lexer' +Rouge.load_file 'template_lexer' + +Rouge.load_lexers + +Rouge.load_file 'guesser' +Rouge.load_file 'guessers/util' +Rouge.load_file 'guessers/glob_mapping' +Rouge.load_file 'guessers/modeline' +Rouge.load_file 'guessers/filename' +Rouge.load_file 'guessers/mimetype' +Rouge.load_file 'guessers/source' +Rouge.load_file 'guessers/disambiguation' + +Rouge.load_file 'formatter' +Rouge.load_file 'formatters/html' +Rouge.load_file 'formatters/html_table' +Rouge.load_file 'formatters/html_pygments' +Rouge.load_file 'formatters/html_legacy' +Rouge.load_file 'formatters/html_linewise' +Rouge.load_file 'formatters/html_line_highlighter' +Rouge.load_file 'formatters/html_line_table' +Rouge.load_file 'formatters/html_inline' +Rouge.load_file 'formatters/terminal256' +Rouge.load_file 'formatters/terminal_truecolor' +Rouge.load_file 'formatters/tex' +Rouge.load_file 'formatters/null' + +Rouge.load_file 'theme' +Rouge.load_file 'tex_theme_renderer' +Rouge.load_file 'themes/thankful_eyes' +Rouge.load_file 'themes/colorful' +Rouge.load_file 'themes/base16' +Rouge.load_file 'themes/github' +Rouge.load_file 'themes/igor_pro' +Rouge.load_file 'themes/monokai' +Rouge.load_file 'themes/molokai' +Rouge.load_file 'themes/monokai_sublime' +Rouge.load_file 'themes/gruvbox' +Rouge.load_file 'themes/tulip' +Rouge.load_file 'themes/pastie' +Rouge.load_file 'themes/bw' +Rouge.load_file 'themes/magritte' diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/cli.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/cli.rb new file mode 100644 index 0000000..2e75314 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/cli.rb @@ -0,0 +1,530 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# not required by the main lib. +# to use this module, require 'rouge/cli'. + +require 'rbconfig' +require 'uri' + +module Rouge + class FileReader + attr_reader :input + def initialize(input) + @input = input + end + + def file + case input + when '-' + IO.new($stdin.fileno, 'rt:bom|utf-8') + when String + File.new(input, 'rt:bom|utf-8') + when ->(i){ i.respond_to? :read } + input + end + end + + def read + @read ||= begin + file.read + rescue => e + $stderr.puts "unable to open #{input}: #{e.message}" + exit 1 + ensure + file.close + end + end + end + + class CLI + def self.doc + return enum_for(:doc) unless block_given? + + yield %|usage: rougify {global options} [command] [args...]| + yield %|| + yield %|where <command> is one of:| + yield %| highlight #{Highlight.desc}| + yield %| debug #{Debug.desc}| + yield %| help #{Help.desc}| + yield %| style #{Style.desc}| + yield %| list #{List.desc}| + yield %| guess #{Guess.desc}| + yield %| version #{Version.desc}| + yield %|| + yield %|global options:| + yield %[ --require|-r <fname> require <fname> after loading rouge] + yield %|| + yield %|See `rougify help <command>` for more info.| + end + + class Error < StandardError + attr_reader :message, :status + def initialize(message, status=1) + @message = message + @status = status + end + end + + def self.parse(argv=ARGV) + argv = normalize_syntax(argv) + + while (head = argv.shift) + case head + when '-h', '--help', 'help', '-help' + return Help.parse(argv) + when '--require', '-r' + require argv.shift + else + break + end + end + + klass = class_from_arg(head) + return klass.parse(argv) if klass + + argv.unshift(head) if head + Highlight.parse(argv) + end + + def initialize(options={}) + end + + def self.error!(msg, status=1) + raise Error.new(msg, status) + end + + def error!(*a) + self.class.error!(*a) + end + + def self.class_from_arg(arg) + case arg + when 'version', '--version', '-v' + Version + when 'help', nil + Help + when 'highlight', 'hi' + Highlight + when 'debug' + Debug + when 'style' + Style + when 'list' + List + when 'guess' + Guess + end + end + + class Version < CLI + def self.desc + "print the rouge version number" + end + + def self.parse(*); new; end + + def run + puts Rouge.version + end + end + + class Help < CLI + def self.desc + "print help info" + end + + def self.doc + return enum_for(:doc) unless block_given? + + yield %|usage: rougify help <command>| + yield %|| + yield %|print help info for <command>.| + end + + def self.parse(argv) + opts = { :mode => CLI } + until argv.empty? + arg = argv.shift + klass = class_from_arg(arg) + if klass + opts[:mode] = klass + next + end + end + new(opts) + end + + def initialize(opts={}) + @mode = opts[:mode] + end + + def run + @mode.doc.each(&method(:puts)) + end + end + + class Highlight < CLI + def self.desc + "highlight code" + end + + def self.doc + return enum_for(:doc) unless block_given? + + yield %[usage: rougify highlight <filename> [options...]] + yield %[ rougify highlight [options...]] + yield %[] + yield %[--input-file|-i <filename> specify a file to read, or - to use stdin] + yield %[] + yield %[--lexer|-l <lexer> specify the lexer to use.] + yield %[ If not provided, rougify will try to guess] + yield %[ based on --mimetype, the filename, and the] + yield %[ file contents.] + yield %[] + yield %[--formatter-preset|-f <opts> specify the output formatter to use.] + yield %[ If not provided, rougify will default to] + yield %[ terminal256. options are: terminal256,] + yield %[ terminal-truecolor, html, html-pygments,] + yield %[ html-inline, html-line-table, html-table,] + yield %[ null/raw/tokens, or tex.] + yield %[] + yield %[--theme|-t <theme> specify the theme to use for highlighting] + yield %[ the file. (only applies to some formatters)] + yield %[] + yield %[--mimetype|-m <mimetype> specify a mimetype for lexer guessing] + yield %[] + yield %[--lexer-opts|-L <opts> specify lexer options in CGI format] + yield %[ (opt1=val1&opt2=val2)] + yield %[] + yield %[--formatter-opts|-F <opts> specify formatter options in CGI format] + yield %[ (opt1=val1&opt2=val2)] + yield %[] + yield %[--require|-r <filename> require a filename or library before] + yield %[ highlighting] + yield %[] + yield %[--escape allow the use of escapes between <! and !>] + yield %[] + yield %[--escape-with <l> <r> allow the use of escapes between custom] + yield %[ delimiters. implies --escape] + end + + # There is no consistent way to do this, but this is used elsewhere, + # and we provide explicit opt-in and opt-out with $COLORTERM + def self.supports_truecolor? + return true if %w(24bit truecolor).include?(ENV['COLORTERM']) + return false if ENV['COLORTERM'] && ENV['COLORTERM'] =~ /256/ + + if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ + ENV['ConEmuANSI'] == 'ON' && !ENV['ANSICON'] + else + ENV['TERM'] !~ /(^rxvt)|(-color$)/ + end + end + + def self.parse_opts(argv) + opts = { + :formatter => supports_truecolor? ? 'terminal-truecolor' : 'terminal256', + :theme => 'thankful_eyes', + :css_class => 'codehilite', + :input_file => '-', + :lexer_opts => {}, + :formatter_opts => {}, + :requires => [], + } + + until argv.empty? + arg = argv.shift + case arg + when '-r', '--require' + opts[:requires] << argv.shift + when '--input-file', '-i' + opts[:input_file] = argv.shift + when '--mimetype', '-m' + opts[:mimetype] = argv.shift + when '--lexer', '-l' + opts[:lexer] = argv.shift + when '--formatter-preset', '-f' + opts[:formatter] = argv.shift + when '--theme', '-t' + opts[:theme] = argv.shift + when '--css-class', '-c' + opts[:css_class] = argv.shift + when '--lexer-opts', '-L' + opts[:lexer_opts] = parse_cgi(argv.shift) + when '--escape' + opts[:escape] = ['<!', '!>'] + when '--escape-with' + opts[:escape] = [argv.shift, argv.shift] + when /^--/ + error! "unknown option #{arg.inspect}" + else + opts[:input_file] = arg + end + end + + opts + end + + def self.parse(argv) + new(parse_opts(argv)) + end + + def input_stream + @input_stream ||= FileReader.new(@input_file) + end + + def input + @input ||= input_stream.read + end + + def lexer_class + @lexer_class ||= Lexer.guess( + :filename => @input_file, + :mimetype => @mimetype, + :source => input_stream, + ) + end + + def raw_lexer + lexer_class.new(@lexer_opts) + end + + def escape_lexer + Rouge::Lexers::Escape.new( + start: @escape[0], + end: @escape[1], + lang: raw_lexer, + ) + end + + def lexer + @lexer ||= @escape ? escape_lexer : raw_lexer + end + + attr_reader :input_file, :lexer_name, :mimetype, :formatter, :escape + + def initialize(opts={}) + Rouge::Lexer.enable_debug! + + opts[:requires].each do |r| + require r + end + + @input_file = opts[:input_file] + + if opts[:lexer] + @lexer_class = Lexer.find(opts[:lexer]) \ + or error! "unknown lexer #{opts[:lexer].inspect}" + else + @lexer_name = opts[:lexer] + @mimetype = opts[:mimetype] + end + + @lexer_opts = opts[:lexer_opts] + + theme = Theme.find(opts[:theme]).new or error! "unknown theme #{opts[:theme]}" + + # TODO: document this in --help + @formatter = case opts[:formatter] + when 'terminal256' then Formatters::Terminal256.new(theme) + when 'terminal-truecolor' then Formatters::TerminalTruecolor.new(theme) + when 'html' then Formatters::HTML.new + when 'html-pygments' then Formatters::HTMLPygments.new(Formatters::HTML.new, opts[:css_class]) + when 'html-inline' then Formatters::HTMLInline.new(theme) + when 'html-line-table' then Formatters::HTMLLineTable.new(Formatters::HTML.new) + when 'html-table' then Formatters::HTMLTable.new(Formatters::HTML.new) + when 'null', 'raw', 'tokens' then Formatters::Null.new + when 'tex' then Formatters::Tex.new + else + error! "unknown formatter preset #{opts[:formatter]}" + end + + @escape = opts[:escape] + end + + def run + Formatter.enable_escape! if @escape + formatter.format(lexer.lex(input), &method(:print)) + end + + private_class_method def self.parse_cgi(str) + pairs = URI.decode_www_form(str).map { |k, v| [k.to_sym, v] } + Hash[pairs] + end + end + + class Debug < Highlight + def self.desc + end + + def self.doc + return enum_for(:doc) unless block_given? + + yield %|usage: rougify debug [<options>]| + yield %|| + yield %|Debug a lexer. Similar options to `rougify highlight`, but| + yield %|defaults to the `null` formatter, and ensures the `debug`| + yield %|option is enabled, to print debugging information to stdout.| + end + + def self.parse_opts(argv) + out = super(argv) + out[:lexer_opts]['debug'] = '1' + out[:formatter] = 'null' + + out + end + end + + class Style < CLI + def self.desc + "print CSS styles" + end + + def self.doc + return enum_for(:doc) unless block_given? + + yield %|usage: rougify style [<theme-name>] [<options>]| + yield %|| + yield %|Print CSS styles for the given theme. Extra options are| + yield %|passed to the theme. To select a mode (light/dark) for the| + yield %|theme, append '.light' or '.dark' to the <theme-name>| + yield %|respectively. Theme defaults to thankful_eyes.| + yield %|| + yield %|options:| + yield %| --scope (default: .highlight) a css selector to scope by| + yield %| --tex (default: false) render as TeX| + yield %| --tex-prefix (default: RG) a command prefix for TeX| + yield %| implies --tex if specified| + yield %|| + yield %|available themes:| + yield %| #{Theme.registry.keys.sort.join(', ')}| + end + + def self.parse(argv) + opts = { + :theme_name => 'thankful_eyes', + :tex => false, + :tex_prefix => 'RG' + } + + until argv.empty? + arg = argv.shift + case arg + when '--tex' + opts[:tex] = true + when '--tex-prefix' + opts[:tex] = true + opts[:tex_prefix] = argv.shift + when /--(\w+)/ + opts[$1.tr('-', '_').to_sym] = argv.shift + else + opts[:theme_name] = arg + end + end + + new(opts) + end + + def initialize(opts) + theme_name = opts.delete(:theme_name) + theme_class = Theme.find(theme_name) \ + or error! "unknown theme: #{theme_name}" + + @theme = theme_class.new(opts) + if opts[:tex] + tex_prefix = opts[:tex_prefix] + @theme = TexThemeRenderer.new(@theme, prefix: tex_prefix) + end + end + + def run + @theme.render(&method(:puts)) + end + end + + class List < CLI + def self.desc + "list available lexers" + end + + def self.doc + return enum_for(:doc) unless block_given? + + yield %|usage: rouge list| + yield %|| + yield %|print a list of all available lexers with their descriptions.| + end + + def self.parse(argv) + new + end + + def run + puts "== Available Lexers ==" + + Lexer.all.sort_by(&:tag).each do |lexer| + desc = String.new("#{lexer.desc}") + if lexer.aliases.any? + desc << " [aliases: #{lexer.aliases.join(',')}]" + end + puts "%s: %s" % [lexer.tag, desc] + + lexer.option_docs.keys.sort.each do |option| + puts " ?#{option}= #{lexer.option_docs[option]}" + end + + puts + end + end + end + + class Guess < CLI + def self.desc + "guess the languages of file" + end + + def self.parse(args) + new(input_file: args.shift) + end + + attr_reader :input_file, :input_source + + def initialize(opts) + @input_file = opts[:input_file] || '-' + @input_source = FileReader.new(@input_file).read + end + + def lexers + Lexer.guesses( + filename: input_file, + source: input_source, + ) + end + + def run + lexers.each do |l| + puts "{ tag: #{l.tag.inspect}, title: #{l.title.inspect}, desc: #{l.desc.inspect} }" + end + end + end + + + private_class_method def self.normalize_syntax(argv) + out = [] + argv.each do |arg| + case arg + when /^(--\w+)=(.*)$/ + out << $1 << $2 + when /^(-\w)(.+)$/ + out << $1 << $2 + else + out << arg + end + end + + out + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/abap b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/abap new file mode 100644 index 0000000..1f0171b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/abap @@ -0,0 +1,6 @@ +lo_obj ?= lo_obj->do_nothing( 'Char' && ` String` ). + +SELECT SINGLE * FROM mara INTO ls_mara WHERE matkl EQ '1324'. +LOOP AT lt_mara ASSIGNING <mara>. + CHECK <mara>-mtart EQ '0001'. +ENDLOOP. diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/actionscript b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/actionscript new file mode 100644 index 0000000..f081e25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/actionscript @@ -0,0 +1,4 @@ +function hello(name:String):void +{ + trace("hello " + name); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ada b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ada new file mode 100644 index 0000000..36182fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ada @@ -0,0 +1,26 @@ +with Ada.Directories; +with Ada.Direct_IO; +with Ada.Text_IO; + +procedure Extra_IO.Read_File (Name : String) is + + package Dirs renames Ada.Directories; + package Text_IO renames Ada.Text_IO; + + -- Get the size of the file for a new string. + Size : Natural := Natural (Dirs.Size (Name)); + subtype File_String is String (1 .. Size); + + -- Instantiate Direct_IO for our file type. + package FIO is new Ada.Direct_IO (File_String); + + File : FIO.File_Type; + Contents : File_String; + +begin + FIO.Open (File, FIO.In_File, Name); + FIO.Read (File, Contents); + FIO.Close (File); + + Text_IO.Put (Contents); +end Extra_IO.Read_File; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apache b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apache new file mode 100644 index 0000000..ce3e5fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apache @@ -0,0 +1,21 @@ +AddDefaultCharset UTF-8 + +RewriteEngine On + +# Serve gzipped version if available and accepted +AddEncoding x-gzip .gz +RewriteCond %{HTTP:Accept-Encoding} gzip +RewriteCond %{REQUEST_FILENAME}.gz -f +RewriteRule ^(.*)$ $1.gz [QSA,L] +<FilesMatch \.css\.gz$> + ForceType text/css + Header append Vary Accept-Encoding +</FilesMatch> +<FilesMatch \.js\.gz$> + ForceType application/javascript + Header append Vary Accept-Encoding +</FilesMatch> +<FilesMatch \.html\.gz$> + ForceType text/html + Header append Vary Accept-Encoding +</FilesMatch> diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apex b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apex new file mode 100644 index 0000000..5b23b00 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apex @@ -0,0 +1,9 @@ +public class with sharing Trigger { + @Deprecated + public void resolveSum(int x, int y) { + System.debug('x is ' + x); + System.debug('y is ' + y); + + System.debug('x + y = ' + (x+y)); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apiblueprint b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apiblueprint new file mode 100644 index 0000000..25dc577 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/apiblueprint @@ -0,0 +1,33 @@ +FORMAT: 1A +HOST: http://polls.apiblueprint.org/ + +# Polls + +Polls is a simple API allowing consumers to view polls and vote in them. + +# Polls API Root [/] + +## Group Question + +Resources related to questions in the API. + +## Question [/questions/{question_id}] + ++ Parameters + + question_id: 1 (number, required) - ID of the Question in form of an integer + ++ Attributes + + question: `Favourite programming language?` (required) + + published_at: `2014-11-11T08:40:51.620Z` - An ISO8601 date when the question was published + + choices (array[Choice], required) - An array of Choice objects + + url: /questions/1 + +### View a Questions Detail [GET] + ++ Response 200 (application/json) + + Attributes (Question) + +### Delete a Question [DELETE] + ++ Relation: delete ++ Response 204 diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/applescript b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/applescript new file mode 100644 index 0000000..c824919 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/applescript @@ -0,0 +1,2 @@ +-- AppleScript playing with iTunes +tell application "iTunes" to get current selection diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/armasm b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/armasm new file mode 100644 index 0000000..b8bdf65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/armasm @@ -0,0 +1,12 @@ + GET common.s + +RetVal * 0x123 :SHL: 4 + + AREA |Area$$Name|, CODE, READONLY + +MyFunction ROUT ; This is a comment + ASSERT RetVal <> 0 +1 MOVW r0, #RetVal + BX lr + + END diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/augeas b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/augeas new file mode 100644 index 0000000..8f0ab0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/augeas @@ -0,0 +1,16 @@ +(* + This is a comment +*) +module Foo = +autoload xfm + +let a = b | c . d + +let lns = a* + +let filter = incl "/path/to/file" + . incl "/path/to/other_file" + . Util.stdexcl + +(* xmf is the transform *) +let xmf = transform lns filter diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/awk b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/awk new file mode 100644 index 0000000..fb6ca72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/awk @@ -0,0 +1,4 @@ +BEGIN { # Simulate echo(1) + for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i] + printf "\n" + exit } diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/batchfile b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/batchfile new file mode 100644 index 0000000..9426eb4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/batchfile @@ -0,0 +1,3 @@ +@echo off +setlocal enableextensions enabledelayedexpansion +for /f "tokens=*" %%a in ("hello !username! hi") do echo %%~a diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bbcbasic b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bbcbasic new file mode 100644 index 0000000..5737a5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bbcbasic @@ -0,0 +1,6 @@ +REM > DefaultFilename +REM Ordinary comment +FOR n=1 TO 10 +PRINTTAB(n)"Hello there ";FNnumber(n)DIV3+1 +NEXT:END +DEFFNnumber(x%)=ABS(x%-4) diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bibtex b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bibtex new file mode 100644 index 0000000..e029265 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bibtex @@ -0,0 +1,12 @@ +@article{Witten:1988hf, + author = "Witten, Edward", + title = "{Quantum Field Theory and the Jones Polynomial}", + journal = "Commun. Math. Phys.", + volume = "121", + year = "1989", + pages = "351-399", + doi = "10.1007/BF01217730", + note = "[,233(1988)]", + reportNumber = "IASSNS-HEP-88-33", + SLACcitation = "%%CITATION = CMPHA,121,351;%%" +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bicep b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bicep new file mode 100644 index 0000000..63e9b23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bicep @@ -0,0 +1,10 @@ +targetScope = 'subscription' // To create a resource group + +@description('The Azure region to create the resources in.') +param location string + +// Create a resource group +resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: 'rg-sample' + location: location +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/biml b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/biml new file mode 100644 index 0000000..e4d5f68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/biml @@ -0,0 +1,38 @@ +<#@ template language="C#" #> +<#@ import namespace="System.Data" #> +<Biml xmlns="http://schemas.varigence.com/biml.xsd"> + <Connections> + <!-- Creates a connection to the Adventure Works database --> + <Connection + Name="AdventureWorks" + ConnectionString="Provider=SQLNCLI10.1;Data Source=Localhost;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=AdventureWorksDW" + /> + </Connections> + <!-- Packages Collection --> + <Packages> + <!-- A Package --> + <Package + Name="MyFirstPackage" + ConstraintMode="Linear" + > + <!-- A Package's Tasks --> + <Tasks> + <ExecuteSQL Name="ExecuteStoredProc" ConnectionName="AdventureWorks"> + <DirectInput>EXEC usp_StoredProc</DirectInput> + </ExecuteSQL> + <# foreach (var table in RootNode.Tables) { #> + <Dataflow Name="Duplicate <#=table.Name#> Data"> + <Transformations> + <OleDbSource Name="Retrieve Data" ConnectionName="AdventureWorks"> + <DirectInput>SELECT * FROM <#=table.Name#></DirectInput> + </OleDbSource> + <OleDbDestination Name="Insert Data" ConnectionName="AdventureWorks"> + <ExternalTableOutput Table="<#=table.Name#>" /> + </OleDbDestination> + </Transformations> + </Dataflow> + <# } #> + </Tasks> + </Package> + </Packages> +</Biml> diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bpf b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bpf new file mode 100644 index 0000000..45c2083 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bpf @@ -0,0 +1,7 @@ +r0 = *(u8 *)skb[23] +*(u32 *)(r10 - 4) = r0 +r1 = *(u32 *)(r6 + 4) +r1 = 0 ll +call 1 /* lookup */ +if r0 == 0 goto +2 <LBB0_3> +lock *(u64 *)(r0 + 0) += r1 diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brainfuck b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brainfuck new file mode 100644 index 0000000..87cc69f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brainfuck @@ -0,0 +1,5 @@ +[ + This is a sample + comment. +] +.[>+<-]>, diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brightscript b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brightscript new file mode 100644 index 0000000..72224eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/brightscript @@ -0,0 +1,6 @@ +function main(args as dynamic) as void + screen = CreateObject("roSGScreen") + 'Create a scene and load /components/helloworld.xml' + scene = screen.CreateScene("HelloWorld") + screen.show() +end function diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bsl b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bsl new file mode 100644 index 0000000..8a6a8d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/bsl @@ -0,0 +1,7 @@ +#Область ПрограммныйИнтерфейс + +Процедура ПриветМир() Экспорт + Сообщить("Привет мир"); +КонецПроцедуры + +#КонецОбласти diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/c b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/c new file mode 100644 index 0000000..34771c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/c @@ -0,0 +1,8 @@ +#include "ruby/ruby.h" + +static int +clone_method_i(st_data_t key, st_data_t value, st_data_t data) +{ + clone_method((VALUE)data, (ID)key, (const rb_method_entry_t *)value); + return ST_CONTINUE; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ceylon b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ceylon new file mode 100644 index 0000000..fcf19e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ceylon @@ -0,0 +1,7 @@ +shared class CeylonClass<Parameter>() + given Parameter satisfies Object { + + shared String name => "CeylonClass"; +} + +shared void run() => CeylonClass(); diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cfscript b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cfscript new file mode 100644 index 0000000..b91d82d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cfscript @@ -0,0 +1,18 @@ +component accessors="true" { + + property type="string" name="firstName" default=""; + property string username; + + function init(){ + return this; + } + + public any function submitOrder( required product, coupon="", boolean results=true ){ + + var foo = function( required string baz, x=true, y=false ){ + return "bar!"; + }; + + return foo; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cisco_ios b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cisco_ios new file mode 100644 index 0000000..c4d4e69 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cisco_ios @@ -0,0 +1,19 @@ +interface FastEthernet0.20 + encapsulation dot1Q 20 + no ip route-cache + bridge-group 1 + no bridge-group 1 source-learning + bridge-group 1 spanning-disabled + +! Supports shortened versions of config words, too +inter gi0.10 +encap dot1q 10 native +inter gi0 + +banner login # Authenticate yourself! # + +! Supports #, $ and % to delimit banners, and multiline +banner motd $ +Attention! +We will be having scheduled system maintenance on this device. +$ diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clean b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clean new file mode 100644 index 0000000..9f947f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clean @@ -0,0 +1,6 @@ +delete :: !a !.(Set a) -> Set a | < a +delete x Tip = Tip +delete x (Bin _ y l r) + | x < y = balanceR y (delete x l) r + | x > y = balanceL y l (delete x r) + | otherwise = glue l r diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clojure b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clojure new file mode 100644 index 0000000..a9b682e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/clojure @@ -0,0 +1,5 @@ +(defn make-adder [x] + (let [y x] + (fn [z] (+ y z)))) +(def add2 (make-adder 2)) +(add2 4) diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmake b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmake new file mode 100644 index 0000000..89fcc51 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmake @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8.3) + +project(foo C) + +# some note +add_executable(foo utils.c "foo.c") +target_link_libraries(foo ${LIBRARIES}) diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmhg b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmhg new file mode 100644 index 0000000..76eeaf9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cmhg @@ -0,0 +1,8 @@ +; Header comments + +#include "definitions.h" + +command-keyword-table: command_handler + foo(min-args:0, max-args:0,; comment + international:, + invalid-syntax: "syntaxtoken" help-text: "helptoken") diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cobol b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cobol new file mode 100644 index 0000000..ad2691a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cobol @@ -0,0 +1,103 @@ + *----------------------- + * This file was sourced from https://github.com/openmainframeproject/cobol-programming-course + * Credits: + * The course materials were made available through a joint collaboration between IBM, its clients, and + * American River College and proposed as a new project by IBM. + *----------------------- + * Copyright Contributors to the COBOL Programming Course + * SPDX-License-Identifier: CC-BY-4.0 + *----------------------- + IDENTIFICATION DIVISION. + *----------------------- + PROGRAM-ID. CBL0001 + AUTHOR. Otto B. Fun. + *-------------------- + ENVIRONMENT DIVISION. + *-------------------- + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT PRINT-LINE ASSIGN TO PRTLINE. + SELECT ACCT-REC ASSIGN TO ACCTREC. + *SELECT clause creates an internal file name + *ASSIGN clause creates a name for an external data source, + *which is associated with the JCL DDNAME used by the z/OS + *e.g. ACCTREC is linked in JCL file CBL0001J to &SYSUID..DATA + *where &SYSUID. stands for Your z/OS user id + *e.g. if Your user id is Z54321, + *the data set used for ACCTREC is Z54321.DATA + *------------- + DATA DIVISION. + *------------- + FILE SECTION. + FD PRINT-LINE RECORDING MODE F. + 01 PRINT-REC. + 05 ACCT-NO-O PIC X(8). + 05 ACCT-LIMIT-O PIC $$,$$$,$$9.99. + 05 ACCT-BALANCE-O PIC $$,$$$,$$9.99. + * PIC $$,$$$,$$9.99 -- Alternative for PIC on chapter 7.2.3, + * using $ to allow values of different amounts of digits + * and .99 instead of v99 to allow period display on output + 05 LAST-NAME-O PIC X(20). + 05 FIRST-NAME-O PIC X(15). + 05 COMMENTS-O PIC X(50). + * since the level 05 is higher than level 01, + * all variables belong to PRINT-REC (see chapter 7.3.3) + * + FD ACCT-REC RECORDING MODE F. + 01 ACCT-FIELDS. + 05 ACCT-NO PIC X(8). + 05 ACCT-LIMIT PIC S9(7)V99 COMP-3. + 05 ACCT-BALANCE PIC S9(7)V99 COMP-3. + * PIC S9(7)v99 -- seven-digit plus a sign digit value + * COMP-3 -- packed BCD (binary coded decimal) representation + 05 LAST-NAME PIC X(20). + 05 FIRST-NAME PIC X(15). + 05 CLIENT-ADDR. + 10 STREET-ADDR PIC X(25). + 10 CITY-COUNTY PIC X(20). + 10 USA-STATE PIC X(15). + 05 RESERVED PIC X(7). + 05 COMMENTS PIC X(50). + * + WORKING-STORAGE SECTION. + 01 FLAGS. + 05 LASTREC PIC X VALUE SPACE. + *------------------ + PROCEDURE DIVISION. + *------------------ + OPEN-FILES. + OPEN INPUT ACCT-REC. + OPEN OUTPUT PRINT-LINE. + * + READ-NEXT-RECORD. + PERFORM READ-RECORD + * The previous statement is needed before entering the loop. + * Both the loop condition LASTREC = 'Y' + * and the call to WRITE-RECORD depend on READ-RECORD having + * been executed before. + * The loop starts at the next line with PERFORM UNTIL + PERFORM UNTIL LASTREC = 'Y' + PERFORM WRITE-RECORD + PERFORM READ-RECORD + END-PERFORM + . + * + CLOSE-STOP. + CLOSE ACCT-REC. + CLOSE PRINT-LINE. + GOBACK. + * + READ-RECORD. + READ ACCT-REC + AT END MOVE 'Y' TO LASTREC + END-READ. + * + WRITE-RECORD. + MOVE ACCT-NO TO ACCT-NO-O. + MOVE ACCT-LIMIT TO ACCT-LIMIT-O. + MOVE ACCT-BALANCE TO ACCT-BALANCE-O. + MOVE LAST-NAME TO LAST-NAME-O. + MOVE FIRST-NAME TO FIRST-NAME-O. + MOVE COMMENTS TO COMMENTS-O. + WRITE PRINT-REC. + * diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/codeowners b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/codeowners new file mode 100644 index 0000000..e4d88dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/codeowners @@ -0,0 +1,6 @@ +# Specify a default Code Owner by using a wildcard: +* @default-codeowner + +/docs/ @all-docs + +[Development] @dev-team diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coffeescript b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coffeescript new file mode 100644 index 0000000..a562db6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coffeescript @@ -0,0 +1,5 @@ +# Objects: +math = + root: Math.sqrt + square: square + cube: (x) -> x * square x diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/common_lisp b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/common_lisp new file mode 100644 index 0000000..c6d2861 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/common_lisp @@ -0,0 +1 @@ +(defun square (x) (* x x)) diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/conf b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/conf new file mode 100644 index 0000000..5386d4e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/conf @@ -0,0 +1,4 @@ +# A generic configuration file +option1 "val1" +option2 23 +option3 'val3' diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/console b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/console new file mode 100644 index 0000000..9d6ed1c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/console @@ -0,0 +1,6 @@ +# prints "hello, world" to the screen +~# echo Hello, World +Hello, World + +# don't run this +~# rm -rf --no-preserve-root / diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coq b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coq new file mode 100644 index 0000000..eadd44a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/coq @@ -0,0 +1,16 @@ +Require Import Coq.Lists.List. + +Section with_T. + Context {T : Type}. + + Fixpoint length (ls : list T) : nat := + match ls with + | nil => 0 + | _ :: ls => S (length ls) + end. +End with_T. + +Definition a_string := "hello +world". +Definition escape_string := "0123". +Definition zero_string := "0". diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cpp b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cpp new file mode 100644 index 0000000..c20cf27 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cpp @@ -0,0 +1,8 @@ +#include<iostream> + +using namespace std; + +int main() +{ + cout << "Hello World" << endl; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/crystal b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/crystal new file mode 100644 index 0000000..988753e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/crystal @@ -0,0 +1,45 @@ +lib LibC + WNOHANG = 0x00000001 + + @[ReturnsTwice] + fun fork : PidT + fun getpgid(pid : PidT) : PidT + fun kill(pid : PidT, signal : Int) : Int + fun getpid : PidT + fun getppid : PidT + fun exit(status : Int) : NoReturn + + ifdef x86_64 + alias ClockT = UInt64 + else + alias ClockT = UInt32 + end + + SC_CLK_TCK = 3 + + struct Tms + utime : ClockT + stime : ClockT + cutime : ClockT + cstime : ClockT + end + + fun times(buffer : Tms*) : ClockT + fun sysconf(name : Int) : Long +end + +class Process + def self.exit(status = 0) + LibC.exit(status) + end + + def self.pid + LibC.getpid + end + + def self.getpgid(pid : Int32) + ret = LibC.getpgid(pid) + raise Errno.new(ret) if ret < 0 + ret + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csharp b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csharp new file mode 100644 index 0000000..04e4a8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csharp @@ -0,0 +1,5 @@ +// reverse byte order (16-bit) +public static UInt16 ReverseBytes(UInt16 value) +{ + return (UInt16)((value & 0xFFU) << 8 | (value & 0xFF00U) >> 8); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/css b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/css new file mode 100644 index 0000000..0d1fe74 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/css @@ -0,0 +1,4 @@ +body { + font-size: 12pt; + background: #fff url(temp.png) top left no-repeat; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csvs b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csvs new file mode 100644 index 0000000..6112b7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/csvs @@ -0,0 +1,8 @@ +version 1.1 +@totalColumns 5 +@separator ',' +Transaction_Date: xDate +Transaction_ID: notEmpty +Originator_Name: notEmpty +Originator_Address: any("yes","no") +Originator_Country: notEmpty diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cuda b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cuda new file mode 100644 index 0000000..6f9fa56 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cuda @@ -0,0 +1,11 @@ +#include <cstdio> + +__global__ void helloFromGPU() { + std::printf("Hello World\n"); + __syncthreads(); +} + +int main() { + dim3 block(1, 10); + helloFromGPU<<<1, block>>>(); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cypher b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cypher new file mode 100644 index 0000000..098df7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cypher @@ -0,0 +1,5 @@ +// Cypher Mode for Rouge +CREATE (john:Person {name: 'John'}) +MATCH (user)-[:friend]->(follower) +WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*' +RETURN user.name, follower.name diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cython b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cython new file mode 100644 index 0000000..be57661 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/cython @@ -0,0 +1,6 @@ +cdef extern from 'foo.h': + int foo_int + struct foo_struct: + pass + +ctypedef int word diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/d b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/d new file mode 100644 index 0000000..65d4945 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/d @@ -0,0 +1,16 @@ +import std.algorithm, std.conv, std.functional, + std.math, std.regex, std.stdio; + +alias round = pipe!(to!real, std.math.round, to!string); +static reFloatingPoint = ctRegex!`[0-9]+\.[0-9]+`; + +void main() +{ + // Replace anything that looks like a real + // number with the rounded equivalent. + stdin + .byLine + .map!(l => l.replaceAll!(c => c.hit.round) + (reFloatingPoint)) + .each!writeln; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dafny b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dafny new file mode 100644 index 0000000..66415a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dafny @@ -0,0 +1,16 @@ +module A { + const i: int := 56_78 +} + +method m(b: bool, s: string) { + var x: string; + var i: int; + if b then i := 1; else i := 2; + i := if b 1 else 2; + assert b; + assume b; + print s; + expect b; +} + +function f(i: int): int { i + 1 } diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dart b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dart new file mode 100644 index 0000000..4b40da5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dart @@ -0,0 +1,6 @@ +void main() { + var collection=[1,2,3,4,5]; + for(var a in collection){ + print(a); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/datastudio b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/datastudio new file mode 100644 index 0000000..17db7a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/datastudio @@ -0,0 +1,20 @@ + +Get_Variable("EUSER","ENV","USERNAME"); + +Message("Le Login Windows est : %EUSER%"); + +Get_Variable("st","JOB","FOLDER1.date_err.SYSTEM.STATUS"); + + +AFFECT("filter1", '%%/"t"'); +AFFECT("filter2", '%%/"pi"'); +JSONTOSQL("%{jsonpath}%/file.json", "", + " JSONPATH like '%filter1%' ", "a = JSONVALUE", + " JSONPATH like '%filter2%' ", "b = JSONVALUE; output(json_data, a, b)"); + + +Affect(VAR1,'%TEST%'); //Créer et affecter la variable VAR1 avec une chaîne +select * from TABLE1 where COL1 like %VAR1%; //utiliser la variable VAR1 dans une requête + +select * from TEST_TABLE; //exécution d'une requête Select pour ramener des valeurs +Affect_LastColumns("TEST1"); //création du paramètre TEST1 diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/diff b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/diff new file mode 100644 index 0000000..ab4f316 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/diff @@ -0,0 +1,7 @@ +--- file1 2012-10-16 15:07:58.086886874 +0100 ++++ file2 2012-10-16 15:08:07.642887236 +0100 +@@ -1,3 +1,3 @@ + a b c +-d e f ++D E F + g h i diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/digdag b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/digdag new file mode 100644 index 0000000..f7dbad0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/digdag @@ -0,0 +1,19 @@ +# this is digdag task definitions +timezone: UTC + ++setup: + echo>: start ${session_time} + ++disp_current_date: + echo>: ${moment(session_time).utc().format('YYYY-MM-DD HH:mm:ss Z')} + ++repeat: + for_each>: + order: [first, second, third] + animal: [dog, cat] + _do: + echo>: ${order} ${animal} + _parallel: true + ++teardown: + echo>: finish ${session_time} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/docker b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/docker new file mode 100644 index 0000000..656d2bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/docker @@ -0,0 +1,9 @@ +maintainer First O'Last + +run echo \ + 123 $bar +# comment +onbuild add . /app/src +onbuild run echo \ + 123 $bar +CMD /bin/bash diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dot b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dot new file mode 100644 index 0000000..243ee73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/dot @@ -0,0 +1,5 @@ +// The graph name and the semicolons are optional +graph G { + a -- b -- c; + b -- d; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ecl b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ecl new file mode 100644 index 0000000..b63b320 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ecl @@ -0,0 +1,17 @@ +/* + Example code - use without restriction. +*/ +Layout_Person := RECORD + UNSIGNED1 PersonID; + STRING15 FirstName; + STRING25 LastName; +END; + +allPeople := DATASET([ {1,'Fred','Smith'}, + {2,'Joe','Blow'}, + {3,'Jane','Smith'}],Layout_Person); + +somePeople := allPeople(LastName = 'Smith'); + +// Outputs --- +somePeople; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eex b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eex new file mode 100644 index 0000000..1f922b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eex @@ -0,0 +1 @@ +<title><%= @title %> diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eiffel b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eiffel new file mode 100644 index 0000000..ec025cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/eiffel @@ -0,0 +1,30 @@ +note + description: "Represents a person." + +class + PERSON + +create + make, make_unknown + +feature {NONE} -- Creation + + make (a_name: like name) + -- Create a person with `a_name' as `name'. + do + name := a_name + ensure + name = a_name + end + + make_unknown + do ensure + name = Void + end + +feature -- Access + + name: detachable STRING + -- Full name or Void if unknown. + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elixir b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elixir new file mode 100644 index 0000000..f81d641 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elixir @@ -0,0 +1 @@ +Enum.map([1,2,3], fn(x) -> x * 2 end) diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elm b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elm new file mode 100644 index 0000000..8d38380 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/elm @@ -0,0 +1,4 @@ +import Html exposing (text) + +main = + text "Hello, World!" diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/email b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/email new file mode 100644 index 0000000..b355729 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/email @@ -0,0 +1,11 @@ +From: Me +To: You +Date: Tue, 21 Jul 2020 15:14:03 +0000 +Subject: A very important message + +> Please investigate. Thank you. + +I have investigated. + +-- +This message is highly confidential and will self-destruct. diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/epp b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/epp new file mode 100644 index 0000000..e8decec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/epp @@ -0,0 +1,4 @@ +<%- | + Optional[String] $title, +| -%> +<%= $title %> diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erb new file mode 100644 index 0000000..1f922b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erb @@ -0,0 +1 @@ +<%= @title %> diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erlang b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erlang new file mode 100644 index 0000000..4c3cb99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/erlang @@ -0,0 +1,7 @@ +%%% Geometry module. +-module(geometry). +-export([area/1]). + +%% Compute rectangle and circle area. +area({rectangle, Width, Ht}) -> Width * Ht; +area({circle, R}) -> 3.14159 * R * R. diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/escape b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/escape new file mode 100644 index 0000000..b71d6b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/escape @@ -0,0 +1,3 @@ +If Formatter.enable_escape! is called, this allows escaping into html +or the parent format with a special delimiter. For example: +!>underlined text!!> diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/factor b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/factor new file mode 100644 index 0000000..2538dff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/factor @@ -0,0 +1,5 @@ +USING: io kernel sequences ; + +4 iota [ + "Happy Birthday " write 2 = "dear NAME" "to You" ? print +] each diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fluent b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fluent new file mode 100644 index 0000000..2e7ac8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fluent @@ -0,0 +1,13 @@ +# Simple things are simple. +hello-user = Hello, {$userName}! + +# Complex things are possible. +shared-photos = + {$userName} {$photoCount -> + [one] added a new photo + *[other] added {$photoCount} new photos + } to {$userGender -> + [male] his stream + [female] her stream + *[other] their stream + }. diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fortran b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fortran new file mode 100644 index 0000000..4fc52c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fortran @@ -0,0 +1,22 @@ +program bottles + + implicit none + integer :: nbottles + + do nbottles = 99, 1, -1 + call print_bottles(nbottles) + end do + +contains + + subroutine print_bottles(n) + implicit none + integer, intent(in) :: n + + write(*, "(I0, 1X, 'bottles of beer on the wall,')") n + write(*, "(I0, 1X, 'bottles of beer.')") n + write(*, "('Take one down, pass it around,')") + write(*, "(I0, 1X, 'bottles of beer on the wall.', /)") n - 1 + end subroutine print_bottles + +end program bottles diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/freefem b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/freefem new file mode 100644 index 0000000..9205675 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/freefem @@ -0,0 +1,16 @@ +include "MUMPS" + +// Parameters +func f = 1.; + +// Mesh +int nn = 25; //Mesh quality +mesh Th = square(nn, nn); + +// Fespace +func Pk = P2; +fespace Uh(Th, Pk); +Uh u; + +// Plot +plot(u, nbiso=30, fill=true, value=true, cmm="A"); diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fsharp b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fsharp new file mode 100644 index 0000000..2e58e03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/fsharp @@ -0,0 +1,12 @@ +(* Binary tree with leaves car­rying an integer. *) +type Tree = Leaf of int | Node of Tree * Tree + +let rec existsLeaf test tree = + match tree with + | Leaf v -> test v + | Node (left, right) -> + existsLeaf test left + || existsLeaf test right + +let hasEvenLeaf tree = + existsLeaf (fun n -> n % 2 = 0) tree diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gdscript b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gdscript new file mode 100644 index 0000000..72ba52c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gdscript @@ -0,0 +1,18 @@ +extends Node + +# Variables & Built-in Types + +var a = 5 +var b = true +var s = "Hello" +var arr = [1, 2, 3] + +# Constants & Enums + +const ANSWER = 42 +enum { UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALLY } + +# Functions + +func _ready(): + print("Hello, World") diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-cmm b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-cmm new file mode 100644 index 0000000..72b764e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-cmm @@ -0,0 +1,23 @@ +[lvl_s4t3_entry() // [R1] + { info_tbls: [(c4uB, + label: lvl_s4t3_info + rep: HeapRep 1 ptrs { Thunk } + srt: Nothing)] + stack_info: arg_space: 8 updfr_space: Just 8 + } + {offset + c4uB: // global + if ((Sp + -32) < SpLim) (likely: False) goto c4uC; else goto c4uD; + c4uC: // global + R1 = R1; + call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; + c4uD: // global + I64[Sp - 16] = stg_upd_frame_info; + P64[Sp - 8] = R1; + R2 = P64[R1 + 16]; + I64[Sp - 32] = stg_ap_p_info; + P64[Sp - 24] = Main.fib3_closure+1; + Sp = Sp - 32; + call GHC.Num.fromInteger_info(R2) args: 40, res: 0, upd: 24; + } + } diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-core b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-core new file mode 100644 index 0000000..a421f79 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ghc-core @@ -0,0 +1,26 @@ +Rec { +-- RHS size: {terms: 24, types: 3, coercions: 0, joins: 0/0} +Main.fib_fib [Occ=LoopBreaker] :: Integer -> Integer +[GblId, Arity=1, Str=, Unf=OtherCon []] +Main.fib_fib + = \ (ds_d2OU :: Integer) -> + case integer-gmp-1.0.2.0:GHC.Integer.Type.eqInteger# + ds_d2OU Main.fib1 + of { + __DEFAULT -> + case integer-gmp-1.0.2.0:GHC.Integer.Type.eqInteger# + ds_d2OU Main.fib3 + of { + __DEFAULT -> + integer-gmp-1.0.2.0:GHC.Integer.Type.plusInteger + (Main.fib_fib + (integer-gmp-1.0.2.0:GHC.Integer.Type.minusInteger + ds_d2OU Main.fib3)) + (Main.fib_fib + (integer-gmp-1.0.2.0:GHC.Integer.Type.minusInteger + ds_d2OU Main.fib2)); + 1# -> Main.fib3 + }; + 1# -> Main.fib1 + } +end Rec } diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gherkin b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gherkin new file mode 100644 index 0000000..78e4ba6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/gherkin @@ -0,0 +1,17 @@ +# language: en +Feature: Addition + In order to avoid silly mistakes + As someone who has trouble with mental math + I want to be told the sum of two numbers + + Scenario Outline: Add two numbers + Given I have entered into the calculator + And I have entered into the calculator + When I press + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rml b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rml new file mode 100644 index 0000000..5a09810 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rml @@ -0,0 +1,33 @@ +// A system agnostic domain specific language for runtime monitoring and verification +// Basic events + +insert(index,elem) matches {event:'func_pre',name:'my_insert',args:[index,elem]}; + +relevant matches insert(_,_)|remove(_,_)|size(_)|get(_,_); + +insert_in_bounds(size) matches insert(index,_) with index >= 0 && index <= size; + +del_false matches del(_,false); +not_add_true_del(el) not matches add(el,true) | del(el,_); + +Main = relevant >> (CheckIndex<0> /\ add_rm_get >> CheckElem)!; +CheckIndex = + get_size(size)* (insert_in_bounds(size) CheckIndex \/ remove_in_bounds(size) CheckIndex); + +Msg = if(inf<=sup) msg(inf) Msg else empty; +Main=relevant>>Msg<1,4>*!; + +acquire(id) matches {event:'func_pre',name:'acquire',args:[_,id,...]}; + +Main = relevant >> Resources; +Resources = + {let id; acquire(id) + ((Resources | use(id)* release(id)) /\ + acqRel(id) >> release(id) all) + }?; + +msg(ty) matches {event:'func_pre',name:'msg',args:[ty]}; +relevant matches msg(_); + +Msg = if(inf<=sup) msg(inf) Msg else empty; +Main=relevant>>Msg<1,4>*!; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/robot_framework b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/robot_framework new file mode 100644 index 0000000..3ba3fdc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/robot_framework @@ -0,0 +1,27 @@ +*** Settings *** +Document Example taken from http://robotframework.org/ +Suite Setup Open Browser To Login Page +Suite Teardown Close Browser +Test Setup Go To Login Page +Test Template Login With Invalid Credentials Should Fail +Resource resource.txt + +*** Test Cases *** User Name Password +Invalid Username invalid ${VALID PASSWORD} +Invalid Password ${VALID USER} invalid +Invalid Username And Password invalid whatever +Empty Username ${EMPTY} ${VALID PASSWORD} +Empty Password ${VALID USER} ${EMPTY} +Empty Username And Password ${EMPTY} ${EMPTY} + +*** Keywords *** +Login With Invalid Credentials Should Fail + [Arguments] ${username} ${password} + Input Username ${username} + Input Password ${password} + Submit Credentials + Login Should Have Failed + +Login Should Have Failed + Location Should Be ${ERROR URL} + Title Should Be Error Page diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ruby b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ruby new file mode 100644 index 0000000..be609a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ruby @@ -0,0 +1,9 @@ +class Greeter + def initialize(name="World") + @name = name + end + + def say_hi + puts "Hi #{@name}!" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rust b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rust new file mode 100644 index 0000000..b73b162 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/rust @@ -0,0 +1,12 @@ +use core::*; + +fn main() { + for ["Alice", "Bob", "Carol"].each |&name| { + do task::spawn { + let v = rand::Rng().shuffle([1, 2, 3]); + for v.each |&num| { + io::print(fmt!("%s says: '%d'\n", name, num)) + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sas b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sas new file mode 100644 index 0000000..1eee876 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sas @@ -0,0 +1,13 @@ +data sim; + do i = 1 to 100; + x1 = rand("Normal"); + x2 = rand("Binomial", 0.5, 100); + output; + end; +run; + +proc means data=sashelp.class; + class sex; + var height weight; + output out = mean_by_sex; +run; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sass b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sass new file mode 100644 index 0000000..1e768de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sass @@ -0,0 +1,3 @@ +@for $i from 1 through 3 + .item-#{$i} + width: 2em * $i diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scala b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scala new file mode 100644 index 0000000..75f19ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scala @@ -0,0 +1,3 @@ +class Greeter(name: String = "World") { + def sayHi() { println("Hi " + name + "!") } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scheme b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scheme new file mode 100644 index 0000000..c9c4dbd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scheme @@ -0,0 +1,4 @@ +(define Y + (lambda (m) + ((lambda (f) (m (lambda (a) ((f f) a)))) + (lambda (f) (m (lambda (a) ((f f) a))))))) diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scss b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scss new file mode 100644 index 0000000..3f259a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/scss @@ -0,0 +1,5 @@ +@for $i from 1 through 3 { + .item-#{$i} { + width: 2em * $i; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sed b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sed new file mode 100644 index 0000000..4683cd3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sed @@ -0,0 +1,4 @@ +/begin/,/end/ { + /begin/n # skip over the line that has "begin" on it + s/old/new/ +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/shell b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/shell new file mode 100644 index 0000000..f01fe48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/shell @@ -0,0 +1,2 @@ +# If not running interactively, don't do anything +[[ -z "$PS1" ]] && return diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sieve b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sieve new file mode 100644 index 0000000..5f6889d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sieve @@ -0,0 +1,10 @@ +require "fileinto"; +require "imap4flags"; + +if header :is "X-Spam" "Yes" { + fileinto "Junk"; + setflag "\\seen"; + stop; +} + +/* Other messages get filed into Inbox or to user's scripts */ diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slice b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slice new file mode 100644 index 0000000..7c38220 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slice @@ -0,0 +1,10 @@ +// Printer.ice +module Demo +{ + interface Printer + { + // A client can invoke this operation on a server. + // In this example we print the string s + void printString(string s); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slim b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slim new file mode 100644 index 0000000..215a4e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/slim @@ -0,0 +1,17 @@ +doctype html +html + body + h1 Markup examples + #content + p + | Slim can have #{ruby_code} interpolated! + /[if IE] + javascript: + alert('Slim supports embedded javascript!') + + - unless items.empty? + table + - for item in items do + tr + td.name = item.name + td.price = item.price diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smalltalk b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smalltalk new file mode 100644 index 0000000..af97161 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smalltalk @@ -0,0 +1,6 @@ +quadMultiply: i1 and: i2 + "This method multiplies the given numbers by each other + and the result by 4." + | mul | + mul := i1 * i2. + ^mul * 4 diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smarty b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smarty new file mode 100644 index 0000000..cf36485 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/smarty @@ -0,0 +1,11 @@ +{foo bar='single quotes' baz="double quotes" test3=$test3} + +
    + {foreach from=$myvariable item=data} +
  • {$data.field}
  • + {foreachelse} +
  • No Data
  • + {/foreach} +
+ +
{$foo.bar.baz}
diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sml b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sml new file mode 100644 index 0000000..02a57d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sml @@ -0,0 +1,4 @@ +datatype shape + = Circle of loc * real (* center and radius *) + | Square of loc * real (* upper-left corner and side length; axis-aligned *) + | Triangle of loc * loc * loc (* corners *) diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sparql b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sparql new file mode 100644 index 0000000..6884bd0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sparql @@ -0,0 +1,6 @@ +SELECT ?item ?itemLabel +WHERE +{ + ?item wdt:P31 wd:Q146. + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sqf b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sqf new file mode 100644 index 0000000..9f54383 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sqf @@ -0,0 +1,14 @@ +// Creates a dot marker at the given position +#include "script_component.hpp" +params ["_pos", "_txt"]; + +if (isNil QGVAR(markerID)) then { + GVAR(markerID) = 0; +}; + +_markerstr = createMarker [QGVAR(marker) + str GVAR(markerID), _pos]; +_markerstr setMarkerShape "ICON"; +_markerstr setMarkerType "hd_dot"; +_markerstr setMarkerText _txt; + +GVAR(markerID) = GVAR(markerID) + 1; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sql b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sql new file mode 100644 index 0000000..45a7a17 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/sql @@ -0,0 +1 @@ +SELECT * FROM `users` WHERE `user`.`id` = 1 diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ssh b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ssh new file mode 100644 index 0000000..47f9cdb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ssh @@ -0,0 +1,4 @@ +Host example + Hostname example.com + User user + Port 1234 diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stan b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stan new file mode 100644 index 0000000..0eac821 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stan @@ -0,0 +1,13 @@ +data { + int N; + vector[N] x; + vector[N] y; +} +parameters { + real alpha; + real beta; + real sigma; +} +model { + y ~ normal(alpha + beta * x, sigma); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stata b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stata new file mode 100644 index 0000000..3d2430d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/stata @@ -0,0 +1,14 @@ +* Run a series of linear regressions +sysuse auto, clear +foreach v of varlist mpg weight-turn { + regress price `v', robust +} + +regress price i.foreign +local num_obs = e(N) +global myglobal = 4 + +* Generate and manipulate variables +generate newvar1 = "string" +generate newvar2 = 34 - `num_obs' +replace newvar2 = $myglobal diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/supercollider b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/supercollider new file mode 100644 index 0000000..23a8e4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/supercollider @@ -0,0 +1,11 @@ +// modulate a sine frequency and a noise amplitude with another sine +// whose frequency depends on the horizontal mouse pointer position +~myFunction = { + var x = SinOsc.ar(MouseX.kr(1, 100)); + SinOsc.ar(300 * x + 800, 0, 0.1) + + + PinkNoise.ar(0.1 * x + 0.1) +}; + +~myFunction.play; +"that's all, folks!".postln; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/svelte b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/svelte new file mode 100644 index 0000000..8b3bb5c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/svelte @@ -0,0 +1,29 @@ + + + + + +{#await loadSrc(src)} + loading... +{:then data} + {#each cats as { name }, i} +
  • {name}
  • + {/each} + + + {#each cats as cat (cat.id)} +
  • {cat.name}
  • + {/each} +{:catch err} + {@debug err} + {#await solveErr(err, {x: 'asdf'}) then reason}{@html reason}{/await} +{/await} + + diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/swift b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/swift new file mode 100644 index 0000000..0c54ed2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/swift @@ -0,0 +1,5 @@ +// Say hello to poeple +func sayHello(personName: String) -> String { + let greeting = "Hello, " + personName + "!" + return greeting +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/systemd b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/systemd new file mode 100644 index 0000000..e68c72e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/systemd @@ -0,0 +1,4 @@ +[Unit] +Description=Snap Daemon +Requires=snapd.socket +OnFailure=snapd.failure.service diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzlang b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzlang new file mode 100644 index 0000000..bebdb1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzlang @@ -0,0 +1,15 @@ +include + +resource fd_test[fd] + +openat$test(fd const[AT_FDCWD], file ptr[in, string["/dev/test"]], flags flags[open_flags], mode const[0]) fd_test + +ioctl$TEST(fd fd_test, cmd const[TEST], arg ptr[in, test]) + +test { + number int32 + size len[data, int32] + data array[int8] +} + +_ = TEST diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzprog b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzprog new file mode 100644 index 0000000..92ef895 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/syzprog @@ -0,0 +1,8 @@ +# Source: https://github.com/google/syzkaller/blob/master/sys/linux/test/vusb_hid + +r0 = syz_usb_connect$hid(0x0, 0x36, &(0x7f0000000040)=ANY=[@ANYBLOB="12010000000018105e04da07000000000001090224000100000000090400000903000000092100000001222200090581030800000000"], 0x0) +syz_usb_control_io$hid(r0, 0x0, 0x0) +syz_usb_control_io$hid(r0, &(0x7f00000001c0)={0x24, 0x0, 0x0, &(0x7f0000000000)={0x0, 0x22, 0x22, {[@global=@item_012={0x2, 0x1, 0x9, "2313"}, @global=@item_012={0x2, 0x1, 0x0, "e53f"}, @global=@item_4={0x3, 0x1, 0x0, '\f\x00'}, @local=@item_012={0x2, 0x2, 0x2, "9000"}, @global=@item_4={0x3, 0x1, 0x0, "0900be00"}, @main=@item_4={0x3, 0x0, 0x8, '\x00'}, @local=@item_4={0x3, 0x2, 0x0, "09007a15"}, @local=@item_4={0x3, 0x2, 0x0, "5d8c3dda"}]}}, 0x0}, 0x0) +syz_usb_ep_write(r0, 0x81, 0x7, &(0x7f0000000000)='BBBBBBB') +syz_usb_ep_write(r0, 0x81, 0x7, &(0x7f0000000000)='BBBBBBB') +syz_usb_ep_write(r0, 0x81, 0x7, &(0x7f0000000000)='BBBBBBB') diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tap b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tap new file mode 100644 index 0000000..1d9bf5a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tap @@ -0,0 +1,5 @@ +ok 1 - Input file opened +not ok 2 - First line of the input valid +ok 3 - Read the rest of the file +not ok 4 - Summarized correctly # TODO Not written yet +1..4 diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tcl b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tcl new file mode 100644 index 0000000..9bbe87c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tcl @@ -0,0 +1 @@ +proc cross_sum {s} {expr [join [split $s ""] +]} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/terraform b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/terraform new file mode 100644 index 0000000..006e4f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/terraform @@ -0,0 +1,16 @@ +resource "aws_elb" "web" { + name = "terraform-example-elb" + + # The same availability zone as our instances + availability_zones = ["${aws_instance.web.*.availability_zone}"] + + listener { + instance_port = 80 + instance_protocol = "http" + lb_port = 80 + lb_protocol = "http" + } + + # The instances are registered automatically + instances = ["${aws_instance.web.*.id}"] +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tex b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tex new file mode 100644 index 0000000..430510f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tex @@ -0,0 +1 @@ +To write \LaTeX\ you would type \verb:\LaTeX:. diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/toml b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/toml new file mode 100644 index 0000000..40c11c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/toml @@ -0,0 +1,9 @@ +# This is a TOML document. Boom. + +title = "TOML Example" + +[owner] +name = "Tom Preston-Werner" +organization = "GitHub" +bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." +dob = 1979-05-27T07:32:00Z # First class dates? Why not? diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tsx b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tsx new file mode 100644 index 0000000..422d2a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tsx @@ -0,0 +1,17 @@ +class HelloWorld extends React.Component<{date: Date}, void> { + render() { + return ( +

    + Hello, ! + It is {this.props.date.toTimeString()} +

    + ); + } +} + +setInterval(function() { + ReactDOM.render( + , + document.getElementById('example') + ); +}, 500); diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ttcn3 b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ttcn3 new file mode 100644 index 0000000..969107d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/ttcn3 @@ -0,0 +1,6 @@ +module DNSTester { + type integer Identification( 0..65535 ); // 16-bit integer + type enumerated MessageKind {e_Question, e_Answer}; + type charstring Question; + type charstring Answer; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tulip b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tulip new file mode 100644 index 0000000..8c18ccf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/tulip @@ -0,0 +1,13 @@ +@module ref + +ref value = Ref (spawn [ ! => loop value ]) + +loop value = receive [ + .set new-value => loop new-value + p, id, .get => { send p (id, value); loop value } +] + +@object Ref pid [ + set val = .set val > send pid + get! = .get > send-wait pid +] diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/turtle b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/turtle new file mode 100644 index 0000000..8c86d0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/turtle @@ -0,0 +1,26 @@ +@prefix xsd: +@prefix dcat: . +@prefix dcterms: . +@prefix foaf: . +@base . + +PREFIX test: +PrEfIx insensitive: + +GRAPH { + a dcat:Dataset ; + +#-----Mandatory-----# + + dcterms:title 'Test title'@cs, "Test title"@en ; + dcterms:description """Multiline + string"""@cs, '''Another + multiline string '''@en ; + +#-----Recommended-----# + dcat:contactPoint [ a foaf:Person ] ; + test:list ( 1 1.1 +1 -1 1.2E+4 "Test" "\"Quote\"" ) ; + test:datatype "2016-07-20"^^xsd:date ; + test:text """next multiline"""; + . +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/twig b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/twig new file mode 100644 index 0000000..2e5e577 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/twig @@ -0,0 +1,9 @@ +{% include 'header.html' %} + +{% for user in users %} + * {{ user.name }} +{% else %} + No users have been found. +{% endfor %} + +{% include 'footer.html' %} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/typescript b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/typescript new file mode 100644 index 0000000..134a70e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/typescript @@ -0,0 +1 @@ +$(document).ready(function() { alert('ready!'); }); diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vala b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vala new file mode 100644 index 0000000..2989be0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vala @@ -0,0 +1,8 @@ +class Demo.HelloWorld : GLib.Object +{ + public static int main (String[] args) + { + stdout.printf("Hello World\n"); + return 0; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vb new file mode 100644 index 0000000..f7e323d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vb @@ -0,0 +1,4 @@ +Private Sub Form_Load() + ' Execute a simple message box that says "Hello, World!" + MsgBox "Hello, World!" +End Sub diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vcl b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vcl new file mode 100644 index 0000000..75c8eea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vcl @@ -0,0 +1,12 @@ +vcl 4.0; + +backend server1 { + .host = "server1.example.com"; + .probe = { + .url = "/"; + .timeout = 1s; + .interval = 5s; + .window = 5; + .threshold = 3; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/velocity b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/velocity new file mode 100644 index 0000000..845776b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/velocity @@ -0,0 +1,9 @@ +#* + There is multi-line comment. + see this text because the Velocity Templating Engine will ignore it. +*# +

    List

    +## This is a single line comment. +#if( $allProducts ) +

    not found.

    +#end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/verilog b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/verilog new file mode 100644 index 0000000..7f752c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/verilog @@ -0,0 +1,27 @@ +/** + * Verilog Lexer + */ +module Foo( + input logic Clk_CI, + input logic Rst_RBI, + input logic A, + input logic B, + output logic C +); + logic C_DN, C_DP; + + assign C = C_DP; + + always_comb begin : proc_next_state + C_DN = A + B; + end + + // Clocked process + always_ff @(posedge Clk_CI, negedge Rst_RBI) begin + if(~Rst_RBI) begin + C_DP <= 1'b0; + end else begin + C_DP <= C_DN; + end + end +endmodule diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vhdl b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vhdl new file mode 100644 index 0000000..9355b50 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vhdl @@ -0,0 +1,23 @@ +entity toggle_demo is + port ( + clk_in : in std_logic; -- System Clock + data_q : out std_logic -- Toggling Port + ); +end entity toggle_demo; + +architecture RTL of toggle_demo is + signal data : std_logic := '0'; +begin + + data_q <= data; + + data_proc : process (clk_in) + begin + + if (rising_edge(clk_in)) then + data <= not data; + end if; + + end process; + +end architecture RTL; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/viml b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/viml new file mode 100644 index 0000000..93a364b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/viml @@ -0,0 +1,14 @@ +function! s:Make(dir, make, format, name) abort + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd' + let cwd = getcwd() + let [mp, efm, cc] = [&l:mp, &l:efm, get(b:, 'current_compiler', '')] + try + execute cd fnameescape(dir) + let [&l:mp, &l:efm, b:current_compiler] = [a:make, a:format, a:compiler] + execute (exists(':Make') == 2 ? 'Make' : 'make') + finally + let [&l:mp, &l:efm, b:current_compiler] = [mp, efm, cc] + if empty(cc) | unlet! b:current_compiler | endif + execute cd fnameescape(cwd) + endtry +endfunction diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vue b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vue new file mode 100644 index 0000000..8b54b28 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/vue @@ -0,0 +1,11 @@ + + + diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/wollok b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/wollok new file mode 100644 index 0000000..ae467f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/wollok @@ -0,0 +1,11 @@ +object pepita { + var energy = 100 + + method energy() = energy + + method fly(kilometers) { + energy -= kilometers + 10 + } + + method sayHi() = "Coo!" +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xml b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xml new file mode 100644 index 0000000..149844b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xml @@ -0,0 +1,2 @@ + + diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xojo b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xojo new file mode 100644 index 0000000..698a921 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xojo @@ -0,0 +1,14 @@ +Dim f As FolderItem +f = GetOpenFolderItem(FileTypes1.jpeg) // defined in the File Type Set editor +rem - we should check for nil! +If not f.Exists Then + Beep 'Just for fun + MsgBox("The file " + f.NativePath + "doesn't ""exist.""") +Else // document exists + ImageWell1.image=Picture.Open(f) +End If +if f isa folderitem then + msgbox(f.name) +end if +Exception err As NilObjectException + MsgBox("Invalid pathname!") diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xpath b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xpath new file mode 100644 index 0000000..ddc4b6a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xpath @@ -0,0 +1,2 @@ +(: Authors named Bob Joe who didn't graduate from Harvard :) +//author[first-name = "Joe" and last-name = "Bob"][degree/@from != "Harvard"] diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xquery b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xquery new file mode 100644 index 0000000..4f7b325 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/xquery @@ -0,0 +1,22 @@ +declare namespace html = "http://www.w3.org/1999/xhtml"; + +declare function local:test-function($catalog as document-node()) { + + + XQuery example for the Rouge highlighter + + + +

    List

    +
      + {for $product in $catalog/items/product[@sell-by > current-date()] return +
    • +
        +
      • {data($product/name)}
      • +
      • {$product/price * (1 + $product/tax)}$
      • +
      +
    • } +
    + + +}; diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yaml b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yaml new file mode 100644 index 0000000..2f622de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yaml @@ -0,0 +1,4 @@ +--- +one: Mark McGwire +two: Sammy Sosa +three: Ken Griffey diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yang b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yang new file mode 100644 index 0000000..c68ff7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/yang @@ -0,0 +1,17 @@ +module petstore { + namespace "http://autlan.dt/gribok/yang/example"; + prefix ex; + + revision 2020-04-01 { + description "Example yang"; + } + + container pets { + list dogs { + key name; + leaf name { + type string; + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/zig b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/zig new file mode 100644 index 0000000..8374aa4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/demos/zig @@ -0,0 +1,6 @@ +const std = @import("std"); +const warn = std.debug.warn; + +fn add_floats(x: f16, y: f16) f16 { + return x + y; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatter.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatter.rb new file mode 100644 index 0000000..a953812 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatter.rb @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + # A Formatter takes a token stream and formats it for human viewing. + class Formatter + # @private + REGISTRY = {} + + # Specify or get the unique tag for this formatter. This is used + # for specifying a formatter in `rougify`. + def self.tag(tag=nil) + return @tag unless tag + REGISTRY[tag] = self + + @tag = tag + end + + # Find a formatter class given a unique tag. + def self.find(tag) + REGISTRY[tag] + end + + def self.with_escape + Thread.current[:'rouge/with-escape'] = true + yield + ensure + Thread.current[:'rouge/with-escape'] = false + end + + def self.escape_enabled? + !!(((defined? @escape_enabled) && @escape_enabled) || Thread.current[:'rouge/with-escape']) + end + + def self.enable_escape! + @escape_enabled = true + end + + def self.disable_escape! + @escape_enabled = false + Thread.current[:'rouge/with-escape'] = false + end + + # Format a token stream. Delegates to {#format}. + def self.format(tokens, *args, **kwargs, &b) + new(*args, **kwargs).format(tokens, &b) + end + + def initialize(opts={}) + # pass + end + + def escape?(tok) + tok == Token::Tokens::Escape + end + + def filter_escapes(tokens) + tokens.each do |t, v| + if t == Token::Tokens::Escape + yield Token::Tokens::Error, v + else + yield t, v + end + end + end + + # Format a token stream. + def format(tokens, &b) + tokens = enum_for(:filter_escapes, tokens) unless Formatter.escape_enabled? + + return stream(tokens, &b) if block_given? + + out = String.new('') + stream(tokens) { |piece| out << piece } + + out + end + + # @deprecated Use {#format} instead. + def render(tokens) + warn 'Formatter#render is deprecated, use #format instead.' + format(tokens) + end + + # @abstract + # yield strings that, when concatenated, form the formatted output + def stream(tokens, &b) + raise 'abstract' + end + + protected + def token_lines(tokens, &b) + return enum_for(:token_lines, tokens) unless block_given? + + out = [] + tokens.each do |tok, val| + val.scan %r/\n|[^\n]+/ do |s| + if s == "\n" + yield out + out = [] + else + out << [tok, s] + end + end + end + + # for inputs not ending in a newline + yield out if out.any? + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html.rb new file mode 100644 index 0000000..643fd19 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html.rb @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + # Transforms a token stream into HTML output. + class HTML < Formatter + TABLE_FOR_ESCAPE_HTML = { + '&' => '&', + '<' => '<', + '>' => '>', + }.freeze + + ESCAPE_REGEX = /[&<>]/.freeze + + tag 'html' + + # @yield the html output. + def stream(tokens, &b) + tokens.each { |tok, val| yield span(tok, val) } + end + + def span(tok, val) + return val if escape?(tok) + + safe_span(tok, escape_special_html_chars(val)) + end + + def safe_span(tok, safe_val) + if tok == Token::Tokens::Text + safe_val + else + shortname = tok.shortname or raise "unknown token: #{tok.inspect} for #{safe_val.inspect}" + + "#{safe_val}" + end + end + + private + + # A performance-oriented helper method to escape `&`, `<` and `>` for the rendered + # HTML from this formatter. + # + # `String#gsub` will always return a new string instance irrespective of whether + # a substitution occurs. This method however invokes `String#gsub` only if + # a substitution is imminent. + # + # Returns either the given `value` argument string as is or a new string with the + # special characters replaced with their escaped counterparts. + def escape_special_html_chars(value) + return value unless value =~ ESCAPE_REGEX + + value.gsub(ESCAPE_REGEX, TABLE_FOR_ESCAPE_HTML) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_inline.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_inline.rb new file mode 100644 index 0000000..13f6e95 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_inline.rb @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + class HTMLInline < HTML + tag 'html_inline' + + def initialize(theme) + if theme.is_a?(Class) && theme < Rouge::Theme + @theme = theme.new + elsif theme.is_a?(Rouge::Theme) + @theme = theme + elsif theme.is_a?(String) + @theme = Rouge::Theme.find(theme).new + else + raise ArgumentError, "invalid theme: #{theme.inspect}" + end + end + + def safe_span(tok, safe_val) + return safe_val if tok == Token::Tokens::Text + + rules = @theme.style_for(tok).rendered_rules + + "#{safe_val}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_legacy.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_legacy.rb new file mode 100644 index 0000000..6cfe08b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_legacy.rb @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + # Transforms a token stream into HTML output. + class HTMLLegacy < Formatter + tag 'html_legacy' + + # @option opts [String] :css_class ('highlight') + # @option opts [true/false] :line_numbers (false) + # @option opts [Rouge::CSSTheme] :inline_theme (nil) + # @option opts [true/false] :wrap (true) + # + # Initialize with options. + # + # If `:inline_theme` is given, then instead of rendering the + # tokens as tags with CSS classes, the styles according to + # the given theme will be inlined in "style" attributes. This is + # useful for formats in which stylesheets are not available. + # + # Content will be wrapped in a tag (`div` if tableized, `pre` if + # not) with the given `:css_class` unless `:wrap` is set to `false`. + def initialize(opts={}) + @formatter = opts[:inline_theme] ? HTMLInline.new(opts[:inline_theme]) + : HTML.new + + + @formatter = HTMLTable.new(@formatter, opts) if opts[:line_numbers] + + if opts.fetch(:wrap, true) + @formatter = HTMLPygments.new(@formatter, opts.fetch(:css_class, 'codehilite')) + end + end + + # @yield the html output. + def stream(tokens, &b) + @formatter.stream(tokens, &b) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_highlighter.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_highlighter.rb new file mode 100644 index 0000000..2fffec0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_highlighter.rb @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + class HTMLLineHighlighter < Formatter + tag 'html_line_highlighter' + + def initialize(delegate, opts = {}) + @delegate = delegate + @highlight_line_class = opts.fetch(:highlight_line_class, 'hll') + @highlight_lines = opts[:highlight_lines] || [] + end + + def stream(tokens) + token_lines(tokens).with_index(1) do |line_tokens, lineno| + line = %(#{@delegate.format(line_tokens)}\n) + line = %(#{line}) if @highlight_lines.include? lineno + yield line + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_table.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_table.rb new file mode 100644 index 0000000..bb21584 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_line_table.rb @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + class HTMLLineTable < Formatter + tag 'html_line_table' + + # @param [Rouge::Formatters::Formatter] formatter An instance of a + # `Rouge::Formatters::HTML` or `Rouge::Formatters::HTMLInline` + # @param [Hash] opts options for HTMLLineTable instance. + # @option opts [Integer] :start_line line number to start from. Defaults to `1`. + # @option opts [String] :table_class Class name for the table. + # Defaults to `"rouge-line-table"`. + # @option opts [String] :line_id a `sprintf` template for generating an `id` + # attribute for each table row corresponding to current line number. + # Defaults to `"line-%i"`. + # @option opts [String] :line_class Class name for each table row. + # Defaults to `"lineno"`. + # @option opts [String] :gutter_class Class name for rendered line-number cell. + # Defaults to `"rouge-gutter"`. + # @option opts [String] :code_class Class name for rendered code cell. + # Defaults to `"rouge-code"`. + def initialize(formatter, opts={}) + @formatter = formatter + @start_line = opts.fetch :start_line, 1 + @table_class = opts.fetch :table_class, 'rouge-line-table' + @gutter_class = opts.fetch :gutter_class, 'rouge-gutter' + @code_class = opts.fetch :code_class, 'rouge-code' + @line_class = opts.fetch :line_class, 'lineno' + @line_id = opts.fetch :line_id, 'line-%i' + end + + def stream(tokens, &b) + buffer = [%()] + token_lines(tokens).with_index(@start_line) do |line_tokens, lineno| + buffer << %() + buffer << %() + buffer << %(" + end + buffer << %(
    ) + buffer << %(
    #{lineno}
    )
    +          @formatter.stream(line_tokens) { |formatted| buffer << formatted }
    +          buffer << "\n
    ) + yield buffer.join + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_linewise.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_linewise.rb new file mode 100644 index 0000000..dc58d91 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_linewise.rb @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + class HTMLLinewise < Formatter + def initialize(formatter, opts={}) + @formatter = formatter + @tag_name = opts.fetch(:tag_name, 'div') + @class_format = opts.fetch(:class, 'line-%i') + end + + def stream(tokens, &b) + token_lines(tokens).with_index(1) do |line_tokens, lineno| + yield %(<#{@tag_name} class="#{sprintf @class_format, lineno}">) + @formatter.stream(line_tokens) {|formatted| yield formatted } + yield %(\n) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_pygments.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_pygments.rb new file mode 100644 index 0000000..8ed8f54 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_pygments.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Rouge + module Formatters + class HTMLPygments < Formatter + def initialize(inner, css_class='codehilite') + @inner = inner + @css_class = css_class + end + + def stream(tokens, &b) + yield %(
    )
    +        @inner.stream(tokens, &b)
    +        yield "
    " + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_table.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_table.rb new file mode 100644 index 0000000..fa9a181 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/html_table.rb @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + class HTMLTable < Formatter + tag 'html_table' + + def initialize(inner, opts={}) + @inner = inner + @start_line = opts.fetch(:start_line, 1) + @line_format = opts.fetch(:line_format, '%i') + @table_class = opts.fetch(:table_class, 'rouge-table') + @gutter_class = opts.fetch(:gutter_class, 'rouge-gutter') + @code_class = opts.fetch(:code_class, 'rouge-code') + end + + def style(scope) + yield %(#{scope} .rouge-table { border-spacing: 0 }) + yield %(#{scope} .rouge-gutter { text-align: right }) + end + + def stream(tokens, &b) + last_val = nil + num_lines = tokens.reduce(0) {|count, (_, val)| count + (last_val = val).count(?\n) } + formatted = @inner.format(tokens) + unless last_val && last_val.end_with?(?\n) + num_lines += 1 + formatted << ?\n + end + + # generate a string of newline-separated line numbers for the gutter> + formatted_line_numbers = (@start_line..(@start_line + num_lines - 1)).map do |i| + sprintf(@line_format, i) + end.join(?\n) << ?\n + + buffer = [%()] + # the "gl" class applies the style for Generic.Lineno + buffer << %(' + buffer << %(' + buffer << '
    ) + buffer << %(
    #{formatted_line_numbers}
    ) + buffer << '
    )
    +        buffer << formatted
    +        buffer << '
    ' + + yield buffer.join + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/null.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/null.rb new file mode 100644 index 0000000..078c461 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/null.rb @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + # A formatter which renders nothing. + class Null < Formatter + tag 'null' + + def initialize(*) + end + + def stream(tokens, &b) + tokens.each do |tok, val| + yield "#{tok.qualname} #{val.inspect}\n" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal256.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal256.rb new file mode 100644 index 0000000..140d53c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal256.rb @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + # A formatter for 256-color terminals + class Terminal256 < Formatter + tag 'terminal256' + + # @private + attr_reader :theme + + # @param [Hash,Rouge::Theme] theme + # the theme to render with. + def initialize(theme = Themes::ThankfulEyes.new) + if theme.is_a?(Rouge::Theme) + @theme = theme + elsif theme.is_a?(Hash) + @theme = theme[:theme] || Themes::ThankfulEyes.new + else + raise ArgumentError, "invalid theme: #{theme.inspect}" + end + end + + def stream(tokens, &b) + tokens.each do |tok, val| + escape_sequence(tok).stream_value(val, &b) + end + end + + class EscapeSequence + attr_reader :style + def initialize(style) + @style = style + end + + def self.xterm_colors + @xterm_colors ||= [].tap do |out| + # colors 0..15: 16 basic colors + out << [0x00, 0x00, 0x00] # 0 + out << [0xcd, 0x00, 0x00] # 1 + out << [0x00, 0xcd, 0x00] # 2 + out << [0xcd, 0xcd, 0x00] # 3 + out << [0x00, 0x00, 0xee] # 4 + out << [0xcd, 0x00, 0xcd] # 5 + out << [0x00, 0xcd, 0xcd] # 6 + out << [0xe5, 0xe5, 0xe5] # 7 + out << [0x7f, 0x7f, 0x7f] # 8 + out << [0xff, 0x00, 0x00] # 9 + out << [0x00, 0xff, 0x00] # 10 + out << [0xff, 0xff, 0x00] # 11 + out << [0x5c, 0x5c, 0xff] # 12 + out << [0xff, 0x00, 0xff] # 13 + out << [0x00, 0xff, 0xff] # 14 + out << [0xff, 0xff, 0xff] # 15 + + # colors 16..232: the 6x6x6 color cube + valuerange = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff] + + 217.times do |i| + r = valuerange[(i / 36) % 6] + g = valuerange[(i / 6) % 6] + b = valuerange[i % 6] + out << [r, g, b] + end + + # colors 233..253: grayscale + 1.upto 22 do |i| + v = 8 + i * 10 + out << [v, v, v] + end + end + end + + def fg + return @fg if instance_variable_defined? :@fg + @fg = style.fg && self.class.color_index(style.fg) + end + + def bg + return @bg if instance_variable_defined? :@bg + @bg = style.bg && self.class.color_index(style.bg) + end + + + def stream_value(val, &b) + yield style_string + yield val.gsub("\e", "\\e") + .gsub("\n", "#{reset_string}\n#{style_string}") + yield reset_string + end + + def style_string + @style_string ||= begin + attrs = [] + + attrs << ['38', '5', fg.to_s] if fg + attrs << ['48', '5', bg.to_s] if bg + attrs << '01' if style[:bold] + attrs << '04' if style[:italic] # underline, but hey, whatevs + escape(attrs) + end + end + + def reset_string + @reset_string ||= begin + attrs = [] + attrs << '39' if fg # fg reset + attrs << '49' if bg # bg reset + attrs << '00' if style[:bold] || style[:italic] + + escape(attrs) + end + end + + private + def escape(attrs) + return '' if attrs.empty? + "\e[#{attrs.join(';')}m" + end + + def self.color_index(color) + @color_index_cache ||= {} + @color_index_cache[color] ||= closest_color(*get_rgb(color)) + end + + def self.get_rgb(color) + color = $1 if color =~ /#([0-9a-f]+)/i + hexes = case color.size + when 3 + color.chars.map { |c| "#{c}#{c}" } + when 6 + color.scan(/../) + else + raise "invalid color: #{color}" + end + + hexes.map { |h| h.to_i(16) } + end + + # max distance between two colors, #000000 to #ffffff + MAX_DISTANCE = 257 * 257 * 3 + + def self.closest_color(r, g, b) + @@colors_cache ||= {} + key = (r << 16) + (g << 8) + b + @@colors_cache.fetch(key) do + distance = MAX_DISTANCE + + match = 0 + + xterm_colors.each_with_index do |(cr, cg, cb), i| + d = (r - cr)**2 + (g - cg)**2 + (b - cb)**2 + next if d >= distance + + match = i + distance = d + end + + match + end + end + end + + class Unescape < EscapeSequence + def initialize(*) end + def style_string(*) '' end + def reset_string(*) '' end + def stream_value(val) yield val end + end + + # private + def escape_sequence(token) + return Unescape.new if escape?(token) + @escape_sequences ||= {} + @escape_sequences[token.qualname] ||= + make_escape_sequence(get_style(token)) + end + + def make_escape_sequence(style) + EscapeSequence.new(style) + end + + def get_style(token) + return text_style if token.ancestors.include? Token::Tokens::Text + + theme.get_own_style(token) || text_style + end + + def text_style + style = theme.get_style(Token['Text']) + # don't highlight text backgrounds + style.delete :bg + style + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal_truecolor.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal_truecolor.rb new file mode 100644 index 0000000..07feab0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/terminal_truecolor.rb @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true +module Rouge + module Formatters + class TerminalTruecolor < Terminal256 + tag 'terminal_truecolor' + + class TruecolorEscapeSequence < Terminal256::EscapeSequence + def style_string + @style_string ||= begin + out = String.new('') + out << escape(['48', '2', *get_rgb(style.bg)]) if style.bg + out << escape(['38', '2', *get_rgb(style.fg)]) if style.fg + out << escape(['1']) if style[:bold] || style[:italic] + out + end + end + + def get_rgb(color) + color = $1 if color =~ /#(\h+)/ + + case color.size + when 3 then color.chars.map { |c| c.to_i(16) * 2 } + when 6 then color.scan(/../).map { |cc| cc.to_i(16) } + else + raise "invalid color: #{color.inspect}" + end + end + end + + # @override + def make_escape_sequence(style) + TruecolorEscapeSequence.new(style) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/tex.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/tex.rb new file mode 100644 index 0000000..e42c2bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/formatters/tex.rb @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Formatters + class Tex < Formatter + tag 'tex' + + # A map of TeX escape characters. + # Newlines are handled specially by using #token_lines + # spaces are preserved as long as they aren't at the beginning + # of a line. see #tag_first for our initial-space strategy + ESCAPE = { + '&' => '\&', + '%' => '\%', + '$' => '\$', + '#' => '\#', + '_' => '\_', + '{' => '\{', + '}' => '\}', + '~' => '{\textasciitilde}', + '^' => '{\textasciicircum}', + '|' => '{\textbar}', + '\\' => '{\textbackslash}', + '`' => '{\textasciigrave}', + "'" => "'{}", + '"' => '"{}', + "\t" => '{\tab}', + } + + ESCAPE_REGEX = /[#{ESCAPE.keys.map(&Regexp.method(:escape)).join}]/om + + def initialize(opts={}) + @prefix = opts.fetch(:prefix) { 'RG' } + end + + def escape_tex(str) + str.gsub(ESCAPE_REGEX, ESCAPE) + end + + def stream(tokens, &b) + # surround the output with \begin{RG*}...\end{RG*} + yield "\\begin{#{@prefix}*}%\n" + + # we strip the newline off the last line to avoid + # an extra line being rendered. we do this by yielding + # the \newline tag *before* every line group except + # the first. + first = true + + token_lines tokens do |line| + if first + first = false + else + yield "\\newline%\n" + end + + render_line(line, &b) + end + + yield "%\n\\end{#{@prefix}*}%\n" + end + + def render_line(line, &b) + line.each do |(tok, val)| + hphantom_tag(tok, val, &b) + end + end + + # Special handling for leading spaces, since they may be gobbled + # by a previous command. We replace all initial spaces with + # \hphantom{xxxx}, which renders an empty space equal to the size + # of the x's. + def hphantom_tag(tok, val) + leading = nil + val.sub!(/^[ ]+/) { leading = $&.size; '' } + yield "\\hphantom{#{'x' * leading}}" if leading + yield tag(tok, val) unless val.empty? + end + + def tag(tok, val) + if escape?(tok) + val + elsif tok == Token::Tokens::Text + escape_tex(val) + else + "\\#@prefix{#{tok.shortname}}{#{escape_tex(val)}}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guesser.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guesser.rb new file mode 100644 index 0000000..7cfc3e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guesser.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Rouge + class Guesser + class Ambiguous < StandardError + attr_reader :alternatives + def initialize(alternatives); @alternatives = alternatives; end + + def message + "Ambiguous guess: can't decide between #{alternatives.map(&:tag).inspect}" + end + end + + def self.guess(guessers, lexers) + original_size = lexers.size + + guessers.each do |g| + new_lexers = case g + when Guesser then g.filter(lexers) + when proc { |x| x.respond_to? :call } then g.call(lexers) + else raise "bad guesser: #{g}" + end + + lexers = new_lexers && new_lexers.any? ? new_lexers : lexers + end + + # if we haven't filtered the input at *all*, + # then we have no idea what language it is, + # so we bail and return []. + lexers.size < original_size ? lexers : [] + end + + def collect_best(lexers, opts={}, &scorer) + best = [] + best_score = opts[:threshold] + + lexers.each do |lexer| + score = scorer.call(lexer) + + next if score.nil? + + if best_score.nil? || score > best_score + best_score = score + best = [lexer] + elsif score == best_score + best << lexer + end + end + + best + end + + def filter(lexers) + raise 'abstract' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/disambiguation.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/disambiguation.rb new file mode 100644 index 0000000..202eb0e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/disambiguation.rb @@ -0,0 +1,172 @@ +# frozen_string_literal: true + +module Rouge + module Guessers + class Disambiguation < Guesser + include Util + include Lexers + + def initialize(filename, source) + @filename = File.basename(filename) + @source = source + end + + def filter(lexers) + return lexers if lexers.size == 1 + return lexers if lexers.size == Lexer.all.size + + @analyzer = TextAnalyzer.new(get_source(@source)) + + self.class.disambiguators.each do |disambiguator| + next unless disambiguator.match?(@filename) + + filtered = disambiguator.decide!(self) + return filtered if filtered + end + + return lexers + end + + def contains?(text) + return @analyzer.include?(text) + end + + def matches?(re) + return !!(@analyzer =~ re) + end + + @disambiguators = [] + def self.disambiguate(*patterns, &decider) + @disambiguators << Disambiguator.new(patterns, &decider) + end + + def self.disambiguators + @disambiguators + end + + class Disambiguator + include Util + + def initialize(patterns, &decider) + @patterns = patterns + @decider = decider + end + + def decide!(guesser) + out = guesser.instance_eval(&@decider) + case out + when Array then out + when nil then nil + else [out] + end + end + + def match?(filename) + @patterns.any? { |p| test_glob(p, filename) } + end + end + + disambiguate '*.cfg' do + next CiscoIos if matches?(/\A\s*(version|banner|interface)\b/) + + INI + end + + disambiguate '*.pl' do + next Perl if contains?('my $') + next Prolog if contains?(':-') + next Prolog if matches?(/\A\w+(\(\w+\,\s*\w+\))*\./) + end + + disambiguate '*.h' do + next ObjectiveC if matches?(/@(end|implementation|protocol|property)\b/) + next ObjectiveC if contains?('@"') + next Cpp if matches?(/^\s*(?:catch|class|constexpr|namespace|private| + protected|public|template|throw|try|using)\b/x) + + C + end + + disambiguate '*.m' do + next ObjectiveC if matches?(/@(end|implementation|protocol|property)\b/) + next ObjectiveC if contains?('@"') + + # Objective-C dereferenced pointers and Mathematica comments are similar. + # Disambiguate for Mathematica by looking for any amount of whitespace (or no whitespace) + # followed by "(*" (e.g. `(* comment *)`). + next Mathematica if matches?(/^\s*\(\*/) + + # Disambiguate for objc by looking for a deref'd pointer in a statement (e.g. `if (*foo == 0)`). + # This pattern is less specific than the Mathematica pattern, so its positioned after it. + next ObjectiveC if matches?(/^\s*(if|while|for|switch|do)\s*\([^)]*\*[^)]*\)/) + + next Mathematica if contains?(':=') + + next Mason if matches?(/<%(def|method|text|doc|args|flags|attr|init|once|shared|perl|cleanup|filter)([^>]*)(>)/) + + next Matlab if matches?(/^\s*?%/) + # Matlab cell array creation: data = { + next Matlab if matches?(/^\s*[a-zA-Z]\w*\s*=\s*\{/) + + next Mason if matches? %r!( lexer name mappings + class GlobMapping < Guesser + include Util + + def self.by_pairs(mapping, filename) + glob_map = {} + mapping.each do |(glob, lexer_name)| + lexer = Lexer.find(lexer_name) + + # ignore unknown lexers + next unless lexer + + glob_map[lexer.name] ||= [] + glob_map[lexer.name] << glob + end + + new(glob_map, filename) + end + + attr_reader :glob_map, :filename + def initialize(glob_map, filename) + @glob_map = glob_map + @filename = filename + end + + def filter(lexers) + basename = File.basename(filename) + + collect_best(lexers) do |lexer| + (@glob_map[lexer.name] || []).map do |pattern| + if test_glob(pattern, basename) + # specificity is better the fewer wildcards there are + -pattern.scan(/[*?\[]/).size + end + end.compact.min + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/mimetype.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/mimetype.rb new file mode 100644 index 0000000..92a1d43 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/mimetype.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Rouge + module Guessers + class Mimetype < Guesser + attr_reader :mimetype + def initialize(mimetype) + @mimetype = mimetype + end + + def filter(lexers) + lexers.select { |lexer| lexer.mimetypes.include? @mimetype } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/modeline.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/modeline.rb new file mode 100644 index 0000000..9754798 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/modeline.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Rouge + module Guessers + class Modeline < Guesser + include Util + + # [jneen] regexen stolen from linguist + EMACS_MODELINE = /-\*-\s*(?:(?!mode)[\w-]+\s*:\s*(?:[\w+-]+)\s*;?\s*)*(?:mode\s*:)?\s*([\w+-]+)\s*(?:;\s*(?!mode)[\w-]+\s*:\s*[\w+-]+\s*)*;?\s*-\*-/i + + # First form vim modeline + # [text]{white}{vi:|vim:|ex:}[white]{options} + # ex: 'vim: syntax=ruby' + VIM_MODELINE_1 = /(?:vim|vi|ex):\s*(?:ft|filetype|syntax)=(\w+)\s?/i + + # Second form vim modeline (compatible with some versions of Vi) + # [text]{white}{vi:|vim:|Vim:|ex:}[white]se[t] {options}:[text] + # ex: 'vim set syntax=ruby:' + VIM_MODELINE_2 = /(?:vim|vi|Vim|ex):\s*se(?:t)?.*\s(?:ft|filetype|syntax)=(\w+)\s?.*:/i + + MODELINES = [EMACS_MODELINE, VIM_MODELINE_1, VIM_MODELINE_2] + + def initialize(source, opts={}) + @source = source + @lines = opts[:lines] || 5 + end + + def filter(lexers) + # don't bother reading the stream if we've already decided + return lexers if lexers.size == 1 + + source_text = get_source(@source) + + lines = source_text.split(/\n/) + + search_space = (lines.first(@lines) + lines.last(@lines)).join("\n") + + matches = MODELINES.map { |re| re.match(search_space) }.compact + return lexers unless matches.any? + + match_set = Set.new(matches.map { |m| m[1] }) + lexers.select { |l| match_set.include?(l.tag) || l.aliases.any? { |a| match_set.include?(a) } } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/source.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/source.rb new file mode 100644 index 0000000..90a51cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/source.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Rouge + module Guessers + class Source < Guesser + include Util + + attr_reader :source + def initialize(source) + @source = source + end + + def filter(lexers) + # don't bother reading the input if + # we've already filtered to 1 + return lexers if lexers.size == 1 + + source_text = get_source(@source) + + Lexer.assert_utf8!(source_text) + + source_text = TextAnalyzer.new(source_text) + + collect_best(lexers) do |lexer| + next unless lexer.detectable? + lexer.detect?(source_text) ? 1 : nil + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/util.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/util.rb new file mode 100644 index 0000000..89c50be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/guessers/util.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Rouge + module Guessers + module Util + module SourceNormalizer + UTF8_BOM = "\xEF\xBB\xBF" + UTF8_BOM_RE = /\A#{UTF8_BOM}/ + + # @param [String,nil] source + # @return [String,nil] + def self.normalize(source) + source.sub(UTF8_BOM_RE, '').gsub(/\r\n/, "\n") + end + end + + def test_glob(pattern, path) + File.fnmatch?(pattern, path, File::FNM_DOTMATCH | File::FNM_CASEFOLD) + end + + # @param [String,IO] source + # @return [String] + def get_source(source) + if source.respond_to?(:to_str) + SourceNormalizer.normalize(source.to_str) + elsif source.respond_to?(:read) + SourceNormalizer.normalize(source.read) + else + raise ArgumentError, "Invalid source: #{source.inspect}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexer.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexer.rb new file mode 100644 index 0000000..e191dfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexer.rb @@ -0,0 +1,537 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# stdlib +require 'strscan' +require 'set' +require 'uri' + +module Rouge + # @abstract + # A lexer transforms text into a stream of `[token, chunk]` pairs. + class Lexer + include Token::Tokens + + @option_docs = {} + + class << self + # Lexes `stream` with the given options. The lex is delegated to a + # new instance. + # + # @see #lex + def lex(stream, opts={}, &b) + new(opts).lex(stream, &b) + end + + # In case #continue_lex is called statically, we simply + # begin a new lex from the beginning, since there is no state. + # + # @see #continue_lex + def continue_lex(*a, &b) + lex(*a, &b) + end + + # Given a name in string, return the correct lexer class. + # @param [String] name + # @return [Class,nil] + def find(name) + registry[name.to_s] + end + + # Same as ::find_fancy, except instead of returning an instantiated + # lexer, returns a pair of [lexer_class, options], so that you can + # modify or provide additional options to the lexer. + # + # Please note: the lexer class might be nil! + def lookup_fancy(str, code=nil, default_options={}) + if str && !str.include?('?') && str != 'guess' + lexer_class = find(str) + return [lexer_class, default_options] + end + + name, opts = str ? str.split('?', 2) : [nil, ''] + + # parse the options hash from a cgi-style string + cgi_opts = Hash.new { |hash, key| hash[key] = [] } + URI.decode_www_form(opts || '').each do |k, val| + cgi_opts[k] << val + end + cgi_opts.transform_values! do |vals| + case vals.size + when 0 then true + when 1 then vals[0] + else vals + end + end + + opts = default_options.merge(cgi_opts) + + lexer_class = case name + when 'guess', nil + self.guess(:source => code, :mimetype => opts['mimetype']) + when String + self.find(name) + end + + [lexer_class, opts] + end + + # Find a lexer, with fancy shiny features. + # + # * The string you pass can include CGI-style options + # + # Lexer.find_fancy('erb?parent=tex') + # + # * You can pass the special name 'guess' so we guess for you, + # and you can pass a second argument of the code to guess by + # + # Lexer.find_fancy('guess', "#!/bin/bash\necho Hello, world") + # + # If the code matches more than one lexer then Guesser::Ambiguous + # is raised. + # + # This is used in the Redcarpet plugin as well as Rouge's own + # markdown lexer for highlighting internal code blocks. + # + def find_fancy(str, code=nil, default_options={}) + lexer_class, opts = lookup_fancy(str, code, default_options) + + lexer_class && lexer_class.new(opts) + end + + # Specify or get this lexer's title. Meant to be human-readable. + def title(t=nil) + if t.nil? + t = tag.capitalize + end + @title ||= t + end + + # Specify or get this lexer's description. + def desc(arg=:absent) + if arg == :absent + @desc + else + @desc = arg + end + end + + def option_docs + @option_docs ||= InheritableHash.new(superclass.option_docs) + end + + def option(name, desc) + option_docs[name.to_s] = desc + end + + # Specify or get the path name containing a small demo for + # this lexer (can be overriden by {demo}). + def demo_file(arg=:absent) + return @demo_file = Pathname.new(arg) unless arg == :absent + + @demo_file = Pathname.new(File.join(__dir__, 'demos', tag)) + end + + # Specify or get a small demo string for this lexer + def demo(arg=:absent) + return @demo = arg unless arg == :absent + + @demo = File.read(demo_file, mode: 'rt:bom|utf-8') + end + + # @return a list of all lexers. + def all + @all ||= registry.values.uniq + end + + # Guess which lexer to use based on a hash of info. + # + # This accepts the same arguments as Lexer.guess, but will never throw + # an error. It will return a (possibly empty) list of potential lexers + # to use. + def guesses(info={}) + mimetype, filename, source = info.values_at(:mimetype, :filename, :source) + custom_globs = info[:custom_globs] + + guessers = (info[:guessers] || []).dup + + guessers << Guessers::Mimetype.new(mimetype) if mimetype + guessers << Guessers::GlobMapping.by_pairs(custom_globs, filename) if custom_globs && filename + guessers << Guessers::Filename.new(filename) if filename + guessers << Guessers::Modeline.new(source) if source + guessers << Guessers::Source.new(source) if source + guessers << Guessers::Disambiguation.new(filename, source) if source && filename + + Guesser.guess(guessers, Lexer.all) + end + + # Guess which lexer to use based on a hash of info. + # + # @option info :mimetype + # A mimetype to guess by + # @option info :filename + # A filename to guess by + # @option info :source + # The source itself, which, if guessing by mimetype or filename + # fails, will be searched for shebangs, tags, and + # other hints. + # @param [Proc] fallback called if multiple lexers are detected. + # If omitted, Guesser::Ambiguous is raised. + # + # @see Lexer.detect? + # @see Lexer.guesses + # @return [Class] + def guess(info={}, &fallback) + lexers = guesses(info) + + return Lexers::PlainText if lexers.empty? + return lexers[0] if lexers.size == 1 + + if fallback + fallback.call(lexers) + else + raise Guesser::Ambiguous.new(lexers) + end + end + + def guess_by_mimetype(mt) + guess :mimetype => mt + end + + def guess_by_filename(fname) + guess :filename => fname + end + + def guess_by_source(source) + guess :source => source + end + + def enable_debug! + @debug_enabled = true + end + + def disable_debug! + remove_instance_variable :@debug_enabled if defined? @debug_enabled + end + + def debug_enabled? + (defined? @debug_enabled) ? true : false + end + + # Determine if a lexer has a method named +:detect?+ defined in its + # singleton class. + def detectable? + return @detectable if defined?(@detectable) + @detectable = singleton_methods(false).include?(:detect?) + end + + protected + # @private + def register(name, lexer) + # reset an existing list of lexers + @all = nil if defined?(@all) + registry[name.to_s] = lexer + end + + public + # Used to specify or get the canonical name of this lexer class. + # + # @example + # class MyLexer < Lexer + # tag 'foo' + # end + # + # MyLexer.tag # => 'foo' + # + # Lexer.find('foo') # => MyLexer + def tag(t=nil) + return @tag if t.nil? + + @tag = t.to_s + Lexer.register(@tag, self) + end + + # Used to specify alternate names this lexer class may be found by. + # + # @example + # class Erb < Lexer + # tag 'erb' + # aliases 'eruby', 'rhtml' + # end + # + # Lexer.find('eruby') # => Erb + def aliases(*args) + args.map!(&:to_s) + args.each { |arg| Lexer.register(arg, self) } + (@aliases ||= []).concat(args) + end + + # Specify a list of filename globs associated with this lexer. + # + # If a filename glob is associated with more than one lexer, this can + # cause a Guesser::Ambiguous error to be raised in various guessing + # methods. These errors can be avoided by disambiguation. Filename globs + # are disambiguated in one of two ways. Either the lexer will define a + # `self.detect?` method (intended for use with shebangs and doctypes) or a + # manual rule will be specified in Guessers::Disambiguation. + # + # @example + # class Ruby < Lexer + # filenames '*.rb', '*.ruby', 'Gemfile', 'Rakefile' + # end + def filenames(*fnames) + (@filenames ||= []).concat(fnames) + end + + # Specify a list of mimetypes associated with this lexer. + # + # @example + # class Html < Lexer + # mimetypes 'text/html', 'application/xhtml+xml' + # end + def mimetypes(*mts) + (@mimetypes ||= []).concat(mts) + end + + # @private + def assert_utf8!(str) + encoding = str.encoding + return if encoding == Encoding::US_ASCII || encoding == Encoding::UTF_8 || encoding == Encoding::BINARY + + raise EncodingError.new( + "Bad encoding: #{str.encoding.names.join(',')}. " + + "Please convert your string to UTF-8." + ) + end + + private + def registry + @registry ||= {} + end + end + + # -*- instance methods -*- # + + attr_reader :options + # Create a new lexer with the given options. Individual lexers may + # specify extra options. The only current globally accepted option + # is `:debug`. + # + # @option opts :debug + # Prints debug information to stdout. The particular info depends + # on the lexer in question. In regex lexers, this will log the + # state stack at the beginning of each step, along with each regex + # tried and each stream consumed. Try it, it's pretty useful. + def initialize(opts={}) + @options = {} + opts.each { |k, v| @options[k.to_s] = v } + + @debug = Lexer.debug_enabled? && bool_option('debug') + end + + # Returns a new lexer with the given options set. Useful for e.g. setting + # debug flags post hoc, or providing global overrides for certain options + def with(opts={}) + new_options = @options.dup + opts.each { |k, v| new_options[k.to_s] = v } + self.class.new(new_options) + end + + def as_bool(val) + case val + when nil, false, 0, '0', 'false', 'off' + false + when Array + val.empty? ? true : as_bool(val.last) + else + true + end + end + + def as_string(val) + return as_string(val.last) if val.is_a?(Array) + + val ? val.to_s : nil + end + + def as_list(val) + case val + when Array + val.flat_map { |v| as_list(v) } + when String + val.split(',') + else + [] + end + end + + def as_lexer(val) + return as_lexer(val.last) if val.is_a?(Array) + return val.new(@options) if val.is_a?(Class) && val < Lexer + + case val + when Lexer + val + when String + lexer_class = Lexer.find(val) + lexer_class && lexer_class.new(@options) + end + end + + def as_token(val) + return as_token(val.last) if val.is_a?(Array) + case val + when Token + val + else + Token[val] + end + end + + def bool_option(name, &default) + name_str = name.to_s + + if @options.key?(name_str) + as_bool(@options[name_str]) + else + default ? default.call : false + end + end + + def string_option(name, &default) + as_string(@options.delete(name.to_s, &default)) + end + + def lexer_option(name, &default) + as_lexer(@options.delete(name.to_s, &default)) + end + + def list_option(name, &default) + as_list(@options.delete(name.to_s, &default)) + end + + def token_option(name, &default) + as_token(@options.delete(name.to_s, &default)) + end + + def hash_option(name, defaults, &val_cast) + name = name.to_s + out = defaults.dup + + base = @options.delete(name.to_s) + base = {} unless base.is_a?(Hash) + base.each { |k, v| out[k.to_s] = val_cast ? val_cast.call(v) : v } + + @options.keys.each do |key| + next unless key =~ /(\w+)\[(\w+)\]/ and $1 == name + value = @options.delete(key) + + out[$2] = val_cast ? val_cast.call(value) : value + end + + out + end + + # @abstract + # + # Called after each lex is finished. The default implementation + # is a noop. + def reset! + end + + # Given a string, yield [token, chunk] pairs. If no block is given, + # an enumerator is returned. + # + # @option opts :continue + # Continue the lex from the previous state (i.e. don't call #reset!) + # + # @note The use of :continue => true has been deprecated. A warning is + # issued if run with `$VERBOSE` set to true. + # + # @note The use of arbitrary `opts` has never been supported, but we + # previously ignored them with no error. We now warn unconditionally. + def lex(string, opts=nil, &b) + if opts + if (opts.keys - [:continue]).size > 0 + # improper use of options hash + warn('Improper use of Lexer#lex - this method does not receive options.' + + ' This will become an error in a future version.') + end + + if opts[:continue] + warn '`lex :continue => true` is deprecated, please use #continue_lex instead' + return continue_lex(string, &b) + end + end + + return enum_for(:lex, string) unless block_given? + + Lexer.assert_utf8!(string) + reset! + + continue_lex(string, &b) + end + + # Continue the lex from the the current state without resetting + def continue_lex(string, &b) + return enum_for(:continue_lex, string, &b) unless block_given? + + # consolidate consecutive tokens of the same type + last_token = nil + last_val = nil + stream_tokens(string) do |tok, val| + next if val.empty? + + if tok == last_token + last_val << val + next + end + + b.call(last_token, last_val) if last_token + last_token = tok + last_val = val + end + + b.call(last_token, last_val) if last_token + end + + # delegated to {Lexer.tag} + def tag + self.class.tag + end + + # @abstract + # + # Yield `[token, chunk]` pairs, given a prepared input stream. This + # must be implemented. + # + # @param [StringScanner] stream + # the stream + def stream_tokens(stream, &b) + raise 'abstract' + end + + # @abstract + # + # Return true if there is an in-text indication (such as a shebang + # or DOCTYPE declaration) that this lexer should be used. + # + # @param [TextAnalyzer] text + # the text to be analyzed, with a couple of handy methods on it, + # like {TextAnalyzer#shebang?} and {TextAnalyzer#doctype?} + def self.detect?(text) + false + end + end + + module Lexers + BASE_DIR = "#{__dir__}/lexers".freeze + @_loaded_lexers = {} + + def self.load_lexer(relpath) + return if @_loaded_lexers.key?(relpath) + @_loaded_lexers[relpath] = true + Kernel::load File.join(BASE_DIR, relpath) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/abap.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/abap.rb new file mode 100644 index 0000000..8be9e95 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/abap.rb @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# ABAP elements taken from http://help.sap.com/abapdocu_750/en/index.htm?file=abapdo.htm + +module Rouge + module Lexers + class ABAP < RegexLexer + title "ABAP" + desc "SAP - Advanced Business Application Programming" + tag 'abap' + filenames '*.abap' + mimetypes 'text/x-abap' + + def self.keywords + @keywords = Set.new %w( + *-INPUT ?TO ABAP-SOURCE ABBREVIATED ABS ABSTRACT ACCEPT ACCEPTING + ACCORDING ACCP ACTIVATION ACTUAL ADD ADD-CORRESPONDING ADJACENT + AFTER ALIAS ALIASES ALIGN ALL ALLOCATE ALPHA ANALYSIS ANALYZER AND + ANY APPEND APPENDAGE APPENDING APPLICATION ARCHIVE AREA ARITHMETIC + AS ASCENDING ASPECT ASSERT ASSIGN ASSIGNED ASSIGNING ASSOCIATION + ASYNCHRONOUS AT ATTRIBUTES AUTHORITY AUTHORITY-CHECK AVG BACK + BACKGROUND BACKUP BACKWARD BADI BASE BEFORE BEGIN BETWEEN BIG BINARY + BINTOHEX BIT BIT-AND BIT-NOT BIT-OR BIT-XOR BLACK BLANK BLANKS BLOB + BLOCK BLOCKS BLUE BOUND BOUNDARIES BOUNDS BOXED BREAK-POINT BT + BUFFER BY BYPASSING BYTE BYTE-CA BYTE-CN BYTE-CO BYTE-CS BYTE-NA + BYTE-NS BYTE-ORDER CA CALL CALLING CASE CAST CASTING CATCH CEIL + CENTER CENTERED CHAIN CHAIN-INPUT CHAIN-REQUEST CHANGE CHANGING + CHANNELS CHAR CHAR-TO-HEX CHARACTER CHECK CHECKBOX CIRCULAR CLASS + CLASS-CODING CLASS-DATA CLASS-EVENTS CLASS-METHODS CLASS-POOL + CLEANUP CLEAR CLIENT CLNT CLOB CLOCK CLOSE CN CO COALESCE CODE + CODING COLLECT COLOR COLUMN COLUMNS COL_BACKGROUND COL_GROUP + COL_HEADING COL_KEY COL_NEGATIVE COL_NORMAL COL_POSITIVE COL_TOTAL + COMMENT COMMENTS COMMIT COMMON COMMUNICATION COMPARING COMPONENT + COMPONENTS COMPRESSION COMPUTE CONCAT CONCATENATE CONCAT_WITH_SPACE + COND CONDENSE CONDITION CONNECT CONNECTION CONSTANTS CONTEXT + CONTEXTS CONTINUE CONTROL CONTROLS CONV CONVERSION CONVERT COPIES + COPY CORRESPONDING COUNT COUNTRY COVER CP CPI CREATE CREATING + CRITICAL CS CUKY CURR CURRENCY CURRENCY_CONVERSION CURRENT CURSOR + CURSOR-SELECTION CUSTOMER CUSTOMER-FUNCTION CX_DYNAMIC_CHECK + CX_NO_CHECK CX_ROOT CX_SQL_EXCEPTION CX_STATIC_CHECK DANGEROUS DATA + DATABASE DATAINFO DATASET DATE DATS DATS_ADD_DAYS DATS_ADD_MONTHS + DATS_DAYS_BETWEEN DATS_IS_VALID DAYLIGHT DD/MM/YY DD/MM/YYYY DDMMYY + DEALLOCATE DEC DECIMALS DECIMAL_SHIFT DECLARATIONS DEEP DEFAULT + DEFERRED DEFINE DEFINING DEFINITION DELETE DELETING DEMAND + DEPARTMENT DESCENDING DESCRIBE DESTINATION DETAIL DF16_DEC DF16_RAW + DF16_SCL DF34_DEC DF34_RAW DF34_SCL DIALOG DIRECTORY DISCONNECT + DISPLAY DISPLAY-MODE DISTANCE DISTINCT DIV DIVIDE + DIVIDE-CORRESPONDING DIVISION DO DUMMY DUPLICATE DUPLICATES DURATION + DURING DYNAMIC DYNPRO E EDIT EDITOR-CALL ELSE ELSEIF EMPTY ENABLED + ENABLING ENCODING END END-ENHANCEMENT-SECTION END-LINES + END-OF-DEFINITION END-OF-FILE END-OF-PAGE END-OF-SELECTION + END-TEST-INJECTION END-TEST-SEAM ENDAT ENDCASE ENDCATCH ENDCHAIN + ENDCLASS ENDDO ENDENHANCEMENT ENDEXEC ENDFORM ENDFUNCTION ENDIAN + ENDIF ENDING ENDINTERFACE ENDLOOP ENDMETHOD ENDMODULE ENDON + ENDPROVIDE ENDSELECT ENDTRY ENDWHILE ENDWITH ENGINEERING ENHANCEMENT + ENHANCEMENT-POINT ENHANCEMENT-SECTION ENHANCEMENTS ENTRIES ENTRY + ENVIRONMENT EQ EQUIV ERRORMESSAGE ERRORS ESCAPE ESCAPING EVENT + EVENTS EXACT EXCEPT EXCEPTION EXCEPTION-TABLE EXCEPTIONS EXCLUDE + EXCLUDING EXEC EXECUTE EXISTS EXIT EXIT-COMMAND EXPAND EXPANDING + EXPIRATION EXPLICIT EXPONENT EXPORT EXPORTING EXTEND EXTENDED + EXTENSION EXTRACT FAIL FETCH FIELD FIELD-GROUPS FIELD-SYMBOL + FIELD-SYMBOLS FIELDS FILE FILTER FILTER-TABLE FILTERS FINAL FIND + FIRST FIRST-LINE FIXED-POINT FKEQ FKGE FLOOR FLTP FLUSH FONT FOR + FORM FORMAT FORWARD FOUND FRAME FRAMES FREE FRIENDS FROM FUNCTION + FUNCTION-POOL FUNCTIONALITY FURTHER GAPS GE GENERATE GET + GET_PRINT_PARAMETERS GIVING GKEQ GKGE GLOBAL GRANT GREEN GROUP + GROUPS GT HANDLE HANDLER HARMLESS HASHED HAVING HDB HEAD-LINES + HEADER HEADERS HEADING HELP-ID HELP-REQUEST HEXTOBIN HIDE HIGH HINT + HOLD HOTSPOT I ICON ID IDENTIFICATION IDENTIFIER IDS IF + IF_ABAP_CLOSE_RESOURCE IF_ABAP_CODEPAGE IF_ABAP_DB_BLOB_HANDLE + IF_ABAP_DB_CLOB_HANDLE IF_ABAP_DB_LOB_HANDLE IF_ABAP_DB_READER + IF_ABAP_DB_WRITER IF_ABAP_READER IF_ABAP_WRITER IF_MESSAGE + IF_OS_CA_INSTANCE IF_OS_CA_PERSISTENCY IF_OS_FACTORY IF_OS_QUERY + IF_OS_QUERY_MANAGER IF_OS_QUERY_OPTIONS IF_OS_STATE + IF_OS_TRANSACTION IF_OS_TRANSACTION_MANAGER IF_SERIALIZABLE_OBJECT + IF_SHM_BUILD_INSTANCE IF_SYSTEM_UUID IF_T100_DYN_MSG IF_T100_MESSAGE + IGNORE IGNORING IMMEDIATELY IMPLEMENTATION IMPLEMENTATIONS + IMPLEMENTED IMPLICIT IMPORT IMPORTING IN INACTIVE INCL INCLUDE + INCLUDES INCLUDING INCREMENT INDEX INDEX-LINE INFOTYPES INHERITING + INIT INITIAL INITIALIZATION INNER INOUT INPUT INSERT INSTANCE + INSTANCES INSTR INT1 INT2 INT4 INT8 INTENSIFIED INTERFACE + INTERFACE-POOL INTERFACES INTERNAL INTERVALS INTO INVERSE + INVERTED-DATE IS ISO ITNO JOB JOIN KEEP KEEPING KERNEL KEY KEYS + KEYWORDS KIND LANG LANGUAGE LAST LATE LAYOUT LCHR LDB_PROCESS LE + LEADING LEAVE LEFT LEFT-JUSTIFIED LEFTPLUS LEFTSPACE LEGACY LENGTH + LET LEVEL LEVELS LIKE LINE LINE-COUNT LINE-SELECTION LINE-SIZE + LINEFEED LINES LIST LIST-PROCESSING LISTBOX LITTLE LLANG LOAD + LOAD-OF-PROGRAM LOB LOCAL LOCALE LOCATOR LOG-POINT LOGFILE LOGICAL + LONG LOOP LOW LOWER LPAD LPI LRAW LT LTRIM M MAIL MAIN MAJOR-ID + MAPPING MARGIN MARK MASK MATCH MATCHCODE MAX MAXIMUM MEDIUM MEMBERS + MEMORY MESH MESSAGE MESSAGE-ID MESSAGES MESSAGING METHOD METHODS MIN + MINIMUM MINOR-ID MM/DD/YY MM/DD/YYYY MMDDYY MOD MODE MODIF MODIFIER + MODIFY MODULE MOVE MOVE-CORRESPONDING MULTIPLY + MULTIPLY-CORRESPONDING NA NAME NAMETAB NATIVE NB NE NESTED NESTING + NEW NEW-LINE NEW-PAGE NEW-SECTION NEXT NO NO-DISPLAY NO-EXTENSION + NO-GAP NO-GAPS NO-GROUPING NO-HEADING NO-SCROLLING NO-SIGN NO-TITLE + NO-TOPOFPAGE NO-ZERO NODE NODES NON-UNICODE NON-UNIQUE NOT NP NS + NULL NUMBER NUMC O OBJECT OBJECTS OBLIGATORY OCCURRENCE OCCURRENCES + OCCURS OF OFF OFFSET ON ONLY OPEN OPTION OPTIONAL OPTIONS OR ORDER + OTHER OTHERS OUT OUTER OUTPUT OUTPUT-LENGTH OVERFLOW OVERLAY PACK + PACKAGE PAD PADDING PAGE PAGES PARAMETER PARAMETER-TABLE PARAMETERS + PART PARTIALLY PATTERN PERCENTAGE PERFORM PERFORMING PERSON PF + PF-STATUS PINK PLACES POOL POSITION POS_HIGH POS_LOW PRAGMAS PREC + PRECOMPILED PREFERRED PRESERVING PRIMARY PRINT PRINT-CONTROL + PRIORITY PRIVATE PROCEDURE PROCESS PROGRAM PROPERTY PROTECTED + PROVIDE PUBLIC PUSH PUSHBUTTON PUT QUAN QUEUE-ONLY QUICKINFO + RADIOBUTTON RAISE RAISING RANGE RANGES RAW RAWSTRING READ READ-ONLY + READER RECEIVE RECEIVED RECEIVER RECEIVING RED REDEFINITION REDUCE + REDUCED REF REFERENCE REFRESH REGEX REJECT REMOTE RENAMING REPLACE + REPLACEMENT REPLACING REPORT REQUEST REQUESTED RESERVE RESET + RESOLUTION RESPECTING RESPONSIBLE RESULT RESULTS RESUMABLE RESUME + RETRY RETURN RETURNCODE RETURNING RETURNS RIGHT RIGHT-JUSTIFIED + RIGHTPLUS RIGHTSPACE RISK RMC_COMMUNICATION_FAILURE + RMC_INVALID_STATUS RMC_SYSTEM_FAILURE ROLE ROLLBACK ROUND ROWS RPAD + RTRIM RUN SAP SAP-SPOOL SAVING SCALE_PRESERVING + SCALE_PRESERVING_SCIENTIFIC SCAN SCIENTIFIC + SCIENTIFIC_WITH_LEADING_ZERO SCREEN SCROLL SCROLL-BOUNDARY SCROLLING + SEARCH SECONDARY SECONDS SECTION SELECT SELECT-OPTIONS SELECTION + SELECTION-SCREEN SELECTION-SET SELECTION-SETS SELECTION-TABLE + SELECTIONS SEND SEPARATE SEPARATED SET SHARED SHIFT SHORT + SHORTDUMP-ID SIGN SIGN_AS_POSTFIX SIMPLE SINGLE SIZE SKIP SKIPPING + SMART SOME SORT SORTABLE SORTED SOURCE SPACE SPECIFIED SPLIT SPOOL + SPOTS SQL SQLSCRIPT SSTRING STABLE STAMP STANDARD START-OF-SELECTION + STARTING STATE STATEMENT STATEMENTS STATIC STATICS STATUSINFO + STEP-LOOP STOP STRING STRUCTURE STRUCTURES STYLE SUBKEY SUBMATCHES + SUBMIT SUBROUTINE SUBSCREEN SUBSTRING SUBTRACT + SUBTRACT-CORRESPONDING SUFFIX SUM SUMMARY SUMMING SUPPLIED SUPPLY + SUPPRESS SWITCH SWITCHSTATES SYMBOL SYNCPOINTS SYNTAX SYNTAX-CHECK + SYNTAX-TRACE SYST SYSTEM-CALL SYSTEM-EXCEPTIONS SYSTEM-EXIT TAB + TABBED TABLE TABLES TABLEVIEW TABSTRIP TARGET TASK TASKS TEST + TEST-INJECTION TEST-SEAM TESTING TEXT TEXTPOOL THEN THROW TIME TIMES + TIMESTAMP TIMEZONE TIMS TIMS_IS_VALID TITLE TITLE-LINES TITLEBAR TO + TOKENIZATION TOKENS TOP-LINES TOP-OF-PAGE TRACE-FILE TRACE-TABLE + TRAILING TRANSACTION TRANSFER TRANSFORMATION TRANSLATE TRANSPORTING + TRMAC TRUNCATE TRUNCATION TRY TSTMP_ADD_SECONDS + TSTMP_CURRENT_UTCTIMESTAMP TSTMP_IS_VALID TSTMP_SECONDS_BETWEEN TYPE + TYPE-POOL TYPE-POOLS TYPES ULINE UNASSIGN UNDER UNICODE UNION UNIQUE + UNIT UNIT_CONVERSION UNIX UNPACK UNTIL UNWIND UP UPDATE UPPER USER + USER-COMMAND USING UTF-8 VALID VALUE VALUE-REQUEST VALUES VARC VARY + VARYING VERIFICATION-MESSAGE VERSION VIA VIEW VISIBLE WAIT WARNING + WHEN WHENEVER WHERE WHILE WIDTH WINDOW WINDOWS WITH WITH-HEADING + WITH-TITLE WITHOUT WORD WORK WRITE WRITER XML XSD YELLOW YES YYMMDD + Z ZERO ZONE + ) + end + + def self.builtins + @keywords = Set.new %w( + acos apply asin assign atan attribute bit-set boolc boolx call + call-method cast ceil cfunc charlen char_off class_constructor clear + cluster cmax cmin cnt communication_failure concat_lines_of cond + cond-var condense constructor contains contains_any_not_of + contains_any_of copy cos cosh count count_any_not_of count_any_of + create cursor data dbmaxlen dbtab deserialize destructor distance + empty error_message escape exp extensible find find_any_not_of + find_any_of find_end floor frac from_mixed group hashed header idx + include index insert ipow itab key lax lines line_exists line_index + log log10 loop loop_key match matches me mesh_path namespace nmax + nmin node numeric numofchar object parameter primary_key read ref + repeat replace rescale resource_failure reverse root round segment + sender serialize shift_left shift_right sign simple sin sinh skip + sorted space sqrt standard strlen substring substring_after + substring_before substring_from substring_to sum switch switch-var + system_failure table table_line tan tanh template text to_lower + to_mixed to_upper transform translate trunc type value variable write + xsdbool xsequence xstrlen + ) + end + + def self.types + @types = Set.new %w( + b c d decfloat16 decfloat34 f i int8 n p s t x + clike csequence decfloat string xstring + ) + end + + def self.new_keywords + @types = Set.new %w( + DATA FIELD-SYMBOL + ) + end + + state :root do + rule %r/\s+/m, Text + + rule %r/".*/, Comment::Single + rule %r(^\*.*), Comment::Multiline + rule %r/\d+/, Num::Integer + rule %r/('|`)/, Str::Single, :single_string + rule %r/[\[\]\(\)\{\}\.,:\|]/, Punctuation + + # builtins / new ABAP 7.40 keywords (@DATA(), ...) + rule %r/(->|=>)?([A-Za-z][A-Za-z0-9_\-]*)(\()/ do |m| + if m[1] != '' + token Operator, m[1] + end + + if (self.class.new_keywords.include? m[2].upcase) && m[1].nil? + token Keyword, m[2] + elsif (self.class.builtins.include? m[2].downcase) && m[1].nil? + token Name::Builtin, m[2] + else + token Name, m[2] + end + token Punctuation, m[3] + end + + # keywords, types and normal text + rule %r/\w\w*/ do |m| + if self.class.keywords.include? m[0].upcase + token Keyword + elsif self.class.types.include? m[0].downcase + token Keyword::Type + else + token Name + end + end + + # operators + rule %r((->|->>|=>)), Operator + rule %r([-\*\+%/~=&\?<>!#\@\^]+), Operator + + end + + state :operators do + rule %r((->|->>|=>)), Operator + rule %r([-\*\+%/~=&\?<>!#\@\^]+), Operator + end + + state :single_string do + rule %r/\\./, Str::Escape + rule %r/(''|``)/, Str::Escape + rule %r/['`]/, Str::Single, :pop! + rule %r/[^\\'`]+/, Str::Single + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/actionscript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/actionscript.rb new file mode 100644 index 0000000..557320e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/actionscript.rb @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Actionscript < RegexLexer + title "ActionScript" + desc "ActionScript" + + tag 'actionscript' + aliases 'as', 'as3' + filenames '*.as' + mimetypes 'application/x-actionscript' + + state :comments_and_whitespace do + rule %r/\s+/, Text + rule %r(//.*?$), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + end + + state :expr_start do + mixin :comments_and_whitespace + + rule %r(/) do + token Str::Regex + goto :regex + end + + rule %r/[{]/, Punctuation, :object + + rule %r//, Text, :pop! + end + + state :regex do + rule %r(/) do + token Str::Regex + goto :regex_end + end + + rule %r([^/]\n), Error, :pop! + + rule %r/\n/, Error, :pop! + rule %r/\[\^/, Str::Escape, :regex_group + rule %r/\[/, Str::Escape, :regex_group + rule %r/\\./, Str::Escape + rule %r{[(][?][:=>>? | === + | !== )x, + Operator, :expr_start + rule %r([:-<>+*%&|\^/!=]=?), Operator, :expr_start + rule %r/[(\[,]/, Punctuation, :expr_start + rule %r/;/, Punctuation, :statement + rule %r/[)\].]/, Punctuation + + rule %r/[?]/ do + token Punctuation + push :ternary + push :expr_start + end + + rule %r/[{}]/, Punctuation, :statement + + rule id do |m| + if self.class.keywords.include? m[0] + token Keyword + push :expr_start + elsif self.class.declarations.include? m[0] + token Keyword::Declaration + push :expr_start + elsif self.class.reserved.include? m[0] + token Keyword::Reserved + elsif self.class.constants.include? m[0] + token Keyword::Constant + elsif self.class.builtins.include? m[0] + token Name::Builtin + else + token Name::Other + end + end + + rule %r/\-?[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, Num::Float + rule %r/0x[0-9a-fA-F]+/, Num::Hex + rule %r/\-?[0-9]+/, Num::Integer + rule %r/"(\\\\|\\"|[^"])*"/, Str::Double + rule %r/'(\\\\|\\'|[^'])*'/, Str::Single + end + + # braced parts that aren't object literals + state :statement do + rule %r/(#{id})(\s*)(:)/ do + groups Name::Label, Text, Punctuation + end + + rule %r/[{}]/, Punctuation + + mixin :expr_start + end + + # object literals + state :object do + mixin :comments_and_whitespace + rule %r/[}]/ do + token Punctuation + goto :statement + end + + rule %r/(#{id})(\s*)(:)/ do + groups Name::Attribute, Text, Punctuation + push :expr_start + end + + rule %r/:/, Punctuation + mixin :root + end + + # ternary expressions, where : is not a label! + state :ternary do + rule %r/:/ do + token Punctuation + goto :expr_start + end + + mixin :root + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ada.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ada.rb new file mode 100644 index 0000000..141079c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ada.rb @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Ada < RegexLexer + tag 'ada' + filenames '*.ada', '*.ads', '*.adb', '*.adc', '*.gpr' + mimetypes 'text/x-ada' + + title 'Ada' + desc 'The Ada 2012 programming language' + + # Ada identifiers are Unicode with underscores only allowed as separators. + ID = /\b[[:alpha:]](?:\p{Pc}?[[:alnum:]])*\b/ + + # Numerals can also contain underscores. + NUM = /\d(_?\d)*/ + XNUM = /\h(_?\h)*/ + EXP = /(E[-+]?#{NUM})?/i + + # Return a hash mapping lower-case identifiers to token classes. + def self.idents + @idents ||= Hash.new(Name).tap do |h| + %w( + abort abstract accept access aliased all array at begin body + case constant declare delay delta digits do else elsif end + exception exit for generic goto if in interface is limited + loop new null of others out overriding parallel pragma private + protected raise range record renames requeue return reverse + select separate some synchronized tagged task terminate then + until use when while with + ).each {|w| h[w] = Keyword} + + %w(abs and mod not or rem xor).each {|w| h[w] = Operator::Word} + + %w( + entry function package procedure subtype type + ).each {|w| h[w] = Keyword::Declaration} + + %w( + boolean character constraint_error duration float integer + natural positive long_float long_integer long_long_float + long_long_integer program_error short_float short_integer + short_short_integer storage_error string tasking_error + wide_character wide_string wide_wide_character + wide_wide_string + ).each {|w| h[w] = Name::Builtin} + end + end + + state :whitespace do + rule %r{\s+}m, Text + rule %r{--.*$}, Comment::Single + end + + state :dquote_string do + rule %r{[^"\n]+}, Literal::String::Double + rule %r{""}, Literal::String::Escape + rule %r{"}, Literal::String::Double, :pop! + rule %r{\n}, Error, :pop! + end + + state :attr do + mixin :whitespace + rule ID, Name::Attribute, :pop! + rule %r{}, Text, :pop! + end + + # Handle a dotted name immediately following a declaration keyword. + state :decl_name do + mixin :whitespace + rule %r{body\b}i, Keyword::Declaration # package body Foo.Bar is... + rule %r{(#{ID})(\.)} do + groups Name::Namespace, Punctuation + end + # function "<=" (Left, Right: Type) is ... + rule %r{#{ID}|"(and|or|xor|/?=|<=?|>=?|\+|–|&\|/|mod|rem|\*?\*|abs|not)"}, + Name::Function, :pop! + rule %r{}, Text, :pop! + end + + # Handle a sequence of library unit names: with Ada.Foo, Ada.Bar; + # + # There's a chance we entered this state mistakenly since 'with' + # has multiple other uses in Ada (none of which are likely to + # appear at the beginning of a line). Try to bail as soon as + # possible if we see something suspicious like keywords. + # + # See ada_spec.rb for some examples. + state :libunit_name do + mixin :whitespace + + rule ID do |m| + t = self.class.idents[m[0].downcase] + if t <= Name + # Convert all kinds of Name to namespaces in this context. + token Name::Namespace + else + # Yikes, we're not supposed to get a keyword in a library unit name! + # We probably entered this state by mistake, so try to fix it. + token t + if t == Keyword::Declaration + goto :decl_name + else + pop! + end + end + end + + rule %r{[.,]}, Punctuation + rule %r{}, Text, :pop! + end + + state :root do + mixin :whitespace + + # String literals. + rule %r{'.'}, Literal::String::Char + rule %r{"[^"\n]*}, Literal::String::Double, :dquote_string + + # Real literals. + rule %r{#{NUM}\.#{NUM}#{EXP}}, Literal::Number::Float + rule %r{#{NUM}##{XNUM}\.#{XNUM}##{EXP}}, Literal::Number::Float + + # Integer literals. + rule %r{2#[01](_?[01])*##{EXP}}, Literal::Number::Bin + rule %r{8#[0-7](_?[0-7])*##{EXP}}, Literal::Number::Oct + rule %r{16##{XNUM}*##{EXP}}, Literal::Number::Hex + rule %r{#{NUM}##{XNUM}##{EXP}}, Literal::Number::Integer + rule %r{#{NUM}#\w+#}, Error + rule %r{#{NUM}#{EXP}}, Literal::Number::Integer + + # Special constructs. + rule %r{'}, Punctuation, :attr + rule %r{<<#{ID}>>}, Name::Label + + # Context clauses are tricky because the 'with' keyword is used + # for many purposes. Detect at beginning of the line only. + rule %r{^(?:(limited)(\s+))?(?:(private)(\s+))?(with)\b}i do + groups Keyword::Namespace, Text, Keyword::Namespace, Text, Keyword::Namespace + push :libunit_name + end + + # Operators and punctuation characters. + rule %r{[+*/&<=>|]|-|=>|\.\.|\*\*|[:>>|<>|@}, Operator + rule %r{[.,:;()\[\]]}, Punctuation + + rule ID do |m| + t = self.class.idents[m[0].downcase] + token t + if t == Keyword::Declaration + push :decl_name + end + end + + # Flag word-like things that don't match the ID pattern. + rule %r{\b(\p{Pc}|[[:alpha:]])\p{Word}*}, Error + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache.rb new file mode 100644 index 0000000..2b8046b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'yaml' + +module Rouge + module Lexers + class Apache < RegexLexer + title "Apache" + desc 'configuration files for Apache web server' + tag 'apache' + mimetypes 'text/x-httpd-conf', 'text/x-apache-conf' + filenames '.htaccess', 'httpd.conf' + + # self-modifying method that loads the keywords file + def self.directives + Kernel::load File.join(Lexers::BASE_DIR, 'apache/keywords.rb') + directives + end + + def self.sections + Kernel::load File.join(Lexers::BASE_DIR, 'apache/keywords.rb') + sections + end + + def self.values + Kernel::load File.join(Lexers::BASE_DIR, 'apache/keywords.rb') + values + end + + def name_for_token(token, tktype) + if self.class.sections.include? token + tktype + elsif self.class.directives.include? token + tktype + elsif self.class.values.include? token + tktype + else + Text + end + end + + state :whitespace do + rule %r/\#.*/, Comment + rule %r/\s+/m, Text + end + + state :root do + mixin :whitespace + + rule %r/(<\/?)(\w+)/ do |m| + groups Punctuation, name_for_token(m[2].downcase, Name::Label) + push :section + end + + rule %r/\w+/ do |m| + token name_for_token(m[0].downcase, Name::Class) + push :directive + end + end + + state :section do + # Match section arguments + rule %r/([^>]+)?(>(?:\r\n?|\n)?)/ do + groups Literal::String::Regex, Punctuation + pop! + end + + mixin :whitespace + end + + state :directive do + # Match value literals and other directive arguments + rule %r/\r\n?|\n/, Text, :pop! + + mixin :whitespace + + rule %r/\S+/ do |m| + token name_for_token(m[0].downcase, Literal::String::Symbol) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache/keywords.rb new file mode 100644 index 0000000..e71876e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apache/keywords.rb @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# DO NOT EDIT +# This file is automatically generated by `rake builtins:apache`. +# See tasks/builtins/apache.rake for more info. + +module Rouge + module Lexers + class Apache + def self.directives + @directives ||= Set.new ["acceptfilter", "acceptpathinfo", "accessfilename", "action", "addalt", "addaltbyencoding", "addaltbytype", "addcharset", "adddefaultcharset", "adddescription", "addencoding", "addhandler", "addicon", "addiconbyencoding", "addiconbytype", "addinputfilter", "addlanguage", "addmoduleinfo", "addoutputfilter", "addoutputfilterbytype", "addtype", "alias", "aliasmatch", "allow", "allowconnect", "allowencodedslashes", "allowmethods", "allowoverride", "allowoverridelist", "anonymous", "anonymous_logemail", "anonymous_mustgiveemail", "anonymous_nouserid", "anonymous_verifyemail", "asyncrequestworkerfactor", "authbasicauthoritative", "authbasicfake", "authbasicprovider", "authbasicusedigestalgorithm", "authdbduserpwquery", "authdbduserrealmquery", "authdbmgroupfile", "authdbmtype", "authdbmuserfile", "authdigestalgorithm", "authdigestdomain", "authdigestnoncelifetime", "authdigestprovider", "authdigestqop", "authdigestshmemsize", "authformauthoritative", "authformbody", "authformdisablenostore", "authformfakebasicauth", "authformlocation", "authformloginrequiredlocation", "authformloginsuccesslocation", "authformlogoutlocation", "authformmethod", "authformmimetype", "authformpassword", "authformprovider", "authformsitepassphrase", "authformsize", "authformusername", "authgroupfile", "authldapauthorizeprefix", "authldapbindauthoritative", "authldapbinddn", "authldapbindpassword", "authldapcharsetconfig", "authldapcompareasuser", "authldapcomparednonserver", "authldapdereferencealiases", "authldapgroupattribute", "authldapgroupattributeisdn", "authldapinitialbindasuser", "authldapinitialbindpattern", "authldapmaxsubgroupdepth", "authldapremoteuserattribute", "authldapremoteuserisdn", "authldapsearchasuser", "authldapsubgroupattribute", "authldapsubgroupclass", "authldapurl", "authmerging", "authname", "authncachecontext", "authncacheenable", "authncacheprovidefor", "authncachesocache", "authncachetimeout", "authnzfcgicheckauthnprovider", "authnzfcgidefineprovider", "authtype", "authuserfile", "authzdbdlogintoreferer", "authzdbdquery", "authzdbdredirectquery", "authzdbmtype", "authzsendforbiddenonfailure", "balancergrowth", "balancerinherit", "balancermember", "balancerpersist", "brotlialteretag", "brotlicompressionmaxinputblock", "brotlicompressionquality", "brotlicompressionwindow", "brotlifilternote", "browsermatch", "browsermatchnocase", "bufferedlogs", "buffersize", "cachedefaultexpire", "cachedetailheader", "cachedirlength", "cachedirlevels", "cachedisable", "cacheenable", "cachefile", "cacheheader", "cacheignorecachecontrol", "cacheignoreheaders", "cacheignorenolastmod", "cacheignorequerystring", "cacheignoreurlsessionidentifiers", "cachekeybaseurl", "cachelastmodifiedfactor", "cachelock", "cachelockmaxage", "cachelockpath", "cachemaxexpire", "cachemaxfilesize", "cacheminexpire", "cacheminfilesize", "cachenegotiateddocs", "cachequickhandler", "cachereadsize", "cachereadtime", "cacheroot", "cachesocache", "cachesocachemaxsize", "cachesocachemaxtime", "cachesocachemintime", "cachesocachereadsize", "cachesocachereadtime", "cachestaleonerror", "cachestoreexpired", "cachestorenostore", "cachestoreprivate", "cgidscripttimeout", "cgimapextension", "cgipassauth", "cgivar", "charsetdefault", "charsetoptions", "charsetsourceenc", "checkcaseonly", "checkspelling", "chrootdir", "contentdigest", "cookiedomain", "cookieexpires", "cookiename", "cookiestyle", "cookietracking", "coredumpdirectory", "customlog", "dav", "davdepthinfinity", "davgenericlockdb", "davlockdb", "davmintimeout", "dbdexptime", "dbdinitsql", "dbdkeep", "dbdmax", "dbdmin", "dbdparams", "dbdpersist", "dbdpreparesql", "dbdriver", "defaulticon", "defaultlanguage", "defaultruntimedir", "defaulttype", "define", "deflatebuffersize", "deflatecompressionlevel", "deflatefilternote", "deflateinflatelimitrequestbody", "deflateinflateratioburst", "deflateinflateratiolimit", "deflatememlevel", "deflatewindowsize", "deny", "directorycheckhandler", "directoryindex", "directoryindexredirect", "directoryslash", "documentroot", "dtraceprivileges", "dumpioinput", "dumpiooutput", "enableexceptionhook", "enablemmap", "enablesendfile", "error", "errordocument", "errorlog", "errorlogformat", "example", "expiresactive", "expiresbytype", "expiresdefault", "extendedstatus", "extfilterdefine", "extfilteroptions", "fallbackresource", "fileetag", "filterchain", "filterdeclare", "filterprotocol", "filterprovider", "filtertrace", "forcelanguagepriority", "forcetype", "forensiclog", "globallog", "gprofdir", "gracefulshutdowntimeout", "group", "h2copyfiles", "h2direct", "h2earlyhints", "h2maxsessionstreams", "h2maxworkeridleseconds", "h2maxworkers", "h2minworkers", "h2moderntlsonly", "h2push", "h2pushdiarysize", "h2pushpriority", "h2pushresource", "h2serializeheaders", "h2streammaxmemsize", "h2tlscooldownsecs", "h2tlswarmupsize", "h2upgrade", "h2windowsize", "header", "headername", "heartbeataddress", "heartbeatlisten", "heartbeatmaxservers", "heartbeatstorage", "heartbeatstorage", "hostnamelookups", "httpprotocoloptions", "identitycheck", "identitychecktimeout", "imapbase", "imapdefault", "imapmenu", "include", "includeoptional", "indexheadinsert", "indexignore", "indexignorereset", "indexoptions", "indexorderdefault", "indexstylesheet", "inputsed", "isapiappendlogtoerrors", "isapiappendlogtoquery", "isapicachefile", "isapifakeasync", "isapilognotsupported", "isapireadaheadbuffer", "keepalive", "keepalivetimeout", "keptbodysize", "languagepriority", "ldapcacheentries", "ldapcachettl", "ldapconnectionpoolttl", "ldapconnectiontimeout", "ldaplibrarydebug", "ldapopcacheentries", "ldapopcachettl", "ldapreferralhoplimit", "ldapreferrals", "ldapretries", "ldapretrydelay", "ldapsharedcachefile", "ldapsharedcachesize", "ldaptimeout", "ldaptrustedclientcert", "ldaptrustedglobalcert", "ldaptrustedmode", "ldapverifyservercert", "limitinternalrecursion", "limitrequestbody", "limitrequestfields", "limitrequestfieldsize", "limitrequestline", "limitxmlrequestbody", "listen", "listenbacklog", "listencoresbucketsratio", "loadfile", "loadmodule", "logformat", "logiotrackttfb", "loglevel", "logmessage", "luaauthzprovider", "luacodecache", "luahookaccesschecker", "luahookauthchecker", "luahookcheckuserid", "luahookfixups", "luahookinsertfilter", "luahooklog", "luahookmaptostorage", "luahooktranslatename", "luahooktypechecker", "luainherit", "luainputfilter", "luamaphandler", "luaoutputfilter", "luapackagecpath", "luapackagepath", "luaquickhandler", "luaroot", "luascope", "maxconnectionsperchild", "maxkeepaliverequests", "maxmemfree", "maxrangeoverlaps", "maxrangereversals", "maxranges", "maxrequestworkers", "maxspareservers", "maxsparethreads", "maxthreads", "mdbaseserver", "mdcachallenges", "mdcertificateagreement", "mdcertificateauthority", "mdcertificateprotocol", "mddrivemode", "mdhttpproxy", "mdmember", "mdmembers", "mdmuststaple", "mdnotifycmd", "mdomain", "mdportmap", "mdprivatekeys", "mdrenewwindow", "mdrequirehttps", "mdstoredir", "memcacheconnttl", "mergetrailers", "metadir", "metafiles", "metasuffix", "mimemagicfile", "minspareservers", "minsparethreads", "mmapfile", "modemstandard", "modmimeusepathinfo", "multiviewsmatch", "mutex", "namevirtualhost", "noproxy", "nwssltrustedcerts", "nwsslupgradeable", "options", "order", "outputsed", "passenv", "pidfile", "privilegesmode", "protocol", "protocolecho", "protocols", "protocolshonororder", "proxyaddheaders", "proxybadheader", "proxyblock", "proxydomain", "proxyerroroverride", "proxyexpressdbmfile", "proxyexpressdbmtype", "proxyexpressenable", "proxyfcgibackendtype", "proxyfcgisetenvif", "proxyftpdircharset", "proxyftpescapewildcards", "proxyftplistonwildcard", "proxyhcexpr", "proxyhctemplate", "proxyhctpsize", "proxyhtmlbufsize", "proxyhtmlcharsetout", "proxyhtmldoctype", "proxyhtmlenable", "proxyhtmlevents", "proxyhtmlextended", "proxyhtmlfixups", "proxyhtmlinterp", "proxyhtmllinks", "proxyhtmlmeta", "proxyhtmlstripcomments", "proxyhtmlurlmap", "proxyiobuffersize", "proxymaxforwards", "proxypass", "proxypassinherit", "proxypassinterpolateenv", "proxypassmatch", "proxypassreverse", "proxypassreversecookiedomain", "proxypassreversecookiepath", "proxypreservehost", "proxyreceivebuffersize", "proxyremote", "proxyremotematch", "proxyrequests", "proxyscgiinternalredirect", "proxyscgisendfile", "proxyset", "proxysourceaddress", "proxystatus", "proxytimeout", "proxyvia", "qualifyredirecturl", "readmename", "receivebuffersize", "redirect", "redirectmatch", "redirectpermanent", "redirecttemp", "reflectorheader", "registerhttpmethod", "remoteipheader", "remoteipinternalproxy", "remoteipinternalproxylist", "remoteipproxiesheader", "remoteipproxyprotocol", "remoteipproxyprotocolexceptions", "remoteiptrustedproxy", "remoteiptrustedproxylist", "removecharset", "removeencoding", "removehandler", "removeinputfilter", "removelanguage", "removeoutputfilter", "removetype", "requestheader", "requestreadtimeout", "require", "rewritebase", "rewritecond", "rewriteengine", "rewritemap", "rewriteoptions", "rewriterule", "rlimitcpu", "rlimitmem", "rlimitnproc", "satisfy", "scoreboardfile", "script", "scriptalias", "scriptaliasmatch", "scriptinterpretersource", "scriptlog", "scriptlogbuffer", "scriptloglength", "scriptsock", "securelisten", "seerequesttail", "sendbuffersize", "serveradmin", "serveralias", "serverlimit", "servername", "serverpath", "serverroot", "serversignature", "servertokens", "session", "sessioncookiename", "sessioncookiename2", "sessioncookieremove", "sessioncryptocipher", "sessioncryptodriver", "sessioncryptopassphrase", "sessioncryptopassphrasefile", "sessiondbdcookiename", "sessiondbdcookiename2", "sessiondbdcookieremove", "sessiondbddeletelabel", "sessiondbdinsertlabel", "sessiondbdperuser", "sessiondbdselectlabel", "sessiondbdupdatelabel", "sessionenv", "sessionexclude", "sessionheader", "sessioninclude", "sessionmaxage", "setenv", "setenvif", "setenvifexpr", "setenvifnocase", "sethandler", "setinputfilter", "setoutputfilter", "ssiendtag", "ssierrormsg", "ssietag", "ssilastmodified", "ssilegacyexprparser", "ssistarttag", "ssitimeformat", "ssiundefinedecho", "sslcacertificatefile", "sslcacertificatepath", "sslcadnrequestfile", "sslcadnrequestpath", "sslcarevocationcheck", "sslcarevocationfile", "sslcarevocationpath", "sslcertificatechainfile", "sslcertificatefile", "sslcertificatekeyfile", "sslciphersuite", "sslcompression", "sslcryptodevice", "sslengine", "sslfips", "sslhonorcipherorder", "sslinsecurerenegotiation", "sslocspdefaultresponder", "sslocspenable", "sslocspnoverify", "sslocspoverrideresponder", "sslocspproxyurl", "sslocsprespondercertificatefile", "sslocsprespondertimeout", "sslocspresponsemaxage", "sslocspresponsetimeskew", "sslocspuserequestnonce", "sslopensslconfcmd", "ssloptions", "sslpassphrasedialog", "sslprotocol", "sslproxycacertificatefile", "sslproxycacertificatepath", "sslproxycarevocationcheck", "sslproxycarevocationfile", "sslproxycarevocationpath", "sslproxycheckpeercn", "sslproxycheckpeerexpire", "sslproxycheckpeername", "sslproxyciphersuite", "sslproxyengine", "sslproxymachinecertificatechainfile", "sslproxymachinecertificatefile", "sslproxymachinecertificatepath", "sslproxyprotocol", "sslproxyverify", "sslproxyverifydepth", "sslrandomseed", "sslrenegbuffersize", "sslrequire", "sslrequiressl", "sslsessioncache", "sslsessioncachetimeout", "sslsessionticketkeyfile", "sslsessiontickets", "sslsrpunknownuserseed", "sslsrpverifierfile", "sslstaplingcache", "sslstaplingerrorcachetimeout", "sslstaplingfaketrylater", "sslstaplingforceurl", "sslstaplingrespondertimeout", "sslstaplingresponsemaxage", "sslstaplingresponsetimeskew", "sslstaplingreturnrespondererrors", "sslstaplingstandardcachetimeout", "sslstrictsnivhostcheck", "sslusername", "sslusestapling", "sslverifyclient", "sslverifydepth", "startservers", "startthreads", "substitute", "substituteinheritbefore", "substitutemaxlinelength", "suexec", "suexecusergroup", "threadlimit", "threadsperchild", "threadstacksize", "timeout", "traceenable", "transferlog", "typesconfig", "undefine", "undefmacro", "unsetenv", "use", "usecanonicalname", "usecanonicalphysicalport", "user", "userdir", "vhostcgimode", "vhostcgiprivs", "vhostgroup", "vhostprivs", "vhostsecure", "vhostuser", "virtualdocumentroot", "virtualdocumentrootip", "virtualscriptalias", "virtualscriptaliasip", "watchdoginterval", "xbithack", "xml2encalias", "xml2encdefault", "xml2startparse"] + end + + def self.sections + @sections ||= Set.new ["authnprovideralias", "authzprovideralias", "directory", "directorymatch", "else", "elseif", "files", "filesmatch", "if", "ifdefine", "ifmodule", "ifversion", "limit", "limitexcept", "location", "locationmatch", "macro", "mdomainset", "proxy", "proxymatch", "requireall", "requireany", "requirenone", "virtualhost"] + end + + def self.values + @values ||= Set.new ["add", "addaltclass", "addsuffix", "alias", "all", "allow", "allowanyuri", "allownoslash", "always", "and", "any", "ap_auth_internal_per_uri", "api_version", "append", "ascending", "attribute", "auth", "auth-int", "authconfig", "auto", "backend-address", "balancer_name", "balancer_route_changed", "balancer_session_route", "balancer_session_sticky", "balancer_worker_name", "balancer_worker_route", "base", "basedn", "basic", "before", "block", "boolean", "byte", "byteranges", "cache", "cache-hit", "cache-invalidate", "cache-miss", "cache-revalidate", "cgi", "chain", "change", "charset", "circle", "cmd", "conditional-expression", "condpattern", "conn", "conn_remote_addr", "cookie", "cookie2", "current-uri", "date", "date_gmt", "date_local", "db", "dbm", "decoding", "default", "deny", "descending", "description", "descriptionwidth", "digest", "disabled", "disableenv", "dns", "document_args", "document_name", "document_root", "document_uri", "domain", "double", "duration", "early", "echo", "echomsg", "edit", "edit*", "email", "enableenv", "encoding", "env", "environment-variable-name", "errmsg", "error", "errorlog", "errorlogformat", "execcgi", "expr", "fallback", "fancyindexing", "fast", "file", "file-group", "file-owner", "fileinfo", "filename", "filter", "filter-name", "filter_name", "filters", "finding", "first-dot", "foldersfirst", "followsymlinks", "forever", "form", "formatted", "fpm", "from", "ftype", "full", "function_name", "gdbm", "generic", "gone", "handlers", "hit", "hook_function_name", "host", "hostname", "hse_append_log_parameter", "hse_req_done_with_session", "hse_req_is_connected", "hse_req_is_keep_conn", "hse_req_map_url_to_path", "hse_req_send_response_header", "hse_req_send_response_header_ex", "hse_req_send_url", "hse_req_send_url_redirect_resp", "html", "htmltable", "https", "iconheight", "iconsarelinks", "iconwidth", "ignore", "ignorecase", "ignoreclient", "ignorecontextinfo", "ignoreinherit", "imal", "in", "includes", "includesnoexec", "indexes", "inherit", "inheritbefore", "inheritdown", "inheritdownbefore", "inode", "input", "int", "integer", "intype", "ipaddr", "is_subreq", "iserror", "last-dot", "last_modified", "ldap", "leaf", "legacyprefixdocroot", "level", "limit", "log_function_name", "major", "manual", "map", "map1", "map2", "max", "md5", "md5-sess", "menu", "merge", "mergebase", "minor", "miss", "mod_cache_disk", "mod_cache_socache", "mode", "mtime", "multiviews", "mutual-failure", "mysql", "name", "namewidth", "ndbm", "negotiatedonly", "never", "no", "nochange", "nocontent", "nodecode", "none", "nonfatal", "note", "number-of-ranges", "odbc", "off", "on", "once", "onerror", "onfail", "option", "optional", "options", "or", "oracle", "order", "original-uri", "os", "output", "outtype", "parent-first", "parent-last", "path", "path_info", "permanent", "pipe", "point", "poly", "postgresql", "prefer", "preservescontentlength", "prg", "protocol", "provider-name", "provider_name", "proxy", "proxy-chain-auth", "proxy-fcgi-pathinfo", "proxy-initial-not-pooled", "proxy-interim-response", "proxy-nokeepalive", "proxy-scgi-pathinfo", "proxy-sendcl", "proxy-sendextracrlf", "proxy-source-port", "proxy-status", "qs", "query_string_unescaped", "range", "ratio", "rect", "referer", "regex", "registry", "registry-strict", "remote_addr", "remote_host", "remote_ident", "remote_user", "remove", "request", "request_filename", "request_rec", "request_scheme", "request_uri", "reset", "revalidate", "rewritecond", "rfc2109", "rnd", "scanhtmltitles", "scope", "script", "sdbm", "searching", "secure", "seeother", "selective", "semiformatted", "server", "server_addr", "server_admin", "server_name", "set", "setifempty", "showforbidden", "size", "sizefmt", "sqlite2", "sqlite3", "ssl", "ssl-access-forbidden", "ssl-secure-reneg", "startbody", "stat", "string", "string1", "subnet", "suppresscolumnsorting", "suppressdescription", "suppresshtmlpreamble", "suppressicon", "suppresslastmodified", "suppressrules", "suppresssize", "symlinksifownermatch", "temp", "temporary", "test_condition1", "the_request", "thread", "timefmt", "tls", "to-pattern", "trackmodified", "transform", "txt", "type", "uctonly", "uid", "unescape", "unformatted", "unlimited", "unset", "uri-pattern", "url", "url-of-terms-of-service", "url-path", "useolddateformat", "value", "value-expression", "var", "versionsort", "virtual", "x-forwarded-for", "x-forwarded-host", "x-forwarded-server", "xhtml"] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apex.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apex.rb new file mode 100644 index 0000000..79b5d33 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apex.rb @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Apex < RegexLexer + title "Apex" + desc "The Apex programming language (provided by salesforce)" + + tag 'apex' + filenames '*.cls' + mimetypes 'text/x-apex' + + def self.keywords + @keywords ||= Set.new %w( + assert break case catch continue default do else finally for if goto + instanceof new return switch this throw try while insert update + delete + ) + end + + def self.declarations + @declarations ||= Set.new %w( + abstract const enum extends final implements native private protected + public static super synchronized throws transient volatile with + sharing without inherited virtual global testmethod + ) + end + + def self.soql + @soql ||= Set.new %w( + SELECT FROM WHERE UPDATE LIKE TYPEOF END USING SCOPE WITH DATA + CATEGORY GROUP BY ROLLUP CUBE HAVING ORDER BY ASC DESC NULLS FIRST + LAST LIMIT OFFSET FOR VIEW REFERENCE UPDATE TRACKING VIEWSTAT OR AND + ) + end + + def self.types + @types ||= Set.new %w( + String boolean byte char double float int long short var void + ) + end + + def self.constants + @constants ||= Set.new %w(true false null) + end + + id = /[a-z_][a-z0-9_]*/i + + state :root do + rule %r/\s+/m, Text + + rule %r(//.*?$), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + + rule %r/(?:class|interface)\b/, Keyword::Declaration, :class + rule %r/import\b/, Keyword::Namespace, :import + + rule %r/([@$.]?)(#{id})([:(]?)/io do |m| + lowercased = m[0].downcase + uppercased = m[0].upcase + if self.class.keywords.include? lowercased + token Keyword + elsif self.class.soql.include? uppercased + token Keyword + elsif self.class.declarations.include? lowercased + token Keyword::Declaration + elsif self.class.types.include? lowercased + token Keyword::Type + elsif self.class.constants.include? lowercased + token Keyword::Constant + elsif lowercased == 'package' + token Keyword::Namespace + elsif m[1] == "@" + token Name::Decorator + elsif m[3] == ":" + groups Operator, Name::Label, Punctuation + elsif m[3] == "(" + groups Operator, Name::Function, Punctuation + elsif m[1] == "." + groups Operator, Name::Property, Punctuation + else + token Name + end + end + + rule %r/"/, Str::Double, :dq + rule %r/'/, Str::Single, :sq + + digit = /[0-9]_+[0-9]|[0-9]/ + rule %r/#{digit}+\.#{digit}+([eE]#{digit}+)?[fd]?/, Num::Float + rule %r/0b(?:[01]_+[01]|[01])+/i, Num::Bin + rule %r/0x(?:\h_+\h|\h)+/i, Num::Hex + rule %r/0(?:[0-7]_+[0-7]|[0-7])+/, Num::Oct + rule %r/#{digit}+L?/, Num::Integer + + rule %r/[-+\/*~^!%&<>|=.?]/, Operator + rule %r/[\[\](){},:;]/, Punctuation; + end + + state :class do + rule %r/\s+/m, Text + rule id, Name::Class, :pop! + end + + state :import do + rule %r/\s+/m, Text + rule %r/[a-z0-9_.]+\*?/i, Name::Namespace, :pop! + end + + state :escape do + rule %r/\\[btnfr\\"']/, Str::Escape + end + + state :dq do + mixin :escape + rule %r/[^\\"]+/, Str::Double + rule %r/"/, Str::Double, :pop! + end + + state :sq do + mixin :escape + rule %r/[^\\']+/, Str::Double + rule %r/'/, Str::Double, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apiblueprint.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apiblueprint.rb new file mode 100644 index 0000000..7695c39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apiblueprint.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'markdown.rb' + + class APIBlueprint < Markdown + title 'API Blueprint' + desc 'Markdown based API description language.' + + tag 'apiblueprint' + aliases 'apiblueprint', 'apib' + filenames '*.apib' + mimetypes 'text/vnd.apiblueprint' + + prepend :root do + # Metadata + rule(/(\S+)(:\s*)(.*)$/) do + groups Name::Variable, Punctuation, Literal::String + end + + # Resource Group + rule(/^(#+)(\s*Group\s+)(.*)$/) do + groups Punctuation, Keyword, Generic::Heading + end + + # Resource \ Action + rule(/^(#+)(.*)(\[.*\])$/) do + groups Punctuation, Generic::Heading, Literal::String + end + + # Relation + rule(/^([\+\-\*])(\s*Relation:)(\s*.*)$/) do + groups Punctuation, Keyword, Literal::String + end + + # MSON + rule(/^(\s+[\+\-\*]\s*)(Attributes|Parameters)(.*)$/) do + groups Punctuation, Keyword, Literal::String + end + + # Request/Response + rule(/^([\+\-\*]\s*)(Request|Response)(\s+\d\d\d)?(.*)$/) do + groups Punctuation, Keyword, Literal::Number, Literal::String + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apple_script.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apple_script.rb new file mode 100644 index 0000000..7a47b29 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/apple_script.rb @@ -0,0 +1,370 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class AppleScript < RegexLexer + title "AppleScript" + desc "The AppleScript scripting language by Apple Inc. (https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html)" + + tag 'applescript' + aliases 'applescript' + + filenames '*.applescript', '*.scpt' + + mimetypes 'application/x-applescript' + + def self.literals + @literals ||= ['AppleScript', 'current application', 'false', 'linefeed', + 'missing value', 'pi','quote', 'result', 'return', 'space', + 'tab', 'text item delimiters', 'true', 'version'] + end + + def self.classes + @classes ||= ['alias ', 'application ', 'boolean ', 'class ', 'constant ', + 'date ', 'file ', 'integer ', 'list ', 'number ', 'POSIX file ', + 'real ', 'record ', 'reference ', 'RGB color ', 'script ', + 'text ', 'unit types', '(?:Unicode )?text', 'string'] + end + + def self.builtins + @builtins ||= ['attachment', 'attribute run', 'character', 'day', 'month', + 'paragraph', 'word', 'year'] + end + + def self.handler_params + @handler_params ||= ['about', 'above', 'against', 'apart from', 'around', + 'aside from', 'at', 'below', 'beneath', 'beside', + 'between', 'for', 'given', 'instead of', 'on', 'onto', + 'out of', 'over', 'since'] + end + + def self.commands + @commands ||= ['ASCII (character|number)', 'activate', 'beep', 'choose URL', + 'choose application', 'choose color', 'choose file( name)?', + 'choose folder', 'choose from list', + 'choose remote application', 'clipboard info', + 'close( access)?', 'copy', 'count', 'current date', 'delay', + 'delete', 'display (alert|dialog)', 'do shell script', + 'duplicate', 'exists', 'get eof', 'get volume settings', + 'info for', 'launch', 'list (disks|folder)', 'load script', + 'log', 'make', 'mount volume', 'new', 'offset', + 'open( (for access|location))?', 'path to', 'print', 'quit', + 'random number', 'read', 'round', 'run( script)?', + 'say', 'scripting components', + 'set (eof|the clipboard to|volume)', 'store script', + 'summarize', 'system attribute', 'system info', + 'the clipboard', 'time to GMT', 'write', 'quoted form'] + end + + def self.references + @references ||= ['(in )?back of', '(in )?front of', '[0-9]+(st|nd|rd|th)', + 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', + 'seventh', 'eighth', 'ninth', 'tenth', 'after', 'back', + 'before', 'behind', 'every', 'front', 'index', 'last', + 'middle', 'some', 'that', 'through', 'thru', 'where', 'whose'] + end + + def self.operators + @operators ||= ["and", "or", "is equal", "equals", "(is )?equal to", "is not", + "isn't", "isn't equal( to)?", "is not equal( to)?", + "doesn't equal", "does not equal", "(is )?greater than", + "comes after", "is not less than or equal( to)?", + "isn't less than or equal( to)?", "(is )?less than", + "comes before", "is not greater than or equal( to)?", + "isn't greater than or equal( to)?", + "(is )?greater than or equal( to)?", "is not less than", + "isn't less than", "does not come before", + "doesn't come before", "(is )?less than or equal( to)?", + "is not greater than", "isn't greater than", + "does not come after", "doesn't come after", "starts? with", + "begins? with", "ends? with", "contains?", "does not contain", + "doesn't contain", "is in", "is contained by", "is not in", + "is not contained by", "isn't contained by", "div", "mod", + "not", "(a )?(ref( to)?|reference to)", "is", "does"] + end + + def self.controls + @controls ||= ['considering', 'else', 'error', 'exit', 'from', 'if', + 'ignoring', 'in', 'repeat', 'tell', 'then', 'times', 'to', + 'try', 'until', 'using terms from', 'while', 'whith', + 'with timeout( of)?', 'with transaction', 'by', 'continue', + 'end', 'its?', 'me', 'my', 'return', 'of' , 'as'] + end + + def self.declarations + @declarations ||= ['global', 'local', 'prop(erty)?', 'set', 'get'] + end + + def self.reserved + @reserved ||= ['but', 'put', 'returning', 'the'] + end + + def self.studio_classes + @studio_classes ||= ['action cell', 'alert reply', 'application', 'box', + 'browser( cell)?', 'bundle', 'button( cell)?', 'cell', + 'clip view', 'color well', 'color-panel', + 'combo box( item)?', 'control', + 'data( (cell|column|item|row|source))?', 'default entry', + 'dialog reply', 'document', 'drag info', 'drawer', + 'event', 'font(-panel)?', 'formatter', + 'image( (cell|view))?', 'matrix', 'menu( item)?', 'item', + 'movie( view)?', 'open-panel', 'outline view', 'panel', + 'pasteboard', 'plugin', 'popup button', + 'progress indicator', 'responder', 'save-panel', + 'scroll view', 'secure text field( cell)?', 'slider', + 'sound', 'split view', 'stepper', 'tab view( item)?', + 'table( (column|header cell|header view|view))', + 'text( (field( cell)?|view))?', 'toolbar( item)?', + 'user-defaults', 'view', 'window'] + end + + def self.studio_events + @studio_events ||= ['accept outline drop', 'accept table drop', 'action', + 'activated', 'alert ended', 'awake from nib', 'became key', + 'became main', 'begin editing', 'bounds changed', + 'cell value', 'cell value changed', 'change cell value', + 'change item value', 'changed', 'child of item', + 'choose menu item', 'clicked', 'clicked toolbar item', + 'closed', 'column clicked', 'column moved', + 'column resized', 'conclude drop', 'data representation', + 'deminiaturized', 'dialog ended', 'document nib name', + 'double clicked', 'drag( (entered|exited|updated))?', + 'drop', 'end editing', 'exposed', 'idle', 'item expandable', + 'item value', 'item value changed', 'items changed', + 'keyboard down', 'keyboard up', 'launched', + 'load data representation', 'miniaturized', 'mouse down', + 'mouse dragged', 'mouse entered', 'mouse exited', + 'mouse moved', 'mouse up', 'moved', + 'number of browser rows', 'number of items', + 'number of rows', 'open untitled', 'opened', 'panel ended', + 'parameters updated', 'plugin loaded', 'prepare drop', + 'prepare outline drag', 'prepare outline drop', + 'prepare table drag', 'prepare table drop', + 'read from file', 'resigned active', 'resigned key', + 'resigned main', 'resized( sub views)?', + 'right mouse down', 'right mouse dragged', + 'right mouse up', 'rows changed', 'scroll wheel', + 'selected tab view item', 'selection changed', + 'selection changing', 'should begin editing', + 'should close', 'should collapse item', + 'should end editing', 'should expand item', + 'should open( untitled)?', + 'should quit( after last window closed)?', + 'should select column', 'should select item', + 'should select row', 'should select tab view item', + 'should selection change', 'should zoom', 'shown', + 'update menu item', 'update parameters', + 'update toolbar item', 'was hidden', 'was miniaturized', + 'will become active', 'will close', 'will dismiss', + 'will display browser cell', 'will display cell', + 'will display item cell', 'will display outline cell', + 'will finish launching', 'will hide', 'will miniaturize', + 'will move', 'will open', 'will pop up', 'will quit', + 'will resign active', 'will resize( sub views)?', + 'will select tab view item', 'will show', 'will zoom', + 'write to file', 'zoomed'] + end + + def self.studio_commands + @studio_commands ||= ['animate', 'append', 'call method', 'center', + 'close drawer', 'close panel', 'display', + 'display alert', 'display dialog', 'display panel', 'go', + 'hide', 'highlight', 'increment', 'item for', + 'load image', 'load movie', 'load nib', 'load panel', + 'load sound', 'localized string', 'lock focus', 'log', + 'open drawer', 'path for', 'pause', 'perform action', + 'play', 'register', 'resume', 'scroll', 'select( all)?', + 'show', 'size to fit', 'start', 'step back', + 'step forward', 'stop', 'synchronize', 'unlock focus', + 'update'] + end + + def self.studio_properties + @studio_properties ||= ['accepts arrow key', 'action method', 'active', + 'alignment', 'allowed identifiers', + 'allows branch selection', 'allows column reordering', + 'allows column resizing', 'allows column selection', + 'allows customization', 'allows editing text attributes', + 'allows empty selection', 'allows mixed state', + 'allows multiple selection', 'allows reordering', + 'allows undo', 'alpha( value)?', 'alternate image', + 'alternate increment value', 'alternate title', + 'animation delay', 'associated file name', + 'associated object', 'auto completes', 'auto display', + 'auto enables items', 'auto repeat', 'auto resizes( outline column)?', + 'auto save expanded items', 'auto save name', + 'auto save table columns', 'auto saves configuration', + 'auto scroll', 'auto sizes all columns to fit', + 'auto sizes cells', 'background color', 'bezel state', + 'bezel style', 'bezeled', 'border rect', 'border type', + 'bordered', 'bounds( rotation)?', 'box type', + 'button returned', 'button type', + 'can choose directories', 'can choose files', 'can draw', 'can hide', + 'cell( (background color|size|type))?', 'characters', + 'class', 'click count', 'clicked( data)? column', + 'clicked data item', 'clicked( data)? row', + 'closeable', 'collating', 'color( (mode|panel))', + 'command key down', 'configuration', + 'content(s| (size|view( margins)?))?', 'context', + 'continuous', 'control key down', 'control size', + 'control tint', 'control view', + 'controller visible', 'coordinate system', + 'copies( on scroll)?', 'corner view', 'current cell', + 'current column', 'current( field)? editor', + 'current( menu)? item', 'current row', + 'current tab view item', 'data source', + 'default identifiers', 'delta (x|y|z)', + 'destination window', 'directory', 'display mode', + 'displayed cell', 'document( (edited|rect|view))?', + 'double value', 'dragged column', 'dragged distance', + 'dragged items', 'draws( cell)? background', + 'draws grid', 'dynamically scrolls', 'echos bullets', + 'edge', 'editable', 'edited( data)? column', + 'edited data item', 'edited( data)? row', 'enabled', + 'enclosing scroll view', 'ending page', + 'error handling', 'event number', 'event type', + 'excluded from windows menu', 'executable path', + 'expanded', 'fax number', 'field editor', 'file kind', + 'file name', 'file type', 'first responder', + 'first visible column', 'flipped', 'floating', + 'font( panel)?', 'formatter', 'frameworks path', + 'frontmost', 'gave up', 'grid color', 'has data items', + 'has horizontal ruler', 'has horizontal scroller', + 'has parent data item', 'has resize indicator', + 'has shadow', 'has sub menu', 'has vertical ruler', + 'has vertical scroller', 'header cell', 'header view', + 'hidden', 'hides when deactivated', 'highlights by', + 'horizontal line scroll', 'horizontal page scroll', + 'horizontal ruler view', 'horizontally resizable', + 'icon image', 'id', 'identifier', + 'ignores multiple clicks', + 'image( (alignment|dims when disabled|frame style|scaling))?', + 'imports graphics', 'increment value', + 'indentation per level', 'indeterminate', 'index', + 'integer value', 'intercell spacing', 'item height', + 'key( (code|equivalent( modifier)?|window))?', + 'knob thickness', 'label', 'last( visible)? column', + 'leading offset', 'leaf', 'level', 'line scroll', + 'loaded', 'localized sort', 'location', 'loop mode', + 'main( (bunde|menu|window))?', 'marker follows cell', + 'matrix mode', 'maximum( content)? size', + 'maximum visible columns', + 'menu( form representation)?', 'miniaturizable', + 'miniaturized', 'minimized image', 'minimized title', + 'minimum column width', 'minimum( content)? size', + 'modal', 'modified', 'mouse down state', + 'movie( (controller|file|rect))?', 'muted', 'name', + 'needs display', 'next state', 'next text', + 'number of tick marks', 'only tick mark values', + 'opaque', 'open panel', 'option key down', + 'outline table column', 'page scroll', 'pages across', + 'pages down', 'palette label', 'pane splitter', + 'parent data item', 'parent window', 'pasteboard', + 'path( (names|separator))?', 'playing', + 'plays every frame', 'plays selection only', 'position', + 'preferred edge', 'preferred type', 'pressure', + 'previous text', 'prompt', 'properties', + 'prototype cell', 'pulls down', 'rate', + 'released when closed', 'repeated', + 'requested print time', 'required file type', + 'resizable', 'resized column', 'resource path', + 'returns records', 'reuses columns', 'rich text', + 'roll over', 'row height', 'rulers visible', + 'save panel', 'scripts path', 'scrollable', + 'selectable( identifiers)?', 'selected cell', + 'selected( data)? columns?', 'selected data items?', + 'selected( data)? rows?', 'selected item identifier', + 'selection by rect', 'send action on arrow key', + 'sends action when done editing', 'separates columns', + 'separator item', 'sequence number', 'services menu', + 'shared frameworks path', 'shared support path', + 'sheet', 'shift key down', 'shows alpha', + 'shows state by', 'size( mode)?', + 'smart insert delete enabled', 'sort case sensitivity', + 'sort column', 'sort order', 'sort type', + 'sorted( data rows)?', 'sound', 'source( mask)?', + 'spell checking enabled', 'starting page', 'state', + 'string value', 'sub menu', 'super menu', 'super view', + 'tab key traverses cells', 'tab state', 'tab type', + 'tab view', 'table view', 'tag', 'target( printer)?', + 'text color', 'text container insert', + 'text container origin', 'text returned', + 'tick mark position', 'time stamp', + 'title(d| (cell|font|height|position|rect))?', + 'tool tip', 'toolbar', 'trailing offset', 'transparent', + 'treat packages as directories', 'truncated labels', + 'types', 'unmodified characters', 'update views', + 'use sort indicator', 'user defaults', + 'uses data source', 'uses ruler', 'uses threaded animation', + 'uses title from previous column', 'value wraps', 'version', + 'vertical( (line scroll|page scroll|ruler view))?', 'vertically resizable', 'view', + 'visible( document rect)?', 'volume', 'width', 'window', + 'windows menu', 'wraps', 'zoomable', 'zoomed'] + end + + operators = %r(\b(#{self.operators.to_a.join('|')})\b) + classes = %r(\b(as )(#{self.classes.to_a.join('|')})\b) + literals = %r(\b(#{self.literals.to_a.join('|')})\b) + commands = %r(\b(#{self.commands.to_a.join('|')})\b) + controls = %r(\b(#{self.controls.to_a.join('|')})\b) + declarations = %r(\b(#{self.declarations.to_a.join('|')})\b) + reserved = %r(\b(#{self.reserved.to_a.join('|')})\b) + builtins = %r(\b(#{self.builtins.to_a.join('|')})s?\b) + handler_params = %r(\b(#{self.handler_params.to_a.join('|')})\b) + references = %r(\b(#{self.references.to_a.join('|')})\b) + studio_properties = %r(\b(#{self.studio_properties.to_a.join('|')})\b) + studio_classes = %r(\b(#{self.studio_classes.to_a.join('|')})s?\b) + studio_commands = %r(\b(#{self.studio_commands.to_a.join('|')})\b) + identifiers = %r(\b([a-zA-Z]\w*)\b) + + state :root do + rule %r/\s+/, Text::Whitespace + rule %r/¬\n/, Literal::String::Escape + rule %r/'s\s+/, Text + rule %r/(--|#).*?$/, Comment::Single + rule %r/\(\*/, Comment::Multiline + rule %r/[\(\){}!,.:]/, Punctuation + rule %r/(«)([^»]+)(»)/ do |match| + token Text, match[1] + token Name::Builtin, match[2] + token Text, match[3] + end + rule %r/\b((?:considering|ignoring)\s*)(application responses|case|diacriticals|hyphens|numeric strings|punctuation|white space)/ do |match| + token Keyword, match[1] + token Name::Builtin, match[2] + end + rule %r/(-|\*|\+|&|≠|>=?|<=?|=|≥|≤|\/|÷|\^)/, Operator + rule operators, Operator::Word + rule %r/^(\s*(?:on|end)\s+)'r'(%s)/ do |match| + token Keyword, match[1] + token Name::Function, match[2] + end + rule %r/^(\s*)(in|on|script|to)(\s+)/ do |match| + token Text, match[1] + token Keyword, match[2] + token Text, match[3] + end + rule classes do |match| + token Keyword, match[1] + token Name::Class, match[2] + end + rule literals, Name::Builtin + rule commands, Name::Builtin + rule controls, Keyword + rule declarations, Keyword + rule reserved, Name::Builtin + rule builtins, Name::Builtin + rule handler_params, Name::Builtin + rule studio_properties, Name::Attribute + rule studio_classes, Name::Builtin + rule studio_commands, Name::Builtin + rule references, Name::Builtin + rule %r/"(\\\\|\\"|[^"])*"/, Literal::String::Double + rule identifiers, Name::Variable + rule %r/[-+]?(\d+\.\d*|\d*\.\d+)(E[-+][0-9]+)?/, Literal::Number::Float + rule %r/[-+]?\d+/, Literal::Number::Integer + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/armasm.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/armasm.rb new file mode 100644 index 0000000..51b4a38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/armasm.rb @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class ArmAsm < RegexLexer + title "ArmAsm" + desc "Arm assembly syntax" + tag 'armasm' + filenames '*.s' + + def self.preproc_keyword + @preproc_keyword ||= %w( + define elif else endif error if ifdef ifndef include line pragma undef warning + ) + end + + def self.file_directive + @file_directive ||= %w( + BIN GET INCBIN INCLUDE LNK + ) + end + + def self.general_directive + @general_directive ||= %w( + ALIAS ALIGN AOF AOUT AREA ARM ASSERT ATTR CN CODE16 CODE32 COMMON CP + DATA DCB DCD DCDO DCDU DCFD DCFDU DCFH DCFHU DCFS DCFSU DCI DCI.N DCI.W + DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT + EXPORTAS EXTERN FIELD FILL FN FRAME FUNCTION GBLA GBLL GBLS GLOBAL IF + IMPORT INFO KEEP LCLA LCLL LCLS LEADR LEAF LTORG MACRO MAP MEND MEXIT + NOFP OPT ORG PRESERVE8 PROC QN RELOC REQUIRE REQUIRE8 RLIST RN ROUT + SETA SETL SETS SN SPACE STRONG SUBT THUMB THUMBX TTL WEND WHILE + \[ \] [|!#*=%&^] + ) + end + + def self.shift_or_condition + @shift_or_condition ||= %w( + ASR LSL LSR ROR RRX AL CC CS EQ GE GT HI HS LE LO LS LT MI NE PL VC VS + asr lsl lsr ror rrx al cc cs eq ge gt hi hs le lo ls lt mi ne pl vc vs + ) + end + + def self.builtin + @builtin ||= %w( + ARCHITECTURE AREANAME ARMASM_VERSION CODESIZE COMMANDLINE CONFIG CPU + ENDIAN FALSE FPIC FPU INPUTFILE INTER LINENUM LINENUMUP LINENUMUPPER + OBJASM_VERSION OPT PC PCSTOREOFFSET REENTRANT ROPI RWPI TRUE VAR + ) + end + + def self.operator + @operator ||= %w( + AND BASE CC CC_ENCODING CHR DEF EOR FATTR FEXEC FLOAD FSIZE INDEX LAND + LEFT LEN LEOR LNOT LOR LOWERCASE MOD NOT OR RCONST REVERSE_CC RIGHT ROL + ROR SHL SHR STR TARGET_ARCH_[0-9A-Z_]+ TARGET_FEATURE_[0-9A-Z_]+ + TARGET_FPU_[A-Z_] TARGET_PROFILE_[ARM] UAL UPPERCASE + ) + end + + state :root do + rule %r/\n/, Text + rule %r/^([ \t]*)(#[ \t]*(?:(?:#{ArmAsm.preproc_keyword.join('|')})(?:[ \t].*)?)?)(\n)/ do + groups Text, Comment::Preproc, Text + end + rule %r/[ \t]+/, Text, :command + rule %r/;.*/, Comment + rule %r/\$[a-z_]\w*\.?/i, Name::Namespace # variable substitution or macro argument + rule %r/\w+|\|[^|\n]+\|/, Name::Label + end + + state :command do + rule %r/\n/, Text, :pop! + rule %r/[ \t]+/ do |m| + token Text + goto :args + end + rule %r/;.*/, Comment, :pop! + rule %r/(?:#{ArmAsm.file_directive.join('|')})\b/ do |m| + token Keyword + goto :filespec + end + rule %r/(?:#{ArmAsm.general_directive.join('|')})(?=[; \t\n])/, Keyword + rule %r/(?:[A-Z][\dA-Z]*|[a-z][\da-z]*)(?:\.[NWnw])?(?:\.[DFIPSUdfipsu]?(?:8|16|32|64)?){,3}\b/, Name::Builtin # rather than attempt to list all opcodes, rely on all-uppercase or all-lowercase rule + rule %r/[a-z_]\w*|\|[^|\n]+\|/i, Name::Function # probably a macro name + rule %r/\$[a-z]\w*\.?/i, Name::Namespace + end + + state :args do + rule %r/\n/, Text, :pop! + rule %r/[ \t]+/, Text + rule %r/;.*/, Comment, :pop! + rule %r/(?:#{ArmAsm.shift_or_condition.join('|')})\b/, Name::Builtin + rule %r/[a-z_]\w*|\|[^|\n]+\|/i, Name::Variable # various types of symbol + rule %r/%[bf]?[at]?\d+(?:[a-z_]\w*)?/i, Name::Label + rule %r/(?:&|0x)\h+(?!p)/i, Literal::Number::Hex + rule %r/(?:&|0x)[.\h]+(?:p[-+]?\d+)?/i, Literal::Number::Float + rule %r/0f_\h{8}|0d_\h{16}/i, Literal::Number::Float + rule %r/(?:2_[01]+|3_[0-2]+|4_[0-3]+|5_[0-4]+|6_[0-5]+|7_[0-6]+|8_[0-7]+|9_[0-8]+|\d+)(?!e)/i, Literal::Number::Integer + rule %r/(?:2_[.01]+|3_[.0-2]+|4_[.0-3]+|5_[.0-4]+|6_[.0-5]+|7_[.0-6]+|8_[.0-7]+|9_[.0-8]+|[.\d]+)(?:e[-+]?\d+)?/i, Literal::Number::Float + rule %r/[@:](?=[ \t]*(?:8|16|32|64|128|256)[^\d])/, Operator + rule %r/[.@]|\{(?:#{ArmAsm.builtin.join('|')})\}/, Name::Constant + rule %r/[-!#%&()*+,\/<=>?^{|}]|\[|\]|!=|&&|\/=|<<|<=|<>|==|><|>=|>>|\|\||:(?:#{ArmAsm.operator.join('|')}):/, Operator + rule %r/\$[a-z]\w*\.?/i, Name::Namespace + rule %r/'/ do |m| + token Literal::String::Char + goto :singlequoted + end + rule %r/"/ do |m| + token Literal::String::Double + goto :doublequoted + end + end + + state :singlequoted do + rule %r/\n/, Text, :pop! + rule %r/\$\$/, Literal::String::Char + rule %r/\$[a-z]\w*\.?/i, Name::Namespace + rule %r/'/ do |m| + token Literal::String::Char + goto :args + end + rule %r/[^$'\n]+/, Literal::String::Char + end + + state :doublequoted do + rule %r/\n/, Text, :pop! + rule %r/\$\$/, Literal::String::Double + rule %r/\$[a-z]\w*\.?/i, Name::Namespace + rule %r/"/ do |m| + token Literal::String::Double + goto :args + end + rule %r/[^$"\n]+/, Literal::String::Double + end + + state :filespec do + rule %r/\n/, Text, :pop! + rule %r/\$\$/, Literal::String::Other + rule %r/\$[a-z]\w*\.?/i, Name::Namespace + rule %r/[^$\n]+/, Literal::String::Other + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/augeas.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/augeas.rb new file mode 100644 index 0000000..2fda76f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/augeas.rb @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Augeas < RegexLexer + title "Augeas" + desc "The Augeas programming language (augeas.net)" + + tag 'augeas' + aliases 'aug' + filenames '*.aug' + mimetypes 'text/x-augeas' + + def self.reserved + @reserved ||= Set.new %w( + _ let del store value counter seq key label autoload incl excl + transform test get put in after set clear insa insb print_string + print_regexp print_endline print_tree lens_ctype lens_atype + lens_ktype lens_vtype lens_format_atype regexp_match + ) + end + + state :basic do + rule %r/\s+/m, Text + rule %r/\(\*/, Comment::Multiline, :comment + end + + state :comment do + rule %r/\*\)/, Comment::Multiline, :pop! + rule %r/\(\*/, Comment::Multiline, :comment + rule %r/[^*)]+/, Comment::Multiline + rule %r/[*)]/, Comment::Multiline + end + + state :root do + mixin :basic + + rule %r/(:)(\w\w*)/ do + groups Punctuation, Keyword::Type + end + + rule %r/\w[\w']*/ do |m| + name = m[0] + if name == "module" + token Keyword::Reserved + push :module + elsif self.class.reserved.include? name + token Keyword::Reserved + elsif name =~ /\A[A-Z]/ + token Keyword::Namespace + else + token Name + end + end + + rule %r/"/, Str, :string + rule %r/\//, Str, :regexp + + rule %r([-*+.=?\|]+), Operator + rule %r/[\[\](){}:;]/, Punctuation + end + + state :module do + rule %r/\s+/, Text + rule %r/[A-Z][a-zA-Z0-9_.]*/, Name::Namespace, :pop! + end + + state :regexp do + rule %r/\//, Str::Regex, :pop! + rule %r/[^\\\/]+/, Str::Regex + rule %r/\\[\\\/]/, Str::Regex + rule %r/\\/, Str::Regex + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\/, Str::Escape, :escape + rule %r/[^\\"]+/, Str + end + + state :escape do + rule %r/[abfnrtv"'&\\]/, Str::Escape, :pop! + rule %r/\^[\]\[A-Z@\^_]/, Str::Escape, :pop! + rule %r/o[0-7]+/i, Str::Escape, :pop! + rule %r/x[\da-f]+/i, Str::Escape, :pop! + rule %r/\d+/, Str::Escape, :pop! + rule %r/\s+/, Str::Escape, :pop! + rule %r/./, Str, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/awk.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/awk.rb new file mode 100644 index 0000000..8301f86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/awk.rb @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Awk < RegexLexer + title "Awk" + desc "pattern-directed scanning and processing language" + + tag 'awk' + filenames '*.awk' + mimetypes 'application/x-awk' + + def self.detect?(text) + return true if text.shebang?('awk') + end + + id = /[$a-zA-Z_][a-zA-Z0-9_]*/ + + def self.keywords + @keywords ||= Set.new %w( + if else while for do break continue return next nextfile delete + exit print printf getline + ) + end + + def self.declarations + @declarations ||= Set.new %w(function) + end + + def self.reserved + @reserved ||= Set.new %w(BEGIN END) + end + + def self.constants + @constants ||= Set.new %w( + CONVFMT FS NF NR FNR FILENAME RS OFS ORS OFMT SUBSEP ARGC ARGV + ENVIRON + ) + end + + def self.builtins + @builtins ||= %w( + exp log sqrt sin cos atan2 length rand srand int substr index match + split sub gsub sprintf system tolower toupper + ) + end + + state :comments_and_whitespace do + rule %r/\s+/, Text + rule %r(#.*?$), Comment::Single + end + + state :expr_start do + mixin :comments_and_whitespace + rule %r(/) do + token Str::Regex + goto :regex + end + rule %r//, Text, :pop! + end + + state :regex do + rule %r(/) do + token Str::Regex + goto :regex_end + end + + rule %r([^/]\n), Error, :pop! + + rule %r/\n/, Error, :pop! + rule %r/\[\^/, Str::Escape, :regex_group + rule %r/\[/, Str::Escape, :regex_group + rule %r/\\./, Str::Escape + rule %r{[(][?][:=+*/%\^!=]=?|in\b|\+\+|--|\|), Operator, :expr_start + rule %r(&&|\|\||~!?), Operator, :expr_start + rule %r/[(\[,]/, Punctuation, :expr_start + rule %r/;/, Punctuation, :statement + rule %r/[)\].]/, Punctuation + + rule %r/[?]/ do + token Punctuation + push :ternary + push :expr_start + end + + rule %r/[{}]/, Punctuation, :statement + + rule id do |m| + if self.class.keywords.include? m[0] + token Keyword + push :expr_start + elsif self.class.declarations.include? m[0] + token Keyword::Declaration + push :expr_start + elsif self.class.reserved.include? m[0] + token Keyword::Reserved + elsif self.class.constants.include? m[0] + token Keyword::Constant + elsif self.class.builtins.include? m[0] + token Name::Builtin + elsif m[0] =~ /^\$/ + token Name::Variable + else + token Name::Other + end + end + + rule %r/[0-9]+\.[0-9]+/, Num::Float + rule %r/[0-9]+/, Num::Integer + rule %r/"(\\[\\"]|[^"])*"/, Str::Double + rule %r/:/, Punctuation + end + + state :statement do + rule %r/[{}]/, Punctuation + mixin :expr_start + end + + state :ternary do + rule %r/:/ do + token Punctuation + goto :expr_start + end + + mixin :root + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/batchfile.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/batchfile.rb new file mode 100644 index 0000000..cc61d85 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/batchfile.rb @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Batchfile < RegexLexer + title "Batchfile" + desc "Windows Batch File" + + tag 'batchfile' + aliases 'bat', 'batch', 'dosbatch', 'winbatch' + filenames '*.bat', '*.cmd' + + mimetypes 'application/bat', 'application/x-bat', 'application/x-msdos-program' + + def self.keywords + @keywords ||= %w( + if else for in do goto call exit + ) + end + + def self.operator_words + @operator_words ||= %w( + exist defined errorlevel cmdextversion not equ neq lss leq gtr geq + ) + end + + def self.devices + @devices ||= %w( + con prn aux nul com1 com2 com3 com4 com5 com6 com7 com8 com9 lpt1 lpt2 + lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9 + ) + end + + def self.builtin_commands + @builtin_commands ||= %w( + assoc attrib break bcdedit cacls cd chcp chdir chkdsk chkntfs choice + cls cmd color comp compact convert copy date del dir diskpart doskey + dpath driverquery echo endlocal erase fc find findstr format fsutil + ftype gpresult graftabl help icacls label md mkdir mklink mode more + move openfiles path pause popd print prompt pushd rd recover ren + rename replace rmdir robocopy setlocal sc schtasks shift shutdown sort + start subst systeminfo takeown tasklist taskkill time timeout title + tree type ver verify vol xcopy waitfor wmic + ) + end + + def self.other_commands + @other_commands ||= %w( + addusers admodcmd ansicon arp at bcdboot bitsadmin browstat certreq + certutil change cidiag cipher cleanmgr clip cmdkey compress convertcp + coreinfo csccmd csvde cscript curl debug defrag delprof deltree devcon + diamond dirquota diruse diskshadow diskuse dism dnscmd dsacls dsadd + dsget dsquery dsmod dsmove dsrm dsmgmt dsregcmd edlin eventcreate + expand extract fdisk fltmc forfiles freedisk ftp getmac gpupdate + hostname ifmember inuse ipconfig kill lgpo lodctr logman logoff + logtime makecab mapisend mbsacli mem mountvol moveuser msg mshta + msiexec msinfo32 mstsc nbtstat net net1 netdom netsh netstat nlsinfo + nltest now nslookup ntbackup ntdsutil ntoskrnl ntrights nvspbind + pathping perms ping portqry powercfg pngout pnputil printbrm prncnfg + prnmngr procdump psexec psfile psgetsid psinfo pskill pslist + psloggedon psloglist pspasswd psping psservice psshutdown pssuspend + qbasic qgrep qprocess query quser qwinsta rasdial reg reg1 regdump + regedt32 regsvr32 regini reset restore rundll32 rmtshare route rpcping + run runas scandisk setspn setx sfc share shellrunas shortcut sigcheck + sleep slmgr strings subinacl sysmon telnet tftp tlist touch tracerpt + tracert tscon tsdiscon tskill tttracer typeperf tzutil undelete + unformat verifier vmconnect vssadmin w32tm wbadmin wecutil wevtutil + wget where whoami windiff winrm winrs wpeutil wpr wusa wuauclt wscript + ) + end + + def self.attributes + @attributes ||= %w( + on off disable enableextensions enabledelayedexpansion + ) + end + + state :basic do + # Comments + rule %r/@?\brem\b.*$/i, Comment + + # Empty Labels + rule %r/^::.*$/, Comment + + # Labels + rule %r/:[a-z]+/i, Name::Label + + rule %r/([a-z]\w*)(\.exe|com|bat|cmd|msi)?/i do |m| + if self.class.devices.include? m[1] + groups Keyword::Reserved, Error + elsif self.class.keywords.include? m[1] + groups Keyword, Error + elsif self.class.operator_words.include? m[1] + groups Operator::Word, Error + elsif self.class.builtin_commands.include? m[1] + token Name::Builtin + elsif self.class.other_commands.include? m[1] + token Name::Builtin + elsif self.class.attributes.include? m[1] + groups Name::Attribute, Error + elsif "set".casecmp m[1] + groups Keyword::Declaration, Error + else + token Text + end + end + + rule %r/((?:[\/\+]|--?)[a-z]+)\s*/i, Name::Attribute + + mixin :expansions + + rule %r/[<>&|(){}\[\]\-+=;,~?*]/, Operator + end + + state :escape do + rule %r/\^./m, Str::Escape + end + + state :expansions do + # Normal and Delayed expansion + rule %r/[%!]+([a-z_$@#]+)[%!]+/i, Name::Variable + # For Variables + rule %r/(\%+~?[a-z]+\d?)/i, Name::Variable::Magic + end + + state :double_quotes do + mixin :escape + rule %r/["]/, Str::Double, :pop! + mixin :expansions + rule %r/[^\^"%!]+/, Str::Double + end + + state :single_quotes do + mixin :escape + rule %r/[']/, Str::Single, :pop! + mixin :expansions + rule %r/[^\^'%!]+/, Str::Single + end + + state :backtick do + mixin :escape + rule %r/[`]/, Str::Backtick, :pop! + mixin :expansions + rule %r/[^\^`%!]+/, Str::Backtick + end + + state :data do + rule %r/\s+/, Text + rule %r/0x[0-9a-f]+/i, Literal::Number::Hex + rule %r/[0-9]/, Literal::Number + rule %r/["]/, Str::Double, :double_quotes + rule %r/[']/, Str::Single, :single_quotes + rule %r/[`]/, Str::Backtick, :backtick + rule %r/[^\s&|()\[\]{}\^=;!%+\-,"'`~?*]+/, Text + mixin :escape + end + + state :root do + mixin :basic + mixin :data + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bbcbasic.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bbcbasic.rb new file mode 100644 index 0000000..c64a1b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bbcbasic.rb @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class BBCBASIC < RegexLexer + title "BBCBASIC" + desc "BBC BASIC syntax" + tag 'bbcbasic' + filenames '*,fd1' + + def self.punctuation + @punctuation ||= %w( + [,;'~] SPC TAB + ) + end + + def self.function + @function ||= %w( + ABS ACS ADVAL ASC ASN ATN BEATS BEAT BGET# CHR\$ COS COUNT DEG DIM + EOF# ERL ERR EVAL EXP EXT# FN GET\$# GET\$ GET HIMEM INKEY\$ INKEY + INSTR INT LEFT\$ LEN LN LOG LOMEM MID\$ OPENIN OPENOUT OPENUP PAGE + POINT POS PTR# RAD REPORT\$ RIGHT\$ RND SGN SIN SQR STR\$ STRING\$ SUM + SUMLEN TAN TEMPO TIME\$ TIME TOP USR VAL VPOS + ) + end + + def self.statement + @statement ||= %w( + BEATS BPUT# CALL CASE CHAIN CLEAR CLG CLOSE# CLS COLOR COLOUR DATA + ELSE ENDCASE ENDIF ENDPROC ENDWHILE END ENVELOPE FOR GCOL GOSUB GOTO + IF INSTALL LET LIBRARY MODE NEXT OFF OF ON ORIGIN OSCI OTHERWISE + OVERLAY PLOT PRINT# PRINT PROC QUIT READ REPEAT REPORT RETURN SOUND + STEP STEREO STOP SWAP SYS THEN TINT TO VDU VOICES VOICE UNTIL WAIT + WHEN WHILE WIDTH + ) + end + + def self.operator + @operator ||= %w( + << <= <> < >= >>> >> > [-!$()*+/=?^|] AND DIV EOR MOD NOT OR + ) + end + + def self.constant + @constant ||= %w( + FALSE TRUE + ) + end + + state :expression do + rule %r/#{BBCBASIC.function.join('|')}/o, Name::Builtin # function or pseudo-variable + rule %r/#{BBCBASIC.operator.join('|')}/o, Operator + rule %r/#{BBCBASIC.constant.join('|')}/o, Name::Constant + rule %r/"[^"]*"/o, Literal::String + rule %r/[a-z_`][\w`]*[$%]?/io, Name::Variable + rule %r/@%/o, Name::Variable + rule %r/[\d.]+/o, Literal::Number + rule %r/%[01]+/o, Literal::Number::Bin + rule %r/&[\h]+/o, Literal::Number::Hex + end + + state :root do + rule %r/(:+)( *)(\*)(.*)/ do + groups Punctuation, Text, Keyword, Text # CLI command + end + rule %r/(\n+ *)(\*)(.*)/ do + groups Text, Keyword, Text # CLI command + end + rule %r/(ELSE|OTHERWISE|REPEAT|THEN)( *)(\*)(.*)/ do + groups Keyword, Text, Keyword, Text # CLI command + end + rule %r/[ \n]+/o, Text + rule %r/:+/o, Punctuation + rule %r/[\[]/o, Keyword, :assembly1 + rule %r/REM *>.*/o, Comment::Special + rule %r/REM.*/o, Comment + rule %r/(?:#{BBCBASIC.statement.join('|')}|CIRCLE(?: *FILL)?|DEF *(?:FN|PROC)|DRAW(?: *BY)?|DIM(?!\()|ELLIPSE(?: *FILL)?|ERROR(?: *EXT)?|FILL(?: *BY)?|INPUT(?:#| *LINE)?|LINE(?: *INPUT)?|LOCAL(?: *DATA| *ERROR)?|MOUSE(?: *COLOUR| *OFF| *ON| *RECTANGLE| *STEP| *TO)?|MOVE(?: *BY)?|ON(?! *ERROR)|ON *ERROR *(?:LOCAL|OFF)?|POINT(?: *BY)?(?!\()|RECTANGE(?: *FILL)?|RESTORE(?: *DATA| *ERROR)?|TRACE(?: *CLOSE| *ENDPROC| *OFF| *STEP(?: *FN| *ON| *PROC)?| *TO)?)/o, Keyword + mixin :expression + rule %r/#{BBCBASIC.punctuation.join('|')}/o, Punctuation + end + + # Assembly statements are parsed as + # {label} {directive|opcode |']' {expressions}} {comment} + # Technically, you don't need whitespace between opcodes and arguments, + # but this is rare in uncrunched source and trying to enumerate all + # possible opcodes here is impractical so we colour it as though + # the whitespace is required. Opcodes and directives can only easily be + # distinguished from the symbols that make up expressions by looking at + # their position within the statement. Similarly, ']' is treated as a + # keyword at the start of a statement or as punctuation elsewhere. This + # requires a two-state state machine. + + state :assembly1 do + rule %r/ +/o, Text + rule %r/]/o, Keyword, :pop! + rule %r/[:\n]/o, Punctuation + rule %r/\.[a-z_`][\w`]*%? */io, Name::Label + rule %r/(?:REM|;)[^:\n]*/o, Comment + rule %r/[^ :\n]+/o, Keyword, :assembly2 + end + + state :assembly2 do + rule %r/ +/o, Text + rule %r/[:\n]/o, Punctuation, :pop! + rule %r/(?:REM|;)[^:\n]*/o, Comment, :pop! + mixin :expression + rule %r/[!#,@\[\]^{}]/, Punctuation + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bibtex.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bibtex.rb new file mode 100644 index 0000000..cc6ece7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bibtex.rb @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# Regular expressions based on https://github.com/SaswatPadhi/prismjs-bibtex +# and https://github.com/alecthomas/chroma/blob/master/lexers/b/bibtex.go + +module Rouge + module Lexers + class BibTeX < RegexLexer + title 'BibTeX' + desc "BibTeX" + tag 'bibtex' + aliases 'bib' + filenames '*.bib' + + valid_punctuation = Regexp.quote("@!$&.\\:;<>?[]^`|~*/+-") + valid_name = /[a-z_#{valid_punctuation}][\w#{valid_punctuation}]*/io + + state :root do + mixin :whitespace + + rule %r/@(#{valid_name})/o do |m| + match = m[1].downcase + + if match == "comment" + token Comment + elsif match == "preamble" + token Name::Class + push :closing_brace + push :value + push :opening_brace + elsif match == "string" + token Name::Class + push :closing_brace + push :field + push :opening_brace + else + token Name::Class + push :closing_brace + push :command_body + push :opening_brace + end + end + + rule %r/.+/, Comment + end + + state :opening_brace do + mixin :whitespace + rule %r/[{(]/, Punctuation, :pop! + end + + state :closing_brace do + mixin :whitespace + rule %r/[})]/, Punctuation, :pop! + end + + state :command_body do + mixin :whitespace + rule %r/[^\s\,\}]+/ do + token Name::Label + pop! + push :fields + end + end + + state :fields do + mixin :whitespace + rule %r/,/, Punctuation, :field + rule(//) { pop! } + end + + state :field do + mixin :whitespace + rule valid_name do + token Name::Attribute + push :value + push :equal_sign + end + rule(//) { pop! } + end + + state :equal_sign do + mixin :whitespace + rule %r/=/, Punctuation, :pop! + end + + state :value do + mixin :whitespace + rule valid_name, Name::Variable + rule %r/"/, Literal::String, :quoted_string + rule %r/\{/, Literal::String, :braced_string + rule %r/\d+/, Literal::Number + rule %r/#/, Punctuation + rule(//) { pop! } + end + + state :quoted_string do + rule %r/\{/, Literal::String, :braced_string + rule %r/"/, Literal::String, :pop! + rule %r/[^\{\"]+/, Literal::String + end + + state :braced_string do + rule %r/\{/, Literal::String, :braced_string + rule %r/\}/, Literal::String, :pop! + rule %r/[^\{\}]+/, Literal::String + end + + state :whitespace do + rule %r/\s+/, Text + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bicep.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bicep.rb new file mode 100644 index 0000000..5748f4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bicep.rb @@ -0,0 +1,111 @@ +module Rouge + module Lexers + class Bicep < Rouge::RegexLexer + tag 'bicep' + filenames '*.bicep' + + title "Bicep" + desc 'Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources.' + + def self.keywords + @keywords ||= Set.new %w( + as assert existing extends extension false for from func if import in metadata module + none null output param provider resource targetScope test true type using var void with + ) + end + + def self.datatypes + @datatypes ||= Set.new %w(array bool int object string) + end + + def self.functions + @functions ||= Set.new %w( + array base64 base64ToJson base64ToString bool cidrHost cidrSubnet concat contains dataUri + dataUriToString dateTimeAdd dateTimeFromEpoch dateTimeToEpoch deployer deployment empty endsWith + environment extensionResourceId fail filter first flatten format getSecret groupBy guid indexOf int + intersection items join json last lastIndexOf length list* listAccountSas listKeys listSecrets loadFileAsBase64 + loadJsonContent loadTextContent loadYamlContent managementGroup managementGroupResourceId map mapValue max min + newGuid objectKeys padLeft parseCidr pickZones range readEnvironmentVariable reduce reference replace resourceGroup + resourceId shallowMerge skip sort split startsWith string subscription subscriptionResourceId substring take tenant + tenantResourceId toLogicalZone toLower toObject toPhysicalZone toUpper trim union uniqueString uri uriComponent + uriComponentToString utcNow + ) + end + + operators = %w(+ - * / % < <= > >= == != =~ !~ && || ! ?? ... .?) + + punctuations = %w(( ) { } [ ] , : ; = .) + + state :root do + mixin :comments + + # Match strings + rule %r/'/, Str::Single, :string + + # Match numbers + rule %r/\b\d+\b/, Num + + # Rules for sets of reserved keywords + rule %r/\b\w+\b/ do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.datatypes.include? m[0] + token Keyword::Type + elsif self.class.functions.include? m[0] + token Name::Function + else + token Name + end + end + + # Match operators + rule %r/#{operators.map { |o| Regexp.escape(o) }.join('|')}/, Operator + + # Enter a state when encountering an opening curly bracket + rule %r/{/, Punctuation::Indicator, :block + + # Match punctuation + rule %r/#{punctuations.map { |p| Regexp.escape(p) }.join('|')}/, Punctuation + + # Match identifiers + rule %r/[a-zA-Z_]\w*/, Name + + # Match decorators + rule %r/@[a-zA-Z_]\w*/, Name::Decorator + + # Ignore whitespace + rule %r/\s+/, Text + end + + state :comments do + rule %r(//[^\n\r]+), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + end + + state :string do + rule %r/[^'$}]+/, Str::Single + rule %r/\$(?!\{)/, Str::Single + rule %r/\$[\{]/, Str::Interpol, :interp + rule %r/\'/, Str::Single, :pop! + rule %r/\$+/, Str::Single + end + + state :interp do + rule %r/\}/, Str::Interpol, :pop! + mixin :root + end + + # State for matching code blocks between curly brackets + state :block do + # Match property names + rule %r/\b([a-zA-Z_]\w*)\b(?=\s*:)/, Name::Property + + # Match closing curly brackets + rule %r/}/, Punctuation::Indicator, :pop! + + # Include the root state for nested tokens + mixin :root + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/biml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/biml.rb new file mode 100644 index 0000000..602a57a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/biml.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'xml.rb' + + class BIML < XML + title "BIML" + desc "BIML, Business Intelligence Markup Language" + tag 'biml' + filenames '*.biml' + + def self.detect?(text) + return true if text =~ /<\s*Biml\b/ + end + + prepend :root do + rule %r(<#\@\s*)m, Name::Tag, :directive_tag + + rule %r(<#[=]?\s*)m, Name::Tag, :directive_as_csharp + end + + prepend :attr do + #TODO: how to deal with embedded <# tags inside a attribute string + #rule %r("<#[=]?\s*)m, Name::Tag, :directive_as_csharp + end + + state :directive_as_csharp do + rule %r/\s*#>\s*/m, Name::Tag, :pop! + rule %r(.*?(?=\s*#>\s*))m do + delegate CSharp + end + end + + state :directive_tag do + rule %r/\s+/m, Text + rule %r/[\w.:-]+\s*=/m, Name::Attribute, :attr + rule %r/\w+\s*/m, Name::Attribute + rule %r(/?\s*#>), Name::Tag, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bpf.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bpf.rb new file mode 100644 index 0000000..cd3307c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bpf.rb @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class BPF < RegexLexer + title "BPF" + desc "BPF bytecode syntax" + tag 'bpf' + + TYPE_KEYWORDS = %w( + u8 u16 u32 u64 s8 s16 s32 s64 ll + ).join('|') + + MISC_KEYWORDS = %w( + be16 be32 be64 le16 le32 le64 bswap16 bswap32 bswap64 exit lock map + ).join('|') + + state :root do + # Line numbers and hexadecimal output from bpftool/objdump + rule %r/(\d+)(:)(\s+)(\(\h{2}\))/i do + groups Generic::Lineno, Punctuation, Text::Whitespace, Generic + end + rule %r/(\d+)(:)(\s+)((?:\h{2} ){8})/i do + groups Generic::Lineno, Punctuation, Text::Whitespace, Generic + end + rule %r/(\d+)(:)(\s+)/i do + groups Generic::Lineno, Punctuation, Text::Whitespace + end + + # Calls to helpers + rule %r/(call)(\s+)(\d+)/i do + groups Keyword, Text::Whitespace, Literal::Number::Integer + end + rule %r/(call)(\s+)(\w+)(?:(#)(\d+))?/i do + groups Keyword, Text::Whitespace, Name::Builtin, Punctuation, Literal::Number::Integer + end + + # Unconditional jumps + rule %r/(gotol?)(\s*)([-+]0x\w+)?([-+]\d+)?(\s*)(?)/i do + groups Keyword, Text::Whitespace, Literal::Number::Hex, Literal::Number::Integer, Text::Whitespace, Name::Label + end + + # Conditional jumps + rule %r/(if)(\s+)([rw]\d+)(\s*)([s!=<>]+)(\s*)(0x\h+|[-]?\d+)(\s*)(gotol?)(\s*)([-+]0x\w+)?([-+]\d+)?(\s*)(?)/i do + groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Literal::Number, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Hex, Literal::Number::Integer, Text::Whitespace, Name::Label + end + rule %r/(if)(\s+)([rw]\d+)(\s*)([s!=<>]+)(\s*)([rw]\d+)(\s*)(gotol?)(\s*)([-+]0x\w+)?([-+]\d+)?(\s*)(?)/i do + groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Name, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Hex, Literal::Number::Integer, Text::Whitespace, Name::Label + end + + # Dereferences + rule %r/(\*)(\s*)(\()(#{TYPE_KEYWORDS})(\s*)(\*)(\))/i do + groups Operator, Text::Whitespace, Punctuation, Keyword::Type, Text::Whitespace, Operator, Punctuation + push :address + end + + # Operators + rule %r/[+-\/\*&|><^s]{0,3}=/i, Operator + + # Registers + rule %r/([+-]?)([rw]\d+)/i do + groups Punctuation, Name + end + + # Comments + rule %r/\/\//, Comment::Single, :linecomment + rule %r/\/\*/, Comment::Multiline, :multilinescomment + + rule %r/#{MISC_KEYWORDS}/i, Keyword + + # Literals and global objects (maps) refered by name + rule %r/([-]?0x\h+|[-]?\d+)(\s*)(ll)?/i do + groups Literal::Number, Text::Whitespace, Keyword::Type + end + rule %r/(\w+)(\s*)(ll)/i do + groups Name, Text::Whitespace, Keyword::Type + end + + # Labels + rule %r/(\w+)(\s*)(:)/i do + groups Name::Label, Text::Whitespace, Punctuation + end + + rule %r{.}m, Text + end + + state :address do + # Address is offset from register + rule %r/(\()([rw]\d+)(\s*)([+-])(\s*)(\d+)(\))/i do + groups Punctuation, Name, Text::Whitespace, Operator, Text::Whitespace, Literal::Number::Integer, Punctuation + pop! + end + + # Address is array subscript + rule %r/(\w+)(\[)(\d+)(\])/i do + groups Name, Punctuation, Literal::Number::Integer, Punctuation + pop! + end + rule %r/(\w+)(\[)([rw]\d+)(\])/i do + groups Name, Punctuation, Name, Punctuation + pop! + end + end + + state :linecomment do + rule %r/\n/, Comment::Single, :pop! + rule %r/.+/, Comment::Single + end + + state :multilinescomment do + rule %r/\*\//, Comment::Multiline, :pop! + rule %r/([^\*\/]+)/, Comment::Multiline + rule %r/([\*\/])/, Comment::Multiline + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brainfuck.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brainfuck.rb new file mode 100644 index 0000000..6c25d00 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brainfuck.rb @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Brainfuck < RegexLexer + tag 'brainfuck' + filenames '*.b', '*.bf' + mimetypes 'text/x-brainfuck' + + title "Brainfuck" + aliases "bf" + desc "The Brainfuck programming language" + + start { push :bol } + + state :bol do + rule %r/\s+/m, Text + rule %r/\[/, Comment::Multiline, :comment_multi + rule(//) { pop! } + end + + state :root do + rule %r/\]/, Error + rule %r/\[/, Punctuation, :loop + + mixin :comment_single + mixin :commands + end + + state :comment_multi do + rule %r/\[/, Comment::Multiline, :comment_multi + rule %r/\]/, Comment::Multiline, :pop! + rule %r/[^\[\]]+?/m, Comment::Multiline + end + + state :comment_single do + rule %r/[^><+\-.,\[\]]+/, Comment::Single + end + + state :loop do + rule %r/\[/, Punctuation, :loop + rule %r/\]/, Punctuation, :pop! + mixin :comment_single + mixin :commands + end + + state :commands do + rule %r/[><]+/, Name::Builtin + rule %r/[+\-.,]+/, Name::Function + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brightscript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brightscript.rb new file mode 100644 index 0000000..ebd6336 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/brightscript.rb @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Brightscript < RegexLexer + title "BrightScript" + desc "BrightScript Programming Language (https://developer.roku.com/en-ca/docs/references/brightscript/language/brightscript-language-reference.md)" + tag 'brightscript' + aliases 'bs', 'brs' + filenames '*.brs' + + # https://developer.roku.com/en-ca/docs/references/brightscript/language/global-utility-functions.md + # https://developer.roku.com/en-ca/docs/references/brightscript/language/global-string-functions.md + # https://developer.roku.com/en-ca/docs/references/brightscript/language/global-math-functions.md + def self.name_builtin + @name_builtin ||= Set.new %w( + ABS ASC ATN CDBL CHR CINT CONTROL COPYFILE COS CREATEDIRECTORY CSNG + DELETEDIRECTORY DELETEFILE EXP FINDMEMBERFUNCTION FINDNODE FIX + FORMATDRIVEFORMATJSON GETINTERFACE INSTR INT LCASE LEFT LEN LISTDIR + LOG MATCHFILES MID MOVEFILE OBSERVEFIELD PARSEJSON PARSEXML + READASCIIFILE REBOOTSYSTEM RIGHT RND RUNGARBAGECOLLECTOR SGN SIN + SLEEP SQR STR STRI STRING STRINGI STRTOI SUBSTITUTE TANTEXTTOP TEXT + TRUCASE UPTIME VALVISIBLE VISIBLE WAIT + ) + end + + # https://developer.roku.com/en-ca/docs/references/brightscript/language/reserved-words.md + def self.keyword_reserved + @keyword_reserved ||= Set.new %w( + BOX CREATEOBJECT DIM EACH ELSE ELSEIF END ENDFUNCTION ENDIF ENDSUB + ENDWHILE EVAL EXIT EXITWHILE FALSE FOR FUNCTION GETGLOBALAA + GETLASTRUNCOMPILEERROR GETLASTRUNRUNTIMEERROR GOTO IF IN INVALID LET + LINE_NUM M NEXT OBJFUN POS PRINT REM RETURN RUN STEP STOP SUB TAB TO + TRUE TYPE WHILE + ) + end + + # These keywords are present in BrightScript, but not supported in standard .brs files + def self.keyword_reserved_unsupported + @keyword_reserved_unsupported ||= Set.new %w( + CLASS CONST IMPORT LIBRARY NAMESPACE PRIVATE PROTECTED PUBLIC + ) + end + + # https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md + def self.keyword_type + @keyword_type ||= Set.new %w( + BOOLEAN DIM DOUBLE DYNAMIC FLOAT FUNCTION INTEGER INTERFACE INVALID + LONGINTEGER OBJECT STRING VOID + ) + end + + # https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md#operators + def self.operator_word + @operator_word ||= Set.new %w( + AND AS MOD NOT OR THEN + ) + end + + # Scene graph components configured as builtins. See BrightScript component documentation e.g. + # https://developer.roku.com/en-ca/docs/references/brightscript/components/roappinfo.md + def self.builtins + @builtins ||= Set.new %w( + roAppendFile roAppInfo roAppManager roArray roAssociativeArray + roAudioGuide roAudioMetadata roAudioPlayer roAudioPlayerEvent + roAudioResourceroBitmap roBoolean roBoolean roBrightPackage roBrSub + roButton roByteArray roCaptionRenderer roCaptionRendererEvent + roCecInterface roCECStatusEvent roChannelStore roChannelStoreEvent + roClockWidget roCodeRegistrationScreen + roCodeRegistrationScreenEventroCompositor roControlDown roControlPort + roControlPort roControlUp roCreateFile roDatagramReceiver + roDatagramSender roDataGramSocket roDateTime roDeviceInfo + roDeviceInfoEvent roDoubleroEVPCipher roEVPDigest roFileSystem + roFileSystemEvent roFloat roFont roFontMetrics roFontRegistry + roFunction roGlobal roGpio roGridScreen roGridScreenEvent + roHdmiHotPlugEventroHdmiStatus roHdmiStatusEvent roHMAC roHttpAgent + roImageCanvas roImageCanvasEvent roImageMetadata roImagePlayer + roImageWidgetroInput roInputEvent roInt roInt roInvalid roInvalid + roIRRemote roKeyboard roKeyboardPress roKeyboardScreen + roKeyboardScreenEventroList roListScreen roListScreenEvent + roLocalization roLongInteger roMessageDialog roMessageDialogEvent + roMessagePort roMicrophone roMicrophoneEvent roNetworkConfiguration + roOneLineDialog roOneLineDialogEventroParagraphScreen + roParagraphScreenEvent roPath roPinEntryDialog roPinEntryDialogEvent + roPinentryScreen roPosterScreen roPosterScreenEventroProgramGuide + roQuadravoxButton roReadFile roRectangleroRegexroRegion roRegistry + roRegistrySection roResourceManager roRSA roRssArticle roRssParser + roScreen roSearchHistory roSearchScreen roSearchScreenEvent + roSerialPort roSGNode roSGNodeEvent roSGScreenroSGScreenEvent + roSlideShowroSlideShowEvent roSNS5 roSocketAddress roSocketEvent + roSpringboardScreen roSpringboardScreenEventroSprite roStorageInfo + roStreamSocket roStringroSystemLogroSystemLogEvent roSystemTime + roTextFieldroTextScreen roTextScreenEvent roTextToSpeech + roTextToSpeechEvent roTextureManager roTextureRequest + roTextureRequestEventroTextWidget roTimer roTimespan roTouchScreen + roTunerroTunerEvent roUniversalControlEvent roUrlEvent roUrlTransfer + roVideoEvent roVideoInput roVideoMode roVideoPlayer roVideoPlayerEvent + roVideoScreen roVideoScreenEventroWriteFile roXMLElement roXMLList + ) + end + + id = /[$a-z_][a-z0-9_]*/io + + state :root do + rule %r/\s+/m, Text::Whitespace + + # https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md#comments + rule %r/\'.*/, Comment::Single + rule %r/REM.*/i, Comment::Single + + # https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md#operators + rule %r([~!%^&*+=\|?:<>/-]), Operator + + rule %r/\d*\.\d+(e-?\d+)?/i, Num::Float + rule %r/\d+[lu]*/i, Num::Integer + + rule %r/".*?"/, Str::Double + + rule %r/#{id}(?=\s*[(])/, Name::Function + + rule %r/[()\[\],.;{}]/, Punctuation + + rule id do |m| + caseSensitiveChunk = m[0] + caseInsensitiveChunk = m[0].upcase + + if self.class.builtins.include?(caseSensitiveChunk) + token Keyword::Reserved + elsif self.class.keyword_reserved.include?(caseInsensitiveChunk) + token Keyword::Reserved + elsif self.class.keyword_reserved_unsupported.include?(caseInsensitiveChunk) + token Keyword::Reserved + elsif self.class.keyword_type.include?(caseInsensitiveChunk) + token Keyword::Type + elsif self.class.name_builtin.include?(caseInsensitiveChunk) + token Name::Builtin + elsif self.class.operator_word.include?(caseInsensitiveChunk) + token Operator::Word + else + token Name + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bsl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bsl.rb new file mode 100644 index 0000000..109d81f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/bsl.rb @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Bsl < RegexLexer + title "1C (BSL)" + desc "The 1C:Enterprise programming language" + tag 'bsl' + filenames '*.bsl', '*.os' + + KEYWORDS = /(?<=[^\wа-яё]|^)(?: + КонецПроцедуры | EndProcedure | КонецФункции | EndFunction + | Прервать | Break | Продолжить | Continue + | Возврат | Return | Если | If + | Иначе | Else | ИначеЕсли | ElsIf + | Тогда | Then | КонецЕсли | EndIf + | Попытка | Try | Исключение | Except + | КонецПопытки | EndTry | Raise | ВызватьИсключение + | Пока | While | Для | For + | Каждого | Each | Из | In + | По | To | Цикл | Do + | КонецЦикла | EndDo | НЕ | NOT + | И | AND | ИЛИ | OR + | Новый | New | Процедура | Procedure + | Функция | Function | Перем | Var + | Экспорт | Export | Знач | Val + )(?=[^\wа-яё]|$)/ix + + BUILTINS = /(?<=[^\wа-яё]|^)(?: + СтрДлина|StrLen|СокрЛ|TrimL|СокрП|TrimR|СокрЛП|TrimAll|Лев|Left|Прав|Right|Сред|Mid|СтрНайти|StrFind|ВРег|Upper|НРег|Lower|ТРег|Title|Символ|Char|КодСимвола|CharCode|ПустаяСтрока|IsBlankString|СтрЗаменить|StrReplace|СтрЧислоСтрок|StrLineCount|СтрПолучитьСтроку|StrGetLine|СтрЧислоВхождений|StrOccurrenceCount|СтрСравнить|StrCompare|СтрНачинаетсяС|StrStartWith|СтрЗаканчиваетсяНа|StrEndsWith|СтрРазделить|StrSplit|СтрСоединить|StrConcat + | Цел|Int|Окр|Round|ACos|ACos|ASin|ASin|ATan|ATan|Cos|Cos|Exp|Exp|Log|Log|Log10|Log10|Pow|Pow|Sin|Sin|Sqrt|Sqrt|Tan|Tan + | Год|Year|Месяц|Month|День|Day|Час|Hour|Минута|Minute|Секунда|Second|НачалоГода|BegOfYear|НачалоДня|BegOfDay|НачалоКвартала|BegOfQuarter|НачалоМесяца|BegOfMonth|НачалоМинуты|BegOfMinute|НачалоНедели|BegOfWeek|НачалоЧаса|BegOfHour|КонецГода|EndOfYear|КонецДня|EndOfDay|КонецКвартала|EndOfQuarter|КонецМесяца|EndOfMonth|КонецМинуты|EndOfMinute|КонецНедели|EndOfWeek|КонецЧаса|EndOfHour|НеделяГода|WeekOfYear|ДеньГода|DayOfYear|ДеньНедели|WeekDay|ТекущаяДата|CurrentDate|ДобавитьМесяц|AddMonth + | Тип|Type|ТипЗнч|TypeOf + | Булево|Boolean|Число|Number|Строка|String|Дата|Date + | ПоказатьВопрос|ShowQueryBox|Вопрос|DoQueryBox|ПоказатьПредупреждение|ShowMessageBox|Предупреждение|DoMessageBox|Сообщить|Message|ОчиститьСообщения|ClearMessages|ОповеститьОбИзменении|NotifyChanged|Состояние|Status|Сигнал|Beep|ПоказатьЗначение|ShowValue|ОткрытьЗначение|OpenValue|Оповестить|Notify|ОбработкаПрерыванияПользователя|UserInterruptProcessing|ОткрытьСодержаниеСправки|OpenHelpContent|ОткрытьИндексСправки|OpenHelpIndex|ОткрытьСправку|OpenHelp|ПоказатьИнформациюОбОшибке|ShowErrorInfo|КраткоеПредставлениеОшибки|BriefErrorDescription|ПодробноеПредставлениеОшибки|DetailErrorDescription|ПолучитьФорму|GetForm|ЗакрытьСправку|CloseHelp|ПоказатьОповещениеПользователя|ShowUserNotification|ОткрытьФорму|OpenForm|ОткрытьФормуМодально|OpenFormModal|АктивноеОкно|ActiveWindow|ВыполнитьОбработкуОповещения|ExecuteNotifyProcessing + | ПоказатьВводЗначения|ShowInputValue|ВвестиЗначение|InputValue|ПоказатьВводЧисла|ShowInputNumber|ВвестиЧисло|InputNumber|ПоказатьВводСтроки|ShowInputString|ВвестиСтроку|InputString|ПоказатьВводДаты|ShowInputDate|ВвестиДату|InputDate + | Формат|Format|ЧислоПрописью|NumberInWords|НСтр|NStr|ПредставлениеПериода|PeriodPresentation|СтрШаблон|StrTemplate + | ПолучитьОбщийМакет|GetCommonTemplate|ПолучитьОбщуюФорму|GetCommonForm|ПредопределенноеЗначение|PredefinedValue|ПолучитьПолноеИмяПредопределенногоЗначения|GetPredefinedValueFullName + | ПолучитьЗаголовокСистемы|GetCaption|ПолучитьСкоростьКлиентскогоСоединения|GetClientConnectionSpeed|ПодключитьОбработчикОжидания|AttachIdleHandler|УстановитьЗаголовокСистемы|SetCaption|ОтключитьОбработчикОжидания|DetachIdleHandler|ИмяКомпьютера|ComputerName|ЗавершитьРаботуСистемы|Exit|ИмяПользователя|UserName|ПрекратитьРаботуСистемы|Terminate|ПолноеИмяПользователя|UserFullName|ЗаблокироватьРаботуПользователя|LockApplication|КаталогПрограммы|BinDir|КаталогВременныхФайлов|TempFilesDir|ПравоДоступа|AccessRight|РольДоступна|IsInRole|ТекущийЯзык|CurrentLanguage|ТекущийКодЛокализации|CurrentLocaleCode|СтрокаСоединенияИнформационнойБазы|InfoBaseConnectionString|ПодключитьОбработчикОповещения|AttachNotificationHandler|ОтключитьОбработчикОповещения|DetachNotificationHandler|ПолучитьСообщенияПользователю|GetUserMessages|ПараметрыДоступа|AccessParameters|ПредставлениеПриложения|ApplicationPresentation|ТекущийЯзыкСистемы|CurrentSystemLanguage|ЗапуститьСистему|RunSystem|ТекущийРежимЗапуска|CurrentRunMode|УстановитьЧасовойПоясСеанса|SetSessionTimeZone|ЧасовойПоясСеанса|SessionTimeZone|ТекущаяДатаСеанса|CurrentSessionDate|УстановитьКраткийЗаголовокПриложения|SetShortApplicationCaption|ПолучитьКраткийЗаголовокПриложения|GetShortApplicationCaption|ПредставлениеПрава|RightPresentation|ВыполнитьПроверкуПравДоступа|VerifyAccessRights|РабочийКаталогДанныхПользователя|UserDataWorkDir|КаталогДокументов|DocumentsDir|ПолучитьИнформациюЭкрановКлиента|GetClientDisplaysInformation|ТекущийВариантОсновногоШрифтаКлиентскогоПриложения|ClientApplicationBaseFontCurrentVariant|ТекущийВариантИнтерфейсаКлиентскогоПриложения|ClientApplicationInterfaceCurrentVariant|УстановитьЗаголовокКлиентскогоПриложения|SetClientApplicationCaption|ПолучитьЗаголовокКлиентскогоПриложения|GetClientApplicationCaption|НачатьПолучениеКаталогаВременныхФайлов|BeginGettingTempFilesDir|НачатьПолучениеКаталогаДокументов|BeginGettingDocumentsDir|НачатьПолучениеРабочегоКаталогаДанныхПользователя|BeginGettingUserDataWorkDir|ПодключитьОбработчикЗапросаНастроекКлиентаЛицензирования|AttachLicensingClientParametersRequestHandler|ОтключитьОбработчикЗапросаНастроекКлиентаЛицензирования|DetachLicensingClientParametersRequestHandler + | ЗначениеВСтрокуВнутр|ValueToStringInternal|ЗначениеИзСтрокиВнутр|ValueFromStringInternal|ЗначениеВФайл|ValueToFile|ЗначениеИзФайла|ValueFromFile + | КомандаСистемы|System|ЗапуститьПриложение|RunApp|ПолучитьCOMОбъект|GetCOMObject|ПользователиОС|OSUsers|НачатьЗапускПриложения|BeginRunningApplication + | ПодключитьВнешнююКомпоненту|AttachAddIn|НачатьУстановкуВнешнейКомпоненты|BeginInstallAddIn|УстановитьВнешнююКомпоненту|InstallAddIn|НачатьПодключениеВнешнейКомпоненты|BeginAttachingAddIn + | КопироватьФайл|FileCopy|ПереместитьФайл|MoveFile|УдалитьФайлы|DeleteFiles|НайтиФайлы|FindFiles|СоздатьКаталог|CreateDirectory|ПолучитьИмяВременногоФайла|GetTempFileName|РазделитьФайл|SplitFile|ОбъединитьФайлы|MergeFiles|ПолучитьФайл|GetFile|НачатьПомещениеФайла|BeginPutFile|ПоместитьФайл|PutFile|ЭтоАдресВременногоХранилища|IsTempStorageURL|УдалитьИзВременногоХранилища|DeleteFromTempStorage|ПолучитьИзВременногоХранилища|GetFromTempStorage|ПоместитьВоВременноеХранилище|PutToTempStorage|ПодключитьРасширениеРаботыСФайлами|AttachFileSystemExtension|НачатьУстановкуРасширенияРаботыСФайлами|BeginInstallFileSystemExtension|УстановитьРасширениеРаботыСФайлами|InstallFileSystemExtension|ПолучитьФайлы|GetFiles|ПоместитьФайлы|PutFiles|ЗапроситьРазрешениеПользователя|RequestUserPermission|ПолучитьМаскуВсеФайлы|GetAllFilesMask|ПолучитьМаскуВсеФайлыКлиента|GetClientAllFilesMask|ПолучитьМаскуВсеФайлыСервера|GetServerAllFilesMask|ПолучитьРазделительПути|GetPathSeparator|ПолучитьРазделительПутиКлиента|GetClientPathSeparator|ПолучитьРазделительПутиСервера|GetServerPathSeparator|НачатьПодключениеРасширенияРаботыСФайлами|BeginAttachingFileSystemExtension|НачатьЗапросРазрешенияПользователя|BeginRequestingUserPermission|НачатьПоискФайлов|BeginFindingFiles|НачатьСозданиеКаталога|BeginCreatingDirectory|НачатьКопированиеФайла|BeginCopyingFile|НачатьПеремещениеФайла|BeginMovingFile|НачатьУдалениеФайлов|BeginDeletingFiles|НачатьПолучениеФайлов|BeginGettingFiles|НачатьПомещениеФайлов|BeginPuttingFiles + | НачатьТранзакцию|BeginTransaction|ЗафиксироватьТранзакцию|CommitTransaction|ОтменитьТранзакцию|RollbackTransaction|УстановитьМонопольныйРежим|SetExclusiveMode|МонопольныйРежим|ExclusiveMode|ПолучитьОперативнуюОтметкуВремени|GetRealTimeTimestamp|ПолучитьСоединенияИнформационнойБазы|GetInfoBaseConnections|НомерСоединенияИнформационнойБазы|InfoBaseConnectionNumber|КонфигурацияИзменена|ConfigurationChanged|КонфигурацияБазыДанныхИзмененаДинамически|DataBaseConfigurationChangedDynamically|УстановитьВремяОжиданияБлокировкиДанных|SetLockWaitTime|ОбновитьНумерациюОбъектов|RefreshObjectsNumbering|ПолучитьВремяОжиданияБлокировкиДанных|GetLockWaitTime|КодЛокализацииИнформационнойБазы|InfoBaseLocaleCode|УстановитьМинимальнуюДлинуПаролейПользователей|SetUserPasswordMinLength|ПолучитьМинимальнуюДлинуПаролейПользователей|GetUserPasswordMinLength|ИнициализироватьПредопределенныеДанные|InitializePredefinedData|УдалитьДанныеИнформационнойБазы|EraseInfoBaseData|УстановитьПроверкуСложностиПаролейПользователей|SetUserPasswordStrengthCheck|ПолучитьПроверкуСложностиПаролейПользователей|GetUserPasswordStrengthCheck|ПолучитьСтруктуруХраненияБазыДанных|GetDBStorageStructureInfo|УстановитьПривилегированныйРежим|SetPrivilegedMode|ПривилегированныйРежим|PrivilegedMode|ТранзакцияАктивна|TransactionActive|НеобходимостьЗавершенияСоединения|ConnectionStopRequest|НомерСеансаИнформационнойБазы|InfoBaseSessionNumber|ПолучитьСеансыИнформационнойБазы|GetInfoBaseSessions|ЗаблокироватьДанныеДляРедактирования|LockDataForEdit|УстановитьСоединениеСВнешнимИсточникомДанных|ConnectExternalDataSource|РазблокироватьДанныеДляРедактирования|UnlockDataForEdit|РазорватьСоединениеСВнешнимИсточникомДанных|DisconnectExternalDataSource|ПолучитьБлокировкуСеансов|GetSessionsLock|УстановитьБлокировкуСеансов|SetSessionsLock|ОбновитьПовторноИспользуемыеЗначения|RefreshReusableValues|УстановитьБезопасныйРежим|SetSafeMode|БезопасныйРежим|SafeMode|ПолучитьДанныеВыбора|GetChoiceData|УстановитьЧасовойПоясИнформационнойБазы|SetInfoBaseTimeZone|ПолучитьЧасовойПоясИнформационнойБазы|GetInfoBaseTimeZone|ПолучитьОбновлениеКонфигурацииБазыДанных|GetDataBaseConfigurationUpdate|УстановитьБезопасныйРежимРазделенияДанных|SetDataSeparationSafeMode|БезопасныйРежимРазделенияДанных|DataSeparationSafeMode|УстановитьВремяЗасыпанияПассивногоСеанса|SetPassiveSessionHibernateTime|ПолучитьВремяЗасыпанияПассивногоСеанса|GetPassiveSessionHibernateTime|УстановитьВремяЗавершенияСпящегоСеанса|SetHibernateSessionTerminateTime|ПолучитьВремяЗавершенияСпящегоСеанса|GetHibernateSessionTerminateTime|ПолучитьТекущийСеансИнформационнойБазы|GetCurrentInfoBaseSession|ПолучитьИдентификаторКонфигурации|GetConfigurationID|УстановитьНастройкиКлиентаЛицензирования|SetLicensingClientParameters|ПолучитьИмяКлиентаЛицензирования|GetLicensingClientName|ПолучитьДополнительныйПараметрКлиентаЛицензирования|GetLicensingClientAdditionalParameter + | НайтиПомеченныеНаУдаление|FindMarkedForDeletion|НайтиПоСсылкам|FindByRef|УдалитьОбъекты|DeleteObjects|УстановитьОбновлениеПредопределенныхДанныхИнформационнойБазы|SetInfoBasePredefinedDataUpdate|ПолучитьОбновлениеПредопределенныхДанныхИнформационнойБазы|GetInfoBasePredefinedData + | XMLСтрока|XMLString|XMLЗначение|XMLValue|XMLТип|XMLType|XMLТипЗнч|XMLTypeOf|ИзXMLТипа|FromXMLType|ВозможностьЧтенияXML|CanReadXML|ПолучитьXMLТип|GetXMLType|ПрочитатьXML|ReadXML|ЗаписатьXML|WriteXML|НайтиНедопустимыеСимволыXML|FindDisallowedXMLCharacters|ИмпортМоделиXDTO|ImportXDTOModel|СоздатьФабрикуXDTO|CreateXDTOFactory + | ЗаписатьJSON|WriteJSON|ПрочитатьJSON|ReadJSON|ПрочитатьДатуJSON|ReadJSONDate|ЗаписатьДатуJSON|WriteJSONDate + | ЗаписьЖурналаРегистрации|WriteLogEvent|ПолучитьИспользованиеЖурналаРегистрации|GetEventLogUsing|УстановитьИспользованиеЖурналаРегистрации|SetEventLogUsing|ПредставлениеСобытияЖурналаРегистрации|EventLogEventPresentation|ВыгрузитьЖурналРегистрации|UnloadEventLog|ПолучитьЗначенияОтбораЖурналаРегистрации|GetEventLogFilterValues|УстановитьИспользованиеСобытияЖурналаРегистрации|SetEventLogEventUse|ПолучитьИспользованиеСобытияЖурналаРегистрации|GetEventLogEventUse|СкопироватьЖурналРегистрации|CopyEventLog|ОчиститьЖурналРегистрации|ClearEventLog + | ЗначениеВДанныеФормы|ValueToFormData|ДанныеФормыВЗначение|FormDataToValue|КопироватьДанныеФормы|CopyFormData|УстановитьСоответствиеОбъектаИФормы|SetObjectAndFormConformity|ПолучитьСоответствиеОбъектаИФормы|GetObjectAndFormConformity + | ПолучитьФункциональнуюОпцию|GetFunctionalOption|ПолучитьФункциональнуюОпциюИнтерфейса|GetInterfaceFunctionalOption|УстановитьПараметрыФункциональныхОпцийИнтерфейса|SetInterfaceFunctionalOptionParameters|ПолучитьПараметрыФункциональныхОпцийИнтерфейса|GetInterfaceFunctionalOptionParameters|ОбновитьИнтерфейс|RefreshInterface + | УстановитьРасширениеРаботыСКриптографией|InstallCryptoExtension|НачатьУстановкуРасширенияРаботыСКриптографией|BeginInstallCryptoExtension|ПодключитьРасширениеРаботыСКриптографией|AttachCryptoExtension|НачатьПодключениеРасширенияРаботыСКриптографией|BeginAttachingCryptoExtension + | УстановитьСоставСтандартногоИнтерфейсаOData|SetStandardODataInterfaceContent|ПолучитьСоставСтандартногоИнтерфейсаOData|GetStandardODataInterfaceContent + | Мин|Min|Макс|Max|ОписаниеОшибки|ErrorDescription|Вычислить|Eval|ИнформацияОбОшибке|ErrorInfo|Base64Значение|Base64Value|Base64Строка|Base64String|ЗаполнитьЗначенияСвойств|FillPropertyValues|ЗначениеЗаполнено|ValueIsFilled|ПолучитьПредставленияНавигационныхСсылок|GetURLsPresentations|НайтиОкноПоНавигационнойСсылке|FindWindowByURL|ПолучитьОкна|GetWindows|ПерейтиПоНавигационнойСсылке|GotoURL|ПолучитьНавигационнуюСсылку|GetURL|ПолучитьДопустимыеКодыЛокализации|GetAvailableLocaleCodes|ПолучитьНавигационнуюСсылкуИнформационнойБазы|GetInfoBaseURL|ПредставлениеКодаЛокализации|LocaleCodePresentation|ПолучитьДопустимыеЧасовыеПояса|GetAvailableTimeZones|ПредставлениеЧасовогоПояса|TimeZonePresentation|ТекущаяУниверсальнаяДата|CurrentUniversalDate|ТекущаяУниверсальнаяДатаВМиллисекундах|CurrentUniversalDateInMilliseconds|МестноеВремя|ToLocalTime|УниверсальноеВремя|ToUniversalTime|ЧасовойПояс|TimeZone|СмещениеЛетнегоВремени|DaylightTimeOffset|СмещениеСтандартногоВремени|StandardTimeOffset|КодироватьСтроку|EncodeString|РаскодироватьСтроку|DecodeString|Найти|Find + | ПередНачаломРаботыСистемы|BeforeStart|ПриНачалеРаботыСистемы|OnStart|ПередЗавершениемРаботыСистемы|BeforeExit|ПриЗавершенииРаботыСистемы|OnExit|ОбработкаВнешнегоСобытия|ExternEventProcessing|УстановкаПараметровСеанса|SessionParametersSetting|ПриИзмененииПараметровЭкрана|OnChangeDisplaySettings + | WSСсылки|WSReferences|БиблиотекаКартинок|PictureLib|БиблиотекаМакетовОформленияКомпоновкиДанных|DataCompositionAppearanceTemplateLib|БиблиотекаСтилей|StyleLib|БизнесПроцессы|BusinessProcesses|ВнешниеИсточникиДанных|ExternalDataSources|ВнешниеОбработки|ExternalDataProcessors|ВнешниеОтчеты|ExternalReports|Документы|Documents|ДоставляемыеУведомления|DeliverableNotifications|ЖурналыДокументов|DocumentJournals|Задачи|Tasks|ИспользованиеРабочейДаты|WorkingDateUse|ИсторияРаботыПользователя|UserWorkHistory|Константы|Constants|КритерииОтбора|FilterCriteria|Метаданные|Metadata|Обработки|DataProcessors|ОтправкаДоставляемыхУведомлений|DeliverableNotificationSend|Отчеты|Reports|ПараметрыСеанса|SessionParameters|Перечисления|Enums|ПланыВидовРасчета|ChartsOfCalculationTypes|ПланыВидовХарактеристик|ChartsOfCharacteristicTypes|ПланыОбмена|ExchangePlans|ПланыСчетов|ChartsOfAccounts|ПолнотекстовыйПоиск|FullTextSearch|ПользователиИнформационнойБазы|InfoBaseUsers|Последовательности|Sequences|РасширенияКонфигурации|ConfigurationExtensions|РегистрыБухгалтерии|AccountingRegisters|РегистрыНакопления|AccumulationRegisters|РегистрыРасчета|CalculationRegisters|РегистрыСведений|InformationRegisters|РегламентныеЗадания|ScheduledJobs|СериализаторXDTO|XDTOSerializer|Справочники|Catalogs|СредстваГеопозиционирования|LocationTools|СредстваКриптографии|CryptoToolsManager|СредстваМультимедиа|MultimediaTools|СредстваПочты|MailTools|СредстваТелефонии|TelephonyTools|ФабрикаXDTO|XDTOFactory|ФоновыеЗадания|BackgroundJobs|ХранилищаНастроек + | ГлавныйИнтерфейс|MainInterface|ГлавныйСтиль|MainStyle|ПараметрЗапуска|LaunchParameter|РабочаяДата|WorkingDate|SettingsStorages|ХранилищеВариантовОтчетов|ReportsVariantsStorage|ХранилищеНастроекДанныхФорм|FormDataSettingsStorage|ХранилищеОбщихНастроек|CommonSettingsStorage|ХранилищеПользовательскихНастроекДинамическихСписков|DynamicListsUserSettingsStorage|ХранилищеПользовательскихНастроекОтчетов|ReportsUserSettingsStorage|ХранилищеСистемныхНастроек|SystemSettingsStorage + | Если|If|ИначеЕсли|ElsIf|Иначе|Else|КонецЕсли|EndIf|Тогда|Then + | Неопределено|Undefined|Истина|True|Ложь|False|NULL + )\s*(?=\()/ix + + state :root do + rule %r/\n/, Text + rule %r/[^\S\n]+/, Text + rule %r(//.*$), Comment::Single + rule %r/[\[\]:(),;]/, Punctuation + rule %r/(?<=[^\wа-яё]|^)\&.*$/, Keyword::Declaration + rule %r/[-+\/*%=<>.?&]/, Operator + rule %r/(?<=[^\wа-яё]|^)\#.*$/, Keyword::Declaration + rule KEYWORDS, Keyword + rule BUILTINS, Name::Builtin + rule %r/[\wа-яё][\wа-яё]*/i, Name::Variable + + #literals + rule %r/\b((\h{8}-(\h{4}-){3}\h{12})|\d+\.?\d*)\b/, Literal::Number + rule %r/\'.*\'/, Literal::Date + rule %r/".*?("|$)/, Literal::String::Single + rule %r/(?<=[^\wа-яё]|^)\|((?!\"\").)*?(\"|$)/, Literal::String + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/c.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/c.rb new file mode 100644 index 0000000..ad6624a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/c.rb @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class C < RegexLexer + tag 'c' + filenames '*.c', '*.h', '*.idc' + mimetypes 'text/x-chdr', 'text/x-csrc' + + title "C" + desc "The C programming language" + + # optional comment or whitespace + ws = %r((?:\s|//.*?\n|/[*].*?[*]/)+) + id = /[a-zA-Z_][a-zA-Z0-9_]*/ + + def self.keywords + @keywords ||= Set.new %w( + auto break case const continue default do else enum extern + for goto if register restricted return sizeof static struct + switch typedef union volatile virtual while + + _Alignas _Alignof _Atomic _Generic _Imaginary + _Noreturn _Static_assert _Thread_local + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + int long float short double char unsigned signed void + + jmp_buf FILE DIR div_t ldiv_t mbstate_t sig_atomic_t fpos_t + clock_t time_t va_list size_t ssize_t off_t wchar_t ptrdiff_t + wctrans_t wint_t wctype_t + + _Bool _Complex int8_t int16_t int32_t int64_t + uint8_t uint16_t uint32_t uint64_t int_least8_t + int_least16_t int_least32_t int_least64_t + uint_least8_t uint_least16_t uint_least32_t + uint_least64_t int_fast8_t int_fast16_t int_fast32_t + int_fast64_t uint_fast8_t uint_fast16_t uint_fast32_t + uint_fast64_t intptr_t uintptr_t intmax_t + uintmax_t + + char16_t char32_t + ) + end + + def self.reserved + @reserved ||= Set.new %w( + __asm __int8 __based __except __int16 __stdcall __cdecl + __fastcall __int32 __declspec __finally __int61 __try __leave + inline _inline __inline naked _naked __naked restrict _restrict + __restrict thread _thread __thread typename _typename __typename + ) + end + + def self.builtins + @builtins ||= [] + end + + start { push :bol } + + state :expr_bol do + mixin :inline_whitespace + + rule %r/#if\s0/, Comment, :if_0 + rule %r/#/, Comment::Preproc, :macro + + rule(//) { pop! } + end + + # :expr_bol is the same as :bol but without labels, since + # labels can only appear at the beginning of a statement. + state :bol do + rule %r/#{id}:(?!:)/, Name::Label + mixin :expr_bol + end + + state :inline_whitespace do + rule %r/[ \t\r]+/, Text + rule %r/\\\n/, Text # line continuation + rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline + end + + state :whitespace do + rule %r/\n+/m, Text, :bol + rule %r(//(\\.|.)*?$), Comment::Single, :bol + mixin :inline_whitespace + end + + state :expr_whitespace do + rule %r/\n+/m, Text, :expr_bol + mixin :whitespace + end + + state :statements do + mixin :whitespace + rule %r/(u8|u|U|L)?"/, Str, :string + rule %r((u8|u|U|L)?'(\\.|\\[0-7]{1,3}|\\x[a-f0-9]{1,2}|[^\\'\n])')i, Str::Char + rule %r((\d+[.]\d*|[.]?\d+)e[+-]?\d+[lu]*)i, Num::Float + rule %r(\d+e[+-]?\d+[lu]*)i, Num::Float + rule %r/0x[0-9a-f]+[lu]*/i, Num::Hex + rule %r/0[0-7]+[lu]*/i, Num::Oct + rule %r/\d+[lu]*/i, Num::Integer + rule %r(\*/), Error + rule %r([~!%^&*+=\|?:<>/-]), Operator + rule %r/[()\[\],.;]/, Punctuation + rule %r/\bcase\b/, Keyword, :case + rule %r/(?:true|false|NULL)\b/, Name::Builtin + rule id do |m| + name = m[0] + + if self.class.keywords.include? name + token Keyword + elsif self.class.keywords_type.include? name + token Keyword::Type + elsif self.class.reserved.include? name + token Keyword::Reserved + elsif self.class.builtins.include? name + token Name::Builtin + else + token Name + end + end + end + + state :case do + rule %r/:/, Punctuation, :pop! + mixin :statements + end + + state :root do + mixin :expr_whitespace + rule %r( + ([\w*\s]+?[\s*]) # return arguments + (#{id}) # function name + (\s*\([^;]*?\)) # signature + (#{ws}?)({|;) # open brace or semicolon + )mx do |m| + # TODO: do this better. + recurse m[1] + token Name::Function, m[2] + recurse m[3] + recurse m[4] + token Punctuation, m[5] + if m[5] == ?{ + push :function + end + end + rule %r/\{/, Punctuation, :function + mixin :statements + end + + state :function do + mixin :whitespace + mixin :statements + rule %r/;/, Punctuation + rule %r/{/, Punctuation, :function + rule %r/}/, Punctuation, :pop! + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\([\\abfnrtv"']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})/, Str::Escape + rule %r/[^\\"\n]+/, Str + rule %r/\\\n/, Str + rule %r/\\/, Str # stray backslash + end + + state :macro do + mixin :include + rule %r([^/\n\\]+), Comment::Preproc + rule %r/\\./m, Comment::Preproc + mixin :inline_whitespace + rule %r(/), Comment::Preproc + # NB: pop! goes back to :bol + rule %r/\n/, Comment::Preproc, :pop! + end + + state :include do + rule %r/(include)(\s*)(<[^>]+>)([^\n]*)/ do + groups Comment::Preproc, Text, Comment::PreprocFile, Comment::Single + end + rule %r/(include)(\s*)("[^"]+")([^\n]*)/ do + groups Comment::Preproc, Text, Comment::PreprocFile, Comment::Single + end + end + + state :if_0 do + # NB: no \b here, to cover #ifdef and #ifndef + rule %r/^\s*#if/, Comment, :if_0 + rule %r/^\s*#\s*el(?:se|if)/, Comment, :pop! + rule %r/^\s*#\s*endif\b.*?(?|+=:;,./?`-]), Operator + rule %r(\d{1,3}(_\d{3})+\.\d{1,3}(_\d{3})+[kMGTPmunpf]?), Literal::Number::Float + rule %r(\d{1,3}(_\d{3})+\.[0-9]+([eE][+-]?[0-9]+)?[kMGTPmunpf]?), + Literal::Number::Float + rule %r([0-9][0-9]*\.\d{1,3}(_\d{3})+[kMGTPmunpf]?), Literal::Number::Float + rule %r([0-9][0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[kMGTPmunpf]?), + Literal::Number::Float + rule %r(#([0-9a-fA-F]{4})(_[0-9a-fA-F]{4})+), Literal::Number::Hex + rule %r(#[0-9a-fA-F]+), Literal::Number::Hex + rule %r(\$([01]{4})(_[01]{4})+), Literal::Number::Bin + rule %r(\$[01]+), Literal::Number::Bin + rule %r(\d{1,3}(_\d{3})+[kMGTP]?), Literal::Number::Integer + rule %r([0-9]+[kMGTP]?), Literal::Number::Integer + rule %r(\n), Text + + end + + state :class do + mixin :whitespace + rule %r([A-Za-z_]\w*), Name::Class, :pop! + end + + state :import do + rule %r([a-z][\w.]*), Name::Namespace, :pop! + rule %r("(\\\\|\\"|[^"])*"), Literal::String, :pop! + end + + state :comment do + rule %r([^*/]), Comment.Multiline + rule %r(/\*), Comment::Multiline, :push! + rule %r(\*/), Comment::Multiline, :pop! + rule %r([*/]), Comment::Multiline + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cfscript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cfscript.rb new file mode 100644 index 0000000..6b083ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cfscript.rb @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + + class Cfscript < RegexLexer + title "CFScript" + desc 'CFScript, the CFML scripting language' + tag 'cfscript' + aliases 'cfc' + filenames '*.cfc' + + def self.keywords + @keywords ||= %w( + if else var xml default break switch do try catch throw in continue for return while required + ) + end + + def self.declarations + @declarations ||= %w( + component property function remote public package private + ) + end + + def self.types + @types ||= %w( + any array binary boolean component date guid numeric query string struct uuid void xml + ) + end + + constants = %w(application session client cookie super this variables arguments cgi) + + + operators = %w(\+\+ -- && \|\| <= >= < > == != mod eq lt gt lte gte not is and or xor eqv imp equal contains \? ) + dotted_id = /[$a-zA-Z_][a-zA-Z0-9_.]*/ + + state :root do + mixin :comments_and_whitespace + rule %r/(?:#{operators.join('|')}|does not contain|greater than(?: or equal to)?|less than(?: or equal to)?)\b/i, Operator, :expr_start + rule %r([-<>+*%&|\^/!=]=?), Operator, :expr_start + + rule %r/[(\[,]/, Punctuation, :expr_start + rule %r/;/, Punctuation, :statement + rule %r/[)\].]/, Punctuation + + rule %r/[?]/ do + token Punctuation + push :ternary + push :expr_start + end + + rule %r/[{}]/, Punctuation, :statement + + rule %r/(?:#{constants.join('|')})\b/, Name::Constant + rule %r/(?:true|false|null)\b/, Keyword::Constant + rule %r/import\b/, Keyword::Namespace, :import + rule %r/(#{dotted_id})(\s*)(:)(\s*)/ do + groups Name, Text, Punctuation, Text + push :expr_start + end + + rule %r/([A-Za-z_$][\w.]*)(\s*)(\()/ do |m| + if self.class.keywords.include? m[1] + token Keyword, m[1] + token Text, m[2] + token Punctuation, m[3] + else + token Name::Function, m[1] + token Text, m[2] + token Punctuation, m[3] + end + end + + rule dotted_id do |m| + if self.class.declarations.include? m[0] + token Keyword::Declaration + push :expr_start + elsif self.class.keywords.include? m[0] + token Keyword + push :expr_start + elsif self.class.types.include? m[0] + token Keyword::Type + push :expr_start + else + token Name::Other + end + end + + rule %r/[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, Num::Float + rule %r/0x[0-9a-fA-F]+/, Num::Hex + rule %r/[0-9]+/, Num::Integer + rule %r/"(\\\\|\\"|[^"])*"/, Str::Double + rule %r/'(\\\\|\\'|[^'])*'/, Str::Single + + end + + # same as java, broken out + state :comments_and_whitespace do + rule %r/\s+/, Text + rule %r(//.*?$), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + end + + state :expr_start do + mixin :comments_and_whitespace + + rule %r/[{]/, Punctuation, :object + + rule %r//, Text, :pop! + end + + state :statement do + + rule %r/[{}]/, Punctuation + + mixin :expr_start + end + + # object literals + state :object do + mixin :comments_and_whitespace + rule %r/[}]/ do + token Punctuation + push :expr_start + end + + rule %r/(#{dotted_id})(\s*)(:)/ do + groups Name::Other, Text, Punctuation + push :expr_start + end + + rule %r/:/, Punctuation + mixin :root + end + + # ternary expressions, where : is not a label! + state :ternary do + rule %r/:/ do + token Punctuation + goto :expr_start + end + + mixin :root + end + + state :import do + rule %r/\s+/m, Text + rule %r/[a-z0-9_.]+\*?/i, Name::Namespace, :pop! + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cisco_ios.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cisco_ios.rb new file mode 100644 index 0000000..685c2ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cisco_ios.rb @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# Based on/regexes mostly from Brandon Bennett's pygments-routerlexers: +# https://github.com/nemith/pygments-routerlexers + +module Rouge + module Lexers + class CiscoIos < RegexLexer + title 'Cisco IOS' + desc 'Cisco IOS configuration lexer' + tag 'cisco_ios' + filenames '*.cfg' + mimetypes 'text/x-cisco-conf' + + state :root do + rule %r/^!.*/, Comment::Single + + rule %r/^(version\s+)(.*)$/ do + groups Keyword, Num::Float + end + + rule %r/(desc*r*i*p*t*i*o*n*)(.*?)$/ do + groups Keyword, Comment::Single + end + + rule %r/^(inte*r*f*a*c*e*|controller|router \S+|voice translation-\S+|voice-port|line)(.*)$/ do + groups Keyword::Type, Name::Function + end + + rule %r/(password|secret)(\s+[57]\s+)(\S+)/ do + groups Keyword, Num, String::Double + end + + rule %r/(permit|deny)/, Operator::Word + + rule %r/^(banner\s+)(motd\s+|login\s+)([#$%])/ do + groups Keyword, Name::Function, Str::Delimiter + push :cisco_ios_text + end + + rule %r/^(dial-peer\s+\S+\s+)(\S+)(.*?)$/ do + groups Keyword, Name::Attribute, Keyword + end + + rule %r/^(vlan\s+)(\d+)$/ do + groups Keyword, Name::Attribute + end + + # IPv4 Address/Prefix + rule %r/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\/\d{1,2})?/, Num + + # NSAP + rule %r/49\.\d{4}\.\d{4}\.\d{4}\.\d{4}\.\d{2}/, Num + + # MAC Address + rule %r/[a-f0-9]{4}\.[a-f0-9]{4}\.[a-f0-9]{4}/, Num::Hex + + rule %r/^(\s*no\s+)(\S+)/ do + groups Keyword::Constant, Keyword + end + + rule %r/^[^\n\r]\s*\S+/, Keyword + + # Obfuscated Passwords + rule %r/\*+/, Name::Entity + + rule %r/(?<= )\d+(?= )/, Num + + # Newline catcher, avoid errors on empty lines + rule %r/\n+/m, Text + + # This one goes last, a text catch-all + rule %r/./, Text + end + + state :cisco_ios_text do + rule %r/[^#$%]/, Text + rule %r/[#$%]/, Str::Delimiter, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clean.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clean.rb new file mode 100644 index 0000000..031cd61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clean.rb @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Clean < RegexLexer + title "Clean" + desc "The Clean programming language (clean.cs.ru.nl)" + + tag 'clean' + filenames '*.dcl', '*.icl' + + def self.keywords + @keywords ||= Set.new %w( + if otherwise + let in + with where + case of + infix infixl infixr + class instance + generic derive + special + implementation definition system module + from import qualified as + dynamic + code inline foreign export ccall stdcall + ) + end + + # These are literal patterns common to the ABC intermediate language and + # Clean. Clean has more extensive literal patterns (see :basic below). + state :common_literals do + rule %r/'(?:[^'\\]|\\(?:x[0-9a-fA-F]+|\d+|.))'/, Str::Char + + rule %r/[+~-]?\d+\.\d+(?:E[+-]?\d+)?\b/, Num::Float + rule %r/[+~-]?\d+E[+-]?\d+\b/, Num::Float + rule %r/[+~-]?\d+/, Num::Integer + + rule %r/"/, Str::Double, :string + end + + state :basic do + rule %r/\s+/m, Text::Whitespace + + rule %r/\/\/\*.*/, Comment::Doc + rule %r/\/\/.*/, Comment::Single + rule %r/\/\*\*/, Comment::Doc, :comment_doc + rule %r/\/\*/, Comment::Multiline, :comment + + rule %r/[+~-]?0[0-7]+/, Num::Oct + rule %r/[+~-]?0x[0-9a-fA-F]+/, Num::Hex + mixin :common_literals + rule %r/(\[)(\s*)(')(?=.*?'\])/ do + groups Punctuation, Text::Whitespace, Str::Single, Punctuation + push :charlist + end + end + + # nested commenting + state :comment_doc do + rule %r/\*\//, Comment::Doc, :pop! + rule %r/\/\/.*/, Comment::Doc # Singleline comments in multiline comments are skipped + rule %r/\/\*/, Comment::Doc, :comment + rule %r/[^*\/]+/, Comment::Doc + rule %r/[*\/]/, Comment::Doc + end + + # This is the same as the above, but with Multiline instead of Doc + state :comment do + rule %r/\*\//, Comment::Multiline, :pop! + rule %r/\/\/.*/, Comment::Multiline # Singleline comments in multiline comments are skipped + rule %r/\/\*/, Comment::Multiline, :comment + rule %r/[^*\/]+/, Comment::Multiline + rule %r/[*\/]/, Comment::Multiline + end + + state :root do + mixin :basic + + rule %r/code(\s+inline)?\s*{/, Comment::Preproc, :abc + + rule %r/_*[a-z][\w`]*/ do |m| + if self.class.keywords.include?(m[0]) + token Keyword + else + token Name + end + end + + rule %r/_*[A-Z][\w`]*/ do |m| + if m[0]=='True' || m[0]=='False' + token Keyword::Constant + else + token Keyword::Type + end + end + + rule %r/[^\w\s`]/, Punctuation + rule %r/_\b/, Punctuation + end + + state :escapes do + rule %r/\\x[0-9a-fA-F]{1,2}/i, Str::Escape + rule %r/\\d\d{0,3}/i, Str::Escape + rule %r/\\0[0-7]{0,3}/, Str::Escape + rule %r/\\[0-7]{1,3}/, Str::Escape + rule %r/\\[nrfbtv\\"']/, Str::Escape + end + + state :string do + rule %r/"/, Str::Double, :pop! + mixin :escapes + rule %r/[^\\"]+/, Str::Double + end + + state :charlist do + rule %r/(')(\])/ do + groups Str::Single, Punctuation + pop! + end + mixin :escapes + rule %r/[^\\']/, Str::Single + end + + state :abc_basic do + rule %r/\s+/, Text::Whitespace + rule %r/\|.*/, Comment::Single + mixin :common_literals + end + + # The ABC intermediate language can be included, similar to C's inline + # assembly. For some information about ABC, see: + # https://en.wikipedia.org/wiki/Clean_(programming_language)#The_ABC-Machine + state :abc do + mixin :abc_basic + + rule %r/}/, Comment::Preproc, :pop! + rule %r/\.\w*/, Keyword, :abc_rest_of_line + rule %r/[\w]+/, Name::Builtin, :abc_rest_of_line + end + + state :abc_rest_of_line do + rule %r/\n/, Text::Whitespace, :pop! + rule %r/}/ do + token Comment::Preproc + pop! + pop! + end + + mixin :abc_basic + + rule %r/\S+/, Name + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clojure.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clojure.rb new file mode 100644 index 0000000..06b34e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clojure.rb @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Clojure < RegexLexer + title "Clojure" + desc "The Clojure programming language (clojure.org)" + + tag 'clojure' + aliases 'clj', 'cljs' + + filenames '*.clj', '*.cljs', '*.cljc', 'build.boot', '*.edn' + + mimetypes 'text/x-clojure', 'application/x-clojure' + + def self.keywords + @keywords ||= Set.new %w( + fn def defn defmacro defmethod defmulti defn- defstruct if + cond let for + ) + end + + def self.builtins + @builtins ||= Set.new %w( + . .. * + - -> / < <= = == > >= accessor agent agent-errors + aget alength all-ns alter and append-child apply array-map + aset aset-boolean aset-byte aset-char aset-double aset-float + aset-int aset-long aset-short assert assoc await await-for bean + binding bit-and bit-not bit-or bit-shift-left bit-shift-right + bit-xor boolean branch? butlast byte cast char children + class clear-agent-errors comment commute comp comparator + complement concat conj cons constantly construct-proxy + contains? count create-ns create-struct cycle dec deref + difference disj dissoc distinct doall doc dorun doseq dosync + dotimes doto double down drop drop-while edit end? ensure eval + every? false? ffirst file-seq filter find find-doc find-ns + find-var first float flush fnseq frest gensym get-proxy-class + get hash-map hash-set identical? identity if-let import in-ns + inc index insert-child insert-left insert-right inspect-table + inspect-tree instance? int interleave intersection into + into-array iterate join key keys keyword keyword? last lazy-cat + lazy-cons left lefts line-seq list* list load load-file locking + long loop macroexpand macroexpand-1 make-array make-node map + map-invert map? mapcat max max-key memfn merge merge-with meta + min min-key name namespace neg? new newline next nil? node not + not-any? not-every? not= ns-imports ns-interns ns-map ns-name + ns-publics ns-refers ns-resolve ns-unmap nth nthrest or parse + partial path peek pop pos? pr pr-str print print-str println + println-str prn prn-str project proxy proxy-mappings quot + rand rand-int range re-find re-groups re-matcher re-matches + re-pattern re-seq read read-line reduce ref ref-set refer rem + remove remove-method remove-ns rename rename-keys repeat replace + replicate resolve rest resultset-seq reverse rfirst right + rights root rrest rseq second select select-keys send send-off + seq seq-zip seq? set short slurp some sort sort-by sorted-map + sorted-map-by sorted-set special-symbol? split-at split-with + str string? struct struct-map subs subvec symbol symbol? + sync take take-nth take-while test time to-array to-array-2d + tree-seq true? union up update-proxy val vals var-get var-set + var? vector vector-zip vector? when when-first when-let + when-not with-local-vars with-meta with-open with-out-str + xml-seq xml-zip zero? zipmap zipper' + ) + end + + identifier = %r([\w!$%*+,<=>?/.-]+) + keyword = %r([\w!\#$%*+,<=>?/.-]+) + + def name_token(name) + return Keyword if self.class.keywords.include?(name) + return Name::Builtin if self.class.builtins.include?(name) + nil + end + + state :root do + rule %r/;.*?$/, Comment::Single + rule %r/\s+/m, Text::Whitespace + + rule %r/-?\d+\.\d+/, Num::Float + rule %r/-?\d+/, Num::Integer + rule %r/0x-?[0-9a-fA-F]+/, Num::Hex + + rule %r/"(\\.|[^"])*"/, Str + rule %r/'#{keyword}/, Str::Symbol + rule %r/::?#{keyword}/, Name::Constant + rule %r/\\(.|[a-z]+)/i, Str::Char + + + rule %r/~@|[`\'#^~&@]/, Operator + + rule %r/(\()(\s*)(#{identifier})/m do |m| + token Punctuation, m[1] + token Text::Whitespace, m[2] + token(name_token(m[3]) || Name::Function, m[3]) + end + + rule identifier do |m| + token name_token(m[0]) || Name + end + + # vectors + rule %r/[\[\]]/, Punctuation + + # maps + rule %r/[{}]/, Punctuation + + # parentheses + rule %r/[()]/, Punctuation + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmake.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmake.rb new file mode 100644 index 0000000..a22169c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmake.rb @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class CMake < RegexLexer + title 'CMake' + desc 'The cross-platform, open-source build system' + tag 'cmake' + filenames 'CMakeLists.txt', '*.cmake' + mimetypes 'text/x-cmake' + + SPACE = '[ \t]' + BRACKET_OPEN = '\[=*\[' + + STATES_MAP = { + :root => Text, + :bracket_string => Str::Double, + :quoted_argument => Str::Double, + :bracket_comment => Comment::Multiline, + :variable_reference => Name::Variable, + } + + BUILTIN_COMMANDS = Set.new %w[ + add_compile_definitions + add_compile_options + add_custom_command + add_custom_target + add_definitions + add_dependencies + add_executable + add_library + add_link_options + add_subdirectory + add_test + aux_source_directory + break + build_command + build_name + cmake_host_system_information + cmake_language + cmake_minimum_required + cmake_parse_arguments + cmake_policy + configure_file + create_test_sourcelist + define_property + else + elseif + enable_language + enable_testing + endforeach + endfunction + endif + endmacro + endwhile + exec_program + execute_process + export + export_library_dependencies + file + find_file + find_library + find_package + find_path + find_program + fltk_wrap_ui + foreach + function + get_cmake_property + get_directory_property + get_filename_component + get_property + get_source_file_property + get_target_property + get_test_property + if + include + include_directories + include_external_msproject + include_guard + include_regular_expression + install + install_files + install_programs + install_targets + link_directories + link_libraries + list + load_cache + load_command + macro + make_directory + mark_as_advanced + math + message + option + output_required_files + project + qt_wrap_cpp + qt_wrap_ui + remove + remove_definitions + return + separate_arguments + set + set_directory_properties + set_property + set_source_files_properties + set_target_properties + set_tests_properties + site_name + source_group + string + subdir_depends + subdirs + target_compile_definitions + target_compile_features + target_compile_options + target_include_directories + target_link_directories + target_link_libraries + target_link_options + target_precompile_headers + target_sources + try_compile + try_run + unset + use_mangled_mesa + utility_source + variable_requires + variable_watch + while + write_file + ] + + state :default do + rule %r/\r\n?|\n/ do + token STATES_MAP[state.name.to_sym] + end + rule %r/./ do + token STATES_MAP[state.name.to_sym] + end + end + + state :variable_interpolation do + rule %r/\$\{/ do + token Str::Interpol + push :variable_reference + end + end + + state :bracket_close do + rule %r/\]=*\]/ do |m| + token STATES_MAP[state.name.to_sym] + goto :root if m[0].length == @bracket_len + end + end + + state :root do + mixin :variable_interpolation + + rule %r/#{SPACE}/, Text + rule %r/[()]/, Punctuation + + rule %r/##{BRACKET_OPEN}/ do |m| + token Comment::Multiline + @bracket_len = m[0].length - 1 # decount '#' + goto :bracket_comment + end + rule %r/#{BRACKET_OPEN}/ do |m| + token Str::Double + @bracket_len = m[0].length + goto :bracket_string + end + + rule %r/\\"/, Text + rule %r/"/, Str::Double, :quoted_argument + + rule %r/([A-Za-z_][A-Za-z0-9_]*)(#{SPACE}*)(\()/ do |m| + groups BUILTIN_COMMANDS.include?(m[1]) ? Name::Builtin : Name::Function, Text, Punctuation + end + + rule %r/#.*/, Comment::Single + + mixin :default + end + + state :bracket_string do + mixin :bracket_close + mixin :variable_interpolation + mixin :default + end + + state :bracket_comment do + mixin :bracket_close + mixin :default + end + + state :variable_reference do + mixin :variable_interpolation + + rule %r/}/, Str::Interpol, :pop! + + mixin :default + end + + state :quoted_argument do + mixin :variable_interpolation + + rule %r/"/, Str::Double, :root + rule %r/\\[()#" \\$@^trn;]/, Str::Escape + + mixin :default + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmhg.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmhg.rb new file mode 100644 index 0000000..338a3fa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cmhg.rb @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class CMHG < RegexLexer + title "CMHG" + desc "RISC OS C module header generator source file" + tag 'cmhg' + filenames '*.cmhg' + + def self.preproc_keyword + @preproc_keyword ||= %w( + define elif else endif error if ifdef ifndef include line pragma undef warning + ) + end + + state :root do + rule %r/;[^\n]*/, Comment + rule %r/^([ \t]*)(#[ \t]*(?:(?:#{CMHG.preproc_keyword.join('|')})(?:[ \t].*)?)?)(?=\n)/ do + groups Text, Comment::Preproc + end + rule %r/[-a-z]+:/, Keyword::Declaration + rule %r/[a-z_]\w+/i, Name::Entity + rule %r/"[^"]*"/, Literal::String + rule %r/(?:&|0x)\h+/, Literal::Number::Hex + rule %r/\d+/, Literal::Number + rule %r/[,\/()]/, Punctuation + rule %r/[ \t]+/, Text + rule %r/\n+/, Text + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cobol.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cobol.rb new file mode 100644 index 0000000..cceb046 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/cobol.rb @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class COBOL < RegexLexer + title 'COBOL' + desc 'COBOL (Common Business-Oriented Language) programming language' + tag 'cobol' + filenames '*.cob', '*.cbl', '*.cpy', '*.cpb' + mimetypes 'text/x-cobol' + + identifier = /\p{Alpha}[\p{Alnum}-]*/ + + def self.divisions + @divisions ||= %w( + IDENTIFICATION ENVIRONMENT DATA PROCEDURE DIVISION + ) + end + + def self.sections + @sections ||= %w( + CONFIGURATION INPUT-OUTPUT FILE WORKING-STORAGE LOCAL-STORAGE LINKAGE SECTION + ) + end + + # List of COBOL keywords + # sourced from https://www.ibm.com/docs/en/cobol-zos/6.4?topic=appendixes-reserved-words + def self.keywords + @keywords ||= Set.new(%w( + ACCEPT ACCESS ACTIVE-CLASS ADD ADDRESS ADVANCING AFTER ALIGNED ALL ALLOCATE ALPHABET ALPHABETIC ALPHABETIC-LOWER + ALPHABETIC-UPPER ALPHANUMERIC ALPHANUMERIC-EDITED ALSO ALTER ALTERNATE AND ANYCASE ANY APPLY ARE AREA AREAS + ASCENDING ASSIGN AT AUTHOR B-AND B-NOT B-OR B-XOR BASED BASIS BEFORE BEGINNING BINARY BINARY-CHAR BINARY-DOUBLE + BINARY-LONG BINARY-SHORT BIT BLANK BLOCK BOOLEAN BOTTOM BY BYTE-LENGTH CALL CANCEL CBL CD CF CH CHARACTER + CHARACTERS CLASS CLASS-ID CLOCK-UNITS CLOSE COBOL CODE CODE-SET COL COLLATING COLS COLUMN COLUMNS COM-REG COMMA + COMMON COMMUNICATION COMP-1 COMP-2 COMP-3 COMP-4 COMP-5 COMP COMPUTATIONAL-1 COMPUTATIONAL-2 + COMPUTATIONAL-3 COMPUTATIONAL-4 COMPUTATIONAL-5 COMPUTATIONAL COMPUTE CONDITION CONSTANT CONTAINS CONTENT + CONTINUE CONTROL CONTROLS CONVERTING COPY CORR CORRESPONDING COUNT CRT CURRENCY CURSOR DATA-POINTER DATE + DATE-COMPILED DATE-WRITTEN DAY DAY-OF-WEEK DBCS DE DEBUG-CONTENTS DEBUG-ITEM DEBUG-LINE DEBUG-NAME DEBUG-SUB-1 + DEBUG-SUB-2 DEBUG-SUB-3 DEBUGGING DECIMAL-POINT DECLARATIVES DEFAULT DELETE DELIMITED DELIMITER DEPENDING + DESCENDING DESTINATION DETAIL DISABLE DISPLAY-1 DISPLAY DIVIDE DOWN DUPLICATES DYNAMIC EC EGCS EGI + EJECT ELSE EMI ENABLE END-ACCEPT END-ADD END-CALL END-COMPUTE END-DELETE END-DISPLAY END-DIVIDE END-EVALUATE + END-EXEC END-IF END-INVOKE END-JSON END-MULTIPLY END-OF-PAGE END-PERFORM END-READ END-RECEIVE END-RETURN + END-REWRITE END-SEARCH END-START END-STRING END-SUBTRACT END-UNSTRING END-WRITE END-XML ENDING END ENTER ENTRY + EO EOP EQUAL ERROR ESI EVALUATE EVERY EXCEPTION EXCEPTION-OBJECT EXEC EXECUTE EXIT EXTEND EXTERNAL + FACTORY FALSE FD FILE-CONTROL FILLER FINAL FIRST FLOAT-EXTENDED FLOAT-LONG FLOAT-SHORT FOOTING FOR FORMAT + FREE FROM FUNCTION FUNCTION-ID FUNCTION-POINTER GENERATE GET GIVING GLOBAL GO GOBACK GREATER GROUP GROUP-USAGE + HEADING HIGH-VALUE HIGH-VALUES I-O-CONTROL I-O ID IF IN INDEX INDEXED INDICATE INHERITS INITIAL + INITIALIZE INITIATE INPUT INSERT INSPECT INSTALLATION INTERFACE INTERFACE-ID INTO INVALID INVOKE + IS JAVA JNIENVPTR JSON JSON-CODE JSON-STATUS JUST JUSTIFIED KANJI KEY LABEL LAST LEADING LEFT LENGTH LESS LIMIT + LIMITS LINAGE-COUNTER LINAGE LINE-COUNTER LINES LINE LOCALE LOCK LOW-VALUE LOW-VALUES + MEMORY MERGE MESSAGE METHOD METHOD-ID MINUS MODE MODULES MORE-LABELS MOVE MULTIPLE MULTIPLY NATIONAL + NATIONAL-EDITED NATIVE NEGATIVE NESTED NEXT NO NOT NULL NULLS NUMBER NUMERIC NUMERIC-EDITED OBJECT + OBJECT-COMPUTER OBJECT-REFERENCE OCCURS OF OFF OMITTED ON OPEN OPTIONAL OPTIONS OR ORDER ORGANIZATION + OTHER OUTPUT OVERFLOW OVERRIDE PACKED-DECIMAL PADDING PAGE PAGE-COUNTER PASSWORD PERFORM PF PH PIC PICTURE + PLUS POINTER- POINTER-31 POINTER-32 POINTER-64 POINTER POSITION POSITIVE PRESENT PRINTING + PROCEDURE-POINTER PROCEDURES PROCEED PROCESSING PROGRAM-ID PROGRAM-POINTER PROGRAM PROPERTY PROTOTYPE + PURGE QUEUE QUOTE QUOTES RAISE RAISING RANDOM RD READ READY RECEIVE RECORD RECORDING RECORDS RECURSIVE REDEFINES + REEL REFERENCE REFERENCES RELATIVE RELEASE RELOAD REMAINDER REMOVAL RENAMES REPLACE REPLACING REPORT REPORTING + REPORTS REPOSITORY RERUN RESERVE RESET RESUME RETRY RETURN RETURN-CODE RETURNING REVERSED REWIND REWRITE RF RH + RIGHT ROUNDED RUN SAME SCREEN SD SEARCH SECTION SECURITY SEGMENT SEGMENT-LIMIT SELECT SELF SEND SENTENCE + SEPARATE SEQUENCE SEQUENTIAL SERVICE SET SHARING SHIFT-IN SHIFT-OUT SIGN SIZE SKIP1 SKIP2 SKIP3 + SORT-CONTROL SORT-CORE-SIZE SORT-FILE-SIZE SORT-MERGE SORT-MESSAGE SORT-MODE-SIZE SORT-RETURN SORT + SOURCE-COMPUTER SOURCES SOURCE SPACE SPACES SPECIAL-NAMES SQL SQLIMS STANDARD-1 STANDARD-2 STANDARD START STATUS STOP + STRING SUB-QUEUE-1 SUB-QUEUE-2 SUB-QUEUE-3 SUBTRACT SUM SUPER SUPPRESS SYMBOLIC SYNC SYNCHRONIZED SYSTEM-DEFAULT + TABLE TALLY TALLYING TAPE TERMINAL TERMINATE TEST TEXT THAN THEN THROUGH THRU TIME TIMES TITLE TO TOP TRACE + TRAILING TRUE TYPE TYPEDEF UNIT UNIVERSAL UNLOCK UNSTRING UNTIL UP UPON USAGE USE USER-DEFAULT USING UTF-8 + VAL-STATUS VALID VALIDATE VALIDATE-STATUS VALUE VALUES VARYING VOLATILE WHEN WHEN-COMPILED WITH WORDS + WRITE WRITE-ONLY XML-CODE XML-EVENT XML-INFORMATION XML-NAMESPACE XML-NAMESPACE-PREFIX + XML-NNAMESPACE XML-NNAMESPACE-PREFIX XML-NTEXT XML-SCHEMA XML-TEXT XML ZERO ZEROES ZEROS + )) + end + + state :root do + # First detect the comments + rule %r/^( \*).*|^(^Debug \*).*/, Comment::Special + + # Strings + rule %r/"/, Str::Double, :string_double + rule %r/'/, Str::Single, :string_single + + # Keywords and divisions + rule %r/(?.*/, Comment::Single + + # Operators + rule %r/[+\-*\/><=]/, Operator + + # Whitespace remaining + rule %r/\s/, Text::Whitespace + + # Anything else remaining + rule %r/.+/, Text + end + + # TODO double check string escaping in COBOL + # TODO Fix that a string opened by " can't be closed by ' + # TODO Fix that strings can't be multi-line + + # Handle strings where " opens a string and must be closed by " + state :string_double do + # Ensure strings can't span multiple lines + rule %r/[^"\\\n]+/, Str + rule %r/\\./, Str::Escape + rule %r/"/, Str::Double, :pop! + rule %r/\n/, Error # Flag an error if a string goes to the next line + end + + # Handle strings where ' opens a string and must be closed by ' + state :string_single do + # Ensure strings can't span multiple lines + rule %r/[^'\\\n]+/, Str + rule %r/\\./, Str::Escape + rule %r/'/, Str::Single, :pop! + rule %r/\n/, Error # Flag an error if a string goes to the next line + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/codeowners.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/codeowners.rb new file mode 100644 index 0000000..7f07911 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/codeowners.rb @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Codeowners < RegexLexer + title 'CODEOWNERS' + desc 'Code Owners syntax (https://docs.gitlab.com/ee/user/project/codeowners/reference.html)' + tag 'codeowners' + filenames 'CODEOWNERS' + + state :root do + rule %r/[ \t\r\n]+/, Text::Whitespace + rule %r/^\s*#.*$/, Comment::Single + + rule %r( + (\^?\[(?!\d+\])[^\]]+\]) + (\[\d+\])? + )x do + groups Name::Namespace, Literal::Number + end + + rule %r/\S*@\S+/, Name::Function + + rule %r/[\p{Word}\.\/\-\*]+/, Name + rule %r/.*\\[\#\s]/, Name + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/coffeescript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/coffeescript.rb new file mode 100644 index 0000000..032943b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/coffeescript.rb @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Coffeescript < RegexLexer + tag 'coffeescript' + aliases 'coffee', 'coffee-script' + filenames '*.coffee', 'Cakefile' + mimetypes 'text/coffeescript' + + title "CoffeeScript" + desc 'The Coffeescript programming language (coffeescript.org)' + + def self.detect?(text) + return true if text.shebang? 'coffee' + end + + def self.keywords + @keywords ||= Set.new %w( + for by while until loop break continue return + switch when then if else do yield throw try catch finally await + new delete typeof instanceof super extends this class + import export debugger + ) + end + + def self.reserved + @reserved ||= Set.new %w( + case function var void with const let enum + native implements interface package private protected public static + ) + end + + def self.constants + @constants ||= Set.new %w( + true false yes no on off null NaN Infinity undefined + ) + end + + def self.builtins + @builtins ||= Set.new %w( + Array Boolean Date Error Function Math netscape Number Object + Packages RegExp String sun decodeURI decodeURIComponent + encodeURI encodeURIComponent eval isFinite isNaN parseFloat + parseInt document window + ) + end + + id = /[$a-zA-Z_][a-zA-Z0-9_]*/ + + state :comments do + rule %r/###[^#].*?###/m, Comment::Multiline + rule %r/#.*$/, Comment::Single + end + + state :whitespace do + rule %r/\s+/m, Text + end + + state :regex_comment do + rule %r/^#(?!\{).*$/, Comment::Single + rule %r/(\s+)(#(?!\{).*)$/ do + groups Text, Comment::Single + end + end + + state :multiline_regex_begin do + rule %r(///) do + token Str::Regex + goto :multiline_regex + end + end + + state :multiline_regex_end do + rule %r(///([gimy]+\b|\B)), Str::Regex, :pop! + end + + state :multiline_regex do + mixin :multiline_regex_end + mixin :regex_comment + mixin :has_interpolation + mixin :comments + mixin :whitespace + mixin :code_escape + + rule %r/\\\D/, Str::Escape + rule %r/\\\d+/, Name::Variable + rule %r/./m, Str::Regex + end + + state :slash_starts_regex do + mixin :comments + mixin :whitespace + mixin :multiline_regex_begin + + rule %r( + /(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/ # a regex + ([gimy]+\b|\B) + )x, Str::Regex, :pop! + + rule(//) { pop! } + end + + state :root do + rule(%r(^(?=\s|/| + rule %r/--(?![!#\$\%&*+.\/<=>?@\^\|_~]).*?$/, Comment::Single + end + + # nested commenting + state :comment do + rule %r/-}/, Comment::Multiline, :pop! + rule %r/{-/, Comment::Multiline, :comment + rule %r/[^-{}]+/, Comment::Multiline + rule %r/[-{}]/, Comment::Multiline + end + + state :comment_preproc do + rule %r/-}/, Comment::Preproc, :pop! + rule %r/{-/, Comment::Preproc, :comment + rule %r/[^-{}]+/, Comment::Preproc + rule %r/[-{}]/, Comment::Preproc + end + + state :root do + mixin :basic + + rule %r/'(?=(?:.|\\\S+)')/, Str::Char, :character + rule %r/"/, Str, :string + + rule %r/\d+e[+-]?\d+/i, Num::Float + rule %r/\d+\.\d+(e[+-]?\d+)?/i, Num::Float + rule %r/0o[0-7]+/i, Num::Oct + rule %r/0x[\da-f]+/i, Num::Hex + rule %r/\d+/, Num::Integer + + rule %r/[\w']+/ do |m| + match = m[0] + if match == "import" + token Keyword::Reserved + push :import + elsif match == "module" + token Keyword::Reserved + push :module + elsif reserved.include?(match) + token Keyword::Reserved + elsif match =~ /\A'?[A-Z]/ + token Keyword::Type + else + token Name + end + end + + # lambda operator + rule %r(\\(?![:!#\$\%&*+.\\/<=>?@^\|~-]+)), Name::Function + # special operators + rule %r((<-|::|->|=>|=)(?![:!#\$\%&*+.\\/<=>?@^\|~-]+)), Operator + # constructor/type operators + rule %r(:[:!#\$\%&*+.\\/<=>?@^\|~-]*), Operator + # other operators + rule %r([:!#\$\%&*+.\\/<=>?@^\|~-]+), Operator + + rule %r/\[\s*\]/, Keyword::Type + rule %r/\(\s*\)/, Name::Builtin + + # Quasiquotations + rule %r/(\[)([_a-z][\w']*)(\|)/ do |m| + token Operator, m[1] + token Name, m[2] + token Operator, m[3] + push :quasiquotation + end + + rule %r/[\[\](),;`{}]/, Punctuation + end + + state :import do + rule %r/\s+/, Text + rule %r/"/, Str, :string + rule %r/\bqualified\b/, Keyword + # import X as Y + rule %r/([A-Z][\w.]*)(\s+)(as)(\s+)([A-Z][a-zA-Z0-9_.]*)/ do + groups( + Name::Namespace, # X + Text, Keyword, # as + Text, Name # Y + ) + pop! + end + + # import X hiding (functions) + rule %r/([A-Z][\w.]*)(\s+)(hiding)(\s+)(\()/ do + groups( + Name::Namespace, # X + Text, Keyword, # hiding + Text, Punctuation # ( + ) + goto :funclist + end + + # import X (functions) + rule %r/([A-Z][\w.]*)(\s+)(\()/ do + groups( + Name::Namespace, # X + Text, + Punctuation # ( + ) + goto :funclist + end + + rule %r/[\w.]+/, Name::Namespace, :pop! + end + + state :module do + rule %r/\s+/, Text + # module Foo (functions) + rule %r/([A-Z][\w.]*)(\s+)(\()/ do + groups Name::Namespace, Text, Punctuation + push :funclist + end + + rule %r/\bwhere\b/, Keyword::Reserved, :pop! + + rule %r/[A-Z][a-zA-Z0-9_.]*/, Name::Namespace, :pop! + end + + state :funclist do + mixin :basic + rule %r/[A-Z]\w*/, Keyword::Type + rule %r/(_[\w\']+|[a-z][\w\']*)/, Name::Function + rule %r/,/, Punctuation + rule %r/[:!#\$\%&*+.\\\/<=>?@^\|~-]+/, Operator + rule %r/\(/, Punctuation, :funclist + rule %r/\)/, Punctuation, :pop! + end + + state :character do + rule %r/\\/ do + token Str::Escape + goto :character_end + push :escape + end + + rule %r/./ do + token Str::Char + goto :character_end + end + end + + state :character_end do + rule %r/'/, Str::Char, :pop! + rule %r/./, Error, :pop! + end + + state :quasiquotation do + rule %r/\|\]/, Operator, :pop! + rule %r/[^\|]+/m, Text + rule %r/\|/, Text + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\/, Str::Escape, :escape + rule %r/[^\\"]+/, Str + end + + state :escape do + rule %r/[abfnrtv"'&\\]/, Str::Escape, :pop! + rule %r/\^[\]\[A-Z@\^_]/, Str::Escape, :pop! + rule %r/#{ascii.join('|')}/, Str::Escape, :pop! + rule %r/o[0-7]+/i, Str::Escape, :pop! + rule %r/x[\da-f]+/i, Str::Escape, :pop! + rule %r/\d+/, Str::Escape, :pop! + rule %r/\s+\\/, Str::Escape, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/haxe.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/haxe.rb new file mode 100644 index 0000000..bca64ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/haxe.rb @@ -0,0 +1,265 @@ +# -*- coding: utf-8 -*- # + +module Rouge + module Lexers + class Haxe < RegexLexer + title "Haxe" + desc "Haxe Cross-platform Toolkit (http://haxe.org)" + + tag 'haxe' + aliases 'hx', 'haxe' + filenames '*.hx' + mimetypes 'text/haxe', 'text/x-haxe', 'text/x-hx' + + def self.detect?(text) + return true if text.shebang? "haxe" + end + + def self.keywords + @keywords ||= Set.new %w( + as break case cast catch class continue default do else enum false for + function if import in interface macro new null override package private + public return switch this throw true try untyped while + ) + end + + def self.imports + @imports ||= Set.new %w( + package import using + ) + end + + def self.declarations + @declarations ||= Set.new %w( + abstract dynamic extern extends from implements inline static to + typedef var + ) + end + + def self.reserved + @reserved ||= Set.new %w( + super trace inline build autoBuild enum + ) + end + + def self.constants + @constants ||= Set.new %w(true false null) + end + + def self.builtins + @builtins ||= %w( + Void Dynamic Math Class Any Float Int UInt String StringTools Sys + EReg isNaN parseFloat parseInt this Array Map Date DateTools Bool + Lambda Reflect Std File FileSystem + ) + end + + id = /[$a-zA-Z_][a-zA-Z0-9_]*/ + dotted_id = /[$a-zA-Z_][a-zA-Z0-9_.]*/ + + state :comments_and_whitespace do + rule %r/\s+/, Text + rule %r(//.*?$), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + end + + state :expr_start do + mixin :comments_and_whitespace + + rule %r/#(?:if|elseif|else|end).*/, Comment::Preproc + + rule %r(~) do + token Str::Regex + goto :regex + end + + rule %r/[{]/, Punctuation, :object + + rule %r//, Text, :pop! + end + + state :namespace do + mixin :comments_and_whitespace + + rule %r/ + (#{dotted_id}) + (\s+)(in|as)(\s+) + (#{id}) + /x do + groups(Name::Namespace, Text::Whitespace, Keyword, Text::Whitespace, Name) + end + + rule %r/#{dotted_id}/, Name::Namespace + + rule(//) { pop! } + end + + state :regex do + rule %r(/) do + token Str::Regex + goto :regex_end + end + + rule %r([^/]\n), Error, :pop! + + rule %r/\n/, Error, :pop! + rule %r/\[\^/, Str::Escape, :regex_group + rule %r/\[/, Str::Escape, :regex_group + rule %r/\\./, Str::Escape + rule %r{[(][?][:=> | == + | != )x, + Operator, :expr_start + rule %r([-:<>+*%&|\^/!=]=?), Operator, :expr_start + rule %r/[(\[,]/, Punctuation, :expr_start + rule %r/;/, Punctuation, :statement + rule %r/[)\]}.]/, Punctuation + + rule %r/[?]/ do + token Punctuation + push :ternary + push :expr_start + end + + rule id do |m| + match = m[0] + + if self.class.imports.include?(match) + token Keyword::Namespace + push :namespace + elsif self.class.keywords.include?(match) + token Keyword + push :expr_start + elsif self.class.declarations.include?(match) + token Keyword::Declaration + push :expr_start + elsif self.class.reserved.include?(match) + token Keyword::Reserved + elsif self.class.constants.include?(match) + token Keyword::Constant + elsif self.class.builtins.include?(match) + token Name::Builtin + else + token Name::Other + end + end + + rule %r/\-?\d+\.\d+(?:[eE]\d+)?[fd]?/, Num::Float + rule %r/0x\h+/, Num::Hex + rule %r/\-?[0-9]+/, Num::Integer + rule %r/"/, Str::Double, :str_double + rule %r/'/, Str::Single, :str_single + end + + # braced parts that aren't object literals + state :statement do + rule %r/(#{id})(\s*)(:)/ do + groups Name::Label, Text, Punctuation + end + + mixin :expr_start + end + + # object literals + state :object do + mixin :comments_and_whitespace + rule %r/[}]/ do + token Punctuation + goto :statement + end + + rule %r/(#{id})(\s*)(:)/ do + groups Name::Attribute, Text, Punctuation + push :expr_start + end + + rule %r/:/, Punctuation + mixin :root + end + + state :metadata do + rule %r/(#{id})(\()?/ do |m| + groups Name::Decorator, Punctuation + pop! unless m[2] + end + rule %r/:#{id}(?:\.#{id})*/, Name::Decorator, :pop! + rule %r/\)/, Name::Decorator, :pop! + mixin :root + end + + # ternary expressions, where : is not a label! + state :ternary do + rule %r/:/ do + token Punctuation + goto :expr_start + end + + mixin :root + end + + state :str_double do + mixin :str_escape + rule %r/"/, Str::Double, :pop! + rule %r/[^\\"]+/, Str::Double + end + + state :str_single do + mixin :str_escape + rule %r/'/, Str::Single, :pop! + rule %r/\$\$/, Str::Single + rule %r/\$#{id}/, Str::Interpol + rule %r/\$\{/, Str::Interpol, :str_interpol + rule %r/[^\\$']+/, Str::Single + end + + state :str_escape do + rule %r/\\[\\tnr'"]/, Str::Escape + rule %r/\\[0-7]{3}/, Str::Escape + rule %r/\\x\h{2}/, Str::Escape + rule %r/\\u\h{4}/, Str::Escape + rule %r/\\u\{\h{1,6}\}/, Str::Escape + end + + state :str_interpol do + rule %r/\}/, Str::Interpol, :pop! + mixin :root + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hcl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hcl.rb new file mode 100644 index 0000000..69a65f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hcl.rb @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Hcl < RegexLexer + tag 'hcl' + filenames '*.hcl', '*.nomad' + + title 'Hashicorp Configuration Language' + desc 'Hashicorp Configuration Language, used by Terraform and other Hashicorp tools' + + state :multiline_comment do + rule %r([*]/), Comment::Multiline, :pop! + rule %r([^*/]+), Comment::Multiline + rule %r([*/]), Comment::Multiline + end + + state :comments_and_whitespace do + rule %r/\s+/, Text + rule %r(//.*?$), Comment::Single + rule %r(#.*?$), Comment::Single + rule %r(/[*]), Comment::Multiline, :multiline_comment + end + + state :primitives do + rule %r/[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?([kKmMgG]b?)?/, Num::Float + rule %r/[0-9]+([kKmMgG]b?)?/, Num::Integer + rule %r/[-+*\/!%&<>|=:?]/, Operator + + rule %r/"/, Str::Double, :dq + rule %r/'/, Str::Single, :sq + rule %r/(<<-?)(\s*)(\'?)(\\?)(\w+)(\3)/ do |m| + groups Operator, Text, Str::Heredoc, Str::Heredoc, Name::Constant, Str::Heredoc + @heredocstr = Regexp.escape(m[5]) + push :heredoc + end + end + + def self.keywords + @keywords ||= Set.new %w() + end + + def self.declarations + @declarations ||= Set.new %w() + end + + def self.reserved + @reserved ||= Set.new %w() + end + + def self.constants + @constants ||= Set.new %w(true false null) + end + + def self.builtins + @builtins ||= %w() + end + + id = /[$a-z_\-][a-z0-9_\-]*/io + + state :root do + mixin :comments_and_whitespace + mixin :primitives + + rule %r/\{/ do + token Punctuation + push :hash + end + rule %r/\[/ do + token Punctuation + push :array + end + + rule id do |m| + if self.class.keywords.include? m[0] + token Keyword + push :composite + elsif self.class.declarations.include? m[0] + token Keyword::Declaration + push :composite + elsif self.class.reserved.include? m[0] + token Keyword::Reserved + elsif self.class.constants.include? m[0] + token Keyword::Constant + elsif self.class.builtins.include? m[0] + token Name::Builtin + else + token Name::Other + push :composite + end + end + end + + state :composite do + mixin :comments_and_whitespace + + rule %r/[{]/ do + token Punctuation + pop! + push :hash + end + + rule %r/[\[]/ do + token Punctuation + pop! + push :array + end + + mixin :root + + rule %r//, Text, :pop! + end + + state :hash do + mixin :comments_and_whitespace + + rule %r/[.,()\\\/*]/, Punctuation + rule %r/\=/, Punctuation + rule %r/\}/, Punctuation, :pop! + + mixin :root + end + + state :array do + mixin :comments_and_whitespace + + rule %r/[.,()\\\/*]/, Punctuation + rule %r/\]/, Punctuation, :pop! + + mixin :root + end + + state :dq do + rule %r/[^\\"]+/, Str::Double + rule %r/\\"/, Str::Escape + rule %r/"/, Str::Double, :pop! + end + + state :sq do + rule %r/[^\\']+/, Str::Single + rule %r/\\'/, Str::Escape + rule %r/'/, Str::Single, :pop! + end + + state :heredoc do + rule %r/\n/, Str::Heredoc, :heredoc_nl + rule %r/[^$\n]+/, Str::Heredoc + rule %r/[$]/, Str::Heredoc + end + + state :heredoc_nl do + rule %r/\s*(\w+)\s*\n/ do |m| + if m[1] == @heredocstr + token Name::Constant + pop! 2 + else + token Str::Heredoc + end + end + + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hlsl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hlsl.rb new file mode 100644 index 0000000..8fac6fa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hlsl.rb @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'c.rb' + + class HLSL < C + title "HLSL" + desc "HLSL, the High Level Shading Language for DirectX (docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl)" + tag 'hlsl' + filenames '*.hlsl', '*.hlsli' + mimetypes 'text/x-hlsl' + + def self.keywords + @keywords ||= Set.new %w( + asm asm_fragment break case cbuffer centroid class column_major + compile compile_fragment const continue default discard do else export + extern for fxgroup globallycoherent groupshared if in inline inout + interface line lineadj linear namespace nointerpolation noperspective + NULL out packoffset pass pixelfragment point precise return register + row_major sample sampler shared stateblock stateblock_state static + struct switch tbuffer technique technique10 technique11 texture + typedef triangle uniform vertexfragment volatile while + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + dword matrix snorm string unorm unsigned void vector BlendState Buffer + ByteAddressBuffer ComputeShader DepthStencilState DepthStencilView + DomainShader GeometryShader HullShader InputPatch LineStream + OutputPatch PixelShader PointStream RasterizerState RenderTargetView + RasterizerOrderedBuffer RasterizerOrderedByteAddressBuffer + RasterizerOrderedStructuredBuffer RasterizerOrderedTexture1D + RasterizerOrderedTexture1DArray RasterizerOrderedTexture2D + RasterizerOrderedTexture2DArray RasterizerOrderedTexture3D RWBuffer + RWByteAddressBuffer RWStructuredBuffer RWTexture1D RWTexture1DArray + RWTexture2D RWTexture2DArray RWTexture3D SamplerState + SamplerComparisonState StructuredBuffer Texture1D Texture1DArray + Texture2D Texture2DArray Texture2DMS Texture2DMSArray Texture3D + TextureCube TextureCubeArray TriangleStream VertexShader + + bool1 bool2 bool3 bool4 BOOL1 BOOL2 BOOL3 BOOL4 + int1 int2 int3 int4 + half1 half2 half3 half4 + float1 float2 float3 float4 + double1 double2 double3 double4 + + bool1x1 bool1x2 bool1x3 bool1x4 bool2x1 bool2x2 bool2x3 bool2x4 + bool3x1 bool3x2 bool3x3 bool3x4 bool4x1 bool4x2 bool4x3 bool4x4 + BOOL1x1 BOOL1x2 BOOL1x3 BOOL1x4 BOOL2x1 BOOL2x2 BOOL2x3 BOOL2x4 + BOOL3x1 BOOL3x2 BOOL3x3 BOOL3x4 BOOL4x1 BOOL4x2 BOOL4x3 BOOL4x4 + half1x1 half1x2 half1x3 half1x4 half2x1 half2x2 half2x3 half2x4 + half3x1 half3x2 half3x3 half3x4 half4x1 half4x2 half4x3 half4x4 + int1x1 int1x2 int1x3 int1x4 int2x1 int2x2 int2x3 int2x4 + int3x1 int3x2 int3x3 int3x4 int4x1 int4x2 int4x3 int4x4 + float1x1 float1x2 float1x3 float1x4 float2x1 float2x2 float2x3 float2x4 + float3x1 float3x2 float3x3 float3x4 float4x1 float4x2 float4x3 float4x4 + double1x1 double1x2 double1x3 double1x4 double2x1 double2x2 double2x3 double2x4 + double3x1 double3x2 double3x3 double3x4 double4x1 double4x2 double4x3 double4x4 + ) + end + + def self.reserved + @reserved ||= Set.new %w( + auto catch char const_cast delete dynamic_cast enum explicit friend + goto long mutable new operator private protected public + reinterpret_cast short signed sizeof static_cast template this throw + try typename union unsigned using virtual + ) + end + + def self.builtins + @builtins ||= Set.new %w( + abort abs acos all AllMemoryBarrier AllMemoryBarrierWithGroupSync any + AppendStructuredBuffer asdouble asfloat asin asint asuint asuint atan + atan2 ceil CheckAccessFullyMapped clamp clip CompileShader + ConsumeStructuredBuffer cos cosh countbits cross D3DCOLORtoUBYTE4 ddx + ddx_coarse ddx_fine ddy ddy_coarse ddy_fine degrees determinant + DeviceMemoryBarrier DeviceMemoryBarrierWithGroupSync distance dot dst + errorf EvaluateAttributeAtCentroid EvaluateAttributeAtSample + EvaluateAttributeSnapped exp exp2 f16tof32 f32tof16 faceforward + firstbithigh firstbitlow floor fma fmod frac frexp fwidth + GetRenderTargetSampleCount GetRenderTargetSamplePosition + GlobalOrderedCountIncrement GroupMemoryBarrier + GroupMemoryBarrierWithGroupSync InterlockedAdd InterlockedAnd + InterlockedCompareExchange InterlockedCompareStore InterlockedExchange + InterlockedMax InterlockedMin InterlockedOr InterlockedXor isfinite + isinf isnan ldexp length lerp lit log log10 log2 mad max min modf + msad4 mul noise normalize pow printf Process2DQuadTessFactorsAvg + Process2DQuadTessFactorsMax Process2DQuadTessFactorsMin + ProcessIsolineTessFactors ProcessQuadTessFactorsAvg + ProcessQuadTessFactorsMax ProcessQuadTessFactorsMin + ProcessTriTessFactorsAvg ProcessTriTessFactorsMax + ProcessTriTessFactorsMin QuadReadLaneAt QuadSwapX QuadSwapY radians + rcp reflect refract reversebits round rsqrt saturate sign sin sincos + sinh smoothstep sqrt step tan tanh tex1D tex1D tex1Dbias tex1Dgrad + tex1Dlod tex1Dproj tex2D tex2D tex2Dbias tex2Dgrad tex2Dlod tex2Dproj + tex3D tex3D tex3Dbias tex3Dgrad tex3Dlod tex3Dproj texCUBE texCUBE + texCUBEbias texCUBEgrad texCUBElod texCUBEproj transpose trunc + WaveAllBitAnd WaveAllMax WaveAllMin WaveAllBitOr WaveAllBitXor + WaveAllEqual WaveAllProduct WaveAllSum WaveAllTrue WaveAnyTrue + WaveBallot WaveGetLaneCount WaveGetLaneIndex WaveGetOrderedIndex + WaveIsHelperLane WaveOnce WavePrefixProduct WavePrefixSum + WaveReadFirstLane WaveReadLaneAt + + SV_CLIPDISTANCE SV_CLIPDISTANCE0 SV_CLIPDISTANCE1 SV_CULLDISTANCE + SV_CULLDISTANCE0 SV_CULLDISTANCE1 SV_COVERAGE SV_DEPTH + SV_DEPTHGREATEREQUAL SV_DEPTHLESSEQUAL SV_DISPATCHTHREADID + SV_DOMAINLOCATION SV_GROUPID SV_GROUPINDEX SV_GROUPTHREADID + SV_GSINSTANCEID SV_INNERCOVERAGE SV_INSIDETESSFACTOR SV_INSTANCEID + SV_ISFRONTFACE SV_OUTPUTCONTROLPOINTID SV_POSITION SV_PRIMITIVEID + SV_RENDERTARGETARRAYINDEX SV_SAMPLEINDEX SV_STENCILREF SV_TESSFACTOR + SV_VERTEXID SV_VIEWPORTARRAYINDEX + + allow_uav_condition branch call domain earlydepthstencil fastopt + flatten forcecase instance loop maxtessfactor numthreads + outputcontrolpoints outputtopology partitioning patchconstantfunc + unroll + + BINORMAL BINORMAL0 BINORMAL1 BINORMAL2 BINORMAL3 BINORMAL4 + BLENDINDICES0 BLENDINDICES1 BLENDINDICES2 BLENDINDICES3 BLENDINDICES4 + BLENDWEIGHT0 BLENDWEIGHT1 BLENDWEIGHT2 BLENDWEIGHT3 BLENDWEIGHT4 COLOR + COLOR0 COLOR1 COLOR2 COLOR3 COLOR4 NORMAL NORMAL0 NORMAL1 NORMAL2 + NORMAL3 NORMAL4 POSITION POSITION0 POSITION1 POSITION2 POSITION3 + POSITION4 POSITIONT PSIZE0 PSIZE1 PSIZE2 PSIZE3 PSIZE4 TANGENT + TANGENT0 TANGENT1 TANGENT2 TANGENT3 TANGENT4 TESSFACTOR0 TESSFACTOR1 + TESSFACTOR2 TESSFACTOR3 TESSFACTOR4 TEXCOORD0 TEXCOORD1 TEXCOORD2 + TEXCOORD3 TEXCOORD4 + + FOG PSIZE + + VFACE VPOS + + DEPTH0 DEPTH1 DEPTH2 DEPTH3 DEPTH4 + ) + end + + ws = %r((?:\s|//.*?\n|/[*].*?[*]/)+) + id = /[a-zA-Z_][a-zA-Z0-9_]*/ + + state :root do + mixin :expr_whitespace + rule %r( + ([\w*\s]+?[\s*]) # return arguments + (#{id}) # function name + (\s*\([^;]*?\)(?:\s*:\s+#{id})?) # signature + (#{ws}?)({|;) # open brace or semicolon + )mx do |m| + # This is copied from the C lexer + recurse m[1] + token Name::Function, m[2] + recurse m[3] + recurse m[4] + token Punctuation, m[5] + if m[5] == ?{ + push :function + end + end + rule %r/\{/, Punctuation, :function + mixin :statements + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hocon.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hocon.rb new file mode 100644 index 0000000..881a969 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hocon.rb @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'json.rb' + + class HOCON < JSON + title 'HOCON' + desc "Human-Optimized Config Object Notation (https://github.com/lightbend/config)" + tag 'hocon' + filenames '*.hocon' + + state :comments do + # Comments + rule %r(//.*?$), Comment::Single + rule %r(#.*?$), Comment::Single + end + + prepend :root do + mixin :comments + end + + prepend :object do + # Keywords + rule %r/\b(?:include|url|file|classpath)\b/, Keyword + end + + state :name do + rule %r/("(?:\"|[^"\n])*?")(\s*)([:=]|(?={))/ do + groups Name::Label, Text::Whitespace, Punctuation + end + + rule %r/([-\w.]+)(\s*)([:=]|(?={))/ do + groups Name::Label, Text::Whitespace, Punctuation + end + end + + state :value do + mixin :comments + + rule %r/\n/, Text::Whitespace + rule %r/\s+/, Text::Whitespace + + mixin :constants + + # Interpolation + rule %r/[$][{][?]?/, Literal::String::Interpol, :interpolation + + # Strings + rule %r/"""/, Literal::String::Double, :multiline_string + rule %r/"/, Str::Double, :string + + rule %r/\[/, Punctuation, :array + rule %r/{/, Punctuation, :object + + # Symbols (only those not handled by JSON) + rule %r/[()=]/, Punctuation + + # Values + rule %r/[^$"{}\[\]:=,\+#`^?!@*&]+?/, Literal + end + + state :interpolation do + rule %r/[\w\-\.]+?/, Name::Variable + rule %r/}/, Literal::String::Interpol, :pop! + end + + prepend :string do + rule %r/[$][{][?]?/, Literal::String::Interpol, :interpolation + rule %r/[^\\"\${]+/, Literal::String::Double + end + + state :multiline_string do + rule %r/"[^"]{1,2}/, Literal::String::Double + mixin :string + rule %r/"""/, Literal::String::Double, :pop! + end + + prepend :constants do + # Numbers (handle the case where we have multiple periods, ie. IP addresses) + rule %r/\d+\.(\d+\.?){3,}/, Literal + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hql.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hql.rb new file mode 100644 index 0000000..ba7dab4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/hql.rb @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- # + +module Rouge + module Lexers + load_lexer 'sql.rb' + + class HQL < SQL + title "HQL" + desc "Hive Query Language SQL dialect" + tag 'hql' + filenames '*.hql' + + def self.keywords + # sources: + # https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL + # https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF + @keywords ||= Set.new(%w( + ADD ADMIN AFTER ANALYZE ARCHIVE ASC BEFORE BUCKET BUCKETS CASCADE + CHANGE CLUSTER CLUSTERED CLUSTERSTATUS COLLECTION COLUMNS COMMENT + COMPACT COMPACTIONS COMPUTE CONCATENATE CONTINUE DATA DATABASES + DATETIME DAY DBPROPERTIES DEFERRED DEFINED DELIMITED DEPENDENCY DESC + DIRECTORIES DIRECTORY DISABLE DISTRIBUTE ELEM_TYPE ENABLE ESCAPED + EXCLUSIVE EXPLAIN EXPORT FIELDS FILE FILEFORMAT FIRST FORMAT FORMATTED + FUNCTIONS HOLD_DDLTIME HOUR IDXPROPERTIES IGNORE INDEX INDEXES INPATH + INPUTDRIVER INPUTFORMAT ITEMS JAR KEYS KEY_TYPE LIMIT LINES LOAD + LOCATION LOCK LOCKS LOGICAL LONG MAPJOIN MATERIALIZED METADATA MINUS + MINUTE MONTH MSCK NOSCAN NO_DROP OFFLINE OPTION OUTPUTDRIVER + OUTPUTFORMAT OVERWRITE OWNER PARTITIONED PARTITIONS PLUS PRETTY + PRINCIPALS PROTECTION PURGE READ READONLY REBUILD RECORDREADER + RECORDWRITER REGEXP RELOAD RENAME REPAIR REPLACE REPLICATION RESTRICT + REWRITE RLIKE ROLE ROLES SCHEMA SCHEMAS SECOND SEMI SERDE + SERDEPROPERTIES SERVER SETS SHARED SHOW SHOW_DATABASE SKEWED SORT + SORTED SSL STATISTICS STORED STREAMTABLE STRING STRUCT TABLES + TBLPROPERTIES TEMPORARY TERMINATED TINYINT TOUCH TRANSACTIONS UNARCHIVE + UNDO UNIONTYPE UNLOCK UNSET UNSIGNED URI USE UTC UTCTIMESTAMP + VALUE_TYPE VIEW WHILE YEAR IF + + ALL ALTER AND ARRAY AS AUTHORIZATION BETWEEN BIGINT BINARY BOOLEAN + BOTH BY CASE CAST CHAR COLUMN CONF CREATE CROSS CUBE CURRENT + CURRENT_DATE CURRENT_TIMESTAMP CURSOR DATABASE DATE DECIMAL DELETE + DESCRIBE DISTINCT DOUBLE DROP ELSE END EXCHANGE EXISTS EXTENDED + EXTERNAL FALSE FETCH FLOAT FOLLOWING FOR FROM FULL FUNCTION GRANT + GROUP GROUPING HAVING IF IMPORT IN INNER INSERT INT INTERSECT + INTERVAL INTO IS JOIN LATERAL LEFT LESS LIKE LOCAL MACRO MAP MORE + NONE NOT NULL OF ON OR ORDER OUT OUTER OVER PARTIALSCAN PARTITION + PERCENT PRECEDING PRESERVE PROCEDURE RANGE READS REDUCE REVOKE RIGHT + ROLLUP ROW ROWS SELECT SET SMALLINT TABLE TABLESAMPLE THEN TIMESTAMP + TO TRANSFORM TRIGGER TRUE TRUNCATE UNBOUNDED UNION UNIQUEJOIN UPDATE + USER USING UTC_TMESTAMP VALUES VARCHAR WHEN WHERE WINDOW WITH + + AUTOCOMMIT ISOLATION LEVEL OFFSET SNAPSHOT TRANSACTION WORK WRITE + + COMMIT ONLY REGEXP RLIKE ROLLBACK START + + ABORT KEY LAST NORELY NOVALIDATE NULLS RELY VALIDATE + + CACHE CONSTRAINT FOREIGN PRIMARY REFERENCES + + DETAIL DOW EXPRESSION OPERATOR QUARTER SUMMARY VECTORIZATION WEEK YEARS MONTHS WEEKS DAYS HOURS MINUTES SECONDS + + DAYOFWEEK EXTRACT FLOOR INTEGER PRECISION VIEWS + + TIMESTAMPTZ ZONE + + TIME NUMERIC + + NAMED_STRUCT CREATE_UNION + + ROUND BROUND FLOOR CEIL CEILING RAND EXP LN LOG10 LOG2 LOG POW POWER SQRT BIN + HEX UNHEX CONV ABS PMOD SIN ASIN COS ACOS TAN ATAN DEGREES RADIANS POSITIVE + NEGATIVE SIGN E PI FACTORIAL CBRT SHIFTLEFT SHIFTRIGHT SHIFTRIGHTUNSIGNED + GREATEST LEAST WIDTH_BUCKET SIZE SIZE MAP_KEYS MAP_VALUES ARRAY_CONTAINS + SORT_ARRAY BINARY CAST FROM_UNIXTIME UNIX_TIMESTAMP UNIX_TIMESTAMP + UNIX_TIMESTAMP TO_DATE YEAR QUARTER MONTH DAY DAYOFMONTH HOUR MINUTE SECOND + WEEKOFYEAR EXTRACT DATEDIFF DATE_ADD DATE_SUB FROM_UTC_TIMESTAMP + TO_UTC_TIMESTAMP CURRENT_DATE CURRENT_TIMESTAMP ADD_MONTHS LAST_DAY NEXT_DAY + TRUNC MONTHS_BETWEEN DATE_FORMAT IF ISNULL ISNOTNULL NVL COALESCE CASE WHEN + then else end NULLIF ASSERT_TRUE ASCII BASE64 CHARACTER_LENGTH CHR CONCAT + CONTEXT_NGRAMS CONCAT_WS CONCAT_WS DECODE ELT ENCODE FIELD FIND_IN_SET + FORMAT_NUMBER GET_JSON_OBJECT IN_FILE INSTR LENGTH LOCATE LOWER LCASE LPAD LTRIM + NGRAMS OCTET_LENGTH PARSE_URL PRINTF REGEXP_EXTRACT REGEXP_REPLACE REPEAT + REPLACE REVERSE RPAD RTRIM SENTENCES SPACE SPLIT STR_TO_MAP SUBSTR SUBSTRING + SUBSTRING_INDEX TRANSLATE TRIM UNBASE64 UPPER UCASE INITCAP LEVENSHTEIN SOUNDEX + MASK MASK_FIRST_N MASK_LAST_N MASK_SHOW_FIRST_N MASK_SHOW_LAST_N MASK_HASH + JAVA_METHOD REFLECT HASH CURRENT_USER LOGGED_IN_USER CURRENT_DATABASE MD5 SHA1 + SHA CRC32 SHA2 AES_ENCRYPT AES_DECRYPT VERSION COUNT SUM AVG MIN MAX VARIANCE + VAR_POP VAR_SAMP STDDEV_POP STDDEV_SAMP COVAR_POP COVAR_SAMP CORR PERCENTILE + PERCENTILE_APPROX PERCENTILE_APPROX REGR_AVGX REGR_AVGY REGR_COUNT + REGR_INTERCEPT REGR_R2 REGR_SLOPE REGR_SXX REGR_SXY REGR_SYY HISTOGRAM_NUMERIC + COLLECT_SET COLLECT_LIST NTILE EXPLODE EXPLODE POSEXPLODE INLINE STACK + + JSON_TUPLE PARSE_URL_TUPLE + + XPATH XPATH_SHORT XPATH_INT XPATH_LONG XPATH_FLOAT XPATH_DOUBLE + XPATH_NUMBER XPATH_STRING GET_JSON_OBJECT JSON_TUPLE + + PARSE_URL_TUPLE + )) + end + + def self.keywords_type + # source: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types + @keywords_type ||= Set.new(%w( + TINYINT SMALLINT INT INTEGER BIGINT FLOAT DOUBLE PRECISION DECIMAL NUMERIC + TIMESTAMP DATE INTERVAL + STRING VARCHAR CHAR + BOOLEAN BINARY + ARRAY MAP STRUCT UNIONTYPE + )) + end + + prepend :root do + # a double-quoted string is a string literal in Hive QL. + rule %r/"/, Str::Double, :double_string + + # interpolation of variables through ${...} + rule %r/\$\{/, Name::Variable, :hive_variable + end + + prepend :single_string do + rule %r/\$\{/, Name::Variable, :hive_variable + rule %r/[^\\'\$]+/, Str::Single + end + + prepend :double_string do + rule %r/\$\{/, Name::Variable, :hive_variable + # double-quoted strings are string literals so need to change token + rule %r/"/, Str::Double, :pop! + rule %r/[^\\"\$]+/, Str::Double + end + + state :hive_variable do + rule %r/\}/, Name::Variable, :pop! + rule %r/[^\}]+/, Name::Variable + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/html.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/html.rb new file mode 100644 index 0000000..f50e8e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/html.rb @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class HTML < RegexLexer + title "HTML" + desc "HTML, the markup language of the web" + tag 'html' + filenames '*.htm', '*.html', '*.xhtml', '*.cshtml', '*.razor' + mimetypes 'text/html', 'application/xhtml+xml' + + def self.detect?(text) + return true if text.doctype?(/\bhtml\b/i) + return false if text =~ /\A<\?xml\b/ + return true if text =~ /<\s*html\b/ + end + + start do + @javascript = Javascript.new(options) + @css = CSS.new(options) + end + + state :root do + rule %r/[^<&]+/m, Text + rule %r/&\S*?;/, Name::Entity + rule %r//im, Comment::Preproc + rule %r//m, Comment::Preproc + rule %r//, Comment, :pop! + rule %r/-/, Comment + end + + state :tag do + rule %r/\s+/m, Text + rule %r/[\p{L}:_\[\]()*.-][\p{Word}\p{Cf}:.·\[\]()*-]*\s*=\s*/m, Name::Attribute, :attr + rule %r/[\p{L}:_*#-][\p{Word}\p{Cf}:.·*#-]*/, Name::Attribute + rule %r(/?\s*>)m, Name::Tag, :pop! + end + + state :attr do + # TODO: are backslash escapes valid here? + rule %r/"/ do + token Str + goto :dq + end + + rule %r/'/ do + token Str + goto :sq + end + + rule %r/[^\s>]+/, Str, :pop! + end + + state :dq do + rule %r/"/, Str, :pop! + rule %r/[^"]+/, Str + end + + state :sq do + rule %r/'/, Str, :pop! + rule %r/[^']+/, Str + end + + state :script_content do + rule %r([^<]+) do + delegate @javascript + end + + rule %r(<\s*/\s*script\s*>)m, Name::Tag, :pop! + + rule %r(<) do + delegate @javascript + end + end + + state :style_content do + rule %r/[^<]+/ do + delegate @lang + end + + rule %r(<\s*/\s*style\s*>)m, Name::Tag, :pop! + + rule %r/ ->> . / // + //= /= < << <<= <= = > >= >> + >>= @ @= ^ ^= accumulate apply as-> assoc butlast + calling-module-name car cdr chain coll? combinations comp complement compress cond + cons cons? constantly count cut cycle dec defclass defmacro defmacro! + defmacro/g! defmain defn defreader dict-comp disassemble dispatch-reader-macro distinct do doto + drop drop-last drop-while empty? eval eval-and-compile eval-when-compile even? every? filter + first flatten float? fn for* fraction genexpr gensym get group-by + identity if* if-not if-python2 inc input instance? integer integer-char? integer? + interleave interpose islice iterable? iterate iterator? juxt keyword keyword? last + let lif lif-not list* list-comp macro-error macroexpand macroexpand-1 map merge-with + multicombinations name neg? none? not-in not? nth numeric? odd? partition + permutations pos? product quasiquote quote range read read-str reduce remove + repeat repeatedly require rest second set-comp setv some string string? + symbol? take take-nth take-while tee unless unquote unquote-splicing when with* + with-decorator with-gensyms xor yield-from zero? zip zip-longest | |= ~ + ) + end + + identifier = %r([\w!$%*+,<=>?/.-]+) + keyword = %r([\w!\#$%*+,<=>?/.-]+) + + def name_token(name) + return Keyword if self.class.keywords.include?(name) + return Name::Builtin if self.class.builtins.include?(name) + nil + end + + state :root do + rule %r/;.*?$/, Comment::Single + rule %r/\s+/m, Text::Whitespace + + rule %r/-?\d+\.\d+/, Num::Float + rule %r/-?\d+/, Num::Integer + rule %r/0x-?[0-9a-fA-F]+/, Num::Hex + + rule %r/"(\\.|[^"])*"/, Str + rule %r/'#{keyword}/, Str::Symbol + rule %r/::?#{keyword}/, Name::Constant + rule %r/\\(.|[a-z]+)/i, Str::Char + + + rule %r/~@|[`\'#^~&@]/, Operator + + rule %r/(\()(\s*)(#{identifier})/m do |m| + token Punctuation, m[1] + token Text::Whitespace, m[2] + token(name_token(m[3]) || Name::Function, m[3]) + end + + rule identifier do |m| + token name_token(m[0]) || Name + end + + # vectors + rule %r/[\[\]]/, Punctuation + + # maps + rule %r/[{}]/, Punctuation + + # parentheses + rule %r/[()]/, Punctuation + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idlang.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idlang.rb new file mode 100644 index 0000000..6431ce4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idlang.rb @@ -0,0 +1,312 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# vim: set ts=2 sw=2 et: + +module Rouge + module Lexers + class IDLang < RegexLexer + title "IDL" + desc "Interactive Data Language" + + tag 'idlang' + filenames '*.idl' + + name = /[_A-Z]\w*/i + kind_param = /(\d+|#{name})/ + exponent = /[dDeE][+-]\d+/ + + def self.exec_unit + @exec_unit ||= Set.new %w( + PRO FUNCTION + ) + end + + def self.keywords + @keywords ||= Set.new %w( + STRUCT INHERITS + RETURN CONTINUE BEGIN END BREAK GOTO + ) + end + + def self.standalone_statements + # Must not have a comma afterwards + @standalone_statements ||= Set.new %w( + COMMON FORWARD_FUNCTION + ) + end + + def self.decorators + # Must not have a comma afterwards + @decorators ||= Set.new %w( + COMPILE_OPT + ) + end + + def self.operators + @operators ||= Set.new %w( + AND= EQ= GE= GT= LE= LT= MOD= NE= OR= XOR= NOT= + ) + end + + def self.conditionals + @conditionals ||= Set.new %w( + OF DO ENDIF ENDELSE ENDFOR ENDFOREACH ENDWHILE ENDREP ENDCASE ENDSWITCH + IF THEN ELSE FOR FOREACH WHILE REPEAT UNTIL CASE SWITCH + AND EQ GE GT LE LT MOD NE OR XOR NOT + ) + end + + def self.routines + @routines ||= Set.new %w( + A_CORRELATE ABS ACOS ADAPT_HIST_EQUAL ALOG ALOG10 + AMOEBA ANNOTATE ARG_PRESENT ARRAY_EQUAL + ARRAY_INDICES ARROW ASCII_TEMPLATE ASIN ASSOC ATAN + AXIS BAR_PLOT BESELI BESELJ BESELK BESELY BETA + BILINEAR BIN_DATE BINARY_TEMPLATE BINDGEN BINOMIAL + BLAS_AXPY BLK_CON BOX_CURSOR BREAK BREAKPOINT + BROYDEN BYTARR BYTE BYTEORDER BYTSCL C_CORRELATE + CALDAT CALENDAR CALL_EXTERNAL CALL_FUNCTION + CALL_METHOD CALL_PROCEDURE CATCH CD CEIL CHEBYSHEV + CHECK_MATH CHISQR_CVF CHISQR_PDF CHOLDC CHOLSOL + CINDGEN CIR_3PNT CLOSE CLUST_WTS CLUSTER + COLOR_CONVERT COLOR_QUAN COLORMAP_APPLICABLE COMFIT + COMPLEX COMPLEXARR COMPLEXROUND + COMPUTE_MESH_NORMALS COND CONGRID CONJ + CONSTRAINED_MIN CONTOUR CONVERT_COORD CONVOL + COORD2TO3 CORRELATE COS COSH CRAMER CREATE_STRUCT + CREATE_VIEW CROSSP CRVLENGTH CT_LUMINANCE CTI_TEST + CURSOR CURVEFIT CV_COORD CVTTOBM CW_ANIMATE + CW_ANIMATE_GETP CW_ANIMATE_LOAD CW_ANIMATE_RUN + CW_ARCBALL CW_BGROUP CW_CLR_INDEX CW_COLORSEL + CW_DEFROI CW_FIELD CW_FILESEL CW_FORM CW_FSLIDER + CW_LIGHT_EDITOR CW_LIGHT_EDITOR_GET + CW_LIGHT_EDITOR_SET CW_ORIENT CW_PALETTE_EDITOR + CW_PALETTE_EDITOR_GET CW_PALETTE_EDITOR_SET + CW_PDMENU CW_RGBSLIDER CW_TMPL CW_ZOOM DBLARR + DCINDGEN DCOMPLEX DCOMPLEXARR DEFINE_KEY DEFROI + DEFSYSV DELETE_SYMBOL DELLOG DELVAR DERIV DERIVSIG + DETERM DEVICE DFPMIN DIALOG_MESSAGE + DIALOG_PICKFILE DIALOG_PRINTERSETUP + DIALOG_PRINTJOB DIALOG_READ_IMAGE + DIALOG_WRITE_IMAGE DICTIONARY DIGITAL_FILTER DILATE DINDGEN + DISSOLVE DIST DLM_LOAD DLM_REGISTER + DO_APPLE_SCRIPT DOC_LIBRARY DOUBLE DRAW_ROI EFONT + EIGENQL EIGENVEC ELMHES EMPTY ENABLE_SYSRTN EOF + ERASE ERODE ERRORF ERRPLOT EXECUTE EXIT EXP EXPAND + EXPAND_PATH EXPINT EXTRAC EXTRACT_SLICE F_CVF + F_PDF FACTORIAL FFT FILE_CHMOD FILE_DELETE + FILE_EXPAND_PATH FILE_MKDIR FILE_TEST FILE_WHICH + FILE_SEARCH PATH_SEP FILE_DIRNAME FILE_BASENAME + FILE_INFO FILE_MOVE FILE_COPY FILE_LINK FILE_POLL_INPUT + FILEPATH FINDFILE FINDGEN FINITE FIX FLICK FLOAT + FLOOR FLOW3 FLTARR FLUSH FORMAT_AXIS_VALUES + FORWARD_FUNCTION FREE_LUN FSTAT FULSTR FUNCT + FV_TEST FX_ROOT FZ_ROOTS GAMMA GAMMA_CT + GAUSS_CVF GAUSS_PDF GAUSS2DFIT GAUSSFIT GAUSSINT + GET_DRIVE_LIST GET_KBRD GET_LUN GET_SCREEN_SIZE + GET_SYMBOL GETENV GOTO GREG2JUL GRID_TPS GRID3 GS_ITER + H_EQ_CT H_EQ_INT HANNING HASH HEAP_GC HELP HILBERT + HIST_2D HIST_EQUAL HISTOGRAM HLS HOUGH HQR HSV + IBETA IDENTITY IDL_CONTAINER IDLANROI + IDLANROIGROUP IDLFFDICOM IDLFFDXF IDLFFLANGUAGECAT + IDLFFSHAPE IDLGRAXIS IDLGRBUFFER IDLGRCLIPBOARD + IDLGRCOLORBAR IDLGRCONTOUR IDLGRFONT IDLGRIMAGE + IDLGRLEGEND IDLGRLIGHT IDLGRMODEL IDLGRMPEG + IDLGRPALETTE IDLGRPATTERN IDLGRPLOT IDLGRPOLYGON + IDLGRPOLYLINE IDLGRPRINTER IDLGRROI IDLGRROIGROUP + IDLGRSCENE IDLGRSURFACE IDLGRSYMBOL + IDLGRTESSELLATOR IDLGRTEXT IDLGRVIEW + IDLGRVIEWGROUP IDLGRVOLUME IDLGRVRML IDLGRWINDOW + IGAMMA IMAGE_CONT IMAGE_STATISTICS IMAGINARY + INDGEN INT_2D INT_3D INT_TABULATED INTARR INTERPOL + INTERPOLATE INVERT IOCTL ISA ISHFT ISOCONTOUR + ISOSURFACE JOURNAL JUL2GREG JULDAY KEYWORD_SET KRIG2D + KURTOSIS KW_TEST L64INDGEN LABEL_DATE LABEL_REGION + LADFIT LAGUERRE LEEFILT LEGENDRE LINBCG LINDGEN + LINFIT LINKIMAGE LIST LIVE_CONTOUR LIVE_CONTROL + LIVE_DESTROY LIVE_EXPORT LIVE_IMAGE LIVE_INFO + LIVE_LINE LIVE_LOAD LIVE_OPLOT LIVE_PLOT + LIVE_PRINT LIVE_RECT LIVE_STYLE LIVE_SURFACE + LIVE_TEXT LJLCT LL_ARC_DISTANCE LMFIT LMGR LNGAMMA + LNP_TEST LOADCT LOCALE_GET LON64ARR LONARR LONG + LONG64 LSODE LU_COMPLEX LUDC LUMPROVE LUSOL + M_CORRELATE MACHAR MAKE_ARRAY MAKE_DLL MAP_2POINTS + MAP_CONTINENTS MAP_GRID MAP_IMAGE MAP_PATCH + MAP_PROJ_INFO MAP_SET MAX MATRIX_MULTIPLY MD_TEST MEAN + MEANABSDEV MEDIAN MEMORY MESH_CLIP MESH_DECIMATE + MESH_ISSOLID MESH_MERGE MESH_NUMTRIANGLES MESH_OBJ + MESH_SMOOTH MESH_SURFACEAREA MESH_VALIDATE + MESH_VOLUME MESSAGE MIN MIN_CURVE_SURF MK_HTML_HELP + MODIFYCT MOMENT MORPH_CLOSE MORPH_DISTANCE + MORPH_GRADIENT MORPH_HITORMISS MORPH_OPEN + MORPH_THIN MORPH_TOPHAT MPEG_CLOSE MPEG_OPEN + MPEG_PUT MPEG_SAVE MSG_CAT_CLOSE MSG_CAT_COMPILE + MSG_CAT_OPEN MULTI N_ELEMENTS N_PARAMS N_TAGS + NEWTON NORM OBJ_CLASS OBJ_DESTROY OBJ_ISA OBJ_NEW + OBJ_VALID OBJARR ON_ERROR ON_IOERROR ONLINE_HELP + OPEN OPENR OPENW OPENU OPLOT OPLOTERR ORDEREDHASH P_CORRELATE + PARTICLE_TRACE PCOMP PLOT PLOT_3DBOX PLOT_FIELD + PLOTERR PLOTS PNT_LINE POINT_LUN POLAR_CONTOUR + POLAR_SURFACE POLY POLY_2D POLY_AREA POLY_FIT + POLYFILL POLYFILLV POLYSHADE POLYWARP POPD POWELL + PRIMES PRINT PRINTF PRINTD PRODUCT PROFILE PROFILER + PROFILES PROJECT_VOL PS_SHOW_FONTS PSAFM PSEUDO + PTR_FREE PTR_NEW PTR_VALID PTRARR PUSHD QROMB + QROMO QSIMP QUERY_CSV R_CORRELATE R_TEST RADON RANDOMN + RANDOMU RANKS RDPIX READ READF READ_ASCII + READ_BINARY READ_BMP READ_CSV READ_DICOM READ_IMAGE + READ_INTERFILE READ_JPEG READ_PICT READ_PNG + READ_PPM READ_SPR READ_SRF READ_SYLK READ_TIFF + READ_WAV READ_WAVE READ_X11_BITMAP READ_XWD READS + READU REBIN RECALL_COMMANDS RECON3 REDUCE_COLORS + REFORM REGRESS REPLICATE REPLICATE_INPLACE + RESOLVE_ALL RESOLVE_ROUTINE RESTORE RETALL + REVERSE REWIND RK4 ROBERTS ROT ROTATE ROUND + ROUTINE_INFO RS_TEST S_TEST SAVE SAVGOL SCALE3 + SCALE3D SCOPE_LEVEL SCOPE_TRACEBACK SCOPE_VARFETCH + SCOPE_VARNAME SEARCH2D SEARCH3D SET_PLOT SET_SHADING + SET_SYMBOL SETENV SETLOG SETUP_KEYS SFIT + SHADE_SURF SHADE_SURF_IRR SHADE_VOLUME SHIFT SHOW3 + SHOWFONT SIGNUM SIN SINDGEN SINH SIZE SKEWNESS SKIPF + SLICER3 SLIDE_IMAGE SMOOTH SOBEL SOCKET SORT SPAWN + SPH_4PNT SPH_SCAT SPHER_HARM SPL_INIT SPL_INTERP + SPLINE SPLINE_P SPRSAB SPRSAX SPRSIN SPRSTP SQRT + STANDARDIZE STDDEV STOP STRARR STRCMP STRCOMPRESS + STREAMLINE STREGEX STRETCH STRING STRJOIN STRLEN + STRLOWCASE STRMATCH STRMESSAGE STRMID STRPOS + STRPUT STRSPLIT STRTRIM STRUCT_ASSIGN STRUCT_HIDE + STRUPCASE SURFACE SURFR SVDC SVDFIT SVSOL + SWAP_ENDIAN SWITCH SYSTIME T_CVF T_PDF T3D + TAG_NAMES TAN TANH TAPRD TAPWRT TEK_COLOR + TEMPORARY TETRA_CLIP TETRA_SURFACE TETRA_VOLUME + THIN THREED TIME_TEST2 TIMEGEN TM_TEST TOTAL TRACE + TRANSPOSE TRI_SURF TRIANGULATE TRIGRID TRIQL + TRIRED TRISOL TRNLOG TS_COEF TS_DIFF TS_FCAST + TS_SMOOTH TV TVCRS TVLCT TVRD TVSCL TYPENAME UINDGEN UINT + UINTARR UL64INDGEN ULINDGEN ULON64ARR ULONARR + ULONG ULONG64 UNIQ USERSYM VALUE_LOCATE VARIANCE + VAX_FLOAT VECTOR_FIELD VEL VELOVECT VERT_T3D VOIGT + VORONOI VOXEL_PROJ WAIT WARP_TRI WATERSHED WDELETE + WEOF WF_DRAW WHERE WIDGET_BASE WIDGET_BUTTON + WIDGET_CONTROL WIDGET_DRAW WIDGET_DROPLIST + WIDGET_EVENT WIDGET_INFO WIDGET_LABEL WIDGET_LIST + WIDGET_SLIDER WIDGET_TABLE WIDGET_TEXT WINDOW + WRITE_BMP WRITE_CSV WRITE_IMAGE WRITE_JPEG WRITE_NRIF + WRITE_PICT WRITE_PNG WRITE_PPM WRITE_SPR WRITE_SRF + WRITE_SYLK WRITE_TIFF WRITE_WAV WRITE_WAVE WRITEU + WSET WSHOW WTN WV_APPLET WV_CW_WAVELET WV_CWT + WV_DENOISE WV_DWT WV_FN_COIFLET WV_FN_DAUBECHIES + WV_FN_GAUSSIAN WV_FN_HAAR WV_FN_MORLET WV_FN_PAUL + WV_FN_SYMLET WV_IMPORT_DATA WV_IMPORT_WAVELET + WV_PLOT3D_WPS WV_PLOT_MULTIRES WV_PWT + WV_TOOL_DENOISE XBM_EDIT XDISPLAYFILE XDXF XFONT + XINTERANIMATE XLOADCT XMANAGER XMNG_TMPL XMTOOL + XOBJVIEW XPALETTE XPCOLOR XPLOT3D XREGISTERED XROI + XSQ_TEST XSURFACE XVAREDIT XVOLUME XVOLUME_ROTATE + XVOLUME_WRITE_IMAGE XYOUTS ZOOM ZOOM_24 + ) + end + + state :root do + rule %r/\s+/, Text::Whitespace + # Normal comments + rule %r/;.*$/, Comment::Single + rule %r/\,\s*\,/, Error + rule %r/\!#{name}/, Name::Variable::Global + + rule %r/[(),:\&\$]/, Punctuation + + ## Format statements are quite a strange beast. + ## Better process them in their own state. + #rule %r/\b(FORMAT)(\s*)(\()/mi do |m| + # token Keyword, m[1] + # token Text::Whitespace, m[2] + # token Punctuation, m[3] + # push :format_spec + #end + + rule %r( + [+-]? # sign + ( + (\d+[.]\d*|[.]\d+)(#{exponent})? + | \d+#{exponent} # exponent is mandatory + ) + (_#{kind_param})? # kind parameter + )xi, Num::Float + + rule %r/\d+(B|S|U|US|LL|L|ULL|UL)?/i, Num::Integer + rule %r/"[0-7]+(B|O|U|ULL|UL|LL|L)?/i, Num::Oct + rule %r/'[0-9A-F]+'X(B|S|US|ULL|UL|U|LL|L)?/i, Num::Hex + rule %r/(#{kind_param}_)?'/, Str::Single, :string_single + rule %r/(#{kind_param}_)?"/, Str::Double, :string_double + + rule %r{\#\#|\#|\&\&|\|\||/=|<=|>=|->|\@|\?|[-+*/<=~^{}]}, Operator + # Structures and the like + rule %r/(#{name})(\.)([^\s,]*)/i do + groups Name, Operator, Name + #delegate IDLang, m[3] + end + + rule %r/(function|pro)((?:\s|\$\s)+)/i do + groups Keyword, Text::Whitespace + push :funcname + end + + rule %r/#{name}/m do |m| + match = m[0].upcase + if self.class.keywords.include? match + token Keyword + elsif self.class.conditionals.include? match + token Keyword + elsif self.class.decorators.include? match + token Name::Decorator + elsif self.class.standalone_statements.include? match + token Keyword::Reserved + elsif self.class.operators.include? match + token Operator::Word + elsif self.class.routines.include? match + token Name::Builtin + else + token Name + end + end + + end + + state :funcname do + rule %r/#{name}/, Name::Function + + rule %r/\s+/, Text::Whitespace + rule %r/(:+|\$)/, Operator + rule %r/;.*/, Comment::Single + + # Be done with this state if we hit EOL or comma + rule %r/$/, Text::Whitespace, :pop! + rule %r/,/, Operator, :pop! + end + + state :string_single do + rule %r/[^']+/, Str::Single + rule %r/''/, Str::Escape + rule %r/'/, Str::Single, :pop! + end + + state :string_double do + rule %r/[^"]+/, Str::Double + rule %r/"/, Str::Double, :pop! + end + + state :format_spec do + rule %r/'/, Str::Single, :string_single + rule %r/"/, Str::Double, :string_double + rule %r/\(/, Punctuation, :format_spec + rule %r/\)/, Punctuation, :pop! + rule %r/,/, Punctuation + rule %r/\s+/, Text::Whitespace + # Edit descriptors could be seen as a kind of "format literal". + rule %r/[^\s'"(),]+/, Literal + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idris.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idris.rb new file mode 100644 index 0000000..99b4cb5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/idris.rb @@ -0,0 +1,210 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Idris < RegexLexer + title "Idris" + desc "The Idris programming language (idris-lang.org)" + + tag 'idris' + aliases 'idr' + filenames '*.idr' + mimetypes 'text/x-idris' + + def self.reserved_keywords + @reserved_keywords ||= %w( + _ data class instance namespace + infix[lr]? let where of with type + do if then else case in + ) + end + + def self.ascii + @ascii ||= %w( + NUL SOH [SE]TX EOT ENQ ACK BEL BS HT LF VT FF CR S[OI] DLE + DC[1-4] NAK SYN ETB CAN EM SUB ESC [FGRU]S SP DEL + ) + end + + def self.prelude_functions + @prelude_functions ||= %w( + abs acos all and any asin atan atan2 break ceiling compare concat + concatMap const cos cosh curry cycle div drop dropWhile elem + encodeFloat enumFrom enumFromThen enumFromThenTo enumFromTo exp + fail filter flip floor foldl foldl1 foldr foldr1 fromInteger fst + gcd getChar getLine head id init iterate last lcm length lines log + lookup map max maxBound maximum maybe min minBound minimum mod + negate not null or pi pred print product putChar putStr putStrLn + readFile recip repeat replicate return reverse scanl scanl1 sequence + sequence_ show sin sinh snd span splitAt sqrt succ sum tail take + takeWhile tan tanh uncurry unlines unwords unzip unzip3 words + writeFile zip zip3 zipWith zipWith3 + ) + end + + state :basic do + rule %r/\s+/m, Text + rule %r/{-#/, Comment::Preproc, :comment_preproc + rule %r/{-/, Comment::Multiline, :comment + rule %r/^\|\|\|.*$/, Comment::Doc + rule %r/--(?![!#\$\%&*+.\/<=>?@\^\|_~]).*?$/, Comment::Single + end + + # nested commenting + state :comment do + rule %r/-}/, Comment::Multiline, :pop! + rule %r/{-/, Comment::Multiline, :comment + rule %r/[^-{}]+/, Comment::Multiline + rule %r/[-{}]/, Comment::Multiline + end + state :comment_preproc do + rule %r/-}/, Comment::Preproc, :pop! + rule %r/{-/, Comment::Preproc, :comment + rule %r/[^-{}]+/, Comment::Preproc + rule %r/[-{}]/, Comment::Preproc + end + + state :directive do + rule %r/\%(default)\s+(total|partial)/, Keyword # totality + rule %r/\%(access)\s+(public|abstract|private|export)/, Keyword # export + rule %r/\%(language)\s+(.*)/, Keyword # language + rule %r/\%(provide)\s+.*\s+(with)\s+/, Keyword # type + end + + state :prelude do + rule %r/\b(Type|Exists|World|IO|IntTy|FTy|File|Mode|Dec|Bool|Ordering|Either|IsJust|List|Maybe|Nat|Stream|StrM|Not|Lazy|Inf)\s/, Keyword::Type + rule %r/\b(Eq|Ord|Num|MinBound|MaxBound|Integral|Applicative|Alternative|Cast|Foldable|Functor|Monad|Traversable|Uninhabited|Semigroup|Monoid)\s/, Name::Class + rule %r/\b(?:#{Idris.prelude_functions.join('|')})[ ]+(?![=:-])/, Name::Builtin + end + + state :root do + mixin :basic + mixin :directive + + rule %r/\bimport\b/, Keyword::Reserved, :import + rule %r/\bmodule\b/, Keyword::Reserved, :module + rule %r/\b(?:#{Idris.reserved_keywords.join('|')})\b/, Keyword::Reserved + rule %r/\b(Just|Nothing|Left|Right|True|False|LT|LTE|EQ|GT|GTE)\b/, Keyword::Constant + # function signature + rule %r/^[\w']+\s*:/, Name::Function + # should be below as you can override names defined in Prelude + mixin :prelude + rule %r/[_a-z][\w']*/, Name + rule %r/[A-Z][\w']*/, Keyword::Type + + # lambda operator + rule %r(\\(?![:!#\$\%&*+.\\/<=>?@^\|~-]+)), Name::Function + # special operators + rule %r((<-|::|->|=>|=)(?![:!#\$\%&*+.\\/<=>?@^\|~-]+)), Operator + # constructor/type operators + rule %r(:[:!#\$\%&*+.\\/<=>?@^\|~-]*), Operator + # other operators + rule %r([:!#\$\%&*+.\\/<=>?@^\|~-]+), Operator + + rule %r/\d+(\.\d+)?(e[+-]?\d+)?/i, Num::Float + rule %r/0o[0-7]+/i, Num::Oct + rule %r/0x[\da-f]+/i, Num::Hex + rule %r/\d+/, Num::Integer + + rule %r/'/, Str::Char, :character + rule %r/"/, Str, :string + + rule %r/\[\s*\]/, Keyword::Type + rule %r/\(\s*\)/, Name::Builtin + + # Quasiquotations + rule %r/(\[)([_a-z][\w']*)(\|)/ do |m| + token Operator, m[1] + token Name, m[2] + token Operator, m[3] + push :quasiquotation + end + + rule %r/[\[\](),;`{}]/, Punctuation + end + + state :import do + rule %r/\s+/, Text + rule %r/"/, Str, :string + # import X as Y + rule %r/([A-Z][\w.]*)(\s+)(as)(\s+)([A-Z][a-zA-Z0-9_.]*)/ do + groups( + Name::Namespace, # X + Text, Keyword, # as + Text, Name # Y + ) + pop! + end + + # import X (functions) + rule %r/([A-Z][\w.]*)(\s+)(\()/ do + groups( + Name::Namespace, # X + Text, + Punctuation # ( + ) + goto :funclist + end + + rule %r/[\w.]+/, Name::Namespace, :pop! + end + + state :module do + rule %r/\s+/, Text + # module X + rule %r/([A-Z][\w.]*)/, Name::Namespace, :pop! + end + + state :funclist do + mixin :basic + rule %r/[A-Z]\w*/, Keyword::Type + rule %r/(_[\w\']+|[a-z][\w\']*)/, Name::Function + rule %r/,/, Punctuation + rule %r/[:!#\$\%&*+.\\\/<=>?@^\|~-]+/, Operator + rule %r/\(/, Punctuation, :funclist + rule %r/\)/, Punctuation, :pop! + end + + state :character do + rule %r/\\/ do + token Str::Escape + goto :character_end + push :escape + end + + rule %r/./ do + token Str::Char + goto :character_end + end + end + + state :character_end do + rule %r/'/, Str::Char, :pop! + rule %r/./, Error, :pop! + end + + state :quasiquotation do + rule %r/\|\]/, Operator, :pop! + rule %r/[^\|]+/m, Text + rule %r/\|/, Text + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\/, Str::Escape, :escape + rule %r/[^\\"]+/, Str + end + + state :escape do + rule %r/[abfnrtv"'&\\]/, Str::Escape, :pop! + rule %r/\^[\]\[A-Z@\^_]/, Str::Escape, :pop! + rule %r/#{Idris.ascii.join('|')}/, Str::Escape, :pop! + rule %r/o[0-7]+/i, Str::Escape, :pop! + rule %r/x[\da-fA-F]+/i, Str::Escape, :pop! + rule %r/\d+/, Str::Escape, :pop! + rule %r/\s+\\/, Str::Escape, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/iecst.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/iecst.rb new file mode 100644 index 0000000..d1e1196 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/iecst.rb @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class IecST < RegexLexer + tag 'iecst' + title "IEC 61131-3 Structured Text" + desc 'Structured text is a programming language for PLCs (programmable logic controllers).' + filenames '*.awl', '*.scl', '*.st' + + mimetypes 'text/x-iecst' + + def self.keywords + blocks = %w( + PROGRAM CONFIGURATION INITIAL_STEP INTERFACE FUNCTION_BLOCK FUNCTION ACTION TRANSITION + TYPE STRUCT STEP NAMESPACE LIBRARY CHANNEL FOLDER RESOURCE + VAR_ACCESS VAR_CONFIG VAR_EXTERNAL VAR_GLOBAL VAR_INPUT VAR_IN_OUT VAR_OUTPUT VAR_TEMP VAR + CONST METHOD PROPERTY + CASE FOR IF REPEAT WHILE + ) + @keywords ||= Set.new %w( + AT BEGIN BY CONSTANT CONTINUE DO ELSE ELSIF EXIT EXTENDS FROM GET GOTO IMPLEMENTS JMP + NON_RETAIN OF PRIVATE PROTECTED PUBLIC RETAIN RETURN SET TASK THEN TO UNTIL USING WITH + __CATCH __ENDTRY __FINALLY __TRY + ) + blocks + blocks.map {|kw| "END_" + kw} + end + + def self.types + @types ||= Set.new %w( + ANY ARRAY BOOL BYTE POINTER STRING + DATE DATE_AND_TIME DT TIME TIME_OF_DAY TOD + INT DINT LINT SINT UINT UDINT ULINT USINT + WORD DWORD LWORD + REAL LREAL + ) + end + + def self.literals + @literals ||= Set.new %w(TRUE FALSE NULL) + end + + def self.operators + @operators ||= Set.new %w(AND EQ EXPT GE GT LE LT MOD NE NOT OR XOR) + end + + state :whitespace do + # Spaces + rule %r/\s+/m, Text + # // Comments + rule %r((//).*$\n?), Comment::Single + # (* Comments *) + rule %r(\(\*.*?\*\))m, Comment::Multiline + # { Comments } + rule %r(\{.*?\})m, Comment::Special + end + + state :root do + mixin :whitespace + + rule %r/'[^']+'/, Literal::String::Single + rule %r/"[^"]+"/, Literal::String::Symbol + rule %r/%[IQM][XBWDL][\d.]*|%[IQ][\d.]*/, Name::Variable::Magic + rule %r/\b(?:D|DT|T|TOD)#[\d_shmd:]*/i, Literal::Date + rule %r/\b(?:16#[\d_a-f]+|0x[\d_a-f]+)\b/i, Literal::Number::Hex + rule %r/\b2#[01_]+/, Literal::Number::Bin + rule %r/(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, Literal::Number::Float + rule %r/\b[\d.,_]+/, Literal::Number + + rule %r/\b[A-Z_]+\b/i do |m| + name = m[0].upcase + if self.class.keywords.include?(name) + token Keyword + elsif self.class.types.include?(name) + token Keyword::Type + elsif self.class.literals.include?(name) + token Literal + elsif self.class.operators.include?(name) + token Operator + else + token Name + end + end + + rule %r/S?R?:?=>?|&&?|\*\*?|<[=>]?|>=?|[-:^\/+#]/, Operator + rule %r/\b[a-z_]\w*(?=\s*\()/i, Name::Function + rule %r/\b[a-z_]\w*\b/i, Name + rule %r/[()\[\].,;]/, Punctuation + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/igorpro.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/igorpro.rb new file mode 100644 index 0000000..a542cea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/igorpro.rb @@ -0,0 +1,664 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class IgorPro < RegexLexer + tag 'igorpro' + filenames '*.ipf' + mimetypes 'text/x-igorpro' + + title "IgorPro" + desc "WaveMetrics Igor Pro" + + def self.keywords + @keywords ||= Set.new %w( + structure endstructure + threadsafe static + macro proc window menu function end + if else elseif endif switch strswitch endswitch + break return continue + for endfor do while + case default + try catch endtry + abortonrte + ) + end + + def self.preprocessor + @preprocessor ||= Set.new %w( + pragma include + define ifdef ifndef undef + if elif else endif + ) + end + + def self.igorDeclarations + @igorDeclarations ||= Set.new %w( + variable string wave strconstant constant + nvar svar dfref funcref struct + char uchar int16 uint16 int32 uint32 int64 uint64 float double + ) + end + + def self.igorConstants + @igorConstants ||= Set.new %w( + nan inf + ) + end + + def self.igorFunction + @igorFunction ||= Set.new %w( + AddListItem AiryA AiryAD AiryB AiryBD AnnotationInfo + AnnotationList AxisInfo AxisList AxisValFromPixel + AxonTelegraphAGetDataNum AxonTelegraphAGetDataString + AxonTelegraphAGetDataStruct AxonTelegraphGetDataNum + AxonTelegraphGetDataString AxonTelegraphGetDataStruct + AxonTelegraphGetTimeoutMs AxonTelegraphSetTimeoutMs + Base64Decode Base64Encode Besseli Besselj Besselk + Bessely BinarySearch BinarySearchInterp CTabList + CaptureHistory CaptureHistoryStart CheckName + ChildWindowList CleanupName ContourInfo ContourNameList + ContourNameToWaveRef ContourZ ControlNameList + ConvertTextEncoding CountObjects CountObjectsDFR + CreationDate CsrInfo CsrWave CsrWaveRef CsrXWave + CsrXWaveRef DataFolderDir DataFolderExists + DataFolderRefStatus DataFolderRefsEqual DateToJulian + Dawson DimDelta DimOffset DimSize Faddeeva FetchURL + FindDimLabel FindListItem FontList FontSizeHeight + FontSizeStringWidth FresnelCos FresnelSin FuncRefInfo + FunctionInfo FunctionList FunctionPath + GISGetAllFileFormats GISSRefsAreEqual Gauss Gauss1D + Gauss2D GetBrowserLine GetBrowserSelection + GetDataFolder GetDataFolderDFR GetDefaultFont + GetDefaultFontSize GetDefaultFontStyle GetDimLabel + GetEnvironmentVariable GetErrMessage GetFormula + GetIndependentModuleName GetIndexedObjName + GetIndexedObjNameDFR GetKeyState GetRTErrMessage + GetRTError GetRTLocInfo GetRTLocation GetRTStackInfo + GetScrapText GetUserData GetWavesDataFolder + GetWavesDataFolderDFR GizmoInfo GizmoScale GrepList + GrepString GuideInfo GuideNameList HDF5AttributeInfo + HDF5DatasetInfo HDF5LibraryInfo HDF5TypeInfo Hash + HyperG0F1 HyperG1F1 HyperG2F1 HyperGNoise HyperGPFQ + IgorInfo IgorVersion ImageInfo ImageNameList + ImageNameToWaveRef IndependentModuleList IndexToScale + IndexedDir IndexedFile Inf Integrate1D Interp2D + Interp3D ItemsInList JacobiCn JacobiSn JulianToDate + Laguerre LaguerreA LaguerreGauss LambertW LayoutInfo + LegendreA ListMatch ListToTextWave ListToWaveRefWave + LowerStr MCC_AutoBridgeBal MCC_AutoFastComp + MCC_AutoPipetteOffset MCC_AutoSlowComp + MCC_AutoWholeCellComp MCC_GetBridgeBalEnable + MCC_GetBridgeBalResist MCC_GetFastCompCap + MCC_GetFastCompTau MCC_GetHolding MCC_GetHoldingEnable + MCC_GetMode MCC_GetNeutralizationCap + MCC_GetNeutralizationEnable MCC_GetOscKillerEnable + MCC_GetPipetteOffset MCC_GetPrimarySignalGain + MCC_GetPrimarySignalHPF MCC_GetPrimarySignalLPF + MCC_GetRsCompBandwidth MCC_GetRsCompCorrection + MCC_GetRsCompEnable MCC_GetRsCompPrediction + MCC_GetSecondarySignalGain MCC_GetSecondarySignalLPF + MCC_GetSlowCompCap MCC_GetSlowCompTau + MCC_GetSlowCompTauX20Enable MCC_GetSlowCurrentInjEnable + MCC_GetSlowCurrentInjLevel + MCC_GetSlowCurrentInjSetlTime MCC_GetWholeCellCompCap + MCC_GetWholeCellCompEnable MCC_GetWholeCellCompResist + MCC_SelectMultiClamp700B MCC_SetBridgeBalEnable + MCC_SetBridgeBalResist MCC_SetFastCompCap + MCC_SetFastCompTau MCC_SetHolding MCC_SetHoldingEnable + MCC_SetMode MCC_SetNeutralizationCap + MCC_SetNeutralizationEnable MCC_SetOscKillerEnable + MCC_SetPipetteOffset MCC_SetPrimarySignalGain + MCC_SetPrimarySignalHPF MCC_SetPrimarySignalLPF + MCC_SetRsCompBandwidth MCC_SetRsCompCorrection + MCC_SetRsCompEnable MCC_SetRsCompPrediction + MCC_SetSecondarySignalGain MCC_SetSecondarySignalLPF + MCC_SetSlowCompCap MCC_SetSlowCompTau + MCC_SetSlowCompTauX20Enable MCC_SetSlowCurrentInjEnable + MCC_SetSlowCurrentInjLevel + MCC_SetSlowCurrentInjSetlTime MCC_SetTimeoutMs + MCC_SetWholeCellCompCap MCC_SetWholeCellCompEnable + MCC_SetWholeCellCompResist MPFXEMGPeak + MPFXExpConvExpPeak MPFXGaussPeak MPFXLorenzianPeak + MPFXVoigtPeak MacroList MandelbrotPoint MarcumQ + MatrixCondition MatrixDet MatrixDot MatrixRank + MatrixTrace ModDate NVAR_Exists NaN NameOfWave + NewFreeDataFolder NewFreeWave NormalizeUnicode + NumVarOrDefault NumberByKey OperationList PICTInfo + PICTList PadString PanelResolution ParamIsDefault + ParseFilePath PathList Pi PixelFromAxisVal PolygonArea + PossiblyQuoteName ProcedureText RemoveByKey + RemoveEnding RemoveFromList RemoveListItem + ReplaceNumberByKey ReplaceString ReplaceStringByKey + SQL2DBinaryWaveToTextWave SQLAllocHandle SQLAllocStmt + SQLBinaryWavesToTextWave SQLBindCol SQLBindParameter + SQLBrowseConnect SQLBulkOperations SQLCancel + SQLCloseCursor SQLColAttributeNum SQLColAttributeStr + SQLColumnPrivileges SQLColumns SQLConnect + SQLDataSources SQLDescribeCol SQLDescribeParam + SQLDisconnect SQLDriverConnect SQLDrivers SQLEndTran + SQLError SQLExecDirect SQLExecute SQLFetch + SQLFetchScroll SQLForeignKeys SQLFreeConnect SQLFreeEnv + SQLFreeHandle SQLFreeStmt SQLGetConnectAttrNum + SQLGetConnectAttrStr SQLGetCursorName SQLGetDataNum + SQLGetDataStr SQLGetDescFieldNum SQLGetDescFieldStr + SQLGetDescRec SQLGetDiagFieldNum SQLGetDiagFieldStr + SQLGetDiagRec SQLGetEnvAttrNum SQLGetEnvAttrStr + SQLGetFunctions SQLGetInfoNum SQLGetInfoStr + SQLGetStmtAttrNum SQLGetStmtAttrStr SQLGetTypeInfo + SQLMoreResults SQLNativeSql SQLNumParams + SQLNumResultCols SQLNumResultRowsIfKnown + SQLNumRowsFetched SQLParamData SQLPrepare + SQLPrimaryKeys SQLProcedureColumns SQLProcedures + SQLPutData SQLReinitialize SQLRowCount + SQLSetConnectAttrNum SQLSetConnectAttrStr + SQLSetCursorName SQLSetDescFieldNum SQLSetDescFieldStr + SQLSetDescRec SQLSetEnvAttrNum SQLSetEnvAttrStr + SQLSetPos SQLSetStmtAttrNum SQLSetStmtAttrStr + SQLSpecialColumns SQLStatistics SQLTablePrivileges + SQLTables SQLTextWaveTo2DBinaryWave + SQLTextWaveToBinaryWaves SQLUpdateBoundValues + SQLXOPCheckState SVAR_Exists ScreenResolution Secs2Date + Secs2Time SelectNumber SelectString + SetEnvironmentVariable SortList SpecialCharacterInfo + SpecialCharacterList SpecialDirPath SphericalBessJ + SphericalBessJD SphericalBessY SphericalBessYD + SphericalHarmonics StartMSTimer StatsBetaCDF + StatsBetaPDF StatsBinomialCDF StatsBinomialPDF + StatsCMSSDCDF StatsCauchyCDF StatsCauchyPDF StatsChiCDF + StatsChiPDF StatsCorrelation StatsDExpCDF StatsDExpPDF + StatsEValueCDF StatsEValuePDF StatsErlangCDF + StatsErlangPDF StatsErrorPDF StatsExpCDF StatsExpPDF + StatsFCDF StatsFPDF StatsFriedmanCDF StatsGEVCDF + StatsGEVPDF StatsGammaCDF StatsGammaPDF + StatsGeometricCDF StatsGeometricPDF StatsHyperGCDF + StatsHyperGPDF StatsInvBetaCDF StatsInvBinomialCDF + StatsInvCMSSDCDF StatsInvCauchyCDF StatsInvChiCDF + StatsInvDExpCDF StatsInvEValueCDF StatsInvExpCDF + StatsInvFCDF StatsInvFriedmanCDF StatsInvGammaCDF + StatsInvGeometricCDF StatsInvKuiperCDF + StatsInvLogNormalCDF StatsInvLogisticCDF + StatsInvMaxwellCDF StatsInvMooreCDF + StatsInvNBinomialCDF StatsInvNCChiCDF StatsInvNCFCDF + StatsInvNormalCDF StatsInvParetoCDF StatsInvPoissonCDF + StatsInvPowerCDF StatsInvQCDF StatsInvQpCDF + StatsInvRayleighCDF StatsInvRectangularCDF + StatsInvSpearmanCDF StatsInvStudentCDF + StatsInvTopDownCDF StatsInvTriangularCDF + StatsInvUsquaredCDF StatsInvVonMisesCDF + StatsInvWeibullCDF StatsKuiperCDF StatsLogNormalCDF + StatsLogNormalPDF StatsLogisticCDF StatsLogisticPDF + StatsMaxwellCDF StatsMaxwellPDF StatsMedian + StatsMooreCDF StatsNBinomialCDF StatsNBinomialPDF + StatsNCChiCDF StatsNCChiPDF StatsNCFCDF StatsNCFPDF + StatsNCTCDF StatsNCTPDF StatsNormalCDF StatsNormalPDF + StatsParetoCDF StatsParetoPDF StatsPermute + StatsPoissonCDF StatsPoissonPDF StatsPowerCDF + StatsPowerNoise StatsPowerPDF StatsQCDF StatsQpCDF + StatsRayleighCDF StatsRayleighPDF StatsRectangularCDF + StatsRectangularPDF StatsRunsCDF StatsSpearmanRhoCDF + StatsStudentCDF StatsStudentPDF StatsTopDownCDF + StatsTriangularCDF StatsTriangularPDF StatsTrimmedMean + StatsUSquaredCDF StatsVonMisesCDF StatsVonMisesNoise + StatsVonMisesPDF StatsWaldCDF StatsWaldPDF + StatsWeibullCDF StatsWeibullPDF StopMSTimer + StrVarOrDefault StringByKey StringFromList StringList + StudentA StudentT TDMAddChannel TDMAddGroup + TDMAppendDataValues TDMAppendDataValuesTime + TDMChannelPropertyExists TDMCloseChannel TDMCloseFile + TDMCloseGroup TDMCreateChannelProperty TDMCreateFile + TDMCreateFileProperty TDMCreateGroupProperty + TDMFilePropertyExists TDMGetChannelPropertyNames + TDMGetChannelPropertyNum TDMGetChannelPropertyStr + TDMGetChannelPropertyTime TDMGetChannelPropertyType + TDMGetChannelStringPropertyLen TDMGetChannels + TDMGetDataType TDMGetDataValues TDMGetDataValuesTime + TDMGetFilePropertyNames TDMGetFilePropertyNum + TDMGetFilePropertyStr TDMGetFilePropertyTime + TDMGetFilePropertyType TDMGetFileStringPropertyLen + TDMGetGroupPropertyNames TDMGetGroupPropertyNum + TDMGetGroupPropertyStr TDMGetGroupPropertyTime + TDMGetGroupPropertyType TDMGetGroupStringPropertyLen + TDMGetGroups TDMGetLibraryErrorDescription + TDMGetNumChannelProperties TDMGetNumChannels + TDMGetNumDataValues TDMGetNumFileProperties + TDMGetNumGroupProperties TDMGetNumGroups + TDMGroupPropertyExists TDMOpenFile TDMOpenFileEx + TDMRemoveChannel TDMRemoveGroup TDMReplaceDataValues + TDMReplaceDataValuesTime TDMSaveFile + TDMSetChannelPropertyNum TDMSetChannelPropertyStr + TDMSetChannelPropertyTime TDMSetDataValues + TDMSetDataValuesTime TDMSetFilePropertyNum + TDMSetFilePropertyStr TDMSetFilePropertyTime + TDMSetGroupPropertyNum TDMSetGroupPropertyStr + TDMSetGroupPropertyTime TableInfo TagVal TagWaveRef + TextEncodingCode TextEncodingName TextFile + ThreadGroupCreate ThreadGroupGetDF ThreadGroupGetDFR + ThreadGroupRelease ThreadGroupWait ThreadProcessorCount + ThreadReturnValue TraceFromPixel TraceInfo + TraceNameList TraceNameToWaveRef TrimString URLDecode + URLEncode UnPadString UniqueName + UnsetEnvironmentVariable UpperStr VariableList Variance + VoigtFunc VoigtPeak WaveCRC WaveDims WaveExists + WaveHash WaveInfo WaveList WaveMax WaveMin WaveName + WaveRefIndexed WaveRefIndexedDFR WaveRefWaveToList + WaveRefsEqual WaveTextEncoding WaveType WaveUnits + WhichListItem WinList WinName WinRecreation WinType + XWaveName XWaveRefFromTrace ZernikeR abs acos acosh + alog area areaXY asin asinh atan atan2 atanh beta betai + binomial binomialNoise binomialln cabs ceil cequal + char2num chebyshev chebyshevU cmplx cmpstr conj cos + cosIntegral cosh cot coth cpowi csc csch date date2secs + datetime defined deltax digamma dilogarithm ei enoise + equalWaves erf erfc erfcw exists exp expInt + expIntegralE1 expNoise fDAQmx_AI_GetReader + fDAQmx_AO_UpdateOutputs fDAQmx_CTR_Finished + fDAQmx_CTR_IsFinished fDAQmx_CTR_IsPulseFinished + fDAQmx_CTR_ReadCounter fDAQmx_CTR_ReadWithOptions + fDAQmx_CTR_SetPulseFrequency fDAQmx_CTR_Start + fDAQmx_ConnectTerminals fDAQmx_DIO_Finished + fDAQmx_DIO_PortWidth fDAQmx_DIO_Read fDAQmx_DIO_Write + fDAQmx_DeviceNames fDAQmx_DisconnectTerminals + fDAQmx_ErrorString fDAQmx_ExternalCalDate + fDAQmx_NumAnalogInputs fDAQmx_NumAnalogOutputs + fDAQmx_NumCounters fDAQmx_NumDIOPorts fDAQmx_ReadChan + fDAQmx_ReadNamedChan fDAQmx_ResetDevice + fDAQmx_ScanGetAvailable fDAQmx_ScanGetNextIndex + fDAQmx_ScanStart fDAQmx_ScanStop fDAQmx_ScanWait + fDAQmx_ScanWaitWithTimeout fDAQmx_SelfCalDate + fDAQmx_SelfCalibration fDAQmx_WF_IsFinished + fDAQmx_WF_WaitUntilFinished fDAQmx_WaveformStart + fDAQmx_WaveformStop fDAQmx_WriteChan factorial fakedata + faverage faverageXY floor gamma gammaEuler gammaInc + gammaNoise gammln gammp gammq gcd gnoise hcsr hermite + hermiteGauss imag interp inverseERF inverseERFC leftx + limit ln log logNormalNoise lorentzianNoise magsqr max + mean median min mod norm note num2char num2istr num2str + numpnts numtype p2rect pcsr pnt2x poissonNoise poly + poly2D qcsr r2polar real rightx round sawtooth + scaleToIndex sec sech sign sin sinIntegral sinc sinh + sqrt str2num stringCRC stringmatch strlen strsearch sum + tan tango_close_device tango_command_inout + tango_compute_image_proj tango_get_dev_attr_list + tango_get_dev_black_box tango_get_dev_cmd_list + tango_get_dev_status tango_get_dev_timeout + tango_get_error_stack tango_open_device + tango_ping_device tango_read_attribute + tango_read_attributes tango_reload_dev_interface + tango_resume_attr_monitor tango_set_attr_monitor_period + tango_set_dev_timeout tango_start_attr_monitor + tango_stop_attr_monitor tango_suspend_attr_monitor + tango_write_attribute tango_write_attributes tanh ticks + time trunc vcsr viAssertIntrSignal viAssertTrigger + viAssertUtilSignal viClear viClose viDisableEvent + viDiscardEvents viEnableEvent viFindNext viFindRsrc + viGetAttribute viGetAttributeString viGpibCommand + viGpibControlATN viGpibControlREN viGpibPassControl + viGpibSendIFC viIn16 viIn32 viIn8 viLock viMapAddress + viMapTrigger viMemAlloc viMemFree viMoveIn16 viMoveIn32 + viMoveIn8 viMoveOut16 viMoveOut32 viMoveOut8 viOpen + viOpenDefaultRM viOut16 viOut32 viOut8 viPeek16 + viPeek32 viPeek8 viPoke16 viPoke32 viPoke8 viRead + viReadSTB viSetAttribute viSetAttributeString + viStatusDesc viTerminate viUnlock viUnmapAddress + viUnmapTrigger viUsbControlIn viUsbControlOut + viVxiCommandQuery viWaitOnEvent viWrite wnoise x2pnt + xcsr zcsr zeromq_client_connect zeromq_client_connect + zeromq_client_recv zeromq_client_recv + zeromq_client_send zeromq_client_send + zeromq_handler_start zeromq_handler_start + zeromq_handler_stop zeromq_handler_stop + zeromq_server_bind zeromq_server_bind + zeromq_server_recv zeromq_server_recv + zeromq_server_send zeromq_server_send zeromq_set + zeromq_set zeromq_stop zeromq_stop + zeromq_test_callfunction zeromq_test_callfunction + zeromq_test_serializeWave zeromq_test_serializeWave + zeta + ) + end + + def self.igorOperation + @igorOperation ||= Set.new %w( + APMath Abort AddFIFOData AddFIFOVectData AddMovieAudio + AddMovieFrame AddWavesToBoxPlot AddWavesToViolinPlot + AdoptFiles Append AppendBoxPlot AppendImage + AppendLayoutObject AppendMatrixContour AppendText + AppendToGizmo AppendToGraph AppendToLayout + AppendToTable AppendViolinPlot AppendXYZContour + AutoPositionWindow AxonTelegraphFindServers + BackgroundInfo Beep BoundingBall BoxSmooth BrowseURL + BuildMenu Button CWT Chart CheckBox CheckDisplayed + ChooseColor Close CloseHelp CloseMovie CloseProc + ColorScale ColorTab2Wave Concatenate ControlBar + ControlInfo ControlUpdate + ConvertGlobalStringTextEncoding ConvexHull Convolve + CopyDimLabels CopyFile CopyFolder CopyScales Correlate + CreateAliasShortcut CreateBrowser Cross CtrlBackground + CtrlFIFO CtrlNamedBackground Cursor CurveFit + CustomControl DAQmx_AI_SetupReader DAQmx_AO_SetOutputs + DAQmx_CTR_CountEdges DAQmx_CTR_OutputPulse + DAQmx_CTR_Period DAQmx_CTR_PulseWidth DAQmx_DIO_Config + DAQmx_DIO_WriteNewData DAQmx_Scan DAQmx_WaveformGen + DPSS DSPDetrend DSPPeriodogram DWT Debugger + DebuggerOptions DefaultFont DefaultGuiControls + DefaultGuiFont DefaultTextEncoding DefineGuide + DelayUpdate DeleteAnnotations DeleteFile DeleteFolder + DeletePoints Differentiate Display DisplayHelpTopic + DisplayProcedure DoAlert DoIgorMenu DoUpdate DoWindow + DoXOPIdle DrawAction DrawArc DrawBezier DrawLine + DrawOval DrawPICT DrawPoly DrawRRect DrawRect DrawText + DrawUserShape Duplicate DuplicateDataFolder EdgeStats + Edit ErrorBars EstimatePeakSizes Execute + ExecuteScriptText ExperimentInfo ExperimentModified + ExportGizmo Extract FBinRead FBinWrite FFT FGetPos + FIFO2Wave FIFOStatus FMaxFlat FPClustering FReadLine + FSetPos FStatus FTPCreateDirectory FTPDelete + FTPDownload FTPUpload FastGaussTransform FastOp + FilterFIR FilterIIR FindAPeak FindContour + FindDuplicates FindLevel FindLevels FindPeak + FindPointsInPoly FindRoots FindSequence FindValue + FuncFit FuncFitMD GBLoadWave GISCreateVectorLayer + GISGetRasterInfo GISGetRegisteredFileInfo + GISGetVectorLayerInfo GISLoadRasterData + GISLoadVectorData GISRasterizeVectorData + GISRegisterFile GISTransformCoords GISUnRegisterFile + GISWriteFieldData GISWriteGeometryData GISWriteRaster + GPIB2 GPIBRead2 GPIBReadBinary2 GPIBReadBinaryWave2 + GPIBReadWave2 GPIBWrite2 GPIBWriteBinary2 + GPIBWriteBinaryWave2 GPIBWriteWave2 GetAxis GetCamera + GetFileFolderInfo GetGizmo GetLastUserMenuInfo + GetMarquee GetMouse GetSelection GetWindow GraphNormal + GraphWaveDraw GraphWaveEdit Grep GroupBox + HDF5CloseFile HDF5CloseGroup HDF5ConvertColors + HDF5CreateFile HDF5CreateGroup HDF5CreateLink HDF5Dump + HDF5DumpErrors HDF5DumpState HDF5FlushFile + HDF5ListAttributes HDF5ListGroup HDF5LoadData + HDF5LoadGroup HDF5LoadImage HDF5OpenFile HDF5OpenGroup + HDF5SaveData HDF5SaveGroup HDF5SaveImage + HDF5TestOperation HDF5UnlinkObject HDFInfo + HDFReadImage HDFReadSDS HDFReadVset Hanning + HideIgorMenus HideInfo HideProcedures HideTools + HilbertTransform Histogram ICA IFFT ITCCloseAll2 + ITCCloseDevice2 ITCConfigAllChannels2 + ITCConfigChannel2 ITCConfigChannelReset2 + ITCConfigChannelUpload2 ITCFIFOAvailable2 + ITCFIFOAvailableAll2 ITCGetAllChannelsConfig2 + ITCGetChannelConfig2 ITCGetCurrentDevice2 + ITCGetDeviceInfo2 ITCGetDevices2 ITCGetErrorString2 + ITCGetSerialNumber2 ITCGetState2 ITCGetVersions2 + ITCInitialize2 ITCOpenDevice2 ITCReadADC2 + ITCReadDigital2 ITCReadTimer2 ITCSelectDevice2 + ITCSetDAC2 ITCSetGlobals2 ITCSetModes2 ITCSetState2 + ITCStartAcq2 ITCStopAcq2 ITCUpdateFIFOPosition2 + ITCUpdateFIFOPositionAll2 ITCWriteDigital2 + ImageAnalyzeParticles ImageBlend ImageBoundaryToMask + ImageComposite ImageEdgeDetection ImageFileInfo + ImageFilter ImageFocus ImageFromXYZ ImageGLCM + ImageGenerateROIMask ImageHistModification + ImageHistogram ImageInterpolate ImageLineProfile + ImageLoad ImageMorphology ImageRegistration + ImageRemoveBackground ImageRestore ImageRotate + ImageSave ImageSeedFill ImageSkeleton3d ImageSnake + ImageStats ImageThreshold ImageTransform + ImageUnwrapPhase ImageWindow IndexSort InsertPoints + Integrate Integrate2D IntegrateODE Interp3DPath + Interpolate2 Interpolate3D JCAMPLoadWave + JointHistogram KMeans KillBackground KillControl + KillDataFolder KillFIFO KillFreeAxis KillPICTs + KillPath KillStrings KillVariables KillWaves + KillWindow Label Layout LayoutPageAction + LayoutSlideShow Legend LinearFeedbackShiftRegister + ListBox LoadData LoadPICT LoadPackagePreferences + LoadWave Loess LombPeriodogram MCC_FindServers + MFR_CheckForNewBricklets MFR_CloseResultFile + MFR_CreateOverviewTable MFR_GetBrickletCount + MFR_GetBrickletData MFR_GetBrickletDeployData + MFR_GetBrickletMetaData MFR_GetBrickletRawData + MFR_GetReportTemplate MFR_GetResultFileMetaData + MFR_GetResultFileName MFR_GetVernissageVersion + MFR_GetVersion MFR_GetXOPErrorMessage + MFR_OpenResultFile + MLLoadWave Make MakeIndex MarkPerfTestTime + MatrixConvolve MatrixCorr MatrixEigenV MatrixFilter + MatrixGLM MatrixGaussJ MatrixInverse MatrixLLS + MatrixLUBkSub MatrixLUD MatrixLUDTD MatrixLinearSolve + MatrixLinearSolveTD MatrixMultiply MatrixOP + MatrixSVBkSub MatrixSVD MatrixSchur MatrixSolve + MatrixTranspose MeasureStyledText Modify ModifyBoxPlot + ModifyBrowser ModifyCamera ModifyContour ModifyControl + ModifyControlList ModifyFreeAxis ModifyGizmo + ModifyGraph ModifyImage ModifyLayout ModifyPanel + ModifyTable ModifyViolinPlot ModifyWaterfall + MoveDataFolder MoveFile MoveFolder MoveString + MoveSubwindow MoveVariable MoveWave MoveWindow + MultiTaperPSD MultiThreadingControl NC_CloseFile + NC_DumpErrors NC_Inquire NC_ListAttributes + NC_ListObjects NC_LoadData NC_OpenFile NI4882 + NILoadWave NeuralNetworkRun NeuralNetworkTrain + NewCamera NewDataFolder NewFIFO NewFIFOChan + NewFreeAxis NewGizmo NewImage NewLayout NewMovie + NewNotebook NewPanel NewPath NewWaterfall Note + Notebook NotebookAction Open OpenHelp OpenNotebook + Optimize PCA ParseOperationTemplate PathInfo + PauseForUser PauseUpdate PlayMovie PlayMovieAction + PlaySound PopupContextualMenu PopupMenu Preferences + PrimeFactors Print PrintGraphs PrintLayout + PrintNotebook PrintSettings PrintTable Project + PulseStats PutScrapText Quit RatioFromNumber + Redimension Remez Remove RemoveContour RemoveFromGizmo + RemoveFromGraph RemoveFromLayout RemoveFromTable + RemoveImage RemoveLayoutObjects RemovePath Rename + RenameDataFolder RenamePICT RenamePath RenameWindow + ReorderImages ReorderTraces ReplaceText ReplaceWave + Resample ResumeUpdate Reverse Rotate SQLHighLevelOp + STFT Save SaveData SaveExperiment SaveGizmoCopy + SaveGraphCopy SaveNotebook SavePICT + SavePackagePreferences SaveTableCopy + SetActiveSubwindow SetAxis SetBackground + SetDashPattern SetDataFolder SetDimLabel SetDrawEnv + SetDrawLayer SetFileFolderInfo SetFormula + SetIdlePeriod SetIgorHook SetIgorMenuMode + SetIgorOption SetMarquee SetProcessSleep SetRandomSeed + SetScale SetVariable SetWaveLock SetWaveTextEncoding + SetWindow ShowIgorMenus ShowInfo ShowTools Silent + Sleep Slider Smooth SmoothCustom Sort SortColumns + SoundInRecord SoundInSet SoundInStartChart + SoundInStatus SoundInStopChart SoundLoadWave + SoundSaveWave SphericalInterpolate + SphericalTriangulate SplitString SplitWave Stack + StackWindows StatsANOVA1Test StatsANOVA2NRTest + StatsANOVA2RMTest StatsANOVA2Test + StatsAngularDistanceTest StatsChiTest + StatsCircularCorrelationTest StatsCircularMeans + StatsCircularMoments StatsCircularTwoSampleTest + StatsCochranTest StatsContingencyTable StatsDIPTest + StatsDunnettTest StatsFTest StatsFriedmanTest + StatsHodgesAjneTest StatsJBTest StatsKDE StatsKSTest + StatsKWTest StatsKendallTauTest + StatsLinearCorrelationTest StatsLinearRegression + StatsMultiCorrelationTest StatsNPMCTest + StatsNPNominalSRTest StatsQuantiles + StatsRankCorrelationTest StatsResample StatsSRTest + StatsSample StatsScheffeTest StatsShapiroWilkTest + StatsSignTest StatsTTest StatsTukeyTest + StatsVariancesTest StatsWRCorrelationTest + StatsWatsonUSquaredTest StatsWatsonWilliamsTest + StatsWheelerWatsonTest StatsWilcoxonRankTest String + StructFill StructGet StructPut SumDimension SumSeries + TDMLoadData TDMSaveData TabControl Tag TextBox + ThreadGroupPutDF ThreadStart TickWavesFromAxis Tile + TileWindows TitleBox ToCommandLine ToolsGrid + Triangulate3d URLRequest Unwrap VDT2 VDTClosePort2 + VDTGetPortList2 VDTGetStatus2 VDTOpenPort2 + VDTOperationsPort2 VDTRead2 VDTReadBinary2 + VDTReadBinaryWave2 VDTReadHex2 VDTReadHexWave2 + VDTReadWave2 VDTTerminalPort2 VDTWrite2 + VDTWriteBinary2 VDTWriteBinaryWave2 VDTWriteHex2 + VDTWriteHexWave2 VDTWriteWave2 VISAControl VISARead + VISAReadBinary VISAReadBinaryWave VISAReadWave + VISAWrite VISAWriteBinary VISAWriteBinaryWave + VISAWriteWave ValDisplay Variable WaveMeanStdv + WaveStats WaveTransform WignerTransform WindowFunction + XLLoadWave cd dir fprintf printf pwd sprintf sscanf + wfprintf + ) + end + + def self.object_name + /\b[a-z][a-z0-9_\.]*?\b/i + end + + object = self.object_name + noLineBreak = /(?:[ \t]|(?:\\\s*[\r\n]))+/ + operator = %r([\#$~!%^&*+=\|?:<>/-]) + punctuation = /[{}()\[\],.;]/ + number_float= /0x[a-f0-9]+/i + number_hex = /\d+\.\d+(e[\+\-]?\d+)?/ + number_int = /[\d]+(?:_\d+)*/ + + state :root do + rule %r(//), Comment, :comments + + rule %r/#{object}/ do |m| + if m[0].downcase =~ /function/ + token Keyword::Declaration + push :parse_function + elsif self.class.igorDeclarations.include? m[0].downcase + token Keyword::Declaration + push :parse_variables + elsif self.class.keywords.include? m[0].downcase + token Keyword + elsif self.class.igorConstants.include? m[0].downcase + token Keyword::Constant + elsif self.class.igorFunction.include? m[0].downcase + token Name::Builtin + elsif self.class.igorOperation.include? m[0].downcase + token Keyword::Reserved + push :operationFlags + elsif m[0].downcase =~ /\b(v|s|w)_[a-z]+[a-z0-9]*/ + token Name::Constant + else + token Name + end + end + + mixin :preprocessor + mixin :waveFlag + + mixin :characters + mixin :numbers + mixin :whitespace + end + + state :preprocessor do + rule %r((\#)(#{object})) do |m| + if self.class.preprocessor.include? m[2].downcase + token Comment::Preproc + else + token Punctuation, m[1] #i.e. ModuleFunctions + token Name, m[2] + end + + + end + end + + state :assignment do + mixin :whitespace + rule %r/\"/, Literal::String::Double, :string1 #punctuation for string + mixin :string2 + rule %r/#{number_float}/, Literal::Number::Float, :pop! + rule %r/#{number_int}/, Literal::Number::Integer, :pop! + rule %r/[\(\[\{][^\)\]\}]+[\)\]\}]/, Generic, :pop! + rule %r/[^\s\/\(]+/, Generic, :pop! + rule(//) { pop! } + end + + state :parse_variables do + mixin :whitespace + rule %r/[=]/, Punctuation, :assignment + rule object, Name::Variable + rule %r/[\[\]]/, Punctuation # optional variables in functions + rule %r/[,]/, Punctuation, :parse_variables + rule %r/\)/, Punctuation, :pop! # end of function + rule %r([/][a-z]+)i, Keyword::Pseudo, :parse_variables + rule(//) { pop! } + end + + state :parse_function do + rule %r([/][a-z]+)i, Keyword::Pseudo # only one flag + mixin :whitespace + rule object, Name::Function + rule %r/[\(]/, Punctuation, :parse_variables + rule(//) { pop! } + end + + state :operationFlags do + rule %r/#{noLineBreak}/, Text + rule %r/[=]/, Punctuation, :assignment + rule %r([/][a-z]+)i, Keyword::Pseudo, :operationFlags + rule %r/(as)(\s*)(#{object})/i do + groups Keyword::Type, Text, Name::Label + end + rule(//) { pop! } + end + + # inline variable assignments (i.e. for Make) with strict syntax + state :waveFlag do + rule %r( + (/(?:wave|X|Y)) + (\s*)(=)(\s*) + (#{object}) + )ix do |m| + token Keyword::Pseudo, m[1] + token Text, m[2] + token Punctuation, m[3] + token Text, m[4] + token Name::Variable, m[5] + end + end + + state :characters do + rule %r/\s/, Text + rule %r/#{operator}/, Operator + rule %r/#{punctuation}/, Punctuation + rule %r/\"/, Literal::String::Double, :string1 #punctuation for string + mixin :string2 + end + + state :numbers do + rule %r/#{number_float}/, Literal::Number::Float + rule %r/#{number_hex}/, Literal::Number::Hex + rule %r/#{number_int}/, Literal::Number::Integer + end + + state :whitespace do + rule %r/#{noLineBreak}/, Text + end + + state :string1 do + rule %r/%\w\b/, Literal::String::Other + rule %r/\\\\/, Literal::String::Escape + rule %r/\\\"/, Literal::String::Escape + rule %r/\\/, Literal::String::Escape + rule %r/[^"]/, Literal::String + rule %r/\"/, Literal::String::Double, :pop! #punctuation for string + end + + state :string2 do + rule %r/\'[^']*\'/, Literal::String::Single + end + + state :comments do + rule %r{([/]\s*)([@]\w+\b)}i do + # doxygen comments + groups Comment, Comment::Special + end + rule %r/[^\r\n]/, Comment + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ini.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ini.rb new file mode 100644 index 0000000..500167e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ini.rb @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class INI < RegexLexer + title "INI" + desc 'the INI configuration format' + tag 'ini' + + filenames '*.ini', '*.INI', '*.gitconfig', '*.cfg', '.editorconfig', '*.inf' + mimetypes 'text/x-ini', 'text/inf' + + identifier = /[\w\-.]+/ + + state :basic do + rule %r/\s+/, Text::Whitespace + rule %r/[;#].*?\n/, Comment + rule %r/\\\n/, Str::Escape + end + + state :root do + mixin :basic + + rule %r/(#{identifier})(\s*)(=)/ do + groups Name::Property, Text::Whitespace, Punctuation + push :value + end + + rule %r/\[.*?\]/, Name::Namespace + + # standalone option, supported by some INI parsers + rule %r/(.+?)/, Name::Attribute + end + + state :value do + rule %r/\n/, Text, :pop! + mixin :basic + rule %r/"/, Str, :dq + rule %r/'.*?'/, Str + mixin :esc_str + rule %r/[^\\\n]+/, Str + end + + state :dq do + rule %r/"/, Str, :pop! + mixin :esc_str + rule %r/[^\\"]+/m, Str + end + + state :esc_str do + rule %r/\\./m, Str::Escape + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/io.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/io.rb new file mode 100644 index 0000000..9e049a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/io.rb @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class IO < RegexLexer + tag 'io' + title "Io" + desc 'The IO programming language (http://iolanguage.com)' + mimetypes 'text/x-iosrc' + filenames '*.io' + + def self.detect?(text) + return true if text.shebang? 'io' + end + + def self.constants + @constants ||= Set.new %w(nil false true) + end + + def self.builtins + @builtins ||= Set.new %w( + args call clone do doFile doString else elseif for if list + method return super then + ) + end + + state :root do + rule %r/\s+/m, Text + rule %r(//.*), Comment::Single + rule %r(#.*), Comment::Single + rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline + rule %r(/[+]), Comment::Multiline, :nested_comment + + rule %r/"(\\\\|\\"|[^"])*"/, Str + + rule %r(:?:=), Keyword + rule %r/[()]/, Punctuation + + rule %r([-=;,*+>"*] | + [>"*]> + ) + )x + end + + def allow_comments? + true + end + end + + load_lexer 'ruby.rb' + class IRBOutputLexer < Ruby + tag 'irb_output' + + start do + push :stdout + end + + state :has_irb_output do + rule %r(=>), Punctuation, :pop! + rule %r/.+?(\n|$)/, Generic::Output + end + + state :irb_error do + rule %r/.+?(\n|$)/, Generic::Error + mixin :has_irb_output + end + + state :stdout do + rule %r/\w+?(Error|Exception):.+?(\n|$)/, Generic::Error, :irb_error + mixin :has_irb_output + end + + prepend :root do + rule %r/#/, Keyword::Type, :pop! + mixin :root + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isabelle.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isabelle.rb new file mode 100644 index 0000000..6b97b22 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isabelle.rb @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true +# Lexer adapted from https://github.com/pygments/pygments/blob/ad55974ce83b85dbb333ab57764415ab84169461/pygments/lexers/theorem.py + +module Rouge + module Lexers + class Isabelle < RegexLexer + title "Isabelle" + desc 'Isabelle theories (isabelle.in.tum.de)' + tag 'isabelle' + aliases 'isa', 'Isabelle' + filenames '*.thy' + mimetypes 'text/x-isabelle' + + def self.keyword_minor + @keyword_minor ||= Set.new %w( + and assumes attach avoids binder checking + class_instance class_relation code_module congs + constant constrains datatypes defines file fixes + for functions hints identifier if imports in + includes infix infixl infixr is keywords lazy + module_name monos morphisms no_discs_sels notes + obtains open output overloaded parametric permissive + pervasive rep_compat shows structure type_class + type_constructor unchecked unsafe where + ) + end + + def self.keyword_diag + @keyword_diag ||= Set.new %w( + ML_command ML_val class_deps code_deps code_thms + display_drafts find_consts find_theorems find_unused_assms + full_prf help locale_deps nitpick pr prf + print_abbrevs print_antiquotations print_attributes + print_binds print_bnfs print_bundles + print_case_translations print_cases print_claset + print_classes print_codeproc print_codesetup + print_coercions print_commands print_context + print_defn_rules print_dependencies print_facts + print_induct_rules print_inductives print_interps + print_locale print_locales print_methods print_options + print_orders print_quot_maps print_quotconsts + print_quotients print_quotientsQ3 print_quotmapsQ3 + print_rules print_simpset print_state print_statement + print_syntax print_theorems print_theory print_trans_rules + prop pwd quickcheck refute sledgehammer smt_status + solve_direct spark_status term thm thm_deps thy_deps + try try0 typ unused_thms value values welcome + print_ML_antiquotations print_term_bindings values_prolog + ) + end + + def self.keyword_thy + @keyword_thy ||= Set.new %w(theory begin end) + end + + def self.keyword_section + @keyword_section ||= Set.new %w(header chapter) + end + + def self.keyword_subsection + @keyword_subsection ||= Set.new %w(section subsection subsubsection sect subsect subsubsect) + end + + def self.keyword_theory_decl + @keyword_theory_decl ||= Set.new %w( + ML ML_file abbreviation adhoc_overloading arities + atom_decl attribute_setup axiomatization bundle + case_of_simps class classes classrel codatatype + code_abort code_class code_const code_datatype + code_identifier code_include code_instance code_modulename + code_monad code_printing code_reflect code_reserved + code_type coinductive coinductive_set consts context + datatype datatype_new datatype_new_compat declaration + declare default_sort defer_recdef definition defs + domain domain_isomorphism domaindef equivariance + export_code extract extract_type fixrec fun + fun_cases hide_class hide_const hide_fact hide_type + import_const_map import_file import_tptp import_type_map + inductive inductive_set instantiation judgment lemmas + lifting_forget lifting_update local_setup locale + method_setup nitpick_params no_adhoc_overloading + no_notation no_syntax no_translations no_type_notation + nominal_datatype nonterminal notation notepad oracle + overloading parse_ast_translation parse_translation + partial_function primcorec primrec primrec_new + print_ast_translation print_translation quickcheck_generator + quickcheck_params realizability realizers recdef record + refute_params setup setup_lifting simproc_setup + simps_of_case sledgehammer_params spark_end spark_open + spark_open_siv spark_open_vcg spark_proof_functions + spark_types statespace syntax syntax_declaration text + text_raw theorems translations type_notation + type_synonym typed_print_translation typedecl hoarestate + install_C_file install_C_types wpc_setup c_defs c_types + memsafe SML_export SML_file SML_import approximate + bnf_axiomatization cartouche datatype_compat + free_constructors functor nominal_function + nominal_termination permanent_interpretation + binds defining smt2_status term_cartouche + boogie_file text_cartouche + ) + end + + def self.keyword_theory_script + @keyword_theory_script ||= Set.new %w(inductive_cases inductive_simps) + end + + def self.keyword_theory_goal + @keyword_theory_goal ||= Set.new %w( + ax_specification bnf code_pred corollary cpodef + crunch crunch_ignore + enriched_type function instance interpretation lemma + lift_definition nominal_inductive nominal_inductive2 + nominal_primrec pcpodef primcorecursive + quotient_definition quotient_type recdef_tc rep_datatype + schematic_corollary schematic_lemma schematic_theorem + spark_vc specification subclass sublocale termination + theorem typedef wrap_free_constructors + ) + end + + def self.keyword_qed + @keyword_qed ||= Set.new %w(by done qed) + end + + def self.keyword_abandon_proof + @keyword_abandon_proof ||= Set.new %w(sorry oops) + end + + def self.keyword_proof_goal + @keyword_proof_goal ||= Set.new %w(have hence interpret) + end + + def self.keyword_proof_block + @keyword_proof_block ||= Set.new %w(next proof) + end + + def self.keyword_proof_chain + @keyword_proof_chain ||= Set.new %w(finally from then ultimately with) + end + + def self.keyword_proof_decl + @keyword_proof_decl ||= Set.new %w( + ML_prf also include including let moreover note + txt txt_raw unfolding using write + ) + end + + def self.keyword_proof_asm + @keyword_proof_asm ||= Set.new %w(assume case def fix presume) + end + + def self.keyword_proof_asm_goal + @keyword_proof_asm_goal ||= Set.new %w(guess obtain show thus) + end + + def self.keyword_proof_script + @keyword_proof_script ||= Set.new %w(apply apply_end apply_trace back defer prefer) + end + + state :root do + rule %r/\s+/, Text::Whitespace + rule %r/\(\*/, Comment, :comment + rule %r/\{\*|‹/, Text, :text + + rule %r/::|\[|\]|-|[:()_=,|+!?]/, Operator + rule %r/[{}.]|\.\./, Operator::Word + + def word(keywords) + return %r/\b(#{keywords.join('|')})\b/ + end + + rule %r/[a-zA-Z]\w*/ do |m| + sym = m[0] + + if self.class.keyword_minor.include?(sym) || + self.class.keyword_proof_script.include?(sym) + token Keyword::Pseudo + elsif self.class.keyword_diag.include?(sym) + token Keyword::Type + elsif self.class.keyword_thy.include?(sym) || + self.class.keyword_theory_decl.include?(sym) || + self.class.keyword_qed.include?(sym) || + self.class.keyword_proof_goal.include?(sym) || + self.class.keyword_proof_block.include?(sym) || + self.class.keyword_proof_decl.include?(sym) || + self.class.keyword_proof_chain.include?(sym) || + self.class.keyword_proof_asm.include?(sym) || + self.class.keyword_proof_asm_goal.include?(sym) + token Keyword + elsif self.class.keyword_section.include?(sym) + token Generic::Heading + elsif self.class.keyword_subsection.include?(sym) + token Generic::Subheading + elsif self.class.keyword_theory_goal.include?(sym) || + self.class.keyword_theory_script.include?(sym) + token Keyword::Namespace + elsif self.class.keyword_abandon_proof.include?(sym) + token Generic::Error + else + token Name + end + end + + rule %r/\\<\w*>/, Str::Symbol + + rule %r/'[^\W\d][.\w']*/, Name::Variable + + rule %r/0[xX][\da-fA-F][\da-fA-F_]*/, Num::Hex + rule %r/0[oO][0-7][0-7_]*/, Num::Oct + rule %r/0[bB][01][01_]*/, Num::Bin + + rule %r/"/, Str, :string + rule %r/`/, Str::Other, :fact + # Everything except for (most) operators whitespaces may be name + rule %r/[^\s:|\[\]\-()=,+!?{}._][^\s:|\[\]\-()=,+!?{}]*/, Name + end + + state :comment do + rule %r/[^(*)]+/, Comment + rule %r/\(\*/, Comment, :comment + rule %r/\*\)/, Comment, :pop! + rule %r/[(*)]/, Comment + end + + state :text do + rule %r/[^{*}‹›]+/, Text + rule %r/\{\*|‹/, Text, :text + rule %r/\*\}|›/, Text, :pop! + rule %r/[{*}]/, Text + end + + state :string do + rule %r/[^"\\]+/, Str + rule %r/\\<\w*>/, Str::Symbol + rule %r/\\"/, Str + rule %r/\\/, Str + rule %r/"/, Str, :pop! + end + + state :fact do + rule %r/[^`\\]+/, Str::Other + rule %r/\\<\w*>/, Str::Symbol + rule %r/\\`/, Str::Other + rule %r/\\/, Str::Other + rule %r/`/, Str::Other, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl.rb new file mode 100644 index 0000000..2e1184b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl.rb @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class ISBL < RegexLexer + title "ISBL" + desc "The ISBL programming language" + tag 'isbl' + filenames '*.isbl' + + def self.builtins + Kernel::load File.join(Lexers::BASE_DIR, 'isbl/builtins.rb') + self.builtins + end + + def self.constants + @constants ||= self.builtins["const"].merge(self.builtins["enum"]).collect!(&:downcase) + end + + def self.interfaces + @interfaces ||= self.builtins["interface"].collect!(&:downcase) + end + + def self.globals + @globals ||= self.builtins["global"].collect!(&:downcase) + end + + def self.keywords + @keywords = Set.new %w( + and и else иначе endexcept endfinally endforeach конецвсе endif конецесли endwhile + конецпока except exitfor finally foreach все if если in в not не or или try while пока + ) + end + + state :whitespace do + rule %r/\s+/m, Text + rule %r(//.*?$), Comment::Single + rule %r(/[*].*?[*]/)m, Comment::Multiline + end + + state :dotted do + mixin :whitespace + rule %r/[a-zа-яё_0-9]+/i do |m| + name = m[0] + if self.class.constants.include? name.downcase + token Name::Builtin + elsif in_state? :type + token Keyword::Type + else + token Name + end + pop! + end + end + + state :type do + mixin :whitespace + rule %r/[a-zа-яё_0-9]+/i do |m| + name = m[0] + if self.class.interfaces.include? name.downcase + token Keyword::Type + else + token Name + end + pop! + end + rule %r/[.]/, Punctuation, :dotted + rule(//) { pop! } + end + + state :root do + mixin :whitespace + rule %r/[:]/, Punctuation, :type + rule %r/[.]/, Punctuation, :dotted + rule %r/[\[\]();]/, Punctuation + rule %r([&*+=<>/-]), Operator + rule %r/\b[a-zа-яё_][a-zа-яё_0-9]*(?=[(])/i, Name::Function + rule %r/[a-zа-яё_!][a-zа-яё_0-9]*/i do |m| + name = m[0] + if self.class.keywords.include? name.downcase + token Keyword + elsif self.class.constants.include? name.downcase + token Name::Builtin + elsif self.class.globals.include? name.downcase + token Name::Variable::Global + else + token Name::Variable + end + end + rule %r/\b(\d+(\.\d+)?)\b/, Literal::Number + rule %r(["].*?["])m, Literal::String::Double + rule %r(['].*?['])m, Literal::String::Single + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl/builtins.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl/builtins.rb new file mode 100644 index 0000000..5e9eeeb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/isbl/builtins.rb @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class ISBL + def self.builtins + @builtins ||= {}.tap do |b| + b["const"] = Set.new %w(SYSRES_CONST_ACCES_RIGHT_TYPE_EDIT SYSRES_CONST_ACCES_RIGHT_TYPE_FULL SYSRES_CONST_ACCES_RIGHT_TYPE_VIEW SYSRES_CONST_ACCESS_MODE_REQUISITE_CODE SYSRES_CONST_ACCESS_NO_ACCESS_VIEW SYSRES_CONST_ACCESS_NO_ACCESS_VIEW_CODE SYSRES_CONST_ACCESS_RIGHTS_ADD_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_ADD_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_CHANGE_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_CHANGE_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_DELETE_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_DELETE_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_EXECUTE_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_EXECUTE_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_NO_ACCESS_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_NO_ACCESS_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_RATIFY_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_RATIFY_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_VIEW SYSRES_CONST_ACCESS_RIGHTS_VIEW_CODE SYSRES_CONST_ACCESS_RIGHTS_VIEW_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_VIEW_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_TYPE_CHANGE SYSRES_CONST_ACCESS_TYPE_CHANGE_CODE SYSRES_CONST_ACCESS_TYPE_EXISTS SYSRES_CONST_ACCESS_TYPE_EXISTS_CODE SYSRES_CONST_ACCESS_TYPE_FULL SYSRES_CONST_ACCESS_TYPE_FULL_CODE SYSRES_CONST_ACCESS_TYPE_VIEW SYSRES_CONST_ACCESS_TYPE_VIEW_CODE SYSRES_CONST_ACTION_TYPE_ABORT SYSRES_CONST_ACTION_TYPE_ACCEPT SYSRES_CONST_ACTION_TYPE_ACCESS_RIGHTS SYSRES_CONST_ACTION_TYPE_ADD_ATTACHMENT SYSRES_CONST_ACTION_TYPE_CHANGE_CARD SYSRES_CONST_ACTION_TYPE_CHANGE_KIND SYSRES_CONST_ACTION_TYPE_CHANGE_STORAGE SYSRES_CONST_ACTION_TYPE_CONTINUE SYSRES_CONST_ACTION_TYPE_COPY SYSRES_CONST_ACTION_TYPE_CREATE SYSRES_CONST_ACTION_TYPE_CREATE_VERSION SYSRES_CONST_ACTION_TYPE_DELETE SYSRES_CONST_ACTION_TYPE_DELETE_ATTACHMENT SYSRES_CONST_ACTION_TYPE_DELETE_VERSION SYSRES_CONST_ACTION_TYPE_DISABLE_DELEGATE_ACCESS_RIGHTS SYSRES_CONST_ACTION_TYPE_ENABLE_DELEGATE_ACCESS_RIGHTS SYSRES_CONST_ACTION_TYPE_ENCRYPTION_BY_CERTIFICATE SYSRES_CONST_ACTION_TYPE_ENCRYPTION_BY_CERTIFICATE_AND_PASSWORD SYSRES_CONST_ACTION_TYPE_ENCRYPTION_BY_PASSWORD SYSRES_CONST_ACTION_TYPE_EXPORT_WITH_LOCK SYSRES_CONST_ACTION_TYPE_EXPORT_WITHOUT_LOCK SYSRES_CONST_ACTION_TYPE_IMPORT_WITH_UNLOCK SYSRES_CONST_ACTION_TYPE_IMPORT_WITHOUT_UNLOCK SYSRES_CONST_ACTION_TYPE_LIFE_CYCLE_STAGE SYSRES_CONST_ACTION_TYPE_LOCK SYSRES_CONST_ACTION_TYPE_LOCK_FOR_SERVER SYSRES_CONST_ACTION_TYPE_LOCK_MODIFY SYSRES_CONST_ACTION_TYPE_MARK_AS_READED SYSRES_CONST_ACTION_TYPE_MARK_AS_UNREADED SYSRES_CONST_ACTION_TYPE_MODIFY SYSRES_CONST_ACTION_TYPE_MODIFY_CARD SYSRES_CONST_ACTION_TYPE_MOVE_TO_ARCHIVE SYSRES_CONST_ACTION_TYPE_OFF_ENCRYPTION SYSRES_CONST_ACTION_TYPE_PASSWORD_CHANGE SYSRES_CONST_ACTION_TYPE_PERFORM SYSRES_CONST_ACTION_TYPE_RECOVER_FROM_LOCAL_COPY SYSRES_CONST_ACTION_TYPE_RESTART SYSRES_CONST_ACTION_TYPE_RESTORE_FROM_ARCHIVE SYSRES_CONST_ACTION_TYPE_REVISION SYSRES_CONST_ACTION_TYPE_SEND_BY_MAIL SYSRES_CONST_ACTION_TYPE_SIGN SYSRES_CONST_ACTION_TYPE_START SYSRES_CONST_ACTION_TYPE_UNLOCK SYSRES_CONST_ACTION_TYPE_UNLOCK_FROM_SERVER SYSRES_CONST_ACTION_TYPE_VERSION_STATE SYSRES_CONST_ACTION_TYPE_VERSION_VISIBILITY SYSRES_CONST_ACTION_TYPE_VIEW SYSRES_CONST_ACTION_TYPE_VIEW_SHADOW_COPY SYSRES_CONST_ACTION_TYPE_WORKFLOW_DESCRIPTION_MODIFY SYSRES_CONST_ACTION_TYPE_WRITE_HISTORY SYSRES_CONST_ACTIVE_VERSION_STATE_PICK_VALUE SYSRES_CONST_ADD_REFERENCE_MODE_NAME SYSRES_CONST_ADDITION_REQUISITE_CODE SYSRES_CONST_ADDITIONAL_PARAMS_REQUISITE_CODE SYSRES_CONST_ADITIONAL_JOB_END_DATE_REQUISITE_NAME SYSRES_CONST_ADITIONAL_JOB_READ_REQUISITE_NAME SYSRES_CONST_ADITIONAL_JOB_START_DATE_REQUISITE_NAME SYSRES_CONST_ADITIONAL_JOB_STATE_REQUISITE_NAME SYSRES_CONST_ADMINISTRATION_HISTORY_ADDING_USER_TO_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_ADDING_USER_TO_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_COMP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_COMP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_USER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_USER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_CREATION SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_CREATION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_DELETION SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_DELETION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_COMP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_COMP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_FROM_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_FROM_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_RESTRICTION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_RESTRICTION_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_PRIVILEGE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_PRIVILEGE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_RIGHTS_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_RIGHTS_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_IS_MAIN_SERVER_CHANGED_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_IS_MAIN_SERVER_CHANGED_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_IS_PUBLIC_CHANGED_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_IS_PUBLIC_CHANGED_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_RESTRICTION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_RESTRICTION_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_PRIVILEGE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_PRIVILEGE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_RIGHTS_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_RIGHTS_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_CREATION SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_CREATION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_DELETION SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_DELETION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_CATEGORY_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_CATEGORY_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_COMP_TITLE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_COMP_TITLE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_FULL_NAME_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_FULL_NAME_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_PARENT_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_PARENT_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_AUTH_TYPE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_AUTH_TYPE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_LOGIN_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_LOGIN_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_STATUS_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_STATUS_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_USER_PASSWORD_CHANGE SYSRES_CONST_ADMINISTRATION_HISTORY_USER_PASSWORD_CHANGE_ACTION SYSRES_CONST_ALL_ACCEPT_CONDITION_RUS SYSRES_CONST_ALL_USERS_GROUP SYSRES_CONST_ALL_USERS_GROUP_NAME SYSRES_CONST_ALL_USERS_SERVER_GROUP_NAME SYSRES_CONST_ALLOWED_ACCESS_TYPE_CODE SYSRES_CONST_ALLOWED_ACCESS_TYPE_NAME SYSRES_CONST_APP_VIEWER_TYPE_REQUISITE_CODE SYSRES_CONST_APPROVING_SIGNATURE_NAME SYSRES_CONST_APPROVING_SIGNATURE_REQUISITE_CODE SYSRES_CONST_ASSISTANT_SUBSTITUE_TYPE SYSRES_CONST_ASSISTANT_SUBSTITUE_TYPE_CODE SYSRES_CONST_ATTACH_TYPE_COMPONENT_TOKEN SYSRES_CONST_ATTACH_TYPE_DOC SYSRES_CONST_ATTACH_TYPE_EDOC SYSRES_CONST_ATTACH_TYPE_FOLDER SYSRES_CONST_ATTACH_TYPE_JOB SYSRES_CONST_ATTACH_TYPE_REFERENCE SYSRES_CONST_ATTACH_TYPE_TASK SYSRES_CONST_AUTH_ENCODED_PASSWORD SYSRES_CONST_AUTH_ENCODED_PASSWORD_CODE SYSRES_CONST_AUTH_NOVELL SYSRES_CONST_AUTH_PASSWORD SYSRES_CONST_AUTH_PASSWORD_CODE SYSRES_CONST_AUTH_WINDOWS SYSRES_CONST_AUTHENTICATING_SIGNATURE_NAME SYSRES_CONST_AUTHENTICATING_SIGNATURE_REQUISITE_CODE SYSRES_CONST_AUTO_ENUM_METHOD_FLAG SYSRES_CONST_AUTO_NUMERATION_CODE SYSRES_CONST_AUTO_STRONG_ENUM_METHOD_FLAG SYSRES_CONST_AUTOTEXT_NAME_REQUISITE_CODE SYSRES_CONST_AUTOTEXT_TEXT_REQUISITE_CODE SYSRES_CONST_AUTOTEXT_USAGE_ALL SYSRES_CONST_AUTOTEXT_USAGE_ALL_CODE SYSRES_CONST_AUTOTEXT_USAGE_SIGN SYSRES_CONST_AUTOTEXT_USAGE_SIGN_CODE SYSRES_CONST_AUTOTEXT_USAGE_WORK SYSRES_CONST_AUTOTEXT_USAGE_WORK_CODE SYSRES_CONST_AUTOTEXT_USE_ANYWHERE_CODE SYSRES_CONST_AUTOTEXT_USE_ON_SIGNING_CODE SYSRES_CONST_AUTOTEXT_USE_ON_WORK_CODE SYSRES_CONST_BEGIN_DATE_REQUISITE_CODE SYSRES_CONST_BLACK_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_BLUE_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_BTN_PART SYSRES_CONST_CALCULATED_ROLE_TYPE_CODE SYSRES_CONST_CALL_TYPE_VARIABLE_BUTTON_VALUE SYSRES_CONST_CALL_TYPE_VARIABLE_PROGRAM_VALUE SYSRES_CONST_CANCEL_MESSAGE_FUNCTION_RESULT SYSRES_CONST_CARD_PART SYSRES_CONST_CARD_REFERENCE_MODE_NAME SYSRES_CONST_CERTIFICATE_TYPE_REQUISITE_ENCRYPT_VALUE SYSRES_CONST_CERTIFICATE_TYPE_REQUISITE_SIGN_AND_ENCRYPT_VALUE SYSRES_CONST_CERTIFICATE_TYPE_REQUISITE_SIGN_VALUE SYSRES_CONST_CHECK_PARAM_VALUE_DATE_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_FLOAT_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_INTEGER_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_PICK_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_REEFRENCE_PARAM_TYPE SYSRES_CONST_CLOSED_RECORD_FLAG_VALUE_FEMININE SYSRES_CONST_CLOSED_RECORD_FLAG_VALUE_MASCULINE SYSRES_CONST_CODE_COMPONENT_TYPE_ADMIN SYSRES_CONST_CODE_COMPONENT_TYPE_DEVELOPER SYSRES_CONST_CODE_COMPONENT_TYPE_DOCS SYSRES_CONST_CODE_COMPONENT_TYPE_EDOC_CARDS SYSRES_CONST_CODE_COMPONENT_TYPE_EXTERNAL_EXECUTABLE SYSRES_CONST_CODE_COMPONENT_TYPE_OTHER SYSRES_CONST_CODE_COMPONENT_TYPE_REFERENCE SYSRES_CONST_CODE_COMPONENT_TYPE_REPORT SYSRES_CONST_CODE_COMPONENT_TYPE_SCRIPT SYSRES_CONST_CODE_COMPONENT_TYPE_URL SYSRES_CONST_CODE_REQUISITE_ACCESS SYSRES_CONST_CODE_REQUISITE_CODE SYSRES_CONST_CODE_REQUISITE_COMPONENT SYSRES_CONST_CODE_REQUISITE_DESCRIPTION SYSRES_CONST_CODE_REQUISITE_EXCLUDE_COMPONENT SYSRES_CONST_CODE_REQUISITE_RECORD SYSRES_CONST_COMMENT_REQ_CODE SYSRES_CONST_COMMON_SETTINGS_REQUISITE_CODE SYSRES_CONST_COMP_CODE_GRD SYSRES_CONST_COMPONENT_GROUP_TYPE_REQUISITE_CODE SYSRES_CONST_COMPONENT_TYPE_ADMIN_COMPONENTS SYSRES_CONST_COMPONENT_TYPE_DEVELOPER_COMPONENTS SYSRES_CONST_COMPONENT_TYPE_DOCS SYSRES_CONST_COMPONENT_TYPE_EDOC_CARDS SYSRES_CONST_COMPONENT_TYPE_EDOCS SYSRES_CONST_COMPONENT_TYPE_EXTERNAL_EXECUTABLE SYSRES_CONST_COMPONENT_TYPE_OTHER SYSRES_CONST_COMPONENT_TYPE_REFERENCE_TYPES SYSRES_CONST_COMPONENT_TYPE_REFERENCES SYSRES_CONST_COMPONENT_TYPE_REPORTS SYSRES_CONST_COMPONENT_TYPE_SCRIPTS SYSRES_CONST_COMPONENT_TYPE_URL SYSRES_CONST_COMPONENTS_REMOTE_SERVERS_VIEW_CODE SYSRES_CONST_CONDITION_BLOCK_DESCRIPTION SYSRES_CONST_CONST_FIRM_STATUS_COMMON SYSRES_CONST_CONST_FIRM_STATUS_INDIVIDUAL SYSRES_CONST_CONST_NEGATIVE_VALUE SYSRES_CONST_CONST_POSITIVE_VALUE SYSRES_CONST_CONST_SERVER_STATUS_DONT_REPLICATE SYSRES_CONST_CONST_SERVER_STATUS_REPLICATE SYSRES_CONST_CONTENTS_REQUISITE_CODE SYSRES_CONST_DATA_TYPE_BOOLEAN SYSRES_CONST_DATA_TYPE_DATE SYSRES_CONST_DATA_TYPE_FLOAT SYSRES_CONST_DATA_TYPE_INTEGER SYSRES_CONST_DATA_TYPE_PICK SYSRES_CONST_DATA_TYPE_REFERENCE SYSRES_CONST_DATA_TYPE_STRING SYSRES_CONST_DATA_TYPE_TEXT SYSRES_CONST_DATA_TYPE_VARIANT SYSRES_CONST_DATE_CLOSE_REQ_CODE SYSRES_CONST_DATE_FORMAT_DATE_ONLY_CHAR SYSRES_CONST_DATE_OPEN_REQ_CODE SYSRES_CONST_DATE_REQUISITE SYSRES_CONST_DATE_REQUISITE_CODE SYSRES_CONST_DATE_REQUISITE_NAME SYSRES_CONST_DATE_REQUISITE_TYPE SYSRES_CONST_DATE_TYPE_CHAR SYSRES_CONST_DATETIME_FORMAT_VALUE SYSRES_CONST_DEA_ACCESS_RIGHTS_ACTION_CODE SYSRES_CONST_DESCRIPTION_LOCALIZE_ID_REQUISITE_CODE SYSRES_CONST_DESCRIPTION_REQUISITE_CODE SYSRES_CONST_DET1_PART SYSRES_CONST_DET2_PART SYSRES_CONST_DET3_PART SYSRES_CONST_DET4_PART SYSRES_CONST_DET5_PART SYSRES_CONST_DET6_PART SYSRES_CONST_DETAIL_DATASET_KEY_REQUISITE_CODE SYSRES_CONST_DETAIL_PICK_REQUISITE_CODE SYSRES_CONST_DETAIL_REQ_CODE SYSRES_CONST_DO_NOT_USE_ACCESS_TYPE_CODE SYSRES_CONST_DO_NOT_USE_ACCESS_TYPE_NAME SYSRES_CONST_DO_NOT_USE_ON_VIEW_ACCESS_TYPE_CODE SYSRES_CONST_DO_NOT_USE_ON_VIEW_ACCESS_TYPE_NAME SYSRES_CONST_DOCUMENT_STORAGES_CODE SYSRES_CONST_DOCUMENT_TEMPLATES_TYPE_NAME SYSRES_CONST_DOUBLE_REQUISITE_CODE SYSRES_CONST_EDITOR_CLOSE_FILE_OBSERV_TYPE_CODE SYSRES_CONST_EDITOR_CLOSE_PROCESS_OBSERV_TYPE_CODE SYSRES_CONST_EDITOR_TYPE_REQUISITE_CODE SYSRES_CONST_EDITORS_APPLICATION_NAME_REQUISITE_CODE SYSRES_CONST_EDITORS_CREATE_SEVERAL_PROCESSES_REQUISITE_CODE SYSRES_CONST_EDITORS_EXTENSION_REQUISITE_CODE SYSRES_CONST_EDITORS_OBSERVER_BY_PROCESS_TYPE SYSRES_CONST_EDITORS_REFERENCE_CODE SYSRES_CONST_EDITORS_REPLACE_SPEC_CHARS_REQUISITE_CODE SYSRES_CONST_EDITORS_USE_PLUGINS_REQUISITE_CODE SYSRES_CONST_EDITORS_VIEW_DOCUMENT_OPENED_TO_EDIT_CODE SYSRES_CONST_EDOC_CARD_TYPE_REQUISITE_CODE SYSRES_CONST_EDOC_CARD_TYPES_LINK_REQUISITE_CODE SYSRES_CONST_EDOC_CERTIFICATE_AND_PASSWORD_ENCODE_CODE SYSRES_CONST_EDOC_CERTIFICATE_ENCODE_CODE SYSRES_CONST_EDOC_DATE_REQUISITE_CODE SYSRES_CONST_EDOC_KIND_REFERENCE_CODE SYSRES_CONST_EDOC_KINDS_BY_TEMPLATE_ACTION_CODE SYSRES_CONST_EDOC_MANAGE_ACCESS_CODE SYSRES_CONST_EDOC_NONE_ENCODE_CODE SYSRES_CONST_EDOC_NUMBER_REQUISITE_CODE SYSRES_CONST_EDOC_PASSWORD_ENCODE_CODE SYSRES_CONST_EDOC_READONLY_ACCESS_CODE SYSRES_CONST_EDOC_SHELL_LIFE_TYPE_VIEW_VALUE SYSRES_CONST_EDOC_SIZE_RESTRICTION_PRIORITY_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_CHECK_ACCESS_RIGHTS_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_COMPUTER_NAME_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_DATABASE_NAME_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_EDIT_IN_STORAGE_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_LOCAL_PATH_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_SHARED_SOURCE_NAME_REQUISITE_CODE SYSRES_CONST_EDOC_TEMPLATE_REQUISITE_CODE SYSRES_CONST_EDOC_TYPES_REFERENCE_CODE SYSRES_CONST_EDOC_VERSION_ACTIVE_STAGE_CODE SYSRES_CONST_EDOC_VERSION_DESIGN_STAGE_CODE SYSRES_CONST_EDOC_VERSION_OBSOLETE_STAGE_CODE SYSRES_CONST_EDOC_WRITE_ACCES_CODE SYSRES_CONST_EDOCUMENT_CARD_REQUISITES_REFERENCE_CODE_SELECTED_REQUISITE SYSRES_CONST_ENCODE_CERTIFICATE_TYPE_CODE SYSRES_CONST_END_DATE_REQUISITE_CODE SYSRES_CONST_ENUMERATION_TYPE_REQUISITE_CODE SYSRES_CONST_EXECUTE_ACCESS_RIGHTS_TYPE_CODE SYSRES_CONST_EXECUTIVE_FILE_STORAGE_TYPE SYSRES_CONST_EXIST_CONST SYSRES_CONST_EXIST_VALUE SYSRES_CONST_EXPORT_LOCK_TYPE_ASK SYSRES_CONST_EXPORT_LOCK_TYPE_WITH_LOCK SYSRES_CONST_EXPORT_LOCK_TYPE_WITHOUT_LOCK SYSRES_CONST_EXPORT_VERSION_TYPE_ASK SYSRES_CONST_EXPORT_VERSION_TYPE_LAST SYSRES_CONST_EXPORT_VERSION_TYPE_LAST_ACTIVE SYSRES_CONST_EXTENSION_REQUISITE_CODE SYSRES_CONST_FILTER_NAME_REQUISITE_CODE SYSRES_CONST_FILTER_REQUISITE_CODE SYSRES_CONST_FILTER_TYPE_COMMON_CODE SYSRES_CONST_FILTER_TYPE_COMMON_NAME SYSRES_CONST_FILTER_TYPE_USER_CODE SYSRES_CONST_FILTER_TYPE_USER_NAME SYSRES_CONST_FILTER_VALUE_REQUISITE_NAME SYSRES_CONST_FLOAT_NUMBER_FORMAT_CHAR SYSRES_CONST_FLOAT_REQUISITE_TYPE SYSRES_CONST_FOLDER_AUTHOR_VALUE SYSRES_CONST_FOLDER_KIND_ANY_OBJECTS SYSRES_CONST_FOLDER_KIND_COMPONENTS SYSRES_CONST_FOLDER_KIND_EDOCS SYSRES_CONST_FOLDER_KIND_JOBS SYSRES_CONST_FOLDER_KIND_TASKS SYSRES_CONST_FOLDER_TYPE_COMMON SYSRES_CONST_FOLDER_TYPE_COMPONENT SYSRES_CONST_FOLDER_TYPE_FAVORITES SYSRES_CONST_FOLDER_TYPE_INBOX SYSRES_CONST_FOLDER_TYPE_OUTBOX SYSRES_CONST_FOLDER_TYPE_QUICK_LAUNCH SYSRES_CONST_FOLDER_TYPE_SEARCH SYSRES_CONST_FOLDER_TYPE_SHORTCUTS SYSRES_CONST_FOLDER_TYPE_USER SYSRES_CONST_FROM_DICTIONARY_ENUM_METHOD_FLAG SYSRES_CONST_FULL_SUBSTITUTE_TYPE SYSRES_CONST_FULL_SUBSTITUTE_TYPE_CODE SYSRES_CONST_FUNCTION_CANCEL_RESULT SYSRES_CONST_FUNCTION_CATEGORY_SYSTEM SYSRES_CONST_FUNCTION_CATEGORY_USER SYSRES_CONST_FUNCTION_FAILURE_RESULT SYSRES_CONST_FUNCTION_SAVE_RESULT SYSRES_CONST_GENERATED_REQUISITE SYSRES_CONST_GREEN_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_GROUP_ACCOUNT_TYPE_VALUE_CODE SYSRES_CONST_GROUP_CATEGORY_NORMAL_CODE SYSRES_CONST_GROUP_CATEGORY_NORMAL_NAME SYSRES_CONST_GROUP_CATEGORY_SERVICE_CODE SYSRES_CONST_GROUP_CATEGORY_SERVICE_NAME SYSRES_CONST_GROUP_COMMON_CATEGORY_FIELD_VALUE SYSRES_CONST_GROUP_FULL_NAME_REQUISITE_CODE SYSRES_CONST_GROUP_NAME_REQUISITE_CODE SYSRES_CONST_GROUP_RIGHTS_T_REQUISITE_CODE SYSRES_CONST_GROUP_SERVER_CODES_REQUISITE_CODE SYSRES_CONST_GROUP_SERVER_NAME_REQUISITE_CODE SYSRES_CONST_GROUP_SERVICE_CATEGORY_FIELD_VALUE SYSRES_CONST_GROUP_USER_REQUISITE_CODE SYSRES_CONST_GROUPS_REFERENCE_CODE SYSRES_CONST_GROUPS_REQUISITE_CODE SYSRES_CONST_HIDDEN_MODE_NAME SYSRES_CONST_HIGH_LVL_REQUISITE_CODE SYSRES_CONST_HISTORY_ACTION_CREATE_CODE SYSRES_CONST_HISTORY_ACTION_DELETE_CODE SYSRES_CONST_HISTORY_ACTION_EDIT_CODE SYSRES_CONST_HOUR_CHAR SYSRES_CONST_ID_REQUISITE_CODE SYSRES_CONST_IDSPS_REQUISITE_CODE SYSRES_CONST_IMAGE_MODE_COLOR SYSRES_CONST_IMAGE_MODE_GREYSCALE SYSRES_CONST_IMAGE_MODE_MONOCHROME SYSRES_CONST_IMPORTANCE_HIGH SYSRES_CONST_IMPORTANCE_LOW SYSRES_CONST_IMPORTANCE_NORMAL SYSRES_CONST_IN_DESIGN_VERSION_STATE_PICK_VALUE SYSRES_CONST_INCOMING_WORK_RULE_TYPE_CODE SYSRES_CONST_INT_REQUISITE SYSRES_CONST_INT_REQUISITE_TYPE SYSRES_CONST_INTEGER_NUMBER_FORMAT_CHAR SYSRES_CONST_INTEGER_TYPE_CHAR SYSRES_CONST_IS_GENERATED_REQUISITE_NEGATIVE_VALUE SYSRES_CONST_IS_PUBLIC_ROLE_REQUISITE_CODE SYSRES_CONST_IS_REMOTE_USER_NEGATIVE_VALUE SYSRES_CONST_IS_REMOTE_USER_POSITIVE_VALUE SYSRES_CONST_IS_STORED_REQUISITE_NEGATIVE_VALUE SYSRES_CONST_IS_STORED_REQUISITE_STORED_VALUE SYSRES_CONST_ITALIC_LIFE_CYCLE_STAGE_DRAW_STYLE SYSRES_CONST_JOB_BLOCK_DESCRIPTION SYSRES_CONST_JOB_KIND_CONTROL_JOB SYSRES_CONST_JOB_KIND_JOB SYSRES_CONST_JOB_KIND_NOTICE SYSRES_CONST_JOB_STATE_ABORTED SYSRES_CONST_JOB_STATE_COMPLETE SYSRES_CONST_JOB_STATE_WORKING SYSRES_CONST_KIND_REQUISITE_CODE SYSRES_CONST_KIND_REQUISITE_NAME SYSRES_CONST_KINDS_CREATE_SHADOW_COPIES_REQUISITE_CODE SYSRES_CONST_KINDS_DEFAULT_EDOC_LIFE_STAGE_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_ALL_TEPLATES_ALLOWED_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_ALLOW_LIFE_CYCLE_STAGE_CHANGING_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_ALLOW_MULTIPLE_ACTIVE_VERSIONS_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_SHARE_ACCES_RIGHTS_BY_DEFAULT_CODE SYSRES_CONST_KINDS_EDOC_TEMPLATE_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_TYPE_REQUISITE_CODE SYSRES_CONST_KINDS_SIGNERS_REQUISITES_CODE SYSRES_CONST_KOD_INPUT_TYPE SYSRES_CONST_LAST_UPDATE_DATE_REQUISITE_CODE SYSRES_CONST_LIFE_CYCLE_START_STAGE_REQUISITE_CODE SYSRES_CONST_LILAC_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_LINK_OBJECT_KIND_COMPONENT SYSRES_CONST_LINK_OBJECT_KIND_DOCUMENT SYSRES_CONST_LINK_OBJECT_KIND_EDOC SYSRES_CONST_LINK_OBJECT_KIND_FOLDER SYSRES_CONST_LINK_OBJECT_KIND_JOB SYSRES_CONST_LINK_OBJECT_KIND_REFERENCE SYSRES_CONST_LINK_OBJECT_KIND_TASK SYSRES_CONST_LINK_REF_TYPE_REQUISITE_CODE SYSRES_CONST_LIST_REFERENCE_MODE_NAME SYSRES_CONST_LOCALIZATION_DICTIONARY_MAIN_VIEW_CODE SYSRES_CONST_MAIN_VIEW_CODE SYSRES_CONST_MANUAL_ENUM_METHOD_FLAG SYSRES_CONST_MASTER_COMP_TYPE_REQUISITE_CODE SYSRES_CONST_MASTER_TABLE_REC_ID_REQUISITE_CODE SYSRES_CONST_MAXIMIZED_MODE_NAME SYSRES_CONST_ME_VALUE SYSRES_CONST_MESSAGE_ATTENTION_CAPTION SYSRES_CONST_MESSAGE_CONFIRMATION_CAPTION SYSRES_CONST_MESSAGE_ERROR_CAPTION SYSRES_CONST_MESSAGE_INFORMATION_CAPTION SYSRES_CONST_MINIMIZED_MODE_NAME SYSRES_CONST_MINUTE_CHAR SYSRES_CONST_MODULE_REQUISITE_CODE SYSRES_CONST_MONITORING_BLOCK_DESCRIPTION SYSRES_CONST_MONTH_FORMAT_VALUE SYSRES_CONST_NAME_LOCALIZE_ID_REQUISITE_CODE SYSRES_CONST_NAME_REQUISITE_CODE SYSRES_CONST_NAME_SINGULAR_REQUISITE_CODE SYSRES_CONST_NAMEAN_INPUT_TYPE SYSRES_CONST_NEGATIVE_PICK_VALUE SYSRES_CONST_NEGATIVE_VALUE SYSRES_CONST_NO SYSRES_CONST_NO_PICK_VALUE SYSRES_CONST_NO_SIGNATURE_REQUISITE_CODE SYSRES_CONST_NO_VALUE SYSRES_CONST_NONE_ACCESS_RIGHTS_TYPE_CODE SYSRES_CONST_NONOPERATING_RECORD_FLAG_VALUE SYSRES_CONST_NONOPERATING_RECORD_FLAG_VALUE_MASCULINE SYSRES_CONST_NORMAL_ACCESS_RIGHTS_TYPE_CODE SYSRES_CONST_NORMAL_LIFE_CYCLE_STAGE_DRAW_STYLE SYSRES_CONST_NORMAL_MODE_NAME SYSRES_CONST_NOT_ALLOWED_ACCESS_TYPE_CODE SYSRES_CONST_NOT_ALLOWED_ACCESS_TYPE_NAME SYSRES_CONST_NOTE_REQUISITE_CODE SYSRES_CONST_NOTICE_BLOCK_DESCRIPTION SYSRES_CONST_NUM_REQUISITE SYSRES_CONST_NUM_STR_REQUISITE_CODE SYSRES_CONST_NUMERATION_AUTO_NOT_STRONG SYSRES_CONST_NUMERATION_AUTO_STRONG SYSRES_CONST_NUMERATION_FROM_DICTONARY SYSRES_CONST_NUMERATION_MANUAL SYSRES_CONST_NUMERIC_TYPE_CHAR SYSRES_CONST_NUMREQ_REQUISITE_CODE SYSRES_CONST_OBSOLETE_VERSION_STATE_PICK_VALUE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE_CODE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE_FEMININE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE_MASCULINE SYSRES_CONST_OPTIONAL_FORM_COMP_REQCODE_PREFIX SYSRES_CONST_ORANGE_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_ORIGINALREF_REQUISITE_CODE SYSRES_CONST_OURFIRM_REF_CODE SYSRES_CONST_OURFIRM_REQUISITE_CODE SYSRES_CONST_OURFIRM_VAR SYSRES_CONST_OUTGOING_WORK_RULE_TYPE_CODE SYSRES_CONST_PICK_NEGATIVE_RESULT SYSRES_CONST_PICK_POSITIVE_RESULT SYSRES_CONST_PICK_REQUISITE SYSRES_CONST_PICK_REQUISITE_TYPE SYSRES_CONST_PICK_TYPE_CHAR SYSRES_CONST_PLAN_STATUS_REQUISITE_CODE SYSRES_CONST_PLATFORM_VERSION_COMMENT SYSRES_CONST_PLUGINS_SETTINGS_DESCRIPTION_REQUISITE_CODE SYSRES_CONST_POSITIVE_PICK_VALUE SYSRES_CONST_POWER_TO_CREATE_ACTION_CODE SYSRES_CONST_POWER_TO_SIGN_ACTION_CODE SYSRES_CONST_PRIORITY_REQUISITE_CODE SYSRES_CONST_QUALIFIED_TASK_TYPE SYSRES_CONST_QUALIFIED_TASK_TYPE_CODE SYSRES_CONST_RECSTAT_REQUISITE_CODE SYSRES_CONST_RED_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_REF_ID_T_REF_TYPE_REQUISITE_CODE SYSRES_CONST_REF_REQUISITE SYSRES_CONST_REF_REQUISITE_TYPE SYSRES_CONST_REF_REQUISITES_REFERENCE_CODE_SELECTED_REQUISITE SYSRES_CONST_REFERENCE_RECORD_HISTORY_CREATE_ACTION_CODE SYSRES_CONST_REFERENCE_RECORD_HISTORY_DELETE_ACTION_CODE SYSRES_CONST_REFERENCE_RECORD_HISTORY_MODIFY_ACTION_CODE SYSRES_CONST_REFERENCE_TYPE_CHAR SYSRES_CONST_REFERENCE_TYPE_REQUISITE_NAME SYSRES_CONST_REFERENCES_ADD_PARAMS_REQUISITE_CODE SYSRES_CONST_REFERENCES_DISPLAY_REQUISITE_REQUISITE_CODE SYSRES_CONST_REMOTE_SERVER_STATUS_WORKING SYSRES_CONST_REMOTE_SERVER_TYPE_MAIN SYSRES_CONST_REMOTE_SERVER_TYPE_SECONDARY SYSRES_CONST_REMOTE_USER_FLAG_VALUE_CODE SYSRES_CONST_REPORT_APP_EDITOR_INTERNAL SYSRES_CONST_REPORT_BASE_REPORT_ID_REQUISITE_CODE SYSRES_CONST_REPORT_BASE_REPORT_REQUISITE_CODE SYSRES_CONST_REPORT_SCRIPT_REQUISITE_CODE SYSRES_CONST_REPORT_TEMPLATE_REQUISITE_CODE SYSRES_CONST_REPORT_VIEWER_CODE_REQUISITE_CODE SYSRES_CONST_REQ_ALLOW_COMPONENT_DEFAULT_VALUE SYSRES_CONST_REQ_ALLOW_RECORD_DEFAULT_VALUE SYSRES_CONST_REQ_ALLOW_SERVER_COMPONENT_DEFAULT_VALUE SYSRES_CONST_REQ_MODE_AVAILABLE_CODE SYSRES_CONST_REQ_MODE_EDIT_CODE SYSRES_CONST_REQ_MODE_HIDDEN_CODE SYSRES_CONST_REQ_MODE_NOT_AVAILABLE_CODE SYSRES_CONST_REQ_MODE_VIEW_CODE SYSRES_CONST_REQ_NUMBER_REQUISITE_CODE SYSRES_CONST_REQ_SECTION_VALUE SYSRES_CONST_REQ_TYPE_VALUE SYSRES_CONST_REQUISITE_FORMAT_BY_UNIT SYSRES_CONST_REQUISITE_FORMAT_DATE_FULL SYSRES_CONST_REQUISITE_FORMAT_DATE_TIME SYSRES_CONST_REQUISITE_FORMAT_LEFT SYSRES_CONST_REQUISITE_FORMAT_RIGHT SYSRES_CONST_REQUISITE_FORMAT_WITHOUT_UNIT SYSRES_CONST_REQUISITE_NUMBER_REQUISITE_CODE SYSRES_CONST_REQUISITE_SECTION_ACTIONS SYSRES_CONST_REQUISITE_SECTION_BUTTON SYSRES_CONST_REQUISITE_SECTION_BUTTONS SYSRES_CONST_REQUISITE_SECTION_CARD SYSRES_CONST_REQUISITE_SECTION_TABLE SYSRES_CONST_REQUISITE_SECTION_TABLE10 SYSRES_CONST_REQUISITE_SECTION_TABLE11 SYSRES_CONST_REQUISITE_SECTION_TABLE12 SYSRES_CONST_REQUISITE_SECTION_TABLE13 SYSRES_CONST_REQUISITE_SECTION_TABLE14 SYSRES_CONST_REQUISITE_SECTION_TABLE15 SYSRES_CONST_REQUISITE_SECTION_TABLE16 SYSRES_CONST_REQUISITE_SECTION_TABLE17 SYSRES_CONST_REQUISITE_SECTION_TABLE18 SYSRES_CONST_REQUISITE_SECTION_TABLE19 SYSRES_CONST_REQUISITE_SECTION_TABLE2 SYSRES_CONST_REQUISITE_SECTION_TABLE20 SYSRES_CONST_REQUISITE_SECTION_TABLE21 SYSRES_CONST_REQUISITE_SECTION_TABLE22 SYSRES_CONST_REQUISITE_SECTION_TABLE23 SYSRES_CONST_REQUISITE_SECTION_TABLE24 SYSRES_CONST_REQUISITE_SECTION_TABLE3 SYSRES_CONST_REQUISITE_SECTION_TABLE4 SYSRES_CONST_REQUISITE_SECTION_TABLE5 SYSRES_CONST_REQUISITE_SECTION_TABLE6 SYSRES_CONST_REQUISITE_SECTION_TABLE7 SYSRES_CONST_REQUISITE_SECTION_TABLE8 SYSRES_CONST_REQUISITE_SECTION_TABLE9 SYSRES_CONST_REQUISITES_PSEUDOREFERENCE_REQUISITE_NUMBER_REQUISITE_CODE SYSRES_CONST_RIGHT_ALIGNMENT_CODE SYSRES_CONST_ROLES_REFERENCE_CODE SYSRES_CONST_ROUTE_STEP_AFTER_RUS SYSRES_CONST_ROUTE_STEP_AND_CONDITION_RUS SYSRES_CONST_ROUTE_STEP_OR_CONDITION_RUS SYSRES_CONST_ROUTE_TYPE_COMPLEX SYSRES_CONST_ROUTE_TYPE_PARALLEL SYSRES_CONST_ROUTE_TYPE_SERIAL SYSRES_CONST_SBDATASETDESC_NEGATIVE_VALUE SYSRES_CONST_SBDATASETDESC_POSITIVE_VALUE SYSRES_CONST_SBVIEWSDESC_POSITIVE_VALUE SYSRES_CONST_SCRIPT_BLOCK_DESCRIPTION SYSRES_CONST_SEARCH_BY_TEXT_REQUISITE_CODE SYSRES_CONST_SEARCHES_COMPONENT_CONTENT SYSRES_CONST_SEARCHES_CRITERIA_ACTION_NAME SYSRES_CONST_SEARCHES_EDOC_CONTENT SYSRES_CONST_SEARCHES_FOLDER_CONTENT SYSRES_CONST_SEARCHES_JOB_CONTENT SYSRES_CONST_SEARCHES_REFERENCE_CODE SYSRES_CONST_SEARCHES_TASK_CONTENT SYSRES_CONST_SECOND_CHAR SYSRES_CONST_SECTION_REQUISITE_ACTIONS_VALUE SYSRES_CONST_SECTION_REQUISITE_CARD_VALUE SYSRES_CONST_SECTION_REQUISITE_CODE SYSRES_CONST_SECTION_REQUISITE_DETAIL_1_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_2_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_3_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_4_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_5_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_6_VALUE SYSRES_CONST_SELECT_REFERENCE_MODE_NAME SYSRES_CONST_SELECT_TYPE_SELECTABLE SYSRES_CONST_SELECT_TYPE_SELECTABLE_ONLY_CHILD SYSRES_CONST_SELECT_TYPE_SELECTABLE_WITH_CHILD SYSRES_CONST_SELECT_TYPE_UNSLECTABLE SYSRES_CONST_SERVER_TYPE_MAIN SYSRES_CONST_SERVICE_USER_CATEGORY_FIELD_VALUE SYSRES_CONST_SETTINGS_USER_REQUISITE_CODE SYSRES_CONST_SIGNATURE_AND_ENCODE_CERTIFICATE_TYPE_CODE SYSRES_CONST_SIGNATURE_CERTIFICATE_TYPE_CODE SYSRES_CONST_SINGULAR_TITLE_REQUISITE_CODE SYSRES_CONST_SQL_SERVER_AUTHENTIFICATION_FLAG_VALUE_CODE SYSRES_CONST_SQL_SERVER_ENCODE_AUTHENTIFICATION_FLAG_VALUE_CODE SYSRES_CONST_STANDART_ROUTE_REFERENCE_CODE SYSRES_CONST_STANDART_ROUTE_REFERENCE_COMMENT_REQUISITE_CODE SYSRES_CONST_STANDART_ROUTES_GROUPS_REFERENCE_CODE SYSRES_CONST_STATE_REQ_NAME SYSRES_CONST_STATE_REQUISITE_ACTIVE_VALUE SYSRES_CONST_STATE_REQUISITE_CLOSED_VALUE SYSRES_CONST_STATE_REQUISITE_CODE SYSRES_CONST_STATIC_ROLE_TYPE_CODE SYSRES_CONST_STATUS_PLAN_DEFAULT_VALUE SYSRES_CONST_STATUS_VALUE_AUTOCLEANING SYSRES_CONST_STATUS_VALUE_BLUE_SQUARE SYSRES_CONST_STATUS_VALUE_COMPLETE SYSRES_CONST_STATUS_VALUE_GREEN_SQUARE SYSRES_CONST_STATUS_VALUE_ORANGE_SQUARE SYSRES_CONST_STATUS_VALUE_PURPLE_SQUARE SYSRES_CONST_STATUS_VALUE_RED_SQUARE SYSRES_CONST_STATUS_VALUE_SUSPEND SYSRES_CONST_STATUS_VALUE_YELLOW_SQUARE SYSRES_CONST_STDROUTE_SHOW_TO_USERS_REQUISITE_CODE SYSRES_CONST_STORAGE_TYPE_FILE SYSRES_CONST_STORAGE_TYPE_SQL_SERVER SYSRES_CONST_STR_REQUISITE SYSRES_CONST_STRIKEOUT_LIFE_CYCLE_STAGE_DRAW_STYLE SYSRES_CONST_STRING_FORMAT_LEFT_ALIGN_CHAR SYSRES_CONST_STRING_FORMAT_RIGHT_ALIGN_CHAR SYSRES_CONST_STRING_REQUISITE_CODE SYSRES_CONST_STRING_REQUISITE_TYPE SYSRES_CONST_STRING_TYPE_CHAR SYSRES_CONST_SUBSTITUTES_PSEUDOREFERENCE_CODE SYSRES_CONST_SUBTASK_BLOCK_DESCRIPTION SYSRES_CONST_SYSTEM_SETTING_CURRENT_USER_PARAM_VALUE SYSRES_CONST_SYSTEM_SETTING_EMPTY_VALUE_PARAM_VALUE SYSRES_CONST_SYSTEM_VERSION_COMMENT SYSRES_CONST_TASK_ACCESS_TYPE_ALL SYSRES_CONST_TASK_ACCESS_TYPE_ALL_MEMBERS SYSRES_CONST_TASK_ACCESS_TYPE_MANUAL SYSRES_CONST_TASK_ENCODE_TYPE_CERTIFICATION SYSRES_CONST_TASK_ENCODE_TYPE_CERTIFICATION_AND_PASSWORD SYSRES_CONST_TASK_ENCODE_TYPE_NONE SYSRES_CONST_TASK_ENCODE_TYPE_PASSWORD SYSRES_CONST_TASK_ROUTE_ALL_CONDITION SYSRES_CONST_TASK_ROUTE_AND_CONDITION SYSRES_CONST_TASK_ROUTE_OR_CONDITION SYSRES_CONST_TASK_STATE_ABORTED SYSRES_CONST_TASK_STATE_COMPLETE SYSRES_CONST_TASK_STATE_CONTINUED SYSRES_CONST_TASK_STATE_CONTROL SYSRES_CONST_TASK_STATE_INIT SYSRES_CONST_TASK_STATE_WORKING SYSRES_CONST_TASK_TITLE SYSRES_CONST_TASK_TYPES_GROUPS_REFERENCE_CODE SYSRES_CONST_TASK_TYPES_REFERENCE_CODE SYSRES_CONST_TEMPLATES_REFERENCE_CODE SYSRES_CONST_TEST_DATE_REQUISITE_NAME SYSRES_CONST_TEST_DEV_DATABASE_NAME SYSRES_CONST_TEST_DEV_SYSTEM_CODE SYSRES_CONST_TEST_EDMS_DATABASE_NAME SYSRES_CONST_TEST_EDMS_MAIN_CODE SYSRES_CONST_TEST_EDMS_MAIN_DB_NAME SYSRES_CONST_TEST_EDMS_SECOND_CODE SYSRES_CONST_TEST_EDMS_SECOND_DB_NAME SYSRES_CONST_TEST_EDMS_SYSTEM_CODE SYSRES_CONST_TEST_NUMERIC_REQUISITE_NAME SYSRES_CONST_TEXT_REQUISITE SYSRES_CONST_TEXT_REQUISITE_CODE SYSRES_CONST_TEXT_REQUISITE_TYPE SYSRES_CONST_TEXT_TYPE_CHAR SYSRES_CONST_TYPE_CODE_REQUISITE_CODE SYSRES_CONST_TYPE_REQUISITE_CODE SYSRES_CONST_UNDEFINED_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_UNITS_SECTION_ID_REQUISITE_CODE SYSRES_CONST_UNITS_SECTION_REQUISITE_CODE SYSRES_CONST_UNOPERATING_RECORD_FLAG_VALUE_CODE SYSRES_CONST_UNSTORED_DATA_REQUISITE_CODE SYSRES_CONST_UNSTORED_DATA_REQUISITE_NAME SYSRES_CONST_USE_ACCESS_TYPE_CODE SYSRES_CONST_USE_ACCESS_TYPE_NAME SYSRES_CONST_USER_ACCOUNT_TYPE_VALUE_CODE SYSRES_CONST_USER_ADDITIONAL_INFORMATION_REQUISITE_CODE SYSRES_CONST_USER_AND_GROUP_ID_FROM_PSEUDOREFERENCE_REQUISITE_CODE SYSRES_CONST_USER_CATEGORY_NORMAL SYSRES_CONST_USER_CERTIFICATE_REQUISITE_CODE SYSRES_CONST_USER_CERTIFICATE_STATE_REQUISITE_CODE SYSRES_CONST_USER_CERTIFICATE_SUBJECT_NAME_REQUISITE_CODE SYSRES_CONST_USER_CERTIFICATE_THUMBPRINT_REQUISITE_CODE SYSRES_CONST_USER_COMMON_CATEGORY SYSRES_CONST_USER_COMMON_CATEGORY_CODE SYSRES_CONST_USER_FULL_NAME_REQUISITE_CODE SYSRES_CONST_USER_GROUP_TYPE_REQUISITE_CODE SYSRES_CONST_USER_LOGIN_REQUISITE_CODE SYSRES_CONST_USER_REMOTE_CONTROLLER_REQUISITE_CODE SYSRES_CONST_USER_REMOTE_SYSTEM_REQUISITE_CODE SYSRES_CONST_USER_RIGHTS_T_REQUISITE_CODE SYSRES_CONST_USER_SERVER_NAME_REQUISITE_CODE SYSRES_CONST_USER_SERVICE_CATEGORY SYSRES_CONST_USER_SERVICE_CATEGORY_CODE SYSRES_CONST_USER_STATUS_ADMINISTRATOR_CODE SYSRES_CONST_USER_STATUS_ADMINISTRATOR_NAME SYSRES_CONST_USER_STATUS_DEVELOPER_CODE SYSRES_CONST_USER_STATUS_DEVELOPER_NAME SYSRES_CONST_USER_STATUS_DISABLED_CODE SYSRES_CONST_USER_STATUS_DISABLED_NAME SYSRES_CONST_USER_STATUS_SYSTEM_DEVELOPER_CODE SYSRES_CONST_USER_STATUS_USER_CODE SYSRES_CONST_USER_STATUS_USER_NAME SYSRES_CONST_USER_STATUS_USER_NAME_DEPRECATED SYSRES_CONST_USER_TYPE_FIELD_VALUE_USER SYSRES_CONST_USER_TYPE_REQUISITE_CODE SYSRES_CONST_USERS_CONTROLLER_REQUISITE_CODE SYSRES_CONST_USERS_IS_MAIN_SERVER_REQUISITE_CODE SYSRES_CONST_USERS_REFERENCE_CODE SYSRES_CONST_USERS_REGISTRATION_CERTIFICATES_ACTION_NAME SYSRES_CONST_USERS_REQUISITE_CODE SYSRES_CONST_USERS_SYSTEM_REQUISITE_CODE SYSRES_CONST_USERS_USER_ACCESS_RIGHTS_TYPR_REQUISITE_CODE SYSRES_CONST_USERS_USER_AUTHENTICATION_REQUISITE_CODE SYSRES_CONST_USERS_USER_COMPONENT_REQUISITE_CODE SYSRES_CONST_USERS_USER_GROUP_REQUISITE_CODE SYSRES_CONST_USERS_VIEW_CERTIFICATES_ACTION_NAME SYSRES_CONST_VIEW_DEFAULT_CODE SYSRES_CONST_VIEW_DEFAULT_NAME SYSRES_CONST_VIEWER_REQUISITE_CODE SYSRES_CONST_WAITING_BLOCK_DESCRIPTION SYSRES_CONST_WIZARD_FORM_LABEL_TEST_STRING SYSRES_CONST_WIZARD_QUERY_PARAM_HEIGHT_ETALON_STRING SYSRES_CONST_WIZARD_REFERENCE_COMMENT_REQUISITE_CODE SYSRES_CONST_WORK_RULES_DESCRIPTION_REQUISITE_CODE SYSRES_CONST_WORK_TIME_CALENDAR_REFERENCE_CODE SYSRES_CONST_WORK_WORKFLOW_HARD_ROUTE_TYPE_VALUE SYSRES_CONST_WORK_WORKFLOW_HARD_ROUTE_TYPE_VALUE_CODE SYSRES_CONST_WORK_WORKFLOW_HARD_ROUTE_TYPE_VALUE_CODE_RUS SYSRES_CONST_WORK_WORKFLOW_SOFT_ROUTE_TYPE_VALUE_CODE_RUS SYSRES_CONST_WORKFLOW_ROUTE_TYPR_HARD SYSRES_CONST_WORKFLOW_ROUTE_TYPR_SOFT SYSRES_CONST_XML_ENCODING SYSRES_CONST_XREC_STAT_REQUISITE_CODE SYSRES_CONST_XRECID_FIELD_NAME SYSRES_CONST_YES SYSRES_CONST_YES_NO_2_REQUISITE_CODE SYSRES_CONST_YES_NO_REQUISITE_CODE SYSRES_CONST_YES_NO_T_REF_TYPE_REQUISITE_CODE SYSRES_CONST_YES_PICK_VALUE SYSRES_CONST_YES_VALUE CR FALSE nil NO_VALUE NULL TAB TRUE YES_VALUE ADMINISTRATORS_GROUP_NAME CUSTOMIZERS_GROUP_NAME DEVELOPERS_GROUP_NAME SERVICE_USERS_GROUP_NAME DECISION_BLOCK_FIRST_OPERAND_PROPERTY DECISION_BLOCK_NAME_PROPERTY DECISION_BLOCK_OPERATION_PROPERTY DECISION_BLOCK_RESULT_TYPE_PROPERTY DECISION_BLOCK_SECOND_OPERAND_PROPERTY ANY_FILE_EXTENTION COMPRESSED_DOCUMENT_EXTENSION EXTENDED_DOCUMENT_EXTENSION SHORT_COMPRESSED_DOCUMENT_EXTENSION SHORT_EXTENDED_DOCUMENT_EXTENSION JOB_BLOCK_ABORT_DEADLINE_PROPERTY JOB_BLOCK_AFTER_FINISH_EVENT JOB_BLOCK_AFTER_QUERY_PARAMETERS_EVENT JOB_BLOCK_ATTACHMENT_PROPERTY JOB_BLOCK_ATTACHMENTS_RIGHTS_GROUP_PROPERTY JOB_BLOCK_ATTACHMENTS_RIGHTS_TYPE_PROPERTY JOB_BLOCK_BEFORE_QUERY_PARAMETERS_EVENT JOB_BLOCK_BEFORE_START_EVENT JOB_BLOCK_CREATED_JOBS_PROPERTY JOB_BLOCK_DEADLINE_PROPERTY JOB_BLOCK_EXECUTION_RESULTS_PROPERTY JOB_BLOCK_IS_PARALLEL_PROPERTY JOB_BLOCK_IS_RELATIVE_ABORT_DEADLINE_PROPERTY JOB_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY JOB_BLOCK_JOB_TEXT_PROPERTY JOB_BLOCK_NAME_PROPERTY JOB_BLOCK_NEED_SIGN_ON_PERFORM_PROPERTY JOB_BLOCK_PERFORMER_PROPERTY JOB_BLOCK_RELATIVE_ABORT_DEADLINE_TYPE_PROPERTY JOB_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY JOB_BLOCK_SUBJECT_PROPERTY ENGLISH_LANGUAGE_CODE RUSSIAN_LANGUAGE_CODE smHidden smMaximized smMinimized smNormal wmNo wmYes COMPONENT_TOKEN_LINK_KIND DOCUMENT_LINK_KIND EDOCUMENT_LINK_KIND FOLDER_LINK_KIND JOB_LINK_KIND REFERENCE_LINK_KIND TASK_LINK_KIND COMPONENT_TOKEN_LOCK_TYPE EDOCUMENT_VERSION_LOCK_TYPE MONITOR_BLOCK_AFTER_FINISH_EVENT MONITOR_BLOCK_BEFORE_START_EVENT MONITOR_BLOCK_DEADLINE_PROPERTY MONITOR_BLOCK_INTERVAL_PROPERTY MONITOR_BLOCK_INTERVAL_TYPE_PROPERTY MONITOR_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY MONITOR_BLOCK_NAME_PROPERTY MONITOR_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY MONITOR_BLOCK_SEARCH_SCRIPT_PROPERTY NOTICE_BLOCK_AFTER_FINISH_EVENT NOTICE_BLOCK_ATTACHMENT_PROPERTY NOTICE_BLOCK_ATTACHMENTS_RIGHTS_GROUP_PROPERTY NOTICE_BLOCK_ATTACHMENTS_RIGHTS_TYPE_PROPERTY NOTICE_BLOCK_BEFORE_START_EVENT NOTICE_BLOCK_CREATED_NOTICES_PROPERTY NOTICE_BLOCK_DEADLINE_PROPERTY NOTICE_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY NOTICE_BLOCK_NAME_PROPERTY NOTICE_BLOCK_NOTICE_TEXT_PROPERTY NOTICE_BLOCK_PERFORMER_PROPERTY NOTICE_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY NOTICE_BLOCK_SUBJECT_PROPERTY dseAfterCancel dseAfterClose dseAfterDelete dseAfterDeleteOutOfTransaction dseAfterInsert dseAfterOpen dseAfterScroll dseAfterUpdate dseAfterUpdateOutOfTransaction dseBeforeCancel dseBeforeClose dseBeforeDelete dseBeforeDetailUpdate dseBeforeInsert dseBeforeOpen dseBeforeUpdate dseOnAnyRequisiteChange dseOnCloseRecord dseOnDeleteError dseOnOpenRecord dseOnPrepareUpdate dseOnUpdateError dseOnUpdateRatifiedRecord dseOnValidDelete dseOnValidUpdate reOnChange reOnChangeValues SELECTION_BEGIN_ROUTE_EVENT SELECTION_END_ROUTE_EVENT CURRENT_PERIOD_IS_REQUIRED PREVIOUS_CARD_TYPE_NAME SHOW_RECORD_PROPERTIES_FORM ACCESS_RIGHTS_SETTING_DIALOG_CODE ADMINISTRATOR_USER_CODE ANALYTIC_REPORT_TYPE asrtHideLocal asrtHideRemote CALCULATED_ROLE_TYPE_CODE COMPONENTS_REFERENCE_DEVELOPER_VIEW_CODE DCTS_TEST_PROTOCOLS_FOLDER_PATH E_EDOC_VERSION_ALREADY_APPROVINGLY_SIGNED E_EDOC_VERSION_ALREADY_APPROVINGLY_SIGNED_BY_USER E_EDOC_VERSION_ALREDY_SIGNED E_EDOC_VERSION_ALREDY_SIGNED_BY_USER EDOC_TYPES_CODE_REQUISITE_FIELD_NAME EDOCUMENTS_ALIAS_NAME FILES_FOLDER_PATH FILTER_OPERANDS_DELIMITER FILTER_OPERATIONS_DELIMITER FORMCARD_NAME FORMLIST_NAME GET_EXTENDED_DOCUMENT_EXTENSION_CREATION_MODE GET_EXTENDED_DOCUMENT_EXTENSION_IMPORT_MODE INTEGRATED_REPORT_TYPE IS_BUILDER_APPLICATION_ROLE IS_BUILDER_APPLICATION_ROLE2 IS_BUILDER_USERS ISBSYSDEV LOG_FOLDER_PATH mbCancel mbNo mbNoToAll mbOK mbYes mbYesToAll MEMORY_DATASET_DESRIPTIONS_FILENAME mrNo mrNoToAll mrYes mrYesToAll MULTIPLE_SELECT_DIALOG_CODE NONOPERATING_RECORD_FLAG_FEMININE NONOPERATING_RECORD_FLAG_MASCULINE OPERATING_RECORD_FLAG_FEMININE OPERATING_RECORD_FLAG_MASCULINE PROFILING_SETTINGS_COMMON_SETTINGS_CODE_VALUE PROGRAM_INITIATED_LOOKUP_ACTION ratDelete ratEdit ratInsert REPORT_TYPE REQUIRED_PICK_VALUES_VARIABLE rmCard rmList SBRTE_PROGID_DEV SBRTE_PROGID_RELEASE STATIC_ROLE_TYPE_CODE SUPPRESS_EMPTY_TEMPLATE_CREATION SYSTEM_USER_CODE UPDATE_DIALOG_DATASET USED_IN_OBJECT_HINT_PARAM USER_INITIATED_LOOKUP_ACTION USER_NAME_FORMAT USER_SELECTION_RESTRICTIONS WORKFLOW_TEST_PROTOCOLS_FOLDER_PATH ELS_SUBTYPE_CONTROL_NAME ELS_FOLDER_KIND_CONTROL_NAME REPEAT_PROCESS_CURRENT_OBJECT_EXCEPTION_NAME PRIVILEGE_COMPONENT_FULL_ACCESS PRIVILEGE_DEVELOPMENT_EXPORT PRIVILEGE_DEVELOPMENT_IMPORT PRIVILEGE_DOCUMENT_DELETE PRIVILEGE_ESD PRIVILEGE_FOLDER_DELETE PRIVILEGE_MANAGE_ACCESS_RIGHTS PRIVILEGE_MANAGE_REPLICATION PRIVILEGE_MANAGE_SESSION_SERVER PRIVILEGE_OBJECT_FULL_ACCESS PRIVILEGE_OBJECT_VIEW PRIVILEGE_RESERVE_LICENSE PRIVILEGE_SYSTEM_CUSTOMIZE PRIVILEGE_SYSTEM_DEVELOP PRIVILEGE_SYSTEM_INSTALL PRIVILEGE_TASK_DELETE PRIVILEGE_USER_PLUGIN_SETTINGS_CUSTOMIZE PRIVILEGES_PSEUDOREFERENCE_CODE ACCESS_TYPES_PSEUDOREFERENCE_CODE ALL_AVAILABLE_COMPONENTS_PSEUDOREFERENCE_CODE ALL_AVAILABLE_PRIVILEGES_PSEUDOREFERENCE_CODE ALL_REPLICATE_COMPONENTS_PSEUDOREFERENCE_CODE AVAILABLE_DEVELOPERS_COMPONENTS_PSEUDOREFERENCE_CODE COMPONENTS_PSEUDOREFERENCE_CODE FILTRATER_SETTINGS_CONFLICTS_PSEUDOREFERENCE_CODE GROUPS_PSEUDOREFERENCE_CODE RECEIVE_PROTOCOL_PSEUDOREFERENCE_CODE REFERENCE_REQUISITE_PSEUDOREFERENCE_CODE REFERENCE_REQUISITES_PSEUDOREFERENCE_CODE REFTYPES_PSEUDOREFERENCE_CODE REPLICATION_SEANCES_DIARY_PSEUDOREFERENCE_CODE SEND_PROTOCOL_PSEUDOREFERENCE_CODE SUBSTITUTES_PSEUDOREFERENCE_CODE SYSTEM_SETTINGS_PSEUDOREFERENCE_CODE UNITS_PSEUDOREFERENCE_CODE USERS_PSEUDOREFERENCE_CODE VIEWERS_PSEUDOREFERENCE_CODE CERTIFICATE_TYPE_ENCRYPT CERTIFICATE_TYPE_SIGN CERTIFICATE_TYPE_SIGN_AND_ENCRYPT STORAGE_TYPE_FILE STORAGE_TYPE_NAS_CIFS STORAGE_TYPE_SAPERION STORAGE_TYPE_SQL_SERVER COMPTYPE2_REQUISITE_DOCUMENTS_VALUE COMPTYPE2_REQUISITE_TASKS_VALUE COMPTYPE2_REQUISITE_FOLDERS_VALUE COMPTYPE2_REQUISITE_REFERENCES_VALUE SYSREQ_CODE SYSREQ_COMPTYPE2 SYSREQ_CONST_AVAILABLE_FOR_WEB SYSREQ_CONST_COMMON_CODE SYSREQ_CONST_COMMON_VALUE SYSREQ_CONST_FIRM_CODE SYSREQ_CONST_FIRM_STATUS SYSREQ_CONST_FIRM_VALUE SYSREQ_CONST_SERVER_STATUS SYSREQ_CONTENTS SYSREQ_DATE_OPEN SYSREQ_DATE_CLOSE SYSREQ_DESCRIPTION SYSREQ_DESCRIPTION_LOCALIZE_ID SYSREQ_DOUBLE SYSREQ_EDOC_ACCESS_TYPE SYSREQ_EDOC_AUTHOR SYSREQ_EDOC_CREATED SYSREQ_EDOC_DELEGATE_RIGHTS_REQUISITE_CODE SYSREQ_EDOC_EDITOR SYSREQ_EDOC_ENCODE_TYPE SYSREQ_EDOC_ENCRYPTION_PLUGIN_NAME SYSREQ_EDOC_ENCRYPTION_PLUGIN_VERSION SYSREQ_EDOC_EXPORT_DATE SYSREQ_EDOC_EXPORTER SYSREQ_EDOC_KIND SYSREQ_EDOC_LIFE_STAGE_NAME SYSREQ_EDOC_LOCKED_FOR_SERVER_CODE SYSREQ_EDOC_MODIFIED SYSREQ_EDOC_NAME SYSREQ_EDOC_NOTE SYSREQ_EDOC_QUALIFIED_ID SYSREQ_EDOC_SESSION_KEY SYSREQ_EDOC_SESSION_KEY_ENCRYPTION_PLUGIN_NAME SYSREQ_EDOC_SESSION_KEY_ENCRYPTION_PLUGIN_VERSION SYSREQ_EDOC_SIGNATURE_TYPE SYSREQ_EDOC_SIGNED SYSREQ_EDOC_STORAGE SYSREQ_EDOC_STORAGES_ARCHIVE_STORAGE SYSREQ_EDOC_STORAGES_CHECK_RIGHTS SYSREQ_EDOC_STORAGES_COMPUTER_NAME SYSREQ_EDOC_STORAGES_EDIT_IN_STORAGE SYSREQ_EDOC_STORAGES_EXECUTIVE_STORAGE SYSREQ_EDOC_STORAGES_FUNCTION SYSREQ_EDOC_STORAGES_INITIALIZED SYSREQ_EDOC_STORAGES_LOCAL_PATH SYSREQ_EDOC_STORAGES_SAPERION_DATABASE_NAME SYSREQ_EDOC_STORAGES_SEARCH_BY_TEXT SYSREQ_EDOC_STORAGES_SERVER_NAME SYSREQ_EDOC_STORAGES_SHARED_SOURCE_NAME SYSREQ_EDOC_STORAGES_TYPE SYSREQ_EDOC_TEXT_MODIFIED SYSREQ_EDOC_TYPE_ACT_CODE SYSREQ_EDOC_TYPE_ACT_DESCRIPTION SYSREQ_EDOC_TYPE_ACT_DESCRIPTION_LOCALIZE_ID SYSREQ_EDOC_TYPE_ACT_ON_EXECUTE SYSREQ_EDOC_TYPE_ACT_ON_EXECUTE_EXISTS SYSREQ_EDOC_TYPE_ACT_SECTION SYSREQ_EDOC_TYPE_ADD_PARAMS SYSREQ_EDOC_TYPE_COMMENT SYSREQ_EDOC_TYPE_EVENT_TEXT SYSREQ_EDOC_TYPE_NAME_IN_SINGULAR SYSREQ_EDOC_TYPE_NAME_IN_SINGULAR_LOCALIZE_ID SYSREQ_EDOC_TYPE_NAME_LOCALIZE_ID SYSREQ_EDOC_TYPE_NUMERATION_METHOD SYSREQ_EDOC_TYPE_PSEUDO_REQUISITE_CODE SYSREQ_EDOC_TYPE_REQ_CODE SYSREQ_EDOC_TYPE_REQ_DESCRIPTION SYSREQ_EDOC_TYPE_REQ_DESCRIPTION_LOCALIZE_ID SYSREQ_EDOC_TYPE_REQ_IS_LEADING SYSREQ_EDOC_TYPE_REQ_IS_REQUIRED SYSREQ_EDOC_TYPE_REQ_NUMBER SYSREQ_EDOC_TYPE_REQ_ON_CHANGE SYSREQ_EDOC_TYPE_REQ_ON_CHANGE_EXISTS SYSREQ_EDOC_TYPE_REQ_ON_SELECT SYSREQ_EDOC_TYPE_REQ_ON_SELECT_KIND SYSREQ_EDOC_TYPE_REQ_SECTION SYSREQ_EDOC_TYPE_VIEW_CARD SYSREQ_EDOC_TYPE_VIEW_CODE SYSREQ_EDOC_TYPE_VIEW_COMMENT SYSREQ_EDOC_TYPE_VIEW_IS_MAIN SYSREQ_EDOC_TYPE_VIEW_NAME SYSREQ_EDOC_TYPE_VIEW_NAME_LOCALIZE_ID SYSREQ_EDOC_VERSION_AUTHOR SYSREQ_EDOC_VERSION_CRC SYSREQ_EDOC_VERSION_DATA SYSREQ_EDOC_VERSION_EDITOR SYSREQ_EDOC_VERSION_EXPORT_DATE SYSREQ_EDOC_VERSION_EXPORTER SYSREQ_EDOC_VERSION_HIDDEN SYSREQ_EDOC_VERSION_LIFE_STAGE SYSREQ_EDOC_VERSION_MODIFIED SYSREQ_EDOC_VERSION_NOTE SYSREQ_EDOC_VERSION_SIGNATURE_TYPE SYSREQ_EDOC_VERSION_SIGNED SYSREQ_EDOC_VERSION_SIZE SYSREQ_EDOC_VERSION_SOURCE SYSREQ_EDOC_VERSION_TEXT_MODIFIED SYSREQ_EDOCKIND_DEFAULT_VERSION_STATE_CODE SYSREQ_FOLDER_KIND SYSREQ_FUNC_CATEGORY SYSREQ_FUNC_COMMENT SYSREQ_FUNC_GROUP SYSREQ_FUNC_GROUP_COMMENT SYSREQ_FUNC_GROUP_NUMBER SYSREQ_FUNC_HELP SYSREQ_FUNC_PARAM_DEF_VALUE SYSREQ_FUNC_PARAM_IDENT SYSREQ_FUNC_PARAM_NUMBER SYSREQ_FUNC_PARAM_TYPE SYSREQ_FUNC_TEXT SYSREQ_GROUP_CATEGORY SYSREQ_ID SYSREQ_LAST_UPDATE SYSREQ_LEADER_REFERENCE SYSREQ_LINE_NUMBER SYSREQ_MAIN_RECORD_ID SYSREQ_NAME SYSREQ_NAME_LOCALIZE_ID SYSREQ_NOTE SYSREQ_ORIGINAL_RECORD SYSREQ_OUR_FIRM SYSREQ_PROFILING_SETTINGS_BATCH_LOGING SYSREQ_PROFILING_SETTINGS_BATCH_SIZE SYSREQ_PROFILING_SETTINGS_PROFILING_ENABLED SYSREQ_PROFILING_SETTINGS_SQL_PROFILING_ENABLED SYSREQ_PROFILING_SETTINGS_START_LOGGED SYSREQ_RECORD_STATUS SYSREQ_REF_REQ_FIELD_NAME SYSREQ_REF_REQ_FORMAT SYSREQ_REF_REQ_GENERATED SYSREQ_REF_REQ_LENGTH SYSREQ_REF_REQ_PRECISION SYSREQ_REF_REQ_REFERENCE SYSREQ_REF_REQ_SECTION SYSREQ_REF_REQ_STORED SYSREQ_REF_REQ_TOKENS SYSREQ_REF_REQ_TYPE SYSREQ_REF_REQ_VIEW SYSREQ_REF_TYPE_ACT_CODE SYSREQ_REF_TYPE_ACT_DESCRIPTION SYSREQ_REF_TYPE_ACT_DESCRIPTION_LOCALIZE_ID SYSREQ_REF_TYPE_ACT_ON_EXECUTE SYSREQ_REF_TYPE_ACT_ON_EXECUTE_EXISTS SYSREQ_REF_TYPE_ACT_SECTION SYSREQ_REF_TYPE_ADD_PARAMS SYSREQ_REF_TYPE_COMMENT SYSREQ_REF_TYPE_COMMON_SETTINGS SYSREQ_REF_TYPE_DISPLAY_REQUISITE_NAME SYSREQ_REF_TYPE_EVENT_TEXT SYSREQ_REF_TYPE_MAIN_LEADING_REF SYSREQ_REF_TYPE_NAME_IN_SINGULAR SYSREQ_REF_TYPE_NAME_IN_SINGULAR_LOCALIZE_ID SYSREQ_REF_TYPE_NAME_LOCALIZE_ID SYSREQ_REF_TYPE_NUMERATION_METHOD SYSREQ_REF_TYPE_REQ_CODE SYSREQ_REF_TYPE_REQ_DESCRIPTION SYSREQ_REF_TYPE_REQ_DESCRIPTION_LOCALIZE_ID SYSREQ_REF_TYPE_REQ_IS_CONTROL SYSREQ_REF_TYPE_REQ_IS_FILTER SYSREQ_REF_TYPE_REQ_IS_LEADING SYSREQ_REF_TYPE_REQ_IS_REQUIRED SYSREQ_REF_TYPE_REQ_NUMBER SYSREQ_REF_TYPE_REQ_ON_CHANGE SYSREQ_REF_TYPE_REQ_ON_CHANGE_EXISTS SYSREQ_REF_TYPE_REQ_ON_SELECT SYSREQ_REF_TYPE_REQ_ON_SELECT_KIND SYSREQ_REF_TYPE_REQ_SECTION SYSREQ_REF_TYPE_VIEW_CARD SYSREQ_REF_TYPE_VIEW_CODE SYSREQ_REF_TYPE_VIEW_COMMENT SYSREQ_REF_TYPE_VIEW_IS_MAIN SYSREQ_REF_TYPE_VIEW_NAME SYSREQ_REF_TYPE_VIEW_NAME_LOCALIZE_ID SYSREQ_REFERENCE_TYPE_ID SYSREQ_STATE SYSREQ_STATЕ SYSREQ_SYSTEM_SETTINGS_VALUE SYSREQ_TYPE SYSREQ_UNIT SYSREQ_UNIT_ID SYSREQ_USER_GROUPS_GROUP_FULL_NAME SYSREQ_USER_GROUPS_GROUP_NAME SYSREQ_USER_GROUPS_GROUP_SERVER_NAME SYSREQ_USERS_ACCESS_RIGHTS SYSREQ_USERS_AUTHENTICATION SYSREQ_USERS_CATEGORY SYSREQ_USERS_COMPONENT SYSREQ_USERS_COMPONENT_USER_IS_PUBLIC SYSREQ_USERS_DOMAIN SYSREQ_USERS_FULL_USER_NAME SYSREQ_USERS_GROUP SYSREQ_USERS_IS_MAIN_SERVER SYSREQ_USERS_LOGIN SYSREQ_USERS_REFERENCE_USER_IS_PUBLIC SYSREQ_USERS_STATUS SYSREQ_USERS_USER_CERTIFICATE SYSREQ_USERS_USER_CERTIFICATE_INFO SYSREQ_USERS_USER_CERTIFICATE_PLUGIN_NAME SYSREQ_USERS_USER_CERTIFICATE_PLUGIN_VERSION SYSREQ_USERS_USER_CERTIFICATE_STATE SYSREQ_USERS_USER_CERTIFICATE_SUBJECT_NAME SYSREQ_USERS_USER_CERTIFICATE_THUMBPRINT SYSREQ_USERS_USER_DEFAULT_CERTIFICATE SYSREQ_USERS_USER_DESCRIPTION SYSREQ_USERS_USER_GLOBAL_NAME SYSREQ_USERS_USER_LOGIN SYSREQ_USERS_USER_MAIN_SERVER SYSREQ_USERS_USER_TYPE SYSREQ_WORK_RULES_FOLDER_ID RESULT_VAR_NAME RESULT_VAR_NAME_ENG AUTO_NUMERATION_RULE_ID CANT_CHANGE_ID_REQUISITE_RULE_ID CANT_CHANGE_OURFIRM_REQUISITE_RULE_ID CHECK_CHANGING_REFERENCE_RECORD_USE_RULE_ID CHECK_CODE_REQUISITE_RULE_ID CHECK_DELETING_REFERENCE_RECORD_USE_RULE_ID CHECK_FILTRATER_CHANGES_RULE_ID CHECK_RECORD_INTERVAL_RULE_ID CHECK_REFERENCE_INTERVAL_RULE_ID CHECK_REQUIRED_DATA_FULLNESS_RULE_ID CHECK_REQUIRED_REQUISITES_FULLNESS_RULE_ID MAKE_RECORD_UNRATIFIED_RULE_ID RESTORE_AUTO_NUMERATION_RULE_ID SET_FIRM_CONTEXT_FROM_RECORD_RULE_ID SET_FIRST_RECORD_IN_LIST_FORM_RULE_ID SET_IDSPS_VALUE_RULE_ID SET_NEXT_CODE_VALUE_RULE_ID SET_OURFIRM_BOUNDS_RULE_ID SET_OURFIRM_REQUISITE_RULE_ID SCRIPT_BLOCK_AFTER_FINISH_EVENT SCRIPT_BLOCK_BEFORE_START_EVENT SCRIPT_BLOCK_EXECUTION_RESULTS_PROPERTY SCRIPT_BLOCK_NAME_PROPERTY SCRIPT_BLOCK_SCRIPT_PROPERTY SUBTASK_BLOCK_ABORT_DEADLINE_PROPERTY SUBTASK_BLOCK_AFTER_FINISH_EVENT SUBTASK_BLOCK_ASSIGN_PARAMS_EVENT SUBTASK_BLOCK_ATTACHMENTS_PROPERTY SUBTASK_BLOCK_ATTACHMENTS_RIGHTS_GROUP_PROPERTY SUBTASK_BLOCK_ATTACHMENTS_RIGHTS_TYPE_PROPERTY SUBTASK_BLOCK_BEFORE_START_EVENT SUBTASK_BLOCK_CREATED_TASK_PROPERTY SUBTASK_BLOCK_CREATION_EVENT SUBTASK_BLOCK_DEADLINE_PROPERTY SUBTASK_BLOCK_IMPORTANCE_PROPERTY SUBTASK_BLOCK_INITIATOR_PROPERTY SUBTASK_BLOCK_IS_RELATIVE_ABORT_DEADLINE_PROPERTY SUBTASK_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY SUBTASK_BLOCK_JOBS_TYPE_PROPERTY SUBTASK_BLOCK_NAME_PROPERTY SUBTASK_BLOCK_PARALLEL_ROUTE_PROPERTY SUBTASK_BLOCK_PERFORMERS_PROPERTY SUBTASK_BLOCK_RELATIVE_ABORT_DEADLINE_TYPE_PROPERTY SUBTASK_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY SUBTASK_BLOCK_REQUIRE_SIGN_PROPERTY SUBTASK_BLOCK_STANDARD_ROUTE_PROPERTY SUBTASK_BLOCK_START_EVENT SUBTASK_BLOCK_STEP_CONTROL_PROPERTY SUBTASK_BLOCK_SUBJECT_PROPERTY SUBTASK_BLOCK_TASK_CONTROL_PROPERTY SUBTASK_BLOCK_TEXT_PROPERTY SUBTASK_BLOCK_UNLOCK_ATTACHMENTS_ON_STOP_PROPERTY SUBTASK_BLOCK_USE_STANDARD_ROUTE_PROPERTY SUBTASK_BLOCK_WAIT_FOR_TASK_COMPLETE_PROPERTY SYSCOMP_CONTROL_JOBS SYSCOMP_FOLDERS SYSCOMP_JOBS SYSCOMP_NOTICES SYSCOMP_TASKS SYSDLG_CREATE_EDOCUMENT SYSDLG_CREATE_EDOCUMENT_VERSION SYSDLG_CURRENT_PERIOD SYSDLG_EDIT_FUNCTION_HELP SYSDLG_EDOCUMENT_KINDS_FOR_TEMPLATE SYSDLG_EXPORT_MULTIPLE_EDOCUMENTS SYSDLG_EXPORT_SINGLE_EDOCUMENT SYSDLG_IMPORT_EDOCUMENT SYSDLG_MULTIPLE_SELECT SYSDLG_SETUP_ACCESS_RIGHTS SYSDLG_SETUP_DEFAULT_RIGHTS SYSDLG_SETUP_FILTER_CONDITION SYSDLG_SETUP_SIGN_RIGHTS SYSDLG_SETUP_TASK_OBSERVERS SYSDLG_SETUP_TASK_ROUTE SYSDLG_SETUP_USERS_LIST SYSDLG_SIGN_EDOCUMENT SYSDLG_SIGN_MULTIPLE_EDOCUMENTS SYSREF_ACCESS_RIGHTS_TYPES SYSREF_ADMINISTRATION_HISTORY SYSREF_ALL_AVAILABLE_COMPONENTS SYSREF_ALL_AVAILABLE_PRIVILEGES SYSREF_ALL_REPLICATING_COMPONENTS SYSREF_AVAILABLE_DEVELOPERS_COMPONENTS SYSREF_CALENDAR_EVENTS SYSREF_COMPONENT_TOKEN_HISTORY SYSREF_COMPONENT_TOKENS SYSREF_COMPONENTS SYSREF_CONSTANTS SYSREF_DATA_RECEIVE_PROTOCOL SYSREF_DATA_SEND_PROTOCOL SYSREF_DIALOGS SYSREF_DIALOGS_REQUISITES SYSREF_EDITORS SYSREF_EDOC_CARDS SYSREF_EDOC_TYPES SYSREF_EDOCUMENT_CARD_REQUISITES SYSREF_EDOCUMENT_CARD_TYPES SYSREF_EDOCUMENT_CARD_TYPES_REFERENCE SYSREF_EDOCUMENT_CARDS SYSREF_EDOCUMENT_HISTORY SYSREF_EDOCUMENT_KINDS SYSREF_EDOCUMENT_REQUISITES SYSREF_EDOCUMENT_SIGNATURES SYSREF_EDOCUMENT_TEMPLATES SYSREF_EDOCUMENT_TEXT_STORAGES SYSREF_EDOCUMENT_VIEWS SYSREF_FILTERER_SETUP_CONFLICTS SYSREF_FILTRATER_SETTING_CONFLICTS SYSREF_FOLDER_HISTORY SYSREF_FOLDERS SYSREF_FUNCTION_GROUPS SYSREF_FUNCTION_PARAMS SYSREF_FUNCTIONS SYSREF_JOB_HISTORY SYSREF_LINKS SYSREF_LOCALIZATION_DICTIONARY SYSREF_LOCALIZATION_LANGUAGES SYSREF_MODULES SYSREF_PRIVILEGES SYSREF_RECORD_HISTORY SYSREF_REFERENCE_REQUISITES SYSREF_REFERENCE_TYPE_VIEWS SYSREF_REFERENCE_TYPES SYSREF_REFERENCES SYSREF_REFERENCES_REQUISITES SYSREF_REMOTE_SERVERS SYSREF_REPLICATION_SESSIONS_LOG SYSREF_REPLICATION_SESSIONS_PROTOCOL SYSREF_REPORTS SYSREF_ROLES SYSREF_ROUTE_BLOCK_GROUPS SYSREF_ROUTE_BLOCKS SYSREF_SCRIPTS SYSREF_SEARCHES SYSREF_SERVER_EVENTS SYSREF_SERVER_EVENTS_HISTORY SYSREF_STANDARD_ROUTE_GROUPS SYSREF_STANDARD_ROUTES SYSREF_STATUSES SYSREF_SYSTEM_SETTINGS SYSREF_TASK_HISTORY SYSREF_TASK_KIND_GROUPS SYSREF_TASK_KINDS SYSREF_TASK_RIGHTS SYSREF_TASK_SIGNATURES SYSREF_TASKS SYSREF_UNITS SYSREF_USER_GROUPS SYSREF_USER_GROUPS_REFERENCE SYSREF_USER_SUBSTITUTION SYSREF_USERS SYSREF_USERS_REFERENCE SYSREF_VIEWERS SYSREF_WORKING_TIME_CALENDARS ACCESS_RIGHTS_TABLE_NAME EDMS_ACCESS_TABLE_NAME EDOC_TYPES_TABLE_NAME TEST_DEV_DB_NAME TEST_DEV_SYSTEM_CODE TEST_EDMS_DB_NAME TEST_EDMS_MAIN_CODE TEST_EDMS_MAIN_DB_NAME TEST_EDMS_SECOND_CODE TEST_EDMS_SECOND_DB_NAME TEST_EDMS_SYSTEM_CODE TEST_ISB5_MAIN_CODE TEST_ISB5_SECOND_CODE TEST_SQL_SERVER_2005_NAME TEST_SQL_SERVER_NAME ATTENTION_CAPTION cbsCommandLinks cbsDefault CONFIRMATION_CAPTION ERROR_CAPTION INFORMATION_CAPTION mrCancel mrOk EDOC_VERSION_ACTIVE_STAGE_CODE EDOC_VERSION_DESIGN_STAGE_CODE EDOC_VERSION_OBSOLETE_STAGE_CODE cpDataEnciphermentEnabled cpDigitalSignatureEnabled cpID cpIssuer cpPluginVersion cpSerial cpSubjectName cpSubjSimpleName cpValidFromDate cpValidToDate ISBL_SYNTAX NO_SYNTAX XML_SYNTAX WAIT_BLOCK_AFTER_FINISH_EVENT WAIT_BLOCK_BEFORE_START_EVENT WAIT_BLOCK_DEADLINE_PROPERTY WAIT_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY WAIT_BLOCK_NAME_PROPERTY WAIT_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY SYSRES_COMMON SYSRES_CONST SYSRES_MBFUNC SYSRES_SBDATA SYSRES_SBGUI SYSRES_SBINTF SYSRES_SBREFDSC SYSRES_SQLERRORS SYSRES_SYSCOMP) + b["enum"] = Set.new %w(atUser atGroup atRole aemEnabledAlways aemDisabledAlways aemEnabledOnBrowse aemEnabledOnEdit aemDisabledOnBrowseEmpty apBegin apEnd alLeft alRight asmNever asmNoButCustomize asmAsLastTime asmYesButCustomize asmAlways cirCommon cirRevoked ctSignature ctEncode ctSignatureEncode clbUnchecked clbChecked clbGrayed ceISB ceAlways ceNever ctDocument ctReference ctScript ctUnknown ctReport ctDialog ctFunction ctFolder ctEDocument ctTask ctJob ctNotice ctControlJob cfInternal cfDisplay ciUnspecified ciWrite ciRead ckFolder ckEDocument ckTask ckJob ckComponentToken ckAny ckReference ckScript ckReport ckDialog ctISBLEditor ctBevel ctButton ctCheckListBox ctComboBox ctComboEdit ctGrid ctDBCheckBox ctDBComboBox ctDBEdit ctDBEllipsis ctDBMemo ctDBNavigator ctDBRadioGroup ctDBStatusLabel ctEdit ctGroupBox ctInplaceHint ctMemo ctPanel ctListBox ctRadioButton ctRichEdit ctTabSheet ctWebBrowser ctImage ctHyperLink ctLabel ctDBMultiEllipsis ctRibbon ctRichView ctInnerPanel ctPanelGroup ctBitButton cctDate cctInteger cctNumeric cctPick cctReference cctString cctText cltInternal cltPrimary cltGUI dseBeforeOpen dseAfterOpen dseBeforeClose dseAfterClose dseOnValidDelete dseBeforeDelete dseAfterDelete dseAfterDeleteOutOfTransaction dseOnDeleteError dseBeforeInsert dseAfterInsert dseOnValidUpdate dseBeforeUpdate dseOnUpdateRatifiedRecord dseAfterUpdate dseAfterUpdateOutOfTransaction dseOnUpdateError dseAfterScroll dseOnOpenRecord dseOnCloseRecord dseBeforeCancel dseAfterCancel dseOnUpdateDeadlockError dseBeforeDetailUpdate dseOnPrepareUpdate dseOnAnyRequisiteChange dssEdit dssInsert dssBrowse dssInActive dftDate dftShortDate dftDateTime dftTimeStamp dotDays dotHours dotMinutes dotSeconds dtkndLocal dtkndUTC arNone arView arEdit arFull ddaView ddaEdit emLock emEdit emSign emExportWithLock emImportWithUnlock emChangeVersionNote emOpenForModify emChangeLifeStage emDelete emCreateVersion emImport emUnlockExportedWithLock emStart emAbort emReInit emMarkAsReaded emMarkAsUnreaded emPerform emAccept emResume emChangeRights emEditRoute emEditObserver emRecoveryFromLocalCopy emChangeWorkAccessType emChangeEncodeTypeToCertificate emChangeEncodeTypeToPassword emChangeEncodeTypeToNone emChangeEncodeTypeToCertificatePassword emChangeStandardRoute emGetText emOpenForView emMoveToStorage emCreateObject emChangeVersionHidden emDeleteVersion emChangeLifeCycleStage emApprovingSign emExport emContinue emLockFromEdit emUnLockForEdit emLockForServer emUnlockFromServer emDelegateAccessRights emReEncode ecotFile ecotProcess eaGet eaCopy eaCreate eaCreateStandardRoute edltAll edltNothing edltQuery essmText essmCard esvtLast esvtLastActive esvtSpecified edsfExecutive edsfArchive edstSQLServer edstFile edvstNone edvstEDocumentVersionCopy edvstFile edvstTemplate edvstScannedFile vsDefault vsDesign vsActive vsObsolete etNone etCertificate etPassword etCertificatePassword ecException ecWarning ecInformation estAll estApprovingOnly evtLast evtLastActive evtQuery fdtString fdtNumeric fdtInteger fdtDate fdtText fdtUnknown fdtWideString fdtLargeInteger ftInbox ftOutbox ftFavorites ftCommonFolder ftUserFolder ftComponents ftQuickLaunch ftShortcuts ftSearch grhAuto grhX1 grhX2 grhX3 hltText hltRTF hltHTML iffBMP iffJPEG iffMultiPageTIFF iffSinglePageTIFF iffTIFF iffPNG im8bGrayscale im24bRGB im1bMonochrome itBMP itJPEG itWMF itPNG ikhInformation ikhWarning ikhError ikhNoIcon icUnknown icScript icFunction icIntegratedReport icAnalyticReport icDataSetEventHandler icActionHandler icFormEventHandler icLookUpEventHandler icRequisiteChangeEventHandler icBeforeSearchEventHandler icRoleCalculation icSelectRouteEventHandler icBlockPropertyCalculation icBlockQueryParamsEventHandler icChangeSearchResultEventHandler icBlockEventHandler icSubTaskInitEventHandler icEDocDataSetEventHandler icEDocLookUpEventHandler icEDocActionHandler icEDocFormEventHandler icEDocRequisiteChangeEventHandler icStructuredConversionRule icStructuredConversionEventBefore icStructuredConversionEventAfter icWizardEventHandler icWizardFinishEventHandler icWizardStepEventHandler icWizardStepFinishEventHandler icWizardActionEnableEventHandler icWizardActionExecuteEventHandler icCreateJobsHandler icCreateNoticesHandler icBeforeLookUpEventHandler icAfterLookUpEventHandler icTaskAbortEventHandler icWorkflowBlockActionHandler icDialogDataSetEventHandler icDialogActionHandler icDialogLookUpEventHandler icDialogRequisiteChangeEventHandler icDialogFormEventHandler icDialogValidCloseEventHandler icBlockFormEventHandler icTaskFormEventHandler icReferenceMethod icEDocMethod icDialogMethod icProcessMessageHandler isShow isHide isByUserSettings jkJob jkNotice jkControlJob jtInner jtLeft jtRight jtFull jtCross lbpAbove lbpBelow lbpLeft lbpRight eltPerConnection eltPerUser sfcUndefined sfcBlack sfcGreen sfcRed sfcBlue sfcOrange sfcLilac sfsItalic sfsStrikeout sfsNormal ldctStandardRoute ldctWizard ldctScript ldctFunction ldctRouteBlock ldctIntegratedReport ldctAnalyticReport ldctReferenceType ldctEDocumentType ldctDialog ldctServerEvents mrcrtNone mrcrtUser mrcrtMaximal mrcrtCustom vtEqual vtGreaterOrEqual vtLessOrEqual vtRange rdYesterday rdToday rdTomorrow rdThisWeek rdThisMonth rdThisYear rdNextMonth rdNextWeek rdLastWeek rdLastMonth rdWindow rdFile rdPrinter rdtString rdtNumeric rdtInteger rdtDate rdtReference rdtAccount rdtText rdtPick rdtUnknown rdtLargeInteger rdtDocument reOnChange reOnChangeValues ttGlobal ttLocal ttUser ttSystem ssmBrowse ssmSelect ssmMultiSelect ssmBrowseModal smSelect smLike smCard stNone stAuthenticating stApproving sctString sctStream sstAnsiSort sstNaturalSort svtEqual svtContain soatString soatNumeric soatInteger soatDatetime soatReferenceRecord soatText soatPick soatBoolean soatEDocument soatAccount soatIntegerCollection soatNumericCollection soatStringCollection soatPickCollection soatDatetimeCollection soatBooleanCollection soatReferenceRecordCollection soatEDocumentCollection soatAccountCollection soatContents soatUnknown tarAbortByUser tarAbortByWorkflowException tvtAllWords tvtExactPhrase tvtAnyWord usNone usCompleted usRedSquare usBlueSquare usYellowSquare usGreenSquare usOrangeSquare usPurpleSquare usFollowUp utUnknown utUser utDeveloper utAdministrator utSystemDeveloper utDisconnected btAnd btDetailAnd btOr btNotOr btOnly vmView vmSelect vmNavigation vsmSingle vsmMultiple vsmMultipleCheck vsmNoSelection wfatPrevious wfatNext wfatCancel wfatFinish wfepUndefined wfepText3 wfepText6 wfepText9 wfepSpinEdit wfepDropDown wfepRadioGroup wfepFlag wfepText12 wfepText15 wfepText18 wfepText21 wfepText24 wfepText27 wfepText30 wfepRadioGroupColumn1 wfepRadioGroupColumn2 wfepRadioGroupColumn3 wfetQueryParameter wfetText wfetDelimiter wfetLabel wptString wptInteger wptNumeric wptBoolean wptDateTime wptPick wptText wptUser wptUserList wptEDocumentInfo wptEDocumentInfoList wptReferenceRecordInfo wptReferenceRecordInfoList wptFolderInfo wptTaskInfo wptContents wptFileName wptDate wsrComplete wsrGoNext wsrGoPrevious wsrCustom wsrCancel wsrGoFinal wstForm wstEDocument wstTaskCard wstReferenceRecordCard wstFinal waAll waPerformers waManual wsbStart wsbFinish wsbNotice wsbStep wsbDecision wsbWait wsbMonitor wsbScript wsbConnector wsbSubTask wsbLifeCycleStage wsbPause wdtInteger wdtFloat wdtString wdtPick wdtDateTime wdtBoolean wdtTask wdtJob wdtFolder wdtEDocument wdtReferenceRecord wdtUser wdtGroup wdtRole wdtIntegerCollection wdtFloatCollection wdtStringCollection wdtPickCollection wdtDateTimeCollection wdtBooleanCollection wdtTaskCollection wdtJobCollection wdtFolderCollection wdtEDocumentCollection wdtReferenceRecordCollection wdtUserCollection wdtGroupCollection wdtRoleCollection wdtContents wdtUserList wdtSearchDescription wdtDeadLine wdtPickSet wdtAccountCollection wiLow wiNormal wiHigh wrtSoft wrtHard wsInit wsRunning wsDone wsControlled wsAborted wsContinued wtmFull wtmFromCurrent wtmOnlyCurrent) + b["global"] = Set.new %w(AltState Application CallType ComponentTokens CreatedJobs CreatedNotices ControlState DialogResult Dialogs EDocuments EDocumentVersionSource Folders GlobalIDs Job Jobs InputValue LookUpReference LookUpRequisiteNames LookUpSearch Object ParentComponent Processes References Requisite ReportName Reports Result Scripts Searches SelectedAttachments SelectedItems SelectMode Sender ServerEvents ServiceFactory ShiftState SubTask SystemDialogs Tasks Wizard Wizards Work ВызовСпособ ИмяОтчета РеквЗнач) + b["interface"] = Set.new %w(IApplication IAccessRights IAccountRepository IAccountSelectionRestrictions IAction IActionList IAdministrationHistoryDescription IAnchors IApplication IArchiveInfo IAttachment IAttachmentList ICheckListBox ICheckPointedList IColumn IComponent IComponentDescription IComponentToken IComponentTokenFactory IComponentTokenInfo ICompRecordInfo IConnection IContents IControl IControlJob IControlJobInfo IControlList ICrypto ICrypto2 ICustomJob ICustomJobInfo ICustomListBox ICustomObjectWizardStep ICustomWork ICustomWorkInfo IDataSet IDataSetAccessInfo IDataSigner IDateCriterion IDateRequisite IDateRequisiteDescription IDateValue IDeaAccessRights IDeaObjectInfo IDevelopmentComponentLock IDialog IDialogFactory IDialogPickRequisiteItems IDialogsFactory IDICSFactory IDocRequisite IDocumentInfo IDualListDialog IECertificate IECertificateInfo IECertificates IEditControl IEditorForm IEdmsExplorer IEdmsObject IEdmsObjectDescription IEdmsObjectFactory IEdmsObjectInfo IEDocument IEDocumentAccessRights IEDocumentDescription IEDocumentEditor IEDocumentFactory IEDocumentInfo IEDocumentStorage IEDocumentVersion IEDocumentVersionListDialog IEDocumentVersionSource IEDocumentWizardStep IEDocVerSignature IEDocVersionState IEnabledMode IEncodeProvider IEncrypter IEvent IEventList IException IExternalEvents IExternalHandler IFactory IField IFileDialog IFolder IFolderDescription IFolderDialog IFolderFactory IFolderInfo IForEach IForm IFormTitle IFormWizardStep IGlobalIDFactory IGlobalIDInfo IGrid IHasher IHistoryDescription IHyperLinkControl IImageButton IImageControl IInnerPanel IInplaceHint IIntegerCriterion IIntegerList IIntegerRequisite IIntegerValue IISBLEditorForm IJob IJobDescription IJobFactory IJobForm IJobInfo ILabelControl ILargeIntegerCriterion ILargeIntegerRequisite ILargeIntegerValue ILicenseInfo ILifeCycleStage IList IListBox ILocalIDInfo ILocalization ILock IMemoryDataSet IMessagingFactory IMetadataRepository INotice INoticeInfo INumericCriterion INumericRequisite INumericValue IObject IObjectDescription IObjectImporter IObjectInfo IObserver IPanelGroup IPickCriterion IPickProperty IPickRequisite IPickRequisiteDescription IPickRequisiteItem IPickRequisiteItems IPickValue IPrivilege IPrivilegeList IProcess IProcessFactory IProcessMessage IProgress IProperty IPropertyChangeEvent IQuery IReference IReferenceCriterion IReferenceEnabledMode IReferenceFactory IReferenceHistoryDescription IReferenceInfo IReferenceRecordCardWizardStep IReferenceRequisiteDescription IReferencesFactory IReferenceValue IRefRequisite IReport IReportFactory IRequisite IRequisiteDescription IRequisiteDescriptionList IRequisiteFactory IRichEdit IRouteStep IRule IRuleList ISchemeBlock IScript IScriptFactory ISearchCriteria ISearchCriterion ISearchDescription ISearchFactory ISearchFolderInfo ISearchForObjectDescription ISearchResultRestrictions ISecuredContext ISelectDialog IServerEvent IServerEventFactory IServiceDialog IServiceFactory ISignature ISignProvider ISignProvider2 ISignProvider3 ISimpleCriterion IStringCriterion IStringList IStringRequisite IStringRequisiteDescription IStringValue ISystemDialogsFactory ISystemInfo ITabSheet ITask ITaskAbortReasonInfo ITaskCardWizardStep ITaskDescription ITaskFactory ITaskInfo ITaskRoute ITextCriterion ITextRequisite ITextValue ITreeListSelectDialog IUser IUserList IValue IView IWebBrowserControl IWizard IWizardAction IWizardFactory IWizardFormElement IWizardParam IWizardPickParam IWizardReferenceParam IWizardStep IWorkAccessRights IWorkDescription IWorkflowAskableParam IWorkflowAskableParams IWorkflowBlock IWorkflowBlockResult IWorkflowEnabledMode IWorkflowParam IWorkflowPickParam IWorkflowReferenceParam IWorkState IWorkTreeCustomNode IWorkTreeJobNode IWorkTreeTaskNode IXMLEditorForm SBCrypto) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/j.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/j.rb new file mode 100644 index 0000000..7a5ede1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/j.rb @@ -0,0 +1,244 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class J < RegexLexer + title 'J' + desc "The J programming language (jsoftware.com)" + tag 'j' + filenames '*.ijs', '*.ijt' + + # For J-specific terms we use, see: + # https://code.jsoftware.com/wiki/Vocabulary/AET + # https://code.jsoftware.com/wiki/Vocabulary/Glossary + + # https://code.jsoftware.com/wiki/Vocabulary/PartsOfSpeech + def self.token_map + @token_map ||= { + noun: Keyword::Constant, + verb: Name::Function, + modifier: Operator, + name: Name, + param: Name::Builtin::Pseudo, + other: Punctuation, + nil => Error, + } + end + + # https://code.jsoftware.com/wiki/NuVoc + def self.inflection_list + @inflection_list ||= ['', '.', ':', '..', '.:', ':.', '::'] + end + + def self.primitive_table + @primitive_table ||= Hash.new([:name]).tap do |h| + { + '()' => [:other], + '=' => [:verb, :other, :other], + '<>+-*%$|,#' => [:verb, :verb, :verb], + '^' => [:verb, :verb, :modifier], + '~"' => [:modifier, :verb, :verb], + '.:@' => [:modifier, :modifier, :modifier], + ';' => [:verb, :modifier, :verb], + '!' => [:verb, :modifier, :modifier], + '/\\' => [:modifier, :modifier, :verb], + '[' => [:verb, nil, :verb], + ']' => [:verb], + '{' => [:verb, :verb, :verb, nil, nil, nil, :verb], + '}' => [:modifier, :verb, :verb, nil, nil, nil, :modifier], + '`' => [:modifier, nil, :modifier], + '&' => [:modifier, :modifier, :modifier, nil, :modifier], + '?' => [:verb, :verb], + 'a' => [:name, :noun, :noun], + 'ACeEIjorv' => [:name, :verb], + 'bdfHMT' => [:name, :modifier], + 'Dt' => [:name, :modifier, :modifier], + 'F' => [:name, :modifier, :modifier, :modifier, :modifier, + :modifier, :modifier], + 'iu' => [:name, :verb, :verb], + 'L' => [:name, :verb, :modifier], + 'mny' => [:param], + 'p' => [:name, :verb, :verb, :verb], + 'qsZ' => [:name, nil, :verb], + 'S' => [:name, nil, :modifier], + 'u' => [:param, :verb, :verb], + 'v' => [:param, :verb], + 'x' => [:param, nil, :verb], + }.each {|k, v| k.each_char {|c| h[c] = v } } + end + end + + def self.primitive(char, inflection) + i = inflection_list.index(inflection) or return Error + token_map[primitive_table[char][i]] + end + + def self.control_words + @control_words ||= Set.new %w( + assert break case catch catchd catcht continue do else elseif end + fcase for if return select throw try while whilst + ) + end + + def self.control_words_id + @control_words_id ||= Set.new %w(for goto label) + end + + state :expr do + rule %r/\s+/, Text + + rule %r'([!-&(-/:-@\[-^`{-~]|[A-Za-z]\b)([.:]*)' do |m| + token J.primitive(m[1], m[2]) + end + + rule %r/(?:\d|_\d?):([.:]*)/ do |m| + token m[1].empty? ? J.token_map[:verb] : Error + end + + rule %r/[\d_][\w.]*([.:]*)/ do |m| + token m[1].empty? ? Num : Error + end + + rule %r/'/, Str::Single, :str + + rule %r/NB\.(?![.:]).*/, Comment::Single + + rule %r/([A-Za-z]\w*)([.:]*)/ do |m| + if m[2] == '.' + word, sep, id = m[1].partition '_' + list = if sep.empty? + J.control_words + elsif not id.empty? + J.control_words_id + end + if list and list.include? word + token Keyword, word + sep + token((word == 'for' ? Name : Name::Label), id) + token Keyword, m[2] + else + token Error + end + else + token m[2].empty? ? Name : Error + end + end + end + + state :str do + rule %r/''/, Str::Escape + rule %r/[^'\n]+/, Str::Single + rule %r/'|$/, Str::Single, :pop! + end + + start do + @note_next = false + end + + state :root do + rule %r/\n/ do + token Text + if @note_next + push :note + @note_next = false + end + end + + # https://code.jsoftware.com/wiki/Vocabulary/com + # https://code.jsoftware.com/wiki/Vocabulary/NounExplicitDefinition + rule %r/ + ([0-4]|13|adverb|conjunction|dyad|monad|noun|verb)([\ \t]+) + (def(?:ine)?\b|:)(?![.:])([\ \t]*) + /x do |m| + groups Keyword::Pseudo, Text, Keyword::Pseudo, Text + @def_body = (m[1] == '0' || m[1] == 'noun') ? :noun : :code + if m[3] == 'define' + # stack: [:root] + # or [:root, ..., :def_next] + pop! if stack.size > 1 + push @def_body + push :def_next # [:root, ..., @def_body, :def_next] + else + push :expl_def + end + end + + rule %r/^([ \t]*)(Note\b(?![.:]))([ \t\r]*)(?!=[.:]|$)/ do + groups Text, Name, Text + @note_next = true + end + + rule %r/[mnuvxy]\b(?![.:])/, Name + mixin :expr + end + + state :def_next do + rule %r/\n/, Text, :pop! + mixin :root + end + + state :expl_def do + rule %r/0\b(?![.:])/ do + token Keyword::Pseudo + # stack: [:root, :expl_def] + # or [:root, ..., :def_next, :expl_def] + pop! if stack.size > 2 + goto @def_body + push :def_next # [:root, ..., @def_body, :def_next] + end + rule %r/'/ do + if @def_body == :noun + token Str::Single + goto :str + else + token Punctuation + goto :q_expr + end + end + rule(//) { pop! } + end + + # `q_expr` lexes the content of a string literal which is a part of an + # explicit definition. + # e.g. dyad def 'x + y' + state :q_expr do + rule %r/''/, Str::Single, :q_str + rule %r/'|$/, Punctuation, :pop! + rule %r/NB\.(?![.:])([^'\n]|'')*/, Comment::Single + mixin :expr + end + + state :q_str do + rule %r/''''/, Str::Escape + rule %r/[^'\n]+/, Str::Single + rule %r/''/, Str::Single, :pop! + rule(/'|$/) { token Punctuation; pop! 2 } + end + + state :note do + mixin :delimiter + rule %r/.+\n?/, Comment::Multiline + end + + state :noun do + mixin :delimiter + rule %r/.+\n?/, Str::Heredoc + end + + state :code do + mixin :delimiter + rule %r/^([ \t]*)(:)([ \t\r]*)$/ do + groups Text, Punctuation, Text + end + mixin :expr + end + + state :delimiter do + rule %r/^([ \t]*)(\))([ \t\r]*$\n?)/ do + groups Text, Punctuation, Text + pop! + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/janet.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/janet.rb new file mode 100644 index 0000000..18b2465 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/janet.rb @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Janet < RegexLexer + title "Janet" + desc "The Janet programming language (janet-lang.org)" + + tag 'janet' + aliases 'jdn' + + filenames '*.janet', '*.jdn' + + mimetypes 'text/x-janet', 'application/x-janet' + + def self.specials + @specials ||= Set.new %w( + break def do fn if quote quasiquote splice set unquote var while + ) + end + + def self.bundled + @bundled ||= Set.new %w( + % %= * *= + ++ += - -- -= -> ->> -?> -?>> / /= < <= = > >= + abstract? accumulate accumulate2 all all-bindings + all-dynamics and apply array array/concat array/ensure + array/fill array/insert array/new array/new-filled + array/peek array/pop array/push array/remove array/slice + array? as-> as?-> asm assert bad-compile bad-parse band + blshift bnot boolean? bor brshift brushift buffer buffer/bit + buffer/bit-clear buffer/bit-set buffer/bit-toggle + buffer/blit buffer/clear buffer/fill buffer/format + buffer/new buffer/new-filled buffer/popn buffer/push-byte + buffer/push-string buffer/push-word buffer/slice buffer? + bxor bytes? case cfunction? chr cli-main comment comp + compare compare= compare< compare<= compare> compare>= + compile complement comptime cond coro count debug + debug/arg-stack debug/break debug/fbreak debug/lineage + debug/stack debug/stacktrace debug/step debug/unbreak + debug/unfbreak debugger-env dec deep-not= deep= default + default-peg-grammar def- defer defmacro defmacro- defn defn- + defglobal describe dictionary? disasm distinct doc doc* + doc-format dofile drop drop-until drop-while dyn each eachk + eachp eachy edefer eflush empty? env-lookup eprin eprinf + eprint eprintf error errorf eval eval-string even? every? + extreme false? fiber/can-resume? fiber/current fiber/getenv + fiber/maxstack fiber/new fiber/root fiber/setenv + fiber/setmaxstack fiber/status fiber? file/close file/flush + file/open file/popen file/read file/seek file/temp + file/write filter find find-index first flatten flatten-into + flush for forv freeze frequencies function? gccollect + gcinterval gcsetinterval generate gensym get get-in getline + hash idempotent? identity import import* if-let if-not + if-with in inc indexed? int/s64 int/u64 int? interleave + interpose invert janet/build janet/config-bits janet/version + juxt juxt* keep keys keyword keyword? kvs label last length + let load-image load-image-dict loop macex macex1 make-env + make-image make-image-dict map mapcat marshal math/-inf + math/abs math/acos math/acosh math/asin math/asinh math/atan + math/atan2 math/atanh math/cbrt math/ceil math/cos math/cosh + math/e math/erf math/erfc math/exp math/exp2 math/expm1 + math/floor math/gamma math/hypot math/inf math/log + math/log10 math/log1p math/log2 math/next math/pi math/pow + math/random math/rng math/rng-buffer math/rng-int + math/rng-uniform math/round math/seedrandom math/sin + math/sinh math/sqrt math/tan math/tanh math/trunc match max + mean merge merge-into min mod module/add-paths module/cache + module/expand-path module/find module/loaders module/loading + module/paths nan? nat? native neg? net/chunk net/close + net/connect net/read net/server net/write next nil? not not= + number? odd? one? or os/arch os/cd os/chmod os/clock + os/cryptorand os/cwd os/date os/dir os/environ os/execute + os/exit os/getenv os/link os/lstat os/mkdir os/mktime + os/perm-int os/perm-string os/readlink os/realpath os/rename + os/rm os/rmdir os/setenv os/shell os/sleep os/stat + os/symlink os/time os/touch os/umask os/which pairs parse + parser/byte parser/clone parser/consume parser/eof + parser/error parser/flush parser/has-more parser/insert + parser/new parser/produce parser/state parser/status + parser/where partial partition peg/compile peg/match pos? + postwalk pp prewalk prin prinf print printf product prompt + propagate protect put put-in quit range reduce reduce2 + repeat repl require resume return reverse reversed root-env + run-context scan-number seq setdyn shortfn signal slice + slurp some sort sort-by sorted sorted-by spit stderr stdin + stdout string string/ascii-lower string/ascii-upper + string/bytes string/check-set string/find string/find-all + string/format string/from-bytes string/has-prefix? + string/has-suffix? string/join string/repeat string/replace + string/replace-all string/reverse string/slice string/split + string/trim string/triml string/trimr string? struct struct? + sum symbol symbol? table table/clone table/getproto + table/new table/rawget table/setproto table/to-struct table? + take take-until take-while tarray/buffer tarray/copy-bytes + tarray/length tarray/new tarray/properties tarray/slice + tarray/swap-bytes thread/close thread/current thread/new + thread/receive thread/send trace tracev true? truthy? try + tuple tuple/brackets tuple/setmap tuple/slice + tuple/sourcemap tuple/type tuple? type unless unmarshal + untrace update update-in use values var- varfn varglobal + walk walk-ind walk-dict when when-let when-with with + with-dyns with-syms with-vars yield zero? zipcoll + ) + end + + def name_token(name) + if self.class.specials.include? name + Keyword + elsif self.class.bundled.include? name + Keyword::Reserved + else + Name::Function + end + end + + punctuation = %r/[_!$%^&*+=~<>.?\/-]/o + symbol = %r/([[:alpha:]]|#{punctuation})([[:word:]]|#{punctuation}|:)*/o + + state :root do + rule %r/#.*?$/, Comment::Single + rule %r/\s+/m, Text::Whitespace + + rule %r/(true|false|nil)\b/, Name::Constant + rule %r/(['~])(#{symbol})/ do + groups Operator, Str::Symbol + end + rule %r/:([[:word:]]|#{punctuation}|:)*/, Keyword::Constant + + # radix-specified numbers + rule %r/[+-]?\d{1,2}r[\w.]+(&[+-]?\w+)?/, Num::Float + + # hex numbers + rule %r/[+-]?0x\h[\h_]*(\.\h[\h_]*)?/, Num::Hex + rule %r/[+-]?0x\.\h[\h_]*/, Num::Hex + + # decimal numbers (Janet treats all decimals as floats) + rule %r/[+-]?\d[\d_]*(\.\d[\d_]*)?([e][+-]?\d+)?/i, Num::Float + rule %r/[+-]?\.\d[\d_]*([e][+-]?\d+)?/i, Num::Float + + rule %r/@?"/, Str::Double, :string + rule %r/@?(`+).*?\1/m, Str::Heredoc + + rule %r/\(/, Punctuation, :function + + rule %r/(')(@?[(\[{])/ do + groups Operator, Punctuation + push :quote + end + + rule %r/(~)(@?[(\[{])/ do + groups Operator, Punctuation + push :quasiquote + end + + rule %r/[\#~,';\|]/, Operator + + rule %r/@?[(){}\[\]]/, Punctuation + + rule symbol, Name + end + + state :string do + rule %r/"/, Str::Double, :pop! + rule %r/\\(u\h{4}|U\h{6})/, Str::Escape + rule %r/\\./, Str::Escape + rule %r/[^"\\]+/, Str::Double + end + + state :function do + rule %r/[\)]/, Punctuation, :pop! + + rule symbol do |m| + case m[0] + when "quote" + token Keyword + goto :quote + when "quasiquote" + token Keyword + goto :quasiquote + else + token name_token(m[0]) + goto :root + end + end + + mixin :root + end + + state :quote do + rule %r/[(\[{]/, Punctuation, :push + rule %r/[)\]}]/, Punctuation, :pop! + rule symbol, Str::Escape + mixin :root + end + + state :quasiquote do + rule %r/(,)(\()/ do + groups Operator, Punctuation + push :function + end + rule %r/(\()(\s*)(unquote)(\s+)(\()/ do + groups Punctuation, Text, Keyword, Text, Punctuation + push :function + end + + rule %r/(,)(#{symbol})/ do + groups Operator, Name + end + rule %r/(\()(\s*)(unquote)(\s+)(#{symbol})/ do + groups Punctuation, Text, Keyword, Text, Name + end + + mixin :quote + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/java.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/java.rb new file mode 100644 index 0000000..f6749a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/java.rb @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Java < RegexLexer + title "Java" + desc "The Java programming language (java.com)" + + tag 'java' + filenames '*.java' + mimetypes 'text/x-java' + + keywords = %w( + assert break case catch continue default do else finally for + if goto instanceof new return switch this throw try while + ) + + declarations = %w( + abstract const enum extends final implements native private protected + public static strictfp super synchronized throws transient volatile + ) + + types = %w(boolean byte char double float int long short var void) + + id = /[[:alpha:]_][[:word:]]*/ + const_name = /[[:upper:]][[:upper:][:digit:]_]*\b/ + class_name = /[[:upper:]][[:alnum:]]*\b/ + + state :root do + rule %r/[^\S\n]+/, Text + rule %r(//.*?$), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + # keywords: go before method names to avoid lexing "throw new XYZ" + # as a method signature + rule %r/(?:#{keywords.join('|')})\b/, Keyword + + rule %r( + (\s*(?:[a-zA-Z_][a-zA-Z0-9_.\[\]<>]*\s+)+?) # return arguments + ([a-zA-Z_][a-zA-Z0-9_]*) # method name + (\s*)(\() # signature start + )mx do |m| + # TODO: do this better, this shouldn't need a delegation + delegate Java, m[1] + token Name::Function, m[2] + token Text, m[3] + token Operator, m[4] + end + + rule %r/@#{id}/, Name::Decorator + rule %r/(?:#{declarations.join('|')})\b/, Keyword::Declaration + rule %r/(?:#{types.join('|')})\b/, Keyword::Type + rule %r/(?:true|false|null)\b/, Keyword::Constant + rule %r/(?:class|interface|record)\b/, Keyword::Declaration, :class + rule %r/(?:import|package)\b/, Keyword::Namespace, :import + rule %r/"""\s*\n.*?(?\|+=:;,.\/?-]/, Operator + + digit = /[0-9]_+[0-9]|[0-9]/ + bin_digit = /[01]_+[01]|[01]/ + oct_digit = /[0-7]_+[0-7]|[0-7]/ + hex_digit = /[0-9a-f]_+[0-9a-f]|[0-9a-f]/i + rule %r/#{digit}+\.#{digit}+([eE]#{digit}+)?[fd]?/, Num::Float + rule %r/0b#{bin_digit}+/i, Num::Bin + rule %r/0x#{hex_digit}+/i, Num::Hex + rule %r/0#{oct_digit}+/, Num::Oct + rule %r/#{digit}+L?/, Num::Integer + rule %r/\n/, Text + end + + state :class do + rule %r/\s+/m, Text + rule id, Name::Class, :pop! + end + + state :import do + rule %r/\s+/m, Text + rule %r/[a-z0-9_.]+\*?/i, Name::Namespace, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/javascript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/javascript.rb new file mode 100644 index 0000000..45a1184 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/javascript.rb @@ -0,0 +1,315 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + # IMPORTANT NOTICE: + # + # Please do not copy this lexer and open a pull request + # for a new language. It will not get merged, you will + # be unhappy, and kittens will cry. + # + class Javascript < RegexLexer + title "JavaScript" + desc "JavaScript, the browser scripting language" + + tag 'javascript' + aliases 'js' + filenames '*.cjs', '*.js', '*.mjs' + mimetypes 'application/javascript', 'application/x-javascript', + 'text/javascript', 'text/x-javascript' + + # Pseudo-documentation: https://stackoverflow.com/questions/1661197/what-characters-are-valid-for-javascript-variable-names + + def self.detect?(text) + return 1 if text.shebang?('node') + return 1 if text.shebang?('jsc') + # TODO: rhino, spidermonkey, etc + end + + state :multiline_comment do + rule %r([*]/), Comment::Multiline, :pop! + rule %r([^*/]+), Comment::Multiline + rule %r([*/]), Comment::Multiline + end + + state :comments_and_whitespace do + rule %r/\s+/, Text + rule %r/|<(script|style).*?\2>|<(?!\?(lasso(script)?|=)))+/im) { delegate parent } + end + + state :nosquarebrackets do + rule %r/\[noprocess\]/, Comment::Preproc, :noprocess + rule %r/<\?(lasso(script)?|=)/i, Comment::Preproc, :anglebrackets + rule(/([^\[<]||<(script|style).*?\2>|<(?!\?(lasso(script)?|=))|\[(?!noprocess))+/im) { delegate parent } + end + + state :noprocess do + rule %r(\[/noprocess\]), Comment::Preproc, :pop! + rule(%r(([^\[]|\[(?!/noprocess))+)i) { delegate parent } + end + + state :squarebrackets do + rule %r/\]/, Comment::Preproc, :pop! + mixin :lasso + end + + state :anglebrackets do + rule %r/\?>/, Comment::Preproc, :pop! + mixin :lasso + end + + state :lassofile do + rule %r/\]|\?>/, Comment::Preproc, :pop! + mixin :lasso + end + + state :whitespacecomments do + rule %r/\s+/, Text + rule %r(//.*?\n), Comment::Single + rule %r(/\*\*!.*?\*/)m, Comment::Doc + rule %r(/\*.*?\*/)m, Comment::Multiline + end + + state :lasso do + mixin :whitespacecomments + + # literals + rule %r/\d*\.\d+(e[+-]?\d+)?/i, Num::Float + rule %r/0x[\da-f]+/i, Num::Hex + rule %r/\d+/, Num::Integer + rule %r/(infinity|NaN)\b/i, Num + rule %r/'[^'\\]*(\\.[^'\\]*)*'/m, Str::Single + rule %r/"[^"\\]*(\\.[^"\\]*)*"/m, Str::Double + rule %r/`[^`]*`/m, Str::Backtick + + # names + rule %r/\$#{id}/, Name::Variable + rule %r/#(#{id}|\d+\b)/, Name::Variable::Instance + rule %r/(\.\s*)('#{id}')/ do + groups Name::Builtin::Pseudo, Name::Variable::Class + end + rule %r/(self)(\s*->\s*)('#{id}')/i do + groups Name::Builtin::Pseudo, Operator, Name::Variable::Class + end + rule %r/(\.\.?\s*)(#{id}(=(?!=))?)/ do + groups Name::Builtin::Pseudo, Name::Other + end + rule %r/(->\\?\s*|&\s*)(#{id}(=(?!=))?)/ do + groups Operator, Name::Other + end + rule %r/(?)(self|inherited|currentcapture|givenblock)\b/i, Name::Builtin::Pseudo + rule %r/-(?!infinity)#{id}/i, Name::Attribute + rule %r/::\s*#{id}/, Name::Label + + # definitions + rule %r/(define)(\s+)(#{id})(\s*=>\s*)(type|trait|thread)\b/i do + groups Keyword::Declaration, Text, Name::Class, Operator, Keyword + end + rule %r((define)(\s+)(#{id})(\s*->\s*)(#{id}=?|[-+*/%]))i do + groups Keyword::Declaration, Text, Name::Class, Operator, Name::Function + push :signature + end + rule %r/(define)(\s+)(#{id})/i do + groups Keyword::Declaration, Text, Name::Function + push :signature + end + rule %r((public|protected|private|provide)(\s+)((#{id}=?|[-+*/%])(?=\s*\()))i do + groups Keyword, Text, Name::Function + push :signature + end + rule %r/(public|protected|private|provide)(\s+)(#{id})/i do + groups Keyword, Text, Name::Function + end + + # keywords + rule %r/(true|false|none|minimal|full|all|void)\b/i, Keyword::Constant + rule %r/(local|var|variable|global|data(?=\s))\b/i, Keyword::Declaration + rule %r/(#{id})(\s+)(in)\b/i do + groups Name, Text, Keyword + end + rule %r/(let|into)(\s+)(#{id})/i do + groups Keyword, Text, Name + end + + # other + rule %r/,/, Punctuation, :commamember + rule %r/(and|or|not)\b/i, Operator::Word + rule %r/(#{id})(\s*::\s*#{id})?(\s*=(?!=|>))/ do + groups Name, Name::Label, Operator + end + + rule %r((/?)([\w.]+)) do |m| + name = m[2].downcase + + if m[1] != '' + token Punctuation, m[1] + end + + if name == 'namespace_using' + token Keyword::Namespace, m[2] + elsif self.class.keywords[:exceptions].include? name + token Name::Exception, m[2] + elsif self.class.keywords[:types].include? name + token Keyword::Type, m[2] + elsif self.class.keywords[:traits].include? name + token Name::Decorator, m[2] + elsif self.class.keywords[:keywords].include? name + token Keyword, m[2] + elsif self.class.keywords[:builtins].include? name + token Name::Builtin, m[2] + else + token Name::Other, m[2] + end + end + + rule %r/(=)(n?bw|n?ew|n?cn|lte?|gte?|n?eq|n?rx|ft)\b/i do + groups Operator, Operator::Word + end + rule %r(:=|[-+*/%=<>&|!?\\]+), Operator + rule %r/[{}():;,@^]/, Punctuation + end + + state :signature do + rule %r/\=>/, Operator, :pop! + rule %r/\)/, Punctuation, :pop! + rule %r/[(,]/, Punctuation, :parameter + mixin :lasso + end + + state :parameter do + rule %r/\)/, Punctuation, :pop! + rule %r/-?#{id}/, Name::Attribute, :pop! + rule %r/\.\.\./, Name::Builtin::Pseudo + mixin :lasso + end + + state :commamember do + rule %r((#{id}=?|[-+*/%])(?=\s*(\(([^()]*\([^()]*\))*[^\)]*\)\s*)?(::[\w.\s]+)?=>)), Name::Function, :signature + mixin :whitespacecomments + rule %r//, Text, :pop! + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lasso/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lasso/keywords.rb new file mode 100644 index 0000000..f5c4eea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lasso/keywords.rb @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# DO NOT EDIT +# This file is automatically generated by `rake builtins:lasso`. +# See tasks/builtins/lasso.rake for more info. + +module Rouge + module Lexers + def Lasso.keywords + @keywords ||= {}.tap do |h| + h[:types] = Set.new ["array", "date", "decimal", "duration", "integer", "map", "pair", "string", "tag", "xml", "null", "boolean", "bytes", "keyword", "list", "locale", "queue", "set", "stack", "staticarray", "atbegin", "bson_iter", "bson", "bytes_document_body", "cache_server_element", "cache_server", "capture", "client_address", "client_ip", "component_container", "component_render_state", "component", "curl", "curltoken", "currency", "custom", "data_document", "database_registry", "dateandtime", "dbgp_packet", "dbgp_server", "debugging_stack", "delve", "dir", "dirdesc", "dns_response", "document_base", "document_body", "document_header", "dsinfo", "eacher", "email_compose", "email_parse", "email_pop", "email_queue_impl_base", "email_queue_impl", "email_smtp", "email_stage_impl_base", "email_stage_impl", "fastcgi_each_fcgi_param", "fastcgi_server", "fcgi_record", "fcgi_request", "file", "filedesc", "filemaker_datasource", "generateforeachkeyed", "generateforeachunkeyed", "generateseries", "hash_map", "html_atomic_element", "html_attr", "html_base", "html_binary", "html_br", "html_cdata", "html_container_element", "html_div", "html_document_body", "html_document_head", "html_eol", "html_fieldset", "html_form", "html_h1", "html_h2", "html_h3", "html_h4", "html_h5", "html_h6", "html_hr", "html_img", "html_input", "html_json", "html_label", "html_legend", "html_link", "html_meta", "html_object", "html_option", "html_raw", "html_script", "html_select", "html_span", "html_style", "html_table", "html_td", "html_text", "html_th", "html_tr", "http_document_header", "http_document", "http_error", "http_header_field", "http_server_connection_handler_globals", "http_server_connection_handler", "http_server_request_logger_thread", "http_server_web_connection", "http_server", "image", "include_cache", "inline_type", "java_jnienv", "jbyte", "jbytearray", "jchar", "jchararray", "jfieldid", "jfloat", "jint", "jmethodid", "jobject", "jshort", "json_decode", "json_encode", "json_literal", "json_object", "lassoapp_compiledsrc_appsource", "lassoapp_compiledsrc_fileresource", "lassoapp_content_rep_halt", "lassoapp_dirsrc_appsource", "lassoapp_dirsrc_fileresource", "lassoapp_installer", "lassoapp_livesrc_appsource", "lassoapp_livesrc_fileresource", "lassoapp_long_expiring_bytes", "lassoapp_manualsrc_appsource", "lassoapp_zip_file_server", "lassoapp_zipsrc_appsource", "lassoapp_zipsrc_fileresource", "ldap", "library_thread_loader", "list_node", "log_impl_base", "log_impl", "magick_image", "map_node", "memberstream", "memory_session_driver_impl_entry", "memory_session_driver_impl", "memory_session_driver", "mime_reader", "mongo_client", "mongo_collection", "mongo_cursor", "mustache_ctx", "mysql_session_driver_impl", "mysql_session_driver", "net_named_pipe", "net_tcp_ssl", "net_tcp", "net_udp_packet", "net_udp", "odbc_session_driver_impl", "odbc_session_driver", "opaque", "os_process", "pair_compare", "pairup", "pdf_barcode", "pdf_chunk", "pdf_color", "pdf_doc", "pdf_font", "pdf_hyphenator", "pdf_image", "pdf_list", "pdf_paragraph", "pdf_phrase", "pdf_read", "pdf_table", "pdf_text", "pdf_typebase", "percent", "portal_impl", "queriable_groupby", "queriable_grouping", "queriable_groupjoin", "queriable_join", "queriable_orderby", "queriable_orderbydescending", "queriable_select", "queriable_selectmany", "queriable_skip", "queriable_take", "queriable_thenby", "queriable_thenbydescending", "queriable_where", "raw_document_body", "regexp", "repeat", "scientific", "security_registry", "serialization_element", "serialization_object_identity_compare", "serialization_reader", "serialization_writer_ref", "serialization_writer_standin", "serialization_writer", "session_delete_expired_thread", "signature", "sourcefile", "sqlite_column", "sqlite_currentrow", "sqlite_db", "sqlite_results", "sqlite_session_driver_impl_entry", "sqlite_session_driver_impl", "sqlite_session_driver", "sqlite_table", "sqlite3_stmt", "sqlite3", "sys_process", "text_document", "tie", "timeonly", "tree_base", "tree_node", "tree_nullnode", "ucal", "usgcpu", "usgvm", "web_error_atend", "web_node_base", "web_node_content_representation_css_specialized", "web_node_content_representation_html_specialized", "web_node_content_representation_js_specialized", "web_node_content_representation_xhr_container", "web_node_echo", "web_node_root", "web_request_impl", "web_request", "web_response_impl", "web_response", "web_router", "websocket_handler", "worker_pool", "xml_attr", "xml_cdatasection", "xml_characterdata", "xml_comment", "xml_document", "xml_documentfragment", "xml_documenttype", "xml_domimplementation", "xml_element", "xml_entity", "xml_entityreference", "xml_namednodemap_attr", "xml_namednodemap_ht", "xml_namednodemap", "xml_node", "xml_nodelist", "xml_notation", "xml_processinginstruction", "xml_text", "xmlstream", "zip_file_impl", "zip_file", "zip_impl", "zip"] + h[:traits] = Set.new ["any", "formattingbase", "html_attributed", "html_element_coreattrs", "html_element_eventsattrs", "html_element_i18nattrs", "lassoapp_capabilities", "lassoapp_resource", "lassoapp_source", "queriable_asstring", "session_driver", "trait_array", "trait_asstring", "trait_backcontractible", "trait_backended", "trait_backexpandable", "trait_close", "trait_contractible", "trait_decompose_assignment", "trait_doubleended", "trait_each_sub", "trait_encodeurl", "trait_endedfullymutable", "trait_expandable", "trait_file", "trait_finite", "trait_finiteforeach", "trait_foreach", "trait_foreachtextelement", "trait_frontcontractible", "trait_frontended", "trait_frontexpandable", "trait_fullymutable", "trait_generator", "trait_generatorcentric", "trait_hashable", "trait_json_serialize", "trait_keyed", "trait_keyedfinite", "trait_keyedforeach", "trait_keyedmutable", "trait_list", "trait_map", "trait_net", "trait_pathcomponents", "trait_positionallykeyed", "trait_positionallysearchable", "trait_queriable", "trait_queriablelambda", "trait_readbytes", "trait_readstring", "trait_scalar", "trait_searchable", "trait_serializable", "trait_setencoding", "trait_setoperations", "trait_stack", "trait_treenode", "trait_writebytes", "trait_writestring", "trait_xml_elementcompat", "trait_xml_nodecompat", "web_connection", "web_node_container", "web_node_content_css_specialized", "web_node_content_document", "web_node_content_html_specialized", "web_node_content_js_specialized", "web_node_content_json_specialized", "web_node_content_representation", "web_node_content", "web_node_postable", "web_node"] + h[:builtins] = Set.new ["__char", "__sync_timestamp__", "_admin_addgroup", "_admin_adduser", "_admin_defaultconnector", "_admin_defaultconnectornames", "_admin_defaultdatabase", "_admin_defaultfield", "_admin_defaultgroup", "_admin_defaulthost", "_admin_defaulttable", "_admin_defaultuser", "_admin_deleteconnector", "_admin_deletedatabase", "_admin_deletefield", "_admin_deletegroup", "_admin_deletehost", "_admin_deletetable", "_admin_deleteuser", "_admin_duplicategroup", "_admin_internaldatabase", "_admin_listconnectors", "_admin_listdatabases", "_admin_listfields", "_admin_listgroups", "_admin_listhosts", "_admin_listtables", "_admin_listusers", "_admin_refreshconnector", "_admin_refreshsecurity", "_admin_servicepath", "_admin_updateconnector", "_admin_updatedatabase", "_admin_updatefield", "_admin_updategroup", "_admin_updatehost", "_admin_updatetable", "_admin_updateuser", "_chartfx_activation_string", "_chartfx_getchallengestring", "_chop_args", "_chop_mimes", "_client_addr_old", "_client_address_old", "_client_ip_old", "_database_names", "_datasource_reload", "_date_current", "_date_format", "_date_msec", "_date_parse", "_execution_timelimit", "_file_chmod", "_initialize", "_jdbc_acceptsurl", "_jdbc_debug", "_jdbc_deletehost", "_jdbc_driverclasses", "_jdbc_driverinfo", "_jdbc_metainfo", "_jdbc_propertyinfo", "_jdbc_setdriver", "_lasso_param", "_log_helper", "_proc_noparam", "_proc_withparam", "_recursion_limit", "_request_param", "_security_binaryexpiration", "_security_flushcaches", "_security_isserialized", "_security_serialexpiration", "_srand", "_strict_literals", "_substring", "_xmlrpc_exconverter", "_xmlrpc_inconverter", "_xmlrpc_xmlinconverter", "action_addinfo", "action_addrecord", "action_setfoundcount", "action_setrecordid", "action_settotalcount", "admin_allowedfileroots", "admin_changeuser", "admin_createuser", "admin_groupassignuser", "admin_grouplistusers", "admin_groupremoveuser", "admin_listgroups", "admin_refreshlicensing", "admin_refreshsecurity", "admin_reloaddatasource", "admin_userlistgroups", "array_iterator", "auth_auth", "auth", "base64", "bean", "bigint", "cache_delete", "cache_empty", "cache_exists", "cache_fetch", "cache_internal", "cache_maintenance", "cache_object", "cache_preferences", "cache_store", "chartfx_records", "chartfx_serve", "chartfx", "choice_list", "choice_listitem", "choicelistitem", "click_text", "client_ipfrominteger", "compare_beginswith", "compare_contains", "compare_endswith", "compare_equalto", "compare_greaterthan", "compare_greaterthanorequals", "compare_greaterthanorequls", "compare_lessthan", "compare_lessthanorequals", "compare_notbeginswith", "compare_notcontains", "compare_notendswith", "compare_notequalto", "compare_notregexp", "compare_regexp", "compare_strictequalto", "compare_strictnotequalto", "compiler_removecacheddoc", "compiler_setdefaultparserflags", "curl_ftp_getfile", "curl_ftp_getlisting", "curl_ftp_putfile", "curl_include_url", "database_changecolumn", "database_changefield", "database_createcolumn", "database_createfield", "database_createtable", "database_fmcontainer", "database_hostinfo", "database_inline", "database_nameitem", "database_realname", "database_removecolumn", "database_removefield", "database_removetable", "database_repeating_valueitem", "database_repeating", "database_repeatingvalueitem", "database_schemanameitem", "database_tablecolumn", "database_tablenameitem", "datasource_name", "datasource_register", "date__date_current", "date__date_format", "date__date_msec", "date__date_parse", "date_add", "date_date", "date_difference", "date_duration", "date_format", "date_getcurrentdate", "date_getday", "date_getdayofweek", "date_gethour", "date_getlocaltimezone", "date_getminute", "date_getmonth", "date_getsecond", "date_gettime", "date_getyear", "date_gmttolocal", "date_localtogmt", "date_maximum", "date_minimum", "date_msec", "date_setformat", "date_subtract", "db_layoutnameitem", "db_layoutnames", "db_nameitem", "db_names", "db_tablenameitem", "db_tablenames", "dbi_column_names", "dbi_field_names", "decimal_setglobaldefaultprecision", "decode_base64", "decode_bheader", "decode_hex", "decode_html", "decode_json", "decode_qheader", "decode_quotedprintable", "decode_quotedprintablebytes", "decode_url", "decode_xml", "decrypt_blowfish2", "default", "define_constant", "define_prototype", "define_tagp", "define_typep", "deserialize", "directory_directorynameitem", "directory_lister", "directory_nameitem", "directorynameitem", "email_mxerror", "encode_base64", "encode_bheader", "encode_break", "encode_breaks", "encode_crc32", "encode_hex", "encode_html", "encode_htmltoxml", "encode_json", "encode_quotedprintable", "encode_quotedprintablebytes", "encode_smart", "encode_sql", "encode_sql92", "encode_stricturl", "encode_url", "encode_xml", "encrypt_blowfish2", "error_currenterror", "error_norecordsfound", "error_seterrorcode", "error_seterrormessage", "euro", "event_schedule", "file_autoresolvefullpaths", "file_chmod", "file_control", "file_copy", "file_create", "file_creationdate", "file_currenterror", "file_delete", "file_exists", "file_getlinecount", "file_getsize", "file_isdirectory", "file_listdirectory", "file_moddate", "file_move", "file_openread", "file_openreadwrite", "file_openwrite", "file_openwriteappend", "file_openwritetruncate", "file_probeeol", "file_processuploads", "file_read", "file_readline", "file_rename", "file_serve", "file_setsize", "file_stream", "file_streamcopy", "file_uploads", "file_waitread", "file_waittimeout", "file_waitwrite", "file_write", "find_soap_ops", "form_param", "global_defined", "global_remove", "global_reset", "globals", "http_getfile", "ical_alarm", "ical_attribute", "ical_calendar", "ical_daylight", "ical_event", "ical_freebusy", "ical_item", "ical_journal", "ical_parse", "ical_standard", "ical_timezone", "ical_todo", "image_url", "img", "include_cgi", "iterator", "java_bean", "java", "json_records", "lasso_comment", "lasso_datasourceis", "lasso_datasourceis4d", "lasso_datasourceisfilemaker", "lasso_datasourceisfilemaker7", "lasso_datasourceisfilemaker9", "lasso_datasourceisfilemakersa", "lasso_datasourceisjdbc", "lasso_datasourceislassomysql", "lasso_datasourceismysql", "lasso_datasourceisodbc", "lasso_datasourceisopenbase", "lasso_datasourceisoracle", "lasso_datasourceispostgresql", "lasso_datasourceisspotlight", "lasso_datasourceissqlite", "lasso_datasourceissqlserver", "lasso_datasourcemodulename", "lasso_datatype", "lasso_disableondemand", "lasso_parser", "lasso_process", "lasso_sessionid", "lasso_siteid", "lasso_siteisrunning", "lasso_sitename", "lasso_siterestart", "lasso_sitestart", "lasso_sitestop", "lasso_tagmodulename", "lasso_updatecheck", "lasso_uptime", "lassoapp_create", "lassoapp_dump", "lassoapp_flattendir", "lassoapp_getappdata", "lassoapp_list", "lassoapp_process", "lassoapp_unitize", "ldml_ldml", "ldml", "link_currentactionparams", "link_currentactionurl", "link_currentgroupparams", "link_currentgroupurl", "link_currentrecordparams", "link_currentrecordurl", "link_currentsearch", "link_currentsearchparams", "link_currentsearchurl", "link_detailparams", "link_detailurl", "link_firstgroupparams", "link_firstgroupurl", "link_firstrecordparams", "link_firstrecordurl", "link_lastgroupparams", "link_lastgroupurl", "link_lastrecordparams", "link_lastrecordurl", "link_nextgroupparams", "link_nextgroupurl", "link_nextrecordparams", "link_nextrecordurl", "link_params", "link_prevgroupparams", "link_prevgroupurl", "link_prevrecordparams", "link_prevrecordurl", "link_setformat", "link_url", "list_additem", "list_fromlist", "list_fromstring", "list_getitem", "list_itemcount", "list_iterator", "list_removeitem", "list_replaceitem", "list_reverseiterator", "list_tostring", "literal", "ljax_end", "ljax_hastarget", "ljax_include", "ljax_start", "local_defined", "local_remove", "local_reset", "locals", "logicalop_value", "logicaloperator_value", "map_iterator", "match_comparator", "match_notrange", "match_notregexp", "match_range", "match_regexp", "math_abs", "math_acos", "math_add", "math_asin", "math_atan", "math_atan2", "math_ceil", "math_converteuro", "math_cos", "math_div", "math_exp", "math_floor", "math_internal_rand", "math_internal_randmax", "math_internal_srand", "math_ln", "math_log", "math_log10", "math_max", "math_min", "math_mod", "math_mult", "math_pow", "math_random", "math_range", "math_rint", "math_roman", "math_round", "math_sin", "math_sqrt", "math_sub", "math_tan", "mime_type", "misc__srand", "misc_randomnumber", "misc_roman", "misc_valid_creditcard", "named_param", "namespace_current", "namespace_delimiter", "namespace_exists", "namespace_file_fullpathexists", "namespace_load", "namespace_page", "namespace_unload", "net", "no_default_output", "object", "once", "oneoff", "op_logicalvalue", "operator_logicalvalue", "option", "postcondition", "precondition", "prettyprintingnsmap", "prettyprintingtypemap", "priorityqueue", "proc_convert", "proc_convertbody", "proc_convertone", "proc_extract", "proc_extractone", "proc_find", "proc_first", "proc_foreach", "proc_get", "proc_join", "proc_lasso", "proc_last", "proc_map_entry", "proc_null", "proc_regexp", "proc_xml", "proc_xslt", "rand", "randomnumber", "raw", "recid_value", "record_count", "recordcount", "recordid_value", "reference", "repeating_valueitem", "repeatingvalueitem", "repetition", "req_column", "req_field", "required_column", "required_field", "response_fileexists", "reverseiterator", "roman", "row_count", "search_columnitem", "search_fielditem", "search_operatoritem", "search_opitem", "search_valueitem", "searchfielditem", "searchoperatoritem", "searchopitem", "searchvalueitem", "serialize", "server_date", "server_day", "server_siteisrunning", "server_sitestart", "server_sitestop", "server_time", "session_addoutputfilter", "session_addvariable", "session_removevariable", "session_setdriver", "set_iterator", "set_reverseiterator", "site_atbegin", "site_restart", "soap_convertpartstopairs", "soap_info", "soap_stub", "sort_columnitem", "sort_fielditem", "sort_orderitem", "sortcolumnitem", "sortfielditem", "sortorderitem", "srand", "stock_quote", "string_charfromname", "string_concatenate", "string_countfields", "string_endswith", "string_extract", "string_findposition", "string_findregexp", "string_fordigit", "string_getfield", "string_getunicodeversion", "string_insert", "string_isalpha", "string_isalphanumeric", "string_isdigit", "string_ishexdigit", "string_islower", "string_isnumeric", "string_ispunctuation", "string_isspace", "string_isupper", "string_length", "string_lowercase", "string_remove", "string_removeleading", "string_removetrailing", "string_replace", "string_replaceregexp", "string_todecimal", "string_tointeger", "string_uppercase", "table_realname", "tags_find", "tags_list", "tags", "tcp_close", "tcp_open", "tcp_send", "tcp_tcp_close", "tcp_tcp_open", "tcp_tcp_send", "thread_abort", "thread_event", "thread_exists", "thread_getcurrentid", "thread_getpriority", "thread_info", "thread_list", "thread_lock", "thread_pipe", "thread_priority_default", "thread_priority_high", "thread_priority_low", "thread_rwlock", "thread_semaphore", "thread_setpriority", "total_records", "treemap_iterator", "url_rewrite", "valid_creditcard", "valid_date", "valid_email", "valid_url", "var_defined", "var_remove", "var_reset", "var_set", "variable_defined", "variable_set", "variables", "variant_count", "vars", "wsdl_extract", "wsdl_getbinding", "wsdl_getbindingforoperation", "wsdl_getbindingoperations", "wsdl_getmessagenamed", "wsdl_getmessageparts", "wsdl_getmessagetriofromporttype", "wsdl_getopbodystyle", "wsdl_getopbodyuse", "wsdl_getoperation", "wsdl_getoplocation", "wsdl_getopmessagetypes", "wsdl_getopsoapaction", "wsdl_getportaddress", "wsdl_getportsforservice", "wsdl_getporttype", "wsdl_getporttypeoperation", "wsdl_getservicedocumentation", "wsdl_getservices", "wsdl_gettargetnamespace", "wsdl_issoapoperation", "wsdl_listoperations", "wsdl_maketest", "xml_extract", "xml_rpc", "xml_rpccall", "xml_rw", "xml_serve", "xml_xml", "xml_xmlstream", "xsd_attribute", "xsd_blankarraybase", "xsd_blankbase", "xsd_buildtype", "xsd_cache", "xsd_checkcardinality", "xsd_continueall", "xsd_continueannotation", "xsd_continueany", "xsd_continueanyattribute", "xsd_continueattribute", "xsd_continueattributegroup", "xsd_continuechoice", "xsd_continuecomplexcontent", "xsd_continuecomplextype", "xsd_continuedocumentation", "xsd_continueextension", "xsd_continuegroup", "xsd_continuekey", "xsd_continuelist", "xsd_continuerestriction", "xsd_continuesequence", "xsd_continuesimplecontent", "xsd_continuesimpletype", "xsd_continueunion", "xsd_deserialize", "xsd_fullyqualifyname", "xsd_generate", "xsd_generateblankfromtype", "xsd_generateblanksimpletype", "xsd_generatetype", "xsd_getschematype", "xsd_issimpletype", "xsd_loadschema", "xsd_lookupnamespaceuri", "xsd_lookuptype", "xsd_processany", "xsd_processattribute", "xsd_processattributegroup", "xsd_processcomplextype", "xsd_processelement", "xsd_processgroup", "xsd_processimport", "xsd_processinclude", "xsd_processschema", "xsd_processsimpletype", "xsd_ref", "xsd_type", "_ffi", "abort_clear", "abort_now", "action_param", "action_params", "action_statement", "admin_authorization", "admin_currentgroups", "admin_currentuserid", "admin_currentusername", "admin_getpref", "admin_initialize", "admin_lassoservicepath", "admin_removepref", "admin_setpref", "admin_userexists", "auth_admin", "auth_check", "auth_custom", "auth_group", "auth_prompt", "auth_user", "bom_utf16be", "bom_utf16le", "bom_utf32be", "bom_utf32le", "bom_utf8", "capture_nearestloopabort", "capture_nearestloopcontinue", "capture_nearestloopcount", "checked", "cipher_decrypt_private", "cipher_decrypt_public", "cipher_decrypt", "cipher_digest", "cipher_encrypt_private", "cipher_encrypt_public", "cipher_encrypt", "cipher_generate_key", "cipher_hmac", "cipher_keylength", "cipher_list", "cipher_open", "cipher_seal", "cipher_sign", "cipher_verify", "client_addr", "client_authorization", "client_browser", "client_contentlength", "client_contenttype", "client_cookielist", "client_cookies", "client_encoding", "client_formmethod", "client_getargs", "client_getparam", "client_getparams", "client_headers", "client_integertoip", "client_iptointeger", "client_password", "client_postargs", "client_postparam", "client_postparams", "client_type", "client_url", "client_username", "column_name", "column_names", "column_type", "column", "compress", "content_addheader", "content_body", "content_encoding", "content_header", "content_replaceheader", "content_type", "cookie_set", "cookie", "curl_easy_cleanup", "curl_easy_duphandle", "curl_easy_getinfo", "curl_easy_init", "curl_easy_reset", "curl_easy_setopt", "curl_easy_strerror", "curl_getdate", "curl_http_version_1_0", "curl_http_version_1_1", "curl_http_version_none", "curl_ipresolve_v4", "curl_ipresolve_v6", "curl_ipresolve_whatever", "curl_multi_perform", "curl_multi_result", "curl_netrc_ignored", "curl_netrc_optional", "curl_netrc_required", "curl_sslversion_default", "curl_sslversion_sslv2", "curl_sslversion_sslv3", "curl_sslversion_tlsv1", "curl_version_asynchdns", "curl_version_debug", "curl_version_gssnegotiate", "curl_version_idn", "curl_version_info", "curl_version_ipv6", "curl_version_kerberos4", "curl_version_largefile", "curl_version_libz", "curl_version_ntlm", "curl_version_spnego", "curl_version_ssl", "curl_version", "curlauth_any", "curlauth_anysafe", "curlauth_basic", "curlauth_digest", "curlauth_gssnegotiate", "curlauth_none", "curlauth_ntlm", "curle_aborted_by_callback", "curle_bad_calling_order", "curle_bad_content_encoding", "curle_bad_download_resume", "curle_bad_function_argument", "curle_bad_password_entered", "curle_couldnt_connect", "curle_couldnt_resolve_host", "curle_couldnt_resolve_proxy", "curle_failed_init", "curle_file_couldnt_read_file", "curle_filesize_exceeded", "curle_ftp_access_denied", "curle_ftp_cant_get_host", "curle_ftp_cant_reconnect", "curle_ftp_couldnt_get_size", "curle_ftp_couldnt_retr_file", "curle_ftp_couldnt_set_ascii", "curle_ftp_couldnt_set_binary", "curle_ftp_couldnt_use_rest", "curle_ftp_port_failed", "curle_ftp_quote_error", "curle_ftp_ssl_failed", "curle_ftp_user_password_incorrect", "curle_ftp_weird_227_format", "curle_ftp_weird_pass_reply", "curle_ftp_weird_pasv_reply", "curle_ftp_weird_server_reply", "curle_ftp_weird_user_reply", "curle_ftp_write_error", "curle_function_not_found", "curle_got_nothing", "curle_http_post_error", "curle_http_range_error", "curle_http_returned_error", "curle_interface_failed", "curle_ldap_cannot_bind", "curle_ldap_invalid_url", "curle_ldap_search_failed", "curle_library_not_found", "curle_login_denied", "curle_malformat_user", "curle_obsolete", "curle_ok", "curle_operation_timeouted", "curle_out_of_memory", "curle_partial_file", "curle_read_error", "curle_recv_error", "curle_send_error", "curle_send_fail_rewind", "curle_share_in_use", "curle_ssl_cacert", "curle_ssl_certproblem", "curle_ssl_cipher", "curle_ssl_connect_error", "curle_ssl_engine_initfailed", "curle_ssl_engine_notfound", "curle_ssl_engine_setfailed", "curle_ssl_peer_certificate", "curle_telnet_option_syntax", "curle_too_many_redirects", "curle_unknown_telnet_option", "curle_unsupported_protocol", "curle_url_malformat_user", "curle_url_malformat", "curle_write_error", "curlftpauth_default", "curlftpauth_ssl", "curlftpauth_tls", "curlftpssl_all", "curlftpssl_control", "curlftpssl_last", "curlftpssl_none", "curlftpssl_try", "curlinfo_connect_time", "curlinfo_content_length_download", "curlinfo_content_length_upload", "curlinfo_content_type", "curlinfo_effective_url", "curlinfo_filetime", "curlinfo_header_size", "curlinfo_http_connectcode", "curlinfo_httpauth_avail", "curlinfo_namelookup_time", "curlinfo_num_connects", "curlinfo_os_errno", "curlinfo_pretransfer_time", "curlinfo_proxyauth_avail", "curlinfo_redirect_count", "curlinfo_redirect_time", "curlinfo_request_size", "curlinfo_response_code", "curlinfo_size_download", "curlinfo_size_upload", "curlinfo_speed_download", "curlinfo_speed_upload", "curlinfo_ssl_engines", "curlinfo_ssl_verifyresult", "curlinfo_starttransfer_time", "curlinfo_total_time", "curlmsg_done", "curlopt_autoreferer", "curlopt_buffersize", "curlopt_cainfo", "curlopt_capath", "curlopt_connecttimeout", "curlopt_cookie", "curlopt_cookiefile", "curlopt_cookiejar", "curlopt_cookiesession", "curlopt_crlf", "curlopt_customrequest", "curlopt_dns_use_global_cache", "curlopt_egdsocket", "curlopt_encoding", "curlopt_failonerror", "curlopt_filetime", "curlopt_followlocation", "curlopt_forbid_reuse", "curlopt_fresh_connect", "curlopt_ftp_account", "curlopt_ftp_create_missing_dirs", "curlopt_ftp_response_timeout", "curlopt_ftp_ssl", "curlopt_ftp_use_eprt", "curlopt_ftp_use_epsv", "curlopt_ftpappend", "curlopt_ftplistonly", "curlopt_ftpport", "curlopt_ftpsslauth", "curlopt_header", "curlopt_http_version", "curlopt_http200aliases", "curlopt_httpauth", "curlopt_httpget", "curlopt_httpheader", "curlopt_httppost", "curlopt_httpproxytunnel", "curlopt_infilesize_large", "curlopt_infilesize", "curlopt_interface", "curlopt_ipresolve", "curlopt_krb4level", "curlopt_low_speed_limit", "curlopt_low_speed_time", "curlopt_mail_from", "curlopt_mail_rcpt", "curlopt_maxconnects", "curlopt_maxfilesize_large", "curlopt_maxfilesize", "curlopt_maxredirs", "curlopt_netrc_file", "curlopt_netrc", "curlopt_nobody", "curlopt_noprogress", "curlopt_port", "curlopt_post", "curlopt_postfields", "curlopt_postfieldsize_large", "curlopt_postfieldsize", "curlopt_postquote", "curlopt_prequote", "curlopt_proxy", "curlopt_proxyauth", "curlopt_proxyport", "curlopt_proxytype", "curlopt_proxyuserpwd", "curlopt_put", "curlopt_quote", "curlopt_random_file", "curlopt_range", "curlopt_readdata", "curlopt_referer", "curlopt_resume_from_large", "curlopt_resume_from", "curlopt_ssl_cipher_list", "curlopt_ssl_verifyhost", "curlopt_ssl_verifypeer", "curlopt_sslcert", "curlopt_sslcerttype", "curlopt_sslengine_default", "curlopt_sslengine", "curlopt_sslkey", "curlopt_sslkeypasswd", "curlopt_sslkeytype", "curlopt_sslversion", "curlopt_tcp_nodelay", "curlopt_timecondition", "curlopt_timeout", "curlopt_timevalue", "curlopt_transfertext", "curlopt_unrestricted_auth", "curlopt_upload", "curlopt_url", "curlopt_use_ssl", "curlopt_useragent", "curlopt_userpwd", "curlopt_verbose", "curlopt_writedata", "curlproxy_http", "curlproxy_socks4", "curlproxy_socks5", "database_adddefaultsqlitehost", "database_database", "database_initialize", "database_name", "database_qs", "database_table_database_tables", "database_table_datasource_databases", "database_table_datasource_hosts", "database_table_datasources", "database_table_table_fields", "database_util_cleanpath", "dbgp_stop_stack_name", "debugging_break", "debugging_breakpoint_get", "debugging_breakpoint_list", "debugging_breakpoint_remove", "debugging_breakpoint_set", "debugging_breakpoint_update", "debugging_context_locals", "debugging_context_self", "debugging_context_vars", "debugging_detach", "debugging_enabled", "debugging_get_context", "debugging_get_stack", "debugging_run", "debugging_step_in", "debugging_step_out", "debugging_step_over", "debugging_stop", "debugging_terminate", "decimal_random", "decompress", "decrypt_blowfish", "define_atbegin", "define_atend", "dns_default", "dns_lookup", "document", "email_attachment_mime_type", "email_digestchallenge", "email_digestresponse", "email_extract", "email_findemails", "email_fix_address_list", "email_fix_address", "email_fs_error_clean", "email_immediate", "email_initialize", "email_merge", "email_mxlookup", "email_pop_priv_extract", "email_pop_priv_quote", "email_pop_priv_substring", "email_queue", "email_result", "email_safeemail", "email_send", "email_status", "email_token", "email_translatebreakstocrlf", "encode_qheader", "encoding_iso88591", "encoding_utf8", "encrypt_blowfish", "encrypt_crammd5", "encrypt_hmac", "encrypt_md5", "eol", "error_code", "error_msg", "error_obj", "error_pop", "error_push", "error_reset", "error_stack", "escape_tag", "evdns_resolve_ipv4", "evdns_resolve_ipv6", "evdns_resolve_reverse_ipv6", "evdns_resolve_reverse", "fail_now", "failure_clear", "fastcgi_createfcgirequest", "fastcgi_handlecon", "fastcgi_handlereq", "fastcgi_initialize", "fastcgi_initiate_request", "fcgi_abort_request", "fcgi_authorize", "fcgi_begin_request", "fcgi_bodychunksize", "fcgi_cant_mpx_conn", "fcgi_data", "fcgi_end_request", "fcgi_filter", "fcgi_get_values_result", "fcgi_get_values", "fcgi_keep_conn", "fcgi_makeendrequestbody", "fcgi_makestdoutbody", "fcgi_max_conns", "fcgi_max_reqs", "fcgi_mpxs_conns", "fcgi_null_request_id", "fcgi_overloaded", "fcgi_params", "fcgi_read_timeout_seconds", "fcgi_readparam", "fcgi_request_complete", "fcgi_responder", "fcgi_stderr", "fcgi_stdin", "fcgi_stdout", "fcgi_unknown_role", "fcgi_unknown_type", "fcgi_version_1", "fcgi_x_stdin", "field_name", "field_names", "field", "file_copybuffersize", "file_defaultencoding", "file_forceroot", "file_modechar", "file_modeline", "file_stderr", "file_stdin", "file_stdout", "file_tempfile", "filemakerds_initialize", "filemakerds", "found_count", "ftp_deletefile", "ftp_getdata", "ftp_getfile", "ftp_getlisting", "ftp_putdata", "ftp_putfile", "generateforeach", "hash_primes", "http_char_colon", "http_char_cr", "http_char_htab", "http_char_lf", "http_char_question", "http_char_space", "http_default_files", "http_read_headers", "http_read_timeout_secs", "http_server_apps_path", "http_server_request_logger", "include_cache_compare", "include_currentpath", "include_filepath", "include_localpath", "include_once", "include_path", "include_raw", "include_url", "include", "includes", "inline_colinfo_name_pos", "inline_colinfo_type_pos", "inline_colinfo_valuelist_pos", "inline_columninfo_pos", "inline_foundcount_pos", "inline_namedget", "inline_namedput", "inline_resultrows_pos", "inline_scopeget", "inline_scopepop", "inline_scopepush", "integer_bitor", "integer_random", "io_dir_dt_blk", "io_dir_dt_chr", "io_dir_dt_dir", "io_dir_dt_fifo", "io_dir_dt_lnk", "io_dir_dt_reg", "io_dir_dt_sock", "io_dir_dt_unknown", "io_dir_dt_wht", "io_file_access", "io_file_chdir", "io_file_chmod", "io_file_chown", "io_file_dirname", "io_file_f_dupfd", "io_file_f_getfd", "io_file_f_getfl", "io_file_f_getlk", "io_file_f_rdlck", "io_file_f_setfd", "io_file_f_setfl", "io_file_f_setlk", "io_file_f_setlkw", "io_file_f_test", "io_file_f_tlock", "io_file_f_ulock", "io_file_f_unlck", "io_file_f_wrlck", "io_file_fd_cloexec", "io_file_fioasync", "io_file_fioclex", "io_file_fiodtype", "io_file_fiogetown", "io_file_fionbio", "io_file_fionclex", "io_file_fionread", "io_file_fiosetown", "io_file_getcwd", "io_file_lchown", "io_file_link", "io_file_lockf", "io_file_lstat_atime", "io_file_lstat_mode", "io_file_lstat_mtime", "io_file_lstat_size", "io_file_mkdir", "io_file_mkfifo", "io_file_mkstemp", "io_file_o_append", "io_file_o_async", "io_file_o_creat", "io_file_o_excl", "io_file_o_exlock", "io_file_o_fsync", "io_file_o_nofollow", "io_file_o_nonblock", "io_file_o_rdonly", "io_file_o_rdwr", "io_file_o_shlock", "io_file_o_sync", "io_file_o_trunc", "io_file_o_wronly", "io_file_pipe", "io_file_readlink", "io_file_realpath", "io_file_remove", "io_file_rename", "io_file_rmdir", "io_file_s_ifblk", "io_file_s_ifchr", "io_file_s_ifdir", "io_file_s_ififo", "io_file_s_iflnk", "io_file_s_ifmt", "io_file_s_ifreg", "io_file_s_ifsock", "io_file_s_irgrp", "io_file_s_iroth", "io_file_s_irusr", "io_file_s_irwxg", "io_file_s_irwxo", "io_file_s_irwxu", "io_file_s_isgid", "io_file_s_isuid", "io_file_s_isvtx", "io_file_s_iwgrp", "io_file_s_iwoth", "io_file_s_iwusr", "io_file_s_ixgrp", "io_file_s_ixoth", "io_file_s_ixusr", "io_file_seek_cur", "io_file_seek_end", "io_file_seek_set", "io_file_stat_atime", "io_file_stat_mode", "io_file_stat_mtime", "io_file_stat_size", "io_file_stderr", "io_file_stdin", "io_file_stdout", "io_file_symlink", "io_file_tempnam", "io_file_truncate", "io_file_umask", "io_file_unlink", "io_net_accept", "io_net_af_inet", "io_net_af_inet6", "io_net_af_unix", "io_net_bind", "io_net_connect", "io_net_getpeername", "io_net_getsockname", "io_net_ipproto_ip", "io_net_ipproto_udp", "io_net_listen", "io_net_msg_oob", "io_net_msg_peek", "io_net_msg_waitall", "io_net_recv", "io_net_recvfrom", "io_net_send", "io_net_sendto", "io_net_shut_rd", "io_net_shut_rdwr", "io_net_shut_wr", "io_net_shutdown", "io_net_so_acceptconn", "io_net_so_broadcast", "io_net_so_debug", "io_net_so_dontroute", "io_net_so_error", "io_net_so_keepalive", "io_net_so_linger", "io_net_so_oobinline", "io_net_so_rcvbuf", "io_net_so_rcvlowat", "io_net_so_rcvtimeo", "io_net_so_reuseaddr", "io_net_so_sndbuf", "io_net_so_sndlowat", "io_net_so_sndtimeo", "io_net_so_timestamp", "io_net_so_type", "io_net_so_useloopback", "io_net_sock_dgram", "io_net_sock_raw", "io_net_sock_rdm", "io_net_sock_seqpacket", "io_net_sock_stream", "io_net_socket", "io_net_sol_socket", "io_net_ssl_accept", "io_net_ssl_begin", "io_net_ssl_connect", "io_net_ssl_end", "io_net_ssl_error", "io_net_ssl_errorstring", "io_net_ssl_funcerrorstring", "io_net_ssl_liberrorstring", "io_net_ssl_read", "io_net_ssl_reasonerrorstring", "io_net_ssl_setacceptstate", "io_net_ssl_setconnectstate", "io_net_ssl_setverifylocations", "io_net_ssl_shutdown", "io_net_ssl_usecertificatechainfile", "io_net_ssl_useprivatekeyfile", "io_net_ssl_write", "java_jvm_create", "java_jvm_getenv", "jdbc_initialize", "json_back_slash", "json_back_space", "json_close_array", "json_close_object", "json_colon", "json_comma", "json_consume_array", "json_consume_object", "json_consume_string", "json_consume_token", "json_cr", "json_debug", "json_deserialize", "json_e_lower", "json_e_upper", "json_f_lower", "json_form_feed", "json_forward_slash", "json_lf", "json_n_lower", "json_negative", "json_open_array", "json_open_object", "json_period", "json_positive", "json_quote_double", "json_rpccall", "json_serialize", "json_t_lower", "json_tab", "json_white_space", "keycolumn_name", "keycolumn_value", "keyfield_name", "keyfield_value", "lasso_currentaction", "lasso_errorreporting", "lasso_executiontimelimit", "lasso_methodexists", "lasso_tagexists", "lasso_uniqueid", "lasso_version", "lassoapp_current_app", "lassoapp_current_include", "lassoapp_do_with_include", "lassoapp_exists", "lassoapp_find_missing_file", "lassoapp_format_mod_date", "lassoapp_get_capabilities_name", "lassoapp_include_current", "lassoapp_include", "lassoapp_initialize_db", "lassoapp_initialize", "lassoapp_invoke_resource", "lassoapp_issourcefileextension", "lassoapp_link", "lassoapp_load_module", "lassoapp_mime_get", "lassoapp_mime_type_appcache", "lassoapp_mime_type_css", "lassoapp_mime_type_csv", "lassoapp_mime_type_doc", "lassoapp_mime_type_docx", "lassoapp_mime_type_eof", "lassoapp_mime_type_eot", "lassoapp_mime_type_gif", "lassoapp_mime_type_html", "lassoapp_mime_type_ico", "lassoapp_mime_type_jpg", "lassoapp_mime_type_js", "lassoapp_mime_type_lasso", "lassoapp_mime_type_map", "lassoapp_mime_type_pdf", "lassoapp_mime_type_png", "lassoapp_mime_type_ppt", "lassoapp_mime_type_rss", "lassoapp_mime_type_svg", "lassoapp_mime_type_swf", "lassoapp_mime_type_tif", "lassoapp_mime_type_ttf", "lassoapp_mime_type_txt", "lassoapp_mime_type_woff", "lassoapp_mime_type_xaml", "lassoapp_mime_type_xap", "lassoapp_mime_type_xbap", "lassoapp_mime_type_xhr", "lassoapp_mime_type_xml", "lassoapp_mime_type_zip", "lassoapp_path_to_method_name", "lassoapp_settingsdb", "layout_name", "lcapi_datasourceadd", "lcapi_datasourcecloseconnection", "lcapi_datasourcedelete", "lcapi_datasourceduplicate", "lcapi_datasourceexecsql", "lcapi_datasourcefindall", "lcapi_datasourceimage", "lcapi_datasourceinfo", "lcapi_datasourceinit", "lcapi_datasourcematchesname", "lcapi_datasourcenames", "lcapi_datasourcenothing", "lcapi_datasourceopand", "lcapi_datasourceopany", "lcapi_datasourceopbw", "lcapi_datasourceopct", "lcapi_datasourceopeq", "lcapi_datasourceopew", "lcapi_datasourceopft", "lcapi_datasourceopgt", "lcapi_datasourceopgteq", "lcapi_datasourceopin", "lcapi_datasourceoplt", "lcapi_datasourceoplteq", "lcapi_datasourceopnbw", "lcapi_datasourceopnct", "lcapi_datasourceopneq", "lcapi_datasourceopnew", "lcapi_datasourceopnin", "lcapi_datasourceopno", "lcapi_datasourceopnot", "lcapi_datasourceopnrx", "lcapi_datasourceopor", "lcapi_datasourceoprx", "lcapi_datasourcepreparesql", "lcapi_datasourceprotectionnone", "lcapi_datasourceprotectionreadonly", "lcapi_datasourcerandom", "lcapi_datasourceschemanames", "lcapi_datasourcescripts", "lcapi_datasourcesearch", "lcapi_datasourcesortascending", "lcapi_datasourcesortcustom", "lcapi_datasourcesortdescending", "lcapi_datasourcetablenames", "lcapi_datasourceterm", "lcapi_datasourcetickle", "lcapi_datasourcetypeblob", "lcapi_datasourcetypeboolean", "lcapi_datasourcetypedate", "lcapi_datasourcetypedecimal", "lcapi_datasourcetypeinteger", "lcapi_datasourcetypestring", "lcapi_datasourceunpreparesql", "lcapi_datasourceupdate", "lcapi_fourchartointeger", "lcapi_listdatasources", "lcapi_loadmodule", "lcapi_loadmodules", "lcapi_updatedatasourceslist", "ldap_scope_base", "ldap_scope_children", "ldap_scope_onelevel", "ldap_scope_subtree", "library_once", "library", "ljapi_initialize", "locale_availablelocales", "locale_canada", "locale_canadafrench", "locale_china", "locale_chinese", "locale_default", "locale_english", "locale_format_style_date_time", "locale_format_style_default", "locale_format_style_full", "locale_format_style_long", "locale_format_style_medium", "locale_format_style_none", "locale_format_style_short", "locale_format", "locale_france", "locale_french", "locale_german", "locale_germany", "locale_isocountries", "locale_isolanguages", "locale_italian", "locale_italy", "locale_japan", "locale_japanese", "locale_korea", "locale_korean", "locale_prc", "locale_setdefault", "locale_simplifiedchinese", "locale_taiwan", "locale_traditionalchinese", "locale_uk", "locale_us", "log_always", "log_critical", "log_deprecated", "log_destination_console", "log_destination_database", "log_destination_file", "log_detail", "log_initialize", "log_level_critical", "log_level_deprecated", "log_level_detail", "log_level_sql", "log_level_warning", "log_max_file_size", "log_setdestination", "log_sql", "log_trim_file_size", "log_warning", "loop_key_pop", "loop_key_push", "loop_key", "loop_pop", "loop_push", "loop_value_pop", "loop_value_push", "loop_value", "main_thread_only", "maxrecords_value", "median", "method_name", "micros", "millis", "mongo_insert_continue_on_error", "mongo_insert_no_validate", "mongo_insert_none", "mongo_query_await_data", "mongo_query_exhaust", "mongo_query_no_cursor_timeout", "mongo_query_none", "mongo_query_oplog_replay", "mongo_query_partial", "mongo_query_slave_ok", "mongo_query_tailable_cursor", "mongo_remove_none", "mongo_remove_single_remove", "mongo_update_multi_update", "mongo_update_no_validate", "mongo_update_none", "mongo_update_upsert", "mustache_compile_file", "mustache_compile_string", "mustache_include", "mysqlds", "namespace_global", "namespace_import", "net_connectinprogress", "net_connectok", "net_typessl", "net_typessltcp", "net_typessludp", "net_typetcp", "net_typeudp", "net_waitread", "net_waittimeout", "net_waitwrite", "nslookup", "odbc_session_driver_mssql", "odbc", "output", "pdf_package", "pdf_rectangle", "pdf_serve", "pi", "postgresql", "process", "protect_now", "queriable_average", "queriable_defaultcompare", "queriable_do", "queriable_internal_combinebindings", "queriable_max", "queriable_min", "queriable_qsort", "queriable_reversecompare", "queriable_sum", "random_seed", "range", "records_array", "records_map", "redirect_url", "referer_url", "referrer_url", "register_thread", "register", "response_filepath", "response_localpath", "response_path", "response_realm", "response_root", "resultset_count", "resultsets", "rows_array", "rows_impl", "schema_name", "security_database", "security_default_realm", "security_initialize", "security_table_groups", "security_table_ug_map", "security_table_users", "selected", "series", "server_admin", "server_ip", "server_name", "server_port", "server_protocol", "server_push", "server_signature", "server_software", "session_abort", "session_addvar", "session_decorate", "session_deleteexpired", "session_end", "session_getdefaultdriver", "session_id", "session_initialize", "session_removevar", "session_result", "session_setdefaultdriver", "session_start", "shown_count", "shown_first", "shown_last", "site_id", "site_name", "skiprecords_value", "sleep", "sqlite_abort", "sqlite_auth", "sqlite_blob", "sqlite_busy", "sqlite_cantopen", "sqlite_constraint", "sqlite_corrupt", "sqlite_createdb", "sqlite_done", "sqlite_empty", "sqlite_error", "sqlite_float", "sqlite_format", "sqlite_full", "sqlite_integer", "sqlite_internal", "sqlite_interrupt", "sqlite_ioerr", "sqlite_locked", "sqlite_mismatch", "sqlite_misuse", "sqlite_nolfs", "sqlite_nomem", "sqlite_notadb", "sqlite_notfound", "sqlite_null", "sqlite_ok", "sqlite_perm", "sqlite_protocol", "sqlite_range", "sqlite_readonly", "sqlite_row", "sqlite_schema", "sqlite_setsleepmillis", "sqlite_setsleeptries", "sqlite_text", "sqlite_toobig", "sqliteconnector", "staticarray_join", "stdout", "stdoutnl", "string_validcharset", "suspend", "sys_appspath", "sys_chroot", "sys_clock", "sys_clockspersec", "sys_credits", "sys_daemon", "sys_databasespath", "sys_detach_exec", "sys_difftime", "sys_dll_ext", "sys_drand48", "sys_environ", "sys_eol", "sys_erand48", "sys_errno", "sys_exec_pid_to_os_pid", "sys_exec", "sys_exit", "sys_fork", "sys_garbagecollect", "sys_getbytessincegc", "sys_getchar", "sys_getegid", "sys_getenv", "sys_geteuid", "sys_getgid", "sys_getgrnam", "sys_getheapfreebytes", "sys_getheapsize", "sys_getlogin", "sys_getpid", "sys_getppid", "sys_getpwnam", "sys_getpwuid", "sys_getstartclock", "sys_getthreadcount", "sys_getuid", "sys_growheapby", "sys_homepath", "sys_is_full_path", "sys_is_windows", "sys_isfullpath", "sys_iswindows", "sys_iterate", "sys_jrand48", "sys_kill_exec", "sys_kill", "sys_lcong48", "sys_librariespath", "sys_library", "sys_listtraits", "sys_listtypes", "sys_listunboundmethods", "sys_load_dynamic_library", "sys_loadlibrary", "sys_lrand48", "sys_masterhomepath", "sys_mrand48", "sys_nrand48", "sys_pid_exec", "sys_pointersize", "sys_rand", "sys_random", "sys_seed48", "sys_setenv", "sys_setgid", "sys_setsid", "sys_setuid", "sys_sigabrt", "sys_sigalrm", "sys_sigbus", "sys_sigchld", "sys_sigcont", "sys_sigfpe", "sys_sighup", "sys_sigill", "sys_sigint", "sys_sigkill", "sys_sigpipe", "sys_sigprof", "sys_sigquit", "sys_sigsegv", "sys_sigstop", "sys_sigsys", "sys_sigterm", "sys_sigtrap", "sys_sigtstp", "sys_sigttin", "sys_sigttou", "sys_sigurg", "sys_sigusr1", "sys_sigusr2", "sys_sigvtalrm", "sys_sigxcpu", "sys_sigxfsz", "sys_srand", "sys_srand48", "sys_srandom", "sys_strerror", "sys_supportpath", "sys_test_exec", "sys_time", "sys_uname", "sys_unsetenv", "sys_usercapimodulepath", "sys_userstartuppath", "sys_version", "sys_wait_exec", "sys_waitpid", "sys_wcontinued", "sys_while", "sys_wnohang", "sys_wuntraced", "table_name", "tag_exists", "thread_var_get", "thread_var_pop", "thread_var_push", "threadvar_find", "threadvar_get", "threadvar_set_asrt", "threadvar_set", "timer", "token_value", "treemap", "u_lb_alphabetic", "u_lb_ambiguous", "u_lb_break_after", "u_lb_break_before", "u_lb_break_both", "u_lb_break_symbols", "u_lb_carriage_return", "u_lb_close_punctuation", "u_lb_combining_mark", "u_lb_complex_context", "u_lb_contingent_break", "u_lb_exclamation", "u_lb_glue", "u_lb_h2", "u_lb_h3", "u_lb_hyphen", "u_lb_ideographic", "u_lb_infix_numeric", "u_lb_inseparable", "u_lb_jl", "u_lb_jt", "u_lb_jv", "u_lb_line_feed", "u_lb_mandatory_break", "u_lb_next_line", "u_lb_nonstarter", "u_lb_numeric", "u_lb_open_punctuation", "u_lb_postfix_numeric", "u_lb_prefix_numeric", "u_lb_quotation", "u_lb_space", "u_lb_surrogate", "u_lb_unknown", "u_lb_word_joiner", "u_lb_zwspace", "u_nt_decimal", "u_nt_digit", "u_nt_none", "u_nt_numeric", "u_sb_aterm", "u_sb_close", "u_sb_format", "u_sb_lower", "u_sb_numeric", "u_sb_oletter", "u_sb_other", "u_sb_sep", "u_sb_sp", "u_sb_sterm", "u_sb_upper", "u_wb_aletter", "u_wb_extendnumlet", "u_wb_format", "u_wb_katakana", "u_wb_midletter", "u_wb_midnum", "u_wb_numeric", "u_wb_other", "ucal_ampm", "ucal_dayofmonth", "ucal_dayofweek", "ucal_dayofweekinmonth", "ucal_dayofyear", "ucal_daysinfirstweek", "ucal_dowlocal", "ucal_dstoffset", "ucal_era", "ucal_extendedyear", "ucal_firstdayofweek", "ucal_hour", "ucal_hourofday", "ucal_julianday", "ucal_lenient", "ucal_listtimezones", "ucal_millisecond", "ucal_millisecondsinday", "ucal_minute", "ucal_month", "ucal_second", "ucal_weekofmonth", "ucal_weekofyear", "ucal_year", "ucal_yearwoy", "ucal_zoneoffset", "uchar_age", "uchar_alphabetic", "uchar_ascii_hex_digit", "uchar_bidi_class", "uchar_bidi_control", "uchar_bidi_mirrored", "uchar_bidi_mirroring_glyph", "uchar_bidi_paired_bracket", "uchar_block", "uchar_canonical_combining_class", "uchar_case_folding", "uchar_case_sensitive", "uchar_dash", "uchar_decomposition_type", "uchar_default_ignorable_code_point", "uchar_deprecated", "uchar_diacritic", "uchar_east_asian_width", "uchar_extender", "uchar_full_composition_exclusion", "uchar_general_category_mask", "uchar_general_category", "uchar_grapheme_base", "uchar_grapheme_cluster_break", "uchar_grapheme_extend", "uchar_grapheme_link", "uchar_hangul_syllable_type", "uchar_hex_digit", "uchar_hyphen", "uchar_id_continue", "uchar_ideographic", "uchar_ids_binary_operator", "uchar_ids_trinary_operator", "uchar_iso_comment", "uchar_join_control", "uchar_joining_group", "uchar_joining_type", "uchar_lead_canonical_combining_class", "uchar_line_break", "uchar_logical_order_exception", "uchar_lowercase_mapping", "uchar_lowercase", "uchar_math", "uchar_name", "uchar_nfc_inert", "uchar_nfc_quick_check", "uchar_nfd_inert", "uchar_nfd_quick_check", "uchar_nfkc_inert", "uchar_nfkc_quick_check", "uchar_nfkd_inert", "uchar_nfkd_quick_check", "uchar_noncharacter_code_point", "uchar_numeric_type", "uchar_numeric_value", "uchar_pattern_syntax", "uchar_pattern_white_space", "uchar_posix_alnum", "uchar_posix_blank", "uchar_posix_graph", "uchar_posix_print", "uchar_posix_xdigit", "uchar_quotation_mark", "uchar_radical", "uchar_s_term", "uchar_script", "uchar_segment_starter", "uchar_sentence_break", "uchar_simple_case_folding", "uchar_simple_lowercase_mapping", "uchar_simple_titlecase_mapping", "uchar_simple_uppercase_mapping", "uchar_soft_dotted", "uchar_terminal_punctuation", "uchar_titlecase_mapping", "uchar_trail_canonical_combining_class", "uchar_unicode_1_name", "uchar_unified_ideograph", "uchar_uppercase_mapping", "uchar_uppercase", "uchar_variation_selector", "uchar_white_space", "uchar_word_break", "uchar_xid_continue", "uncompress", "usage", "uuid_compare", "uuid_copy", "uuid_generate_random", "uuid_generate_time", "uuid_generate", "uuid_is_null", "uuid_parse", "uuid_unparse_lower", "uuid_unparse_upper", "uuid_unparse", "value_listitem", "valuelistitem", "var_keys", "var_values", "wap_isenabled", "wap_maxbuttons", "wap_maxcolumns", "wap_maxhorzpixels", "wap_maxrows", "wap_maxvertpixels", "web_handlefcgirequest", "web_node_content_representation_css", "web_node_content_representation_html", "web_node_content_representation_js", "web_node_content_representation_xhr", "web_node_forpath", "web_nodes_initialize", "web_nodes_normalizeextension", "web_nodes_processcontentnode", "web_nodes_requesthandler", "web_response_nodesentry", "web_router_database", "web_router_initialize", "websocket_handler_timeout", "wexitstatus", "wifcontinued", "wifexited", "wifsignaled", "wifstopped", "wstopsig", "wtermsig", "xml_transform", "zip_add_dir", "zip_add", "zip_checkcons", "zip_close", "zip_cm_bzip2", "zip_cm_default", "zip_cm_deflate", "zip_cm_deflate64", "zip_cm_implode", "zip_cm_pkware_implode", "zip_cm_reduce_1", "zip_cm_reduce_2", "zip_cm_reduce_3", "zip_cm_reduce_4", "zip_cm_shrink", "zip_cm_store", "zip_create", "zip_delete", "zip_em_3des_112", "zip_em_3des_168", "zip_em_aes_128", "zip_em_aes_192", "zip_em_aes_256", "zip_em_des", "zip_em_none", "zip_em_rc2_old", "zip_em_rc2", "zip_em_rc4", "zip_em_trad_pkware", "zip_em_unknown", "zip_er_changed", "zip_er_close", "zip_er_compnotsupp", "zip_er_crc", "zip_er_deleted", "zip_er_eof", "zip_er_exists", "zip_er_incons", "zip_er_internal", "zip_er_inval", "zip_er_memory", "zip_er_multidisk", "zip_er_noent", "zip_er_nozip", "zip_er_ok", "zip_er_open", "zip_er_read", "zip_er_remove", "zip_er_rename", "zip_er_seek", "zip_er_tmpopen", "zip_er_write", "zip_er_zipclosed", "zip_er_zlib", "zip_error_get_sys_type", "zip_error_get", "zip_error_to_str", "zip_et_none", "zip_et_sys", "zip_et_zlib", "zip_excl", "zip_fclose", "zip_file_error_get", "zip_file_strerror", "zip_fl_compressed", "zip_fl_nocase", "zip_fl_nodir", "zip_fl_unchanged", "zip_fopen_index", "zip_fopen", "zip_fread", "zip_get_archive_comment", "zip_get_file_comment", "zip_get_name", "zip_get_num_files", "zip_name_locate", "zip_open", "zip_rename", "zip_replace", "zip_set_archive_comment", "zip_set_file_comment", "zip_stat_index", "zip_stat", "zip_strerror", "zip_unchange_all", "zip_unchange_archive", "zip_unchange", "zlib_version"] + h[:keywords] = Set.new ["cache", "database_names", "database_schemanames", "database_tablenames", "define_tag", "define_type", "email_batch", "encode_set", "html_comment", "handle", "handle_error", "header", "if", "inline", "iterate", "ljax_target", "link", "link_currentaction", "link_currentgroup", "link_currentrecord", "link_detail", "link_firstgroup", "link_firstrecord", "link_lastgroup", "link_lastrecord", "link_nextgroup", "link_nextrecord", "link_prevgroup", "link_prevrecord", "log", "loop", "namespace_using", "output_none", "portal", "private", "protect", "records", "referer", "referrer", "repeating", "resultset", "rows", "search_args", "search_arguments", "select", "sort_args", "sort_arguments", "thread_atomic", "value_list", "while", "abort", "case", "else", "fail_if", "fail_ifnot", "fail", "if_empty", "if_false", "if_null", "if_true", "loop_abort", "loop_continue", "loop_count", "params", "params_up", "return", "return_value", "run_children", "soap_definetag", "soap_lastrequest", "soap_lastresponse", "tag_name", "ascending", "average", "by", "define", "descending", "do", "equals", "frozen", "group", "handle_failure", "import", "in", "into", "join", "let", "match", "max", "min", "on", "order", "parent", "protected", "provide", "public", "require", "returnhome", "skip", "split_thread", "sum", "take", "thread", "to", "trait", "type", "where", "with", "yield", "yieldhome"] + h[:exceptions] = Set.new ["error_adderror", "error_columnrestriction", "error_databaseconnectionunavailable", "error_databasetimeout", "error_deleteerror", "error_fieldrestriction", "error_filenotfound", "error_invaliddatabase", "error_invalidpassword", "error_invalidusername", "error_modulenotfound", "error_noerror", "error_nopermission", "error_outofmemory", "error_reqcolumnmissing", "error_reqfieldmissing", "error_requiredcolumnmissing", "error_requiredfieldmissing", "error_updateerror"] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lean.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lean.rb new file mode 100644 index 0000000..d19d7f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lean.rb @@ -0,0 +1,164 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# NOTE: This is for Lean 3 (community fork). +module Rouge + module Lexers + class Lean < RegexLexer + title 'Lean' + desc 'The Lean programming language (leanprover.github.io)' + tag 'lean' + aliases 'lean' + filenames '*.lean' + + def self.keywords + @keywords ||= Set.new %w( + abbreviation + add_rewrite + alias + assume + axiom + begin + by + calc + calc_refl + calc_subst + calc_trans + #check + coercion + conjecture + constant + constants + context + corollary + def + definition + end + #eval + example + export + expose + exposing + exit + extends + from + fun + have + help + hiding + hott + hypothesis + import + include + including + inductive + infix + infixl + infixr + inline + instance + irreducible + lemma + match + namespace + notation + opaque + opaque_hint + open + options + parameter + parameters + postfix + precedence + prefix + #print + private + protected + #reduce + reducible + renaming + repeat + section + set_option + show + tactic_hint + theorem + universe + universes + using + variable + variables + with + ) + end + + def self.types + @types ||= %w( + Sort + Prop + Type + ) + end + + def self.operators + @operators ||= %w( + != # & && \* \+ - / @ ! ` -\. -> + \. \.\. \.\.\. :: :> ; ;; < + <- = == > _ \| \|\| ~ => <= >= + /\ \/ ∀ Π λ ↔ ∧ ∨ ≠ ≤ ≥ ⊎ + ¬ ⁻¹ ⬝ ▸ → ∃ ℕ ℤ ≈ × ⌞ ⌟ ≡ ⟨ ⟩ + ) + end + + state :root do + # comments starting after some space + rule %r/\s*--+\s+.*?$/, Comment::Doc + + rule %r/"/, Str, :string + rule %r/\d+/, Num::Integer + + # special commands or keywords + rule(/#?\w+/) do |m| + match = m[0] + if self.class.keywords.include?(match) + token Keyword + elsif self.class.types.include?(match) + token Keyword::Type + else + token Name + end + end + + # special unicode keywords + rule %r/[λ]/, Keyword + + # ---------------- + # operators rules + # ---------------- + + rule %r/\:=?/, Text + rule %r/\.[0-9]*/, Operator + + rule %r(#{Lean.operators.join('|')}), Operator + + # unmatched symbols + rule %r/[\s\(\),\[\]αβ‹›]+/, Text + + # show missing matches + rule %r/./, Error + + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\/, Str::Escape, :escape + rule %r/[^\\"]+/, Str + end + + state :escape do + rule %r/[nrt"'\\]/, Str::Escape, :pop! + rule %r/x[\da-f]+/i, Str::Escape, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/liquid.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/liquid.rb new file mode 100644 index 0000000..c54d700 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/liquid.rb @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Liquid < RegexLexer + title "Liquid" + desc 'Liquid is a templating engine for Ruby (liquidmarkup.org)' + tag 'liquid' + filenames '*.liquid' + mimetypes 'text/html+liquid' + + state :root do + rule %r/[^\{]+/, Text + + rule %r/(\{%-?)(\s*)/ do + groups Comment::Preproc, Text::Whitespace + push :logic + end + + rule %r/(\{\{-?)(\s*)/ do + groups Comment::Preproc, Text::Whitespace + push :output + end + + rule %r/\{/, Text + end + + state :end_logic do + rule(/(\s*)(-?%\})/) do + groups Text::Whitespace, Comment::Preproc + reset_stack + end + + rule(/\n\s*/) do + token Text::Whitespace + if in_state? :liquid + pop! until state? :liquid + end + end + + mixin :whitespace + end + + state :end_output do + rule(/(\s*)(-?\}\})/) do + groups Text::Whitespace, Comment::Preproc + reset_stack + end + end + + state :liquid do + mixin :end_logic + mixin :logic + end + + state :logic do + rule %r/(liquid)\b/, Name::Tag, :liquid + + # builtin logic blocks + rule %r/(if|elsif|unless|case)\b/, Name::Tag, :condition + rule %r/(when)\b/, Name::Tag, :value + rule %r/(else|ifchanged|end\w+)\b/, Name::Tag, :end_logic + rule %r/(break|continue)\b/, Keyword::Reserved, :end_logic + + # builtin iteration blocks + rule %r/(for|tablerow)(\s+)(\S+)(\s+)(in)(\s+)/ do + groups Name::Tag, Text::Whitespace, Name::Variable, Text::Whitespace, + Name::Tag, Text::Whitespace + push :iteration_args + end + + # other builtin blocks + rule %r/(capture|(?:in|de)crement)(\s+)([a-zA-Z_](?:\w|-(?!%))*)/ do + groups Name::Tag, Text::Whitespace, Name::Variable + push :end_logic + end + + rule %r/(comment)(\s*)(-?%\})/ do + groups Name::Tag, Text::Whitespace, Comment::Preproc + push :comment + end + + rule %r/(raw)(\s*)(-?%\})/ do + groups Name::Tag, Text::Whitespace, Comment::Preproc + push :raw + end + + # builtin tags + rule %r/(assign|echo)\b/, Name::Tag, :assign + + rule %r/(include|render)(\s+)([\/\w-]+(?:\.[\w-]+)+\b)?/ do + groups Name::Tag, Text::Whitespace, Text + push :include + end + + rule %r/(cycle)(\s+)(?:([\w-]+|'[^']*'|"[^"]*")(\s*)(:))?(\s*)/ do |m| + token_class = case m[3] + when %r/'[^']*'/ then Str::Single + when %r/"[^"]*"/ then Str::Double + else + Name::Attribute + end + groups Name::Tag, Text::Whitespace, token_class, + Text::Whitespace, Punctuation, Text::Whitespace + push :tag_args + end + + # custom tags or blocks + rule %r/(\w+)\b/, Name::Tag, :block_args + + mixin :end_logic + end + + state :output do + rule %r/(\|)(\s*)/ do + groups Punctuation, Text::Whitespace + push :filters + push :filter + end + + mixin :end_output + mixin :static + mixin :variable + end + + state :condition do + rule %r/([=!]=|[<>]=?)/, Operator + rule %r/(and|or|contains)\b/, Operator::Word + + mixin :value + end + + state :value do + mixin :end_logic + mixin :static + mixin :variable + end + + state :iteration_args do + rule %r/(reversed|continue)\b/, Name::Attribute + rule %r/\(/, Punctuation, :range + + mixin :tag_args + end + + state :block_args do + rule %r/(\{\{-?)/, Comment::Preproc, :output_embed + + rule %r/(\|)(\s*)/ do + groups Punctuation, Text::Whitespace + push :filters + push :filter + end + + mixin :tag_args + end + + state :tag_args do + mixin :end_logic + mixin :args + end + + state :comment do + rule %r/[^\{]+/, Comment + + rule %r/(\{%-?)(\s*)(endcomment)(\s*)(-?%\})/ do + groups Comment::Preproc, Text::Whitespace, Name::Tag, Text::Whitespace, Comment::Preproc + reset_stack + end + + rule %r/\{/, Comment + end + + state :raw do + rule %r/[^\{]+/, Text + + rule %r/(\{%-?)(\s*)(endraw)(\s*)(-?%\})/ do + groups Comment::Preproc, Text::Whitespace, Name::Tag, Text::Whitespace, Comment::Preproc + reset_stack + end + + rule %r/\{/, Text + end + + state :assign do + rule %r/=/, Operator + rule %r/\(/, Punctuation, :range + + rule %r/(\|)(\s*)/ do + groups Punctuation, Text::Whitespace + push :filters + push :filter + end + + mixin :value + end + + state :include do + rule %r/(\{\{-?)/, Comment::Preproc, :output_embed + rule %r/(with|for|as)\b/, Keyword::Reserved + + mixin :tag_args + end + + state :output_embed do + rule %r/(\|)(\s*)([a-zA-Z_](?:\w|-(?!}))*)/ do + groups Punctuation, Text::Whitespace, Name::Function + end + + rule %r/-?\}\}/, Comment::Preproc, :pop! + + mixin :args + end + + state :range do + rule %r/\.\./, Punctuation + rule %r/\)/, Punctuation, :pop! + + mixin :whitespace + mixin :number + mixin :variable + end + + state :filters do + rule %r/(\|)(\s*)/ do + groups Punctuation, Text::Whitespace + push :filter + end + + mixin :end_logic + mixin :end_output + mixin :args + end + + state :filter do + rule %r/[a-zA-Z_](?:\w|-(?![%}]))*/, Name::Function, :pop! + + mixin :whitespace + end + + state :args do + mixin :static + + rule %r/([a-zA-Z_][\w-]*)(\s*)(=|:)/ do + groups Name::Attribute, Text::Whitespace, Operator + end + + mixin :variable + end + + state :static do + rule %r/(false|true|nil)\b/, Keyword::Constant + rule %r/'[^']*'/, Str::Single + rule %r/"[^"]*"/, Str::Double + rule %r/[,:]/, Punctuation + + mixin :whitespace + mixin :number + end + + state :whitespace do + rule %r/\s+/, Text::Whitespace + rule %r/#.*?(?=$|-?[}%]})/, Comment + end + + state :number do + rule %r/-/, Operator + rule %r/\d+\.\d+/, Num::Float + rule %r/\d+/, Num::Integer + end + + state :variable do + rule %r/(\.)(\s*)(first|last|size)\b(?![?!\/])/ do + groups Punctuation, Text::Whitespace, Name::Function + end + + rule %r/\.(?= *\w)|\[|\]/, Punctuation + rule %r/(empty|blank|(for|tablerow)loop\.(parentloop\.)*\w+)\b(?![?!\/])/, Name::Builtin + rule %r/[a-zA-Z_][\w-]*\b-?(?![?!\/])/, Name::Variable + rule %r/\S+/, Text + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_coffeescript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_coffeescript.rb new file mode 100644 index 0000000..b991fdf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_coffeescript.rb @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class LiterateCoffeescript < RegexLexer + tag 'literate_coffeescript' + title "Literate CoffeeScript" + desc 'Literate coffeescript' + aliases 'litcoffee' + filenames '*.litcoffee' + + def markdown + @markdown ||= Markdown.new(options) + end + + def coffee + @coffee ||= Coffeescript.new(options) + end + + start { markdown.reset!; coffee.reset! } + + state :root do + rule %r/^( .*?\n)+/m do + delegate coffee + end + + rule %r/^([ ]{0,3}(\S.*?|)\n)*/m do + delegate markdown + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_haskell.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_haskell.rb new file mode 100644 index 0000000..cf43e85 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/literate_haskell.rb @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class LiterateHaskell < RegexLexer + title "Literate Haskell" + desc 'Literate haskell' + tag 'literate_haskell' + aliases 'lithaskell', 'lhaskell', 'lhs' + filenames '*.lhs' + mimetypes 'text/x-literate-haskell' + + def haskell + @haskell ||= Haskell.new(options) + end + + start { haskell.reset! } + + # TODO: support TeX versions as well. + state :root do + rule %r/\s*?\n(?=>)/, Text, :code + rule %r/.*?\n/, Text + rule %r/.+\z/, Text + end + + state :code do + rule %r/(>)( .*?(\n|\z))/ do |m| + token Name::Label, m[1] + delegate haskell, m[2] + end + + rule %r/\s*\n(?=\s*[^>])/, Text, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/livescript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/livescript.rb new file mode 100644 index 0000000..0825e63 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/livescript.rb @@ -0,0 +1,310 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Livescript < RegexLexer + tag 'livescript' + aliases 'ls' + filenames '*.ls' + mimetypes 'text/livescript' + + title 'LiveScript' + desc 'LiveScript, a language which compiles to JavaScript (livescript.net)' + + def self.detect?(text) + return text.shebang? 'lsc' + end + + def self.declarations + @declarations ||= Set.new %w(const let var function class extends implements) + end + + def self.keywords + @keywords ||= Set.new %w( + loop until for in of while break return continue switch case + fallthrough default otherwise when then if unless else throw try + catch finally new delete typeof instanceof super by from to til + with require do debugger import export yield + ) + end + + def self.constants + @constants ||= Javascript.constants + %w(yes no on off void) + end + + def self.builtins + @builtins ||= Javascript.builtins + %w(this it that arguments) + end + + def self.loop_control_keywords + @loop_control_keywords ||= Set.new %w(break continue) + end + + id = /[$a-z_]((-(?=[a-z]))?[a-z0-9_])*/i + int_number = /\d[\d_]*/ + int = /#{int_number}(e[+-]?#{int_number})?[$\w]*/ # the last class matches units + + state :root do + rule(%r(^(?=\s|/))) { push :slash_starts_regex } + mixin :comments + mixin :whitespace + + # list of words + rule %r/(<\[)(.*?)(\]>)/m do + groups Punctuation, Str, Punctuation + end + + # function declarations + rule %r/!\s*function\b/, Keyword::Declaration + rule %r/!?[-~]>|<[-~]!?/, Keyword::Declaration + + # switch arrow + rule %r/(=>)/, Keyword + + # prototype attributes + rule %r/(::)(#{id})/ do + groups Punctuation, Name::Attribute + push :id + end + rule %r/(::)(#{int})/ do + groups Punctuation, Num::Integer + push :id + end + + # instance attributes + rule %r/(@)(#{id})/ do + groups Name::Variable::Instance, Name::Attribute + push :id + end + rule %r/([.])(#{id})/ do + groups Punctuation, Name::Attribute + push :id + end + rule %r/([.])(\d+)/ do + groups Punctuation, Num::Integer + push :id + end + rule %r/#{id}(?=\s*:[^:=])/, Name::Attribute + + # operators + rule %r( + [+][+]|--|&&|\b(and|x?or|is(nt)?|not)\b(?!-[a-zA-Z]|_)|[|][|]| + [.]([|&^]|<<|>>>?)[.]|\\(?=\n)|[.:]=|<<<| + (<<|>>|==?|!=?|[-<>+*%^/~?])=? + )x, Operator, :slash_starts_regex + + # arguments shorthand + rule %r/(&)(#{id})?/ do + groups Name::Builtin, Name::Attribute + end + + # switch case + rule %r/[|]|\bcase(?=\s)/, Keyword, :switch_underscore + + rule %r/@/, Name::Variable::Instance + rule %r/[.]{3}/, Punctuation + rule %r/:/, Punctuation + + # keywords + rule %r/#{id}/ do |m| + if self.class.loop_control_keywords.include? m[0] + token Keyword + push :loop_control + next + elsif self.class.keywords.include? m[0] + token Keyword + elsif self.class.constants.include? m[0] + token Name::Constant + elsif self.class.builtins.include? m[0] + token Name::Builtin + elsif self.class.declarations.include? m[0] + token Keyword::Declaration + elsif /^[A-Z]/.match(m[0]) && /[^-][a-z]/.match(m[0]) + token Name::Class + else + token Name::Variable + end + push :id + end + + # punctuation and brackets + rule %r/\](?=[!?.]|#{id})/, Punctuation, :id + rule %r/[{(\[;,]/, Punctuation, :slash_starts_regex + rule %r/[})\].]/, Punctuation + + # literals + rule %r/#{int_number}[.]#{int}/, Num::Float + rule %r/0x[0-9A-Fa-f]+/, Num::Hex + rule %r/#{int}/, Num::Integer + + # strings + rule %r/"""/ do + token Str + push do + rule %r/"""/, Str, :pop! + rule %r/"/, Str + mixin :double_strings + end + end + + rule %r/'''/ do + token Str + push do + rule %r/'''/, Str, :pop! + rule %r/'/, Str + mixin :single_strings + end + end + + rule %r/"/ do + token Str + push do + rule %r/"/, Str, :pop! + mixin :double_strings + end + end + + rule %r/'/ do + token Str + push do + rule %r/'/, Str, :pop! + mixin :single_strings + end + end + + # words + rule %r/\\\S[^\s,;\])}]*/, Str + end + + state :code_escape do + rule %r(\\( + c[A-Z]| + x[0-9a-fA-F]{2}| + u[0-9a-fA-F]{4}| + u\{[0-9a-fA-F]{4}\} + ))x, Str::Escape + end + + state :interpolated_expression do + rule %r/}/, Str::Interpol, :pop! + mixin :root + end + + state :interpolation do + # with curly braces + rule %r/[#][{]/, Str::Interpol, :interpolated_expression + # without curly braces + rule %r/(#)(#{id})/ do |m| + groups Str::Interpol, (self.class.builtins.include? m[2]) ? Name::Builtin : Name::Variable + end + end + + state :whitespace do + # white space and loop labels + rule %r/(\s+?)(?:^([^\S\n]*)(:#{id}))?/m do + groups Text, Text, Name::Label + end + end + + state :whitespace_single_line do + rule %r([^\S\n]+), Text + end + + state :slash_starts_regex do + mixin :comments + mixin :whitespace + mixin :multiline_regex_begin + + rule %r( + /(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/ # a regex + ([gimy]+\b|\B) + )x, Str::Regex, :pop! + + rule(//) { pop! } + end + + state :multiline_regex_begin do + rule %r(//) do + token Str::Regex + goto :multiline_regex + end + end + + state :multiline_regex_end do + rule %r(//([gimy]+\b|\B)), Str::Regex, :pop! + end + + state :multiline_regex do + mixin :multiline_regex_end + mixin :regex_comment + mixin :interpolation + mixin :code_escape + rule %r/\\\D/, Str::Escape + rule %r/\\\d+/, Name::Variable + rule %r/./m, Str::Regex + end + + state :regex_comment do + rule %r/^#(\s+.*)?$/, Comment::Single + rule %r/(\s+)(#)(\s+.*)?$/ do + groups Text, Comment::Single, Comment::Single + end + end + + state :comments do + rule %r(/\*.*?\*/)m, Comment::Multiline + rule %r/#.*$/, Comment::Single + end + + state :switch_underscore do + mixin :whitespace_single_line + rule %r/_(?=\s*=>|\s+then\b)/, Keyword + rule(//) { pop! } + end + + state :loop_control do + mixin :whitespace_single_line + rule %r/#{id}(?=[);\n])/, Name::Label + rule(//) { pop! } + end + + state :id do + rule %r/[!?]|[.](?!=)/, Punctuation + rule %r/[{]/ do + # destructuring + token Punctuation + push do + rule %r/[,;]/, Punctuation + rule %r/#{id}/, Name::Attribute + rule %r/#{int}/, Num::Integer + mixin :whitespace + rule %r/[}]/, Punctuation, :pop! + end + end + rule %r/#{id}/, Name::Attribute + rule %r/#{int}/, Num::Integer + rule(//) { goto :slash_starts_regex } + end + + state :strings do + # all strings are multi-line + rule %r/[^#\\'"]+/m, Str + mixin :code_escape + rule %r/\\./, Str::Escape + rule %r/#/, Str + end + + state :double_strings do + rule %r/'/, Str + mixin :interpolation + mixin :strings + end + + state :single_strings do + rule %r/"/, Str + mixin :strings + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm.rb new file mode 100644 index 0000000..b5ffa44 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm.rb @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class LLVM < RegexLexer + title "LLVM" + desc 'The LLVM Compiler Infrastructure (http://llvm.org/)' + tag 'llvm' + + filenames '*.ll' + mimetypes 'text/x-llvm' + + string = /"[^"]*?"/ + identifier = /([-a-zA-Z$._][-a-zA-Z$._0-9]*|#{string})/ + + def self.keywords + Kernel::load File.join(Lexers::BASE_DIR, "llvm/keywords.rb") + keywords + end + + def self.instructions + Kernel::load File.join(Lexers::BASE_DIR, "llvm/keywords.rb") + instructions + end + + def self.types + Kernel::load File.join(Lexers::BASE_DIR, "llvm/keywords.rb") + types + end + + state :basic do + rule %r/;.*?$/, Comment::Single + rule %r/\s+/, Text + + rule %r/#{identifier}\s*:/, Name::Label + + rule %r/@(#{identifier}|\d+)/, Name::Variable::Global + rule %r/#\d+/, Name::Variable::Global + rule %r/(%|!)#{identifier}/, Name::Variable + rule %r/(%|!)\d+/, Name::Variable + + rule %r/c?#{string}/, Str + + rule %r/0[xX][a-fA-F0-9]+/, Num + rule %r/-?\d+(?:[.]\d+)?(?:[eE][-+]?\d+(?:[.]\d+)?)?/, Num + + rule %r/[=<>{}\[\]()*.,!]|x/, Punctuation + end + + state :root do + mixin :basic + + rule %r/i[1-9]\d*/, Keyword::Type + + rule %r/\w+/ do |m| + if self.class.types.include? m[0] + token Keyword::Type + elsif self.class.instructions.include? m[0] + token Keyword + elsif self.class.keywords.include? m[0] + token Keyword + else + token Error + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm/keywords.rb new file mode 100644 index 0000000..405ee52 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/llvm/keywords.rb @@ -0,0 +1,25 @@ +# encoding: utf-8 +# frozen_string_literal: true + +# DO NOT EDIT +# This file is automatically generated by `rake builtins:llvm`. +# See tasks/builtins/llvm.rake for more info. + +module Rouge + module Lexers + class LLVM + def self.keywords + @keywords ||= Set.new ["aarch64_sve_vector_pcs", "aarch64_vector_pcs", "acq_rel", "acquire", "addrspace", "afn", "alias", "aliasee", "align", "alignLog2", "alignstack", "allOnes", "allocalign", "allocptr", "allocsize", "alwaysInline", "alwaysinline", "amdgpu_cs", "amdgpu_es", "amdgpu_gfx", "amdgpu_gs", "amdgpu_hs", "amdgpu_kernel", "amdgpu_ls", "amdgpu_ps", "amdgpu_vs", "any", "anyregcc", "appending", "arcp", "argmemonly", "args", "arm_aapcs_vfpcc", "arm_aapcscc", "arm_apcscc", "asm", "async", "atomic", "attributes", "available_externally", "avr_intrcc", "avr_signalcc", "bit", "bitMask", "blockaddress", "blockcount", "branchFunnel", "builtin", "byArg", "byref", "byte", "byteArray", "byval", "c", "callee", "caller", "calls", "canAutoHide", "catch", "cc", "ccc", "cfguard_checkcc", "cleanup", "cold", "coldcc", "comdat", "common", "constant", "contract", "convergent", "critical", "cxx_fast_tlscc", "datalayout", "declare", "default", "define", "dereferenceable", "dereferenceable_or_null", "disable_sanitizer_instrumentation", "distinct", "dllexport", "dllimport", "dsoLocal", "dso_local", "dso_local_equivalent", "dso_preemptable", "elementtype", "eq", "exact", "exactmatch", "extern_weak", "external", "externally_initialized", "false", "fast", "fastcc", "filter", "flags", "from", "funcFlags", "function", "gc", "ghccc", "global", "guid", "gv", "hasUnknownCall", "hash", "hhvm_ccc", "hhvmcc", "hidden", "hot", "hotness", "ifunc", "immarg", "inaccessiblemem_or_argmemonly", "inaccessiblememonly", "inalloca", "inbounds", "indir", "info", "initialexec", "inline", "inlineBits", "inlinehint", "inrange", "inreg", "insts", "intel_ocl_bicc", "inteldialect", "internal", "jumptable", "kind", "largest", "linkage", "linkonce", "linkonce_odr", "live", "local_unnamed_addr", "localdynamic", "localexec", "max", "mayThrow", "min", "minsize", "module", "monotonic", "msp430_intrcc", "mustBeUnreachable", "mustprogress", "musttail", "naked", "name", "nand", "ne", "nest", "ninf", "nnan", "noInline", "noRecurse", "noUnwind", "no_cfi", "noalias", "nobuiltin", "nocallback", "nocapture", "nocf_check", "nodeduplicate", "noduplicate", "nofree", "noimplicitfloat", "noinline", "nomerge", "none", "nonlazybind", "nonnull", "noprofile", "norecurse", "noredzone", "noreturn", "nosanitize_bounds", "nosanitize_coverage", "nosync", "notEligibleToImport", "notail", "noundef", "nounwind", "nsw", "nsz", "null", "null_pointer_is_valid", "nuw", "oeq", "offset", "oge", "ogt", "ole", "olt", "one", "opaque", "optforfuzzing", "optnone", "optsize", "ord", "param", "params", "partition", "path", "personality", "poison", "preallocated", "prefix", "preserve_allcc", "preserve_mostcc", "private", "prologue", "protected", "ptx_device", "ptx_kernel", "readNone", "readOnly", "readnone", "readonly", "reassoc", "refs", "relbf", "release", "resByArg", "returnDoesNotAlias", "returned", "returns_twice", "safestack", "samesize", "sanitize_address", "sanitize_hwaddress", "sanitize_memory", "sanitize_memtag", "sanitize_thread", "section", "seq_cst", "sge", "sgt", "shadowcallstack", "sideeffect", "signext", "single", "singleImpl", "singleImplName", "sizeM1", "sizeM1BitWidth", "sle", "slt", "source_filename", "speculatable", "speculative_load_hardening", "spir_func", "spir_kernel", "sret", "ssp", "sspreq", "sspstrong", "strictfp", "summaries", "summary", "swiftasync", "swiftcc", "swifterror", "swiftself", "swifttailcc", "sync", "syncscope", "tail", "tailcc", "target", "thread_local", "to", "triple", "true", "type", "typeCheckedLoadConstVCalls", "typeCheckedLoadVCalls", "typeIdInfo", "typeTestAssumeConstVCalls", "typeTestAssumeVCalls", "typeTestRes", "typeTests", "typeid", "typeidCompatibleVTable", "ueq", "uge", "ugt", "ule", "ult", "umax", "umin", "undef", "une", "uniformRetVal", "uniqueRetVal", "unknown", "unnamed_addr", "uno", "unordered", "unsat", "unwind", "uselistorder", "uselistorder_bb", "uwtable", "vFuncId", "vTableFuncs", "varFlags", "variable", "vcall_visibility", "virtFunc", "virtualConstProp", "visibility", "volatile", "vscale", "vscale_range", "weak", "weak_odr", "webkit_jscc", "willreturn", "win64cc", "within", "wpdRes", "wpdResolutions", "writeonly", "x", "x86_64_sysvcc", "x86_fastcallcc", "x86_intrcc", "x86_regcallcc", "x86_stdcallcc", "x86_thiscallcc", "x86_vectorcallcc", "xchg", "zeroext", "zeroinitializer"] + end + + def self.types + @types ||= Set.new ["bfloat", "double", "float", "fp128", "half", "label", "metadata", "ppc_fp128", "ptr", "token", "void", "x86_amx", "x86_fp80", "x86_mmx"] + end + + def self.instructions + @instructions ||= Set.new ["add", "addrspacecast", "alloca", "and", "ashr", "atomicrmw", "bitcast", "br", "call", "callbr", "catchpad", "catchret", "catchswitch", "cleanuppad", "cleanupret", "cmpxchg", "extractelement", "extractvalue", "fadd", "fcmp", "fdiv", "fence", "fmul", "fneg", "fpext", "fptosi", "fptoui", "fptrunc", "freeze", "frem", "fsub", "getelementptr", "icmp", "indirectbr", "insertelement", "insertvalue", "inttoptr", "invoke", "landingpad", "load", "lshr", "mul", "or", "phi", "ptrtoint", "resume", "ret", "sdiv", "select", "sext", "shl", "shufflevector", "sitofp", "srem", "store", "sub", "switch", "trunc", "udiv", "uitofp", "unreachable", "urem", "va_arg", "xor", "zext"] + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lua.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lua.rb new file mode 100644 index 0000000..6defd8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lua.rb @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Lua < RegexLexer + title "Lua" + desc "Lua (http://www.lua.org)" + tag 'lua' + filenames '*.lua', '*.wlua' + + mimetypes 'text/x-lua', 'application/x-lua' + + option :function_highlighting, 'Whether to highlight builtin functions (default: true)' + option :disabled_modules, 'builtin modules to disable' + + def initialize(opts={}) + @function_highlighting = opts.delete(:function_highlighting) { true } + @disabled_modules = opts.delete(:disabled_modules) { [] } + super(opts) + end + + def self.detect?(text) + return true if text.shebang? 'lua' + end + + def self.builtins + Kernel::load File.join(Lexers::BASE_DIR, 'lua/keywords.rb') + builtins + end + + def builtins + return [] unless @function_highlighting + + @builtins ||= Set.new.tap do |builtins| + self.class.builtins.each do |mod, fns| + next if @disabled_modules.include? mod + builtins.merge(fns) + end + end + end + + state :root do + # lua allows a file to start with a shebang + rule %r(#!(.*?)$), Comment::Preproc + rule %r//, Text, :base + end + + state :base do + rule %r(--\[(=*)\[.*?\]\1\])m, Comment::Multiline + rule %r(--.*$), Comment::Single + + rule %r((?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?'), Num::Float + rule %r((?i)\d+e[+-]?\d+), Num::Float + rule %r((?i)0x[0-9a-f]*), Num::Hex + rule %r(\d+), Num::Integer + + rule %r(\n), Text + rule %r([^\S\n]), Text + # multiline strings + rule %r(\[(=*)\[.*?\]\1\])m, Str + + rule %r((==|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#])), Operator + rule %r([\[\]\{\}\(\)\.,:;]), Punctuation + rule %r((and|or|not)\b), Operator::Word + + rule %r((break|do|else|elseif|end|for|if|in|repeat|return|then|until|while)\b), Keyword + rule %r((local)\b), Keyword::Declaration + rule %r((true|false|nil)\b), Keyword::Constant + + rule %r((function)\b), Keyword, :function_name + + rule %r([A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?) do |m| + name = m[0] + if name == "gsub" + token Name::Builtin + push :gsub + elsif self.builtins.include?(name) + token Name::Builtin + elsif name =~ /\./ + a, b = name.split('.', 2) + token Name, a + token Punctuation, '.' + token Name, b + else + token Name + end + end + + rule %r('), Str::Single, :escape_sqs + rule %r("), Str::Double, :escape_dqs + end + + state :function_name do + rule %r/\s+/, Text + rule %r((?:([A-Za-z_][A-Za-z0-9_]*)(\.))?([A-Za-z_][A-Za-z0-9_]*)) do + groups Name::Class, Punctuation, Name::Function + pop! + end + # inline function + rule %r(\(), Punctuation, :pop! + end + + state :gsub do + rule %r/\)/, Punctuation, :pop! + rule %r/[(,]/, Punctuation + rule %r/\s+/, Text + rule %r/'/, Str::Regex, :regex_sq + rule %r/"/, Str::Regex, :regex_dq + end + + state :regex_sq do + rule %r(') do + token Str::Regex + goto :regex_end + end + + mixin :regex + end + + state :regex_dq do + rule %r(") do + token Str::Regex + goto :regex_end + end + + mixin :regex + end + + state :regex do + rule %r(") do + token Str::Regex + goto :regex_end + end + + rule %r/\[\^?/, Str::Escape, :regex_group + rule %r/\\./, Str::Escape + rule %r{[(][?][:=?@^|~#-]+) + id = /[a-z_][\w']*/i + + state :root do + rule %r/\s+/m, Text + rule %r/false|true/, Keyword::Constant + rule %r(\-\-.*), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + rule %r(\(\*.*?\*\))m, Comment::Multiline + rule id do |m| + match = m[0] + if self.class.keywords.include? match + token Keyword + elsif self.class.word_operators.include? match + token Operator::Word + elsif self.class.primitives.include? match + token Keyword::Type + else + token Name + end + end + + rule %r/[(){}\[\];]+/, Punctuation + rule operator, Operator + + rule %r/-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i, Num::Float + rule %r/\d[\d_]*/, Num::Integer + + rule %r/'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/, Str::Char + rule %r/'[.]'/, Str::Char + rule %r/"/, Str::Double, :string + rule %r/[~?]#{id}/, Name::Variable + end + + state :string do + rule %r/[^\\"]+/, Str::Double + mixin :escape_sequence + rule %r/\\\n/, Str::Double + rule %r/"/, Str::Double, :pop! + end + + state :escape_sequence do + rule %r/\\[\\"'ntbr]/, Str::Escape + rule %r/\\\d{3}/, Str::Escape + rule %r/\\x\h{2}/, Str::Escape + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lutin.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lutin.rb new file mode 100644 index 0000000..cc1ac53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lutin.rb @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true +# +# adapted from lustre.rf (adapted from ocaml.rb), hence some ocaml-ism migth remains +module Rouge + module Lexers + load_lexer 'lustre.rb' + + class Lutin < Lustre + title "Lutin" + desc 'The Lutin programming language (Verimag)' + tag 'lutin' + filenames '*.lut' + mimetypes 'text/x-lutin' + + def self.keywords + @keywords ||= Set.new %w( + let in node extern system returns weak strong assert raise try catch + trap do exist erun run type ref exception include false true + ) + end + + def self.word_operators + @word_operators ||= Set.new %w( + div and xor mod or not nor if then else pre) + end + + def self.primitives + @primitives ||= Set.new %w(int real bool trace loop fby) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/m68k.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/m68k.rb new file mode 100644 index 0000000..cb610b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/m68k.rb @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class M68k < RegexLexer + tag 'm68k' + + title "M68k" + desc "Motorola 68k Assembler" + + id = /[a-zA-Z_][a-zA-Z0-9_]*/ + + def self.keywords + @keywords ||= Set.new %w( + abcd add adda addi addq addx and andi asl asr + + bcc bcs beq bge bgt bhi ble bls blt bmi bne bpl bvc bvs bhs blo + bchg bclr bfchg bfclr bfests bfextu bfffo bfins bfset bftst bkpt bra bse bsr btst + + callm cas cas2 chk chk2 clr cmp cmpa cmpi cmpm cmp2 + + dbcc dbcs dbeq dbge dbgt dbhi dble dbls dblt dbmi dbne dbpl dbvc dbvs dbhs dblo + dbra dbf dbt divs divsl divu divul + + eor eori exg ext extb + + illegal jmp jsr lea link lsl lsr + + move movea move16 movem movep moveq muls mulu + + nbcd neg negx nop not or ori + + pack pea rol ror roxl roxr rtd rtm rtr rts + + sbcd + + seq sne spl smi svc svs st sf sge sgt sle slt scc shi sls scs shs slo + sub suba subi subq subx swap + + tas trap trapcc TODO trapv tst + + unlk unpk eori + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + dc ds dcb + ) + end + + def self.reserved + @reserved ||= Set.new %w( + include incdir incbin end endf endfunc endmain endproc fpu func machine main mmu opword proc set opt section + rept endr + ifeq ifne ifgt ifge iflt ifle iif ifd ifnd ifc ifnc elseif else endc + even cnop fail machine + output radix __G2 __LK + list nolist plen llen ttl subttl spc page listchar format + equ equenv equr set reg + rsreset rsset offset + cargs + fequ.s fequ.d fequ.x fequ.p fequ.w fequ.l fopt + macro endm mexit narg + ) + end + + def self.builtins + @builtins ||=Set.new %w( + d0 d1 d2 d3 d4 d5 d6 d7 + a0 a1 a2 a3 a4 a5 a6 a7 a7' + pc usp ssp ccr + ) + end + + start { push :expr_bol } + + state :expr_bol do + mixin :inline_whitespace + rule(//) { pop! } + end + + state :inline_whitespace do + rule %r/\s+/, Text + end + + state :whitespace do + rule %r/\n+/m, Text, :expr_bol + rule %r(^\*(\\.|.)*?$), Comment::Single, :expr_bol + rule %r(;(\\.|.)*?$), Comment::Single, :expr_bol + mixin :inline_whitespace + end + + state :root do + rule(//) { push :statements } + end + + state :statements do + mixin :whitespace + rule %r/"/, Str, :string + rule %r/#/, Name::Decorator + rule %r/^\.?[a-zA-Z0-9_]+:?/, Name::Label + rule %r/\.[bswl]\s/i, Name::Decorator + rule %r('(\\.|\\[0-7]{1,3}|\\x[a-f0-9]{1,2}|[^\\'\n])')i, Str::Char + rule %r/\$[0-9a-f]+/i, Num::Hex + rule %r/@[0-8]+/i, Num::Oct + rule %r/%[01]+/i, Num::Bin + rule %r/\d+/i, Num::Integer + rule %r([*~&+=\|?:<>/-]), Operator + rule %r/\\./, Comment::Preproc + rule %r/[(),.]/, Punctuation + rule %r/\[[a-zA-Z0-9]*\]/, Punctuation + + rule id do |m| + name = m[0] + + if self.class.keywords.include? name.downcase + token Keyword + elsif self.class.keywords_type.include? name.downcase + token Keyword::Type + elsif self.class.reserved.include? name.downcase + token Keyword::Reserved + elsif self.class.builtins.include? name.downcase + token Name::Builtin + elsif name =~ /[a-zA-Z0-9]+/ + token Name::Variable + else + token Name + end + end + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\([\\abfnrtv"']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})/, Str::Escape + rule %r/[^\\"\n]+/, Str + rule %r/\\\n/, Str + rule %r/\\/, Str # stray backslash + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/magik.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/magik.rb new file mode 100644 index 0000000..0a3f47a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/magik.rb @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Magik < RegexLexer + title "Magik" + desc "Smallworld Magik" + tag 'magik' + filenames '*.magik' + mimetypes 'text/x-magik', 'application/x-magik' + + def self.keywords + @keywords ||= %w( + _package + _pragma + _block _endblock + _handling _default + _protect _protection _endprotect + _try _with _when _endtry + _catch _endcatch + _throw + _lock _endlock + _if _then _elif _else _endif + _for _over _while _loop _finally _endloop _loopbody _continue _leave + _return + _class + _local _constant _recursive _global _dynamic _import + _private _iter _abstract _method _endmethod + _proc _endproc + _gather _scatter _allresults _optional + _thisthread _self _clone _super + _primitive + _unset _true _false _maybe + _is _isnt _not _and _or _xor _cf _andif _orif + _div _mod + ) + end + + def self.string_double + @string_double ||= /"[^"\n]*?"/ + end + def self.string_single + @string_single ||= /'[^'\n]*?'/ + end + + def self.digits + @digits ||= /[0-9]+/ + end + def self.radix + @radix ||= /r[0-9a-z]/i + end + def self.exponent + @exponent ||= /(e|&)[+-]?#{Magik.digits}/i + end + def self.decimal + @decimal ||= /\.#{Magik.digits}/ + end + def self.number + @number = /#{Magik.digits}(#{Magik.radix}|#{Magik.exponent}|#{Magik.decimal})*/ + end + + def self.character + @character ||= /%u[0-9a-z]{4}|%[^\s]+/i + end + + def self.simple_identifier + @simple_identifier ||= /(?>(?:[a-z0-9_!?]|\\.)+)/i + end + def self.piped_identifier + @piped_identifier ||= /\|[^\|\n]*\|/ + end + def self.identifier + @identifier ||= /(?:#{Magik.simple_identifier}|#{Magik.piped_identifier})+/i + end + def self.package_identifier + @package_identifier ||= /#{Magik.identifier}:#{Magik.identifier}/ + end + def self.symbol + @symbol ||= /:#{Magik.identifier}/i + end + def self.global_ref + @global_ref ||= /@[\s]*#{Magik.identifier}:#{Magik.identifier}/ + end + def self.label + @label = /@[\s]*#{Magik.identifier}/ + end + + state :root do + rule %r/##(.*)?/, Comment::Doc + rule %r/#(.*)?/, Comment::Single + + rule %r/(_method)(\s+)/ do + groups Keyword, Text::Whitespace + push :method_name + end + + rule %r/(?:#{Magik.keywords.join('|')})\b/, Keyword + + rule Magik.string_double, Literal::String + rule Magik.string_single, Literal::String + rule Magik.symbol, Str::Symbol + rule Magik.global_ref, Name::Label + rule Magik.label, Name::Label + rule Magik.character, Literal::String::Char + rule Magik.number, Literal::Number + rule Magik.package_identifier, Name + rule Magik.identifier, Name + + rule %r/[\[\]{}()\.,;]/, Punctuation + rule %r/\$/, Punctuation + rule %r/(<<|^<<)/, Operator + rule %r/(>>)/, Operator + rule %r/[-~+\/*%=&^<>]|!=/, Operator + + rule %r/[\s]+/, Text::Whitespace + end + + state :method_name do + rule %r/(#{Magik.identifier})(\.)(#{Magik.identifier})/ do + groups Name::Class, Punctuation, Name::Function + pop! + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/make.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/make.rb new file mode 100644 index 0000000..3b73383 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/make.rb @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Make < RegexLexer + title "Make" + desc "Makefile syntax" + tag 'make' + aliases 'makefile', 'mf', 'gnumake', 'bsdmake' + filenames '*.make', '*.mak', '*.mk', 'Makefile', 'makefile', 'Makefile.*', 'GNUmakefile', '*,fe1' + mimetypes 'text/x-makefile' + + def self.functions + @functions ||= %w( + abspath addprefix addsuffix and basename call dir error eval file + filter filter-out findstring firstword flavor foreach if join lastword + notdir or origin patsubst realpath shell sort strip subst suffix value + warning wildcard word wordlist words + ) + end + + def initialize(opts={}) + super + @shell = Shell.new(opts) + end + + start { @shell.reset! } + + state :root do + rule %r/\s+/, Text + + rule %r/#.*?\n/, Comment + + rule %r/([-s]?include)((?:[\t ]+[^\t\n #]+)+)/ do + groups Keyword, Literal::String::Other + end + + rule %r/((?:ifn?def|ifn?eq|unexport)\b)([\t ]+)([^#\n]+)/ do + groups Keyword, Text, Name::Variable + end + + rule %r/(else\b)([\t ]+)((?:ifn?def|ifn?eq)\b)([\t ]+)([^#\n]+)/ do + groups Keyword, Text, Keyword, Text, Name::Variable + end + + rule %r/(?:else|endif|endef|endfor)[\t ]*(?=[#\n])/, Keyword + + rule %r/(export)([\t ]+)(?=[\w\${}()\t -]+\n)/ do + groups Keyword, Text + push :export + end + + rule %r/export[\t ]+/, Keyword + + # assignment + rule %r/(override\b)*([\t ]*)([\w${}().-]+)([\t ]*)([!?:+]?=)/m do |m| + groups Name::Builtin, Text, Name::Variable, Text, Operator + push :shell_line + end + + rule %r/"(\\\\|\\.|[^"\\])*"/, Str::Double + rule %r/'(\\\\|\\.|[^'\\])*'/, Str::Single + rule %r/([^\n:]+)(:+)([ \t]*)/ do + groups Name::Label, Operator, Text + push :block_header + end + + rule %r/(override\b)*([\t ])*(define)([\t ]+)([^#\n]+)/ do + groups Name::Builtin, Text, Keyword, Text, Name::Variable + end + + rule %r/(\$[({])([\t ]*)(#{Make.functions.join('|')})([\t ]+)/m do + groups Name::Function, Text, Name::Builtin, Text + push :shell_expr + end + end + + state :export do + rule %r/[\w\${}()-]/, Name::Variable + rule %r/\n/, Text, :pop! + rule %r/[\t ]+/, Text + end + + state :block_header do + rule %r/[^,\\\n#]+/, Name::Function + rule %r/,/, Punctuation + rule %r/#.*?/, Comment + rule %r/\\\n/, Text + rule %r/\\./, Text + rule %r/\n/ do + token Text + goto :block_body + end + end + + state :block_body do + rule %r/(ifn?def|ifn?eq)([\t ]+)([^#\n]+)(#.*)?(\n)/ do + groups Keyword, Text, Name::Variable, Comment, Text + end + + rule %r/(else|endif)([\t ]*)(#.*)?(\n)/ do + groups Keyword, Text, Comment, Text + end + + rule %r/(\t[\t ]*)([@-]?)/ do + groups Text, Punctuation + push :shell_line + end + + rule(//) { @shell.reset!; pop! } + end + + state :shell do + # macro interpolation + rule %r/[\$]{1,2}[({]/, Punctuation, :macro_expr + + # function invocation + rule %r/(\$[({])([\t ]*)(#{Make.functions.join('|')})([\t ]+)/m do + groups Punctuation, Text, Name::Builtin, Text + push :shell_expr + end + + rule(/\\./m) { delegate @shell } + stop = /[\$]{1,2}\(|[\$]{1,2}\{|\(|\)|\}|\\|$/ + rule(/.+?(?=#{stop})/m) { delegate @shell } + rule(stop) { delegate @shell } + end + + state :macro_expr do + rule %r/[)}]/, Punctuation, :pop! + rule %r/\n/, Text, :pop! + mixin :shell + end + + state :shell_expr do + rule(/[({]/) { delegate @shell; push } + rule %r/[)}]/, Punctuation, :pop! + mixin :shell + end + + state :shell_line do + rule %r/\n/, Text, :pop! + mixin :shell + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/markdown.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/markdown.rb new file mode 100644 index 0000000..7d0d2c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/markdown.rb @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Markdown < RegexLexer + title "Markdown" + desc "Markdown, a light-weight markup language for authors" + + tag 'markdown' + aliases 'md', 'mkd' + filenames '*.markdown', '*.md', '*.mkd' + mimetypes 'text/x-markdown' + + def html + @html ||= HTML.new(options) + end + + start { html.reset! } + + edot = /\\.|[^\\\n]/ + + state :root do + # YAML frontmatter + rule(/\A(---\s*\n.*?\n?)^(---\s*$\n?)/m) { delegate YAML } + + rule %r/\\./, Str::Escape + + rule %r/^[\S ]+\n(?:---*)\n/, Generic::Heading + rule %r/^[\S ]+\n(?:===*)\n/, Generic::Subheading + + rule %r/^#(?=[^#]).*?$/, Generic::Heading + rule %r/^##*.*?$/, Generic::Subheading + + rule %r/^([ \t]*)(`{3,}|~{3,})([^\n]*\n)((.*?)(\n\1)(\2))?/m do |m| + name = m[3].strip + sublexer = + begin + Lexer.find_fancy(name.empty? ? "guess" : name, m[5], @options) + rescue Guesser::Ambiguous => e + e.alternatives.first.new(@options) + end + + sublexer ||= PlainText.new(@options.merge(:token => Str::Backtick)) + sublexer.reset! + + token Text, m[1] + token Punctuation, m[2] + token Name::Label, m[3] + if m[5] + delegate sublexer, m[5] + end + + token Text, m[6] + + if m[7] + token Punctuation, m[7] + else + push do + rule %r/^([ \t]*)(#{m[2]})/ do |mb| + pop! + token Text, mb[1] + token Punctuation, mb[2] + end + rule %r/^.*\n/ do |mb| + delegate sublexer, mb[1] + end + end + end + end + + rule %r/\n\n(( |\t).*?\n|\n)+/, Str::Backtick + + rule %r/(`+)(?:#{edot}|\n)+?\1/, Str::Backtick + + # various uses of * are in order of precedence + + # line breaks + rule %r/^(\s*[*]){3,}\s*$/, Punctuation + rule %r/^(\s*[-]){3,}\s*$/, Punctuation + + # bulleted lists + rule %r/^\s*[*+-](?=\s)/, Punctuation + + # numbered lists + rule %r/^\s*\d+\./, Punctuation + + # blockquotes + rule %r/^\s*>.*?$/, Generic::Traceback + + # link references + # [foo]: bar "baz" + rule %r(^ + (\s*) # leading whitespace + (\[) (#{edot}+?) (\]) # the reference + (\s*) (:) # colon + )x do + groups Text, Punctuation, Str::Symbol, Punctuation, Text, Punctuation + + push :title + push :url + end + + # links and images + rule %r/(!?\[)(#{edot}*?|[^\]]*?)(\])(?=[\[(])/ do + groups Punctuation, Name::Variable, Punctuation + push :link + end + + rule %r/[*]{2}[^* \n][^*\n]*[*]{2}/, Generic::Strong + rule %r/[*]{3}[^* \n][^*\n]*[*]{3}/, Generic::EmphStrong + rule %r/__#{edot}*?__/, Generic::Strong + + rule %r/[*]#{edot}*?[*]/, Generic::Emph + rule %r/_#{edot}*?_/, Generic::Emph + + # Automatic links + rule %r/<.*?@.+[.].+>/, Name::Variable + rule %r[<(https?|mailto|ftp)://#{edot}*?>], Name::Variable + + rule %r/[^\\`\[*\n&<]+/, Text + + # inline html + rule(/&\S*;/) { delegate html } + rule(/<#{edot}*?>/) { delegate html } + rule %r/[&<]/, Text + + # An opening square bracket that is not a link + rule %r/\[/, Text + + rule %r/\n/, Text + end + + state :link do + rule %r/(\[)(#{edot}*?)(\])/ do + groups Punctuation, Str::Symbol, Punctuation + pop! + end + + rule %r/[(]/ do + token Punctuation + push :inline_title + push :inline_url + end + + rule %r/[ \t]+/, Text + + rule(//) { pop! } + end + + state :url do + rule %r/[ \t]+/, Text + + # the url + rule %r/(<)(#{edot}*?)(>)/ do + groups Name::Tag, Str::Other, Name::Tag + pop! + end + + rule %r/\S+/, Str::Other, :pop! + end + + state :title do + rule %r/"#{edot}*?"/, Name::Namespace + rule %r/'#{edot}*?'/, Name::Namespace + rule %r/[(]#{edot}*?[)]/, Name::Namespace + rule %r/\s*(?=["'()])/, Text + rule(//) { pop! } + end + + state :inline_title do + rule %r/[)]/, Punctuation, :pop! + mixin :title + end + + state :inline_url do + rule %r/[^<\s)]+/, Str::Other, :pop! + rule %r/\s+/m, Text + mixin :url + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mason.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mason.rb new file mode 100644 index 0000000..06e9f9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mason.rb @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Mason < TemplateLexer + title 'Mason' + desc 'The HTML::Mason framework (https://metacpan.org/pod/HTML::Mason)' + tag 'mason' + filenames '*.mi', '*.mc', '*.mas', '*.m', '*.mhtml', '*.mcomp', 'autohandler', 'dhandler' + mimetypes 'text/x-mason', 'application/x-mason' + + def initialize(*) + super + @perl = Perl.new + end + + # Note: If you add a tag in the lines below, you also need to modify "disambiguate '*.m'" in file disambiguation.rb + TEXT_BLOCKS = %w(text doc) + PERL_BLOCKS = %w(args flags attr init once shared perl cleanup filter) + COMPONENTS = %w(def method) + + state :root do + mixin :mason_tags + end + + state :mason_tags do + rule %r/\s+/, Text::Whitespace + + rule %r/<%(#{TEXT_BLOCKS.join('|')})>/oi, Comment::Preproc, :text_block + + rule %r/<%(#{PERL_BLOCKS.join('|')})>/oi, Comment::Preproc, :perl_block + + rule %r/(<%(#{COMPONENTS.join('|')}))([^>]*)(>)/oi do |m| + token Comment::Preproc, m[1] + token Name, m[3] + token Comment::Preproc, m[4] + push :component_block + end + + # perl line + rule %r/^(%)(.*)$/ do |m| + token Comment::Preproc, m[1] + delegate @perl, m[2] + end + + # start of component call + rule %r/<%/, Comment::Preproc, :component_call + + # start of component with content + rule %r/<&\|/ do + token Comment::Preproc + push :component_with_content + push :component_sub + end + + # start of component substitution + rule %r/<&/, Comment::Preproc, :component_sub + + # fallback to HTML until a mason tag is encountered + rule(/(.+?)(?=(<\/?&|<\/?%|^%|^#))/m) { delegate parent } + + # if we get here, there's no more mason tags, so we parse the rest of the doc as HTML + rule(/.+/m) { delegate parent } + end + + state :perl_block do + rule %r/<\/%(#{PERL_BLOCKS.join('|')})>/oi, Comment::Preproc, :pop! + rule %r/\s+/, Text::Whitespace + rule %r/^(#.*)$/, Comment + rule(/(.*?[^"])(?=<\/%)/m) { delegate @perl } + end + + state :text_block do + rule %r/<\/%(#{TEXT_BLOCKS.join('|')})>/oi, Comment::Preproc, :pop! + rule %r/\s+/, Text::Whitespace + rule %r/^(#.*)$/, Comment + rule %r/(.*?[^"])(?=<\/%)/m, Comment + end + + state :component_block do + rule %r/<\/%(#{COMPONENTS.join('|')})>/oi, Comment::Preproc, :pop! + rule %r/\s+/, Text::Whitespace + rule %r/^(#.*)$/, Comment + mixin :mason_tags + end + + state :component_with_content do + rule %r/<\/&>/ do + token Comment::Preproc + pop! + end + + mixin :mason_tags + end + + state :component_sub do + rule %r/&>/, Comment::Preproc, :pop! + + rule(/(.*?)(?=&>)/m) { delegate @perl } + end + + state :component_call do + rule %r/%>/, Comment::Preproc, :pop! + + rule(/(.*?)(?=%>)/m) { delegate @perl } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica.rb new file mode 100644 index 0000000..cb6d3b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica.rb @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Mathematica < RegexLexer + title "Mathematica" + desc "Wolfram Mathematica, the world's definitive system for modern technical computing." + tag 'mathematica' + aliases 'wl', 'wolfram' + filenames '*.m', '*.wl' + mimetypes 'application/vnd.wolfram.mathematica.package', 'application/vnd.wolfram.wl' + + # Mathematica has various input forms for numbers. We need to handle numbers in bases, precision, accuracy, + # and *^ scientific notation. All this works for integers and real numbers. Some examples + # 1 1234567 1.1 .3 0.2 1*^10 2*^+10 3*^-10 + # 1`1 1``1 1.2` 1.2``1.234*^-10 1.2``1.234*^+10 1.2``1.234*^10 + # 2^^01001 10^^1.2``20.1234*^-10 + base = /(?:\d+)/ + number = /(?:\.\d+|\d+\.\d*|\d+)/ + number_base = /(?:\.\w+|\w+\.\w*|\w+)/ + precision = /`(`?#{number})?/ + + operators = /[+\-*\/|,;.:@~=><&`'^?!_%]/ + braces = /[\[\](){}]/ + + string = /"(\\\\|\\"|[^"])*"/ + + # symbols and namespaced symbols. Note the special form \[Gamma] for named characters. These are also symbols. + # Module With Block Integrate Table Plot + # x32 $x x$ $Context` Context123`$x `Private`Context + # \[Gamma] \[Alpha]x32 Context`\[Xi] + identifier = /[a-zA-Z$][$a-zA-Z0-9]*/ + named_character = /\\\[#{identifier}\]/ + symbol = /(#{identifier}|#{named_character})+/ + context_symbol = /`?#{symbol}(`#{symbol})*`?/ + + # Slots for pure functions. + # Examples: # ## #1 ##3 #Test #"Test" #[Test] #["Test"] + association_slot = /#(#{identifier}|\"#{identifier}\")/ + slot = /#{association_slot}|#[0-9]*/ + + # Handling of message like symbol::usage or symbol::"argx" + message = /::(#{identifier}|#{string})/ + + # Highlighting of the special in and out markers that are prepended when you copy a cell + in_out = /(In|Out)\[[0-9]+\]:?=/ + + # Although Module, With and Block are normal built-in symbols, we give them a special treatment as they are + # the most important expressions for defining local variables + def self.keywords + @keywords = Set.new %w( + Module With Block + ) + end + + # The list of built-in symbols comes from a wolfram server and is created automatically by rake + def self.builtins + Kernel::load File.join(Lexers::BASE_DIR, 'mathematica/keywords.rb') + builtins + end + + state :root do + rule %r/\s+/, Text::Whitespace + rule %r/\(\*/, Comment, :comment + rule %r/#{base}\^\^#{number_base}#{precision}?(\*\^[+-]?\d+)?/, Num # a number with a base + rule %r/(?:#{number}#{precision}?(?:\*\^[+-]?\d+)?)/, Num # all other numbers + rule message, Name::Tag + rule in_out, Generic::Prompt + rule %r/#{context_symbol}/m do |m| + match = m[0] + if self.class.keywords.include? match + token Name::Builtin::Pseudo + elsif self.class.builtins.include? match + token Name::Builtin + else + token Name::Variable + end + end + rule slot, Name::Function + rule operators, Operator + rule braces, Punctuation + rule string, Str + end + + # Allow for nested comments and special treatment of ::Section:: or :Author: markup + state :comment do + rule %r/\(\*/, Comment, :comment + rule %r/\*\)/, Comment, :pop! + rule %r/::#{identifier}::/, Comment::Preproc + rule %r/[ ]:(#{identifier}|[^\S])+:[ ]/, Comment::Preproc + rule %r/./, Comment + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica/keywords.rb new file mode 100644 index 0000000..95fdd61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mathematica/keywords.rb @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# DO NOT EDIT + +# This file is automatically generated by `rake builtins:mathematica`. +# See tasks/builtins/mathematica.rake for more info. + +module Rouge + module Lexers + class Mathematica + def self.builtins + @builtins ||= Set.new ["AASTriangle", "AngleVector", "AsymptoticDSolveValue", "AbelianGroup", "AngularGauge", "AsymptoticEqual", "Abort", "Animate", "AsymptoticEquivalent", "AbortKernels", "AnimationDirection", "AsymptoticGreater", "AbortProtect", "AnimationRate", "AsymptoticGreaterEqual", "Above", "AnimationRepetitions", "AsymptoticIntegrate", "Abs", "AnimationRunning", "AsymptoticLess", "AbsArg", "AnimationRunTime", "AsymptoticLessEqual", "AbsArgPlot", "AnimationTimeIndex", "AsymptoticOutputTracker", "AbsoluteCorrelation", "Animator", "AsymptoticProduct", "AbsoluteCorrelationFunction", "Annotate", "AsymptoticRSolveValue", "AbsoluteCurrentValue", "Annotation", "AsymptoticSolve", "AbsoluteDashing", "AnnotationDelete", "AsymptoticSum", "AbsoluteFileName", "AnnotationKeys", "Asynchronous", "AbsoluteOptions", "AnnotationRules", "Atom", "AbsolutePointSize", "AnnotationValue", "AtomCoordinates", "AbsoluteThickness", "Annuity", "AtomCount", "AbsoluteTime", "AnnuityDue", "AtomDiagramCoordinates", "AbsoluteTiming", "Annulus", "AtomList", "AcceptanceThreshold", "AnomalyDetection", "AtomQ", "AccountingForm", "AnomalyDetector", "AttentionLayer", "Accumulate", "AnomalyDetectorFunction", "Attributes", "Accuracy", "Anonymous", "Audio", "AccuracyGoal", "Antialiasing", "AudioAmplify", "ActionMenu", "AntihermitianMatrixQ", "AudioAnnotate", "Activate", "Antisymmetric", "AudioAnnotationLookup", "ActiveClassification", "AntisymmetricMatrixQ", "AudioBlockMap", "ActiveClassificationObject", "Antonyms", "AudioCapture", "ActivePrediction", "AnyOrder", "AudioChannelAssignment", "ActivePredictionObject", "AnySubset", "AudioChannelCombine", "ActiveStyle", "AnyTrue", "AudioChannelMix", "AcyclicGraphQ", "Apart", "AudioChannels", "AddSides", "ApartSquareFree", "AudioChannelSeparate", "AddTo", "APIFunction", "AudioData", "AddToSearchIndex", "Appearance", "AudioDelay", "AddUsers", "AppearanceElements", "AudioDelete", "AdjacencyGraph", "AppearanceRules", "AudioDistance", "AdjacencyList", "AppellF1", "AudioEncoding", "AdjacencyMatrix", "Append", "AudioFade", "AdjacentMeshCells", "AppendLayer", "AudioFrequencyShift", "AdjustmentBox", "AppendTo", "AudioGenerator", "AdjustmentBoxOptions", "Apply", "AudioIdentify", "AdjustTimeSeriesForecast", "ApplySides", "AudioInputDevice", "AdministrativeDivisionData", "ArcCos", "AudioInsert", "AffineHalfSpace", "ArcCosh", "AudioInstanceQ", "AffineSpace", "ArcCot", "AudioIntervals", "AffineStateSpaceModel", "ArcCoth", "AudioJoin", "AffineTransform", "ArcCsc", "AudioLabel", "After", "ArcCsch", "AudioLength", "AggregatedEntityClass", "ArcCurvature", "AudioLocalMeasurements", "AggregationLayer", "ARCHProcess", "AudioLoudness", "AircraftData", "ArcLength", "AudioMeasurements", "AirportData", "ArcSec", "AudioNormalize", "AirPressureData", "ArcSech", "AudioOutputDevice", "AirTemperatureData", "ArcSin", "AudioOverlay", "AiryAi", "ArcSinDistribution", "AudioPad", "AiryAiPrime", "ArcSinh", "AudioPan", "AiryAiZero", "ArcTan", "AudioPartition", "AiryBi", "ArcTanh", "AudioPause", "AiryBiPrime", "Area", "AudioPitchShift", "AiryBiZero", "Arg", "AudioPlay", "AlgebraicIntegerQ", "ArgMax", "AudioPlot", "AlgebraicNumber", "ArgMin", "AudioQ", "AlgebraicNumberDenominator", "ARIMAProcess", "AudioRecord", "AlgebraicNumberNorm", "ArithmeticGeometricMean", "AudioReplace", "AlgebraicNumberPolynomial", "ARMAProcess", "AudioResample", "AlgebraicNumberTrace", "Around", "AudioReverb", "Algebraics", "AroundReplace", "AudioReverse", "AlgebraicUnitQ", "ARProcess", "AudioSampleRate", "Alignment", "Array", "AudioSpectralMap", "AlignmentPoint", "ArrayComponents", "AudioSpectralTransformation", "All", "ArrayDepth", "AudioSplit", "AllowedCloudExtraParameters", "ArrayFilter", "AudioStop", "AllowedCloudParameterExtensions", "ArrayFlatten", "AudioStream", "AllowedDimensions", "ArrayMesh", "AudioStreams", "AllowedFrequencyRange", "ArrayPad", "AudioTimeStretch", "AllowedHeads", "ArrayPlot", "AudioTracks", "AllowGroupClose", "ArrayQ", "AudioTrim", "AllowInlineCells", "ArrayResample", "AudioType", "AllowLooseGrammar", "ArrayReshape", "AugmentedPolyhedron", "AllowReverseGroupClose", "ArrayRules", "AugmentedSymmetricPolynomial", "AllowVersionUpdate", "Arrays", "Authentication", "AllTrue", "Arrow", "AuthenticationDialog", "Alphabet", "Arrowheads", "AutoAction", "AlphabeticOrder", "ASATriangle", "Autocomplete", "AlphabeticSort", "Ask", "AutocompletionFunction", "AlphaChannel", "AskAppend", "AutoCopy", "AlternatingFactorial", "AskConfirm", "AutocorrelationTest", "AlternatingGroup", "AskDisplay", "AutoDelete", "AlternativeHypothesis", "AskedQ", "AutoIndent", "Alternatives", "AskedValue", "AutoItalicWords", "AltitudeMethod", "AskFunction", "Automatic", "AmbiguityFunction", "AskState", "AutoMultiplicationSymbol", "AmbiguityList", "AskTemplateDisplay", "AutoRefreshed", "AnatomyData", "AspectRatio", "AutoRemove", "AnatomyPlot3D", "Assert", "AutorunSequencing", "AnatomySkinStyle", "AssociateTo", "AutoScroll", "AnatomyStyling", "Association", "AutoSpacing", "AnchoredSearch", "AssociationFormat", "AutoSubmitting", "And", "AssociationMap", "Axes", "AndersonDarlingTest", "AssociationQ", "AxesEdge", "AngerJ", "AssociationThread", "AxesLabel", "AngleBisector", "AssumeDeterministic", "AxesOrigin", "AngleBracket", "Assuming", "AxesStyle", "AnglePath", "Assumptions", "AxiomaticTheory", "AnglePath3D", "Asymptotic", "Axis", "BabyMonsterGroupB", "BezierFunction", "BooleanCountingFunction", "Back", "BilateralFilter", "BooleanFunction", "Background", "Binarize", "BooleanGraph", "Backslash", "BinaryDeserialize", "BooleanMaxterms", "Backward", "BinaryDistance", "BooleanMinimize", "Ball", "BinaryFormat", "BooleanMinterms", "Band", "BinaryImageQ", "BooleanQ", "BandpassFilter", "BinaryRead", "BooleanRegion", "BandstopFilter", "BinaryReadList", "Booleans", "BarabasiAlbertGraphDistribution", "BinarySerialize", "BooleanStrings", "BarChart", "BinaryWrite", "BooleanTable", "BarChart3D", "BinCounts", "BooleanVariables", "BarcodeImage", "BinLists", "BorderDimensions", "BarcodeRecognize", "Binomial", "BorelTannerDistribution", "BaringhausHenzeTest", "BinomialDistribution", "Bottom", "BarLegend", "BinomialProcess", "BottomHatTransform", "BarlowProschanImportance", "BinormalDistribution", "BoundaryDiscretizeGraphics", "BarnesG", "BiorthogonalSplineWavelet", "BoundaryDiscretizeRegion", "BarOrigin", "BipartiteGraphQ", "BoundaryMesh", "BarSpacing", "BiquadraticFilterModel", "BoundaryMeshRegion", "BartlettHannWindow", "BirnbaumImportance", "BoundaryMeshRegionQ", "BartlettWindow", "BirnbaumSaundersDistribution", "BoundaryStyle", "BaseDecode", "BitAnd", "BoundedRegionQ", "BaseEncode", "BitClear", "BoundingRegion", "BaseForm", "BitGet", "BoxData", "Baseline", "BitLength", "Boxed", "BaselinePosition", "BitNot", "Boxes", "BaseStyle", "BitOr", "BoxMatrix", "BasicRecurrentLayer", "BitSet", "BoxObject", "BatchNormalizationLayer", "BitShiftLeft", "BoxRatios", "BatchSize", "BitShiftRight", "BoxStyle", "BatesDistribution", "BitXor", "BoxWhiskerChart", "BattleLemarieWavelet", "BiweightLocation", "BracketingBar", "BayesianMaximization", "BiweightMidvariance", "BrayCurtisDistance", "BayesianMaximizationObject", "Black", "BreadthFirstScan", "BayesianMinimization", "BlackmanHarrisWindow", "Break", "BayesianMinimizationObject", "BlackmanNuttallWindow", "BridgeData", "Because", "BlackmanWindow", "BrightnessEqualize", "BeckmannDistribution", "Blank", "BroadcastStationData", "Beep", "BlankNullSequence", "Brown", "Before", "BlankSequence", "BrownForsytheTest", "Begin", "Blend", "BrownianBridgeProcess", "BeginDialogPacket", "Block", "BSplineBasis", "BeginPackage", "BlockchainAddressData", "BSplineCurve", "BellB", "BlockchainBase", "BSplineFunction", "BellY", "BlockchainBlockData", "BSplineSurface", "Below", "BlockchainContractValue", "BubbleChart", "BenfordDistribution", "BlockchainData", "BubbleChart3D", "BeniniDistribution", "BlockchainGet", "BubbleScale", "BenktanderGibratDistribution", "BlockchainKeyEncode", "BubbleSizes", "BenktanderWeibullDistribution", "BlockchainPut", "BuildingData", "BernoulliB", "BlockchainTokenData", "BulletGauge", "BernoulliDistribution", "BlockchainTransaction", "BusinessDayQ", "BernoulliGraphDistribution", "BlockchainTransactionData", "ButterflyGraph", "BernoulliProcess", "BlockchainTransactionSign", "ButterworthFilterModel", "BernsteinBasis", "BlockchainTransactionSubmit", "Button", "BesselFilterModel", "BlockMap", "ButtonBar", "BesselI", "BlockRandom", "ButtonBox", "BesselJ", "BlomqvistBeta", "ButtonBoxOptions", "BesselJZero", "BlomqvistBetaTest", "ButtonData", "BesselK", "Blue", "ButtonFunction", "BesselY", "Blur", "ButtonMinHeight", "BesselYZero", "BodePlot", "ButtonNotebook", "Beta", "BohmanWindow", "ButtonSource", "BetaBinomialDistribution", "Bold", "Byte", "BetaDistribution", "Bond", "ByteArray", "BetaNegativeBinomialDistribution", "BondCount", "ByteArrayFormat", "BetaPrimeDistribution", "BondList", "ByteArrayQ", "BetaRegularized", "BondQ", "ByteArrayToString", "Between", "Bookmarks", "ByteCount", "BetweennessCentrality", "Boole", "ByteOrdering", "BeveledPolyhedron", "BooleanConsecutiveFunction", "BezierCurve", "BooleanConvert", "C", "ClearSystemCache", "Construct", "CachePersistence", "ClebschGordan", "Containing", "CalendarConvert", "ClickPane", "ContainsAll", "CalendarData", "Clip", "ContainsAny", "CalendarType", "ClippingStyle", "ContainsExactly", "Callout", "ClipPlanes", "ContainsNone", "CalloutMarker", "ClipPlanesStyle", "ContainsOnly", "CalloutStyle", "ClipRange", "ContentFieldOptions", "CallPacket", "Clock", "ContentLocationFunction", "CanberraDistance", "ClockGauge", "ContentObject", "Cancel", "Close", "ContentPadding", "CancelButton", "CloseKernels", "ContentSelectable", "CandlestickChart", "ClosenessCentrality", "ContentSize", "CanonicalGraph", "Closing", "Context", "CanonicalizePolygon", "CloudAccountData", "Contexts", "CanonicalizePolyhedron", "CloudBase", "ContextToFileName", "CanonicalName", "CloudConnect", "Continue", "CanonicalWarpingCorrespondence", "CloudDeploy", "ContinuedFraction", "CanonicalWarpingDistance", "CloudDirectory", "ContinuedFractionK", "CantorMesh", "CloudDisconnect", "ContinuousAction", "CantorStaircase", "CloudEvaluate", "ContinuousMarkovProcess", "Cap", "CloudExport", "ContinuousTask", "CapForm", "CloudExpression", "ContinuousTimeModelQ", "CapitalDifferentialD", "CloudExpressions", "ContinuousWaveletData", "Capitalize", "CloudFunction", "ContinuousWaveletTransform", "CapsuleShape", "CloudGet", "ContourDetect", "CaptureRunning", "CloudImport", "ContourLabels", "CarlemanLinearize", "CloudLoggingData", "ContourPlot", "CarmichaelLambda", "CloudObject", "ContourPlot3D", "CaseOrdering", "CloudObjectNameFormat", "Contours", "Cases", "CloudObjects", "ContourShading", "CaseSensitive", "CloudObjectURLType", "ContourStyle", "Cashflow", "CloudPublish", "ContraharmonicMean", "Casoratian", "CloudPut", "ContrastiveLossLayer", "Catalan", "CloudRenderingMethod", "Control", "CatalanNumber", "CloudSave", "ControlActive", "Catch", "CloudShare", "ControllabilityGramian", "CategoricalDistribution", "CloudSubmit", "ControllabilityMatrix", "Catenate", "CloudSymbol", "ControllableDecomposition", "CatenateLayer", "CloudUnshare", "ControllableModelQ", "CauchyDistribution", "ClusterClassify", "ControllerInformation", "CauchyWindow", "ClusterDissimilarityFunction", "ControllerLinking", "CayleyGraph", "ClusteringComponents", "ControllerManipulate", "CDF", "ClusteringTree", "ControllerMethod", "CDFDeploy", "CMYKColor", "ControllerPath", "CDFWavelet", "CodeAssistOptions", "ControllerState", "Ceiling", "Coefficient", "ControlPlacement", "CelestialSystem", "CoefficientArrays", "ControlsRendering", "Cell", "CoefficientList", "ControlType", "CellAutoOverwrite", "CoefficientRules", "Convergents", "CellBaseline", "CoifletWavelet", "ConversionRules", "CellBracketOptions", "Collect", "ConvexHullMesh", "CellChangeTimes", "Colon", "ConvexPolygonQ", "CellContext", "ColorBalance", "ConvexPolyhedronQ", "CellDingbat", "ColorCombine", "ConvolutionLayer", "CellDynamicExpression", "ColorConvert", "Convolve", "CellEditDuplicate", "ColorCoverage", "ConwayGroupCo1", "CellEpilog", "ColorData", "ConwayGroupCo2", "CellEvaluationDuplicate", "ColorDataFunction", "ConwayGroupCo3", "CellEvaluationFunction", "ColorDetect", "CookieFunction", "CellEventActions", "ColorDistance", "CoordinateBoundingBox", "CellFrame", "ColorFunction", "CoordinateBoundingBoxArray", "CellFrameColor", "ColorFunctionScaling", "CoordinateBounds", "CellFrameLabelMargins", "Colorize", "CoordinateBoundsArray", "CellFrameLabels", "ColorNegate", "CoordinateChartData", "CellFrameMargins", "ColorProfileData", "CoordinatesToolOptions", "CellGroup", "ColorQ", "CoordinateTransform", "CellGroupData", "ColorQuantize", "CoordinateTransformData", "CellGrouping", "ColorReplace", "CoprimeQ", "CellID", "ColorRules", "Coproduct", "CellLabel", "ColorSeparate", "CopulaDistribution", "CellLabelAutoDelete", "ColorSetter", "Copyable", "CellLabelStyle", "ColorSlider", "CopyDatabin", "CellMargins", "ColorsNear", "CopyDirectory", "CellObject", "ColorSpace", "CopyFile", "CellOpen", "ColorToneMapping", "CopyToClipboard", "CellPrint", "Column", "CornerFilter", "CellProlog", "ColumnAlignments", "CornerNeighbors", "Cells", "ColumnLines", "Correlation", "CellStyle", "ColumnsEqual", "CorrelationDistance", "CellTags", "ColumnSpacings", "CorrelationFunction", "CellularAutomaton", "ColumnWidths", "CorrelationTest", "CensoredDistribution", "CombinedEntityClass", "Cos", "Censoring", "CombinerFunction", "Cosh", "Center", "CometData", "CoshIntegral", "CenterArray", "Commonest", "CosineDistance", "CenterDot", "CommonestFilter", "CosineWindow", "CentralFeature", "CommonName", "CosIntegral", "CentralMoment", "CommonUnits", "Cot", "CentralMomentGeneratingFunction", "CommunityBoundaryStyle", "Coth", "Cepstrogram", "CommunityGraphPlot", "Count", "CepstrogramArray", "CommunityLabels", "CountDistinct", "CepstrumArray", "CommunityRegionStyle", "CountDistinctBy", "CForm", "CompanyData", "CountRoots", "ChampernowneNumber", "CompatibleUnitQ", "CountryData", "ChannelBase", "CompilationOptions", "Counts", "ChannelBrokerAction", "CompilationTarget", "CountsBy", "ChannelHistoryLength", "Compile", "Covariance", "ChannelListen", "Compiled", "CovarianceEstimatorFunction", "ChannelListener", "CompiledCodeFunction", "CovarianceFunction", "ChannelListeners", "CompiledFunction", "CoxianDistribution", "ChannelObject", "CompilerOptions", "CoxIngersollRossProcess", "ChannelReceiverFunction", "Complement", "CoxModel", "ChannelSend", "ComplementedEntityClass", "CoxModelFit", "ChannelSubscribers", "CompleteGraph", "CramerVonMisesTest", "ChanVeseBinarize", "CompleteGraphQ", "CreateArchive", "Character", "CompleteKaryTree", "CreateCellID", "CharacterCounts", "Complex", "CreateChannel", "CharacterEncoding", "ComplexContourPlot", "CreateCloudExpression", "CharacteristicFunction", "Complexes", "CreateDatabin", "CharacteristicPolynomial", "ComplexExpand", "CreateDataStructure", "CharacterName", "ComplexInfinity", "CreateDataSystemModel", "CharacterNormalize", "ComplexityFunction", "CreateDialog", "CharacterRange", "ComplexListPlot", "CreateDirectory", "Characters", "ComplexPlot", "CreateDocument", "ChartBaseStyle", "ComplexPlot3D", "CreateFile", "ChartElementFunction", "ComplexRegionPlot", "CreateIntermediateDirectories", "ChartElements", "ComplexStreamPlot", "CreateManagedLibraryExpression", "ChartLabels", "ComplexVectorPlot", "CreateNotebook", "ChartLayout", "ComponentMeasurements", "CreatePacletArchive", "ChartLegends", "ComposeList", "CreatePalette", "ChartStyle", "ComposeSeries", "CreatePermissionsGroup", "Chebyshev1FilterModel", "CompositeQ", "CreateSearchIndex", "Chebyshev2FilterModel", "Composition", "CreateSystemModel", "ChebyshevT", "CompoundElement", "CreateUUID", "ChebyshevU", "CompoundExpression", "CreateWindow", "Check", "CompoundPoissonDistribution", "CriterionFunction", "CheckAbort", "CompoundPoissonProcess", "CriticalityFailureImportance", "Checkbox", "CompoundRenewalProcess", "CriticalitySuccessImportance", "CheckboxBar", "Compress", "CriticalSection", "ChemicalData", "CompressionLevel", "Cross", "ChessboardDistance", "ComputeUncertainty", "CrossEntropyLossLayer", "ChiDistribution", "Condition", "CrossingCount", "ChineseRemainder", "ConditionalExpression", "CrossingDetect", "ChiSquareDistribution", "Conditioned", "CrossingPolygon", "ChoiceButtons", "Cone", "CrossMatrix", "ChoiceDialog", "ConfidenceLevel", "Csc", "CholeskyDecomposition", "ConfidenceRange", "Csch", "Chop", "ConfidenceTransform", "CTCLossLayer", "ChromaticityPlot", "ConformAudio", "Cube", "ChromaticityPlot3D", "ConformImages", "CubeRoot", "ChromaticPolynomial", "Congruent", "Cubics", "Circle", "ConicHullRegion", "Cuboid", "CircleDot", "ConicOptimization", "Cumulant", "CircleMinus", "Conjugate", "CumulantGeneratingFunction", "CirclePlus", "ConjugateTranspose", "Cup", "CirclePoints", "Conjunction", "CupCap", "CircleThrough", "ConnectedComponents", "Curl", "CircleTimes", "ConnectedGraphComponents", "CurrencyConvert", "CirculantGraph", "ConnectedGraphQ", "CurrentDate", "CircularOrthogonalMatrixDistribution", "ConnectedMeshComponents", "CurrentImage", "CircularQuaternionMatrixDistribution", "ConnectedMoleculeComponents", "CurrentNotebookImage", "CircularRealMatrixDistribution", "ConnectedMoleculeQ", "CurrentScreenImage", "CircularSymplecticMatrixDistribution", "ConnectionSettings", "CurrentValue", "CircularUnitaryMatrixDistribution", "ConnectLibraryCallbackFunction", "CurryApplied", "Circumsphere", "ConnectSystemModelComponents", "CurvatureFlowFilter", "CityData", "ConnesWindow", "CurveClosed", "ClassifierFunction", "ConoverTest", "Cyan", "ClassifierMeasurements", "Constant", "CycleGraph", "ClassifierMeasurementsObject", "ConstantArray", "CycleIndexPolynomial", "Classify", "ConstantArrayLayer", "Cycles", "ClassPriors", "ConstantImage", "CyclicGroup", "Clear", "ConstantPlusLayer", "Cyclotomic", "ClearAll", "ConstantRegionQ", "Cylinder", "ClearAttributes", "Constants", "CylindricalDecomposition", "ClearCookies", "ConstantTimesLayer", "ClearPermissions", "ConstellationData", "D", "DeleteFile", "DiscreteLyapunovSolve", "DagumDistribution", "DeleteMissing", "DiscreteMarkovProcess", "DamData", "DeleteObject", "DiscreteMaxLimit", "DamerauLevenshteinDistance", "DeletePermissionsKey", "DiscreteMinLimit", "Darker", "DeleteSearchIndex", "DiscretePlot", "Dashed", "DeleteSmallComponents", "DiscretePlot3D", "Dashing", "DeleteStopwords", "DiscreteRatio", "DatabaseConnect", "DelimitedSequence", "DiscreteRiccatiSolve", "DatabaseDisconnect", "Delimiter", "DiscreteShift", "DatabaseReference", "DelimiterFlashTime", "DiscreteTimeModelQ", "Databin", "Delimiters", "DiscreteUniformDistribution", "DatabinAdd", "DeliveryFunction", "DiscreteVariables", "DatabinRemove", "Dendrogram", "DiscreteWaveletData", "Databins", "Denominator", "DiscreteWaveletPacketTransform", "DatabinUpload", "DensityHistogram", "DiscreteWaveletTransform", "DataDistribution", "DensityPlot", "DiscretizeGraphics", "DataRange", "DensityPlot3D", "DiscretizeRegion", "DataReversed", "DependentVariables", "Discriminant", "Dataset", "Deploy", "DisjointQ", "DataStructure", "Deployed", "Disjunction", "DataStructureQ", "Depth", "Disk", "DateBounds", "DepthFirstScan", "DiskMatrix", "Dated", "Derivative", "DiskSegment", "DateDifference", "DerivativeFilter", "Dispatch", "DatedUnit", "DerivedKey", "DispersionEstimatorFunction", "DateFormat", "DescriptorStateSpace", "DisplayAllSteps", "DateFunction", "DesignMatrix", "DisplayEndPacket", "DateHistogram", "Det", "DisplayForm", "DateInterval", "DeviceClose", "DisplayFunction", "DateList", "DeviceConfigure", "DisplayPacket", "DateListLogPlot", "DeviceExecute", "DistanceFunction", "DateListPlot", "DeviceExecuteAsynchronous", "DistanceMatrix", "DateListStepPlot", "DeviceObject", "DistanceTransform", "DateObject", "DeviceOpen", "Distribute", "DateObjectQ", "DeviceRead", "Distributed", "DateOverlapsQ", "DeviceReadBuffer", "DistributedContexts", "DatePattern", "DeviceReadLatest", "DistributeDefinitions", "DatePlus", "DeviceReadList", "DistributionChart", "DateRange", "DeviceReadTimeSeries", "DistributionFitTest", "DateReduction", "Devices", "DistributionParameterAssumptions", "DateString", "DeviceStreams", "DistributionParameterQ", "DateTicksFormat", "DeviceWrite", "Dithering", "DateValue", "DeviceWriteBuffer", "Div", "DateWithinQ", "DGaussianWavelet", "Divide", "DaubechiesWavelet", "Diagonal", "DivideBy", "DavisDistribution", "DiagonalizableMatrixQ", "Dividers", "DawsonF", "DiagonalMatrix", "DivideSides", "DayCount", "DiagonalMatrixQ", "Divisible", "DayCountConvention", "Dialog", "Divisors", "DayHemisphere", "DialogInput", "DivisorSigma", "DaylightQ", "DialogNotebook", "DivisorSum", "DayMatchQ", "DialogProlog", "DMSList", "DayName", "DialogReturn", "DMSString", "DayNightTerminator", "DialogSymbols", "Do", "DayPlus", "Diamond", "DockedCells", "DayRange", "DiamondMatrix", "DocumentGenerator", "DayRound", "DiceDissimilarity", "DocumentGeneratorInformation", "DeBruijnGraph", "DictionaryLookup", "DocumentGenerators", "DeBruijnSequence", "DictionaryWordQ", "DocumentNotebook", "Decapitalize", "DifferenceDelta", "DocumentWeightingRules", "DecimalForm", "DifferenceQuotient", "Dodecahedron", "DeclarePackage", "DifferenceRoot", "DominantColors", "Decompose", "DifferenceRootReduce", "Dot", "DeconvolutionLayer", "Differences", "DotDashed", "Decrement", "DifferentialD", "DotEqual", "Decrypt", "DifferentialRoot", "DotLayer", "DecryptFile", "DifferentialRootReduce", "Dotted", "DedekindEta", "DifferentiatorFilter", "DoubleBracketingBar", "DeepSpaceProbeData", "DigitalSignature", "DoubleDownArrow", "Default", "DigitBlock", "DoubleLeftArrow", "DefaultAxesStyle", "DigitCharacter", "DoubleLeftRightArrow", "DefaultBaseStyle", "DigitCount", "DoubleLeftTee", "DefaultBoxStyle", "DigitQ", "DoubleLongLeftArrow", "DefaultButton", "DihedralAngle", "DoubleLongLeftRightArrow", "DefaultDuplicateCellStyle", "DihedralGroup", "DoubleLongRightArrow", "DefaultDuration", "Dilation", "DoubleRightArrow", "DefaultElement", "DimensionalCombinations", "DoubleRightTee", "DefaultFaceGridsStyle", "DimensionalMeshComponents", "DoubleUpArrow", "DefaultFieldHintStyle", "DimensionReduce", "DoubleUpDownArrow", "DefaultFrameStyle", "DimensionReducerFunction", "DoubleVerticalBar", "DefaultFrameTicksStyle", "DimensionReduction", "DownArrow", "DefaultGridLinesStyle", "Dimensions", "DownArrowBar", "DefaultLabelStyle", "DiracComb", "DownArrowUpArrow", "DefaultMenuStyle", "DiracDelta", "DownLeftRightVector", "DefaultNaturalLanguage", "DirectedEdge", "DownLeftTeeVector", "DefaultNewCellStyle", "DirectedEdges", "DownLeftVector", "DefaultOptions", "DirectedGraph", "DownLeftVectorBar", "DefaultPrintPrecision", "DirectedGraphQ", "DownRightTeeVector", "DefaultTicksStyle", "DirectedInfinity", "DownRightVector", "DefaultTooltipStyle", "Direction", "DownRightVectorBar", "Defer", "Directive", "Downsample", "DefineInputStreamMethod", "Directory", "DownTee", "DefineOutputStreamMethod", "DirectoryName", "DownTeeArrow", "DefineResourceFunction", "DirectoryQ", "DownValues", "Definition", "DirectoryStack", "Drop", "Degree", "DirichletBeta", "DropoutLayer", "DegreeCentrality", "DirichletCharacter", "DSolve", "DegreeGraphDistribution", "DirichletCondition", "DSolveValue", "DEigensystem", "DirichletConvolve", "Dt", "DEigenvalues", "DirichletDistribution", "DualPolyhedron", "Deinitialization", "DirichletEta", "DualSystemsModel", "Del", "DirichletL", "DumpSave", "DelaunayMesh", "DirichletLambda", "DuplicateFreeQ", "Delayed", "DirichletTransform", "Duration", "Deletable", "DirichletWindow", "Dynamic", "Delete", "DisableFormatting", "DynamicEvaluationTimeout", "DeleteAnomalies", "DiscreteAsymptotic", "DynamicGeoGraphics", "DeleteBorderComponents", "DiscreteChirpZTransform", "DynamicImage", "DeleteCases", "DiscreteConvolve", "DynamicModule", "DeleteChannel", "DiscreteDelta", "DynamicModuleValues", "DeleteCloudExpression", "DiscreteHadamardTransform", "DynamicSetting", "DeleteContents", "DiscreteIndicator", "DynamicUpdating", "DeleteDirectory", "DiscreteLimit", "DynamicWrapper", "DeleteDuplicates", "DiscreteLQEstimatorGains", "DeleteDuplicatesBy", "DiscreteLQRegulatorGains", "E", "EndOfFile", "EventHandler", "EarthImpactData", "EndOfLine", "EventLabels", "EarthquakeData", "EndOfString", "EventSeries", "EccentricityCentrality", "EndPackage", "ExactBlackmanWindow", "Echo", "EngineeringForm", "ExactNumberQ", "EchoFunction", "EnterExpressionPacket", "ExampleData", "EclipseType", "EnterTextPacket", "Except", "EdgeAdd", "Entity", "ExcludedForms", "EdgeBetweennessCentrality", "EntityClass", "ExcludedLines", "EdgeCapacity", "EntityClassList", "ExcludedPhysicalQuantities", "EdgeConnectivity", "EntityCopies", "ExcludePods", "EdgeContract", "EntityFunction", "Exclusions", "EdgeCost", "EntityGroup", "ExclusionsStyle", "EdgeCount", "EntityInstance", "Exists", "EdgeCoverQ", "EntityList", "Exit", "EdgeCycleMatrix", "EntityPrefetch", "ExoplanetData", "EdgeDelete", "EntityProperties", "Exp", "EdgeDetect", "EntityProperty", "Expand", "EdgeForm", "EntityPropertyClass", "ExpandAll", "EdgeIndex", "EntityRegister", "ExpandDenominator", "EdgeLabels", "EntityStore", "ExpandFileName", "EdgeLabelStyle", "EntityStores", "ExpandNumerator", "EdgeList", "EntityTypeName", "Expectation", "EdgeQ", "EntityUnregister", "ExpGammaDistribution", "EdgeRules", "EntityValue", "ExpIntegralE", "EdgeShapeFunction", "Entropy", "ExpIntegralEi", "EdgeStyle", "EntropyFilter", "ExpirationDate", "EdgeTaggedGraph", "Environment", "Exponent", "EdgeTaggedGraphQ", "Epilog", "ExponentFunction", "EdgeTags", "EpilogFunction", "ExponentialDistribution", "EdgeWeight", "Equal", "ExponentialFamily", "EdgeWeightedGraphQ", "EqualTilde", "ExponentialGeneratingFunction", "Editable", "EqualTo", "ExponentialMovingAverage", "EditDistance", "Equilibrium", "ExponentialPowerDistribution", "EffectiveInterest", "EquirippleFilterKernel", "ExponentStep", "Eigensystem", "Equivalent", "Export", "Eigenvalues", "Erf", "ExportByteArray", "EigenvectorCentrality", "Erfc", "ExportForm", "Eigenvectors", "Erfi", "ExportString", "Element", "ErlangB", "Expression", "ElementData", "ErlangC", "ExpressionCell", "ElementwiseLayer", "ErlangDistribution", "ExpressionGraph", "ElidedForms", "Erosion", "ExpToTrig", "Eliminate", "ErrorBox", "ExtendedEntityClass", "Ellipsoid", "EscapeRadius", "ExtendedGCD", "EllipticE", "EstimatedBackground", "Extension", "EllipticExp", "EstimatedDistribution", "ExtentElementFunction", "EllipticExpPrime", "EstimatedProcess", "ExtentMarkers", "EllipticF", "EstimatorGains", "ExtentSize", "EllipticFilterModel", "EstimatorRegulator", "ExternalBundle", "EllipticK", "EuclideanDistance", "ExternalEvaluate", "EllipticLog", "EulerAngles", "ExternalFunction", "EllipticNomeQ", "EulerCharacteristic", "ExternalIdentifier", "EllipticPi", "EulerE", "ExternalObject", "EllipticTheta", "EulerGamma", "ExternalOptions", "EllipticThetaPrime", "EulerianGraphQ", "ExternalSessionObject", "EmbedCode", "EulerMatrix", "ExternalSessions", "EmbeddedHTML", "EulerPhi", "ExternalStorageBase", "EmbeddedService", "Evaluatable", "ExternalStorageDownload", "EmbeddingLayer", "Evaluate", "ExternalStorageGet", "EmitSound", "EvaluatePacket", "ExternalStorageObject", "EmpiricalDistribution", "EvaluationBox", "ExternalStoragePut", "EmptyGraphQ", "EvaluationCell", "ExternalStorageUpload", "EmptyRegion", "EvaluationData", "ExternalTypeSignature", "Enabled", "EvaluationElements", "ExternalValue", "Encode", "EvaluationEnvironment", "Extract", "Encrypt", "EvaluationMonitor", "ExtractArchive", "EncryptedObject", "EvaluationNotebook", "ExtractLayer", "EncryptFile", "EvaluationObject", "ExtractPacletArchive", "End", "Evaluator", "ExtremeValueDistribution", "EndDialogPacket", "EvenQ", "EndOfBuffer", "EventData", "FaceAlign", "FindFaces", "ForceVersionInstall", "FaceForm", "FindFile", "Format", "FaceGrids", "FindFit", "FormatType", "FaceGridsStyle", "FindFormula", "FormBox", "FacialFeatures", "FindFundamentalCycles", "FormBoxOptions", "Factor", "FindGeneratingFunction", "FormControl", "Factorial", "FindGeoLocation", "FormFunction", "Factorial2", "FindGeometricConjectures", "FormLayoutFunction", "FactorialMoment", "FindGeometricTransform", "FormObject", "FactorialMomentGeneratingFunction", "FindGraphCommunities", "FormPage", "FactorialPower", "FindGraphIsomorphism", "FormulaData", "FactorInteger", "FindGraphPartition", "FormulaLookup", "FactorList", "FindHamiltonianCycle", "FortranForm", "FactorSquareFree", "FindHamiltonianPath", "Forward", "FactorSquareFreeList", "FindHiddenMarkovStates", "ForwardBackward", "FactorTerms", "FindImageText", "Fourier", "FactorTermsList", "FindIndependentEdgeSet", "FourierCoefficient", "Failure", "FindIndependentVertexSet", "FourierCosCoefficient", "FailureAction", "FindInstance", "FourierCosSeries", "FailureDistribution", "FindIntegerNullVector", "FourierCosTransform", "FailureQ", "FindKClan", "FourierDCT", "False", "FindKClique", "FourierDCTFilter", "FareySequence", "FindKClub", "FourierDCTMatrix", "FARIMAProcess", "FindKPlex", "FourierDST", "FeatureDistance", "FindLibrary", "FourierDSTMatrix", "FeatureExtract", "FindLinearRecurrence", "FourierMatrix", "FeatureExtraction", "FindList", "FourierParameters", "FeatureExtractor", "FindMatchingColor", "FourierSequenceTransform", "FeatureExtractorFunction", "FindMaximum", "FourierSeries", "FeatureNames", "FindMaximumCut", "FourierSinCoefficient", "FeatureNearest", "FindMaximumFlow", "FourierSinSeries", "FeatureSpacePlot", "FindMaxValue", "FourierSinTransform", "FeatureSpacePlot3D", "FindMeshDefects", "FourierTransform", "FeatureTypes", "FindMinimum", "FourierTrigSeries", "FeedbackLinearize", "FindMinimumCostFlow", "FractionalBrownianMotionProcess", "FeedbackSector", "FindMinimumCut", "FractionalGaussianNoiseProcess", "FeedbackSectorStyle", "FindMinValue", "FractionalPart", "FeedbackType", "FindMoleculeSubstructure", "FractionBox", "FetalGrowthData", "FindPath", "FractionBoxOptions", "Fibonacci", "FindPeaks", "Frame", "Fibonorial", "FindPermutation", "FrameBox", "FieldCompletionFunction", "FindPostmanTour", "FrameBoxOptions", "FieldHint", "FindProcessParameters", "Framed", "FieldHintStyle", "FindRepeat", "FrameLabel", "FieldMasked", "FindRoot", "FrameMargins", "FieldSize", "FindSequenceFunction", "FrameRate", "File", "FindSettings", "FrameStyle", "FileBaseName", "FindShortestPath", "FrameTicks", "FileByteCount", "FindShortestTour", "FrameTicksStyle", "FileConvert", "FindSpanningTree", "FRatioDistribution", "FileDate", "FindSystemModelEquilibrium", "FrechetDistribution", "FileExistsQ", "FindTextualAnswer", "FreeQ", "FileExtension", "FindThreshold", "FrenetSerretSystem", "FileFormat", "FindTransientRepeat", "FrequencySamplingFilterKernel", "FileHash", "FindVertexCover", "FresnelC", "FileNameDepth", "FindVertexCut", "FresnelF", "FileNameDrop", "FindVertexIndependentPaths", "FresnelG", "FileNameForms", "FinishDynamic", "FresnelS", "FileNameJoin", "FiniteAbelianGroupCount", "Friday", "FileNames", "FiniteGroupCount", "FrobeniusNumber", "FileNameSetter", "FiniteGroupData", "FrobeniusSolve", "FileNameSplit", "First", "FromAbsoluteTime", "FileNameTake", "FirstCase", "FromCharacterCode", "FilePrint", "FirstPassageTimeDistribution", "FromCoefficientRules", "FileSize", "FirstPosition", "FromContinuedFraction", "FileSystemMap", "FischerGroupFi22", "FromDigits", "FileSystemScan", "FischerGroupFi23", "FromDMS", "FileTemplate", "FischerGroupFi24Prime", "FromEntity", "FileTemplateApply", "FisherHypergeometricDistribution", "FromJulianDate", "FileType", "FisherRatioTest", "FromLetterNumber", "FilledCurve", "FisherZDistribution", "FromPolarCoordinates", "Filling", "Fit", "FromRomanNumeral", "FillingStyle", "FitRegularization", "FromSphericalCoordinates", "FillingTransform", "FittedModel", "FromUnixTime", "FilteredEntityClass", "FixedOrder", "Front", "FilterRules", "FixedPoint", "FrontEndDynamicExpression", "FinancialBond", "FixedPointList", "FrontEndEventActions", "FinancialData", "Flat", "FrontEndExecute", "FinancialDerivative", "Flatten", "FrontEndToken", "FinancialIndicator", "FlattenAt", "FrontEndTokenExecute", "Find", "FlattenLayer", "Full", "FindAnomalies", "FlatTopWindow", "FullDefinition", "FindArgMax", "FlipView", "FullForm", "FindArgMin", "Floor", "FullGraphics", "FindChannels", "FlowPolynomial", "FullInformationOutputRegulator", "FindClique", "Fold", "FullRegion", "FindClusters", "FoldList", "FullSimplify", "FindCookies", "FoldPair", "Function", "FindCurvePath", "FoldPairList", "FunctionCompile", "FindCycle", "FollowRedirects", "FunctionCompileExport", "FindDevices", "FontColor", "FunctionCompileExportByteArray", "FindDistribution", "FontFamily", "FunctionCompileExportLibrary", "FindDistributionParameters", "FontSize", "FunctionCompileExportString", "FindDivisions", "FontSlant", "FunctionDomain", "FindEdgeCover", "FontSubstitutions", "FunctionExpand", "FindEdgeCut", "FontTracking", "FunctionInterpolation", "FindEdgeIndependentPaths", "FontVariations", "FunctionPeriod", "FindEquationalProof", "FontWeight", "FunctionRange", "FindEulerianCycle", "For", "FunctionSpace", "FindExternalEvaluators", "ForAll", "FussellVeselyImportance", "GaborFilter", "GeoGraphics", "Graph", "GaborMatrix", "GeogravityModelData", "Graph3D", "GaborWavelet", "GeoGridDirectionDifference", "GraphAssortativity", "GainMargins", "GeoGridLines", "GraphAutomorphismGroup", "GainPhaseMargins", "GeoGridLinesStyle", "GraphCenter", "GalaxyData", "GeoGridPosition", "GraphComplement", "GalleryView", "GeoGridRange", "GraphData", "Gamma", "GeoGridRangePadding", "GraphDensity", "GammaDistribution", "GeoGridUnitArea", "GraphDiameter", "GammaRegularized", "GeoGridUnitDistance", "GraphDifference", "GapPenalty", "GeoGridVector", "GraphDisjointUnion", "GARCHProcess", "GeoGroup", "GraphDistance", "GatedRecurrentLayer", "GeoHemisphere", "GraphDistanceMatrix", "Gather", "GeoHemisphereBoundary", "GraphEmbedding", "GatherBy", "GeoHistogram", "GraphHighlight", "GaugeFaceElementFunction", "GeoIdentify", "GraphHighlightStyle", "GaugeFaceStyle", "GeoImage", "GraphHub", "GaugeFrameElementFunction", "GeoLabels", "Graphics", "GaugeFrameSize", "GeoLength", "Graphics3D", "GaugeFrameStyle", "GeoListPlot", "GraphicsColumn", "GaugeLabels", "GeoLocation", "GraphicsComplex", "GaugeMarkers", "GeologicalPeriodData", "GraphicsGrid", "GaugeStyle", "GeomagneticModelData", "GraphicsGroup", "GaussianFilter", "GeoMarker", "GraphicsRow", "GaussianIntegers", "GeometricAssertion", "GraphIntersection", "GaussianMatrix", "GeometricBrownianMotionProcess", "GraphLayout", "GaussianOrthogonalMatrixDistribution", "GeometricDistribution", "GraphLinkEfficiency", "GaussianSymplecticMatrixDistribution", "GeometricMean", "GraphPeriphery", "GaussianUnitaryMatrixDistribution", "GeometricMeanFilter", "GraphPlot", "GaussianWindow", "GeometricOptimization", "GraphPlot3D", "GCD", "GeometricScene", "GraphPower", "GegenbauerC", "GeometricTransformation", "GraphPropertyDistribution", "General", "GeoModel", "GraphQ", "GeneralizedLinearModelFit", "GeoNearest", "GraphRadius", "GenerateAsymmetricKeyPair", "GeoPath", "GraphReciprocity", "GenerateConditions", "GeoPosition", "GraphUnion", "GeneratedCell", "GeoPositionENU", "Gray", "GeneratedDocumentBinding", "GeoPositionXYZ", "GrayLevel", "GenerateDerivedKey", "GeoProjection", "Greater", "GenerateDigitalSignature", "GeoProjectionData", "GreaterEqual", "GenerateDocument", "GeoRange", "GreaterEqualLess", "GeneratedParameters", "GeoRangePadding", "GreaterEqualThan", "GeneratedQuantityMagnitudes", "GeoRegionValuePlot", "GreaterFullEqual", "GenerateFileSignature", "GeoResolution", "GreaterGreater", "GenerateHTTPResponse", "GeoScaleBar", "GreaterLess", "GenerateSecuredAuthenticationKey", "GeoServer", "GreaterSlantEqual", "GenerateSymmetricKey", "GeoSmoothHistogram", "GreaterThan", "GeneratingFunction", "GeoStreamPlot", "GreaterTilde", "GeneratorDescription", "GeoStyling", "Green", "GeneratorHistoryLength", "GeoStylingImageFunction", "GreenFunction", "GeneratorOutputType", "GeoVariant", "Grid", "GenericCylindricalDecomposition", "GeoVector", "GridBox", "GenomeData", "GeoVectorENU", "GridDefaultElement", "GenomeLookup", "GeoVectorPlot", "GridGraph", "GeoAntipode", "GeoVectorXYZ", "GridLines", "GeoArea", "GeoVisibleRegion", "GridLinesStyle", "GeoArraySize", "GeoVisibleRegionBoundary", "GroebnerBasis", "GeoBackground", "GeoWithinQ", "GroupActionBase", "GeoBoundingBox", "GeoZoomLevel", "GroupBy", "GeoBounds", "GestureHandler", "GroupCentralizer", "GeoBoundsRegion", "Get", "GroupElementFromWord", "GeoBubbleChart", "GetEnvironment", "GroupElementPosition", "GeoCenter", "Glaisher", "GroupElementQ", "GeoCircle", "GlobalClusteringCoefficient", "GroupElements", "GeoContourPlot", "Glow", "GroupElementToWord", "GeoDensityPlot", "GoldenAngle", "GroupGenerators", "GeodesicClosing", "GoldenRatio", "Groupings", "GeodesicDilation", "GompertzMakehamDistribution", "GroupMultiplicationTable", "GeodesicErosion", "GoochShading", "GroupOrbits", "GeodesicOpening", "GoodmanKruskalGamma", "GroupOrder", "GeoDestination", "GoodmanKruskalGammaTest", "GroupPageBreakWithin", "GeodesyData", "Goto", "GroupSetwiseStabilizer", "GeoDirection", "Grad", "GroupStabilizer", "GeoDisk", "Gradient", "GroupStabilizerChain", "GeoDisplacement", "GradientFilter", "GrowCutComponents", "GeoDistance", "GradientOrientationFilter", "Gudermannian", "GeoDistanceList", "GrammarApply", "GuidedFilter", "GeoElevationData", "GrammarRules", "GumbelDistribution", "GeoEntities", "GrammarToken", "HaarWavelet", "HermiteH", "HoldComplete", "HadamardMatrix", "HermitianMatrixQ", "HoldFirst", "HalfLine", "HessenbergDecomposition", "HoldForm", "HalfNormalDistribution", "HeunB", "HoldPattern", "HalfPlane", "HeunBPrime", "HoldRest", "HalfSpace", "HeunC", "HolidayCalendar", "HalftoneShading", "HeunCPrime", "HorizontalGauge", "HamiltonianGraphQ", "HeunD", "HornerForm", "HammingDistance", "HeunDPrime", "HostLookup", "HammingWindow", "HeunG", "HotellingTSquareDistribution", "HandlerFunctions", "HeunGPrime", "HoytDistribution", "HandlerFunctionsKeys", "HeunT", "HTTPErrorResponse", "HankelH1", "HeunTPrime", "HTTPRedirect", "HankelH2", "HexadecimalCharacter", "HTTPRequest", "HankelMatrix", "Hexahedron", "HTTPRequestData", "HankelTransform", "HiddenItems", "HTTPResponse", "HannPoissonWindow", "HiddenMarkovProcess", "Hue", "HannWindow", "Highlighted", "HumanGrowthData", "HaradaNortonGroupHN", "HighlightGraph", "HumpDownHump", "HararyGraph", "HighlightImage", "HumpEqual", "HarmonicMean", "HighlightMesh", "HurwitzLerchPhi", "HarmonicMeanFilter", "HighpassFilter", "HurwitzZeta", "HarmonicNumber", "HigmanSimsGroupHS", "HyperbolicDistribution", "Hash", "HilbertCurve", "HypercubeGraph", "HatchFilling", "HilbertFilter", "HyperexponentialDistribution", "HatchShading", "HilbertMatrix", "Hyperfactorial", "Haversine", "Histogram", "Hypergeometric0F1", "HazardFunction", "Histogram3D", "Hypergeometric0F1Regularized", "Head", "HistogramDistribution", "Hypergeometric1F1", "HeaderAlignment", "HistogramList", "Hypergeometric1F1Regularized", "HeaderBackground", "HistogramTransform", "Hypergeometric2F1", "HeaderDisplayFunction", "HistogramTransformInterpolation", "Hypergeometric2F1Regularized", "HeaderLines", "HistoricalPeriodData", "HypergeometricDistribution", "HeaderSize", "HitMissTransform", "HypergeometricPFQ", "HeaderStyle", "HITSCentrality", "HypergeometricPFQRegularized", "Heads", "HjorthDistribution", "HypergeometricU", "HeavisideLambda", "HodgeDual", "Hyperlink", "HeavisidePi", "HoeffdingD", "HyperlinkAction", "HeavisideTheta", "HoeffdingDTest", "Hyperplane", "HeldGroupHe", "Hold", "Hyphenation", "Here", "HoldAll", "HypoexponentialDistribution", "HermiteDecomposition", "HoldAllComplete", "HypothesisTestData", "I", "ImageSizeMultipliers", "IntegerName", "IconData", "ImageSubtract", "IntegerPart", "Iconize", "ImageTake", "IntegerPartitions", "IconRules", "ImageTransformation", "IntegerQ", "Icosahedron", "ImageTrim", "IntegerReverse", "Identity", "ImageType", "Integers", "IdentityMatrix", "ImageValue", "IntegerString", "If", "ImageValuePositions", "Integrate", "IgnoreCase", "ImagingDevice", "Interactive", "IgnoreDiacritics", "ImplicitRegion", "InteractiveTradingChart", "IgnorePunctuation", "Implies", "Interleaving", "IgnoringInactive", "Import", "InternallyBalancedDecomposition", "Im", "ImportByteArray", "InterpolatingFunction", "Image", "ImportOptions", "InterpolatingPolynomial", "Image3D", "ImportString", "Interpolation", "Image3DProjection", "ImprovementImportance", "InterpolationOrder", "Image3DSlices", "In", "InterpolationPoints", "ImageAccumulate", "Inactivate", "Interpretation", "ImageAdd", "Inactive", "InterpretationBox", "ImageAdjust", "IncidenceGraph", "InterpretationBoxOptions", "ImageAlign", "IncidenceList", "Interpreter", "ImageApply", "IncidenceMatrix", "InterquartileRange", "ImageApplyIndexed", "IncludeAromaticBonds", "Interrupt", "ImageAspectRatio", "IncludeConstantBasis", "IntersectedEntityClass", "ImageAssemble", "IncludeDefinitions", "IntersectingQ", "ImageAugmentationLayer", "IncludeDirectories", "Intersection", "ImageBoundingBoxes", "IncludeGeneratorTasks", "Interval", "ImageCapture", "IncludeHydrogens", "IntervalIntersection", "ImageCaptureFunction", "IncludeInflections", "IntervalMarkers", "ImageCases", "IncludeMetaInformation", "IntervalMarkersStyle", "ImageChannels", "IncludePods", "IntervalMemberQ", "ImageClip", "IncludeQuantities", "IntervalSlider", "ImageCollage", "IncludeRelatedTables", "IntervalUnion", "ImageColorSpace", "IncludeWindowTimes", "Inverse", "ImageCompose", "Increment", "InverseBetaRegularized", "ImageContainsQ", "IndefiniteMatrixQ", "InverseCDF", "ImageContents", "IndependenceTest", "InverseChiSquareDistribution", "ImageConvolve", "IndependentEdgeSetQ", "InverseContinuousWaveletTransform", "ImageCooccurrence", "IndependentPhysicalQuantity", "InverseDistanceTransform", "ImageCorners", "IndependentUnit", "InverseEllipticNomeQ", "ImageCorrelate", "IndependentUnitDimension", "InverseErf", "ImageCorrespondingPoints", "IndependentVertexSetQ", "InverseErfc", "ImageCrop", "Indeterminate", "InverseFourier", "ImageData", "IndeterminateThreshold", "InverseFourierCosTransform", "ImageDeconvolve", "Indexed", "InverseFourierSequenceTransform", "ImageDemosaic", "IndexEdgeTaggedGraph", "InverseFourierSinTransform", "ImageDifference", "IndexGraph", "InverseFourierTransform", "ImageDimensions", "InexactNumberQ", "InverseFunction", "ImageDisplacements", "InfiniteFuture", "InverseFunctions", "ImageDistance", "InfiniteLine", "InverseGammaDistribution", "ImageEffect", "InfinitePast", "InverseGammaRegularized", "ImageExposureCombine", "InfinitePlane", "InverseGaussianDistribution", "ImageFeatureTrack", "Infinity", "InverseGudermannian", "ImageFileApply", "Infix", "InverseHankelTransform", "ImageFileFilter", "InflationAdjust", "InverseHaversine", "ImageFileScan", "InflationMethod", "InverseImagePyramid", "ImageFilter", "Information", "InverseJacobiCD", "ImageFocusCombine", "Inherited", "InverseJacobiCN", "ImageForestingComponents", "InheritScope", "InverseJacobiCS", "ImageFormattingWidth", "InhomogeneousPoissonProcess", "InverseJacobiDC", "ImageForwardTransformation", "InitialEvaluationHistory", "InverseJacobiDN", "ImageGraphics", "Initialization", "InverseJacobiDS", "ImageHistogram", "InitializationCell", "InverseJacobiNC", "ImageIdentify", "InitializationObjects", "InverseJacobiND", "ImageInstanceQ", "InitializationValue", "InverseJacobiNS", "ImageKeypoints", "Initialize", "InverseJacobiSC", "ImageLabels", "InitialSeeding", "InverseJacobiSD", "ImageLegends", "Inner", "InverseJacobiSN", "ImageLevels", "InnerPolygon", "InverseLaplaceTransform", "ImageLines", "InnerPolyhedron", "InverseMellinTransform", "ImageMargins", "Inpaint", "InversePermutation", "ImageMarker", "Input", "InverseRadon", "ImageMeasurements", "InputAliases", "InverseRadonTransform", "ImageMesh", "InputAssumptions", "InverseSeries", "ImageMultiply", "InputAutoReplacements", "InverseShortTimeFourier", "ImagePad", "InputField", "InverseSpectrogram", "ImagePadding", "InputForm", "InverseSurvivalFunction", "ImagePartition", "InputNamePacket", "InverseTransformedRegion", "ImagePeriodogram", "InputNotebook", "InverseWaveletTransform", "ImagePerspectiveTransformation", "InputPacket", "InverseWeierstrassP", "ImagePosition", "InputStream", "InverseWishartMatrixDistribution", "ImagePreviewFunction", "InputString", "InverseZTransform", "ImagePyramid", "InputStringPacket", "Invisible", "ImagePyramidApply", "Insert", "IPAddress", "ImageQ", "InsertionFunction", "IrreduciblePolynomialQ", "ImageRecolor", "InsertLinebreaks", "IslandData", "ImageReflect", "InsertResults", "IsolatingInterval", "ImageResize", "Inset", "IsomorphicGraphQ", "ImageResolution", "Insphere", "IsotopeData", "ImageRestyle", "Install", "Italic", "ImageRotate", "InstallService", "Item", "ImageSaliencyFilter", "InString", "ItemAspectRatio", "ImageScaled", "Integer", "ItemDisplayFunction", "ImageScan", "IntegerDigits", "ItemSize", "ImageSize", "IntegerExponent", "ItemStyle", "ImageSizeAction", "IntegerLength", "ItoProcess", "JaccardDissimilarity", "JacobiSC", "JoinAcross", "JacobiAmplitude", "JacobiSD", "Joined", "JacobiCD", "JacobiSN", "JoinedCurve", "JacobiCN", "JacobiSymbol", "JoinForm", "JacobiCS", "JacobiZeta", "JordanDecomposition", "JacobiDC", "JankoGroupJ1", "JordanModelDecomposition", "JacobiDN", "JankoGroupJ2", "JulianDate", "JacobiDS", "JankoGroupJ3", "JuliaSetBoettcher", "JacobiNC", "JankoGroupJ4", "JuliaSetIterationCount", "JacobiND", "JarqueBeraALMTest", "JuliaSetPlot", "JacobiNS", "JohnsonDistribution", "JuliaSetPoints", "JacobiP", "Join", "KagiChart", "KernelObject", "Khinchin", "KaiserBesselWindow", "Kernels", "KillProcess", "KaiserWindow", "Key", "KirchhoffGraph", "KalmanEstimator", "KeyCollisionFunction", "KirchhoffMatrix", "KalmanFilter", "KeyComplement", "KleinInvariantJ", "KarhunenLoeveDecomposition", "KeyDrop", "KnapsackSolve", "KaryTree", "KeyDropFrom", "KnightTourGraph", "KatzCentrality", "KeyExistsQ", "KnotData", "KCoreComponents", "KeyFreeQ", "KnownUnitQ", "KDistribution", "KeyIntersection", "KochCurve", "KEdgeConnectedComponents", "KeyMap", "KolmogorovSmirnovTest", "KEdgeConnectedGraphQ", "KeyMemberQ", "KroneckerDelta", "KeepExistingVersion", "KeypointStrength", "KroneckerModelDecomposition", "KelvinBei", "Keys", "KroneckerProduct", "KelvinBer", "KeySelect", "KroneckerSymbol", "KelvinKei", "KeySort", "KuiperTest", "KelvinKer", "KeySortBy", "KumaraswamyDistribution", "KendallTau", "KeyTake", "Kurtosis", "KendallTauTest", "KeyUnion", "KuwaharaFilter", "KernelFunction", "KeyValueMap", "KVertexConnectedComponents", "KernelMixtureDistribution", "KeyValuePattern", "KVertexConnectedGraphQ", "LABColor", "LetterQ", "ListPickerBox", "Label", "Level", "ListPickerBoxOptions", "Labeled", "LeveneTest", "ListPlay", "LabelingFunction", "LeviCivitaTensor", "ListPlot", "LabelingSize", "LevyDistribution", "ListPlot3D", "LabelStyle", "LibraryDataType", "ListPointPlot3D", "LabelVisibility", "LibraryFunction", "ListPolarPlot", "LaguerreL", "LibraryFunctionError", "ListQ", "LakeData", "LibraryFunctionInformation", "ListSliceContourPlot3D", "LambdaComponents", "LibraryFunctionLoad", "ListSliceDensityPlot3D", "LaminaData", "LibraryFunctionUnload", "ListSliceVectorPlot3D", "LanczosWindow", "LibraryLoad", "ListStepPlot", "LandauDistribution", "LibraryUnload", "ListStreamDensityPlot", "Language", "LiftingFilterData", "ListStreamPlot", "LanguageCategory", "LiftingWaveletTransform", "ListSurfacePlot3D", "LanguageData", "LightBlue", "ListVectorDensityPlot", "LanguageIdentify", "LightBrown", "ListVectorPlot", "LaplaceDistribution", "LightCyan", "ListVectorPlot3D", "LaplaceTransform", "Lighter", "ListZTransform", "Laplacian", "LightGray", "LocalAdaptiveBinarize", "LaplacianFilter", "LightGreen", "LocalCache", "LaplacianGaussianFilter", "Lighting", "LocalClusteringCoefficient", "Large", "LightingAngle", "LocalizeVariables", "Larger", "LightMagenta", "LocalObject", "Last", "LightOrange", "LocalObjects", "Latitude", "LightPink", "LocalResponseNormalizationLayer", "LatitudeLongitude", "LightPurple", "LocalSubmit", "LatticeData", "LightRed", "LocalSymbol", "LatticeReduce", "LightYellow", "LocalTime", "LaunchKernels", "Likelihood", "LocalTimeZone", "LayeredGraphPlot", "Limit", "LocationEquivalenceTest", "LayerSizeFunction", "LimitsPositioning", "LocationTest", "LCHColor", "LindleyDistribution", "Locator", "LCM", "Line", "LocatorAutoCreate", "LeaderSize", "LinearFractionalOptimization", "LocatorPane", "LeafCount", "LinearFractionalTransform", "LocatorRegion", "LeapYearQ", "LinearGradientImage", "Locked", "LearnDistribution", "LinearizingTransformationData", "Log", "LearnedDistribution", "LinearLayer", "Log10", "LearningRate", "LinearModelFit", "Log2", "LearningRateMultipliers", "LinearOffsetFunction", "LogBarnesG", "LeastSquares", "LinearOptimization", "LogGamma", "LeastSquaresFilterKernel", "LinearProgramming", "LogGammaDistribution", "Left", "LinearRecurrence", "LogicalExpand", "LeftArrow", "LinearSolve", "LogIntegral", "LeftArrowBar", "LinearSolveFunction", "LogisticDistribution", "LeftArrowRightArrow", "LineBreakChart", "LogisticSigmoid", "LeftDownTeeVector", "LineGraph", "LogitModelFit", "LeftDownVector", "LineIndent", "LogLikelihood", "LeftDownVectorBar", "LineIndentMaxFraction", "LogLinearPlot", "LeftRightArrow", "LineIntegralConvolutionPlot", "LogLogisticDistribution", "LeftRightVector", "LineIntegralConvolutionScale", "LogLogPlot", "LeftTee", "LineLegend", "LogMultinormalDistribution", "LeftTeeArrow", "LineSpacing", "LogNormalDistribution", "LeftTeeVector", "LinkActivate", "LogPlot", "LeftTriangle", "LinkClose", "LogRankTest", "LeftTriangleBar", "LinkConnect", "LogSeriesDistribution", "LeftTriangleEqual", "LinkCreate", "Longest", "LeftUpDownVector", "LinkFunction", "LongestCommonSequence", "LeftUpTeeVector", "LinkInterrupt", "LongestCommonSequencePositions", "LeftUpVector", "LinkLaunch", "LongestCommonSubsequence", "LeftUpVectorBar", "LinkObject", "LongestCommonSubsequencePositions", "LeftVector", "LinkPatterns", "LongestOrderedSequence", "LeftVectorBar", "LinkProtocol", "Longitude", "LegendAppearance", "LinkRankCentrality", "LongLeftArrow", "Legended", "LinkRead", "LongLeftRightArrow", "LegendFunction", "LinkReadyQ", "LongRightArrow", "LegendLabel", "Links", "LongShortTermMemoryLayer", "LegendLayout", "LinkWrite", "Lookup", "LegendMargins", "LiouvilleLambda", "LoopFreeGraphQ", "LegendMarkers", "List", "Looping", "LegendMarkerSize", "Listable", "LossFunction", "LegendreP", "ListAnimate", "LowerCaseQ", "LegendreQ", "ListContourPlot", "LowerLeftArrow", "Length", "ListContourPlot3D", "LowerRightArrow", "LengthWhile", "ListConvolve", "LowerTriangularize", "LerchPhi", "ListCorrelate", "LowerTriangularMatrixQ", "Less", "ListCurvePathPlot", "LowpassFilter", "LessEqual", "ListDeconvolve", "LQEstimatorGains", "LessEqualGreater", "ListDensityPlot", "LQGRegulator", "LessEqualThan", "ListDensityPlot3D", "LQOutputRegulatorGains", "LessFullEqual", "ListFormat", "LQRegulatorGains", "LessGreater", "ListFourierSequenceTransform", "LucasL", "LessLess", "ListInterpolation", "LuccioSamiComponents", "LessSlantEqual", "ListLineIntegralConvolutionPlot", "LUDecomposition", "LessThan", "ListLinePlot", "LunarEclipse", "LessTilde", "ListLogLinearPlot", "LUVColor", "LetterCharacter", "ListLogLogPlot", "LyapunovSolve", "LetterCounts", "ListLogPlot", "LyonsGroupLy", "LetterNumber", "ListPicker", "MachineNumberQ", "MaxMemoryUsed", "MinimalPolynomial", "MachinePrecision", "MaxMixtureKernels", "MinimalStateSpaceModel", "Magenta", "MaxOverlapFraction", "Minimize", "Magnification", "MaxPlotPoints", "MinimumTimeIncrement", "Magnify", "MaxRecursion", "MinIntervalSize", "MailAddressValidation", "MaxStableDistribution", "MinkowskiQuestionMark", "MailExecute", "MaxStepFraction", "MinLimit", "MailFolder", "MaxSteps", "MinMax", "MailItem", "MaxStepSize", "MinorPlanetData", "MailReceiverFunction", "MaxTrainingRounds", "Minors", "MailResponseFunction", "MaxValue", "MinStableDistribution", "MailSearch", "MaxwellDistribution", "Minus", "MailServerConnect", "MaxWordGap", "MinusPlus", "MailServerConnection", "McLaughlinGroupMcL", "MinValue", "MailSettings", "Mean", "Missing", "Majority", "MeanAbsoluteLossLayer", "MissingBehavior", "MakeBoxes", "MeanAround", "MissingDataMethod", "MakeExpression", "MeanClusteringCoefficient", "MissingDataRules", "ManagedLibraryExpressionID", "MeanDegreeConnectivity", "MissingQ", "ManagedLibraryExpressionQ", "MeanDeviation", "MissingString", "MandelbrotSetBoettcher", "MeanFilter", "MissingStyle", "MandelbrotSetDistance", "MeanGraphDistance", "MissingValuePattern", "MandelbrotSetIterationCount", "MeanNeighborDegree", "MittagLefflerE", "MandelbrotSetMemberQ", "MeanShift", "MixedFractionParts", "MandelbrotSetPlot", "MeanShiftFilter", "MixedGraphQ", "MangoldtLambda", "MeanSquaredLossLayer", "MixedMagnitude", "ManhattanDistance", "Median", "MixedRadix", "Manipulate", "MedianDeviation", "MixedRadixQuantity", "Manipulator", "MedianFilter", "MixedUnit", "MannedSpaceMissionData", "MedicalTestData", "MixtureDistribution", "MannWhitneyTest", "Medium", "Mod", "MantissaExponent", "MeijerG", "Modal", "Manual", "MeijerGReduce", "ModularInverse", "Map", "MeixnerDistribution", "ModularLambda", "MapAll", "MellinConvolve", "Module", "MapAt", "MellinTransform", "Modulus", "MapIndexed", "MemberQ", "MoebiusMu", "MAProcess", "MemoryAvailable", "Molecule", "MapThread", "MemoryConstrained", "MoleculeContainsQ", "MarchenkoPasturDistribution", "MemoryConstraint", "MoleculeEquivalentQ", "MarcumQ", "MemoryInUse", "MoleculeGraph", "MardiaCombinedTest", "MengerMesh", "MoleculeModify", "MardiaKurtosisTest", "MenuCommandKey", "MoleculePattern", "MardiaSkewnessTest", "MenuPacket", "MoleculePlot", "MarginalDistribution", "MenuSortingValue", "MoleculePlot3D", "MarkovProcessProperties", "MenuStyle", "MoleculeProperty", "Masking", "MenuView", "MoleculeQ", "MatchingDissimilarity", "Merge", "MoleculeRecognize", "MatchLocalNames", "MergingFunction", "MoleculeValue", "MatchQ", "MersennePrimeExponent", "Moment", "MathematicalFunctionData", "MersennePrimeExponentQ", "MomentConvert", "MathieuC", "Mesh", "MomentEvaluate", "MathieuCharacteristicA", "MeshCellCentroid", "MomentGeneratingFunction", "MathieuCharacteristicB", "MeshCellCount", "MomentOfInertia", "MathieuCharacteristicExponent", "MeshCellHighlight", "Monday", "MathieuCPrime", "MeshCellIndex", "Monitor", "MathieuGroupM11", "MeshCellLabel", "MonomialList", "MathieuGroupM12", "MeshCellMarker", "MonsterGroupM", "MathieuGroupM22", "MeshCellMeasure", "MoonPhase", "MathieuGroupM23", "MeshCellQuality", "MoonPosition", "MathieuGroupM24", "MeshCells", "MorletWavelet", "MathieuS", "MeshCellShapeFunction", "MorphologicalBinarize", "MathieuSPrime", "MeshCellStyle", "MorphologicalBranchPoints", "MathMLForm", "MeshConnectivityGraph", "MorphologicalComponents", "Matrices", "MeshCoordinates", "MorphologicalEulerNumber", "MatrixExp", "MeshFunctions", "MorphologicalGraph", "MatrixForm", "MeshPrimitives", "MorphologicalPerimeter", "MatrixFunction", "MeshQualityGoal", "MorphologicalTransform", "MatrixLog", "MeshRefinementFunction", "MortalityData", "MatrixNormalDistribution", "MeshRegion", "Most", "MatrixPlot", "MeshRegionQ", "MountainData", "MatrixPower", "MeshShading", "MouseAnnotation", "MatrixPropertyDistribution", "MeshStyle", "MouseAppearance", "MatrixQ", "Message", "Mouseover", "MatrixRank", "MessageDialog", "MousePosition", "MatrixTDistribution", "MessageList", "MovieData", "Max", "MessageName", "MovingAverage", "MaxCellMeasure", "MessagePacket", "MovingMap", "MaxColorDistance", "Messages", "MovingMedian", "MaxDate", "MetaInformation", "MoyalDistribution", "MaxDetect", "MeteorShowerData", "Multicolumn", "MaxDuration", "Method", "MultiedgeStyle", "MaxExtraBandwidths", "MexicanHatWavelet", "MultigraphQ", "MaxExtraConditions", "MeyerWavelet", "Multinomial", "MaxFeatureDisplacement", "Midpoint", "MultinomialDistribution", "MaxFeatures", "Min", "MultinormalDistribution", "MaxFilter", "MinColorDistance", "MultiplicativeOrder", "MaximalBy", "MinDate", "MultiplySides", "Maximize", "MinDetect", "Multiselection", "MaxItems", "MineralData", "MultivariateHypergeometricDistribution", "MaxIterations", "MinFilter", "MultivariatePoissonDistribution", "MaxLimit", "MinimalBy", "MultivariateTDistribution", "N", "NHoldFirst", "NotificationFunction", "NakagamiDistribution", "NHoldRest", "NotLeftTriangle", "NameQ", "NicholsGridLines", "NotLeftTriangleBar", "Names", "NicholsPlot", "NotLeftTriangleEqual", "Nand", "NightHemisphere", "NotLess", "NArgMax", "NIntegrate", "NotLessEqual", "NArgMin", "NMaximize", "NotLessFullEqual", "NBodySimulation", "NMaxValue", "NotLessGreater", "NBodySimulationData", "NMinimize", "NotLessLess", "NCache", "NMinValue", "NotLessSlantEqual", "NDEigensystem", "NominalVariables", "NotLessTilde", "NDEigenvalues", "NoncentralBetaDistribution", "NotNestedGreaterGreater", "NDSolve", "NoncentralChiSquareDistribution", "NotNestedLessLess", "NDSolveValue", "NoncentralFRatioDistribution", "NotPrecedes", "Nearest", "NoncentralStudentTDistribution", "NotPrecedesEqual", "NearestFunction", "NonCommutativeMultiply", "NotPrecedesSlantEqual", "NearestMeshCells", "NonConstants", "NotPrecedesTilde", "NearestNeighborGraph", "NondimensionalizationTransform", "NotReverseElement", "NearestTo", "None", "NotRightTriangle", "NebulaData", "NoneTrue", "NotRightTriangleBar", "NeedlemanWunschSimilarity", "NonlinearModelFit", "NotRightTriangleEqual", "Needs", "NonlinearStateSpaceModel", "NotSquareSubset", "Negative", "NonlocalMeansFilter", "NotSquareSubsetEqual", "NegativeBinomialDistribution", "NonNegative", "NotSquareSuperset", "NegativeDefiniteMatrixQ", "NonNegativeIntegers", "NotSquareSupersetEqual", "NegativeIntegers", "NonNegativeRationals", "NotSubset", "NegativeMultinomialDistribution", "NonNegativeReals", "NotSubsetEqual", "NegativeRationals", "NonPositive", "NotSucceeds", "NegativeReals", "NonPositiveIntegers", "NotSucceedsEqual", "NegativeSemidefiniteMatrixQ", "NonPositiveRationals", "NotSucceedsSlantEqual", "NeighborhoodData", "NonPositiveReals", "NotSucceedsTilde", "NeighborhoodGraph", "Nor", "NotSuperset", "Nest", "NorlundB", "NotSupersetEqual", "NestedGreaterGreater", "Norm", "NotTilde", "NestedLessLess", "Normal", "NotTildeEqual", "NestGraph", "NormalDistribution", "NotTildeFullEqual", "NestList", "NormalizationLayer", "NotTildeTilde", "NestWhile", "Normalize", "NotVerticalBar", "NestWhileList", "Normalized", "Now", "NetAppend", "NormalizedSquaredEuclideanDistance", "NoWhitespace", "NetBidirectionalOperator", "NormalMatrixQ", "NProbability", "NetChain", "NormalsFunction", "NProduct", "NetDecoder", "NormFunction", "NRoots", "NetDelete", "Not", "NSolve", "NetDrop", "NotCongruent", "NSum", "NetEncoder", "NotCupCap", "NuclearExplosionData", "NetEvaluationMode", "NotDoubleVerticalBar", "NuclearReactorData", "NetExtract", "Notebook", "Null", "NetFlatten", "NotebookApply", "NullRecords", "NetFoldOperator", "NotebookAutoSave", "NullSpace", "NetGANOperator", "NotebookClose", "NullWords", "NetGraph", "NotebookDelete", "Number", "NetInitialize", "NotebookDirectory", "NumberCompose", "NetInsert", "NotebookDynamicExpression", "NumberDecompose", "NetInsertSharedArrays", "NotebookEvaluate", "NumberExpand", "NetJoin", "NotebookEventActions", "NumberFieldClassNumber", "NetMapOperator", "NotebookFileName", "NumberFieldDiscriminant", "NetMapThreadOperator", "NotebookFind", "NumberFieldFundamentalUnits", "NetMeasurements", "NotebookGet", "NumberFieldIntegralBasis", "NetModel", "NotebookImport", "NumberFieldNormRepresentatives", "NetNestOperator", "NotebookInformation", "NumberFieldRegulator", "NetPairEmbeddingOperator", "NotebookLocate", "NumberFieldRootsOfUnity", "NetPort", "NotebookObject", "NumberFieldSignature", "NetPortGradient", "NotebookOpen", "NumberForm", "NetPrepend", "NotebookPrint", "NumberFormat", "NetRename", "NotebookPut", "NumberLinePlot", "NetReplace", "NotebookRead", "NumberMarks", "NetReplacePart", "Notebooks", "NumberMultiplier", "NetSharedArray", "NotebookSave", "NumberPadding", "NetStateObject", "NotebookSelection", "NumberPoint", "NetTake", "NotebooksMenu", "NumberQ", "NetTrain", "NotebookTemplate", "NumberSeparator", "NetTrainResultsObject", "NotebookWrite", "NumberSigns", "NetworkPacketCapture", "NotElement", "NumberString", "NetworkPacketRecording", "NotEqualTilde", "Numerator", "NetworkPacketTrace", "NotExists", "NumeratorDenominator", "NeumannValue", "NotGreater", "NumericalOrder", "NevilleThetaC", "NotGreaterEqual", "NumericalSort", "NevilleThetaD", "NotGreaterFullEqual", "NumericArray", "NevilleThetaN", "NotGreaterGreater", "NumericArrayQ", "NevilleThetaS", "NotGreaterLess", "NumericArrayType", "NExpectation", "NotGreaterSlantEqual", "NumericFunction", "NextCell", "NotGreaterTilde", "NumericQ", "NextDate", "Nothing", "NuttallWindow", "NextPrime", "NotHumpDownHump", "NyquistGridLines", "NHoldAll", "NotHumpEqual", "NyquistPlot", "O", "OperatingSystem", "OuterPolyhedron", "ObservabilityGramian", "OperatorApplied", "OutputControllabilityMatrix", "ObservabilityMatrix", "OptimumFlowData", "OutputControllableModelQ", "ObservableDecomposition", "Optional", "OutputForm", "ObservableModelQ", "OptionalElement", "OutputNamePacket", "OceanData", "Options", "OutputResponse", "Octahedron", "OptionsPattern", "OutputSizeLimit", "OddQ", "OptionValue", "OutputStream", "Off", "Or", "OverBar", "Offset", "Orange", "OverDot", "On", "Order", "Overflow", "ONanGroupON", "OrderDistribution", "OverHat", "Once", "OrderedQ", "Overlaps", "OneIdentity", "Ordering", "Overlay", "Opacity", "OrderingBy", "Overscript", "OpacityFunction", "OrderingLayer", "OverscriptBox", "OpacityFunctionScaling", "Orderless", "OverscriptBoxOptions", "OpenAppend", "OrderlessPatternSequence", "OverTilde", "Opener", "OrnsteinUhlenbeckProcess", "OverVector", "OpenerView", "Orthogonalize", "OverwriteTarget", "Opening", "OrthogonalMatrixQ", "OwenT", "OpenRead", "Out", "OwnValues", "OpenWrite", "Outer", "Operate", "OuterPolygon", "PacletDataRebuild", "PeriodicBoundaryCondition", "PolynomialLCM", "PacletDirectoryLoad", "Periodogram", "PolynomialMod", "PacletDirectoryUnload", "PeriodogramArray", "PolynomialQ", "PacletDisable", "Permanent", "PolynomialQuotient", "PacletEnable", "Permissions", "PolynomialQuotientRemainder", "PacletFind", "PermissionsGroup", "PolynomialReduce", "PacletFindRemote", "PermissionsGroups", "PolynomialRemainder", "PacletInstall", "PermissionsKey", "PoolingLayer", "PacletInstallSubmit", "PermissionsKeys", "PopupMenu", "PacletNewerQ", "PermutationCycles", "PopupView", "PacletObject", "PermutationCyclesQ", "PopupWindow", "PacletSite", "PermutationGroup", "Position", "PacletSiteObject", "PermutationLength", "PositionIndex", "PacletSiteRegister", "PermutationList", "Positive", "PacletSites", "PermutationListQ", "PositiveDefiniteMatrixQ", "PacletSiteUnregister", "PermutationMax", "PositiveIntegers", "PacletSiteUpdate", "PermutationMin", "PositiveRationals", "PacletUninstall", "PermutationOrder", "PositiveReals", "PaddedForm", "PermutationPower", "PositiveSemidefiniteMatrixQ", "Padding", "PermutationProduct", "PossibleZeroQ", "PaddingLayer", "PermutationReplace", "Postfix", "PaddingSize", "Permutations", "Power", "PadeApproximant", "PermutationSupport", "PowerDistribution", "PadLeft", "Permute", "PowerExpand", "PadRight", "PeronaMalikFilter", "PowerMod", "PageBreakAbove", "PerpendicularBisector", "PowerModList", "PageBreakBelow", "PersistenceLocation", "PowerRange", "PageBreakWithin", "PersistenceTime", "PowerSpectralDensity", "PageFooters", "PersistentObject", "PowersRepresentations", "PageHeaders", "PersistentObjects", "PowerSymmetricPolynomial", "PageRankCentrality", "PersistentValue", "PrecedenceForm", "PageTheme", "PersonData", "Precedes", "PageWidth", "PERTDistribution", "PrecedesEqual", "Pagination", "PetersenGraph", "PrecedesSlantEqual", "PairedBarChart", "PhaseMargins", "PrecedesTilde", "PairedHistogram", "PhaseRange", "Precision", "PairedSmoothHistogram", "PhysicalSystemData", "PrecisionGoal", "PairedTTest", "Pi", "PreDecrement", "PairedZTest", "Pick", "Predict", "PaletteNotebook", "PIDData", "PredictorFunction", "PalindromeQ", "PIDDerivativeFilter", "PredictorMeasurements", "Pane", "PIDFeedforward", "PredictorMeasurementsObject", "Panel", "PIDTune", "PreemptProtect", "Paneled", "Piecewise", "Prefix", "PaneSelector", "PiecewiseExpand", "PreIncrement", "ParabolicCylinderD", "PieChart", "Prepend", "ParagraphIndent", "PieChart3D", "PrependLayer", "ParagraphSpacing", "PillaiTrace", "PrependTo", "ParallelArray", "PillaiTraceTest", "PreprocessingRules", "ParallelCombine", "PingTime", "PreserveColor", "ParallelDo", "Pink", "PreserveImageOptions", "Parallelepiped", "PitchRecognize", "PreviousCell", "ParallelEvaluate", "PixelValue", "PreviousDate", "Parallelization", "PixelValuePositions", "PriceGraphDistribution", "Parallelize", "Placed", "Prime", "ParallelMap", "Placeholder", "PrimeNu", "ParallelNeeds", "PlaceholderReplace", "PrimeOmega", "Parallelogram", "Plain", "PrimePi", "ParallelProduct", "PlanarAngle", "PrimePowerQ", "ParallelSubmit", "PlanarGraph", "PrimeQ", "ParallelSum", "PlanarGraphQ", "Primes", "ParallelTable", "PlanckRadiationLaw", "PrimeZetaP", "ParallelTry", "PlaneCurveData", "PrimitivePolynomialQ", "ParameterEstimator", "PlanetaryMoonData", "PrimitiveRoot", "ParameterMixtureDistribution", "PlanetData", "PrimitiveRootList", "ParametricFunction", "PlantData", "PrincipalComponents", "ParametricNDSolve", "Play", "PrincipalValue", "ParametricNDSolveValue", "PlayRange", "Print", "ParametricPlot", "Plot", "PrintableASCIIQ", "ParametricPlot3D", "Plot3D", "PrintingStyleEnvironment", "ParametricRampLayer", "PlotLabel", "Printout3D", "ParametricRegion", "PlotLabels", "Printout3DPreviewer", "ParentBox", "PlotLayout", "PrintTemporary", "ParentCell", "PlotLegends", "Prism", "ParentDirectory", "PlotMarkers", "PrivateCellOptions", "ParentNotebook", "PlotPoints", "PrivateFontOptions", "ParetoDistribution", "PlotRange", "PrivateKey", "ParetoPickandsDistribution", "PlotRangeClipping", "PrivateNotebookOptions", "ParkData", "PlotRangePadding", "Probability", "Part", "PlotRegion", "ProbabilityDistribution", "PartBehavior", "PlotStyle", "ProbabilityPlot", "PartialCorrelationFunction", "PlotTheme", "ProbabilityScalePlot", "ParticleAcceleratorData", "Pluralize", "ProbitModelFit", "ParticleData", "Plus", "ProcessConnection", "Partition", "PlusMinus", "ProcessDirectory", "PartitionGranularity", "Pochhammer", "ProcessEnvironment", "PartitionsP", "PodStates", "Processes", "PartitionsQ", "PodWidth", "ProcessEstimator", "PartLayer", "Point", "ProcessInformation", "PartOfSpeech", "PointFigureChart", "ProcessObject", "PartProtection", "PointLegend", "ProcessParameterAssumptions", "ParzenWindow", "PointSize", "ProcessParameterQ", "PascalDistribution", "PoissonConsulDistribution", "ProcessStatus", "PassEventsDown", "PoissonDistribution", "Product", "PassEventsUp", "PoissonProcess", "ProductDistribution", "Paste", "PoissonWindow", "ProductLog", "PasteButton", "PolarAxes", "ProgressIndicator", "Path", "PolarAxesOrigin", "Projection", "PathGraph", "PolarGridLines", "Prolog", "PathGraphQ", "PolarPlot", "ProofObject", "Pattern", "PolarTicks", "Proportion", "PatternFilling", "PoleZeroMarkers", "Proportional", "PatternSequence", "PolyaAeppliDistribution", "Protect", "PatternTest", "PolyGamma", "Protected", "PauliMatrix", "Polygon", "ProteinData", "PaulWavelet", "PolygonalNumber", "Pruning", "Pause", "PolygonAngle", "PseudoInverse", "PDF", "PolygonCoordinates", "PsychrometricPropertyData", "PeakDetect", "PolygonDecomposition", "PublicKey", "PeanoCurve", "Polyhedron", "PublisherID", "PearsonChiSquareTest", "PolyhedronAngle", "PulsarData", "PearsonCorrelationTest", "PolyhedronCoordinates", "PunctuationCharacter", "PearsonDistribution", "PolyhedronData", "Purple", "PercentForm", "PolyhedronDecomposition", "Put", "PerfectNumber", "PolyhedronGenus", "PutAppend", "PerfectNumberQ", "PolyLog", "Pyramid", "PerformanceGoal", "PolynomialExtendedGCD", "Perimeter", "PolynomialGCD", "QBinomial", "Quantity", "Quartics", "QFactorial", "QuantityArray", "QuartileDeviation", "QGamma", "QuantityDistribution", "Quartiles", "QHypergeometricPFQ", "QuantityForm", "QuartileSkewness", "QnDispersion", "QuantityMagnitude", "Query", "QPochhammer", "QuantityQ", "QueueingNetworkProcess", "QPolyGamma", "QuantityUnit", "QueueingProcess", "QRDecomposition", "QuantityVariable", "QueueProperties", "QuadraticIrrationalQ", "QuantityVariableCanonicalUnit", "Quiet", "QuadraticOptimization", "QuantityVariableDimensions", "Quit", "Quantile", "QuantityVariableIdentifier", "Quotient", "QuantilePlot", "QuantityVariablePhysicalQuantity", "QuotientRemainder", "RadialGradientImage", "RegionEqual", "Restricted", "RadialityCentrality", "RegionFillingStyle", "Resultant", "RadicalBox", "RegionFunction", "Return", "RadicalBoxOptions", "RegionImage", "ReturnExpressionPacket", "RadioButton", "RegionIntersection", "ReturnPacket", "RadioButtonBar", "RegionMeasure", "ReturnReceiptFunction", "Radon", "RegionMember", "ReturnTextPacket", "RadonTransform", "RegionMemberFunction", "Reverse", "RamanujanTau", "RegionMoment", "ReverseApplied", "RamanujanTauL", "RegionNearest", "ReverseBiorthogonalSplineWavelet", "RamanujanTauTheta", "RegionNearestFunction", "ReverseElement", "RamanujanTauZ", "RegionPlot", "ReverseEquilibrium", "Ramp", "RegionPlot3D", "ReverseGraph", "RandomChoice", "RegionProduct", "ReverseSort", "RandomColor", "RegionQ", "ReverseSortBy", "RandomComplex", "RegionResize", "ReverseUpEquilibrium", "RandomEntity", "RegionSize", "RevolutionAxis", "RandomFunction", "RegionSymmetricDifference", "RevolutionPlot3D", "RandomGeoPosition", "RegionUnion", "RGBColor", "RandomGraph", "RegionWithin", "RiccatiSolve", "RandomImage", "RegisterExternalEvaluator", "RiceDistribution", "RandomInstance", "RegularExpression", "RidgeFilter", "RandomInteger", "Regularization", "RiemannR", "RandomPermutation", "RegularlySampledQ", "RiemannSiegelTheta", "RandomPoint", "RegularPolygon", "RiemannSiegelZ", "RandomPolygon", "ReIm", "RiemannXi", "RandomPolyhedron", "ReImLabels", "Riffle", "RandomPrime", "ReImPlot", "Right", "RandomReal", "ReImStyle", "RightArrow", "RandomSample", "RelationalDatabase", "RightArrowBar", "RandomSeeding", "RelationGraph", "RightArrowLeftArrow", "RandomVariate", "ReleaseHold", "RightComposition", "RandomWalkProcess", "ReliabilityDistribution", "RightCosetRepresentative", "RandomWord", "ReliefImage", "RightDownTeeVector", "Range", "ReliefPlot", "RightDownVector", "RangeFilter", "RemoteAuthorizationCaching", "RightDownVectorBar", "RankedMax", "RemoteConnect", "RightTee", "RankedMin", "RemoteConnectionObject", "RightTeeArrow", "RarerProbability", "RemoteFile", "RightTeeVector", "Raster", "RemoteRun", "RightTriangle", "Raster3D", "RemoteRunProcess", "RightTriangleBar", "Rasterize", "Remove", "RightTriangleEqual", "RasterSize", "RemoveAlphaChannel", "RightUpDownVector", "Rational", "RemoveAudioStream", "RightUpTeeVector", "Rationalize", "RemoveBackground", "RightUpVector", "Rationals", "RemoveChannelListener", "RightUpVectorBar", "Ratios", "RemoveChannelSubscribers", "RightVector", "RawBoxes", "RemoveDiacritics", "RightVectorBar", "RawData", "RemoveInputStreamMethod", "RiskAchievementImportance", "RayleighDistribution", "RemoveOutputStreamMethod", "RiskReductionImportance", "Re", "RemoveUsers", "RogersTanimotoDissimilarity", "Read", "RemoveVideoStream", "RollPitchYawAngles", "ReadByteArray", "RenameDirectory", "RollPitchYawMatrix", "ReadLine", "RenameFile", "RomanNumeral", "ReadList", "RenderingOptions", "Root", "ReadProtected", "RenewalProcess", "RootApproximant", "ReadString", "RenkoChart", "RootIntervals", "Real", "RepairMesh", "RootLocusPlot", "RealAbs", "Repeated", "RootMeanSquare", "RealBlockDiagonalForm", "RepeatedNull", "RootOfUnityQ", "RealDigits", "RepeatedTiming", "RootReduce", "RealExponent", "RepeatingElement", "Roots", "Reals", "Replace", "RootSum", "RealSign", "ReplaceAll", "Rotate", "Reap", "ReplaceImageValue", "RotateLabel", "RecognitionPrior", "ReplaceList", "RotateLeft", "Record", "ReplacePart", "RotateRight", "RecordLists", "ReplacePixelValue", "RotationAction", "RecordSeparators", "ReplaceRepeated", "RotationMatrix", "Rectangle", "ReplicateLayer", "RotationTransform", "RectangleChart", "RequiredPhysicalQuantities", "Round", "RectangleChart3D", "Resampling", "RoundingRadius", "RectangularRepeatingElement", "ResamplingAlgorithmData", "Row", "RecurrenceFilter", "ResamplingMethod", "RowAlignments", "RecurrenceTable", "Rescale", "RowBox", "Red", "RescalingTransform", "RowLines", "Reduce", "ResetDirectory", "RowMinHeight", "ReferenceLineStyle", "ReshapeLayer", "RowReduce", "Refine", "Residue", "RowsEqual", "ReflectionMatrix", "ResizeLayer", "RowSpacings", "ReflectionTransform", "Resolve", "RSolve", "Refresh", "ResourceData", "RSolveValue", "RefreshRate", "ResourceFunction", "RudinShapiro", "Region", "ResourceObject", "RudvalisGroupRu", "RegionBinarize", "ResourceRegister", "Rule", "RegionBoundary", "ResourceRemove", "RuleDelayed", "RegionBoundaryStyle", "ResourceSearch", "RulePlot", "RegionBounds", "ResourceSubmit", "RulerUnits", "RegionCentroid", "ResourceSystemBase", "Run", "RegionDifference", "ResourceSystemPath", "RunProcess", "RegionDimension", "ResourceUpdate", "RunThrough", "RegionDisjoint", "ResourceVersion", "RuntimeAttributes", "RegionDistance", "ResponseForm", "RuntimeOptions", "RegionDistanceFunction", "Rest", "RussellRaoDissimilarity", "RegionEmbeddingDimension", "RestartInterval", "SameQ", "SingularValueDecomposition", "StreamDensityPlot", "SameTest", "SingularValueList", "StreamMarkers", "SameTestProperties", "SingularValuePlot", "StreamPlot", "SampledEntityClass", "Sinh", "StreamPoints", "SampleDepth", "SinhIntegral", "StreamPosition", "SampledSoundFunction", "SinIntegral", "Streams", "SampledSoundList", "SixJSymbol", "StreamScale", "SampleRate", "Skeleton", "StreamStyle", "SamplingPeriod", "SkeletonTransform", "String", "SARIMAProcess", "SkellamDistribution", "StringCases", "SARMAProcess", "Skewness", "StringContainsQ", "SASTriangle", "SkewNormalDistribution", "StringCount", "SatelliteData", "Skip", "StringDelete", "SatisfiabilityCount", "SliceContourPlot3D", "StringDrop", "SatisfiabilityInstances", "SliceDensityPlot3D", "StringEndsQ", "SatisfiableQ", "SliceDistribution", "StringExpression", "Saturday", "SliceVectorPlot3D", "StringExtract", "Save", "Slider", "StringForm", "SaveConnection", "Slider2D", "StringFormat", "SaveDefinitions", "SlideView", "StringFreeQ", "SavitzkyGolayMatrix", "Slot", "StringInsert", "SawtoothWave", "SlotSequence", "StringJoin", "Scale", "Small", "StringLength", "Scaled", "SmallCircle", "StringMatchQ", "ScaleDivisions", "Smaller", "StringPadLeft", "ScaleOrigin", "SmithDecomposition", "StringPadRight", "ScalePadding", "SmithDelayCompensator", "StringPart", "ScaleRanges", "SmithWatermanSimilarity", "StringPartition", "ScaleRangeStyle", "SmoothDensityHistogram", "StringPosition", "ScalingFunctions", "SmoothHistogram", "StringQ", "ScalingMatrix", "SmoothHistogram3D", "StringRepeat", "ScalingTransform", "SmoothKernelDistribution", "StringReplace", "Scan", "SnDispersion", "StringReplaceList", "ScheduledTask", "Snippet", "StringReplacePart", "SchurDecomposition", "SnubPolyhedron", "StringReverse", "ScientificForm", "SocialMediaData", "StringRiffle", "ScientificNotationThreshold", "SocketConnect", "StringRotateLeft", "ScorerGi", "SocketListen", "StringRotateRight", "ScorerGiPrime", "SocketListener", "StringSkeleton", "ScorerHi", "SocketObject", "StringSplit", "ScorerHiPrime", "SocketOpen", "StringStartsQ", "ScreenStyleEnvironment", "SocketReadMessage", "StringTake", "ScriptBaselineShifts", "SocketReadyQ", "StringTemplate", "ScriptMinSize", "Sockets", "StringToByteArray", "ScriptSizeMultipliers", "SocketWaitAll", "StringToStream", "Scrollbars", "SocketWaitNext", "StringTrim", "ScrollingOptions", "SoftmaxLayer", "StripBoxes", "ScrollPosition", "SokalSneathDissimilarity", "StripOnInput", "SearchAdjustment", "SolarEclipse", "StripWrapperBoxes", "SearchIndexObject", "SolarSystemFeatureData", "StructuralImportance", "SearchIndices", "SolidAngle", "StructuredSelection", "SearchQueryString", "SolidData", "StruveH", "SearchResultObject", "SolidRegionQ", "StruveL", "Sec", "Solve", "Stub", "Sech", "SolveAlways", "StudentTDistribution", "SechDistribution", "Sort", "Style", "SecondOrderConeOptimization", "SortBy", "StyleBox", "SectorChart", "SortedBy", "StyleData", "SectorChart3D", "SortedEntityClass", "StyleDefinitions", "SectorOrigin", "Sound", "Subdivide", "SectorSpacing", "SoundNote", "Subfactorial", "SecuredAuthenticationKey", "SoundVolume", "Subgraph", "SecuredAuthenticationKeys", "SourceLink", "SubMinus", "SeedRandom", "Sow", "SubPlus", "Select", "SpaceCurveData", "SubresultantPolynomialRemainders", "Selectable", "Spacer", "SubresultantPolynomials", "SelectComponents", "Spacings", "Subresultants", "SelectedCells", "Span", "Subscript", "SelectedNotebook", "SpanFromAbove", "SubscriptBox", "SelectFirst", "SpanFromBoth", "SubscriptBoxOptions", "SelectionCreateCell", "SpanFromLeft", "Subsequences", "SelectionEvaluate", "SparseArray", "Subset", "SelectionEvaluateCreateCell", "SpatialGraphDistribution", "SubsetCases", "SelectionMove", "SpatialMedian", "SubsetCount", "SelfLoopStyle", "SpatialTransformationLayer", "SubsetEqual", "SemanticImport", "Speak", "SubsetMap", "SemanticImportString", "SpeakerMatchQ", "SubsetPosition", "SemanticInterpretation", "SpearmanRankTest", "SubsetQ", "SemialgebraicComponentInstances", "SpearmanRho", "SubsetReplace", "SemidefiniteOptimization", "SpeciesData", "Subsets", "SendMail", "SpecificityGoal", "SubStar", "SendMessage", "SpectralLineData", "SubstitutionSystem", "Sequence", "Spectrogram", "Subsuperscript", "SequenceAlignment", "SpectrogramArray", "SubsuperscriptBox", "SequenceCases", "Specularity", "SubsuperscriptBoxOptions", "SequenceCount", "SpeechCases", "SubtitleEncoding", "SequenceFold", "SpeechInterpreter", "SubtitleTracks", "SequenceFoldList", "SpeechRecognize", "Subtract", "SequenceHold", "SpeechSynthesize", "SubtractFrom", "SequenceLastLayer", "SpellingCorrection", "SubtractSides", "SequenceMostLayer", "SpellingCorrectionList", "Succeeds", "SequencePosition", "SpellingOptions", "SucceedsEqual", "SequencePredict", "Sphere", "SucceedsSlantEqual", "SequencePredictorFunction", "SpherePoints", "SucceedsTilde", "SequenceReplace", "SphericalBesselJ", "Success", "SequenceRestLayer", "SphericalBesselY", "SuchThat", "SequenceReverseLayer", "SphericalHankelH1", "Sum", "SequenceSplit", "SphericalHankelH2", "SumConvergence", "Series", "SphericalHarmonicY", "SummationLayer", "SeriesCoefficient", "SphericalPlot3D", "Sunday", "SeriesData", "SphericalRegion", "SunPosition", "SeriesTermGoal", "SphericalShell", "Sunrise", "ServiceConnect", "SpheroidalEigenvalue", "Sunset", "ServiceDisconnect", "SpheroidalJoiningFactor", "SuperDagger", "ServiceExecute", "SpheroidalPS", "SuperMinus", "ServiceObject", "SpheroidalPSPrime", "SupernovaData", "ServiceRequest", "SpheroidalQS", "SuperPlus", "ServiceSubmit", "SpheroidalQSPrime", "Superscript", "SessionSubmit", "SpheroidalRadialFactor", "SuperscriptBox", "SessionTime", "SpheroidalS1", "SuperscriptBoxOptions", "Set", "SpheroidalS1Prime", "Superset", "SetAccuracy", "SpheroidalS2", "SupersetEqual", "SetAlphaChannel", "SpheroidalS2Prime", "SuperStar", "SetAttributes", "Splice", "Surd", "SetCloudDirectory", "SplicedDistribution", "SurdForm", "SetCookies", "SplineClosed", "SurfaceArea", "SetDelayed", "SplineDegree", "SurfaceData", "SetDirectory", "SplineKnots", "SurvivalDistribution", "SetEnvironment", "SplineWeights", "SurvivalFunction", "SetFileDate", "Split", "SurvivalModel", "SetOptions", "SplitBy", "SurvivalModelFit", "SetPermissions", "SpokenString", "SuzukiDistribution", "SetPrecision", "Sqrt", "SuzukiGroupSuz", "SetSelectedNotebook", "SqrtBox", "SwatchLegend", "SetSharedFunction", "SqrtBoxOptions", "Switch", "SetSharedVariable", "Square", "Symbol", "SetStreamPosition", "SquaredEuclideanDistance", "SymbolName", "SetSystemModel", "SquareFreeQ", "SymletWavelet", "SetSystemOptions", "SquareIntersection", "Symmetric", "Setter", "SquareMatrixQ", "SymmetricGroup", "SetterBar", "SquareRepeatingElement", "SymmetricKey", "Setting", "SquaresR", "SymmetricMatrixQ", "SetUsers", "SquareSubset", "SymmetricPolynomial", "Shallow", "SquareSubsetEqual", "SymmetricReduction", "ShannonWavelet", "SquareSuperset", "Symmetrize", "ShapiroWilkTest", "SquareSupersetEqual", "SymmetrizedArray", "Share", "SquareUnion", "SymmetrizedArrayRules", "SharingList", "SquareWave", "SymmetrizedDependentComponents", "Sharpen", "SSSTriangle", "SymmetrizedIndependentComponents", "ShearingMatrix", "StabilityMargins", "SymmetrizedReplacePart", "ShearingTransform", "StabilityMarginsStyle", "SynchronousInitialization", "ShellRegion", "StableDistribution", "SynchronousUpdating", "ShenCastanMatrix", "Stack", "Synonyms", "ShiftedGompertzDistribution", "StackBegin", "SyntaxForm", "ShiftRegisterSequence", "StackComplete", "SyntaxInformation", "Short", "StackedDateListPlot", "SyntaxLength", "ShortDownArrow", "StackedListPlot", "SyntaxPacket", "Shortest", "StackInhibit", "SyntaxQ", "ShortestPathFunction", "StadiumShape", "SynthesizeMissingValues", "ShortLeftArrow", "StandardAtmosphereData", "SystemCredential", "ShortRightArrow", "StandardDeviation", "SystemCredentialData", "ShortTimeFourier", "StandardDeviationFilter", "SystemCredentialKey", "ShortTimeFourierData", "StandardForm", "SystemCredentialKeys", "ShortUpArrow", "Standardize", "SystemCredentialStoreObject", "Show", "Standardized", "SystemDialogInput", "ShowAutoSpellCheck", "StandardOceanData", "SystemInformation", "ShowAutoStyles", "StandbyDistribution", "SystemInstall", "ShowCellBracket", "Star", "SystemModel", "ShowCellLabel", "StarClusterData", "SystemModeler", "ShowCellTags", "StarData", "SystemModelExamples", "ShowCursorTracker", "StarGraph", "SystemModelLinearize", "ShowGroupOpener", "StartExternalSession", "SystemModelParametricSimulate", "ShowPageBreaks", "StartingStepSize", "SystemModelPlot", "ShowSelection", "StartOfLine", "SystemModelProgressReporting", "ShowSpecialCharacters", "StartOfString", "SystemModelReliability", "ShowStringCharacters", "StartProcess", "SystemModels", "ShrinkingDelay", "StartWebSession", "SystemModelSimulate", "SiderealTime", "StateFeedbackGains", "SystemModelSimulateSensitivity", "SiegelTheta", "StateOutputEstimator", "SystemModelSimulationData", "SiegelTukeyTest", "StateResponse", "SystemOpen", "SierpinskiCurve", "StateSpaceModel", "SystemOptions", "SierpinskiMesh", "StateSpaceRealization", "SystemProcessData", "Sign", "StateSpaceTransform", "SystemProcesses", "Signature", "StateTransformationLinearize", "SystemsConnectionsModel", "SignedRankTest", "StationaryDistribution", "SystemsModelDelay", "SignedRegionDistance", "StationaryWaveletPacketTransform", "SystemsModelDelayApproximate", "SignificanceLevel", "StationaryWaveletTransform", "SystemsModelDelete", "SignPadding", "StatusArea", "SystemsModelDimensions", "SignTest", "StatusCentrality", "SystemsModelExtract", "SimilarityRules", "StepMonitor", "SystemsModelFeedbackConnect", "SimpleGraph", "StereochemistryElements", "SystemsModelLabels", "SimpleGraphQ", "StieltjesGamma", "SystemsModelLinearity", "SimplePolygonQ", "StippleShading", "SystemsModelMerge", "SimplePolyhedronQ", "StirlingS1", "SystemsModelOrder", "Simplex", "StirlingS2", "SystemsModelParallelConnect", "Simplify", "StoppingPowerData", "SystemsModelSeriesConnect", "Sin", "StrataVariables", "SystemsModelStateFeedbackConnect", "Sinc", "StratonovichProcess", "SystemsModelVectorRelativeOrders", "SinghMaddalaDistribution", "StreamColorFunction", "SingleLetterItalics", "StreamColorFunctionScaling", "Table", "Thickness", "TraceDepth", "TableAlignments", "Thin", "TraceDialog", "TableDepth", "Thinning", "TraceForward", "TableDirections", "ThompsonGroupTh", "TraceOff", "TableForm", "Thread", "TraceOn", "TableHeadings", "ThreadingLayer", "TraceOriginal", "TableSpacing", "ThreeJSymbol", "TracePrint", "TableView", "Threshold", "TraceScan", "TabView", "Through", "TrackedSymbols", "TagBox", "Throw", "TrackingFunction", "TagBoxOptions", "ThueMorse", "TracyWidomDistribution", "TaggingRules", "Thumbnail", "TradingChart", "TagSet", "Thursday", "TraditionalForm", "TagSetDelayed", "Ticks", "TrainingProgressCheckpointing", "TagUnset", "TicksStyle", "TrainingProgressFunction", "Take", "TideData", "TrainingProgressMeasurements", "TakeDrop", "Tilde", "TrainingProgressReporting", "TakeLargest", "TildeEqual", "TrainingStoppingCriterion", "TakeLargestBy", "TildeFullEqual", "TrainingUpdateSchedule", "TakeList", "TildeTilde", "TransferFunctionCancel", "TakeSmallest", "TimeConstrained", "TransferFunctionExpand", "TakeSmallestBy", "TimeConstraint", "TransferFunctionFactor", "TakeWhile", "TimeDirection", "TransferFunctionModel", "Tally", "TimeFormat", "TransferFunctionPoles", "Tan", "TimeGoal", "TransferFunctionTransform", "Tanh", "TimelinePlot", "TransferFunctionZeros", "TargetDevice", "TimeObject", "TransformationClass", "TargetFunctions", "TimeObjectQ", "TransformationFunction", "TargetSystem", "TimeRemaining", "TransformationFunctions", "TargetUnits", "Times", "TransformationMatrix", "TaskAbort", "TimesBy", "TransformedDistribution", "TaskExecute", "TimeSeries", "TransformedField", "TaskObject", "TimeSeriesAggregate", "TransformedProcess", "TaskRemove", "TimeSeriesForecast", "TransformedRegion", "TaskResume", "TimeSeriesInsert", "TransitionDirection", "Tasks", "TimeSeriesInvertibility", "TransitionDuration", "TaskSuspend", "TimeSeriesMap", "TransitionEffect", "TaskWait", "TimeSeriesMapThread", "TransitiveClosureGraph", "TautologyQ", "TimeSeriesModel", "TransitiveReductionGraph", "TelegraphProcess", "TimeSeriesModelFit", "Translate", "TemplateApply", "TimeSeriesResample", "TranslationOptions", "TemplateBox", "TimeSeriesRescale", "TranslationTransform", "TemplateBoxOptions", "TimeSeriesShift", "Transliterate", "TemplateExpression", "TimeSeriesThread", "Transparent", "TemplateIf", "TimeSeriesWindow", "Transpose", "TemplateObject", "TimeUsed", "TransposeLayer", "TemplateSequence", "TimeValue", "TravelDirections", "TemplateSlot", "TimeZone", "TravelDirectionsData", "TemplateWith", "TimeZoneConvert", "TravelDistance", "TemporalData", "TimeZoneOffset", "TravelDistanceList", "TemporalRegularity", "Timing", "TravelMethod", "Temporary", "Tiny", "TravelTime", "TensorContract", "TitsGroupT", "TreeForm", "TensorDimensions", "ToBoxes", "TreeGraph", "TensorExpand", "ToCharacterCode", "TreeGraphQ", "TensorProduct", "ToContinuousTimeModel", "TreePlot", "TensorRank", "Today", "TrendStyle", "TensorReduce", "ToDiscreteTimeModel", "Triangle", "TensorSymmetry", "ToEntity", "TriangleCenter", "TensorTranspose", "ToeplitzMatrix", "TriangleConstruct", "TensorWedge", "ToExpression", "TriangleMeasurement", "TestID", "Together", "TriangleWave", "TestReport", "Toggler", "TriangularDistribution", "TestReportObject", "TogglerBar", "TriangulateMesh", "TestResultObject", "ToInvertibleTimeSeries", "Trig", "Tetrahedron", "TokenWords", "TrigExpand", "TeXForm", "Tolerance", "TrigFactor", "Text", "ToLowerCase", "TrigFactorList", "TextAlignment", "Tomorrow", "Trigger", "TextCases", "ToNumberField", "TrigReduce", "TextCell", "Tooltip", "TrigToExp", "TextClipboardType", "TooltipDelay", "TrimmedMean", "TextContents", "TooltipStyle", "TrimmedVariance", "TextData", "ToonShading", "TropicalStormData", "TextElement", "Top", "True", "TextGrid", "TopHatTransform", "TrueQ", "TextJustification", "ToPolarCoordinates", "TruncatedDistribution", "TextPacket", "TopologicalSort", "TruncatedPolyhedron", "TextPosition", "ToRadicals", "TsallisQExponentialDistribution", "TextRecognize", "ToRules", "TsallisQGaussianDistribution", "TextSearch", "ToSphericalCoordinates", "TTest", "TextSearchReport", "ToString", "Tube", "TextSentences", "Total", "Tuesday", "TextString", "TotalLayer", "TukeyLambdaDistribution", "TextStructure", "TotalVariationFilter", "TukeyWindow", "TextTranslation", "TotalWidth", "TunnelData", "Texture", "TouchPosition", "Tuples", "TextureCoordinateFunction", "TouchscreenAutoZoom", "TuranGraph", "TextureCoordinateScaling", "TouchscreenControlPlacement", "TuringMachine", "TextWords", "ToUpperCase", "TuttePolynomial", "Therefore", "Tr", "TwoWayRule", "ThermodynamicData", "Trace", "Typed", "ThermometerGauge", "TraceAbove", "TypeSpecifier", "Thick", "TraceBackward", "UnateQ", "UnitaryMatrixQ", "UpperCaseQ", "Uncompress", "UnitBox", "UpperLeftArrow", "UnconstrainedParameters", "UnitConvert", "UpperRightArrow", "Undefined", "UnitDimensions", "UpperTriangularize", "UnderBar", "Unitize", "UpperTriangularMatrixQ", "Underflow", "UnitRootTest", "Upsample", "Underlined", "UnitSimplify", "UpSet", "Underoverscript", "UnitStep", "UpSetDelayed", "UnderoverscriptBox", "UnitSystem", "UpTee", "UnderoverscriptBoxOptions", "UnitTriangle", "UpTeeArrow", "Underscript", "UnitVector", "UpTo", "UnderscriptBox", "UnitVectorLayer", "UpValues", "UnderscriptBoxOptions", "UnityDimensions", "URL", "UnderseaFeatureData", "UniverseModelData", "URLBuild", "UndirectedEdge", "UniversityData", "URLDecode", "UndirectedGraph", "UnixTime", "URLDispatcher", "UndirectedGraphQ", "Unprotect", "URLDownload", "UndoOptions", "UnregisterExternalEvaluator", "URLDownloadSubmit", "UndoTrackedVariables", "UnsameQ", "URLEncode", "Unequal", "UnsavedVariables", "URLExecute", "UnequalTo", "Unset", "URLExpand", "Unevaluated", "UnsetShared", "URLParse", "UniformDistribution", "UpArrow", "URLQueryDecode", "UniformGraphDistribution", "UpArrowBar", "URLQueryEncode", "UniformPolyhedron", "UpArrowDownArrow", "URLRead", "UniformSumDistribution", "Update", "URLResponseTime", "Uninstall", "UpdateInterval", "URLShorten", "Union", "UpdatePacletSites", "URLSubmit", "UnionedEntityClass", "UpdateSearchIndex", "UsingFrontEnd", "UnionPlus", "UpDownArrow", "UtilityFunction", "Unique", "UpEquilibrium", "ValenceErrorHandling", "VerifyDigitalSignature", "VertexStyle", "ValidationLength", "VerifyFileSignature", "VertexTextureCoordinates", "ValidationSet", "VerifyInterpretation", "VertexWeight", "ValueDimensions", "VerifySecurityCertificates", "VertexWeightedGraphQ", "ValuePreprocessingFunction", "VerifySolutions", "VerticalBar", "ValueQ", "VerifyTestAssumptions", "VerticalGauge", "Values", "VersionedPreferences", "VerticalSeparator", "Variables", "VertexAdd", "VerticalSlider", "Variance", "VertexCapacity", "VerticalTilde", "VarianceEquivalenceTest", "VertexColors", "Video", "VarianceEstimatorFunction", "VertexComponent", "VideoEncoding", "VarianceGammaDistribution", "VertexConnectivity", "VideoExtractFrames", "VarianceTest", "VertexContract", "VideoFrameList", "VectorAngle", "VertexCoordinates", "VideoFrameMap", "VectorAround", "VertexCorrelationSimilarity", "VideoPause", "VectorAspectRatio", "VertexCosineSimilarity", "VideoPlay", "VectorColorFunction", "VertexCount", "VideoQ", "VectorColorFunctionScaling", "VertexCoverQ", "VideoStop", "VectorDensityPlot", "VertexDataCoordinates", "VideoStream", "VectorGreater", "VertexDegree", "VideoStreams", "VectorGreaterEqual", "VertexDelete", "VideoTimeSeries", "VectorLess", "VertexDiceSimilarity", "VideoTracks", "VectorLessEqual", "VertexEccentricity", "VideoTrim", "VectorMarkers", "VertexInComponent", "ViewAngle", "VectorPlot", "VertexInDegree", "ViewCenter", "VectorPlot3D", "VertexIndex", "ViewMatrix", "VectorPoints", "VertexJaccardSimilarity", "ViewPoint", "VectorQ", "VertexLabels", "ViewProjection", "VectorRange", "VertexLabelStyle", "ViewRange", "Vectors", "VertexList", "ViewVector", "VectorScaling", "VertexNormals", "ViewVertical", "VectorSizes", "VertexOutComponent", "Visible", "VectorStyle", "VertexOutDegree", "VoiceStyleData", "Vee", "VertexQ", "VoigtDistribution", "Verbatim", "VertexReplace", "VolcanoData", "VerificationTest", "VertexShape", "Volume", "VerifyConvergence", "VertexShapeFunction", "VonMisesDistribution", "VerifyDerivedKey", "VertexSize", "VoronoiMesh", "WaitAll", "WeierstrassEta2", "WindowElements", "WaitNext", "WeierstrassEta3", "WindowFloating", "WakebyDistribution", "WeierstrassHalfPeriods", "WindowFrame", "WalleniusHypergeometricDistribution", "WeierstrassHalfPeriodW1", "WindowFrameElements", "WaringYuleDistribution", "WeierstrassHalfPeriodW2", "WindowMargins", "WarpingCorrespondence", "WeierstrassHalfPeriodW3", "WindowOpacity", "WarpingDistance", "WeierstrassInvariantG2", "WindowSize", "WatershedComponents", "WeierstrassInvariantG3", "WindowStatusArea", "WatsonUSquareTest", "WeierstrassInvariants", "WindowTitle", "WattsStrogatzGraphDistribution", "WeierstrassP", "WindowToolbars", "WaveletBestBasis", "WeierstrassPPrime", "WindSpeedData", "WaveletFilterCoefficients", "WeierstrassSigma", "WindVectorData", "WaveletImagePlot", "WeierstrassZeta", "WinsorizedMean", "WaveletListPlot", "WeightedAdjacencyGraph", "WinsorizedVariance", "WaveletMapIndexed", "WeightedAdjacencyMatrix", "WishartMatrixDistribution", "WaveletMatrixPlot", "WeightedData", "With", "WaveletPhi", "WeightedGraphQ", "WolframAlpha", "WaveletPsi", "Weights", "WolframLanguageData", "WaveletScale", "WelchWindow", "Word", "WaveletScalogram", "WheelGraph", "WordBoundary", "WaveletThreshold", "WhenEvent", "WordCharacter", "WeaklyConnectedComponents", "Which", "WordCloud", "WeaklyConnectedGraphComponents", "While", "WordCount", "WeaklyConnectedGraphQ", "White", "WordCounts", "WeakStationarity", "WhiteNoiseProcess", "WordData", "WeatherData", "WhitePoint", "WordDefinition", "WeatherForecastData", "Whitespace", "WordFrequency", "WebAudioSearch", "WhitespaceCharacter", "WordFrequencyData", "WebElementObject", "WhittakerM", "WordList", "WeberE", "WhittakerW", "WordOrientation", "WebExecute", "WienerFilter", "WordSearch", "WebImage", "WienerProcess", "WordSelectionFunction", "WebImageSearch", "WignerD", "WordSeparators", "WebSearch", "WignerSemicircleDistribution", "WordSpacings", "WebSessionObject", "WikidataData", "WordStem", "WebSessions", "WikidataSearch", "WordTranslation", "WebWindowObject", "WikipediaData", "WorkingPrecision", "Wedge", "WikipediaSearch", "WrapAround", "Wednesday", "WilksW", "Write", "WeibullDistribution", "WilksWTest", "WriteLine", "WeierstrassE1", "WindDirectionData", "WriteString", "WeierstrassE2", "WindingCount", "Wronskian", "WeierstrassE3", "WindingPolygon", "WeierstrassEta1", "WindowClickSelect", "XMLElement", "XMLTemplate", "Xor", "XMLObject", "Xnor", "XYZColor", "Yellow", "Yesterday", "YuleDissimilarity", "ZernikeR", "ZetaZero", "ZoomFactor", "ZeroSymmetric", "ZIPCodeData", "ZTest", "ZeroTest", "ZipfDistribution", "ZTransform", "Zeta", "ZoomCenter"] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab.rb new file mode 100644 index 0000000..d284401 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab.rb @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Matlab < RegexLexer + title "MATLAB" + desc "Matlab" + tag 'matlab' + aliases 'm' + filenames '*.m' + mimetypes 'text/x-matlab', 'application/x-matlab' + + def self.keywords + @keywords = Set.new %w( + arguments break case catch classdef continue else elseif end for + function global if import methods otherwise parfor persistent + properties return spmd switch try while + ) + end + + # self-modifying method that loads the builtins file + def self.builtins + Kernel::load File.join(Lexers::BASE_DIR, 'matlab/keywords.rb') + builtins + end + + state :root do + rule %r/\s+/m, Text # Whitespace + rule %r([{]%.*?%[}])m, Comment::Multiline + rule %r/%.*$/, Comment::Single + rule %r/([.][.][.])(.*?)$/ do + groups(Keyword, Comment) + end + + rule %r/^(!)(.*?)(?=%|$)/ do |m| + token Keyword, m[1] + delegate Shell, m[2] + end + + + rule %r/[a-zA-Z][_a-zA-Z0-9]*/m do |m| + match = m[0] + if self.class.keywords.include? match + token Keyword + elsif self.class.builtins.include? match + token Name::Builtin + else + token Name + end + end + + rule %r{[(){};:,\/\\\]\[]}, Punctuation + + rule %r/~=|==|<<|>>|[-~+\/*%=<>&^|.@]/, Operator + + + rule %r/(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?/i, Num::Float + rule %r/\d+e[+-]?[0-9]+/i, Num::Float + rule %r/\d+L/, Num::Integer::Long + rule %r/\d+/, Num::Integer + + rule %r/'(?=(.*'))/, Str::Single, :chararray + rule %r/"(?=(.*"))/, Str::Double, :string + rule %r/'/, Operator + end + + state :chararray do + rule %r/[^']+/, Str::Single + rule %r/''/, Str::Escape + rule %r/'/, Str::Single, :pop! + end + + state :string do + rule %r/[^"]+/, Str::Double + rule %r/""/, Str::Escape + rule %r/"/, Str::Double, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/builtins.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/builtins.rb new file mode 100644 index 0000000..63d9bb5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/builtins.rb @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# automatically generated by `rake builtins:matlab` +module Rouge + module Lexers + def Matlab.builtins + @builtins ||= Set.new ["abs", "accumarray", "acos", "acosd", "acosh", "acot", "acotd", "acoth", "acsc", "acscd", "acsch", "actxcontrol", "actxcontrollist", "actxcontrolselect", "actxGetRunningServer", "actxserver", "add", "addboundary", "addcats", "addCause", "addClass", "addCondition", "addConditionsFrom", "addConstructor", "addCorrection", "addedge", "addevent", "addFields", "addFields", "addFile", "addFolderIncludingChildFiles", "addFunction", "addLabel", "addlistener", "addMethod", "addmulti", "addnode", "addOptional", "addParameter", "addParamValue", "addPath", "addpath", "addPlugin", "addpoints", "addpref", "addprop", "addprop", "addproperty", "addProperty", "addReference", "addRequired", "addsample", "addsampletocollection", "addShortcut", "addShutdownFile", "addStartupFile", "addTeardown", "addTeardown", "addtodate", "addToolbarExplorationButtons", "addts", "addvars", "adjacency", "airy", "align", "alim", "all", "allchild", "allowModelReferenceDiscreteSampleTimeInheritanceImpl", "alpha", "alphamap", "alphaShape", "alphaSpectrum", "alphaTriangulation", "amd", "analyzeCodeCompatibility", "ancestor", "and", "angle", "animatedline", "annotation", "ans", "any", "appdesigner", "append", "append", "applyFixture", "applyFixture", "area", "area", "area", "array2table", "array2timetable", "arrayfun", "ascii", "asec", "asecd", "asech", "asin", "asind", "asinh", "assert", "assertAccessed", "assertCalled", "assertClass", "assertEmpty", "assertEqual", "assertError", "assertFail", "assertFalse", "assertGreaterThan", "assertGreaterThanOrEqual", "assertInstanceOf", "assertLength", "assertLessThan", "assertLessThanOrEqual", "assertMatches", "assertNotAccessed", "assertNotCalled", "assertNotEmpty", "assertNotEqual", "assertNotSameHandle", "assertNotSet", "assertNumElements", "assertReturnsTrue", "assertSameHandle", "assertSet", "assertSize", "assertSubstring", "assertThat", "assertTrue", "assertUsing", "assertWarning", "assertWarningFree", "assignin", "assignOutputsWhen", "assumeAccessed", "assumeCalled", "assumeClass", "assumeEmpty", "assumeEqual", "assumeError", "assumeFail", "assumeFalse", "assumeGreaterThan", "assumeGreaterThanOrEqual", "assumeInstanceOf", "assumeLength", "assumeLessThan", "assumeLessThanOrEqual", "assumeMatches", "assumeNotAccessed", "assumeNotCalled", "assumeNotEmpty", "assumeNotEqual", "assumeNotSameHandle", "assumeNotSet", "assumeNumElements", "assumeReturnsTrue", "assumeSameHandle", "assumeSet", "assumeSize", "assumeSubstring", "assumeThat", "assumeTrue", "assumeUsing", "assumeWarning", "assumeWarningFree", "atan", "atan2", "atan2d", "atand", "atanh", "audiodevinfo", "audioinfo", "audioplayer", "audioread", "audiorecorder", "audiowrite", "autumn", "aviinfo", "axes", "axis", "axtoolbar", "axtoolbarbtn", "balance", "bandwidth", "bar", "bar3", "bar3h", "barh", "barycentricToCartesian", "baryToCart", "base2dec", "batchStartupOptionUsed", "bctree", "beep", "BeginInvoke", "bench", "besselh", "besseli", "besselj", "besselk", "bessely", "beta", "betainc", "betaincinv", "betaln", "between", "bfsearch", "bicg", "bicgstab", "bicgstabl", "biconncomp", "bin2dec", "binary", "binscatter", "bitand", "bitcmp", "bitget", "bitnot", "bitor", "bitset", "bitshift", "bitxor", "blanks", "blkdiag", "bone", "boundary", "boundary", "boundaryFacets", "boundaryshape", "boundingbox", "bounds", "box", "break", "brighten", "brush", "bsxfun", "build", "builddocsearchdb", "builtin", "bvp4c", "bvp5c", "bvpget", "bvpinit", "bvpset", "bvpxtend", "caldays", "caldiff", "calendar", "calendarDuration", "calllib", "callSoapService", "calmonths", "calquarters", "calweeks", "calyears", "camdolly", "cameratoolbar", "camlight", "camlookat", "camorbit", "campan", "campos", "camproj", "camroll", "camtarget", "camup", "camva", "camzoom", "cancel", "cancelled", "cart2pol", "cart2sph", "cartesianToBarycentric", "cartToBary", "cast", "cat", "cat", "categorical", "categories", "caxis", "cd", "cd", "cdf2rdf", "cdfepoch", "cdfinfo", "cdflib", "cdflib.close", "cdflib.closeVar", "cdflib.computeEpoch", "cdflib.computeEpoch16", "cdflib.create", "cdflib.createAttr", "cdflib.createVar", "cdflib.delete", "cdflib.deleteAttr", "cdflib.deleteAttrEntry", "cdflib.deleteAttrgEntry", "cdflib.deleteVar", "cdflib.deleteVarRecords", "cdflib.epoch16Breakdown", "cdflib.epochBreakdown", "cdflib.getAttrEntry", "cdflib.getAttrgEntry", "cdflib.getAttrMaxEntry", "cdflib.getAttrMaxgEntry", "cdflib.getAttrName", "cdflib.getAttrNum", "cdflib.getAttrScope", "cdflib.getCacheSize", "cdflib.getChecksum", "cdflib.getCompression", "cdflib.getCompressionCacheSize", "cdflib.getConstantNames", "cdflib.getConstantValue", "cdflib.getCopyright", "cdflib.getFileBackward", "cdflib.getFormat", "cdflib.getLibraryCopyright", "cdflib.getLibraryVersion", "cdflib.getMajority", "cdflib.getName", "cdflib.getNumAttrEntries", "cdflib.getNumAttrgEntries", "cdflib.getNumAttributes", "cdflib.getNumgAttributes", "cdflib.getReadOnlyMode", "cdflib.getStageCacheSize", "cdflib.getValidate", "cdflib.getVarAllocRecords", "cdflib.getVarBlockingFactor", "cdflib.getVarCacheSize", "cdflib.getVarCompression", "cdflib.getVarData", "cdflib.getVarMaxAllocRecNum", "cdflib.getVarMaxWrittenRecNum", "cdflib.getVarName", "cdflib.getVarNum", "cdflib.getVarNumRecsWritten", "cdflib.getVarPadValue", "cdflib.getVarRecordData", "cdflib.getVarReservePercent", "cdflib.getVarsMaxWrittenRecNum", "cdflib.getVarSparseRecords", "cdflib.getVersion", "cdflib.hyperGetVarData", "cdflib.hyperPutVarData", "cdflib.inquire", "cdflib.inquireAttr", "cdflib.inquireAttrEntry", "cdflib.inquireAttrgEntry", "cdflib.inquireVar", "cdflib.open", "cdflib.putAttrEntry", "cdflib.putAttrgEntry", "cdflib.putVarData", "cdflib.putVarRecordData", "cdflib.renameAttr", "cdflib.renameVar", "cdflib.setCacheSize", "cdflib.setChecksum", "cdflib.setCompression", "cdflib.setCompressionCacheSize", "cdflib.setFileBackward", "cdflib.setFormat", "cdflib.setMajority", "cdflib.setReadOnlyMode", "cdflib.setStageCacheSize", "cdflib.setValidate", "cdflib.setVarAllocBlockRecords", "cdflib.setVarBlockingFactor", "cdflib.setVarCacheSize", "cdflib.setVarCompression", "cdflib.setVarInitialRecs", "cdflib.setVarPadValue", "cdflib.SetVarReservePercent", "cdflib.setVarsCacheSize", "cdflib.setVarSparseRecords", "cdfread", "cdfwrite", "ceil", "cell", "cell2mat", "cell2struct", "cell2table", "celldisp", "cellfun", "cellplot", "cellstr", "centrality", "centroid", "cgs", "changeFields", "changeFields", "char", "char", "checkcode", "checkin", "checkout", "chol", "cholupdate", "choose", "circshift", "circumcenter", "circumcenters", "cla", "clabel", "class", "classdef", "classUnderlying", "clc", "clear", "clear", "clearAllMemoizedCaches", "clearCache", "clearMockHistory", "clearPersonalValue", "clearpoints", "clearTemporaryValue", "clearvars", "clf", "clibgen.buildInterface", "clibgen.ClassDefinition", "clibgen.ConstructorDefinition", "clibgen.EnumDefinition", "clibgen.FunctionDefinition", "clibgen.generateLibraryDefinition", "clibgen.LibraryDefinition", "clibgen.MethodDefinition", "clibgen.PropertyDefinition", "clibRelease", "clipboard", "clock", "clone", "close", "close", "close", "close", "close", "closeFile", "closereq", "cmopts", "cmpermute", "cmunique", "CodeCompatibilityAnalysis", "codeCompatibilityReport", "colamd", "collapse", "colon", "colorbar", "colorcube", "colordef", "colormap", "ColorSpec", "colperm", "COM", "com.mathworks.engine.MatlabEngine", "com.mathworks.matlab.types.CellStr", "com.mathworks.matlab.types.Complex", "com.mathworks.matlab.types.HandleObject", "com.mathworks.matlab.types.Struct", "combine", "Combine", "CombinedDatastore", "comet", "comet3", "compan", "compass", "complete", "complete", "complete", "complete", "complete", "complete", "complete", "complex", "compose", "computer", "cond", "condeig", "condensation", "condest", "coneplot", "conj", "conncomp", "containers.Map", "contains", "continue", "contour", "contour3", "contourc", "contourf", "contourslice", "contrast", "conv", "conv2", "convert", "convert", "convert", "convertCharsToStrings", "convertContainedStringsToChars", "convertLike", "convertStringsToChars", "convertvars", "convexHull", "convexHull", "convhull", "convhull", "convhulln", "convn", "cool", "copper", "copy", "copyElement", "copyfile", "copyHDU", "copyobj", "copyTo", "corrcoef", "cos", "cosd", "cosh", "cospi", "cot", "cotd", "coth", "count", "countcats", "countEachLabel", "cov", "cplxpair", "cputime", "createCategory", "createClassFromWsdl", "createFile", "createImg", "createLabel", "createMock", "createSampleTime", "createSharedTestFixture", "createSoapMessage", "createTbl", "createTestClassInstance", "createTestMethodInstance", "criticalAlpha", "cross", "csc", "cscd", "csch", "csvread", "csvwrite", "ctranspose", "cummax", "cummin", "cumprod", "cumsum", "cumtrapz", "curl", "currentProject", "customverctrl", "cylinder", "daqread", "daspect", "datacursormode", "datastore", "dataTipInteraction", "dataTipTextRow", "date", "datenum", "dateshift", "datestr", "datetick", "datetime", "datevec", "day", "days", "dbclear", "dbcont", "dbdown", "dblquad", "dbmex", "dbquit", "dbstack", "dbstatus", "dbstep", "dbstop", "dbtype", "dbup", "dde23", "ddeget", "ddensd", "ddesd", "ddeset", "deal", "deblank", "dec2base", "dec2bin", "dec2hex", "decic", "decomposition", "deconv", "defineArgument", "defineArgument", "defineArgument", "defineOutput", "defineOutput", "deg2rad", "degree", "del2", "delaunay", "delaunayn", "DelaunayTri", "DelaunayTri", "delaunayTriangulation", "delegateTo", "delegateTo", "delete", "delete", "delete", "delete", "delete", "deleteCol", "deleteFile", "deleteHDU", "deleteKey", "deleteproperty", "deleteRecord", "deleteRows", "delevent", "delimitedTextImportOptions", "delsample", "delsamplefromcollection", "demo", "det", "details", "detectImportOptions", "detrend", "detrend", "deval", "dfsearch", "diag", "diagnose", "dialog", "diary", "diff", "diffuse", "digraph", "dir", "dir", "disableDefaultInteractivity", "discretize", "disp", "disp", "disp", "display", "displayEmptyObject", "displayNonScalarObject", "displayScalarHandleToDeletedObject", "displayScalarObject", "dissect", "distances", "dither", "divergence", "dlmread", "dlmwrite", "dmperm", "doc", "docsearch", "done", "done", "dos", "dot", "double", "drag", "dragrect", "drawnow", "dsearchn", "duration", "dynamicprops", "echo", "echodemo", "edgeAttachments", "edgeAttachments", "edgecount", "edges", "edges", "edit", "eig", "eigs", "ellipj", "ellipke", "ellipsoid", "empty", "enableDefaultInteractivity", "enableNETfromNetworkDrive", "enableservice", "end", "EndInvoke", "endsWith", "enumeration", "eomday", "eps", "eq", "eq", "equilibrate", "erase", "eraseBetween", "erf", "erfc", "erfcinv", "erfcx", "erfinv", "error", "errorbar", "errordlg", "etime", "etree", "etreeplot", "eval", "evalc", "evalin", "event.DynamicPropertyEvent", "event.EventData", "event.hasListener", "event.listener", "event.PropertyEvent", "event.proplistener", "eventlisteners", "events", "events", "exceltime", "Execute", "exist", "exit", "exp", "expand", "expectedContentLength", "expectedContentLength", "expint", "expm", "expm1", "export", "export2wsdlg", "exportsetupdlg", "extractAfter", "extractBefore", "extractBetween", "eye", "ezcontour", "ezcontourf", "ezmesh", "ezmeshc", "ezplot", "ezplot3", "ezpolar", "ezsurf", "ezsurfc", "faceNormal", "faceNormals", "factor", "factorial", "false", "fatalAssertAccessed", "fatalAssertCalled", "fatalAssertClass", "fatalAssertEmpty", "fatalAssertEqual", "fatalAssertError", "fatalAssertFail", "fatalAssertFalse", "fatalAssertGreaterThan", "fatalAssertGreaterThanOrEqual", "fatalAssertInstanceOf", "fatalAssertLength", "fatalAssertLessThan", "fatalAssertLessThanOrEqual", "fatalAssertMatches", "fatalAssertNotAccessed", "fatalAssertNotCalled", "fatalAssertNotEmpty", "fatalAssertNotEqual", "fatalAssertNotSameHandle", "fatalAssertNotSet", "fatalAssertNumElements", "fatalAssertReturnsTrue", "fatalAssertSameHandle", "fatalAssertSet", "fatalAssertSize", "fatalAssertSubstring", "fatalAssertThat", "fatalAssertTrue", "fatalAssertUsing", "fatalAssertWarning", "fatalAssertWarningFree", "fclose", "fclose", "fcontour", "feather", "featureEdges", "featureEdges", "feof", "ferror", "feval", "Feval", "feval", "fewerbins", "fft", "fft2", "fftn", "fftshift", "fftw", "fgetl", "fgetl", "fgets", "fgets", "fieldnames", "figure", "figurepalette", "fileattrib", "fileDatastore", "filemarker", "fileMode", "fileName", "fileparts", "fileread", "filesep", "fill", "fill3", "fillmissing", "filloutliers", "filter", "filter", "filter2", "fimplicit", "fimplicit3", "find", "findall", "findCategory", "findedge", "findEvent", "findfigs", "findFile", "findgroups", "findLabel", "findnode", "findobj", "findobj", "findprop", "findstr", "finish", "fitsdisp", "fitsinfo", "fitsread", "fitswrite", "fix", "fixedWidthImportOptions", "flag", "flintmax", "flip", "flipdim", "flipedge", "fliplr", "flipud", "floor", "flow", "fmesh", "fminbnd", "fminsearch", "fopen", "fopen", "for", "format", "fplot", "fplot3", "fprintf", "fprintf", "frame2im", "fread", "fread", "freeBoundary", "freeBoundary", "freqspace", "frewind", "fscanf", "fscanf", "fseek", "fsurf", "ftell", "ftp", "full", "fullfile", "func2str", "function", "functions", "FunctionTestCase", "functiontests", "funm", "fwrite", "fwrite", "fzero", "gallery", "gamma", "gammainc", "gammaincinv", "gammaln", "gather", "gca", "gcbf", "gcbo", "gcd", "gcf", "gcmr", "gco", "ge", "genpath", "genvarname", "geoaxes", "geobasemap", "geobubble", "geodensityplot", "geolimits", "geoplot", "geoscatter", "geotickformat", "get", "get", "get", "get", "get", "get", "get", "get", "get", "get", "get", "getabstime", "getabstime", "getAColParms", "getappdata", "getaudiodata", "getBColParms", "GetCharArray", "getClass", "getColName", "getColType", "getConstantValue", "getCurrentTime", "getData", "getData", "getData", "getData", "getData", "getdatasamples", "getdatasamplesize", "getDiagnosticFor", "getDiagnosticFor", "getDiscreteStateImpl", "getDiscreteStateSpecificationImpl", "getdisp", "getenv", "getEqColType", "getfield", "getFields", "getFields", "getFileFormats", "getFooter", "getframe", "GetFullMatrix", "getGlobalNamesImpl", "getHdrSpace", "getHDUnum", "getHDUtype", "getHeader", "getHeaderImpl", "getIconImpl", "getImgSize", "getImgType", "getImpulseResponseLengthImpl", "getInputDimensionConstraintImpl", "getinterpmethod", "getLocation", "getLocation", "getMockHistory", "getNegativeDiagnosticFor", "getnext", "getNumCols", "getNumHDUs", "getNumInputs", "getNumInputsImpl", "getNumOutputs", "getNumOutputsImpl", "getNumRows", "getOpenFiles", "getOutputDataTypeImpl", "getOutputDimensionConstraintImpl", "getOutputSizeImpl", "getParameter", "getParameter", "getParameter", "getpixelposition", "getplayer", "getpoints", "getPostActValString", "getPostConditionString", "getPostDescriptionString", "getPostExpValString", "getPreDescriptionString", "getpref", "getProfiles", "getPropertyGroups", "getPropertyGroupsImpl", "getqualitydesc", "getReasonPhrase", "getReasonPhrase", "getReport", "getsamples", "getSampleTime", "getSampleTimeImpl", "getsampleusingtime", "getsampleusingtime", "getSharedTestFixtures", "getSimulateUsingImpl", "getSimulinkFunctionNamesImpl", "gettimeseriesnames", "getTimeStr", "gettsafteratevent", "gettsafterevent", "gettsatevent", "gettsbeforeatevent", "gettsbeforeevent", "gettsbetweenevents", "GetVariable", "getvaropts", "getVersion", "GetWorkspaceData", "ginput", "global", "gmres", "gobjects", "gplot", "grabcode", "gradient", "graph", "GraphPlot", "gray", "graymon", "grid", "griddata", "griddatan", "griddedInterpolant", "groot", "groupcounts", "groupsummary", "grouptransform", "gsvd", "gt", "gtext", "guidata", "guide", "guihandles", "gunzip", "gzip", "H5.close", "H5.garbage_collect", "H5.get_libversion", "H5.open", "H5.set_free_list_limits", "H5A.close", "H5A.create", "H5A.delete", "H5A.get_info", "H5A.get_name", "H5A.get_space", "H5A.get_type", "H5A.iterate", "H5A.open", "H5A.open_by_idx", "H5A.open_by_name", "H5A.read", "H5A.write", "h5create", "H5D.close", "H5D.create", "H5D.get_access_plist", "H5D.get_create_plist", "H5D.get_offset", "H5D.get_space", "H5D.get_space_status", "H5D.get_storage_size", "H5D.get_type", "H5D.open", "H5D.read", "H5D.set_extent", "H5D.vlen_get_buf_size", "H5D.write", "h5disp", "H5DS.attach_scale", "H5DS.detach_scale", "H5DS.get_label", "H5DS.get_num_scales", "H5DS.get_scale_name", "H5DS.is_scale", "H5DS.iterate_scales", "H5DS.set_label", "H5DS.set_scale", "H5E.clear", "H5E.get_major", "H5E.get_minor", "H5E.walk", "H5F.close", "H5F.create", "H5F.flush", "H5F.get_access_plist", "H5F.get_create_plist", "H5F.get_filesize", "H5F.get_freespace", "H5F.get_info", "H5F.get_mdc_config", "H5F.get_mdc_hit_rate", "H5F.get_mdc_size", "H5F.get_name", "H5F.get_obj_count", "H5F.get_obj_ids", "H5F.is_hdf5", "H5F.mount", "H5F.open", "H5F.reopen", "H5F.set_mdc_config", "H5F.unmount", "H5G.close", "H5G.create", "H5G.get_info", "H5G.open", "H5I.dec_ref", "H5I.get_file_id", "H5I.get_name", "H5I.get_ref", "H5I.get_type", "H5I.inc_ref", "H5I.is_valid", "h5info", "H5L.copy", "H5L.create_external", "H5L.create_hard", "H5L.create_soft", "H5L.delete", "H5L.exists", "H5L.get_info", "H5L.get_name_by_idx", "H5L.get_val", "H5L.iterate", "H5L.iterate_by_name", "H5L.move", "H5L.visit", "H5L.visit_by_name", "H5ML.compare_values", "H5ML.get_constant_names", "H5ML.get_constant_value", "H5ML.get_function_names", "H5ML.get_mem_datatype", "H5ML.hoffset", "H5ML.sizeof", "H5O.close", "H5O.copy", "H5O.get_comment", "H5O.get_comment_by_name", "H5O.get_info", "H5O.link", "H5O.open", "H5O.open_by_idx", "H5O.set_comment", "H5O.set_comment_by_name", "H5O.visit", "H5O.visit_by_name", "H5P.all_filters_avail", "H5P.close", "H5P.close_class", "H5P.copy", "H5P.create", "H5P.equal", "H5P.exist", "H5P.fill_value_defined", "H5P.get", "H5P.get_alignment", "H5P.get_alloc_time", "H5P.get_attr_creation_order", "H5P.get_attr_phase_change", "H5P.get_btree_ratios", "H5P.get_char_encoding", "H5P.get_chunk", "H5P.get_chunk_cache", "H5P.get_class", "H5P.get_class_name", "H5P.get_class_parent", "H5P.get_copy_object", "H5P.get_create_intermediate_group", "H5P.get_driver", "H5P.get_edc_check", "H5P.get_external", "H5P.get_external_count", "H5P.get_family_offset", "H5P.get_fapl_core", "H5P.get_fapl_family", "H5P.get_fapl_multi", "H5P.get_fclose_degree", "H5P.get_fill_time", "H5P.get_fill_value", "H5P.get_filter", "H5P.get_filter_by_id", "H5P.get_gc_references", "H5P.get_hyper_vector_size", "H5P.get_istore_k", "H5P.get_layout", "H5P.get_libver_bounds", "H5P.get_link_creation_order", "H5P.get_link_phase_change", "H5P.get_mdc_config", "H5P.get_meta_block_size", "H5P.get_multi_type", "H5P.get_nfilters", "H5P.get_nprops", "H5P.get_sieve_buf_size", "H5P.get_size", "H5P.get_sizes", "H5P.get_small_data_block_size", "H5P.get_sym_k", "H5P.get_userblock", "H5P.get_version", "H5P.isa_class", "H5P.iterate", "H5P.modify_filter", "H5P.remove_filter", "H5P.set", "H5P.set_alignment", "H5P.set_alloc_time", "H5P.set_attr_creation_order", "H5P.set_attr_phase_change", "H5P.set_btree_ratios", "H5P.set_char_encoding", "H5P.set_chunk", "H5P.set_chunk_cache", "H5P.set_copy_object", "H5P.set_create_intermediate_group", "H5P.set_deflate", "H5P.set_edc_check", "H5P.set_external", "H5P.set_family_offset", "H5P.set_fapl_core", "H5P.set_fapl_family", "H5P.set_fapl_log", "H5P.set_fapl_multi", "H5P.set_fapl_sec2", "H5P.set_fapl_split", "H5P.set_fapl_stdio", "H5P.set_fclose_degree", "H5P.set_fill_time", "H5P.set_fill_value", "H5P.set_filter", "H5P.set_fletcher32", "H5P.set_gc_references", "H5P.set_hyper_vector_size", "H5P.set_istore_k", "H5P.set_layout", "H5P.set_libver_bounds", "H5P.set_link_creation_order", "H5P.set_link_phase_change", "H5P.set_mdc_config", "H5P.set_meta_block_size", "H5P.set_multi_type", "H5P.set_nbit", "H5P.set_scaleoffset", "H5P.set_shuffle", "H5P.set_sieve_buf_size", "H5P.set_sizes", "H5P.set_small_data_block_size", "H5P.set_sym_k", "H5P.set_userblock", "H5R.create", "H5R.dereference", "H5R.get_name", "H5R.get_obj_type", "H5R.get_region", "h5read", "h5readatt", "H5S.close", "H5S.copy", "H5S.create", "H5S.create_simple", "H5S.extent_copy", "H5S.get_select_bounds", "H5S.get_select_elem_npoints", "H5S.get_select_elem_pointlist", "H5S.get_select_hyper_blocklist", "H5S.get_select_hyper_nblocks", "H5S.get_select_npoints", "H5S.get_select_type", "H5S.get_simple_extent_dims", "H5S.get_simple_extent_ndims", "H5S.get_simple_extent_npoints", "H5S.get_simple_extent_type", "H5S.is_simple", "H5S.offset_simple", "H5S.select_all", "H5S.select_elements", "H5S.select_hyperslab", "H5S.select_none", "H5S.select_valid", "H5S.set_extent_none", "H5S.set_extent_simple", "H5T.array_create", "H5T.close", "H5T.commit", "H5T.committed", "H5T.copy", "H5T.create", "H5T.detect_class", "H5T.enum_create", "H5T.enum_insert", "H5T.enum_nameof", "H5T.enum_valueof", "H5T.equal", "H5T.get_array_dims", "H5T.get_array_ndims", "H5T.get_class", "H5T.get_create_plist", "H5T.get_cset", "H5T.get_ebias", "H5T.get_fields", "H5T.get_inpad", "H5T.get_member_class", "H5T.get_member_index", "H5T.get_member_name", "H5T.get_member_offset", "H5T.get_member_type", "H5T.get_member_value", "H5T.get_native_type", "H5T.get_nmembers", "H5T.get_norm", "H5T.get_offset", "H5T.get_order", "H5T.get_pad", "H5T.get_precision", "H5T.get_sign", "H5T.get_size", "H5T.get_strpad", "H5T.get_super", "H5T.get_tag", "H5T.insert", "H5T.is_variable_str", "H5T.lock", "H5T.open", "H5T.pack", "H5T.set_cset", "H5T.set_ebias", "H5T.set_fields", "H5T.set_inpad", "H5T.set_norm", "H5T.set_offset", "H5T.set_order", "H5T.set_pad", "H5T.set_precision", "H5T.set_sign", "H5T.set_size", "H5T.set_strpad", "H5T.set_tag", "H5T.vlen_create", "h5write", "h5writeatt", "H5Z.filter_avail", "H5Z.get_filter_info", "hadamard", "handle", "hankel", "hasdata", "hasdata", "hasFactoryValue", "hasfile", "hasFrame", "hasnext", "hasPersonalValue", "hasTemporaryValue", "hdf5info", "hdf5read", "hdf5write", "hdfan", "hdfdf24", "hdfdfr8", "hdfh", "hdfhd", "hdfhe", "hdfhx", "hdfinfo", "hdfml", "hdfpt", "hdfread", "hdftool", "hdfv", "hdfvf", "hdfvh", "hdfvs", "head", "heatmap", "height", "help", "helpbrowser", "helpdesk", "helpdlg", "helpwin", "hess", "hex2dec", "hex2num", "hgexport", "hggroup", "hgload", "hgsave", "hgtransform", "hidden", "highlight", "hilb", "hist", "histc", "histcounts", "histcounts2", "histogram", "histogram2", "hms", "hold", "holes", "home", "horzcat", "horzcat", "horzcat", "hot", "hour", "hours", "hover", "hsv", "hsv2rgb", "hypot", "ichol", "idealfilter", "idivide", "ifft", "ifft2", "ifftn", "ifftshift", "ilu", "im2double", "im2frame", "im2java", "imag", "image", "imageDatastore", "imagesc", "imapprox", "imfinfo", "imformats", "imgCompress", "import", "importdata", "imread", "imresize", "imshow", "imtile", "imwrite", "incenter", "incenters", "incidence", "ind2rgb", "ind2sub", "indegree", "inedges", "Inf", "info", "infoImpl", "initialize", "initialize", "initialize", "initialize", "initialize", "initializeDatastore", "initializeDatastore", "inline", "inmem", "inner2outer", "innerjoin", "inOutStatus", "inpolygon", "input", "inputdlg", "inputname", "inputParser", "insertAfter", "insertATbl", "insertBefore", "insertBTbl", "insertCol", "insertImg", "insertRows", "inShape", "inspect", "instrcallback", "instrfind", "instrfindall", "int16", "int2str", "int32", "int64", "int8", "integral", "integral2", "integral3", "interp1", "interp1q", "interp2", "interp3", "interpft", "interpn", "interpstreamspeed", "intersect", "intersect", "intmax", "intmin", "inv", "invhilb", "invoke", "ipermute", "iqr", "is*", "isa", "isappdata", "isaUnderlying", "isbanded", "isbetween", "iscalendarduration", "iscategorical", "iscategory", "iscell", "iscellstr", "ischange", "ischar", "iscolumn", "iscom", "isCompatible", "isCompressedImg", "isConnected", "isdag", "isdatetime", "isdiag", "isdir", "isDiscreteStateSpecificationMutableImpl", "isDone", "isDoneImpl", "isdst", "isduration", "isEdge", "isempty", "isempty", "isenum", "isequal", "isequaln", "isequalwithequalnans", "isevent", "isfield", "isfile", "isfinite", "isfloat", "isfolder", "isfullfile", "isfullfile", "isgraphics", "ishandle", "ishermitian", "ishghandle", "ishold", "ishole", "isIllConditioned", "isInactivePropertyImpl", "isinf", "isInputComplexityMutableImpl", "isInputDataTypeMutableImpl", "isInputDirectFeedthroughImpl", "isInputSizeLockedImpl", "isInputSizeMutableImpl", "isinteger", "isinterface", "isInterior", "isinterior", "isisomorphic", "isjava", "isKey", "iskeyword", "isletter", "isLoaded", "islocalmax", "islocalmin", "isLocked", "islogical", "ismac", "ismatrix", "ismember", "ismembertol", "ismethod", "ismissing", "ismultigraph", "isnan", "isnat", "isNull", "isnumeric", "isobject", "isocaps", "isocolors", "isomorphism", "isonormals", "isordinal", "isosurface", "isoutlier", "isOutputComplexImpl", "isOutputFixedSizeImpl", "ispc", "isplaying", "ispref", "isprime", "isprop", "isprotected", "isreal", "isrecording", "isregular", "isrow", "isscalar", "issimplified", "issorted", "issortedrows", "isspace", "issparse", "isstr", "isstring", "isStringScalar", "isstrprop", "isstruct", "isstudent", "issymmetric", "istable", "istall", "istimetable", "istril", "istriu", "isTunablePropertyDataTypeMutableImpl", "isundefined", "isunix", "isvalid", "isvalid", "isvalid", "isvarname", "isvector", "isweekend", "javaaddpath", "javaArray", "javachk", "javaclasspath", "javaMethod", "javaMethodEDT", "javaObject", "javaObjectEDT", "javarmpath", "jet", "join", "join", "join", "jsondecode", "jsonencode", "juliandate", "keepMeasuring", "keyboard", "keys", "KeyValueDatastore", "KeyValueStore", "kron", "labeledge", "labelnode", "lag", "laplacian", "lasterr", "lasterror", "lastwarn", "layout", "lcm", "ldivide", "ldl", "le", "legend", "legendre", "length", "length", "length", "length", "lib.pointer", "libfunctions", "libfunctionsview", "libisloaded", "libpointer", "libstruct", "license", "light", "lightangle", "lighting", "lin2mu", "line", "lines", "LineSpec", "linkaxes", "linkdata", "linkprop", "linsolve", "linspace", "listdlg", "listener", "listfonts", "listModifiedFiles", "listRequiredFiles", "load", "load", "load", "loadlibrary", "loadobj", "loadObjectImpl", "localfunctions", "log", "log", "log", "log10", "log1p", "log2", "logical", "Logical", "loglog", "logm", "logspace", "lookfor", "lower", "ls", "lscov", "lsqminnorm", "lsqnonneg", "lsqr", "lt", "lu", "magic", "makehgtform", "mapreduce", "mapreducer", "mat2cell", "mat2str", "matchpairs", "material", "matfile", "matlab", "matlab", "matlab", "matlab.addons.disableAddon", "matlab.addons.enableAddon", "matlab.addons.install", "matlab.addons.installedAddons", "matlab.addons.isAddonEnabled", "matlab.addons.toolbox.installedToolboxes", "matlab.addons.toolbox.installToolbox", "matlab.addons.toolbox.packageToolbox", "matlab.addons.toolbox.toolboxVersion", "matlab.addons.toolbox.uninstallToolbox", "matlab.addons.uninstall", "matlab.apputil.create", "matlab.apputil.getInstalledAppInfo", "matlab.apputil.install", "matlab.apputil.package", "matlab.apputil.run", "matlab.apputil.uninstall", "matlab.codetools.requiredFilesAndProducts", "matlab.engine.connect_matlab", "matlab.engine.engineName", "matlab.engine.find_matlab", "matlab.engine.FutureResult", "matlab.engine.isEngineShared", "matlab.engine.MatlabEngine", "matlab.engine.shareEngine", "matlab.engine.start_matlab", "matlab.exception.JavaException", "matlab.exception.PyException", "matlab.graphics.Graphics", "matlab.graphics.GraphicsPlaceholder", "matlab.io.Datastore", "matlab.io.datastore.DsFileReader", "matlab.io.datastore.DsFileSet", "matlab.io.datastore.HadoopFileBased", "matlab.io.datastore.HadoopLocationBased", "matlab.io.datastore.Partitionable", "matlab.io.datastore.Shuffleable", "matlab.io.hdf4.sd", "matlab.io.hdf4.sd.attrInfo", "matlab.io.hdf4.sd.close", "matlab.io.hdf4.sd.create", "matlab.io.hdf4.sd.dimInfo", "matlab.io.hdf4.sd.endAccess", "matlab.io.hdf4.sd.fileInfo", "matlab.io.hdf4.sd.findAttr", "matlab.io.hdf4.sd.getCal", "matlab.io.hdf4.sd.getChunkInfo", "matlab.io.hdf4.sd.getCompInfo", "matlab.io.hdf4.sd.getDataStrs", "matlab.io.hdf4.sd.getDimID", "matlab.io.hdf4.sd.getDimScale", "matlab.io.hdf4.sd.getDimStrs", "matlab.io.hdf4.sd.getFilename", "matlab.io.hdf4.sd.getFillValue", "matlab.io.hdf4.sd.getInfo", "matlab.io.hdf4.sd.getRange", "matlab.io.hdf4.sd.idToRef", "matlab.io.hdf4.sd.idType", "matlab.io.hdf4.sd.isCoordVar", "matlab.io.hdf4.sd.isRecord", "matlab.io.hdf4.sd.nameToIndex", "matlab.io.hdf4.sd.nameToIndices", "matlab.io.hdf4.sd.readAttr", "matlab.io.hdf4.sd.readChunk", "matlab.io.hdf4.sd.readData", "matlab.io.hdf4.sd.refToIndex", "matlab.io.hdf4.sd.select", "matlab.io.hdf4.sd.setAttr", "matlab.io.hdf4.sd.setCal", "matlab.io.hdf4.sd.setChunk", "matlab.io.hdf4.sd.setCompress", "matlab.io.hdf4.sd.setDataStrs", "matlab.io.hdf4.sd.setDimName", "matlab.io.hdf4.sd.setDimScale", "matlab.io.hdf4.sd.setDimStrs", "matlab.io.hdf4.sd.setExternalFile", "matlab.io.hdf4.sd.setFillMode", "matlab.io.hdf4.sd.setFillValue", "matlab.io.hdf4.sd.setNBitDataSet", "matlab.io.hdf4.sd.setRange", "matlab.io.hdf4.sd.start", "matlab.io.hdf4.sd.writeChunk", "matlab.io.hdf4.sd.writeData", "matlab.io.hdfeos.gd", "matlab.io.hdfeos.gd.attach", "matlab.io.hdfeos.gd.close", "matlab.io.hdfeos.gd.compInfo", "matlab.io.hdfeos.gd.create", "matlab.io.hdfeos.gd.defBoxRegion", "matlab.io.hdfeos.gd.defComp", "matlab.io.hdfeos.gd.defDim", "matlab.io.hdfeos.gd.defField", "matlab.io.hdfeos.gd.defOrigin", "matlab.io.hdfeos.gd.defPixReg", "matlab.io.hdfeos.gd.defProj", "matlab.io.hdfeos.gd.defTile", "matlab.io.hdfeos.gd.defVrtRegion", "matlab.io.hdfeos.gd.detach", "matlab.io.hdfeos.gd.dimInfo", "matlab.io.hdfeos.gd.extractRegion", "matlab.io.hdfeos.gd.fieldInfo", "matlab.io.hdfeos.gd.getFillValue", "matlab.io.hdfeos.gd.getPixels", "matlab.io.hdfeos.gd.getPixValues", "matlab.io.hdfeos.gd.gridInfo", "matlab.io.hdfeos.gd.ij2ll", "matlab.io.hdfeos.gd.inqAttrs", "matlab.io.hdfeos.gd.inqDims", "matlab.io.hdfeos.gd.inqFields", "matlab.io.hdfeos.gd.inqGrid", "matlab.io.hdfeos.gd.interpolate", "matlab.io.hdfeos.gd.ll2ij", "matlab.io.hdfeos.gd.nEntries", "matlab.io.hdfeos.gd.open", "matlab.io.hdfeos.gd.originInfo", "matlab.io.hdfeos.gd.pixRegInfo", "matlab.io.hdfeos.gd.projInfo", "matlab.io.hdfeos.gd.readAttr", "matlab.io.hdfeos.gd.readBlkSomOffset", "matlab.io.hdfeos.gd.readField", "matlab.io.hdfeos.gd.readTile", "matlab.io.hdfeos.gd.regionInfo", "matlab.io.hdfeos.gd.setFillValue", "matlab.io.hdfeos.gd.setTileComp", "matlab.io.hdfeos.gd.sphereCodeToName", "matlab.io.hdfeos.gd.sphereNameToCode", "matlab.io.hdfeos.gd.tileInfo", "matlab.io.hdfeos.gd.writeAttr", "matlab.io.hdfeos.gd.writeBlkSomOffset", "matlab.io.hdfeos.gd.writeField", "matlab.io.hdfeos.gd.writeTile", "matlab.io.hdfeos.sw", "matlab.io.hdfeos.sw.attach", "matlab.io.hdfeos.sw.close", "matlab.io.hdfeos.sw.compInfo", "matlab.io.hdfeos.sw.create", "matlab.io.hdfeos.sw.defBoxRegion", "matlab.io.hdfeos.sw.defComp", "matlab.io.hdfeos.sw.defDataField", "matlab.io.hdfeos.sw.defDim", "matlab.io.hdfeos.sw.defDimMap", "matlab.io.hdfeos.sw.defGeoField", "matlab.io.hdfeos.sw.defTimePeriod", "matlab.io.hdfeos.sw.defVrtRegion", "matlab.io.hdfeos.sw.detach", "matlab.io.hdfeos.sw.dimInfo", "matlab.io.hdfeos.sw.extractPeriod", "matlab.io.hdfeos.sw.extractRegion", "matlab.io.hdfeos.sw.fieldInfo", "matlab.io.hdfeos.sw.geoMapInfo", "matlab.io.hdfeos.sw.getFillValue", "matlab.io.hdfeos.sw.idxMapInfo", "matlab.io.hdfeos.sw.inqAttrs", "matlab.io.hdfeos.sw.inqDataFields", "matlab.io.hdfeos.sw.inqDims", "matlab.io.hdfeos.sw.inqGeoFields", "matlab.io.hdfeos.sw.inqIdxMaps", "matlab.io.hdfeos.sw.inqMaps", "matlab.io.hdfeos.sw.inqSwath", "matlab.io.hdfeos.sw.mapInfo", "matlab.io.hdfeos.sw.nEntries", "matlab.io.hdfeos.sw.open", "matlab.io.hdfeos.sw.periodInfo", "matlab.io.hdfeos.sw.readAttr", "matlab.io.hdfeos.sw.readField", "matlab.io.hdfeos.sw.regionInfo", "matlab.io.hdfeos.sw.setFillValue", "matlab.io.hdfeos.sw.writeAttr", "matlab.io.hdfeos.sw.writeField", "matlab.io.MatFile", "matlab.io.saveVariablesToScript", "matlab.lang.correction.AppendArgumentsCorrection", "matlab.lang.makeUniqueStrings", "matlab.lang.makeValidName", "matlab.lang.OnOffSwitchState", "matlab.mex.MexHost", "matlab.mixin.Copyable", "matlab.mixin.CustomDisplay", "matlab.mixin.CustomDisplay.convertDimensionsToString", "matlab.mixin.CustomDisplay.displayPropertyGroups", "matlab.mixin.CustomDisplay.getClassNameForHeader", "matlab.mixin.CustomDisplay.getDeletedHandleText", "matlab.mixin.CustomDisplay.getDetailedFooter", "matlab.mixin.CustomDisplay.getDetailedHeader", "matlab.mixin.CustomDisplay.getHandleText", "matlab.mixin.CustomDisplay.getSimpleHeader", "matlab.mixin.Heterogeneous", "matlab.mixin.Heterogeneous.getDefaultScalarElement", "matlab.mixin.SetGet", "matlab.mixin.SetGetExactNames", "matlab.mixin.util.PropertyGroup", "matlab.mock.actions.AssignOutputs", "matlab.mock.actions.Invoke", "matlab.mock.actions.ReturnStoredValue", "matlab.mock.actions.StoreValue", "matlab.mock.actions.ThrowException", "matlab.mock.AnyArguments", "matlab.mock.constraints.Occurred", "matlab.mock.constraints.WasAccessed", "matlab.mock.constraints.WasCalled", "matlab.mock.constraints.WasSet", "matlab.mock.history.MethodCall", "matlab.mock.history.PropertyAccess", "matlab.mock.history.PropertyModification", "matlab.mock.history.SuccessfulMethodCall", "matlab.mock.history.SuccessfulPropertyAccess", "matlab.mock.history.SuccessfulPropertyModification", "matlab.mock.history.UnsuccessfulMethodCall", "matlab.mock.history.UnsuccessfulPropertyAccess", "matlab.mock.history.UnsuccessfulPropertyModification", "matlab.mock.InteractionHistory", "matlab.mock.InteractionHistory.forMock", "matlab.mock.MethodCallBehavior", "matlab.mock.PropertyBehavior", "matlab.mock.PropertyGetBehavior", "matlab.mock.PropertySetBehavior", "matlab.mock.TestCase", "matlab.mock.TestCase.forInteractiveUse", "matlab.net.ArrayFormat", "matlab.net.base64decode", "matlab.net.base64encode", "matlab.net.http.AuthenticationScheme", "matlab.net.http.AuthInfo", "matlab.net.http.Cookie", "matlab.net.http.CookieInfo", "matlab.net.http.CookieInfo.collectFromLog", "matlab.net.http.Credentials", "matlab.net.http.Disposition", "matlab.net.http.field.AcceptField", "matlab.net.http.field.AuthenticateField", "matlab.net.http.field.AuthenticationInfoField", "matlab.net.http.field.AuthorizationField", "matlab.net.http.field.ContentDispositionField", "matlab.net.http.field.ContentLengthField", "matlab.net.http.field.ContentLocationField", "matlab.net.http.field.ContentTypeField", "matlab.net.http.field.CookieField", "matlab.net.http.field.DateField", "matlab.net.http.field.GenericField", "matlab.net.http.field.GenericParameterizedField", "matlab.net.http.field.HTTPDateField", "matlab.net.http.field.IntegerField", "matlab.net.http.field.LocationField", "matlab.net.http.field.MediaRangeField", "matlab.net.http.field.SetCookieField", "matlab.net.http.field.URIReferenceField", "matlab.net.http.HeaderField", "matlab.net.http.HeaderField.displaySubclasses", "matlab.net.http.HTTPException", "matlab.net.http.HTTPOptions", "matlab.net.http.io.BinaryConsumer", "matlab.net.http.io.ContentConsumer", "matlab.net.http.io.ContentProvider", "matlab.net.http.io.FileConsumer", "matlab.net.http.io.FileProvider", "matlab.net.http.io.FormProvider", "matlab.net.http.io.GenericConsumer", "matlab.net.http.io.GenericProvider", "matlab.net.http.io.ImageConsumer", "matlab.net.http.io.ImageProvider", "matlab.net.http.io.JSONConsumer", "matlab.net.http.io.JSONProvider", "matlab.net.http.io.MultipartConsumer", "matlab.net.http.io.MultipartFormProvider", "matlab.net.http.io.MultipartProvider", "matlab.net.http.io.StringConsumer", "matlab.net.http.io.StringProvider", "matlab.net.http.LogRecord", "matlab.net.http.MediaType", "matlab.net.http.Message", "matlab.net.http.MessageBody", "matlab.net.http.MessageType", "matlab.net.http.ProgressMonitor", "matlab.net.http.ProtocolVersion", "matlab.net.http.RequestLine", "matlab.net.http.RequestMessage", "matlab.net.http.RequestMethod", "matlab.net.http.ResponseMessage", "matlab.net.http.StartLine", "matlab.net.http.StatusClass", "matlab.net.http.StatusCode", "matlab.net.http.StatusCode.fromValue", "matlab.net.http.StatusLine", "matlab.net.QueryParameter", "matlab.net.URI", "matlab.perftest.FixedTimeExperiment", "matlab.perftest.FrequentistTimeExperiment", "matlab.perftest.TestCase", "matlab.perftest.TimeExperiment", "matlab.perftest.TimeExperiment.limitingSamplingError", "matlab.perftest.TimeExperiment.withFixedSampleSize", "matlab.perftest.TimeResult", "matlab.project.createProject", "matlab.project.loadProject", "matlab.project.Project", "matlab.project.rootProject", "matlab.System", "matlab.system.display.Action", "matlab.system.display.Header", "matlab.system.display.Icon", "matlab.system.display.Section", "matlab.system.display.SectionGroup", "matlab.system.mixin.CustomIcon", "matlab.system.mixin.FiniteSource", "matlab.system.mixin.Nondirect", "matlab.system.mixin.Propagates", "matlab.system.mixin.SampleTime", "matlab.system.StringSet", "matlab.tall.blockMovingWindow", "matlab.tall.movingWindow", "matlab.tall.reduce", "matlab.tall.transform", "matlab.test.behavior.Missing", "matlab.uitest.TestCase", "matlab.uitest.TestCase.forInteractiveUse", "matlab.uitest.unlock", "matlab.unittest.constraints.AbsoluteTolerance", "matlab.unittest.constraints.AnyCellOf", "matlab.unittest.constraints.AnyElementOf", "matlab.unittest.constraints.BooleanConstraint", "matlab.unittest.constraints.CellComparator", "matlab.unittest.constraints.Constraint", "matlab.unittest.constraints.ContainsSubstring", "matlab.unittest.constraints.EndsWithSubstring", "matlab.unittest.constraints.Eventually", "matlab.unittest.constraints.EveryCellOf", "matlab.unittest.constraints.EveryElementOf", "matlab.unittest.constraints.HasElementCount", "matlab.unittest.constraints.HasField", "matlab.unittest.constraints.HasInf", "matlab.unittest.constraints.HasLength", "matlab.unittest.constraints.HasNaN", "matlab.unittest.constraints.HasSize", "matlab.unittest.constraints.HasUniqueElements", "matlab.unittest.constraints.IsAnything", "matlab.unittest.constraints.IsEmpty", "matlab.unittest.constraints.IsEqualTo", "matlab.unittest.constraints.IsFalse", "matlab.unittest.constraints.IsFile", "matlab.unittest.constraints.IsFinite", "matlab.unittest.constraints.IsFolder", "matlab.unittest.constraints.IsGreaterThan", "matlab.unittest.constraints.IsGreaterThanOrEqualTo", "matlab.unittest.constraints.IsInstanceOf", "matlab.unittest.constraints.IsLessThan", "matlab.unittest.constraints.IsLessThanOrEqualTo", "matlab.unittest.constraints.IsOfClass", "matlab.unittest.constraints.IsReal", "matlab.unittest.constraints.IsSameHandleAs", "matlab.unittest.constraints.IsSameSetAs", "matlab.unittest.constraints.IsScalar", "matlab.unittest.constraints.IsSparse", "matlab.unittest.constraints.IsSubsetOf", "matlab.unittest.constraints.IsSubstringOf", "matlab.unittest.constraints.IssuesNoWarnings", "matlab.unittest.constraints.IssuesWarnings", "matlab.unittest.constraints.IsSupersetOf", "matlab.unittest.constraints.IsTrue", "matlab.unittest.constraints.LogicalComparator", "matlab.unittest.constraints.Matches", "matlab.unittest.constraints.NumericComparator", "matlab.unittest.constraints.ObjectComparator", "matlab.unittest.constraints.PublicPropertyComparator", "matlab.unittest.constraints.PublicPropertyComparator.supportingAllValues", "matlab.unittest.constraints.RelativeTolerance", "matlab.unittest.constraints.ReturnsTrue", "matlab.unittest.constraints.StartsWithSubstring", "matlab.unittest.constraints.StringComparator", "matlab.unittest.constraints.StructComparator", "matlab.unittest.constraints.TableComparator", "matlab.unittest.constraints.Throws", "matlab.unittest.constraints.Tolerance", "matlab.unittest.diagnostics.ConstraintDiagnostic", "matlab.unittest.diagnostics.ConstraintDiagnostic.getDisplayableString", "matlab.unittest.diagnostics.Diagnostic", "matlab.unittest.diagnostics.DiagnosticResult", "matlab.unittest.diagnostics.DisplayDiagnostic", "matlab.unittest.diagnostics.FigureDiagnostic", "matlab.unittest.diagnostics.FileArtifact", "matlab.unittest.diagnostics.FrameworkDiagnostic", "matlab.unittest.diagnostics.FunctionHandleDiagnostic", "matlab.unittest.diagnostics.LoggedDiagnosticEventData", "matlab.unittest.diagnostics.ScreenshotDiagnostic", "matlab.unittest.diagnostics.StringDiagnostic", "matlab.unittest.fixtures.CurrentFolderFixture", "matlab.unittest.fixtures.Fixture", "matlab.unittest.fixtures.PathFixture", "matlab.unittest.fixtures.ProjectFixture", "matlab.unittest.fixtures.SuppressedWarningsFixture", "matlab.unittest.fixtures.TemporaryFolderFixture", "matlab.unittest.fixtures.WorkingFolderFixture", "matlab.unittest.measurement.DefaultMeasurementResult", "matlab.unittest.measurement.MeasurementResult", "matlab.unittest.parameters.ClassSetupParameter", "matlab.unittest.parameters.EmptyParameter", "matlab.unittest.parameters.MethodSetupParameter", "matlab.unittest.parameters.Parameter", "matlab.unittest.parameters.Parameter.fromData", "matlab.unittest.parameters.TestParameter", "matlab.unittest.plugins.codecoverage.CoberturaFormat", "matlab.unittest.plugins.codecoverage.CoverageReport", "matlab.unittest.plugins.codecoverage.ProfileReport", "matlab.unittest.plugins.CodeCoveragePlugin", "matlab.unittest.plugins.CodeCoveragePlugin.forFile", "matlab.unittest.plugins.CodeCoveragePlugin.forFolder", "matlab.unittest.plugins.CodeCoveragePlugin.forPackage", "matlab.unittest.plugins.diagnosticrecord.DiagnosticRecord", "matlab.unittest.plugins.diagnosticrecord.ExceptionDiagnosticRecord", "matlab.unittest.plugins.diagnosticrecord.LoggedDiagnosticRecord", "matlab.unittest.plugins.diagnosticrecord.QualificationDiagnosticRecord", "matlab.unittest.plugins.DiagnosticsOutputPlugin", "matlab.unittest.plugins.DiagnosticsRecordingPlugin", "matlab.unittest.plugins.DiagnosticsValidationPlugin", "matlab.unittest.plugins.FailOnWarningsPlugin", "matlab.unittest.plugins.LoggingPlugin", "matlab.unittest.plugins.LoggingPlugin.withVerbosity", "matlab.unittest.plugins.OutputStream", "matlab.unittest.plugins.plugindata.FinalizedResultPluginData", "matlab.unittest.plugins.plugindata.ImplicitFixturePluginData", "matlab.unittest.plugins.plugindata.PluginData", "matlab.unittest.plugins.plugindata.QualificationContext", "matlab.unittest.plugins.plugindata.SharedTestFixturePluginData", "matlab.unittest.plugins.plugindata.TestContentCreationPluginData", "matlab.unittest.plugins.plugindata.TestSuiteRunPluginData", "matlab.unittest.plugins.QualifyingPlugin", "matlab.unittest.plugins.StopOnFailuresPlugin", "matlab.unittest.plugins.TAPPlugin", "matlab.unittest.plugins.TAPPlugin.producingOriginalFormat", "matlab.unittest.plugins.TAPPlugin.producingVersion13", "matlab.unittest.plugins.testreport.DOCXTestReportPlugin", "matlab.unittest.plugins.testreport.HTMLTestReportPlugin", "matlab.unittest.plugins.testreport.PDFTestReportPlugin", "matlab.unittest.plugins.TestReportPlugin", "matlab.unittest.plugins.TestReportPlugin.producingDOCX", "matlab.unittest.plugins.TestReportPlugin.producingHTML", "matlab.unittest.plugins.TestReportPlugin.producingPDF", "matlab.unittest.plugins.TestRunnerPlugin", "matlab.unittest.plugins.TestRunProgressPlugin", "matlab.unittest.plugins.ToFile", "matlab.unittest.plugins.ToStandardOutput", "matlab.unittest.plugins.ToUniqueFile", "matlab.unittest.plugins.XMLPlugin", "matlab.unittest.plugins.XMLPlugin.producingJUnitFormat", "matlab.unittest.qualifications.Assertable", "matlab.unittest.qualifications.AssertionFailedException", "matlab.unittest.qualifications.Assumable", "matlab.unittest.qualifications.AssumptionFailedException", "matlab.unittest.qualifications.ExceptionEventData", "matlab.unittest.qualifications.FatalAssertable", "matlab.unittest.qualifications.FatalAssertionFailedException", "matlab.unittest.qualifications.QualificationEventData", "matlab.unittest.qualifications.Verifiable", "matlab.unittest.Scope", "matlab.unittest.selectors.AndSelector", "matlab.unittest.selectors.HasBaseFolder", "matlab.unittest.selectors.HasName", "matlab.unittest.selectors.HasParameter", "matlab.unittest.selectors.HasProcedureName", "matlab.unittest.selectors.HasSharedTestFixture", "matlab.unittest.selectors.HasSuperclass", "matlab.unittest.selectors.HasTag", "matlab.unittest.selectors.NotSelector", "matlab.unittest.selectors.OrSelector", "matlab.unittest.Test", "matlab.unittest.TestCase", "matlab.unittest.TestCase.forInteractiveUse", "matlab.unittest.TestResult", "matlab.unittest.TestRunner", "matlab.unittest.TestRunner.withNoPlugins", "matlab.unittest.TestRunner.withTextOutput", "matlab.unittest.TestSuite", "matlab.unittest.TestSuite.fromClass", "matlab.unittest.TestSuite.fromFile", "matlab.unittest.TestSuite.fromFolder", "matlab.unittest.TestSuite.fromMethod", "matlab.unittest.TestSuite.fromName", "matlab.unittest.TestSuite.fromPackage", "matlab.unittest.TestSuite.fromProject", "matlab.unittest.Verbosity", "matlab.wsdl.createWSDLClient", "matlab.wsdl.setWSDLToolPath", "matlabrc", "matlabroot", "matlabshared.supportpkg.checkForUpdate", "matlabshared.supportpkg.getInstalled", "matlabshared.supportpkg.getSupportPackageRoot", "matlabshared.supportpkg.setSupportPackageRoot", "max", "max", "maxflow", "MaximizeCommandWindow", "maxk", "maxNumCompThreads", "maxpartitions", "maxpartitions", "mean", "mean", "median", "median", "memmapfile", "memoize", "MemoizedFunction", "memory", "menu", "mergecats", "mergevars", "mesh", "meshc", "meshgrid", "meshz", "meta.abstractDetails", "meta.ArrayDimension", "meta.class", "meta.class.fromName", "meta.DynamicProperty", "meta.EnumeratedValue", "meta.event", "meta.FixedDimension", "meta.MetaData", "meta.method", "meta.package", "meta.package.fromName", "meta.package.getAllPackages", "meta.property", "meta.UnrestrictedDimension", "meta.Validation", "metaclass", "methods", "methodsview", "mex", "mex.getCompilerConfigurations", "MException", "MException.last", "mexext", "mexhost", "mfilename", "mget", "milliseconds", "min", "min", "MinimizeCommandWindow", "mink", "minres", "minspantree", "minus", "minute", "minutes", "mislocked", "missing", "mkdir", "mkdir", "mkpp", "mldivide", "mlint", "mlintrpt", "mlock", "mmfileinfo", "mod", "mode", "month", "more", "morebins", "movAbsHDU", "move", "move", "movefile", "movegui", "movevars", "movie", "movmad", "movmax", "movmean", "movmedian", "movmin", "movNamHDU", "movprod", "movRelHDU", "movstd", "movsum", "movvar", "mpower", "mput", "mrdivide", "msgbox", "mtimes", "mu2lin", "multibandread", "multibandwrite", "munlock", "mustBeFinite", "mustBeGreaterThan", "mustBeGreaterThanOrEqual", "mustBeInteger", "mustBeLessThan", "mustBeLessThanOrEqual", "mustBeMember", "mustBeNegative", "mustBeNonempty", "mustBeNonNan", "mustBeNonnegative", "mustBeNonpositive", "mustBeNonsparse", "mustBeNonzero", "mustBeNumeric", "mustBeNumericOrLogical", "mustBePositive", "mustBeReal", "namelengthmax", "NaN", "nargchk", "nargin", "nargin", "narginchk", "nargout", "nargout", "nargoutchk", "NaT", "native2unicode", "nccreate", "ncdisp", "nchoosek", "ncinfo", "ncread", "ncreadatt", "ncwrite", "ncwriteatt", "ncwriteschema", "ndgrid", "ndims", "ne", "nearest", "nearestNeighbor", "nearestNeighbor", "nearestNeighbor", "nearestvertex", "neighbors", "neighbors", "neighbors", "NET", "NET.addAssembly", "NET.Assembly", "NET.convertArray", "NET.createArray", "NET.createGeneric", "NET.disableAutoRelease", "NET.enableAutoRelease", "NET.GenericClass", "NET.invokeGenericMethod", "NET.isNETSupported", "NET.NetException", "NET.setStaticProperty", "netcdf.abort", "netcdf.close", "netcdf.copyAtt", "netcdf.create", "netcdf.defDim", "netcdf.defGrp", "netcdf.defVar", "netcdf.defVarChunking", "netcdf.defVarDeflate", "netcdf.defVarFill", "netcdf.defVarFletcher32", "netcdf.delAtt", "netcdf.endDef", "netcdf.getAtt", "netcdf.getChunkCache", "netcdf.getConstant", "netcdf.getConstantNames", "netcdf.getVar", "netcdf.inq", "netcdf.inqAtt", "netcdf.inqAttID", "netcdf.inqAttName", "netcdf.inqDim", "netcdf.inqDimID", "netcdf.inqDimIDs", "netcdf.inqFormat", "netcdf.inqGrpName", "netcdf.inqGrpNameFull", "netcdf.inqGrpParent", "netcdf.inqGrps", "netcdf.inqLibVers", "netcdf.inqNcid", "netcdf.inqUnlimDims", "netcdf.inqVar", "netcdf.inqVarChunking", "netcdf.inqVarDeflate", "netcdf.inqVarFill", "netcdf.inqVarFletcher32", "netcdf.inqVarID", "netcdf.inqVarIDs", "netcdf.open", "netcdf.putAtt", "netcdf.putVar", "netcdf.reDef", "netcdf.renameAtt", "netcdf.renameDim", "netcdf.renameVar", "netcdf.setChunkCache", "netcdf.setDefaultFormat", "netcdf.setFill", "netcdf.sync", "newline", "newplot", "nextfile", "nextpow2", "nnz", "nonzeros", "norm", "normalize", "normest", "not", "notebook", "notify", "now", "nsidedpoly", "nthroot", "null", "num2cell", "num2hex", "num2ruler", "num2str", "numArgumentsFromSubscript", "numboundaries", "numedges", "numel", "numnodes", "numpartitions", "numpartitions", "numRegions", "numsides", "nzmax", "ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", "ode23tb", "ode45", "odeget", "odeset", "odextend", "onCleanup", "ones", "onFailure", "onFailure", "open", "open", "openDiskFile", "openfig", "openFile", "opengl", "openProject", "openvar", "optimget", "optimset", "or", "ordeig", "orderfields", "ordqz", "ordschur", "orient", "orth", "outdegree", "outedges", "outerjoin", "outputImpl", "overlaps", "pack", "pad", "padecoef", "pagesetupdlg", "pan", "panInteraction", "parallelplot", "pareto", "parfor", "parquetDatastore", "parquetinfo", "parquetread", "parquetwrite", "parse", "parse", "parseSoapResponse", "partition", "partition", "partition", "parula", "pascal", "patch", "path", "path2rc", "pathsep", "pathtool", "pause", "pause", "pbaspect", "pcg", "pchip", "pcode", "pcolor", "pdepe", "pdeval", "peaks", "perimeter", "perimeter", "perl", "perms", "permute", "persistent", "pi", "pie", "pie3", "pink", "pinv", "planerot", "play", "play", "playblocking", "plot", "plot", "plot", "plot", "plot", "plot3", "plotbrowser", "plotedit", "plotmatrix", "plottools", "plotyy", "plus", "plus", "pointLocation", "pointLocation", "pol2cart", "polar", "polaraxes", "polarhistogram", "polarplot", "polarscatter", "poly", "polyarea", "polybuffer", "polyder", "polyeig", "polyfit", "polyint", "polyshape", "polyval", "polyvalm", "posixtime", "pow2", "power", "ppval", "predecessors", "prefdir", "preferences", "preferredBufferSize", "preferredBufferSize", "press", "preview", "preview", "primes", "print", "print", "printdlg", "printopt", "printpreview", "prism", "processInputSpecificationChangeImpl", "processTunedPropertiesImpl", "prod", "profile", "profsave", "progress", "propagatedInputComplexity", "propagatedInputDataType", "propagatedInputFixedSize", "propagatedInputSize", "propedit", "propedit", "properties", "propertyeditor", "psi", "publish", "PutCharArray", "putData", "putData", "putData", "putData", "putData", "putData", "putData", "putData", "PutFullMatrix", "PutWorkspaceData", "pwd", "pyargs", "pyversion", "qmr", "qr", "qrdelete", "qrinsert", "qrupdate", "quad", "quad2d", "quadgk", "quadl", "quadv", "quarter", "questdlg", "Quit", "quit", "quiver", "quiver3", "qz", "rad2deg", "rand", "rand", "randi", "randi", "randn", "randn", "randperm", "randperm", "RandStream", "RandStream", "RandStream.create", "RandStream.getGlobalStream", "RandStream.list", "RandStream.setGlobalStream", "rank", "rat", "rats", "rbbox", "rcond", "rdivide", "read", "read", "read", "read", "read", "readall", "readasync", "readATblHdr", "readBTblHdr", "readCard", "readcell", "readCol", "readFrame", "readimage", "readImg", "readKey", "readKeyCmplx", "readKeyDbl", "readKeyLongLong", "readKeyLongStr", "readKeyUnit", "readmatrix", "readRecord", "readtable", "readtimetable", "readvars", "real", "reallog", "realmax", "realmin", "realpow", "realsqrt", "record", "record", "recordblocking", "rectangle", "rectint", "recycle", "reducepatch", "reducevolume", "refresh", "refreshdata", "refreshSourceControl", "regexp", "regexpi", "regexprep", "regexptranslate", "regions", "regionZoomInteraction", "registerevent", "regmatlabserver", "rehash", "relationaloperators", "release", "release", "releaseImpl", "reload", "rem", "Remove", "remove", "RemoveAll", "removeCategory", "removecats", "removeFields", "removeFields", "removeFile", "removeLabel", "removeParameter", "removeParameter", "removePath", "removeReference", "removeShortcut", "removeShutdownFile", "removeStartupFile", "removeToolbarExplorationButtons", "removets", "removevars", "rename", "renamecats", "rendererinfo", "reordercats", "reordernodes", "repeat", "repeat", "repeat", "repeat", "repeat", "repelem", "replace", "replaceBetween", "replaceFields", "replaceFields", "repmat", "reportFinalizedResult", "resample", "resample", "rescale", "reset", "reset", "reset", "reset", "reset", "resetImpl", "reshape", "reshape", "residue", "resolve", "restartable", "restartable", "restartable", "restoredefaultpath", "result", "resume", "rethrow", "rethrow", "retime", "return", "returnStoredValueWhen", "reusable", "reusable", "reusable", "reverse", "rgb2gray", "rgb2hsv", "rgb2ind", "rgbplot", "ribbon", "rlim", "rmappdata", "rmboundary", "rmdir", "rmdir", "rmedge", "rmfield", "rmholes", "rmmissing", "rmnode", "rmoutliers", "rmpath", "rmpref", "rmprop", "rmslivers", "rng", "roots", "rose", "rosser", "rot90", "rotate", "rotate", "rotate3d", "rotateInteraction", "round", "rowfun", "rows2vars", "rref", "rsf2csf", "rtickangle", "rtickformat", "rticklabels", "rticks", "ruler2num", "rulerPanInteraction", "run", "run", "run", "run", "run", "runInParallel", "runperf", "runTest", "runTestClass", "runTestMethod", "runtests", "runTestSuite", "samplefun", "sampleSummary", "satisfiedBy", "satisfiedBy", "save", "save", "save", "saveas", "savefig", "saveobj", "saveObjectImpl", "savepath", "scale", "scatter", "scatter3", "scatteredInterpolant", "scatterhistogram", "schur", "scroll", "sec", "secd", "sech", "second", "seconds", "seek", "selectFailed", "selectIf", "selectIncomplete", "selectLogged", "selectmoveresize", "selectPassed", "semilogx", "semilogy", "send", "sendmail", "serial", "serialbreak", "seriallist", "set", "set", "set", "set", "set", "set", "set", "set", "set", "set", "set", "setabstime", "setabstime", "setappdata", "setBscale", "setcats", "setCompressionType", "setdatatype", "setdiff", "setdisp", "setenv", "setfield", "setHCompScale", "setHCompSmooth", "setinterpmethod", "setParameter", "setParameter", "setParameter", "setpixelposition", "setpref", "setProperties", "setstr", "setTileDim", "settimeseriesnames", "Setting", "settings", "SettingsGroup", "setToValue", "setTscale", "setuniformtime", "setup", "setupImpl", "setupSharedTestFixture", "setupTestClass", "setupTestMethod", "setvaropts", "setvartype", "setxor", "sgtitle", "shading", "sheetnames", "shg", "shiftdim", "shortestpath", "shortestpathtree", "show", "show", "show", "show", "showFiSettingsImpl", "showplottool", "showSimulateUsingImpl", "shrinkfaces", "shuffle", "shuffle", "sign", "simplify", "simplify", "sin", "sind", "single", "sinh", "sinpi", "size", "size", "size", "size", "size", "size", "size", "slice", "smooth3", "smoothdata", "snapnow", "sort", "sortboundaries", "sortByFixtures", "sortregions", "sortrows", "sortx", "sorty", "sound", "soundsc", "spalloc", "sparse", "spaugment", "spconvert", "spdiags", "specular", "speye", "spfun", "sph2cart", "sphere", "spinmap", "spline", "split", "split", "splitapply", "splitEachLabel", "splitlines", "splitvars", "spones", "spparms", "sprand", "sprandn", "sprandsym", "sprank", "spreadsheetDatastore", "spreadsheetImportOptions", "spring", "sprintf", "spy", "sqrt", "sqrtm", "squeeze", "ss2tf", "sscanf", "stack", "stackedplot", "stairs", "standardizeMissing", "start", "start", "start", "start", "start", "start", "start", "start", "start", "start", "start", "start", "startat", "startMeasuring", "startsWith", "startup", "stats", "std", "std", "stem", "stem3", "step", "stepImpl", "stlread", "stlwrite", "stop", "stop", "stopasync", "stopMeasuring", "storeValueWhen", "str2double", "str2func", "str2mat", "str2num", "strcat", "strcmp", "strcmpi", "stream2", "stream3", "streamline", "streamparticles", "streamribbon", "streamslice", "streamtube", "strfind", "string", "string", "string", "string", "string", "string", "strings", "strip", "strjoin", "strjust", "strlength", "strmatch", "strncmp", "strncmpi", "strread", "strrep", "strsplit", "strtok", "strtrim", "struct", "struct2cell", "struct2table", "structfun", "strvcat", "sub2ind", "subgraph", "subplot", "subsasgn", "subset", "subsindex", "subspace", "subsref", "substruct", "subtract", "subvolume", "successors", "sum", "sum", "summary", "summary", "summer", "superclasses", "support", "supportPackageInstaller", "supports", "supportsMultipleInstanceImpl", "surf", "surf2patch", "surface", "surfaceArea", "surfc", "surfl", "surfnorm", "svd", "svds", "swapbytes", "sylvester", "symamd", "symbfact", "symmlq", "symrcm", "symvar", "synchronize", "synchronize", "syntax", "system", "table", "table2array", "table2cell", "table2struct", "table2timetable", "tabularTextDatastore", "tail", "tall", "TallDatastore", "tallrng", "tan", "tand", "tanh", "tar", "tcpclient", "teardown", "teardownSharedTestFixture", "teardownTestClass", "teardownTestMethod", "tempdir", "tempname", "testsuite", "tetramesh", "texlabel", "text", "textread", "textscan", "textwrap", "tfqmr", "then", "then", "then", "then", "then", "thetalim", "thetatickformat", "thetaticklabels", "thetaticks", "thingSpeakRead", "thingSpeakWrite", "throw", "throwAsCaller", "throwExceptionWhen", "tic", "Tiff", "Tiff.computeStrip", "Tiff.computeTile", "Tiff.currentDirectory", "Tiff.getTag", "Tiff.getTagNames", "Tiff.getVersion", "Tiff.isTiled", "Tiff.lastDirectory", "Tiff.nextDirectory", "Tiff.numberOfStrips", "Tiff.numberOfTiles", "Tiff.readEncodedStrip", "Tiff.readEncodedTile", "Tiff.readRGBAImage", "Tiff.readRGBAStrip", "Tiff.readRGBATile", "Tiff.rewriteDirectory", "Tiff.setDirectory", "Tiff.setSubDirectory", "Tiff.setTag", "Tiff.writeDirectory", "Tiff.writeEncodedStrip", "Tiff.writeEncodedTile", "time", "timeit", "timeofday", "timer", "timerange", "timerfind", "timerfindall", "times", "timeseries", "timetable", "timetable2table", "timezones", "title", "toc", "todatenum", "toeplitz", "toolboxdir", "topkrows", "toposort", "trace", "transclosure", "transform", "TransformedDatastore", "translate", "transpose", "transreduction", "trapz", "treelayout", "treeplot", "triangulation", "triangulation", "tril", "trimesh", "triplequad", "triplot", "TriRep", "TriRep", "TriScatteredInterp", "TriScatteredInterp", "trisurf", "triu", "true", "tscollection", "tsdata.event", "tsearchn", "turningdist", "type", "type", "typecast", "tzoffset", "uialert", "uiaxes", "uibutton", "uibuttongroup", "uicheckbox", "uiconfirm", "uicontextmenu", "uicontrol", "uidatepicker", "uidropdown", "uieditfield", "uifigure", "uigauge", "uigetdir", "uigetfile", "uigetpref", "uigridlayout", "uiimage", "uiimport", "uiknob", "uilabel", "uilamp", "uilistbox", "uimenu", "uint16", "uint32", "uint64", "uint8", "uiopen", "uipanel", "uiprogressdlg", "uipushtool", "uiputfile", "uiradiobutton", "uiresume", "uisave", "uisetcolor", "uisetfont", "uisetpref", "uislider", "uispinner", "uistack", "uiswitch", "uitab", "uitabgroup", "uitable", "uitextarea", "uitogglebutton", "uitoggletool", "uitoolbar", "uitree", "uitreenode", "uiwait", "uminus", "underlyingValue", "undocheckout", "unicode2native", "union", "union", "unique", "uniquetol", "unix", "unloadlibrary", "unmesh", "unmkpp", "unregisterallevents", "unregisterevent", "unstack", "untar", "unwrap", "unzip", "updateDependencies", "updateImpl", "upgradePreviouslyInstalledSupportPackages", "uplus", "upper", "urlread", "urlwrite", "usejava", "userpath", "validate", "validate", "validate", "validate", "validateattributes", "validateFunctionSignaturesJSON", "validateInputsImpl", "validatePropertiesImpl", "validatestring", "ValueIterator", "values", "vander", "var", "var", "varargin", "varargout", "varfun", "vartype", "vecnorm", "vectorize", "ver", "verctrl", "verifyAccessed", "verifyCalled", "verifyClass", "verifyEmpty", "verifyEqual", "verifyError", "verifyFail", "verifyFalse", "verifyGreaterThan", "verifyGreaterThanOrEqual", "verifyInstanceOf", "verifyLength", "verifyLessThan", "verifyLessThanOrEqual", "verifyMatches", "verifyNotAccessed", "verifyNotCalled", "verifyNotEmpty", "verifyNotEqual", "verifyNotSameHandle", "verifyNotSet", "verifyNumElements", "verifyReturnsTrue", "verifySameHandle", "verifySet", "verifySize", "verifySubstring", "verifyThat", "verifyTrue", "verifyUsing", "verifyWarning", "verifyWarningFree", "verLessThan", "version", "vertcat", "vertcat", "vertcat", "vertexAttachments", "vertexAttachments", "vertexNormal", "VideoReader", "VideoWriter", "view", "viewmtx", "visdiff", "volume", "volumebounds", "voronoi", "voronoiDiagram", "voronoiDiagram", "voronoin", "wait", "waitbar", "waitfor", "waitforbuttonpress", "warndlg", "warning", "waterfall", "web", "weboptions", "webread", "websave", "webwrite", "week", "weekday", "what", "whatsnew", "when", "when", "when", "which", "while", "whitebg", "who", "who", "whos", "whos", "width", "wilkinson", "winopen", "winqueryreg", "winter", "withAnyInputs", "withExactInputs", "withNargout", "withtol", "wordcloud", "write", "write", "write", "writecell", "writeChecksum", "writeCol", "writeComment", "writeDate", "writeHistory", "writeImg", "writeKey", "writeKeyUnit", "writematrix", "writetable", "writetimetable", "writeVideo", "xcorr", "xcov", "xlabel", "xlim", "xline", "xlsfinfo", "xlsread", "xlswrite", "xmlread", "xmlwrite", "xor", "xor", "xslt", "xtickangle", "xtickformat", "xticklabels", "xticks", "year", "years", "ylabel", "ylim", "yline", "ymd", "ytickangle", "ytickformat", "yticklabels", "yticks", "yyaxis", "yyyymmdd", "zeros", "zip", "zlabel", "zlim", "zoom", "zoomInteraction", "ztickangle", "ztickformat", "zticklabels", "zticks"] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/keywords.rb new file mode 100644 index 0000000..2324705 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/matlab/keywords.rb @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# DO NOT EDIT + +# This file is automatically generated by `rake builtins:matlab`. +# See tasks/builtins/matlab.rake for more info. + +module Rouge + module Lexers + def Matlab.builtins + @builtins ||= Set.new ["abs", "accumarray", "acos", "acosd", "acosh", "acot", "acotd", "acoth", "acsc", "acscd", "acsch", "actxcontrol", "actxcontrollist", "actxcontrolselect", "actxGetRunningServer", "actxserver", "add", "addboundary", "addcats", "addCause", "addClass", "addCondition", "addConditionsFrom", "addConstructor", "addCorrection", "addedge", "addevent", "addFields", "addFields", "addFile", "addFolderIncludingChildFiles", "addFunction", "addLabel", "addlistener", "addMethod", "addmulti", "addnode", "addOptional", "addParameter", "addParamValue", "addPath", "addpath", "addPlugin", "addpoints", "addpref", "addprop", "addprop", "addproperty", "addProperty", "addReference", "addRequired", "addsample", "addsampletocollection", "addShortcut", "addShutdownFile", "addStartupFile", "addTeardown", "addTeardown", "addtodate", "addToolbarExplorationButtons", "addts", "addvars", "adjacency", "airy", "align", "alim", "all", "allchild", "allowModelReferenceDiscreteSampleTimeInheritanceImpl", "alpha", "alphamap", "alphaShape", "alphaSpectrum", "alphaTriangulation", "amd", "analyzeCodeCompatibility", "ancestor", "and", "angle", "animatedline", "annotation", "ans", "any", "appdesigner", "append", "append", "applyFixture", "applyFixture", "area", "area", "area", "array2table", "array2timetable", "arrayfun", "ascii", "asec", "asecd", "asech", "asin", "asind", "asinh", "assert", "assertAccessed", "assertCalled", "assertClass", "assertEmpty", "assertEqual", "assertError", "assertFail", "assertFalse", "assertGreaterThan", "assertGreaterThanOrEqual", "assertInstanceOf", "assertLength", "assertLessThan", "assertLessThanOrEqual", "assertMatches", "assertNotAccessed", "assertNotCalled", "assertNotEmpty", "assertNotEqual", "assertNotSameHandle", "assertNotSet", "assertNumElements", "assertReturnsTrue", "assertSameHandle", "assertSet", "assertSize", "assertSubstring", "assertThat", "assertTrue", "assertUsing", "assertWarning", "assertWarningFree", "assignin", "assignOutputsWhen", "assumeAccessed", "assumeCalled", "assumeClass", "assumeEmpty", "assumeEqual", "assumeError", "assumeFail", "assumeFalse", "assumeGreaterThan", "assumeGreaterThanOrEqual", "assumeInstanceOf", "assumeLength", "assumeLessThan", "assumeLessThanOrEqual", "assumeMatches", "assumeNotAccessed", "assumeNotCalled", "assumeNotEmpty", "assumeNotEqual", "assumeNotSameHandle", "assumeNotSet", "assumeNumElements", "assumeReturnsTrue", "assumeSameHandle", "assumeSet", "assumeSize", "assumeSubstring", "assumeThat", "assumeTrue", "assumeUsing", "assumeWarning", "assumeWarningFree", "atan", "atan2", "atan2d", "atand", "atanh", "audiodevinfo", "audioinfo", "audioplayer", "audioread", "audiorecorder", "audiowrite", "autumn", "aviinfo", "axes", "axis", "axtoolbar", "axtoolbarbtn", "balance", "bandwidth", "bar", "bar3", "bar3h", "barh", "barycentricToCartesian", "baryToCart", "base2dec", "batchStartupOptionUsed", "bctree", "beep", "BeginInvoke", "bench", "besselh", "besseli", "besselj", "besselk", "bessely", "beta", "betainc", "betaincinv", "betaln", "between", "bfsearch", "bicg", "bicgstab", "bicgstabl", "biconncomp", "bin2dec", "binary", "binscatter", "bitand", "bitcmp", "bitget", "bitnot", "bitor", "bitset", "bitshift", "bitxor", "blanks", "blkdiag", "bone", "boundary", "boundary", "boundaryFacets", "boundaryshape", "boundingbox", "bounds", "box", "break", "brighten", "brush", "bsxfun", "build", "builddocsearchdb", "builtin", "bvp4c", "bvp5c", "bvpget", "bvpinit", "bvpset", "bvpxtend", "caldays", "caldiff", "calendar", "calendarDuration", "calllib", "callSoapService", "calmonths", "calquarters", "calweeks", "calyears", "camdolly", "cameratoolbar", "camlight", "camlookat", "camorbit", "campan", "campos", "camproj", "camroll", "camtarget", "camup", "camva", "camzoom", "cancel", "cancelled", "cart2pol", "cart2sph", "cartesianToBarycentric", "cartToBary", "cast", "cat", "cat", "categorical", "categories", "caxis", "cd", "cd", "cdf2rdf", "cdfepoch", "cdfinfo", "cdflib", "cdflib.close", "cdflib.closeVar", "cdflib.computeEpoch", "cdflib.computeEpoch16", "cdflib.create", "cdflib.createAttr", "cdflib.createVar", "cdflib.delete", "cdflib.deleteAttr", "cdflib.deleteAttrEntry", "cdflib.deleteAttrgEntry", "cdflib.deleteVar", "cdflib.deleteVarRecords", "cdflib.epoch16Breakdown", "cdflib.epochBreakdown", "cdflib.getAttrEntry", "cdflib.getAttrgEntry", "cdflib.getAttrMaxEntry", "cdflib.getAttrMaxgEntry", "cdflib.getAttrName", "cdflib.getAttrNum", "cdflib.getAttrScope", "cdflib.getCacheSize", "cdflib.getChecksum", "cdflib.getCompression", "cdflib.getCompressionCacheSize", "cdflib.getConstantNames", "cdflib.getConstantValue", "cdflib.getCopyright", "cdflib.getFileBackward", "cdflib.getFormat", "cdflib.getLibraryCopyright", "cdflib.getLibraryVersion", "cdflib.getMajority", "cdflib.getName", "cdflib.getNumAttrEntries", "cdflib.getNumAttrgEntries", "cdflib.getNumAttributes", "cdflib.getNumgAttributes", "cdflib.getReadOnlyMode", "cdflib.getStageCacheSize", "cdflib.getValidate", "cdflib.getVarAllocRecords", "cdflib.getVarBlockingFactor", "cdflib.getVarCacheSize", "cdflib.getVarCompression", "cdflib.getVarData", "cdflib.getVarMaxAllocRecNum", "cdflib.getVarMaxWrittenRecNum", "cdflib.getVarName", "cdflib.getVarNum", "cdflib.getVarNumRecsWritten", "cdflib.getVarPadValue", "cdflib.getVarRecordData", "cdflib.getVarReservePercent", "cdflib.getVarsMaxWrittenRecNum", "cdflib.getVarSparseRecords", "cdflib.getVersion", "cdflib.hyperGetVarData", "cdflib.hyperPutVarData", "cdflib.inquire", "cdflib.inquireAttr", "cdflib.inquireAttrEntry", "cdflib.inquireAttrgEntry", "cdflib.inquireVar", "cdflib.open", "cdflib.putAttrEntry", "cdflib.putAttrgEntry", "cdflib.putVarData", "cdflib.putVarRecordData", "cdflib.renameAttr", "cdflib.renameVar", "cdflib.setCacheSize", "cdflib.setChecksum", "cdflib.setCompression", "cdflib.setCompressionCacheSize", "cdflib.setFileBackward", "cdflib.setFormat", "cdflib.setMajority", "cdflib.setReadOnlyMode", "cdflib.setStageCacheSize", "cdflib.setValidate", "cdflib.setVarAllocBlockRecords", "cdflib.setVarBlockingFactor", "cdflib.setVarCacheSize", "cdflib.setVarCompression", "cdflib.setVarInitialRecs", "cdflib.setVarPadValue", "cdflib.SetVarReservePercent", "cdflib.setVarsCacheSize", "cdflib.setVarSparseRecords", "cdfread", "cdfwrite", "ceil", "cell", "cell2mat", "cell2struct", "cell2table", "celldisp", "cellfun", "cellplot", "cellstr", "centrality", "centroid", "cgs", "changeFields", "changeFields", "char", "char", "checkcode", "checkin", "checkout", "chol", "cholupdate", "choose", "circshift", "circumcenter", "circumcenters", "cla", "clabel", "class", "classdef", "classUnderlying", "clc", "clear", "clear", "clearAllMemoizedCaches", "clearCache", "clearMockHistory", "clearPersonalValue", "clearpoints", "clearTemporaryValue", "clearvars", "clf", "clibgen.buildInterface", "clibgen.ClassDefinition", "clibgen.ConstructorDefinition", "clibgen.EnumDefinition", "clibgen.FunctionDefinition", "clibgen.generateLibraryDefinition", "clibgen.LibraryDefinition", "clibgen.MethodDefinition", "clibgen.PropertyDefinition", "clibRelease", "clipboard", "clock", "clone", "close", "close", "close", "close", "close", "closeFile", "closereq", "cmopts", "cmpermute", "cmunique", "CodeCompatibilityAnalysis", "codeCompatibilityReport", "colamd", "collapse", "colon", "colorbar", "colorcube", "colordef", "colormap", "ColorSpec", "colperm", "COM", "com.mathworks.engine.MatlabEngine", "com.mathworks.matlab.types.CellStr", "com.mathworks.matlab.types.Complex", "com.mathworks.matlab.types.HandleObject", "com.mathworks.matlab.types.Struct", "combine", "Combine", "CombinedDatastore", "comet", "comet3", "compan", "compass", "complete", "complete", "complete", "complete", "complete", "complete", "complete", "complex", "compose", "computer", "cond", "condeig", "condensation", "condest", "coneplot", "conj", "conncomp", "containers.Map", "contains", "continue", "contour", "contour3", "contourc", "contourf", "contourslice", "contrast", "conv", "conv2", "convert", "convert", "convert", "convertCharsToStrings", "convertContainedStringsToChars", "convertLike", "convertStringsToChars", "convertvars", "convexHull", "convexHull", "convhull", "convhull", "convhulln", "convn", "cool", "copper", "copy", "copyElement", "copyfile", "copyHDU", "copyobj", "copyTo", "corrcoef", "cos", "cosd", "cosh", "cospi", "cot", "cotd", "coth", "count", "countcats", "countEachLabel", "cov", "cplxpair", "cputime", "createCategory", "createClassFromWsdl", "createFile", "createImg", "createLabel", "createMock", "createSampleTime", "createSharedTestFixture", "createSoapMessage", "createTbl", "createTestClassInstance", "createTestMethodInstance", "criticalAlpha", "cross", "csc", "cscd", "csch", "csvread", "csvwrite", "ctranspose", "cummax", "cummin", "cumprod", "cumsum", "cumtrapz", "curl", "currentProject", "customverctrl", "cylinder", "daqread", "daspect", "datacursormode", "datastore", "dataTipInteraction", "dataTipTextRow", "date", "datenum", "dateshift", "datestr", "datetick", "datetime", "datevec", "day", "days", "dbclear", "dbcont", "dbdown", "dblquad", "dbmex", "dbquit", "dbstack", "dbstatus", "dbstep", "dbstop", "dbtype", "dbup", "dde23", "ddeget", "ddensd", "ddesd", "ddeset", "deal", "deblank", "dec2base", "dec2bin", "dec2hex", "decic", "decomposition", "deconv", "defineArgument", "defineArgument", "defineArgument", "defineOutput", "defineOutput", "deg2rad", "degree", "del2", "delaunay", "delaunayn", "DelaunayTri", "DelaunayTri", "delaunayTriangulation", "delegateTo", "delegateTo", "delete", "delete", "delete", "delete", "delete", "deleteCol", "deleteFile", "deleteHDU", "deleteKey", "deleteproperty", "deleteRecord", "deleteRows", "delevent", "delimitedTextImportOptions", "delsample", "delsamplefromcollection", "demo", "det", "details", "detectImportOptions", "detrend", "detrend", "deval", "dfsearch", "diag", "diagnose", "dialog", "diary", "diff", "diffuse", "digraph", "dir", "dir", "disableDefaultInteractivity", "discretize", "disp", "disp", "disp", "display", "displayEmptyObject", "displayNonScalarObject", "displayScalarHandleToDeletedObject", "displayScalarObject", "dissect", "distances", "dither", "divergence", "dlmread", "dlmwrite", "dmperm", "doc", "docsearch", "done", "done", "dos", "dot", "double", "drag", "dragrect", "drawnow", "dsearchn", "duration", "dynamicprops", "echo", "echodemo", "edgeAttachments", "edgeAttachments", "edgecount", "edges", "edges", "edit", "eig", "eigs", "ellipj", "ellipke", "ellipsoid", "empty", "enableDefaultInteractivity", "enableNETfromNetworkDrive", "enableservice", "end", "EndInvoke", "endsWith", "enumeration", "eomday", "eps", "eq", "eq", "equilibrate", "erase", "eraseBetween", "erf", "erfc", "erfcinv", "erfcx", "erfinv", "error", "errorbar", "errordlg", "etime", "etree", "etreeplot", "eval", "evalc", "evalin", "event.DynamicPropertyEvent", "event.EventData", "event.hasListener", "event.listener", "event.PropertyEvent", "event.proplistener", "eventlisteners", "events", "events", "exceltime", "Execute", "exist", "exit", "exp", "expand", "expectedContentLength", "expectedContentLength", "expint", "expm", "expm1", "export", "export2wsdlg", "exportsetupdlg", "extractAfter", "extractBefore", "extractBetween", "eye", "ezcontour", "ezcontourf", "ezmesh", "ezmeshc", "ezplot", "ezplot3", "ezpolar", "ezsurf", "ezsurfc", "faceNormal", "faceNormals", "factor", "factorial", "false", "fatalAssertAccessed", "fatalAssertCalled", "fatalAssertClass", "fatalAssertEmpty", "fatalAssertEqual", "fatalAssertError", "fatalAssertFail", "fatalAssertFalse", "fatalAssertGreaterThan", "fatalAssertGreaterThanOrEqual", "fatalAssertInstanceOf", "fatalAssertLength", "fatalAssertLessThan", "fatalAssertLessThanOrEqual", "fatalAssertMatches", "fatalAssertNotAccessed", "fatalAssertNotCalled", "fatalAssertNotEmpty", "fatalAssertNotEqual", "fatalAssertNotSameHandle", "fatalAssertNotSet", "fatalAssertNumElements", "fatalAssertReturnsTrue", "fatalAssertSameHandle", "fatalAssertSet", "fatalAssertSize", "fatalAssertSubstring", "fatalAssertThat", "fatalAssertTrue", "fatalAssertUsing", "fatalAssertWarning", "fatalAssertWarningFree", "fclose", "fclose", "fcontour", "feather", "featureEdges", "featureEdges", "feof", "ferror", "feval", "Feval", "feval", "fewerbins", "fft", "fft2", "fftn", "fftshift", "fftw", "fgetl", "fgetl", "fgets", "fgets", "fieldnames", "figure", "figurepalette", "fileattrib", "fileDatastore", "filemarker", "fileMode", "fileName", "fileparts", "fileread", "filesep", "fill", "fill3", "fillmissing", "filloutliers", "filter", "filter", "filter2", "fimplicit", "fimplicit3", "find", "findall", "findCategory", "findedge", "findEvent", "findfigs", "findFile", "findgroups", "findLabel", "findnode", "findobj", "findobj", "findprop", "findstr", "finish", "fitsdisp", "fitsinfo", "fitsread", "fitswrite", "fix", "fixedWidthImportOptions", "flag", "flintmax", "flip", "flipdim", "flipedge", "fliplr", "flipud", "floor", "flow", "fmesh", "fminbnd", "fminsearch", "fopen", "fopen", "for", "format", "fplot", "fplot3", "fprintf", "fprintf", "frame2im", "fread", "fread", "freeBoundary", "freeBoundary", "freqspace", "frewind", "fscanf", "fscanf", "fseek", "fsurf", "ftell", "ftp", "full", "fullfile", "func2str", "function", "functions", "FunctionTestCase", "functiontests", "funm", "fwrite", "fwrite", "fzero", "gallery", "gamma", "gammainc", "gammaincinv", "gammaln", "gather", "gca", "gcbf", "gcbo", "gcd", "gcf", "gcmr", "gco", "ge", "genpath", "genvarname", "geoaxes", "geobasemap", "geobubble", "geodensityplot", "geolimits", "geoplot", "geoscatter", "geotickformat", "get", "get", "get", "get", "get", "get", "get", "get", "get", "get", "get", "getabstime", "getabstime", "getAColParms", "getappdata", "getaudiodata", "getBColParms", "GetCharArray", "getClass", "getColName", "getColType", "getConstantValue", "getCurrentTime", "getData", "getData", "getData", "getData", "getData", "getdatasamples", "getdatasamplesize", "getDiagnosticFor", "getDiagnosticFor", "getDiscreteStateImpl", "getDiscreteStateSpecificationImpl", "getdisp", "getenv", "getEqColType", "getfield", "getFields", "getFields", "getFileFormats", "getFooter", "getframe", "GetFullMatrix", "getGlobalNamesImpl", "getHdrSpace", "getHDUnum", "getHDUtype", "getHeader", "getHeaderImpl", "getIconImpl", "getImgSize", "getImgType", "getImpulseResponseLengthImpl", "getInputDimensionConstraintImpl", "getinterpmethod", "getLocation", "getLocation", "getMockHistory", "getNegativeDiagnosticFor", "getnext", "getNumCols", "getNumHDUs", "getNumInputs", "getNumInputsImpl", "getNumOutputs", "getNumOutputsImpl", "getNumRows", "getOpenFiles", "getOutputDataTypeImpl", "getOutputDimensionConstraintImpl", "getOutputSizeImpl", "getParameter", "getParameter", "getParameter", "getpixelposition", "getplayer", "getpoints", "getPostActValString", "getPostConditionString", "getPostDescriptionString", "getPostExpValString", "getPreDescriptionString", "getpref", "getProfiles", "getPropertyGroups", "getPropertyGroupsImpl", "getqualitydesc", "getReasonPhrase", "getReasonPhrase", "getReport", "getsamples", "getSampleTime", "getSampleTimeImpl", "getsampleusingtime", "getsampleusingtime", "getSharedTestFixtures", "getSimulateUsingImpl", "getSimulinkFunctionNamesImpl", "gettimeseriesnames", "getTimeStr", "gettsafteratevent", "gettsafterevent", "gettsatevent", "gettsbeforeatevent", "gettsbeforeevent", "gettsbetweenevents", "GetVariable", "getvaropts", "getVersion", "GetWorkspaceData", "ginput", "global", "gmres", "gobjects", "gplot", "grabcode", "gradient", "graph", "GraphPlot", "gray", "graymon", "grid", "griddata", "griddatan", "griddedInterpolant", "groot", "groupcounts", "groupsummary", "grouptransform", "gsvd", "gt", "gtext", "guidata", "guide", "guihandles", "gunzip", "gzip", "H5.close", "H5.garbage_collect", "H5.get_libversion", "H5.open", "H5.set_free_list_limits", "H5A.close", "H5A.create", "H5A.delete", "H5A.get_info", "H5A.get_name", "H5A.get_space", "H5A.get_type", "H5A.iterate", "H5A.open", "H5A.open_by_idx", "H5A.open_by_name", "H5A.read", "H5A.write", "h5create", "H5D.close", "H5D.create", "H5D.get_access_plist", "H5D.get_create_plist", "H5D.get_offset", "H5D.get_space", "H5D.get_space_status", "H5D.get_storage_size", "H5D.get_type", "H5D.open", "H5D.read", "H5D.set_extent", "H5D.vlen_get_buf_size", "H5D.write", "h5disp", "H5DS.attach_scale", "H5DS.detach_scale", "H5DS.get_label", "H5DS.get_num_scales", "H5DS.get_scale_name", "H5DS.is_scale", "H5DS.iterate_scales", "H5DS.set_label", "H5DS.set_scale", "H5E.clear", "H5E.get_major", "H5E.get_minor", "H5E.walk", "H5F.close", "H5F.create", "H5F.flush", "H5F.get_access_plist", "H5F.get_create_plist", "H5F.get_filesize", "H5F.get_freespace", "H5F.get_info", "H5F.get_mdc_config", "H5F.get_mdc_hit_rate", "H5F.get_mdc_size", "H5F.get_name", "H5F.get_obj_count", "H5F.get_obj_ids", "H5F.is_hdf5", "H5F.mount", "H5F.open", "H5F.reopen", "H5F.set_mdc_config", "H5F.unmount", "H5G.close", "H5G.create", "H5G.get_info", "H5G.open", "H5I.dec_ref", "H5I.get_file_id", "H5I.get_name", "H5I.get_ref", "H5I.get_type", "H5I.inc_ref", "H5I.is_valid", "h5info", "H5L.copy", "H5L.create_external", "H5L.create_hard", "H5L.create_soft", "H5L.delete", "H5L.exists", "H5L.get_info", "H5L.get_name_by_idx", "H5L.get_val", "H5L.iterate", "H5L.iterate_by_name", "H5L.move", "H5L.visit", "H5L.visit_by_name", "H5ML.compare_values", "H5ML.get_constant_names", "H5ML.get_constant_value", "H5ML.get_function_names", "H5ML.get_mem_datatype", "H5ML.hoffset", "H5ML.sizeof", "H5O.close", "H5O.copy", "H5O.get_comment", "H5O.get_comment_by_name", "H5O.get_info", "H5O.link", "H5O.open", "H5O.open_by_idx", "H5O.set_comment", "H5O.set_comment_by_name", "H5O.visit", "H5O.visit_by_name", "H5P.all_filters_avail", "H5P.close", "H5P.close_class", "H5P.copy", "H5P.create", "H5P.equal", "H5P.exist", "H5P.fill_value_defined", "H5P.get", "H5P.get_alignment", "H5P.get_alloc_time", "H5P.get_attr_creation_order", "H5P.get_attr_phase_change", "H5P.get_btree_ratios", "H5P.get_char_encoding", "H5P.get_chunk", "H5P.get_chunk_cache", "H5P.get_class", "H5P.get_class_name", "H5P.get_class_parent", "H5P.get_copy_object", "H5P.get_create_intermediate_group", "H5P.get_driver", "H5P.get_edc_check", "H5P.get_external", "H5P.get_external_count", "H5P.get_family_offset", "H5P.get_fapl_core", "H5P.get_fapl_family", "H5P.get_fapl_multi", "H5P.get_fclose_degree", "H5P.get_fill_time", "H5P.get_fill_value", "H5P.get_filter", "H5P.get_filter_by_id", "H5P.get_gc_references", "H5P.get_hyper_vector_size", "H5P.get_istore_k", "H5P.get_layout", "H5P.get_libver_bounds", "H5P.get_link_creation_order", "H5P.get_link_phase_change", "H5P.get_mdc_config", "H5P.get_meta_block_size", "H5P.get_multi_type", "H5P.get_nfilters", "H5P.get_nprops", "H5P.get_sieve_buf_size", "H5P.get_size", "H5P.get_sizes", "H5P.get_small_data_block_size", "H5P.get_sym_k", "H5P.get_userblock", "H5P.get_version", "H5P.isa_class", "H5P.iterate", "H5P.modify_filter", "H5P.remove_filter", "H5P.set", "H5P.set_alignment", "H5P.set_alloc_time", "H5P.set_attr_creation_order", "H5P.set_attr_phase_change", "H5P.set_btree_ratios", "H5P.set_char_encoding", "H5P.set_chunk", "H5P.set_chunk_cache", "H5P.set_copy_object", "H5P.set_create_intermediate_group", "H5P.set_deflate", "H5P.set_edc_check", "H5P.set_external", "H5P.set_family_offset", "H5P.set_fapl_core", "H5P.set_fapl_family", "H5P.set_fapl_log", "H5P.set_fapl_multi", "H5P.set_fapl_sec2", "H5P.set_fapl_split", "H5P.set_fapl_stdio", "H5P.set_fclose_degree", "H5P.set_fill_time", "H5P.set_fill_value", "H5P.set_filter", "H5P.set_fletcher32", "H5P.set_gc_references", "H5P.set_hyper_vector_size", "H5P.set_istore_k", "H5P.set_layout", "H5P.set_libver_bounds", "H5P.set_link_creation_order", "H5P.set_link_phase_change", "H5P.set_mdc_config", "H5P.set_meta_block_size", "H5P.set_multi_type", "H5P.set_nbit", "H5P.set_scaleoffset", "H5P.set_shuffle", "H5P.set_sieve_buf_size", "H5P.set_sizes", "H5P.set_small_data_block_size", "H5P.set_sym_k", "H5P.set_userblock", "H5R.create", "H5R.dereference", "H5R.get_name", "H5R.get_obj_type", "H5R.get_region", "h5read", "h5readatt", "H5S.close", "H5S.copy", "H5S.create", "H5S.create_simple", "H5S.extent_copy", "H5S.get_select_bounds", "H5S.get_select_elem_npoints", "H5S.get_select_elem_pointlist", "H5S.get_select_hyper_blocklist", "H5S.get_select_hyper_nblocks", "H5S.get_select_npoints", "H5S.get_select_type", "H5S.get_simple_extent_dims", "H5S.get_simple_extent_ndims", "H5S.get_simple_extent_npoints", "H5S.get_simple_extent_type", "H5S.is_simple", "H5S.offset_simple", "H5S.select_all", "H5S.select_elements", "H5S.select_hyperslab", "H5S.select_none", "H5S.select_valid", "H5S.set_extent_none", "H5S.set_extent_simple", "H5T.array_create", "H5T.close", "H5T.commit", "H5T.committed", "H5T.copy", "H5T.create", "H5T.detect_class", "H5T.enum_create", "H5T.enum_insert", "H5T.enum_nameof", "H5T.enum_valueof", "H5T.equal", "H5T.get_array_dims", "H5T.get_array_ndims", "H5T.get_class", "H5T.get_create_plist", "H5T.get_cset", "H5T.get_ebias", "H5T.get_fields", "H5T.get_inpad", "H5T.get_member_class", "H5T.get_member_index", "H5T.get_member_name", "H5T.get_member_offset", "H5T.get_member_type", "H5T.get_member_value", "H5T.get_native_type", "H5T.get_nmembers", "H5T.get_norm", "H5T.get_offset", "H5T.get_order", "H5T.get_pad", "H5T.get_precision", "H5T.get_sign", "H5T.get_size", "H5T.get_strpad", "H5T.get_super", "H5T.get_tag", "H5T.insert", "H5T.is_variable_str", "H5T.lock", "H5T.open", "H5T.pack", "H5T.set_cset", "H5T.set_ebias", "H5T.set_fields", "H5T.set_inpad", "H5T.set_norm", "H5T.set_offset", "H5T.set_order", "H5T.set_pad", "H5T.set_precision", "H5T.set_sign", "H5T.set_size", "H5T.set_strpad", "H5T.set_tag", "H5T.vlen_create", "h5write", "h5writeatt", "H5Z.filter_avail", "H5Z.get_filter_info", "hadamard", "handle", "hankel", "hasdata", "hasdata", "hasFactoryValue", "hasfile", "hasFrame", "hasnext", "hasPersonalValue", "hasTemporaryValue", "hdf5info", "hdf5read", "hdf5write", "hdfan", "hdfdf24", "hdfdfr8", "hdfh", "hdfhd", "hdfhe", "hdfhx", "hdfinfo", "hdfml", "hdfpt", "hdfread", "hdftool", "hdfv", "hdfvf", "hdfvh", "hdfvs", "head", "heatmap", "height", "help", "helpbrowser", "helpdesk", "helpdlg", "helpwin", "hess", "hex2dec", "hex2num", "hgexport", "hggroup", "hgload", "hgsave", "hgtransform", "hidden", "highlight", "hilb", "hist", "histc", "histcounts", "histcounts2", "histogram", "histogram2", "hms", "hold", "holes", "home", "horzcat", "horzcat", "horzcat", "hot", "hour", "hours", "hover", "hsv", "hsv2rgb", "hypot", "ichol", "idealfilter", "idivide", "ifft", "ifft2", "ifftn", "ifftshift", "ilu", "im2double", "im2frame", "im2java", "imag", "image", "imageDatastore", "imagesc", "imapprox", "imfinfo", "imformats", "imgCompress", "import", "importdata", "imread", "imresize", "imshow", "imtile", "imwrite", "incenter", "incenters", "incidence", "ind2rgb", "ind2sub", "indegree", "inedges", "Inf", "info", "infoImpl", "initialize", "initialize", "initialize", "initialize", "initialize", "initializeDatastore", "initializeDatastore", "inline", "inmem", "inner2outer", "innerjoin", "inOutStatus", "inpolygon", "input", "inputdlg", "inputname", "inputParser", "insertAfter", "insertATbl", "insertBefore", "insertBTbl", "insertCol", "insertImg", "insertRows", "inShape", "inspect", "instrcallback", "instrfind", "instrfindall", "int16", "int2str", "int32", "int64", "int8", "integral", "integral2", "integral3", "interp1", "interp1q", "interp2", "interp3", "interpft", "interpn", "interpstreamspeed", "intersect", "intersect", "intmax", "intmin", "inv", "invhilb", "invoke", "ipermute", "iqr", "is*", "isa", "isappdata", "isaUnderlying", "isbanded", "isbetween", "iscalendarduration", "iscategorical", "iscategory", "iscell", "iscellstr", "ischange", "ischar", "iscolumn", "iscom", "isCompatible", "isCompressedImg", "isConnected", "isdag", "isdatetime", "isdiag", "isdir", "isDiscreteStateSpecificationMutableImpl", "isDone", "isDoneImpl", "isdst", "isduration", "isEdge", "isempty", "isempty", "isenum", "isequal", "isequaln", "isequalwithequalnans", "isevent", "isfield", "isfile", "isfinite", "isfloat", "isfolder", "isfullfile", "isfullfile", "isgraphics", "ishandle", "ishermitian", "ishghandle", "ishold", "ishole", "isIllConditioned", "isInactivePropertyImpl", "isinf", "isInputComplexityMutableImpl", "isInputDataTypeMutableImpl", "isInputDirectFeedthroughImpl", "isInputSizeLockedImpl", "isInputSizeMutableImpl", "isinteger", "isinterface", "isInterior", "isinterior", "isisomorphic", "isjava", "isKey", "iskeyword", "isletter", "isLoaded", "islocalmax", "islocalmin", "isLocked", "islogical", "ismac", "ismatrix", "ismember", "ismembertol", "ismethod", "ismissing", "ismultigraph", "isnan", "isnat", "isNull", "isnumeric", "isobject", "isocaps", "isocolors", "isomorphism", "isonormals", "isordinal", "isosurface", "isoutlier", "isOutputComplexImpl", "isOutputFixedSizeImpl", "ispc", "isplaying", "ispref", "isprime", "isprop", "isprotected", "isreal", "isrecording", "isregular", "isrow", "isscalar", "issimplified", "issorted", "issortedrows", "isspace", "issparse", "isstr", "isstring", "isStringScalar", "isstrprop", "isstruct", "isstudent", "issymmetric", "istable", "istall", "istimetable", "istril", "istriu", "isTunablePropertyDataTypeMutableImpl", "isundefined", "isunix", "isvalid", "isvalid", "isvalid", "isvarname", "isvector", "isweekend", "javaaddpath", "javaArray", "javachk", "javaclasspath", "javaMethod", "javaMethodEDT", "javaObject", "javaObjectEDT", "javarmpath", "jet", "join", "join", "join", "jsondecode", "jsonencode", "juliandate", "keepMeasuring", "keyboard", "keys", "KeyValueDatastore", "KeyValueStore", "kron", "labeledge", "labelnode", "lag", "laplacian", "lasterr", "lasterror", "lastwarn", "layout", "lcm", "ldivide", "ldl", "le", "legend", "legendre", "length", "length", "length", "length", "lib.pointer", "libfunctions", "libfunctionsview", "libisloaded", "libpointer", "libstruct", "license", "light", "lightangle", "lighting", "lin2mu", "line", "lines", "LineSpec", "linkaxes", "linkdata", "linkprop", "linsolve", "linspace", "listdlg", "listener", "listfonts", "listModifiedFiles", "listRequiredFiles", "load", "load", "load", "loadlibrary", "loadobj", "loadObjectImpl", "localfunctions", "log", "log", "log", "log10", "log1p", "log2", "logical", "Logical", "loglog", "logm", "logspace", "lookfor", "lower", "ls", "lscov", "lsqminnorm", "lsqnonneg", "lsqr", "lt", "lu", "magic", "makehgtform", "mapreduce", "mapreducer", "mat2cell", "mat2str", "matchpairs", "material", "matfile", "matlab", "matlab", "matlab", "matlab.addons.disableAddon", "matlab.addons.enableAddon", "matlab.addons.install", "matlab.addons.installedAddons", "matlab.addons.isAddonEnabled", "matlab.addons.toolbox.installedToolboxes", "matlab.addons.toolbox.installToolbox", "matlab.addons.toolbox.packageToolbox", "matlab.addons.toolbox.toolboxVersion", "matlab.addons.toolbox.uninstallToolbox", "matlab.addons.uninstall", "matlab.apputil.create", "matlab.apputil.getInstalledAppInfo", "matlab.apputil.install", "matlab.apputil.package", "matlab.apputil.run", "matlab.apputil.uninstall", "matlab.codetools.requiredFilesAndProducts", "matlab.engine.connect_matlab", "matlab.engine.engineName", "matlab.engine.find_matlab", "matlab.engine.FutureResult", "matlab.engine.isEngineShared", "matlab.engine.MatlabEngine", "matlab.engine.shareEngine", "matlab.engine.start_matlab", "matlab.exception.JavaException", "matlab.exception.PyException", "matlab.graphics.Graphics", "matlab.graphics.GraphicsPlaceholder", "matlab.io.Datastore", "matlab.io.datastore.DsFileReader", "matlab.io.datastore.DsFileSet", "matlab.io.datastore.HadoopFileBased", "matlab.io.datastore.HadoopLocationBased", "matlab.io.datastore.Partitionable", "matlab.io.datastore.Shuffleable", "matlab.io.hdf4.sd", "matlab.io.hdf4.sd.attrInfo", "matlab.io.hdf4.sd.close", "matlab.io.hdf4.sd.create", "matlab.io.hdf4.sd.dimInfo", "matlab.io.hdf4.sd.endAccess", "matlab.io.hdf4.sd.fileInfo", "matlab.io.hdf4.sd.findAttr", "matlab.io.hdf4.sd.getCal", "matlab.io.hdf4.sd.getChunkInfo", "matlab.io.hdf4.sd.getCompInfo", "matlab.io.hdf4.sd.getDataStrs", "matlab.io.hdf4.sd.getDimID", "matlab.io.hdf4.sd.getDimScale", "matlab.io.hdf4.sd.getDimStrs", "matlab.io.hdf4.sd.getFilename", "matlab.io.hdf4.sd.getFillValue", "matlab.io.hdf4.sd.getInfo", "matlab.io.hdf4.sd.getRange", "matlab.io.hdf4.sd.idToRef", "matlab.io.hdf4.sd.idType", "matlab.io.hdf4.sd.isCoordVar", "matlab.io.hdf4.sd.isRecord", "matlab.io.hdf4.sd.nameToIndex", "matlab.io.hdf4.sd.nameToIndices", "matlab.io.hdf4.sd.readAttr", "matlab.io.hdf4.sd.readChunk", "matlab.io.hdf4.sd.readData", "matlab.io.hdf4.sd.refToIndex", "matlab.io.hdf4.sd.select", "matlab.io.hdf4.sd.setAttr", "matlab.io.hdf4.sd.setCal", "matlab.io.hdf4.sd.setChunk", "matlab.io.hdf4.sd.setCompress", "matlab.io.hdf4.sd.setDataStrs", "matlab.io.hdf4.sd.setDimName", "matlab.io.hdf4.sd.setDimScale", "matlab.io.hdf4.sd.setDimStrs", "matlab.io.hdf4.sd.setExternalFile", "matlab.io.hdf4.sd.setFillMode", "matlab.io.hdf4.sd.setFillValue", "matlab.io.hdf4.sd.setNBitDataSet", "matlab.io.hdf4.sd.setRange", "matlab.io.hdf4.sd.start", "matlab.io.hdf4.sd.writeChunk", "matlab.io.hdf4.sd.writeData", "matlab.io.hdfeos.gd", "matlab.io.hdfeos.gd.attach", "matlab.io.hdfeos.gd.close", "matlab.io.hdfeos.gd.compInfo", "matlab.io.hdfeos.gd.create", "matlab.io.hdfeos.gd.defBoxRegion", "matlab.io.hdfeos.gd.defComp", "matlab.io.hdfeos.gd.defDim", "matlab.io.hdfeos.gd.defField", "matlab.io.hdfeos.gd.defOrigin", "matlab.io.hdfeos.gd.defPixReg", "matlab.io.hdfeos.gd.defProj", "matlab.io.hdfeos.gd.defTile", "matlab.io.hdfeos.gd.defVrtRegion", "matlab.io.hdfeos.gd.detach", "matlab.io.hdfeos.gd.dimInfo", "matlab.io.hdfeos.gd.extractRegion", "matlab.io.hdfeos.gd.fieldInfo", "matlab.io.hdfeos.gd.getFillValue", "matlab.io.hdfeos.gd.getPixels", "matlab.io.hdfeos.gd.getPixValues", "matlab.io.hdfeos.gd.gridInfo", "matlab.io.hdfeos.gd.ij2ll", "matlab.io.hdfeos.gd.inqAttrs", "matlab.io.hdfeos.gd.inqDims", "matlab.io.hdfeos.gd.inqFields", "matlab.io.hdfeos.gd.inqGrid", "matlab.io.hdfeos.gd.interpolate", "matlab.io.hdfeos.gd.ll2ij", "matlab.io.hdfeos.gd.nEntries", "matlab.io.hdfeos.gd.open", "matlab.io.hdfeos.gd.originInfo", "matlab.io.hdfeos.gd.pixRegInfo", "matlab.io.hdfeos.gd.projInfo", "matlab.io.hdfeos.gd.readAttr", "matlab.io.hdfeos.gd.readBlkSomOffset", "matlab.io.hdfeos.gd.readField", "matlab.io.hdfeos.gd.readTile", "matlab.io.hdfeos.gd.regionInfo", "matlab.io.hdfeos.gd.setFillValue", "matlab.io.hdfeos.gd.setTileComp", "matlab.io.hdfeos.gd.sphereCodeToName", "matlab.io.hdfeos.gd.sphereNameToCode", "matlab.io.hdfeos.gd.tileInfo", "matlab.io.hdfeos.gd.writeAttr", "matlab.io.hdfeos.gd.writeBlkSomOffset", "matlab.io.hdfeos.gd.writeField", "matlab.io.hdfeos.gd.writeTile", "matlab.io.hdfeos.sw", "matlab.io.hdfeos.sw.attach", "matlab.io.hdfeos.sw.close", "matlab.io.hdfeos.sw.compInfo", "matlab.io.hdfeos.sw.create", "matlab.io.hdfeos.sw.defBoxRegion", "matlab.io.hdfeos.sw.defComp", "matlab.io.hdfeos.sw.defDataField", "matlab.io.hdfeos.sw.defDim", "matlab.io.hdfeos.sw.defDimMap", "matlab.io.hdfeos.sw.defGeoField", "matlab.io.hdfeos.sw.defTimePeriod", "matlab.io.hdfeos.sw.defVrtRegion", "matlab.io.hdfeos.sw.detach", "matlab.io.hdfeos.sw.dimInfo", "matlab.io.hdfeos.sw.extractPeriod", "matlab.io.hdfeos.sw.extractRegion", "matlab.io.hdfeos.sw.fieldInfo", "matlab.io.hdfeos.sw.geoMapInfo", "matlab.io.hdfeos.sw.getFillValue", "matlab.io.hdfeos.sw.idxMapInfo", "matlab.io.hdfeos.sw.inqAttrs", "matlab.io.hdfeos.sw.inqDataFields", "matlab.io.hdfeos.sw.inqDims", "matlab.io.hdfeos.sw.inqGeoFields", "matlab.io.hdfeos.sw.inqIdxMaps", "matlab.io.hdfeos.sw.inqMaps", "matlab.io.hdfeos.sw.inqSwath", "matlab.io.hdfeos.sw.mapInfo", "matlab.io.hdfeos.sw.nEntries", "matlab.io.hdfeos.sw.open", "matlab.io.hdfeos.sw.periodInfo", "matlab.io.hdfeos.sw.readAttr", "matlab.io.hdfeos.sw.readField", "matlab.io.hdfeos.sw.regionInfo", "matlab.io.hdfeos.sw.setFillValue", "matlab.io.hdfeos.sw.writeAttr", "matlab.io.hdfeos.sw.writeField", "matlab.io.MatFile", "matlab.io.saveVariablesToScript", "matlab.lang.correction.AppendArgumentsCorrection", "matlab.lang.makeUniqueStrings", "matlab.lang.makeValidName", "matlab.lang.OnOffSwitchState", "matlab.mex.MexHost", "matlab.mixin.Copyable", "matlab.mixin.CustomDisplay", "matlab.mixin.CustomDisplay.convertDimensionsToString", "matlab.mixin.CustomDisplay.displayPropertyGroups", "matlab.mixin.CustomDisplay.getClassNameForHeader", "matlab.mixin.CustomDisplay.getDeletedHandleText", "matlab.mixin.CustomDisplay.getDetailedFooter", "matlab.mixin.CustomDisplay.getDetailedHeader", "matlab.mixin.CustomDisplay.getHandleText", "matlab.mixin.CustomDisplay.getSimpleHeader", "matlab.mixin.Heterogeneous", "matlab.mixin.Heterogeneous.getDefaultScalarElement", "matlab.mixin.SetGet", "matlab.mixin.SetGetExactNames", "matlab.mixin.util.PropertyGroup", "matlab.mock.actions.AssignOutputs", "matlab.mock.actions.Invoke", "matlab.mock.actions.ReturnStoredValue", "matlab.mock.actions.StoreValue", "matlab.mock.actions.ThrowException", "matlab.mock.AnyArguments", "matlab.mock.constraints.Occurred", "matlab.mock.constraints.WasAccessed", "matlab.mock.constraints.WasCalled", "matlab.mock.constraints.WasSet", "matlab.mock.history.MethodCall", "matlab.mock.history.PropertyAccess", "matlab.mock.history.PropertyModification", "matlab.mock.history.SuccessfulMethodCall", "matlab.mock.history.SuccessfulPropertyAccess", "matlab.mock.history.SuccessfulPropertyModification", "matlab.mock.history.UnsuccessfulMethodCall", "matlab.mock.history.UnsuccessfulPropertyAccess", "matlab.mock.history.UnsuccessfulPropertyModification", "matlab.mock.InteractionHistory", "matlab.mock.InteractionHistory.forMock", "matlab.mock.MethodCallBehavior", "matlab.mock.PropertyBehavior", "matlab.mock.PropertyGetBehavior", "matlab.mock.PropertySetBehavior", "matlab.mock.TestCase", "matlab.mock.TestCase.forInteractiveUse", "matlab.net.ArrayFormat", "matlab.net.base64decode", "matlab.net.base64encode", "matlab.net.http.AuthenticationScheme", "matlab.net.http.AuthInfo", "matlab.net.http.Cookie", "matlab.net.http.CookieInfo", "matlab.net.http.CookieInfo.collectFromLog", "matlab.net.http.Credentials", "matlab.net.http.Disposition", "matlab.net.http.field.AcceptField", "matlab.net.http.field.AuthenticateField", "matlab.net.http.field.AuthenticationInfoField", "matlab.net.http.field.AuthorizationField", "matlab.net.http.field.ContentDispositionField", "matlab.net.http.field.ContentLengthField", "matlab.net.http.field.ContentLocationField", "matlab.net.http.field.ContentTypeField", "matlab.net.http.field.CookieField", "matlab.net.http.field.DateField", "matlab.net.http.field.GenericField", "matlab.net.http.field.GenericParameterizedField", "matlab.net.http.field.HTTPDateField", "matlab.net.http.field.IntegerField", "matlab.net.http.field.LocationField", "matlab.net.http.field.MediaRangeField", "matlab.net.http.field.SetCookieField", "matlab.net.http.field.URIReferenceField", "matlab.net.http.HeaderField", "matlab.net.http.HeaderField.displaySubclasses", "matlab.net.http.HTTPException", "matlab.net.http.HTTPOptions", "matlab.net.http.io.BinaryConsumer", "matlab.net.http.io.ContentConsumer", "matlab.net.http.io.ContentProvider", "matlab.net.http.io.FileConsumer", "matlab.net.http.io.FileProvider", "matlab.net.http.io.FormProvider", "matlab.net.http.io.GenericConsumer", "matlab.net.http.io.GenericProvider", "matlab.net.http.io.ImageConsumer", "matlab.net.http.io.ImageProvider", "matlab.net.http.io.JSONConsumer", "matlab.net.http.io.JSONProvider", "matlab.net.http.io.MultipartConsumer", "matlab.net.http.io.MultipartFormProvider", "matlab.net.http.io.MultipartProvider", "matlab.net.http.io.StringConsumer", "matlab.net.http.io.StringProvider", "matlab.net.http.LogRecord", "matlab.net.http.MediaType", "matlab.net.http.Message", "matlab.net.http.MessageBody", "matlab.net.http.MessageType", "matlab.net.http.ProgressMonitor", "matlab.net.http.ProtocolVersion", "matlab.net.http.RequestLine", "matlab.net.http.RequestMessage", "matlab.net.http.RequestMethod", "matlab.net.http.ResponseMessage", "matlab.net.http.StartLine", "matlab.net.http.StatusClass", "matlab.net.http.StatusCode", "matlab.net.http.StatusCode.fromValue", "matlab.net.http.StatusLine", "matlab.net.QueryParameter", "matlab.net.URI", "matlab.perftest.FixedTimeExperiment", "matlab.perftest.FrequentistTimeExperiment", "matlab.perftest.TestCase", "matlab.perftest.TimeExperiment", "matlab.perftest.TimeExperiment.limitingSamplingError", "matlab.perftest.TimeExperiment.withFixedSampleSize", "matlab.perftest.TimeResult", "matlab.project.createProject", "matlab.project.loadProject", "matlab.project.Project", "matlab.project.rootProject", "matlab.System", "matlab.system.display.Action", "matlab.system.display.Header", "matlab.system.display.Icon", "matlab.system.display.Section", "matlab.system.display.SectionGroup", "matlab.system.mixin.CustomIcon", "matlab.system.mixin.FiniteSource", "matlab.system.mixin.Nondirect", "matlab.system.mixin.Propagates", "matlab.system.mixin.SampleTime", "matlab.system.StringSet", "matlab.tall.blockMovingWindow", "matlab.tall.movingWindow", "matlab.tall.reduce", "matlab.tall.transform", "matlab.test.behavior.Missing", "matlab.uitest.TestCase", "matlab.uitest.TestCase.forInteractiveUse", "matlab.uitest.unlock", "matlab.unittest.constraints.AbsoluteTolerance", "matlab.unittest.constraints.AnyCellOf", "matlab.unittest.constraints.AnyElementOf", "matlab.unittest.constraints.BooleanConstraint", "matlab.unittest.constraints.CellComparator", "matlab.unittest.constraints.Constraint", "matlab.unittest.constraints.ContainsSubstring", "matlab.unittest.constraints.EndsWithSubstring", "matlab.unittest.constraints.Eventually", "matlab.unittest.constraints.EveryCellOf", "matlab.unittest.constraints.EveryElementOf", "matlab.unittest.constraints.HasElementCount", "matlab.unittest.constraints.HasField", "matlab.unittest.constraints.HasInf", "matlab.unittest.constraints.HasLength", "matlab.unittest.constraints.HasNaN", "matlab.unittest.constraints.HasSize", "matlab.unittest.constraints.HasUniqueElements", "matlab.unittest.constraints.IsAnything", "matlab.unittest.constraints.IsEmpty", "matlab.unittest.constraints.IsEqualTo", "matlab.unittest.constraints.IsFalse", "matlab.unittest.constraints.IsFile", "matlab.unittest.constraints.IsFinite", "matlab.unittest.constraints.IsFolder", "matlab.unittest.constraints.IsGreaterThan", "matlab.unittest.constraints.IsGreaterThanOrEqualTo", "matlab.unittest.constraints.IsInstanceOf", "matlab.unittest.constraints.IsLessThan", "matlab.unittest.constraints.IsLessThanOrEqualTo", "matlab.unittest.constraints.IsOfClass", "matlab.unittest.constraints.IsReal", "matlab.unittest.constraints.IsSameHandleAs", "matlab.unittest.constraints.IsSameSetAs", "matlab.unittest.constraints.IsScalar", "matlab.unittest.constraints.IsSparse", "matlab.unittest.constraints.IsSubsetOf", "matlab.unittest.constraints.IsSubstringOf", "matlab.unittest.constraints.IssuesNoWarnings", "matlab.unittest.constraints.IssuesWarnings", "matlab.unittest.constraints.IsSupersetOf", "matlab.unittest.constraints.IsTrue", "matlab.unittest.constraints.LogicalComparator", "matlab.unittest.constraints.Matches", "matlab.unittest.constraints.NumericComparator", "matlab.unittest.constraints.ObjectComparator", "matlab.unittest.constraints.PublicPropertyComparator", "matlab.unittest.constraints.PublicPropertyComparator.supportingAllValues", "matlab.unittest.constraints.RelativeTolerance", "matlab.unittest.constraints.ReturnsTrue", "matlab.unittest.constraints.StartsWithSubstring", "matlab.unittest.constraints.StringComparator", "matlab.unittest.constraints.StructComparator", "matlab.unittest.constraints.TableComparator", "matlab.unittest.constraints.Throws", "matlab.unittest.constraints.Tolerance", "matlab.unittest.diagnostics.ConstraintDiagnostic", "matlab.unittest.diagnostics.ConstraintDiagnostic.getDisplayableString", "matlab.unittest.diagnostics.Diagnostic", "matlab.unittest.diagnostics.DiagnosticResult", "matlab.unittest.diagnostics.DisplayDiagnostic", "matlab.unittest.diagnostics.FigureDiagnostic", "matlab.unittest.diagnostics.FileArtifact", "matlab.unittest.diagnostics.FrameworkDiagnostic", "matlab.unittest.diagnostics.FunctionHandleDiagnostic", "matlab.unittest.diagnostics.LoggedDiagnosticEventData", "matlab.unittest.diagnostics.ScreenshotDiagnostic", "matlab.unittest.diagnostics.StringDiagnostic", "matlab.unittest.fixtures.CurrentFolderFixture", "matlab.unittest.fixtures.Fixture", "matlab.unittest.fixtures.PathFixture", "matlab.unittest.fixtures.ProjectFixture", "matlab.unittest.fixtures.SuppressedWarningsFixture", "matlab.unittest.fixtures.TemporaryFolderFixture", "matlab.unittest.fixtures.WorkingFolderFixture", "matlab.unittest.measurement.DefaultMeasurementResult", "matlab.unittest.measurement.MeasurementResult", "matlab.unittest.parameters.ClassSetupParameter", "matlab.unittest.parameters.EmptyParameter", "matlab.unittest.parameters.MethodSetupParameter", "matlab.unittest.parameters.Parameter", "matlab.unittest.parameters.Parameter.fromData", "matlab.unittest.parameters.TestParameter", "matlab.unittest.plugins.codecoverage.CoberturaFormat", "matlab.unittest.plugins.codecoverage.CoverageReport", "matlab.unittest.plugins.codecoverage.ProfileReport", "matlab.unittest.plugins.CodeCoveragePlugin", "matlab.unittest.plugins.CodeCoveragePlugin.forFile", "matlab.unittest.plugins.CodeCoveragePlugin.forFolder", "matlab.unittest.plugins.CodeCoveragePlugin.forPackage", "matlab.unittest.plugins.diagnosticrecord.DiagnosticRecord", "matlab.unittest.plugins.diagnosticrecord.ExceptionDiagnosticRecord", "matlab.unittest.plugins.diagnosticrecord.LoggedDiagnosticRecord", "matlab.unittest.plugins.diagnosticrecord.QualificationDiagnosticRecord", "matlab.unittest.plugins.DiagnosticsOutputPlugin", "matlab.unittest.plugins.DiagnosticsRecordingPlugin", "matlab.unittest.plugins.DiagnosticsValidationPlugin", "matlab.unittest.plugins.FailOnWarningsPlugin", "matlab.unittest.plugins.LoggingPlugin", "matlab.unittest.plugins.LoggingPlugin.withVerbosity", "matlab.unittest.plugins.OutputStream", "matlab.unittest.plugins.plugindata.FinalizedResultPluginData", "matlab.unittest.plugins.plugindata.ImplicitFixturePluginData", "matlab.unittest.plugins.plugindata.PluginData", "matlab.unittest.plugins.plugindata.QualificationContext", "matlab.unittest.plugins.plugindata.SharedTestFixturePluginData", "matlab.unittest.plugins.plugindata.TestContentCreationPluginData", "matlab.unittest.plugins.plugindata.TestSuiteRunPluginData", "matlab.unittest.plugins.QualifyingPlugin", "matlab.unittest.plugins.StopOnFailuresPlugin", "matlab.unittest.plugins.TAPPlugin", "matlab.unittest.plugins.TAPPlugin.producingOriginalFormat", "matlab.unittest.plugins.TAPPlugin.producingVersion13", "matlab.unittest.plugins.testreport.DOCXTestReportPlugin", "matlab.unittest.plugins.testreport.HTMLTestReportPlugin", "matlab.unittest.plugins.testreport.PDFTestReportPlugin", "matlab.unittest.plugins.TestReportPlugin", "matlab.unittest.plugins.TestReportPlugin.producingDOCX", "matlab.unittest.plugins.TestReportPlugin.producingHTML", "matlab.unittest.plugins.TestReportPlugin.producingPDF", "matlab.unittest.plugins.TestRunnerPlugin", "matlab.unittest.plugins.TestRunProgressPlugin", "matlab.unittest.plugins.ToFile", "matlab.unittest.plugins.ToStandardOutput", "matlab.unittest.plugins.ToUniqueFile", "matlab.unittest.plugins.XMLPlugin", "matlab.unittest.plugins.XMLPlugin.producingJUnitFormat", "matlab.unittest.qualifications.Assertable", "matlab.unittest.qualifications.AssertionFailedException", "matlab.unittest.qualifications.Assumable", "matlab.unittest.qualifications.AssumptionFailedException", "matlab.unittest.qualifications.ExceptionEventData", "matlab.unittest.qualifications.FatalAssertable", "matlab.unittest.qualifications.FatalAssertionFailedException", "matlab.unittest.qualifications.QualificationEventData", "matlab.unittest.qualifications.Verifiable", "matlab.unittest.Scope", "matlab.unittest.selectors.AndSelector", "matlab.unittest.selectors.HasBaseFolder", "matlab.unittest.selectors.HasName", "matlab.unittest.selectors.HasParameter", "matlab.unittest.selectors.HasProcedureName", "matlab.unittest.selectors.HasSharedTestFixture", "matlab.unittest.selectors.HasSuperclass", "matlab.unittest.selectors.HasTag", "matlab.unittest.selectors.NotSelector", "matlab.unittest.selectors.OrSelector", "matlab.unittest.Test", "matlab.unittest.TestCase", "matlab.unittest.TestCase.forInteractiveUse", "matlab.unittest.TestResult", "matlab.unittest.TestRunner", "matlab.unittest.TestRunner.withNoPlugins", "matlab.unittest.TestRunner.withTextOutput", "matlab.unittest.TestSuite", "matlab.unittest.TestSuite.fromClass", "matlab.unittest.TestSuite.fromFile", "matlab.unittest.TestSuite.fromFolder", "matlab.unittest.TestSuite.fromMethod", "matlab.unittest.TestSuite.fromName", "matlab.unittest.TestSuite.fromPackage", "matlab.unittest.TestSuite.fromProject", "matlab.unittest.Verbosity", "matlab.wsdl.createWSDLClient", "matlab.wsdl.setWSDLToolPath", "matlabrc", "matlabroot", "matlabshared.supportpkg.checkForUpdate", "matlabshared.supportpkg.getInstalled", "matlabshared.supportpkg.getSupportPackageRoot", "matlabshared.supportpkg.setSupportPackageRoot", "max", "max", "maxflow", "MaximizeCommandWindow", "maxk", "maxNumCompThreads", "maxpartitions", "maxpartitions", "mean", "mean", "median", "median", "memmapfile", "memoize", "MemoizedFunction", "memory", "menu", "mergecats", "mergevars", "mesh", "meshc", "meshgrid", "meshz", "meta.abstractDetails", "meta.ArrayDimension", "meta.class", "meta.class.fromName", "meta.DynamicProperty", "meta.EnumeratedValue", "meta.event", "meta.FixedDimension", "meta.MetaData", "meta.method", "meta.package", "meta.package.fromName", "meta.package.getAllPackages", "meta.property", "meta.UnrestrictedDimension", "meta.Validation", "metaclass", "methods", "methodsview", "mex", "mex.getCompilerConfigurations", "MException", "MException.last", "mexext", "mexhost", "mfilename", "mget", "milliseconds", "min", "min", "MinimizeCommandWindow", "mink", "minres", "minspantree", "minus", "minute", "minutes", "mislocked", "missing", "mkdir", "mkdir", "mkpp", "mldivide", "mlint", "mlintrpt", "mlock", "mmfileinfo", "mod", "mode", "month", "more", "morebins", "movAbsHDU", "move", "move", "movefile", "movegui", "movevars", "movie", "movmad", "movmax", "movmean", "movmedian", "movmin", "movNamHDU", "movprod", "movRelHDU", "movstd", "movsum", "movvar", "mpower", "mput", "mrdivide", "msgbox", "mtimes", "mu2lin", "multibandread", "multibandwrite", "munlock", "mustBeFinite", "mustBeGreaterThan", "mustBeGreaterThanOrEqual", "mustBeInteger", "mustBeLessThan", "mustBeLessThanOrEqual", "mustBeMember", "mustBeNegative", "mustBeNonempty", "mustBeNonNan", "mustBeNonnegative", "mustBeNonpositive", "mustBeNonsparse", "mustBeNonzero", "mustBeNumeric", "mustBeNumericOrLogical", "mustBePositive", "mustBeReal", "namelengthmax", "NaN", "nargchk", "nargin", "nargin", "narginchk", "nargout", "nargout", "nargoutchk", "NaT", "native2unicode", "nccreate", "ncdisp", "nchoosek", "ncinfo", "ncread", "ncreadatt", "ncwrite", "ncwriteatt", "ncwriteschema", "ndgrid", "ndims", "ne", "nearest", "nearestNeighbor", "nearestNeighbor", "nearestNeighbor", "nearestvertex", "neighbors", "neighbors", "neighbors", "NET", "NET.addAssembly", "NET.Assembly", "NET.convertArray", "NET.createArray", "NET.createGeneric", "NET.disableAutoRelease", "NET.enableAutoRelease", "NET.GenericClass", "NET.invokeGenericMethod", "NET.isNETSupported", "NET.NetException", "NET.setStaticProperty", "netcdf.abort", "netcdf.close", "netcdf.copyAtt", "netcdf.create", "netcdf.defDim", "netcdf.defGrp", "netcdf.defVar", "netcdf.defVarChunking", "netcdf.defVarDeflate", "netcdf.defVarFill", "netcdf.defVarFletcher32", "netcdf.delAtt", "netcdf.endDef", "netcdf.getAtt", "netcdf.getChunkCache", "netcdf.getConstant", "netcdf.getConstantNames", "netcdf.getVar", "netcdf.inq", "netcdf.inqAtt", "netcdf.inqAttID", "netcdf.inqAttName", "netcdf.inqDim", "netcdf.inqDimID", "netcdf.inqDimIDs", "netcdf.inqFormat", "netcdf.inqGrpName", "netcdf.inqGrpNameFull", "netcdf.inqGrpParent", "netcdf.inqGrps", "netcdf.inqLibVers", "netcdf.inqNcid", "netcdf.inqUnlimDims", "netcdf.inqVar", "netcdf.inqVarChunking", "netcdf.inqVarDeflate", "netcdf.inqVarFill", "netcdf.inqVarFletcher32", "netcdf.inqVarID", "netcdf.inqVarIDs", "netcdf.open", "netcdf.putAtt", "netcdf.putVar", "netcdf.reDef", "netcdf.renameAtt", "netcdf.renameDim", "netcdf.renameVar", "netcdf.setChunkCache", "netcdf.setDefaultFormat", "netcdf.setFill", "netcdf.sync", "newline", "newplot", "nextfile", "nextpow2", "nnz", "nonzeros", "norm", "normalize", "normest", "not", "notebook", "notify", "now", "nsidedpoly", "nthroot", "null", "num2cell", "num2hex", "num2ruler", "num2str", "numArgumentsFromSubscript", "numboundaries", "numedges", "numel", "numnodes", "numpartitions", "numpartitions", "numRegions", "numsides", "nzmax", "ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", "ode23tb", "ode45", "odeget", "odeset", "odextend", "onCleanup", "ones", "onFailure", "onFailure", "open", "open", "openDiskFile", "openfig", "openFile", "opengl", "openProject", "openvar", "optimget", "optimset", "or", "ordeig", "orderfields", "ordqz", "ordschur", "orient", "orth", "outdegree", "outedges", "outerjoin", "outputImpl", "overlaps", "pack", "pad", "padecoef", "pagesetupdlg", "pan", "panInteraction", "parallelplot", "pareto", "parfor", "parquetDatastore", "parquetinfo", "parquetread", "parquetwrite", "parse", "parse", "parseSoapResponse", "partition", "partition", "partition", "parula", "pascal", "patch", "path", "path2rc", "pathsep", "pathtool", "pause", "pause", "pbaspect", "pcg", "pchip", "pcode", "pcolor", "pdepe", "pdeval", "peaks", "perimeter", "perimeter", "perl", "perms", "permute", "persistent", "pi", "pie", "pie3", "pink", "pinv", "planerot", "play", "play", "playblocking", "plot", "plot", "plot", "plot", "plot", "plot3", "plotbrowser", "plotedit", "plotmatrix", "plottools", "plotyy", "plus", "plus", "pointLocation", "pointLocation", "pol2cart", "polar", "polaraxes", "polarhistogram", "polarplot", "polarscatter", "poly", "polyarea", "polybuffer", "polyder", "polyeig", "polyfit", "polyint", "polyshape", "polyval", "polyvalm", "posixtime", "pow2", "power", "ppval", "predecessors", "prefdir", "preferences", "preferredBufferSize", "preferredBufferSize", "press", "preview", "preview", "primes", "print", "print", "printdlg", "printopt", "printpreview", "prism", "processInputSpecificationChangeImpl", "processTunedPropertiesImpl", "prod", "profile", "profsave", "progress", "propagatedInputComplexity", "propagatedInputDataType", "propagatedInputFixedSize", "propagatedInputSize", "propedit", "propedit", "properties", "propertyeditor", "psi", "publish", "PutCharArray", "putData", "putData", "putData", "putData", "putData", "putData", "putData", "putData", "PutFullMatrix", "PutWorkspaceData", "pwd", "pyargs", "pyversion", "qmr", "qr", "qrdelete", "qrinsert", "qrupdate", "quad", "quad2d", "quadgk", "quadl", "quadv", "quarter", "questdlg", "Quit", "quit", "quiver", "quiver3", "qz", "rad2deg", "rand", "rand", "randi", "randi", "randn", "randn", "randperm", "randperm", "RandStream", "RandStream", "RandStream.create", "RandStream.getGlobalStream", "RandStream.list", "RandStream.setGlobalStream", "rank", "rat", "rats", "rbbox", "rcond", "rdivide", "read", "read", "read", "read", "read", "readall", "readasync", "readATblHdr", "readBTblHdr", "readCard", "readcell", "readCol", "readFrame", "readimage", "readImg", "readKey", "readKeyCmplx", "readKeyDbl", "readKeyLongLong", "readKeyLongStr", "readKeyUnit", "readmatrix", "readRecord", "readtable", "readtimetable", "readvars", "real", "reallog", "realmax", "realmin", "realpow", "realsqrt", "record", "record", "recordblocking", "rectangle", "rectint", "recycle", "reducepatch", "reducevolume", "refresh", "refreshdata", "refreshSourceControl", "regexp", "regexpi", "regexprep", "regexptranslate", "regions", "regionZoomInteraction", "registerevent", "regmatlabserver", "rehash", "relationaloperators", "release", "release", "releaseImpl", "reload", "rem", "Remove", "remove", "RemoveAll", "removeCategory", "removecats", "removeFields", "removeFields", "removeFile", "removeLabel", "removeParameter", "removeParameter", "removePath", "removeReference", "removeShortcut", "removeShutdownFile", "removeStartupFile", "removeToolbarExplorationButtons", "removets", "removevars", "rename", "renamecats", "rendererinfo", "reordercats", "reordernodes", "repeat", "repeat", "repeat", "repeat", "repeat", "repelem", "replace", "replaceBetween", "replaceFields", "replaceFields", "repmat", "reportFinalizedResult", "resample", "resample", "rescale", "reset", "reset", "reset", "reset", "reset", "resetImpl", "reshape", "reshape", "residue", "resolve", "restartable", "restartable", "restartable", "restoredefaultpath", "result", "resume", "rethrow", "rethrow", "retime", "return", "returnStoredValueWhen", "reusable", "reusable", "reusable", "reverse", "rgb2gray", "rgb2hsv", "rgb2ind", "rgbplot", "ribbon", "rlim", "rmappdata", "rmboundary", "rmdir", "rmdir", "rmedge", "rmfield", "rmholes", "rmmissing", "rmnode", "rmoutliers", "rmpath", "rmpref", "rmprop", "rmslivers", "rng", "roots", "rose", "rosser", "rot90", "rotate", "rotate", "rotate3d", "rotateInteraction", "round", "rowfun", "rows2vars", "rref", "rsf2csf", "rtickangle", "rtickformat", "rticklabels", "rticks", "ruler2num", "rulerPanInteraction", "run", "run", "run", "run", "run", "runInParallel", "runperf", "runTest", "runTestClass", "runTestMethod", "runtests", "runTestSuite", "samplefun", "sampleSummary", "satisfiedBy", "satisfiedBy", "save", "save", "save", "saveas", "savefig", "saveobj", "saveObjectImpl", "savepath", "scale", "scatter", "scatter3", "scatteredInterpolant", "scatterhistogram", "schur", "scroll", "sec", "secd", "sech", "second", "seconds", "seek", "selectFailed", "selectIf", "selectIncomplete", "selectLogged", "selectmoveresize", "selectPassed", "semilogx", "semilogy", "send", "sendmail", "serial", "serialbreak", "seriallist", "set", "set", "set", "set", "set", "set", "set", "set", "set", "set", "set", "setabstime", "setabstime", "setappdata", "setBscale", "setcats", "setCompressionType", "setdatatype", "setdiff", "setdisp", "setenv", "setfield", "setHCompScale", "setHCompSmooth", "setinterpmethod", "setParameter", "setParameter", "setParameter", "setpixelposition", "setpref", "setProperties", "setstr", "setTileDim", "settimeseriesnames", "Setting", "settings", "SettingsGroup", "setToValue", "setTscale", "setuniformtime", "setup", "setupImpl", "setupSharedTestFixture", "setupTestClass", "setupTestMethod", "setvaropts", "setvartype", "setxor", "sgtitle", "shading", "sheetnames", "shg", "shiftdim", "shortestpath", "shortestpathtree", "show", "show", "show", "show", "showFiSettingsImpl", "showplottool", "showSimulateUsingImpl", "shrinkfaces", "shuffle", "shuffle", "sign", "simplify", "simplify", "sin", "sind", "single", "sinh", "sinpi", "size", "size", "size", "size", "size", "size", "size", "slice", "smooth3", "smoothdata", "snapnow", "sort", "sortboundaries", "sortByFixtures", "sortregions", "sortrows", "sortx", "sorty", "sound", "soundsc", "spalloc", "sparse", "spaugment", "spconvert", "spdiags", "specular", "speye", "spfun", "sph2cart", "sphere", "spinmap", "spline", "split", "split", "splitapply", "splitEachLabel", "splitlines", "splitvars", "spones", "spparms", "sprand", "sprandn", "sprandsym", "sprank", "spreadsheetDatastore", "spreadsheetImportOptions", "spring", "sprintf", "spy", "sqrt", "sqrtm", "squeeze", "ss2tf", "sscanf", "stack", "stackedplot", "stairs", "standardizeMissing", "start", "start", "start", "start", "start", "start", "start", "start", "start", "start", "start", "start", "startat", "startMeasuring", "startsWith", "startup", "stats", "std", "std", "stem", "stem3", "step", "stepImpl", "stlread", "stlwrite", "stop", "stop", "stopasync", "stopMeasuring", "storeValueWhen", "str2double", "str2func", "str2mat", "str2num", "strcat", "strcmp", "strcmpi", "stream2", "stream3", "streamline", "streamparticles", "streamribbon", "streamslice", "streamtube", "strfind", "string", "string", "string", "string", "string", "string", "strings", "strip", "strjoin", "strjust", "strlength", "strmatch", "strncmp", "strncmpi", "strread", "strrep", "strsplit", "strtok", "strtrim", "struct", "struct2cell", "struct2table", "structfun", "strvcat", "sub2ind", "subgraph", "subplot", "subsasgn", "subset", "subsindex", "subspace", "subsref", "substruct", "subtract", "subvolume", "successors", "sum", "sum", "summary", "summary", "summer", "superclasses", "support", "supportPackageInstaller", "supports", "supportsMultipleInstanceImpl", "surf", "surf2patch", "surface", "surfaceArea", "surfc", "surfl", "surfnorm", "svd", "svds", "swapbytes", "sylvester", "symamd", "symbfact", "symmlq", "symrcm", "symvar", "synchronize", "synchronize", "syntax", "system", "table", "table2array", "table2cell", "table2struct", "table2timetable", "tabularTextDatastore", "tail", "tall", "TallDatastore", "tallrng", "tan", "tand", "tanh", "tar", "tcpclient", "teardown", "teardownSharedTestFixture", "teardownTestClass", "teardownTestMethod", "tempdir", "tempname", "testsuite", "tetramesh", "texlabel", "text", "textread", "textscan", "textwrap", "tfqmr", "then", "then", "then", "then", "then", "thetalim", "thetatickformat", "thetaticklabels", "thetaticks", "thingSpeakRead", "thingSpeakWrite", "throw", "throwAsCaller", "throwExceptionWhen", "tic", "Tiff", "Tiff.computeStrip", "Tiff.computeTile", "Tiff.currentDirectory", "Tiff.getTag", "Tiff.getTagNames", "Tiff.getVersion", "Tiff.isTiled", "Tiff.lastDirectory", "Tiff.nextDirectory", "Tiff.numberOfStrips", "Tiff.numberOfTiles", "Tiff.readEncodedStrip", "Tiff.readEncodedTile", "Tiff.readRGBAImage", "Tiff.readRGBAStrip", "Tiff.readRGBATile", "Tiff.rewriteDirectory", "Tiff.setDirectory", "Tiff.setSubDirectory", "Tiff.setTag", "Tiff.writeDirectory", "Tiff.writeEncodedStrip", "Tiff.writeEncodedTile", "time", "timeit", "timeofday", "timer", "timerange", "timerfind", "timerfindall", "times", "timeseries", "timetable", "timetable2table", "timezones", "title", "toc", "todatenum", "toeplitz", "toolboxdir", "topkrows", "toposort", "trace", "transclosure", "transform", "TransformedDatastore", "translate", "transpose", "transreduction", "trapz", "treelayout", "treeplot", "triangulation", "triangulation", "tril", "trimesh", "triplequad", "triplot", "TriRep", "TriRep", "TriScatteredInterp", "TriScatteredInterp", "trisurf", "triu", "true", "tscollection", "tsdata.event", "tsearchn", "turningdist", "type", "type", "typecast", "tzoffset", "uialert", "uiaxes", "uibutton", "uibuttongroup", "uicheckbox", "uiconfirm", "uicontextmenu", "uicontrol", "uidatepicker", "uidropdown", "uieditfield", "uifigure", "uigauge", "uigetdir", "uigetfile", "uigetpref", "uigridlayout", "uiimage", "uiimport", "uiknob", "uilabel", "uilamp", "uilistbox", "uimenu", "uint16", "uint32", "uint64", "uint8", "uiopen", "uipanel", "uiprogressdlg", "uipushtool", "uiputfile", "uiradiobutton", "uiresume", "uisave", "uisetcolor", "uisetfont", "uisetpref", "uislider", "uispinner", "uistack", "uiswitch", "uitab", "uitabgroup", "uitable", "uitextarea", "uitogglebutton", "uitoggletool", "uitoolbar", "uitree", "uitreenode", "uiwait", "uminus", "underlyingValue", "undocheckout", "unicode2native", "union", "union", "unique", "uniquetol", "unix", "unloadlibrary", "unmesh", "unmkpp", "unregisterallevents", "unregisterevent", "unstack", "untar", "unwrap", "unzip", "updateDependencies", "updateImpl", "upgradePreviouslyInstalledSupportPackages", "uplus", "upper", "urlread", "urlwrite", "usejava", "userpath", "validate", "validate", "validate", "validate", "validateattributes", "validateFunctionSignaturesJSON", "validateInputsImpl", "validatePropertiesImpl", "validatestring", "ValueIterator", "values", "vander", "var", "var", "varargin", "varargout", "varfun", "vartype", "vecnorm", "vectorize", "ver", "verctrl", "verifyAccessed", "verifyCalled", "verifyClass", "verifyEmpty", "verifyEqual", "verifyError", "verifyFail", "verifyFalse", "verifyGreaterThan", "verifyGreaterThanOrEqual", "verifyInstanceOf", "verifyLength", "verifyLessThan", "verifyLessThanOrEqual", "verifyMatches", "verifyNotAccessed", "verifyNotCalled", "verifyNotEmpty", "verifyNotEqual", "verifyNotSameHandle", "verifyNotSet", "verifyNumElements", "verifyReturnsTrue", "verifySameHandle", "verifySet", "verifySize", "verifySubstring", "verifyThat", "verifyTrue", "verifyUsing", "verifyWarning", "verifyWarningFree", "verLessThan", "version", "vertcat", "vertcat", "vertcat", "vertexAttachments", "vertexAttachments", "vertexNormal", "VideoReader", "VideoWriter", "view", "viewmtx", "visdiff", "volume", "volumebounds", "voronoi", "voronoiDiagram", "voronoiDiagram", "voronoin", "wait", "waitbar", "waitfor", "waitforbuttonpress", "warndlg", "warning", "waterfall", "web", "weboptions", "webread", "websave", "webwrite", "week", "weekday", "what", "whatsnew", "when", "when", "when", "which", "while", "whitebg", "who", "who", "whos", "whos", "width", "wilkinson", "winopen", "winqueryreg", "winter", "withAnyInputs", "withExactInputs", "withNargout", "withtol", "wordcloud", "write", "write", "write", "writecell", "writeChecksum", "writeCol", "writeComment", "writeDate", "writeHistory", "writeImg", "writeKey", "writeKeyUnit", "writematrix", "writetable", "writetimetable", "writeVideo", "xcorr", "xcov", "xlabel", "xlim", "xline", "xlsfinfo", "xlsread", "xlswrite", "xmlread", "xmlwrite", "xor", "xor", "xslt", "xtickangle", "xtickformat", "xticklabels", "xticks", "year", "years", "ylabel", "ylim", "yline", "ymd", "ytickangle", "ytickformat", "yticklabels", "yticks", "yyaxis", "yyyymmdd", "zeros", "zip", "zlabel", "zlim", "zoom", "zoomInteraction", "ztickangle", "ztickformat", "zticklabels", "zticks"] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/meson.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/meson.rb new file mode 100644 index 0000000..ab0bd64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/meson.rb @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Meson < RegexLexer + title "Meson" + desc "Meson's specification language (mesonbuild.com)" + tag 'meson' + filenames 'meson.build', 'meson_options.txt' + mimetypes 'text/x-meson' + + def self.keywords + @keywords ||= %w( + continue break elif else endif + if true false foreach endforeach + ) + end + + def self.builtin_variables + @builtin_variables ||= %w( + meson host_machine build_machine target_machine + ) + end + + def self.builtin_functions + @builtin_functions ||= %w( + add_global_arguments add_project_arguments + add_global_link_arguments add_project_link_arguments add_test_setup add_languages + alias_target assert benchmark both_libraries build_target configuration_data configure_file + custom_target declare_dependency dependency disabler environment error executable + generator gettext get_option get_variable files find_library find_program + include_directories import install_data install_headers install_man install_subdir + is_disabler is_variable jar join_paths library message option project + run_target run_command set_variable subdir subdir_done + subproject summary shared_library shared_module static_library test vcs_tag warning + ) + end + + identifier = /[[:alpha:]_][[:alnum:]_]*/ + + def current_string + @current_string ||= StringRegister.new + end + + state :root do + rule %r/\n+/m, Text + + rule %r/[^\S\n]+/, Text + rule %r(#(.*)?\n?), Comment::Single + rule %r/[\[\]{}:(),;.]/, Punctuation + rule %r/\\\n/, Text + rule %r/\\/, Text + + rule %r/(in|and|or|not)\b/, Operator::Word + rule %r/[-+\/*%=<>]=?|!=/, Operator + + rule %r/([f]?)('''|['])/i do |m| + groups Str::Affix, Str + current_string.register type: m[1].downcase, delim: m[2] + push :generic_string + end + + rule %r/(?|->|<-|\\/|xor|/\\), Operator + rule %r(<|>|<=|>=|==|=|!=), Operator + rule %r(\+|-|\*|/|div|mod), Operator + rule %r(\\|\.\.|\+\+), Operator + rule %r([|()\[\]{},:;]), Punctuation + rule %r((true|false)\b), Keyword::Constant + rule %r(([+-]?)\d+(\.(?!\.)\d*)?([eE][-+]?\d+)?), Literal::Number + + rule id do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.keywords_type.include? m[0] + token Keyword::Type + elsif self.class.builtins.include? m[0] + token Name::Builtin + elsif self.class.operators.include? m[0] + token Operator + else + token Name::Other + end + end + + rule %r(::\s*([^\W\d]\w*)(\s*\([^\)]*\))?), Name::Decorator + rule %r(\b([^\W\d]\w*)\b(\()) do + groups Name::Function, Punctuation + end + rule %r([^\W\d]\w*), Name::Other + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mojo.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mojo.rb new file mode 100644 index 0000000..f371120 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mojo.rb @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'python.rb' + + class Mojo < Python + title "Mojo" + desc "The Mojo programming language (modular.com)" + tag 'mojo' + aliases 'mojo' + filenames '*.mojo', '*.🔥' + mimetypes 'text/x-mojo', 'application/x-mojo' + + def self.detect?(text) + return true if text.shebang?(/mojow?(?:[23](?:\.\d+)?)?/) + end + + def self.keywords + @keywords ||= super + %w( + fn self alias out read mut owned ref var + struct trait raises with in match case + ) + end + + def self.builtins + @builtins ||= super + %w( + __mlir_attr __mlir_type __mlir_op parameter alwaysinline + register_passable + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/moonscript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/moonscript.rb new file mode 100644 index 0000000..055422b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/moonscript.rb @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'lua.rb' + + class Moonscript < RegexLexer + title "MoonScript" + desc "Moonscript (http://www.moonscript.org)" + tag 'moonscript' + aliases 'moon' + filenames '*.moon' + mimetypes 'text/x-moonscript', 'application/x-moonscript' + + option :function_highlighting, 'Whether to highlight builtin functions (default: true)' + option :disabled_modules, 'builtin modules to disable' + + def initialize(*) + super + + @function_highlighting = bool_option(:function_highlighting) { true } + @disabled_modules = list_option(:disabled_modules) + end + + def self.detect?(text) + return true if text.shebang? 'moon' + end + + def builtins + return [] unless @function_highlighting + + @builtins ||= Set.new.tap do |builtins| + Rouge::Lexers::Lua.builtins.each do |mod, fns| + next if @disabled_modules.include? mod + builtins.merge(fns) + end + end + end + + state :root do + rule %r(#!(.*?)$), Comment::Preproc # shebang + rule %r//, Text, :main + end + + state :base do + ident = '(?:\w\w*)' + + rule %r((?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?'), Num::Float + rule %r((?i)\d+e[+-]?\d+), Num::Float + rule %r((?i)0x[0-9a-f]*), Num::Hex + rule %r(\d+), Num::Integer + rule %r(@#{ident}*), Name::Variable::Instance + rule %r([A-Z]\w*), Name::Class + rule %r("?[^"]+":), Literal::String::Symbol + rule %r(#{ident}:), Literal::String::Symbol + rule %r(:#{ident}), Literal::String::Symbol + + rule %r(\s+), Text::Whitespace + rule %r((==|~=|!=|<=|>=|\.\.\.|\.\.|->|=>|[=+\-*/%^<>#!\\])), Operator + rule %r([\[\]\{\}\(\)\.,:;]), Punctuation + rule %r((and|or|not)\b), Operator::Word + + keywords = %w{ + break class continue do else elseif end extends for if import in + repeat return switch super then unless until using when with while + } + rule %r((#{keywords.join('|')})\b), Keyword + rule %r((local|export)\b), Keyword::Declaration + rule %r((true|false|nil)\b), Keyword::Constant + + rule %r([A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?) do |m| + name = m[0] + if self.builtins.include?(name) + token Name::Builtin + elsif name =~ /\./ + a, b = name.split('.', 2) + token Name, a + token Punctuation, '.' + token Name, b + else + token Name + end + end + end + + state :main do + rule %r(--.*$), Comment::Single + rule %r(\[(=*)\[.*?\]\1\])m, Str::Heredoc + + mixin :base + + rule %r('), Str::Single, :sqs + rule %r("), Str::Double, :dqs + end + + state :sqs do + rule %r('), Str::Single, :pop! + rule %r([^']+), Str::Single + end + + state :interpolation do + rule %r(\}), Str::Interpol, :pop! + mixin :base + end + + state :dqs do + rule %r(#\{), Str::Interpol, :interpolation + rule %r("), Str::Double, :pop! + rule %r(#[^{]), Str::Double + rule %r([^"#]+), Str::Double + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mosel.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mosel.rb new file mode 100644 index 0000000..bad56d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mosel.rb @@ -0,0 +1,228 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Mosel < RegexLexer + tag 'mosel' + filenames '*.mos' + title "Mosel" + desc "An optimization language used by Fico's Xpress." + # http://www.fico.com/en/products/fico-xpress-optimization-suite + filenames '*.mos' + + mimetypes 'text/x-mosel' + + id = /[a-zA-Z_][a-zA-Z0-9_]*/ + + ############################################################################################################################ + # General language lements + ############################################################################################################################ + + core_keywords = %w( + and array as + boolean break + case count counter + declarations div do dynamic + elif else end evaluation exit + false forall forward from function + if imports in include initialisations initializations integer inter is_binary is_continuous is_free is_integer is_partint is_semcont is_semint is_sos1 is_sos2 + linctr list + max min mod model mpvar + next not of options or + package parameters procedure + public prod range real record repeat requirements + set string sum + then to true + union until uses + version + while with + ) + + core_functions = %w( + abs arctan assert + bitflip bitneg bitset bitshift bittest bitval + ceil cos create currentdate currenttime cuthead cuttail + delcell exists exit exp exportprob + fclose fflush finalize findfirst findlast floor fopen fselect fskipline + getact getcoeff getcoeffs getdual getfid getfirst gethead getfname getlast getobjval getparam getrcost getreadcnt getreverse getsize getslack getsol gettail gettype getvars + iseof ishidden isodd ln log + makesos1 makesos2 maxlist minlist + publish + random read readln reset reverse round + setcoeff sethidden setioerr setname setparam setrandseed settype sin splithead splittail sqrt strfmt substr + timestamp + unpublish + write writeln + ) + + ############################################################################################################################ + # mmxprs module elements + ############################################################################################################################ + + mmxprs_functions = %w( + addmipsol + basisstability + calcsolinfo clearmipdir clearmodcut command copysoltoinit + defdelayedrows defsecurevecs + estimatemarginals + fixglobal + getbstat getdualray getiis getiissense getiistype getinfcause getinfeas getlb getloadedlinctrs getloadedmpvars getname getprimalray getprobstat getrange getsensrng getsize getsol getub getvars + implies indicator isiisvalid isintegral loadbasis + loadmipsol loadprob + maximize minimize + postsolve + readbasis readdirs readsol refinemipsol rejectintsol repairinfeas resetbasis resetiis resetsol + savebasis savemipsol savesol savestate selectsol setbstat setcallback setcbcutoff setgndata setlb setmipdir setmodcut setsol setub setucbdata stopoptimize + unloadprob + writebasis writedirs writeprob writesol + xor + ) + + mmxpres_constants = %w(XPRS_OPT XPRS_UNF XPRS_INF XPRS_UNB XPRS_OTH) + + mmxprs_parameters = %w(XPRS_colorder XPRS_enumduplpol XPRS_enummaxsol XPRS_enumsols XPRS_fullversion XPRS_loadnames XPRS_problem XPRS_probname XPRS_verbose) + + + ############################################################################################################################ + # mmsystem module elements + ############################################################################################################################ + + mmsystem_functions = %w( + addmonths + copytext cuttext + deltext + endswith expandpath + fcopy fdelete findfiles findtext fmove + getasnumber getchar getcwd getdate getday getdaynum getdays getdirsep + getendparse setendparse + getenv getfsize getfstat getftime gethour getminute getmonth getmsec getpathsep + getqtype setqtype + getsecond + getsepchar setsepchar + getsize + getstart setstart + getsucc setsucc + getsysinfo getsysstat gettime + gettmpdir + gettrim settrim + getweekday getyear + inserttext isvalid + makedir makepath newtar + newzip nextfield + openpipe + parseextn parseint parsereal parsetext pastetext pathmatch pathsplit + qsort quote + readtextline regmatch regreplace removedir removefiles + setchar setdate setday setenv sethour + setminute setmonth setmsec setsecond settime setyear sleep startswith system + tarlist textfmt tolower toupper trim + untar unzip + ziplist + ) + + mmsystem_parameters = %w(datefmt datetimefmt monthnames sys_endparse sys_fillchar sys_pid sys_qtype sys_regcache sys_sepchar) + + ############################################################################################################################ + # mmjobs module elements + ############################################################################################################################ + + mmjobs_instance_mgmt_functions = %w( + clearaliases connect + disconnect + findxsrvs + getaliases getbanner gethostalias + sethostalias + ) + + mmjobs_model_mgmt_functions = %w( + compile + detach + getannidents getannotations getexitcode getgid getid getnode getrmtid getstatus getuid + load + reset resetmodpar run + setcontrol setdefstream setmodpar setworkdir stop + unload + ) + + mmjobs_synchornization_functions = %w( + dropnextevent + getclass getfromgid getfromid getfromuid getnextevent getvalue + isqueueempty + nullevent + peeknextevent + send setgid setuid + wait waitfor + ) + + mmjobs_functions = mmjobs_instance_mgmt_functions + mmjobs_model_mgmt_functions + mmjobs_synchornization_functions + + mmjobs_parameters = %w(conntmpl defaultnode fsrvdelay fsrvnbiter fsrvport jobid keepalive nodenumber parentnumber) + + + state :whitespace do + # Spaces + rule %r/\s+/m, Text + # ! Comments + rule %r((!).*$\n?), Comment::Single + # (! Comments !) + rule %r(\(!.*?!\))m, Comment::Multiline + + end + + + # From Mosel documentation: + # Constant strings of characters must be quoted with single (') or double quote (") and may extend over several lines. Strings enclosed in double quotes may contain C-like escape sequences introduced by the 'backslash' + # character (\a \b \f \n \r \t \v \xxx with xxx being the character code as an octal number). + # Each sequence is replaced by the corresponding control character (e.g. \n is the `new line' command) or, if no control character exists, by the second character of the sequence itself (e.g. \\ is replaced by '\'). + # The escape sequences are not interpreted if they are contained in strings that are enclosed in single quotes. + + state :single_quotes do + rule %r/'/, Str::Single, :pop! + rule %r/[^']+/, Str::Single + end + + state :double_quotes do + rule %r/"/, Str::Double, :pop! + rule %r/(\\"|\\[0-7]{1,3}\D|\\[abfnrtv]|\\\\)/, Str::Escape + rule %r/[^"]/, Str::Double + end + + state :base do + + rule %r{"}, Str::Double, :double_quotes + rule %r{'}, Str::Single, :single_quotes + + rule %r{((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?}, Num + rule %r{[~!@#\$%\^&\*\(\)\+`\-={}\[\]:;<>\?,\.\/\|\\]}, Punctuation +# rule %r{'([^']|'')*'}, Str +# rule %r/"(\\\\|\\"|[^"])*"/, Str + + + + rule %r/(true|false)\b/i, Name::Builtin + rule %r/\b(#{core_keywords.join('|')})\b/i, Keyword + rule %r/\b(#{core_functions.join('|')})\b/, Name::Builtin + + + + rule %r/\b(#{mmxprs_functions.join('|')})\b/, Name::Function + rule %r/\b(#{mmxpres_constants.join('|')})\b/, Name::Constant + rule %r/\b(#{mmxprs_parameters.join('|')})\b/i, Name::Property + + rule %r/\b(#{mmsystem_functions.join('|')})\b/i, Name::Function + rule %r/\b(#{mmsystem_parameters.join('|')})\b/, Name::Property + + rule %r/\b(#{mmjobs_functions.join('|')})\b/i, Name::Function + rule %r/\b(#{mmjobs_parameters.join('|')})\b/, Name::Property + + rule id, Name + end + + state :root do + mixin :whitespace + mixin :base + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/msgtrans.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/msgtrans.rb new file mode 100644 index 0000000..4f21ca1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/msgtrans.rb @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class MsgTrans < RegexLexer + title "MessageTrans" + desc "RISC OS message translator messages file" + tag 'msgtrans' + filenames 'Messages', 'Message[0-9]', 'Message[1-9][0-9]', 'Message[1-9][0-9][0-9]' + + state :root do + rule %r/^#[^\n]*/, Comment + rule %r/[^\t\n\r ,):?\/]+/, Name::Variable + rule %r/[\n\/?]/, Operator + rule %r/:/, Operator, :value + end + + state :value do + rule %r/\n/, Text, :pop! + rule %r/%[0-3%]/, Operator + rule %r/[^\n%]/, Literal::String + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mxml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mxml.rb new file mode 100644 index 0000000..4a9145a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/mxml.rb @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class MXML < RegexLexer + title "MXML" + desc "MXML" + tag 'mxml' + filenames '*.mxml' + mimetypes 'application/xv+xml' + + state :root do + rule %r/[^<&]+/, Text + rule %r/&\S*?;/, Name::Entity + + rule %r//, Comment::Preproc + rule %r/]*>/, Comment::Preproc + + rule %r(<\s*[\w:.-]+)m, Name::Tag, :tag # opening tags + rule %r(<\s*/\s*[\w:.-]+\s*>)m, Name::Tag # closing tags + end + + state :comment do + rule %r/[^-]+/m, Comment + rule %r/-->/, Comment, :pop! + rule %r/-/, Comment + end + + state :tag do + rule %r/\s+/m, Text + rule %r/[\w.:-]+\s*=/m, Name::Attribute, :attribute + rule %r(/?\s*>), Name::Tag, :root + end + + state :attribute do + rule %r/\s+/m, Text + rule %r/(")({|@{)/m do + groups Str, Punctuation + push :actionscript_attribute + end + rule %r/".*?"|'.*?'|[^\s>]+/, Str, :tag + end + + state :actionscript_content do + rule %r/\]\]\>/m, Comment::Preproc, :pop! + rule %r/.*?(?=\]\]\>)/m do + delegate Actionscript + end + end + + state :actionscript_attribute do + rule %r/(})(")/m do + groups Punctuation, Str + push :tag + end + rule %r/.*?(?=}")/m do + delegate Actionscript + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nasm.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nasm.rb new file mode 100644 index 0000000..2e2df7f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nasm.rb @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# Based on Chroma's NASM lexer implementation +# https://github.com/alecthomas/chroma/blob/498eaa690f5ac6ab0e3d6f46237e547a8935cdc7/lexers/n/nasm.go +module Rouge + module Lexers + class Nasm < RegexLexer + title "Nasm" + desc "Netwide Assembler" + + tag 'nasm' + filenames '*.asm' + mimetypes 'text/x-nasm' + + state :root do + rule %r/^\s*%/, Comment::Preproc, :preproc + + mixin :whitespace + mixin :punctuation + + rule %r/[a-z$._?][\w$.?#@~]*:/i, Name::Label + + rule %r/([a-z$._?][\w$.?#@~]*)(\s+)(equ)/i do + groups Name::Constant, Keyword::Declaration, Keyword::Declaration + push :instruction_args + end + rule %r/BITS|USE16|USE32|SECTION|SEGMENT|ABSOLUTE|EXTERN|GLOBAL|ORG|ALIGN|STRUC|ENDSTRUC|COMMON|CPU|GROUP|UPPERCASE|IMPORT|EXPORT|LIBRARY|MODULE/, Keyword, :instruction_args + rule %r/(?:res|d)[bwdqt]|times/i, Keyword::Declaration, :instruction_args + rule %r/[a-z$._?][\w$.?#@~]*/i, Name::Function, :instruction_args + + rule %r/[\r\n]+/, Text + end + + state :instruction_args do + rule %r/"(\\\\"|[^"\\n])*"|'(\\\\'|[^'\\n])*'|`(\\\\`|[^`\\n])*`/, Str + rule %r/(?:0x[\da-f]+|$0[\da-f]*|\d+[\da-f]*h)/i, Num::Hex + rule %r/[0-7]+q/i, Num::Oct + rule %r/[01]+b/i, Num::Bin + rule %r/\d+\.e?\d+/i, Num::Float + rule %r/\d+/, Num::Integer + + mixin :punctuation + + rule %r/r\d[0-5]?[bwd]|[a-d][lh]|[er]?[a-d]x|[er]?[sb]p|[er]?[sd]i|[c-gs]s|st[0-7]|mm[0-7]|cr[0-4]|dr[0-367]|tr[3-7]/i, Name::Builtin + rule %r/[a-z$._?][\w$.?#@~]*/i, Name::Variable + rule %r/[\r\n]+/, Text, :pop! + + mixin :whitespace + end + + state :preproc do + rule %r/[^;\n]+/, Comment::Preproc + rule %r/;.*?\n/, Comment::Single, :pop! + rule %r/\n/, Comment::Preproc, :pop! + end + + state :whitespace do + rule %r/\n/, Text + rule %r/[ \t]+/, Text + rule %r/;.*/, Comment::Single + end + + state :punctuation do + rule %r/[,():\[\]]+/, Punctuation + rule %r/[&|^<>+*\/%~-]+/, Operator + rule %r/\$+/, Keyword::Constant + rule %r/seg|wrt|strict/i, Operator::Word + rule %r/byte|[dq]?word/i, Keyword::Type + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nesasm.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nesasm.rb new file mode 100644 index 0000000..a296414 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nesasm.rb @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class NesAsm < RegexLexer + title "NesAsm" + desc "Nesasm3 assembly (6502 asm)" + tag 'nesasm' + aliases 'nes' + filenames '*.nesasm' + + def self.keywords + @keywords ||= %w( + ADC AND ASL BIT BRK CMP CPX CPY DEC EOR INC JMP JSR LDA LDX LDY LSR + NOP ORA ROL ROR RTI RTS SBC STA STX STY TAX TXA DEX INX TAY TYA DEY + INY BPL BMI BVC BVS BCC BCS BNE BEQ CLC SEC CLI SEI CLV CLD SED TXS + TSX PHA PLA PHP PLP + ) + end + + def self.keywords_type + @keywords_type ||= %w( + DB DW BYTE WORD + ) + end + + def self.keywords_reserved + @keywords_reserved ||= %w( + INCBIN INCLUDE ORG BANK RSSET RS MACRO ENDM DS PROC ENDP PROCGROUP + ENDPROCGROUP INCCHR DEFCHR ZP BSS CODE DATA IF IFDEF IFNDEF ELSE + ENDIF FAIL INESPRG INESCHR INESMAP INESMIR FUNC + ) + end + + state :root do + rule %r/\s+/m, Text + rule %r(;.*), Comment::Single + + rule %r/[\(\)\,\.\[\]]/, Punctuation + rule %r/\#?\%[0-1]+/, Num::Bin # #%00110011 %00110011 + rule %r/\#?\$\h+/, Num::Hex # $1f #$1f + rule %r/\#?\d+/, Num # 10 #10 + rule %r([~&*+=\|?:<>/-]), Operator + + rule %r/\#?\w+:?/i do |m| + name = m[0].upcase + + if self.class.keywords.include? name + token Keyword + elsif self.class.keywords_type.include? name + token Keyword::Type + elsif self.class.keywords_reserved.include? name + token Keyword::Reserved + else + token Name::Function + end + end + + rule %r/\#?(?:LOW|HIGH)\(.*\)/i, Keyword::Reserved # LOW() #HIGH() + + rule %r/\#\(/, Punctuation # #() + + rule %r/"/, Str, :string + + rule %r/'\w'/, Str::Char # 'A' for example + + rule %r/\\\??[\d@#]/, Name::Builtin # builtin parameters for use inside macros and functions: \1-\9 , \?1-\?9 , \# , \@ + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\"?/, Str::Escape + rule %r/[^"\\]+/m, Str + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nginx.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nginx.rb new file mode 100644 index 0000000..f2661cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nginx.rb @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Nginx < RegexLexer + title "nginx" + desc 'configuration files for the nginx web server (nginx.org)' + tag 'nginx' + mimetypes 'text/x-nginx-conf' + filenames 'nginx.conf' + + id = /[^\s$;{}()#]+/ + + state :root do + rule %r/(include)(\s+)([^\s;]+)/ do + groups Keyword, Text, Name + end + + rule id, Keyword, :statement + + mixin :base + end + + state :block do + rule %r/}/, Punctuation, :pop! + rule id, Keyword::Namespace, :statement + mixin :base + end + + state :statement do + rule %r/{/ do + token Punctuation; pop!; push :block + end + + rule %r/;/, Punctuation, :pop! + + mixin :base + end + + state :base do + rule %r/\s+/, Text + + rule %r/#.*/, Comment::Single + rule %r/(?:on|off)\b/, Name::Constant + rule %r/[$][\w-]+/, Name::Variable + + # host/port + rule %r/([a-z0-9.-]+)(:)([0-9]+)/i do + groups Name::Function, Punctuation, Num::Integer + end + + # mimetype + rule %r([a-z-]+/[a-z-]+)i, Name::Class + + rule %r/\d+\.\d+/, Num::Float + rule %r/[0-9]+[kmg]?\b/i, Num::Integer + rule %r/(~)(\s*)([^\s{]+)/ do + groups Punctuation, Text, Str::Regex + end + + rule %r/[:=~]/, Punctuation + + # pathname + rule %r(/#{id}?), Name + + rule %r/[^#\s;{}$\\]+/, Str # catchall + + rule %r/[$;]/, Text + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nial.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nial.rb new file mode 100644 index 0000000..42b2260 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nial.rb @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Nial < RegexLexer + title 'Nial' + desc 'The Nial programming language (nial-array-language.org)' + tag 'nial' + filenames '*.ndf', '*.nlg' + + def self.keywords + @keywords ||= Set.new ["is", "gets", "op", "tr", ";", + "if", "then", "elseif", "else", + "endif", "case", "from", "endcase", + "begin", "end", "for", "with", + "endfor", "while", "do", "endwhile", + "repeat", "until", "endrepeat"] + end + + def self.operators + @operators||= Set.new [".", "!", "#", "+", "*", "-", "<<", + "/", "<", ">>", "<=", ">", "=", ">=", "@", "|", "~="] + end + + def self.punctuations + @punctuations ||= Set.new [ "{", "}", "[", "]", ",", "(", ")", ":=", ":", ";"] + end + + def self.transformers + @transformers ||= Set.new ["accumulate", "across", + "bycols", "bykey", "byrows", + "converse", "down", + "eachboth", "eachall", "each", + "eachleft", "eachright", + "filter", "fold", "fork", + "grade", "inner", "iterate", + "leaf", "no_tr", "outer", + "partition", "rank", "recur", + "reduce", "reducecols", "reducerows", + "sort", "team", "timeit", "twig"] + end + + def self.funcs + @funcs ||= Set.new ["operation", "expression", "and", "abs", + "allbools", "allints", "allchars", "allin", + "allreals", "allnumeric", "append", + "arcsin", "arccos", "appendfile", "apply", + "arctan", "atomic", "assign", "atversion", + "axes", "cart", "break", "blend", "breaklist", + "breakin", "bye", "callstack", "choose", "char", + "ceiling", "catenate", "charrep", "check_socket", + "cos", "content", "close", "clearws", + "clearprofile", "cols", "continue", "copyright", + "cosh", "cull", "count", "diverse", "deepplace", + "cutall", "cut", "display", "deparse", + "deepupdate", "descan", "depth", "diagram", + "div", "divide", "drop", "dropright", "edit", + "empty", "expression", "exit", "except", "erase", + "equal", "eval", "eraserecord", "execute", "exp", + "external", "exprs", "findall", "find", + "fault", "falsehood", "filestatus", "filelength", + "filepath", "filetally", "floor", "first", + "flip", "fuse", "fromraw", "front", + "gage", "getfile", "getdef", "getcommandline", + "getenv", "getname", "hitch", "grid", "getsyms", + "gradeup", "gt", "gte", "host", "in", "inverse", + "innerproduct", "inv", "ip", "ln", "link", "isboolean", + "isinteger", "ischar", "isfault", "isreal", "isphrase", + "isstring", "istruthvalue", "last", "laminate", + "like", "libpath", "library", "list", "load", + "loaddefs", "nonlocal", "max", "match", "log", + "lt", "lower", "lte", "mate", "min", "maxlength", + "mod", "mix", "minus", "nialroot", "mold", "not", + "numeric", "no_op", "no_expr", "notin", + "operation", "open", "or", "opposite", "opp", + "operators", "plus", "pick", "pack", "pass", "pair", "parse", + "paste", "phrase", "place", "picture", "placeall", + "power", "positions", "post", "quotient", "putfile", + "profile", "prod", "product", "profiletree", + "profiletable", "quiet_fault", "raise", "reach", + "random", "reciprocal", "read", "readfile", + "readchar", "readarray", "readfield", + "readscreen", "readrecord", "recip", "reshape", + "seek", "second", "rest", "reverse", "restart", + "return_status", "scan", "save", "rows", "rotate", + "seed", "see", "sublist", "sin", "simple", "shape", + "setformat", "setdeftrace", "set", "seeusercalls", + "seeprimcalls", "separator", "setwidth", "settrigger", + "setmessages", "setlogname", "setinterrupts", + "setprompt", "setprofile", "sinh", "single", + "sqrt", "solitary", "sketch", "sleep", + "socket_listen", "socket_accept", "socket_close", + "socket_bind", "socket_connect", "socket_getline", + "socket_receive", "socket_peek", "socket_read", + "socket_send", "socket_write", "solve", "split", + "sortup", "string", "status", "take", "symbols", + "sum", "system", "tan", "tally", "takeright", + "tanh", "tell", "tr", "times", "third", "time", + "toupper", "tolower", "timestamp", "tonumber", + "toraw", "toplevel", "transformer", "type", + "transpose", "trs", "truth", "unequal", + "variable", "valence", "up", "updateall", + "update", "vacate", "value", "version", "vars", + "void", "watch", "watchlist", "write", "writechars", + "writearray", "writefile", "writefield", + "writescreen", "writerecord"] + end + + def self.consts + @consts ||= Set.new %w(false null pi true) + end + + state :root do + rule %r/'/, Str::Single, :str + rule %r/\b[lo]+\b/, Num::Bin + rule %r/-?\d+((\.\d*)?[eE][+-]?\d|\.)\d*/, Num::Float + rule %r/\-?\d+/, Num::Integer + rule %r/`./, Str::Char + rule %r/"[^\s()\[\]{}#,;]*/, Str::Symbol + rule %r/\?[^\s()\[\]{}#,;]*/, Generic::Error + rule %r/%[^;]+;/, Comment::Multiline + rule %r/^#(.+\n)+\n/, Comment::Multiline + rule %r/:=|[\{\}\[\]\(\),:;]/ do |m| + if self.class.punctuations.include?(m[0]) + token Punctuation + else + token Text + end + end + # [".", "!", "#", "+", "*", "-", "<<", + # "/", "<", ">>", "<=", ">", "=", ">=", "@", "|", "~="] + rule %r'>>|>=|<=|~=|[\.!#+*\-=>|<|\+|-|\/|@|\$|~|&|%|\!|\?|\||\\|\[|\]/, Operator) + rule(/\.\.|\.|,|\[\.|\.\]|{\.|\.}|\(\.|\.\)|{|}|\(|\)|:|\^|`|;/, + Punctuation) + + # Strings + rule(/(?:\w+)"/,Str, :rdqs) + rule(/"""/, Str, :tdqs) + rule(/"/, Str, :dqs) + + # Char + rule(/'/, Str::Char, :chars) + + # Keywords + rule(%r[(#{Nim.underscorize(OPWORDS)})\b], Operator::Word) + rule(/(p_?r_?o_?c_?\s)(?![\(\[\]])/, Keyword, :funcname) + rule(%r[(#{Nim.underscorize(KEYWORDS)})\b], Keyword) + rule(%r[(#{Nim.underscorize(NAMESPACE)})\b], Keyword::Namespace) + rule(/(v_?a_?r)\b/, Keyword::Declaration) + rule(%r[(#{Nim.underscorize(TYPES)})\b], Keyword::Type) + rule(%r[(#{Nim.underscorize(PSEUDOKEYWORDS)})\b], Keyword::Pseudo) + # Identifiers + rule(/\b((?![_\d])\w)(((?!_)\w)|(_(?!_)\w))*/, Name) + + # Numbers + # Note: Have to do this with a block to push multiple states first, + # since we can't pass array of states like w/ Pygments. + rule(/[0-9][0-9_]*(?=([eE.]|'?[fF](32|64)))/) do + push :floatsuffix + push :floatnumber + token Num::Float + end + + rule(/0[xX][a-fA-F0-9][a-fA-F0-9_]*/, Num::Hex, :intsuffix) + rule(/0[bB][01][01_]*/, Num, :intsuffix) + rule(/0o[0-7][0-7_]*/, Num::Oct, :intsuffix) + rule(/[0-9][0-9_]*/, Num::Integer, :intsuffix) + + # Whitespace + rule(/\s+/, Text) + rule(/.+$/, Error) + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nix.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nix.rb new file mode 100644 index 0000000..7cc9a3a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/nix.rb @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Nix < RegexLexer + title 'Nix' + desc 'The Nix expression language (https://nixos.org/nix/manual/#ch-expression-language)' + tag 'nix' + aliases 'nixos' + filenames '*.nix' + + state :whitespaces do + rule %r/^\s*\n\s*$/m, Text + rule %r/\s+/, Text + end + + state :comment do + rule %r/#.*$/, Comment + rule %r(/\*), Comment, :multiline_comment + end + + state :multiline_comment do + rule %r(\*/), Comment, :pop! + rule %r/./, Comment + end + + state :number do + rule %r/[0-9]/, Num::Integer + end + + state :null do + rule %r/(null)/, Keyword::Constant + end + + state :boolean do + rule %r/(true|false)/, Keyword::Constant + end + + state :binding do + rule %r/[a-zA-Z_][a-zA-Z0-9-]*/, Name::Variable + end + + state :path do + word = "[a-zA-Z0-9\._-]+" + section = "(\/#{word})" + prefix = "[a-z\+]+:\/\/" + root = /#{section}+/.source + tilde = /~#{section}+/.source + basic = /#{word}(\/#{word})+/.source + url = /#{prefix}(\/?#{basic})/.source + rule %r/(#{root}|#{tilde}|#{basic}|#{url})/, Str::Other + end + + state :string do + rule %r/"/, Str::Double, :double_quoted_string + rule %r/''/, Str::Double, :indented_string + end + + state :string_content do + rule %r/\\./, Str::Escape + rule %r/\$\$/, Str::Escape + rule %r/\${/, Str::Interpol, :string_interpolated_arg + end + + state :indented_string_content do + rule %r/'''/, Str::Escape + rule %r/''\$/, Str::Escape + rule %r/\$\$/, Str::Escape + rule %r/''\\./, Str::Escape + rule %r/\${/, Str::Interpol, :string_interpolated_arg + end + + state :string_interpolated_arg do + mixin :expression + rule %r/}/, Str::Interpol, :pop! + end + + state :indented_string do + mixin :indented_string_content + rule %r/''/, Str::Double, :pop! + rule %r/./, Str::Double + end + + state :double_quoted_string do + mixin :string_content + rule %r/"/, Str::Double, :pop! + rule %r/./, Str::Double + end + + state :operator do + rule %r/(\.|\?|\+\+|\+|!=|!|\/\/|\=\=|&&|\|\||->|\/|\*|-|<|>|<=|=>)/, Operator + end + + state :assignment do + rule %r/(=)/, Operator + rule %r/(@)/, Operator + end + + state :accessor do + rule %r/(\$)/, Punctuation + end + + state :delimiter do + rule %r/(;|,|:)/, Punctuation + end + + state :atom_content do + mixin :expression + rule %r/\)/, Punctuation, :pop! + end + + state :atom do + rule %r/\(/, Punctuation, :atom_content + end + + state :list do + rule %r/\[/, Punctuation, :list_content + end + + state :list_content do + rule %r/\]/, Punctuation, :pop! + mixin :expression + end + + state :set do + rule %r/{/, Punctuation, :set_content + end + + state :set_content do + rule %r/}/, Punctuation, :pop! + mixin :expression + end + + state :expression do + mixin :ignore + mixin :comment + mixin :boolean + mixin :null + mixin :number + mixin :path + mixin :string + mixin :keywords + mixin :operator + mixin :accessor + mixin :assignment + mixin :delimiter + mixin :binding + mixin :atom + mixin :set + mixin :list + end + + state :keywords do + mixin :keywords_namespace + mixin :keywords_declaration + mixin :keywords_conditional + mixin :keywords_reserved + mixin :keywords_builtin + end + + state :keywords_namespace do + keywords = %w(with in inherit) + rule %r/(?:#{keywords.join('|')})\b/, Keyword::Namespace + end + + state :keywords_declaration do + keywords = %w(let) + rule %r/(?:#{keywords.join('|')})\b/, Keyword::Declaration + end + + state :keywords_conditional do + keywords = %w(if then else) + rule %r/(?:#{keywords.join('|')})\b/, Keyword + end + + state :keywords_reserved do + keywords = %w(rec assert map) + rule %r/(?:#{keywords.join('|')})\b/, Keyword::Reserved + end + + state :keywords_builtin do + keywords = %w( + abort + baseNameOf + builtins + derivation + fetchTarball + import + isNull + removeAttrs + throw + toString + ) + rule %r/(?:#{keywords.join('|')})\b/, Keyword::Reserved + end + + state :ignore do + mixin :whitespaces + end + + state :root do + mixin :ignore + mixin :expression + end + + start do + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c.rb new file mode 100644 index 0000000..f147851 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c.rb @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'c.rb' + load_lexer 'objective_c/common.rb' + + class ObjectiveC < C + extend ObjectiveCCommon + + tag 'objective_c' + title "Objective-C" + desc 'an extension of C commonly used to write Apple software' + aliases 'objc', 'obj-c', 'obj_c', 'objectivec', 'objective-c' + filenames '*.m', '*.h' + + mimetypes 'text/x-objective_c', 'application/x-objective_c' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c/common.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c/common.rb new file mode 100644 index 0000000..2cb8107 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_c/common.rb @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + module ObjectiveCCommon + def at_keywords + @at_keywords ||= %w( + selector private protected public encode synchronized try + throw catch finally end property synthesize dynamic optional + interface implementation import autoreleasepool + ) + end + + def at_builtins + @at_builtins ||= %w(true false YES NO) + end + + def builtins + @builtins ||= %w(YES NO nil) + end + + def self.extended(base) + base.prepend :statements do + rule %r/@"/, base::Str, :string + rule %r/@'(\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|\\.|[^\\'\n]')/, + base::Str::Char + rule %r/@(\d+[.]\d*|[.]\d+|\d+)e[+-]?\d+l?/i, + base::Num::Float + rule %r/@(\d+[.]\d*|[.]\d+|\d+f)f?/i, base::Num::Float + rule %r/@0x\h+[lL]?/, base::Num::Hex + rule %r/@0[0-7]+l?/i, base::Num::Oct + rule %r/@\d+l?/, base::Num::Integer + rule %r/\bin\b/, base::Keyword + + rule %r/@(?:interface|implementation)\b/, base::Keyword, :objc_classname + rule %r/@(?:class|protocol)\b/, base::Keyword, :forward_classname + + rule %r/@([[:alnum:]]+)/ do |m| + if base.at_keywords.include? m[1] + token base::Keyword + elsif base.at_builtins.include? m[1] + token base::Name::Builtin + else + token base::Error + end + end + + rule %r/[?]/, base::Punctuation, :ternary + rule %r/\[/, base::Punctuation, :message + rule %r/@\[/, base::Punctuation, :array_literal + rule %r/@\{/, base::Punctuation, :dictionary_literal + end + + id = /[a-z$_][a-z0-9$_]*/i + + base.state :ternary do + rule %r/:/, base::Punctuation, :pop! + mixin :statements + end + + base.state :message_shared do + rule %r/\]/, base::Punctuation, :pop! + rule %r/\{/, base::Punctuation, :pop! + rule %r/;/, base::Error + + mixin :statements + end + + base.state :message do + rule %r/(#{id})(\s*)(:)/ do + groups(base::Name::Function, base::Text, base::Punctuation) + goto :message_with_args + end + + rule %r/(#{id})(\s*)(\])/ do + groups(base::Name::Function, base::Text, base::Punctuation) + pop! + end + + mixin :message_shared + end + + base.state :message_with_args do + rule %r/\{/, base::Punctuation, :function + rule %r/(#{id})(\s*)(:)/ do + groups(base::Name::Function, base::Text, base::Punctuation) + pop! + end + + mixin :message_shared + end + + base.state :array_literal do + rule %r/]/, base::Punctuation, :pop! + rule %r/,/, base::Punctuation + mixin :statements + end + + base.state :dictionary_literal do + rule %r/}/, base::Punctuation, :pop! + rule %r/,/, base::Punctuation + mixin :statements + end + + base.state :objc_classname do + mixin :whitespace + + rule %r/(#{id})(\s*)(:)(\s*)(#{id})/ do + groups(base::Name::Class, base::Text, + base::Punctuation, base::Text, + base::Name::Class) + pop! + end + + rule %r/(#{id})(\s*)([(])(\s*)(#{id})(\s*)([)])/ do + groups(base::Name::Class, base::Text, + base::Punctuation, base::Text, + base::Name::Label, base::Text, + base::Punctuation) + pop! + end + + rule id, base::Name::Class, :pop! + end + + base.state :forward_classname do + mixin :whitespace + + rule %r/(#{id})(\s*)(,)(\s*)/ do + groups(base::Name::Class, base::Text, base::Punctuation, base::Text) + push + end + + rule %r/(#{id})(\s*)(;?)/ do + groups(base::Name::Class, base::Text, base::Punctuation) + pop! + end + end + + base.prepend :root do + rule %r( + ([-+])(\s*) + ([(].*?[)])?(\s*) + (?=#{id}:?) + )ix do |m| + token base::Keyword, m[1] + token base::Text, m[2] + recurse(m[3]) if m[3] + token base::Text, m[4] + push :method_definition + end + end + + base.state :method_definition do + rule %r/,/, base::Punctuation + rule %r/[.][.][.]/, base::Punctuation + rule %r/([(].*?[)])(#{id})/ do |m| + recurse m[1]; token base::Name::Variable, m[2] + end + + rule %r/(#{id})(\s*)(:)/m do + groups(base::Name::Function, base::Text, base::Punctuation) + end + + rule %r/;/, base::Punctuation, :pop! + + rule %r/{/ do + token base::Punctuation + goto :function + end + + mixin :inline_whitespace + rule %r(//.*?\n), base::Comment::Single + rule %r/\s+/m, base::Text + + rule(//) { pop! } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_cpp.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_cpp.rb new file mode 100644 index 0000000..2160692 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/objective_cpp.rb @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'cpp.rb' + load_lexer 'objective_c/common.rb' + + class ObjectiveCpp < Cpp + extend ObjectiveCCommon + + tag 'objective_cpp' + title "Objective-C++" + desc 'an extension of C++ uncommonly used to write Apple software' + aliases 'objcpp', 'obj-cpp', 'obj_cpp', 'objectivecpp', + 'objc++', 'obj-c++', 'obj_c++', 'objectivec++' + filenames '*.mm', '*.h' + + mimetypes 'text/x-objective-c++', 'application/x-objective-c++' + + prepend :statements do + rule %r/(\.)(class)/ do + groups(Operator, Name::Builtin::Pseudo) + end + rule %r/(@selector)(\()(class)(\))/ do + groups(Keyword, Punctuation, Name::Builtin::Pseudo, Punctuation) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml.rb new file mode 100644 index 0000000..684b367 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml.rb @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'ocaml/common.rb' + + class OCaml < OCamlCommon + title "OCaml" + desc 'Objective Caml (ocaml.org)' + tag 'ocaml' + filenames '*.ml', '*.mli', '*.mll', '*.mly' + mimetypes 'text/x-ocaml' + + def self.keywords + @keywords ||= super + Set.new(%w( + match raise + )) + end + + state :root do + rule %r/\s+/m, Text + rule %r/false|true|[(][)]|\[\]/, Name::Builtin::Pseudo + rule %r/#{@@upper_id}(?=\s*[.])/, Name::Namespace, :dotted + rule %r/`#{@@id}/, Name::Tag + rule @@upper_id, Name::Class + rule %r/[(][*](?![)])/, Comment, :comment + rule @@id do |m| + match = m[0] + if self.class.keywords.include? match + token Keyword + elsif self.class.word_operators.include? match + token Operator::Word + elsif self.class.primitives.include? match + token Keyword::Type + else + token Name + end + end + + rule %r/[(){}\[\];]+/, Punctuation + rule @@operator, Operator + + rule %r/-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i, Num::Float + rule %r/0x\h[\h_]*/i, Num::Hex + rule %r/0o[0-7][0-7_]*/i, Num::Oct + rule %r/0b[01][01_]*/i, Num::Bin + rule %r/\d[\d_]*/, Num::Integer + + rule %r/'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/, Str::Char + rule %r/'[.]'/, Str::Char + rule %r/'/, Keyword + rule %r/"/, Str::Double, :string + rule %r/[~?]#{@@id}/, Name::Variable + end + + state :comment do + rule %r/[^(*)]+/, Comment + rule(/[(][*]/) { token Comment; push } + rule %r/[*][)]/, Comment, :pop! + rule %r/[(*)]/, Comment + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml/common.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml/common.rb new file mode 100644 index 0000000..bd6f93d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocaml/common.rb @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + # shared states with Reasonml and ReScript + class OCamlCommon < RegexLexer + def self.keywords + @keywords ||= Set.new %w( + as assert begin class constraint do done downto else end + exception external false for fun function functor if in + include inherit initializer lazy let module mutable new + nonrec object of open rec sig struct then to true try type + val virtual when while with + ) + end + + def self.word_operators + @word_operators ||= Set.new %w(and asr land lor lsl lxor mod or) + end + + def self.primitives + @primitives ||= Set.new %w(unit int float bool string char list array) + end + + @@operator = %r([;,_!$%&*+./:<=>?@^|~#-]+) + @@id = /[a-z_][\w']*/i + @@upper_id = /[A-Z][\w']*/ + + state :string do + rule %r/[^\\"]+/, Str::Double + mixin :escape_sequence + rule %r/\\\n/, Str::Double + rule %r/"/, Str::Double, :pop! + end + + state :escape_sequence do + rule %r/\\[\\"'ntbr]/, Str::Escape + rule %r/\\\d{3}/, Str::Escape + rule %r/\\x\h{2}/, Str::Escape + end + + state :dotted do + rule %r/\s+/m, Text + rule %r/[.]/, Punctuation + rule %r/#{@@upper_id}(?=\s*[.])/, Name::Namespace + rule @@upper_id, Name::Class, :pop! + rule @@id, Name, :pop! + rule %r/[({\[]/, Punctuation, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocl.rb new file mode 100644 index 0000000..6511ffa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ocl.rb @@ -0,0 +1,84 @@ +module Rouge + module Lexers + class OCL < RegexLexer + title "OCL" + desc "OMG Object Constraint Language (omg.org/spec/OCL)" + tag 'ocl' + aliases 'OCL' + filenames '*.ocl' + mimetypes 'text/x-ocl' + + def self.keywords + @keywords ||= Set.new %w( + context pre post inv init body def derive if then else endif import + package endpackage let in + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + Boolean Integer UnlimitedNatural Real String OrderedSet Tuple Bag Set + Sequence OclInvalid OclVoid TupleType OclState Collection OclMessage + ) + end + + def self.builtins + @builtins ||= Set.new %w( + self null result true false invalid @pre + ) + end + + def self.operators + @operators ||= Set.new %w( + or xor and not implies + ) + end + + def self.functions + @functions ||= Set.new %w( + oclAsSet oclIsNew oclIsUndefined oclIsInvalid oclAsType oclIsTypeOf + oclIsKindOf oclInState oclType oclLocale hasReturned result + isSignalSent isOperationCallabs floor round max min toString div mod + size substring concat toInteger toReal toUpperCase toLowerCase + indexOf equalsIgnoreCase at characters toBoolean includes excludes + count includesAll excludesAll isEmpty notEmpty sum product + selectByKind selectByType asBag asSequence asOrderedSet asSet flatten + union intersection including excluding symmetricDifferencecount + append prepend insertAt subOrderedSet first last reverse subSequence + any closure collect collectNested exists forAll isUnique iterate one + reject select sortedBy allInstances average conformsTo + ) + end + + state :single_string do + rule %r/\\./, Str::Escape + rule %r/'/, Str::Single, :pop! + rule %r/[^\\']+/, Str::Single + end + + state :root do + rule %r/\s+/m, Text + rule %r/--.*/, Comment::Single + rule %r/\d+/, Num::Integer + rule %r/'/, Str::Single, :single_string + rule %r([-|+*/<>=~!@#%&?^]), Operator + rule %r/[;:()\[\],.]/, Punctuation + rule %r/[a-zA-Z]\w*/ do |m| + if self.class.operators.include? m[0] + token Operator + elsif self.class.keywords_type.include? m[0] + token Keyword::Declaration + elsif self.class.keywords.include? m[0] + token Keyword + elsif self.class.builtins.include? m[0] + token Name::Builtin + elsif self.class.functions.include? m[0] + token Name::Function + else + token Name + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/openedge.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/openedge.rb new file mode 100644 index 0000000..8250127 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/openedge.rb @@ -0,0 +1,632 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class OpenEdge < RegexLexer + tag 'openedge' + aliases 'abl' + filenames '*.w', '*.i', '*.p', '*.cls', '*.df' + mimetypes 'text/x-openedge' + + title 'OpenEdge ABL' + desc 'The OpenEdge ABL programming language' + + id = /[a-zA-Z_&{}!][a-zA-Z0-9_\-&!}]*/ + + def self.keywords + @keywords ||= Set.new %w( + ABORT ABS ABSO ABSOL ABSOLU ABSOLUT ABSOLUTE ABSTRACT ACCELERATOR ACCEPT-CHANGES ACCEPT-ROW-CHANGES + ACCUM ACCUMU ACCUMUL ACCUMULA ACCUMULAT ACCUMULATE ACROSS ACTIVE ACTIVE-FORM ACTIVE-WINDOW ACTOR ADD + ADD-BUFFER ADD-CALC-COL ADD-CALC-COLU ADD-CALC-COLUM ADD-CALC-COLUMN ADD-COLUMNS-FROM + ADD-EVENTS-PROC ADD-EVENTS-PROCE ADD-EVENTS-PROCED ADD-EVENTS-PROCEDU ADD-EVENTS-PROCEDUR + ADD-EVENTS-PROCEDURE ADD-FIELDS-FROM ADD-FIRST ADD-HEADER-ENTRY ADD-INDEX-FIELD ADD-INTERVAL + ADD-LAST ADD-LIKE-COLUMN ADD-LIKE-FIELD ADD-LIKE-INDEX ADD-NEW-FIELD ADD-NEW-INDEX + ADD-SCHEMA-LOCATION ADD-SOURCE-BUFFER ADD-SUPER-PROC ADD-SUPER-PROCE ADD-SUPER-PROCED + ADD-SUPER-PROCEDU ADD-SUPER-PROCEDUR ADD-SUPER-PROCEDURE ADM-DATA ADVISE AFTER-BUFFER AFTER-ROWID + AFTER-TABLE ALERT-BOX ALIAS ALL ALLOW-COLUMN-SEARCHING ALLOW-PREV-DESERIALIZATION ALLOW-REPLICATION + ALTER ALTERNATE-KEY ALWAYS-ON-TOP AMBIG AMBIGU AMBIGUO AMBIGUOU AMBIGUOUS ANALYZ ANALYZE AND + ANSI-ONLY ANY ANY-KEY ANY-PRINTABLE ANYWHERE APPEND APPEND-CHILD APPEND-LINE APPL-ALERT APPL-ALERT- + APPL-ALERT-B APPL-ALERT-BO APPL-ALERT-BOX APPL-ALERT-BOXE APPL-ALERT-BOXES APPL-CONTEXT-ID + APPLICATION APPLY APPLY-CALLBACK APPSERVER-INFO APPSERVER-PASSWORD APPSERVER-USERID ARRAY-M ARRAY-ME + ARRAY-MES ARRAY-MESS ARRAY-MESSA ARRAY-MESSAG ARRAY-MESSAGE AS ASC ASCE ASCEN ASCEND ASCENDI + ASCENDIN ASCENDING AS-CURSOR ASK-OVERWRITE ASSEMBLY ASSIGN ASYNCHRONOUS ASYNC-REQUEST-COUNT + ASYNC-REQUEST-HANDLE AT ATTACH ATTACH-DATA-SOURCE ATTACHED-PAIRLIST ATTACHMENT ATTR ATTR- + ATTRIBUTE-NAMES ATTRIBUTE-TYPE ATTR-S ATTR-SP ATTR-SPA ATTR-SPAC ATTR-SPACE AUDIT-CONTROL + AUDIT-ENABLED AUDIT-EVENT-CONTEXT AUDIT-POLICY AUTHENTICATION-FAILED AUTHORIZATION AUTO-COMP + AUTO-COMPL AUTO-COMPLE AUTO-COMPLET AUTO-COMPLETI AUTO-COMPLETIO AUTO-COMPLETION AUTO-DELETE + AUTO-DELETE-XML AUTO-ENDKEY AUTO-END-KEY AUTO-GO AUTO-IND AUTO-INDE AUTO-INDEN AUTO-INDENT AUTOMATIC + AUTO-RESIZE AUTO-RET AUTO-RETU AUTO-RETUR AUTO-RETURN AUTO-SYNCHRONIZE AUTO-VAL AUTO-VALI AUTO-VALID + AUTO-VALIDA AUTO-VALIDAT AUTO-VALIDATE AUTO-Z AUTO-ZA AUTO-ZAP AVAIL AVAILA AVAILAB AVAILABL + AVAILABLE AVAILABLE-FORMATS AVE AVER AVERA AVERAG AVERAGE AVG BACK BACKG BACKGR BACKGRO BACKGROU + BACKGROUN BACKGROUND BACKSPACE BACK-TAB BACKWARD BACKWARDS BASE64 BASE64-DECODE BASE64-ENCODE + BASE-ADE BASE-KEY BASIC-LOGGING BATCH BATCH-MODE BATCH-SIZE BEFORE-BUFFER BEFORE-H BEFORE-HI + BEFORE-HID BEFORE-HIDE BEFORE-ROWID BEFORE-TABLE BEGIN-EVENT-GROUP BEGINS BELL BETWEEN BGC BGCO + BGCOL BGCOLO BGCOLOR BIG-ENDIAN BINARY BIND BIND-WHERE BLANK BLOB BLOCK BLOCK-ITERATION-DISPLAY + BLOCK-LEV BLOCK-LEVE BLOCK-LEVEL BORDER-B BORDER-BO BORDER-BOT BORDER-BOTT BORDER-BOTTO + BORDER-BOTTOM BORDER-BOTTOM-C BORDER-BOTTOM-CH BORDER-BOTTOM-CHA BORDER-BOTTOM-CHAR + BORDER-BOTTOM-CHARS BORDER-BOTTOM-P BORDER-BOTTOM-PI BORDER-BOTTOM-PIX BORDER-BOTTOM-PIXE + BORDER-BOTTOM-PIXEL BORDER-BOTTOM-PIXELS BORDER-L BORDER-LE BORDER-LEF BORDER-LEFT BORDER-LEFT-C + BORDER-LEFT-CH BORDER-LEFT-CHA BORDER-LEFT-CHAR BORDER-LEFT-CHARS BORDER-LEFT-P BORDER-LEFT-PI + BORDER-LEFT-PIX BORDER-LEFT-PIXE BORDER-LEFT-PIXEL BORDER-LEFT-PIXELS BORDER-R BORDER-RI BORDER-RIG + BORDER-RIGH BORDER-RIGHT BORDER-RIGHT-C BORDER-RIGHT-CH BORDER-RIGHT-CHA BORDER-RIGHT-CHAR + BORDER-RIGHT-CHARS BORDER-RIGHT-P BORDER-RIGHT-PI BORDER-RIGHT-PIX BORDER-RIGHT-PIXE + BORDER-RIGHT-PIXEL BORDER-RIGHT-PIXELS BORDER-T BORDER-TO BORDER-TOP BORDER-TOP-C BORDER-TOP-CH + BORDER-TOP-CHA BORDER-TOP-CHAR BORDER-TOP-CHARS BORDER-TOP-P BORDER-TOP-PI BORDER-TOP-PIX + BORDER-TOP-PIXE BORDER-TOP-PIXEL BORDER-TOP-PIXELS BOTH BOTTOM BOTTOM-COLUMN BOX BOX-SELECT + BOX-SELECTA BOX-SELECTAB BOX-SELECTABL BOX-SELECTABLE BREAK BREAK-LINE BROWSE BROWSE-COLUMN-DATA-TYPES + BROWSE-COLUMN-FORMATS BROWSE-COLUMN-LABELS BROWSE-HEADER BTOS BUFFER BUFFER-CHARS BUFFER-COMP + BUFFER-COMPA BUFFER-COMPAR BUFFER-COMPARE BUFFER-COPY BUFFER-CREATE BUFFER-DELETE BUFFER-FIELD + BUFFER-GROUP-ID BUFFER-GROUP-NAME BUFFER-HANDLE BUFFER-LINES BUFFER-N BUFFER-NA BUFFER-NAM + BUFFER-NAME BUFFER-PARTITION-ID BUFFER-RELEAS BUFFER-RELEASE BUFFER-TENANT-ID BUFFER-TENANT-NAME + BUFFER-VALIDATE BUFFER-VALUE BUTTON BUTTONS BY BY-POINTER BY-REFERENCE BYTE BYTES-READ BYTES-WRITTEN + BY-VALUE BY-VARIANT-POINT BY-VARIANT-POINTE BY-VARIANT-POINTER CACHE CACHE-SIZE CALL CALL-NAME + CALL-TYPE CANCEL-BREAK CANCEL-BUTTON CANCELLED CANCEL-PICK CANCEL-REQUESTS CANCEL-REQUESTS-AFTER + CAN-CREA CAN-CREAT CAN-CREATE CAN-DELE CAN-DELET CAN-DELETE CAN-DO CAN-DO-DOMAIN-SUPPORT CAN-FIND + CAN-QUERY CAN-READ CAN-SET CAN-WRIT CAN-WRITE CAPS CAREFUL-PAINT CASE CASE-SEN CASE-SENS CASE-SENSI + CASE-SENSIT CASE-SENSITI CASE-SENSITIV CASE-SENSITIVE CAST CATCH CDECL CENTER CENTERE CENTERED + CHAINED CHAR CHARA CHARAC CHARACT CHARACTE CHARACTER CHARACTER_LENGTH CHARSET CHECK CHECKED + CHECK-MEM-STOMP CHILD-BUFFER CHILD-NUM CHOICES CHOOSE CHR CLASS CLASS-TYPE CLEAR CLEAR-APPL-CONTEXT + CLEAR-LOG CLEAR-SELECT CLEAR-SELECTI CLEAR-SELECTIO CLEAR-SELECTION CLEAR-SORT-ARROW + CLEAR-SORT-ARROWS CLIENT-CONNECTION-ID CLIENT-PRINCIPAL CLIENT-TTY CLIENT-TYPE CLIENT-WORKSTATION + CLIPBOARD CLOB CLONE-NODE CLOSE CLOSE-LOG CODE CODEBASE-LOCATOR CODEPAGE CODEPAGE-CONVERT COL + COLLATE COL-OF COLON COLON-ALIGN COLON-ALIGNE COLON-ALIGNED COLOR COLOR-TABLE COLUMN COLUMN-BGC + COLUMN-BGCO COLUMN-BGCOL COLUMN-BGCOLO COLUMN-BGCOLOR COLUMN-CODEPAGE COLUMN-DCOLOR COLUMN-FGC + COLUMN-FGCO COLUMN-FGCOL COLUMN-FGCOLO COLUMN-FGCOLOR COLUMN-FONT COLUMN-LAB COLUMN-LABE + COLUMN-LABEL COLUMN-LABEL-BGC COLUMN-LABEL-BGCO COLUMN-LABEL-BGCOL COLUMN-LABEL-BGCOLO + COLUMN-LABEL-BGCOLOR COLUMN-LABEL-DCOLOR COLUMN-LABEL-FGC COLUMN-LABEL-FGCO COLUMN-LABEL-FGCOL + COLUMN-LABEL-FGCOLO COLUMN-LABEL-FGCOLOR COLUMN-LABEL-FONT COLUMN-LABEL-HEIGHT-C + COLUMN-LABEL-HEIGHT-CH COLUMN-LABEL-HEIGHT-CHA COLUMN-LABEL-HEIGHT-CHAR COLUMN-LABEL-HEIGHT-CHARS + COLUMN-LABEL-HEIGHT-P COLUMN-LABEL-HEIGHT-PI COLUMN-LABEL-HEIGHT-PIX COLUMN-LABEL-HEIGHT-PIXE + COLUMN-LABEL-HEIGHT-PIXEL COLUMN-LABEL-HEIGHT-PIXELS COLUMN-MOVABLE COLUMN-OF COLUMN-PFC COLUMN-PFCO + COLUMN-PFCOL COLUMN-PFCOLO COLUMN-PFCOLOR COLUMN-READ-ONLY COLUMN-RESIZABLE COLUMNS COLUMN-SC + COLUMN-SCR COLUMN-SCRO COLUMN-SCROL COLUMN-SCROLL COLUMN-SCROLLI COLUMN-SCROLLIN COLUMN-SCROLLING + COMBO-BOX COM-HANDLE COMMAND COMPARE COMPARES COMPILE COMPILER COMPLETE COMPONENT-HANDLE + COMPONENT-SELF COM-SELF CONFIG-NAME CONNECT CONNECTED CONSTRAINED CONSTRUCTOR CONTAINER-EVENT + CONTAINS CONTENTS CONTEXT CONTEXT-HELP CONTEXT-HELP-FILE CONTEXT-HELP-ID CONTEXT-POP CONTEXT-POPU + CONTEXT-POPUP CONTROL CONTROL-BOX CONTROL-CONT CONTROL-CONTA CONTROL-CONTAI CONTROL-CONTAIN + CONTROL-CONTAINE CONTROL-CONTAINER CONTROL-FRAM CONTROL-FRAME CONVERT CONVERT-3D CONVERT-3D- + CONVERT-3D-C CONVERT-3D-CO CONVERT-3D-COL CONVERT-3D-COLO CONVERT-3D-COLOR CONVERT-3D-COLORS + CONVERT-TO-OFFS CONVERT-TO-OFFSE CONVERT-TO-OFFSET COPY COPY-DATASET COPY-LOB COPY-SAX-ATTRIBUTES + COPY-TEMP-TABLE COUNT COUNT-OF COVERAGE CPCASE CPCOLL CPINT CPINTE CPINTER CPINTERN CPINTERNA + CPINTERNAL CPLOG CPPRINT CPRCODEIN CPRCODEOUT CPSTREAM CPTERM CRC-VAL CRC-VALU CRC-VALUE CREATE + CREATE-LIKE CREATE-LIKE-SEQUENTIAL CREATE-NODE CREATE-NODE-NAMESPACE CREATE-ON-ADD + CREATE-RESULT-LIST-ENTRY CREATE-TEST-FILE CTOS CURRENT CURRENT_DATE CURRENT-CHANGED CURRENT-COLUMN + CURRENT-ENV CURRENT-ENVI CURRENT-ENVIR CURRENT-ENVIRO CURRENT-ENVIRON CURRENT-ENVIRONM + CURRENT-ENVIRONME CURRENT-ENVIRONMEN CURRENT-ENVIRONMENT CURRENT-ITERATION CURRENT-LANG + CURRENT-LANGU CURRENT-LANGUA CURRENT-LANGUAG CURRENT-LANGUAGE CURRENT-QUERY CURRENT-REQUEST-INFO + CURRENT-RESPONSE-INFO CURRENT-RESULT-ROW CURRENT-ROW-MODIFIED CURRENT-VALUE CURRENT-WINDOW CURS + CURSO CURSOR CURSOR-CHAR CURSOR-DOWN CURSOR-LEFT CURSOR-LINE CURSOR-OFFSET CURSOR-RIGHT CURSOR-UP + CUT DATA-B DATABASE DATA-BI DATA-BIN DATA-BIND DATA-ENTRY-RET DATA-ENTRY-RETU DATA-ENTRY-RETUR + DATA-ENTRY-RETURN DATA-REFRESH-LINE DATA-REFRESH-PAGE DATA-REL DATA-RELA DATA-RELAT DATA-RELATI + DATA-RELATIO DATA-RELATION DATASERVERS DATASET DATASET-HANDLE DATA-SOURCE DATA-SOURCE-COMPLETE-MAP + DATA-SOURCE-MODIFIED DATA-SOURCE-ROWID DATA-T DATA-TY DATA-TYP DATA-TYPE DATE DATE-F DATE-FO + DATE-FOR DATE-FORM DATE-FORMA DATE-FORMAT DATETIME DATETIME-TZ DAY DBCODEPAGE DBCOLLATION DB-CONTEXT + DB-LIST DBNAME DBPARAM DB-REFERENCES DB-REMOTE-HOST DBREST DBRESTR DBRESTRI DBRESTRIC DBRESTRICT + DBRESTRICTI DBRESTRICTIO DBRESTRICTION DBRESTRICTIONS DBTASKID DBTYPE DBVERS DBVERSI DBVERSIO + DBVERSION DCOLOR DDE DDE-ERROR DDE-I DDE-ID DDE-ITEM DDE-NAME DDE-NOTIFY DDE-TOPIC DEBLANK DEBU + DEBUG DEBUG-ALERT DEBUGGER DEBUG-LIST DEBUG-SET-TENANT DEC DECI DECIM DECIMA DECIMAL DECIMALS + DECLARE DECLARE-NAMESPACE DECRYPT DEF DEFAULT DEFAULT-ACTION DEFAULT-BUFFER-HANDLE DEFAULT-BUT + DEFAULT-BUTT DEFAULT-BUTTO DEFAULT-BUTTON DEFAULT-COMMIT DEFAULT-EX DEFAULT-EXT DEFAULT-EXTE + DEFAULT-EXTEN DEFAULT-EXTENS DEFAULT-EXTENSI DEFAULT-EXTENSIO DEFAULT-EXTENSION DEFAULT-NOXL + DEFAULT-NOXLA DEFAULT-NOXLAT DEFAULT-NOXLATE DEFAULT-POP-UP DEFAULT-STRING DEFAULT-VALUE + DEFAULT-WINDOW DEFAUT-B DEFER-LOB-FETCH DEFI DEFIN DEFINE DEFINED DEFINE-USER-EVENT-MANAGER DEL + DELEGATE DELETE DELETE-CHAR DELETE-CHARACTER DELETE-COLUMN DELETE-CURRENT-ROW DELETE-END-LINE + DELETE-FIELD DELETE-HEADER-ENTRY DELETE-LINE DELETE-NODE DELETE-RESULT-LIST-ENTRY + DELETE-SELECTED-ROW DELETE-SELECTED-ROWS DELETE-WORD DELIMITER DESC DESCE DESCEN DESCEND DESCENDI + DESCENDIN DESCENDING DESCRIPT DESCRIPTI DESCRIPTIO DESCRIPTION DESELECT DESELECT-EXTEND + DESELECT-FOCUSED-ROW DESELECTION DESELECTION-EXTEND DESELECT-ROWS DESELECT-SELECTED-ROW DESTRUCTOR + DETACH DETACH-DATA-SOURCE DIALOG-BOX DIALOG-HELP DICT DICTI DICTIO DICTION DICTIONA DICTIONAR + DICTIONARY DIR DIRECTORY DISABLE DISABLE-AUTO-ZAP DISABLE-CONNECTIONS DISABLED DISABLE-DUMP-TRIGGERS + DISABLE-LOAD-TRIGGERS DISCON DISCONN DISCONNE DISCONNEC DISCONNECT DISMISS-MENU DISP DISPL DISPLA + DISPLAY DISPLAY-MESSAGE DISPLAY-T DISPLAY-TIMEZONE DISPLAY-TY DISPLAY-TYP DISPLAY-TYPE DISTINCT + DLL-CALL-TYPE DO DOMAIN-DESCRIPTION DOMAIN-NAME DOMAIN-TYPE DOS DOS-END DOTNET-CLR-LOADED DOUBLE + DOWN DRAG-ENABLED DROP DROP-DOWN DROP-DOWN-LIST DROP-FILE-NOTIFY DROP-TARGET DS-CLOSE-CURSOR + DSLOG-MANAGER DUMP DUMP-LOGGING-NOW DYNAMIC DYNAMIC-CAST DYNAMIC-CURRENT-VALUE DYNAMIC-ENUM + DYNAMIC-FUNC DYNAMIC-FUNCT DYNAMIC-FUNCTI DYNAMIC-FUNCTIO DYNAMIC-FUNCTION DYNAMIC-INVOKE + DYNAMIC-NEW DYNAMIC-NEXT-VALUE DYNAMIC-PROPERTY EACH ECHO EDGE EDGE-C EDGE-CH EDGE-CHA EDGE-CHAR + EDGE-CHARS EDGE-P EDGE-PI EDGE-PIX EDGE-PIXE EDGE-PIXEL EDGE-PIXELS EDIT-CAN-PASTE EDIT-CAN-UNDO + EDIT-CLEAR EDIT-COPY EDIT-CUT EDITING EDITOR EDITOR-BACKTAB EDITOR-TAB EDIT-PASTE EDIT-UNDO ELSE + EMPTY EMPTY-DATASET EMPTY-SELECTION EMPTY-TEMP-TABLE ENABLE ENABLE-CONNECTIONS ENABLED + ENABLED-FIELDS ENCODE ENCODE-DOMAIN-ACCESS-CODE ENCODING ENCRYPT ENCRYPT-AUDIT-MAC-KEY + ENCRYPTION-SALT END END-BOX-SELECTION END-DOCUMENT END-ELEMENT END-ERROR END-EVENT-GROUP + END-FILE-DROP ENDKEY END-KEY END-MOVE END-RESIZE END-ROW-RESIZE END-SEARCH END-USER-PROMPT ENTERED + ENTER-MENUBAR ENTITY-EXPANSION-LIMIT ENTRY ENTRY-TYPES-LIST ENUM EQ ERROR ERROR-COL ERROR-COLU + ERROR-COLUM ERROR-COLUMN ERROR-OBJECT ERROR-OBJECT-DETAIL ERROR-ROW ERROR-STACK-TRACE ERROR-STAT + ERROR-STATU ERROR-STATUS ERROR-STRING ESCAPE ETIME EVENT EVENT-GROUP-ID EVENT-PROCEDURE + EVENT-PROCEDURE-CONTEXT EVENTS EVENT-T EVENT-TY EVENT-TYP EVENT-TYPE EXCEPT EXCLUSIVE EXCLUSIVE-ID + EXCLUSIVE-L EXCLUSIVE-LO EXCLUSIVE-LOC EXCLUSIVE-LOCK EXCLUSIVE-WEB EXCLUSIVE-WEB- EXCLUSIVE-WEB-U + EXCLUSIVE-WEB-US EXCLUSIVE-WEB-USE EXCLUSIVE-WEB-USER EXECUTE EXECUTION-LOG EXISTS EXIT EXIT-CODE + EXP EXPAND EXPANDABLE EXPIRE EXPLICIT EXPORT EXPORT-PRINCIPAL EXTENDED EXTENT EXTERNAL EXTRACT FALSE + FALSE-LEAKS FETCH FETCH-SELECTED-ROW FGC FGCO FGCOL FGCOLO FGCOLOR FIELD FIELDS FILE FILE-ACCESS-D + FILE-ACCESS-DA FILE-ACCESS-DAT FILE-ACCESS-DATE FILE-ACCESS-T FILE-ACCESS-TI FILE-ACCESS-TIM + FILE-ACCESS-TIME FILE-CREATE-D FILE-CREATE-DA FILE-CREATE-DAT FILE-CREATE-DATE FILE-CREATE-T + FILE-CREATE-TI FILE-CREATE-TIM FILE-CREATE-TIME FILE-INFO FILE-INFOR FILE-INFORM FILE-INFORMA + FILE-INFORMAT FILE-INFORMATI FILE-INFORMATIO FILE-INFORMATION FILE-MOD-D FILE-MOD-DA FILE-MOD-DAT + FILE-MOD-DATE FILE-MOD-T FILE-MOD-TI FILE-MOD-TIM FILE-MOD-TIME FILENAME FILE-NAME FILE-OFF + FILE-OFFS FILE-OFFSE FILE-OFFSET FILE-SIZE FILE-TYPE FILL FILLED FILL-IN FILL-MODE FILL-WHERE-STRING + FILTERS FINAL FINALLY FIND FIND-BY-ROWID FIND-CASE-SENSITIVE FIND-CURRENT FINDER FIND-FIRST + FIND-GLOBAL FIND-LAST FIND-NEXT FIND-NEXT-OCCURRENCE FIND-PREVIOUS FIND-PREV-OCCURRENCE FIND-SELECT + FIND-UNIQUE FIND-WRAP-AROUND FIREHOSE-CURSOR FIRST FIRST-ASYNC FIRST-ASYNC- FIRST-ASYNCH-REQUEST + FIRST-ASYNC-R FIRST-ASYNC-RE FIRST-ASYNC-REQ FIRST-ASYNC-REQU FIRST-ASYNC-REQUE FIRST-ASYNC-REQUES + FIRST-ASYNC-REQUEST FIRST-BUFFER FIRST-CHILD FIRST-COLUMN FIRST-DATASET FIRST-DATA-SOURCE FIRST-FORM + FIRST-OBJECT FIRST-OF FIRST-PROC FIRST-PROCE FIRST-PROCED FIRST-PROCEDU FIRST-PROCEDUR + FIRST-PROCEDURE FIRST-QUERY FIRST-SERV FIRST-SERVE FIRST-SERVER FIRST-SERVER-SOCKET FIRST-SOCKET + FIRST-TAB-I FIRST-TAB-IT FIRST-TAB-ITE FIRST-TAB-ITEM FIT-LAST-COLUMN FIX-CODEPAGE FIXED-ONLY FLAGS + FLAT-BUTTON FLOAT FOCUS FOCUSED-ROW FOCUSED-ROW-SELECTED FOCUS-IN FONT FONT-TABLE FOR FORCE-FILE + FORE FOREG FOREGR FOREGRO FOREGROU FOREGROUN FOREGROUND FOREIGN-KEY-HIDDEN FORM FORMA FORMAT + FORMATTE FORMATTED FORM-INPUT FORM-LONG-INPUT FORWARD FORWARD-ONLY FORWARDS FRAGMEN FRAGMENT FRAM + FRAME FRAME-COL FRAME-DB FRAME-DOWN FRAME-FIELD FRAME-FILE FRAME-INDE FRAME-INDEX FRAME-LINE + FRAME-NAME FRAME-ROW FRAME-SPA FRAME-SPAC FRAME-SPACI FRAME-SPACIN FRAME-SPACING FRAME-VAL + FRAME-VALU FRAME-VALUE FRAME-X FRAME-Y FREQUENCY FROM FROM-C FROM-CH FROM-CHA FROM-CHAR FROM-CHARS + FROM-CUR FROM-CURR FROM-CURRE FROM-CURREN FROM-CURRENT FROMNOREORDER FROM-P FROM-PI FROM-PIX + FROM-PIXE FROM-PIXEL FROM-PIXELS FULL-HEIGHT FULL-HEIGHT-C FULL-HEIGHT-CH FULL-HEIGHT-CHA + FULL-HEIGHT-CHAR FULL-HEIGHT-CHARS FULL-HEIGHT-P FULL-HEIGHT-PI FULL-HEIGHT-PIX FULL-HEIGHT-PIXE + FULL-HEIGHT-PIXEL FULL-HEIGHT-PIXELS FULL-PATHN FULL-PATHNA FULL-PATHNAM FULL-PATHNAME FULL-WIDTH + FULL-WIDTH- FULL-WIDTH-C FULL-WIDTH-CH FULL-WIDTH-CHA FULL-WIDTH-CHAR FULL-WIDTH-CHARS FULL-WIDTH-P + FULL-WIDTH-PI FULL-WIDTH-PIX FULL-WIDTH-PIXE FULL-WIDTH-PIXEL FULL-WIDTH-PIXELS FUNCTION + FUNCTION-CALL-TYPE GATEWAY GATEWAYS GE GENERATE-MD5 GENERATE-PBE-KEY GENERATE-PBE-SALT + GENERATE-RANDOM-KEY GENERATE-UUID GET GET-ATTR-CALL-TYPE GET-ATTRIBUTE GET-ATTRIBUTE-NODE + GET-BINARY-DATA GET-BITS GET-BLUE GET-BLUE- GET-BLUE-V GET-BLUE-VA GET-BLUE-VAL GET-BLUE-VALU + GET-BLUE-VALUE GET-BROWSE-COL GET-BROWSE-COLU GET-BROWSE-COLUM GET-BROWSE-COLUMN GET-BUFFER-HANDLE + GETBYTE GET-BYTE GET-BYTE-ORDER GET-BYTES GET-BYTES-AVAILABLE GET-CALLBACK-PROC-CONTEXT + GET-CALLBACK-PROC-NAME GET-CGI-LIST GET-CGI-LONG-VALUE GET-CGI-VALUE GET-CHANGES GET-CHILD + GET-CHILD-REL GET-CHILD-RELA GET-CHILD-RELAT GET-CHILD-RELATI GET-CHILD-RELATIO GET-CHILD-RELATION + GET-CLASS GET-CLIENT GET-CODEPAGE GET-CODEPAGES GET-COLL GET-COLLA GET-COLLAT GET-COLLATI + GET-COLLATIO GET-COLLATION GET-COLLATIONS GET-COLUMN GET-CONFIG-VALUE GET-CURR GET-CURRE GET-CURREN + GET-CURRENT GET-DATASET-BUFFER GET-DB-CLIENT GET-DIR GET-DOCUMENT-ELEMENT GET-DOUBLE + GET-DROPPED-FILE GET-DYNAMIC GET-EFFECTIVE-TENANT-ID GET-EFFECTIVE-TENANT-NAME GET-ERROR-COLUMN + GET-ERROR-ROW GET-FILE GET-FILE-NAME GET-FILE-OFFSE GET-FILE-OFFSET GET-FIRS GET-FIRST GET-FLOAT + GET-GREEN GET-GREEN- GET-GREEN-V GET-GREEN-VA GET-GREEN-VAL GET-GREEN-VALU GET-GREEN-VALUE + GET-HEADER-ENTR GET-HEADER-ENTRY GET-INDEX-BY-NAMESPACE-NAME GET-INDEX-BY-QNAME GET-INT64 + GET-ITERATION GET-KEY-VAL GET-KEY-VALU GET-KEY-VALUE GET-LAST GET-LOCALNAME-BY-INDEX GET-LONG + GET-MESSAGE GET-MESSAGE-TYPE GET-NEXT GET-NODE GET-NUMBER GET-PARENT GET-POINTER-VALUE GET-PREV + GET-PRINTERS GET-PROPERTY GET-QNAME-BY-INDEX GET-RED GET-RED- GET-RED-V GET-RED-VA GET-RED-VAL + GET-RED-VALU GET-RED-VALUE GET-REL GET-RELA GET-RELAT GET-RELATI GET-RELATIO GET-RELATION + GET-REPOSITIONED-ROW GET-RGB GET-RGB- GET-RGB-V GET-RGB-VA GET-RGB-VAL GET-RGB-VALU GET-RGB-VALUE + GET-ROW GET-SAFE-USER GET-SELECTED GET-SELECTED- GET-SELECTED-W GET-SELECTED-WI GET-SELECTED-WID + GET-SELECTED-WIDG GET-SELECTED-WIDGE GET-SELECTED-WIDGET GET-SERIALIZED GET-SHORT GET-SIGNATURE + GET-SIZE GET-SOCKET-OPTION GET-SOURCE-BUFFER GET-STRING GET-TAB-ITEM GET-TEXT-HEIGHT + GET-TEXT-HEIGHT-C GET-TEXT-HEIGHT-CH GET-TEXT-HEIGHT-CHA GET-TEXT-HEIGHT-CHAR GET-TEXT-HEIGHT-CHARS + GET-TEXT-HEIGHT-P GET-TEXT-HEIGHT-PI GET-TEXT-HEIGHT-PIX GET-TEXT-HEIGHT-PIXE GET-TEXT-HEIGHT-PIXEL + GET-TEXT-HEIGHT-PIXELS GET-TEXT-WIDTH GET-TEXT-WIDTH-C GET-TEXT-WIDTH-CH GET-TEXT-WIDTH-CHA + GET-TEXT-WIDTH-CHAR GET-TEXT-WIDTH-CHARS GET-TEXT-WIDTH-P GET-TEXT-WIDTH-PI GET-TEXT-WIDTH-PIX + GET-TEXT-WIDTH-PIXE GET-TEXT-WIDTH-PIXEL GET-TEXT-WIDTH-PIXELS GET-TOP-BUFFER GET-TYPE-BY-INDEX + GET-TYPE-BY-NAMESPACE-NAME GET-TYPE-BY-QNAME GET-UNSIGNED-LONG GET-UNSIGNED-SHORT GET-URI-BY-INDEX + GET-VALUE-BY-INDEX GET-VALUE-BY-NAMESPACE-NAME GET-VALUE-BY-QNAME GET-WAIT GET-WAIT- GET-WAIT-S + GET-WAIT-ST GET-WAIT-STA GET-WAIT-STAT GET-WAIT-STATE GLOBAL GO GO-ON GO-PEND GO-PENDI GO-PENDIN + GO-PENDING GOTO GRANT GRANT-ARCHIVE GRAPHIC-E GRAPHIC-ED GRAPHIC-EDG GRAPHIC-EDGE GRAYED + GRID-FACTOR-H GRID-FACTOR-HO GRID-FACTOR-HOR GRID-FACTOR-HORI GRID-FACTOR-HORIZ GRID-FACTOR-HORIZO + GRID-FACTOR-HORIZON GRID-FACTOR-HORIZONT GRID-FACTOR-HORIZONTA GRID-FACTOR-HORIZONTAL GRID-FACTOR-V + GRID-FACTOR-VE GRID-FACTOR-VER GRID-FACTOR-VERT GRID-FACTOR-VERTI GRID-FACTOR-VERTIC + GRID-FACTOR-VERTICA GRID-FACTOR-VERTICAL GRID-SET GRID-SNAP GRID-UNIT-HEIGHT GRID-UNIT-HEIGHT-C + GRID-UNIT-HEIGHT-CH GRID-UNIT-HEIGHT-CHA GRID-UNIT-HEIGHT-CHAR GRID-UNIT-HEIGHT-CHARS + GRID-UNIT-HEIGHT-P GRID-UNIT-HEIGHT-PI GRID-UNIT-HEIGHT-PIX GRID-UNIT-HEIGHT-PIXE + GRID-UNIT-HEIGHT-PIXEL GRID-UNIT-HEIGHT-PIXELS GRID-UNIT-WIDTH GRID-UNIT-WIDTH-C GRID-UNIT-WIDTH-CH + GRID-UNIT-WIDTH-CHA GRID-UNIT-WIDTH-CHAR GRID-UNIT-WIDTH-CHARS GRID-UNIT-WIDTH-P GRID-UNIT-WIDTH-PI + GRID-UNIT-WIDTH-PIX GRID-UNIT-WIDTH-PIXE GRID-UNIT-WIDTH-PIXEL GRID-UNIT-WIDTH-PIXELS GRID-VISIBLE + GROUP GROUP-BOX GT GUID HANDLE HANDLER HAS-LOBS HAS-RECORDS HAVING HEADER HEIGHT HEIGHT-C HEIGHT-CH + HEIGHT-CHA HEIGHT-CHAR HEIGHT-CHARS HEIGHT-P HEIGHT-PI HEIGHT-PIX HEIGHT-PIXE HEIGHT-PIXEL + HEIGHT-PIXELS HELP HELP-CON HELP-CONT HELP-CONTE HELP-CONTEX HELP-CONTEXT HELPFILE-N HELPFILE-NA + HELPFILE-NAM HELPFILE-NAME HELP-TOPIC HEX-DECODE HEX-ENCODE HIDDEN HIDE HINT HOME HORI HORIZ + HORIZ-END HORIZ-HOME HORIZO HORIZON HORIZONT HORIZONTA HORIZONTAL HORIZ-SCROLL-DRAG HOST-BYTE-ORDER + HTML-CHARSET HTML-END-OF-LINE HTML-END-OF-PAGE HTML-FRAME-BEGIN HTML-FRAME-END HTML-HEADER-BEGIN + HTML-HEADER-END HTML-TITLE-BEGIN HTML-TITLE-END HWND ICFPARAM ICFPARAME ICFPARAMET ICFPARAMETE + ICFPARAMETER ICON IF IGNORE-CURRENT-MOD IGNORE-CURRENT-MODI IGNORE-CURRENT-MODIF + IGNORE-CURRENT-MODIFI IGNORE-CURRENT-MODIFIE IGNORE-CURRENT-MODIFIED IMAGE IMAGE-DOWN + IMAGE-INSENSITIVE IMAGE-SIZE IMAGE-SIZE-C IMAGE-SIZE-CH IMAGE-SIZE-CHA IMAGE-SIZE-CHAR + IMAGE-SIZE-CHARS IMAGE-SIZE-P IMAGE-SIZE-PI IMAGE-SIZE-PIX IMAGE-SIZE-PIXE IMAGE-SIZE-PIXEL + IMAGE-SIZE-PIXELS IMAGE-UP IMMEDIATE-DISPLAY IMPLEMENTS IMPORT IMPORT-NODE IMPORT-PRINCIPAL IN + INCREMENT-EXCLUSIVE-ID INDEX INDEXED-REPOSITION INDEX-HINT INDEX-INFO INDEX-INFOR INDEX-INFORM + INDEX-INFORMA INDEX-INFORMAT INDEX-INFORMATI INDEX-INFORMATIO INDEX-INFORMATION INDICATOR INFO INFOR + INFORM INFORMA INFORMAT INFORMATI INFORMATIO INFORMATION IN-HANDLE INHERIT-BGC INHERIT-BGCO + INHERIT-BGCOL INHERIT-BGCOLO INHERIT-BGCOLOR INHERIT-COLOR-MODE INHERIT-FGC INHERIT-FGCO + INHERIT-FGCOL INHERIT-FGCOLO INHERIT-FGCOLOR INHERITS INIT INITIAL INITIAL-DIR INITIAL-FILTER + INITIALIZE INITIALIZE-DOCUMENT-TYPE INITIATE INNER INNER-CHARS INNER-LINES INPUT INPUT-O INPUT-OU + INPUT-OUT INPUT-OUTP INPUT-OUTPU INPUT-OUTPUT INPUT-VALUE INSERT INSERT-ATTRIBUTE INSERT-B INSERT-BA + INSERT-BAC INSERT-BACK INSERT-BACKT INSERT-BACKTA INSERT-BACKTAB INSERT-BEFORE INSERT-COLUMN + INSERT-FIELD INSERT-FIELD-DATA INSERT-FIELD-LABEL INSERT-FILE INSERT-MODE INSERT-ROW INSERT-STRING + INSERT-T INSERT-TA INSERT-TAB INSTANTIATING-PROCEDURE INT INT64 INTE INTEG INTEGE INTEGER INTERFACE + INTERNAL-ENTRIES INTERVAL INTO INVOKE IS IS-ATTR IS-ATTR- IS-ATTR-S IS-ATTR-SP IS-ATTR-SPA + IS-ATTR-SPAC IS-ATTR-SPACE IS-CLAS IS-CLASS IS-CODEPAGE-FIXED IS-COLUMN-CODEPAGE IS-DB-MULTI-TENANT + IS-JSON IS-LEAD-BYTE IS-MULTI-TENANT ISO-DATE IS-OPEN IS-PARAMETER-SET IS-PARTITIONE IS-PARTITIONED + IS-ROW-SELECTED IS-SELECTED IS-XML ITEM ITEMS-PER-ROW ITERATION-CHANGED JOIN JOIN-BY-SQLDB + JOIN-ON-SELECT KBLABEL KEEP-CONNECTION-OPEN KEEP-FRAME-Z KEEP-FRAME-Z- KEEP-FRAME-Z-O + KEEP-FRAME-Z-OR KEEP-FRAME-Z-ORD KEEP-FRAME-Z-ORDE KEEP-FRAME-Z-ORDER KEEP-MESSAGES + KEEP-SECURITY-CACHE KEEP-TAB-ORDER KEY KEYCACHE-JOIN KEYCODE KEY-CODE KEYFUNC KEY-FUNC KEYFUNCT + KEY-FUNCT KEYFUNCTI KEY-FUNCTI KEYFUNCTIO KEY-FUNCTIO KEYFUNCTION KEY-FUNCTION KEYLABEL KEY-LABEL + KEYS KEYWORD KEYWORD-ALL LABEL LABEL-BGC LABEL-BGCO LABEL-BGCOL LABEL-BGCOLO LABEL-BGCOLOR LABEL-DC + LABEL-DCO LABEL-DCOL LABEL-DCOLO LABEL-DCOLOR LABEL-FGC LABEL-FGCO LABEL-FGCOL LABEL-FGCOLO + LABEL-FGCOLOR LABEL-FONT LABEL-PFC LABEL-PFCO LABEL-PFCOL LABEL-PFCOLO LABEL-PFCOLOR LABELS + LABELS-HAVE-COLONS LANDSCAPE LANGUAGE LANGUAGES LARGE LARGE-TO-SMALL LAST LAST-ASYNC LAST-ASYNC- + LAST-ASYNCH-REQUEST LAST-ASYNC-R LAST-ASYNC-RE LAST-ASYNC-REQ LAST-ASYNC-REQU LAST-ASYNC-REQUE + LAST-ASYNC-REQUES LAST-ASYNC-REQUEST LAST-BATCH LAST-CHILD LAST-EVEN LAST-EVENT LAST-FORM LASTKEY + LAST-KEY LAST-OBJECT LAST-OF LAST-PROCE LAST-PROCED LAST-PROCEDU LAST-PROCEDUR LAST-PROCEDURE + LAST-SERV LAST-SERVE LAST-SERVER LAST-SERVER-SOCKET LAST-SOCKET LAST-TAB-I LAST-TAB-IT LAST-TAB-ITE + LAST-TAB-ITEM LC LDBNAME LE LEADING LEAK-DETECTION LEAVE LEFT LEFT-ALIGN LEFT-ALIGNE LEFT-ALIGNED + LEFT-END LEFT-TRIM LENGTH LIBRARY LIBRARY-CALLING-CONVENTION LIKE LIKE-SEQUENTIAL LINE LINE-COUNT + LINE-COUNTE LINE-COUNTER LINE-DOWN LINE-LEFT LINE-RIGHT LINE-UP LIST-EVENTS LISTI LISTIN LISTING + LISTINGS LIST-ITEM-PAIRS LIST-ITEMS LIST-PROPERTY-NAMES LIST-QUERY-ATTRS LIST-SET-ATTRS LIST-WIDGETS + LITERAL-QUESTION LITTLE-ENDIAN LOAD LOAD-DOMAINS LOAD-FROM LOAD-ICON LOAD-IMAGE LOAD-IMAGE-DOWN + LOAD-IMAGE-INSENSITIVE LOAD-IMAGE-UP LOAD-MOUSE-P LOAD-MOUSE-PO LOAD-MOUSE-POI LOAD-MOUSE-POIN + LOAD-MOUSE-POINT LOAD-MOUSE-POINTE LOAD-MOUSE-POINTER LOAD-PICTURE LOAD-RESULT-INTO LOAD-SMALL-ICON + LOB-DIR LOCAL-HOST LOCAL-NAME LOCAL-PORT LOCAL-VERSION-INFO LOCATOR-COLUMN-NUMBER + LOCATOR-LINE-NUMBER LOCATOR-PUBLIC-ID LOCATOR-SYSTEM-ID LOCATOR-TYPE LOCKED LOCK-REGISTRATION LOG + LOG-AUDIT-EVENT LOG-ENTRY-TYPES LOGFILE-NAME LOGGING-LEVEL LOGICAL LOG-ID LOGIN-EXPIRATION-TIMESTAMP + LOGIN-HOST LOGIN-STATE LOG-MANAGER LOGOUT LOG-THRESHOLD LONG LONGCH LONGCHA LONGCHAR + LONGCHAR-TO-NODE-VALUE LOOKAHEAD LOOKUP LOWER LT MACHINE-CLASS MAIN-MENU MANDATORY MANUAL-HIGHLIGHT + MAP MARGIN-EXTRA MARGIN-HEIGHT MARGIN-HEIGHT-C MARGIN-HEIGHT-CH MARGIN-HEIGHT-CHA MARGIN-HEIGHT-CHAR + MARGIN-HEIGHT-CHARS MARGIN-HEIGHT-P MARGIN-HEIGHT-PI MARGIN-HEIGHT-PIX MARGIN-HEIGHT-PIXE + MARGIN-HEIGHT-PIXEL MARGIN-HEIGHT-PIXELS MARGIN-WIDTH MARGIN-WIDTH-C MARGIN-WIDTH-CH + MARGIN-WIDTH-CHA MARGIN-WIDTH-CHAR MARGIN-WIDTH-CHARS MARGIN-WIDTH-P MARGIN-WIDTH-PI + MARGIN-WIDTH-PIX MARGIN-WIDTH-PIXE MARGIN-WIDTH-PIXEL MARGIN-WIDTH-PIXELS MARK-NEW MARK-ROW-STATE + MATCHES MAX MAX-BUTTON MAX-CHARS MAX-DATA-GUESS MAX-HEIGHT MAX-HEIGHT-C MAX-HEIGHT-CH MAX-HEIGHT-CHA + MAX-HEIGHT-CHAR MAX-HEIGHT-CHARS MAX-HEIGHT-P MAX-HEIGHT-PI MAX-HEIGHT-PIX MAX-HEIGHT-PIXE + MAX-HEIGHT-PIXEL MAX-HEIGHT-PIXELS MAXIMIZE MAXIMUM MAXIMUM-LEVEL MAX-ROWS MAX-SIZE MAX-VAL MAX-VALU + MAX-VALUE MAX-WIDTH MAX-WIDTH-C MAX-WIDTH-CH MAX-WIDTH-CHA MAX-WIDTH-CHAR MAX-WIDTH-CHARS + MAX-WIDTH-P MAX-WIDTH-PI MAX-WIDTH-PIX MAX-WIDTH-PIXE MAX-WIDTH-PIXEL MAX-WIDTH-PIXELS MD5-DIGEST + MD5-VALUE MEMBER MEMPTR MEMPTR-TO-NODE-VALUE MENU MENUBAR MENU-BAR MENU-DROP MENU-ITEM MENU-K + MENU-KE MENU-KEY MENU-M MENU-MO MENU-MOU MENU-MOUS MENU-MOUSE MERGE-BY-FIELD MERGE-CHANGES + MERGE-ROW-CHANGES MESSAGE MESSAGE-AREA MESSAGE-AREA-FONT MESSAGE-AREA-MSG MESSAGE-DIGEST + MESSAGE-LINE MESSAGE-LINES METHOD MIN MIN-BUTTON MIN-COLUMN-WIDTH-C MIN-COLUMN-WIDTH-CH + MIN-COLUMN-WIDTH-CHA MIN-COLUMN-WIDTH-CHAR MIN-COLUMN-WIDTH-CHARS MIN-COLUMN-WIDTH-P + MIN-COLUMN-WIDTH-PI MIN-COLUMN-WIDTH-PIX MIN-COLUMN-WIDTH-PIXE MIN-COLUMN-WIDTH-PIXEL + MIN-COLUMN-WIDTH-PIXELS MIN-HEIGHT MIN-HEIGHT-C MIN-HEIGHT-CH MIN-HEIGHT-CHA MIN-HEIGHT-CHAR + MIN-HEIGHT-CHARS MIN-HEIGHT-P MIN-HEIGHT-PI MIN-HEIGHT-PIX MIN-HEIGHT-PIXE MIN-HEIGHT-PIXEL + MIN-HEIGHT-PIXELS MINI MINIM MINIMU MINIMUM MIN-SCHEMA-MARSHAL MIN-SCHEMA-MARSHALL MIN-SIZE MIN-VAL + MIN-VALU MIN-VALUE MIN-WIDTH MIN-WIDTH-C MIN-WIDTH-CH MIN-WIDTH-CHA MIN-WIDTH-CHAR MIN-WIDTH-CHARS + MIN-WIDTH-P MIN-WIDTH-PI MIN-WIDTH-PIX MIN-WIDTH-PIXE MIN-WIDTH-PIXEL MIN-WIDTH-PIXELS MOD MODIFIED + MODULO MONTH MOUSE MOUSE-P MOUSE-PO MOUSE-POI MOUSE-POIN MOUSE-POINT MOUSE-POINTE MOUSE-POINTER + MOVABLE MOVE MOVE-AFTER MOVE-AFTER- MOVE-AFTER-T MOVE-AFTER-TA MOVE-AFTER-TAB MOVE-AFTER-TAB- + MOVE-AFTER-TAB-I MOVE-AFTER-TAB-IT MOVE-AFTER-TAB-ITE MOVE-AFTER-TAB-ITEM MOVE-BEFOR MOVE-BEFORE + MOVE-BEFORE- MOVE-BEFORE-T MOVE-BEFORE-TA MOVE-BEFORE-TAB MOVE-BEFORE-TAB- MOVE-BEFORE-TAB-I + MOVE-BEFORE-TAB-IT MOVE-BEFORE-TAB-ITE MOVE-BEFORE-TAB-ITEM MOVE-COL MOVE-COLU MOVE-COLUM + MOVE-COLUMN MOVE-TO-B MOVE-TO-BO MOVE-TO-BOT MOVE-TO-BOTT MOVE-TO-BOTTO MOVE-TO-BOTTOM MOVE-TO-EOF + MOVE-TO-T MOVE-TO-TO MOVE-TO-TOP MPE MTIME MULTI-COMPILE MULTIPLE MULTIPLE-KEY MULTITASKING-INTERVAL + MUST-EXIST MUST-UNDERSTAND NAME NAMESPACE-PREFIX NAMESPACE-URI NATIVE NE NEEDS-APPSERVER-PROMPT + NEEDS-PROMPT NESTED NEW NEW-INSTANCE NEW-LINE NEW-ROW NEXT NEXT-COL NEXT-COLU NEXT-COLUM NEXT-COLUMN + NEXT-ERROR NEXT-FRAME NEXT-PROMPT NEXT-ROWID NEXT-SIBLING NEXT-TAB-I NEXT-TAB-ITE NEXT-TAB-ITEM + NEXT-VALUE NEXT-WORD NO NO-APPLY NO-ARRAY-M NO-ARRAY-ME NO-ARRAY-MES NO-ARRAY-MESS NO-ARRAY-MESSA + NO-ARRAY-MESSAG NO-ARRAY-MESSAGE NO-ASSIGN NO-ATTR NO-ATTR-L NO-ATTR-LI NO-ATTR-LIS NO-ATTR-LIST + NO-ATTR-S NO-ATTR-SP NO-ATTR-SPA NO-ATTR-SPAC NO-ATTR-SPACE NO-AUTO-TRI NO-AUTO-TRIM + NO-AUTO-VALIDATE NO-BIND-WHERE NO-BOX NO-COLUMN-SC NO-COLUMN-SCR NO-COLUMN-SCRO NO-COLUMN-SCROL + NO-COLUMN-SCROLL NO-COLUMN-SCROLLI NO-COLUMN-SCROLLIN NO-COLUMN-SCROLLING NO-CONSOLE NO-CONVERT + NO-CONVERT-3D NO-CONVERT-3D- NO-CONVERT-3D-C NO-CONVERT-3D-CO NO-CONVERT-3D-COL NO-CONVERT-3D-COLO + NO-CONVERT-3D-COLOR NO-CONVERT-3D-COLORS NO-CURRENT-VALUE NO-DEBUG NODE-TYPE NODE-VALUE + NODE-VALUE-TO-LONGCHAR NODE-VALUE-TO-MEMPTR NO-DRAG NO-ECHO NO-EMPTY-SPACE NO-ERROR NO-F NO-FI + NO-FIL NO-FILL NO-FIREHOSE-CURSOR NO-FOCUS NO-HELP NO-HIDE NO-INDEX-HINT NO-INHERIT-BGC + NO-INHERIT-BGCO NO-INHERIT-BGCOL NO-INHERIT-BGCOLO NO-INHERIT-BGCOLOR NO-INHERIT-FGC NO-INHERIT-FGCO + NO-INHERIT-FGCOL NO-INHERIT-FGCOLO NO-INHERIT-FGCOLOR NO-JOIN-BY-SQLDB NO-KEYCACHE-JOIN NO-LABEL + NO-LABELS NO-LOBS NO-LOCK NO-LOOKAHEAD NO-MAP NO-MES NO-MESS NO-MESSA NO-MESSAG NO-MESSAGE + NONAMESPACE-SCHEMA-LOCATION NONE NON-SERIALIZABLE NO-PAUSE NO-PREFE NO-PREFET NO-PREFETC NO-PREFETCH + NO-QUERY-O NO-QUERY-OR NO-QUERY-ORD NO-QUERY-ORDE NO-QUERY-ORDER NO-QUERY-ORDER- NO-QUERY-ORDER-A + NO-QUERY-ORDER-AD NO-QUERY-ORDER-ADD NO-QUERY-ORDER-ADDE NO-QUERY-ORDER-ADDED NO-QUERY-U NO-QUERY-UN + NO-QUERY-UNI NO-QUERY-UNIQ NO-QUERY-UNIQU NO-QUERY-UNIQUE NO-QUERY-UNIQUE- NO-QUERY-UNIQUE-A + NO-QUERY-UNIQUE-AD NO-QUERY-UNIQUE-ADD NO-QUERY-UNIQUE-ADDE NO-QUERY-UNIQUE-ADDED NO-RETURN-VAL + NO-RETURN-VALU NO-RETURN-VALUE NORMALIZE NO-ROW-MARKERS NO-SCHEMA-MARSHAL NO-SCHEMA-MARSHALL + NO-SCROLLBAR-V NO-SCROLLBAR-VE NO-SCROLLBAR-VER NO-SCROLLBAR-VERT NO-SCROLLBAR-VERTI + NO-SCROLLBAR-VERTIC NO-SCROLLBAR-VERTICA NO-SCROLLBAR-VERTICAL NO-SCROLLING NO-SEPARATE-CONNECTION + NO-SEPARATORS NOT NO-TAB NO-TAB- NO-TAB-S NO-TAB-ST NO-TAB-STO NO-TAB-STOP NOT-ACTIVE NO-UND NO-UNDE + NO-UNDER NO-UNDERL NO-UNDERLI NO-UNDERLIN NO-UNDERLINE NO-UNDO NO-VAL NO-VALI NO-VALID NO-VALIDA + NO-VALIDAT NO-VALIDATE NOW NO-WAIT NO-WORD-WRAP NULL NUM-ALI NUM-ALIA NUM-ALIAS NUM-ALIASE + NUM-ALIASES NUM-BUFFERS NUM-BUT NUM-BUTT NUM-BUTTO NUM-BUTTON NUM-BUTTONS NUM-CHILD-RELATIONS + NUM-CHILDREN NUM-COL NUM-COLU NUM-COLUM NUM-COLUMN NUM-COLUMNS NUM-COPIES NUM-DBS NUM-DROPPED-FILES + NUM-ENTRIES NUMERIC NUMERIC-DEC NUMERIC-DECI NUMERIC-DECIM NUMERIC-DECIMA NUMERIC-DECIMAL + NUMERIC-DECIMAL- NUMERIC-DECIMAL-P NUMERIC-DECIMAL-PO NUMERIC-DECIMAL-POI NUMERIC-DECIMAL-POIN + NUMERIC-DECIMAL-POINT NUMERIC-F NUMERIC-FO NUMERIC-FOR NUMERIC-FORM NUMERIC-FORMA NUMERIC-FORMAT + NUMERIC-SEP NUMERIC-SEPA NUMERIC-SEPAR NUMERIC-SEPARA NUMERIC-SEPARAT NUMERIC-SEPARATO + NUMERIC-SEPARATOR NUM-FIELDS NUM-FORMATS NUM-HEADER-ENTRIES NUM-ITEMS NUM-ITERATIONS NUM-LINES + NUM-LOCKED-COL NUM-LOCKED-COLU NUM-LOCKED-COLUM NUM-LOCKED-COLUMN NUM-LOCKED-COLUMNS NUM-LOG-FILES + NUM-MESSAGES NUM-PARAMETERS NUM-REFERENCES NUM-RELATIONS NUM-REPL NUM-REPLA NUM-REPLAC NUM-REPLACE + NUM-REPLACED NUM-RESULTS NUM-SELECTED NUM-SELECTED-ROWS NUM-SELECTED-WIDGETS NUM-SOURCE-BUFFERS + NUM-TABS NUM-TOP-BUFFERS NUM-TO-RETAIN NUM-VISIBLE-COL NUM-VISIBLE-COLU NUM-VISIBLE-COLUM + NUM-VISIBLE-COLUMN NUM-VISIBLE-COLUMNS OBJECT OCTET_LENGTH OCTET-LENGTH OF OFF OFF-END OFF-HOME OK + OK-CANCEL OLD OLE-INVOKE-LOCA OLE-INVOKE-LOCAL OLE-INVOKE-LOCALE OLE-NAMES-LOCA OLE-NAMES-LOCAL + OLE-NAMES-LOCALE ON ON-FRAME ON-FRAME- ON-FRAME-B ON-FRAME-BO ON-FRAME-BOR ON-FRAME-BORD + ON-FRAME-BORDE ON-FRAME-BORDER OPEN OPEN-LINE-ABOVE OPSYS OPTION OPTIONS OPTIONS-FILE OR + ORDERED-JOIN ORDINAL ORIENTATION ORIGIN-HANDLE ORIGIN-ROWID OS2 OS400 OS-APPEND OS-COMMAND OS-COPY + OS-CREATE-DIR OS-DELETE OS-DIR OS-DRIVE OS-DRIVES OS-ERROR OS-GETENV OS-RENAME OTHERWISE OUTER + OUTER-JOIN OUT-OF-DATA OUTPUT OVERLAY OVERRIDE OWNER OWNER-DOCUMENT PACKAGE-PRIVATE + PACKAGE-PROTECTED PAGE PAGE-BOT PAGE-BOTT PAGE-BOTTO PAGE-BOTTOM PAGED PAGE-DOWN PAGE-LEFT PAGE-NUM + PAGE-NUMB PAGE-NUMBE PAGE-NUMBER PAGE-RIGHT PAGE-RIGHT-TEXT PAGE-SIZE PAGE-TOP PAGE-UP PAGE-WID + PAGE-WIDT PAGE-WIDTH PARAM PARAME PARAMET PARAMETE PARAMETER PARENT PARENT-BUFFER + PARENT-FIELDS-AFTER PARENT-FIELDS-BEFORE PARENT-ID-FIELD PARENT-ID-RELATION PARENT-REL PARENT-RELA + PARENT-RELAT PARENT-RELATI PARENT-RELATIO PARENT-RELATION PARENT-WINDOW-CLOSE PARSE-STATUS + PARTIAL-KEY PASCAL PASSWORD-FIELD PASTE PATHNAME PAUSE PBE-HASH-ALG PBE-HASH-ALGO PBE-HASH-ALGOR + PBE-HASH-ALGORI PBE-HASH-ALGORIT PBE-HASH-ALGORITH PBE-HASH-ALGORITHM PBE-KEY-ROUNDS PDBNAME PERF + PERFO PERFOR PERFORM PERFORMA PERFORMAN PERFORMANC PERFORMANCE PERSIST PERSISTE PERSISTEN PERSISTENT + PERSISTENT-CACHE-DISABLED PERSISTENT-PROCEDURE PFC PFCO PFCOL PFCOLO PFCOLOR PICK PICK-AREA + PICK-BOTH PIXELS PIXELS-PER-COL PIXELS-PER-COLU PIXELS-PER-COLUM PIXELS-PER-COLUMN PIXELS-PER-ROW + POPUP-M POPUP-ME POPUP-MEN POPUP-MENU POPUP-O POPUP-ON POPUP-ONL POPUP-ONLY PORTRAIT POSITION + PRECISION PREFER-DATASET PREPARED PREPARE-STRING PREPROC PREPROCE PREPROCES PREPROCESS PRESEL + PRESELE PRESELEC PRESELECT PREV PREV-COL PREV-COLU PREV-COLUM PREV-COLUMN PREV-FRAME PREV-SIBLING + PREV-TAB-I PREV-TAB-IT PREV-TAB-ITE PREV-TAB-ITEM PREV-WORD PRIMARY PRIMARY-PASSPHRASE PRINTER + PRINTER-CONTROL-HANDLE PRINTER-HDC PRINTER-NAME PRINTER-PORT PRINTER-SETUP PRIVATE PRIVATE-D + PRIVATE-DA PRIVATE-DAT PRIVATE-DATA PRIVILEGES PROCE PROCED PROCEDU PROCEDUR PROCEDURE + PROCEDURE-CALL-TYPE PROCEDURE-COMPLETE PROCEDURE-NAME PROCEDURE-TYPE PROCESS PROCESS-ARCHITECTURE + PROC-HA PROC-HAN PROC-HAND PROC-HANDL PROC-HANDLE PROC-ST PROC-STA PROC-STAT PROC-STATU PROC-STATUS + PROC-TEXT PROC-TEXT-BUFFER PROFILE-FILE PROFILER PROFILING PROGRAM-NAME PROGRESS PROGRESS-S + PROGRESS-SO PROGRESS-SOU PROGRESS-SOUR PROGRESS-SOURC PROGRESS-SOURCE PROMPT PROMPT-F PROMPT-FO + PROMPT-FOR PROMSGS PROPATH PROPERTY PROTECTED PROVERS PROVERSI PROVERSIO PROVERSION PROXY + PROXY-PASSWORD PROXY-USERID PUBLIC PUBLIC-ID PUBLISH PUBLISHED-EVENTS PUT PUT-BITS PUTBYTE PUT-BYTE + PUT-BYTES PUT-DOUBLE PUT-FLOAT PUT-INT64 PUT-KEY-VAL PUT-KEY-VALU PUT-KEY-VALUE PUT-LONG PUT-SHORT + PUT-STRING PUT-UNSIGNED-LONG PUT-UNSIGNED-SHORT QUALIFIED-USER-ID QUERY QUERY-CLOSE QUERY-OFF-END + QUERY-OPEN QUERY-PREPARE QUERY-TUNING QUESTION QUIT QUOTER RADIO-BUTTONS RADIO-SET RANDOM RAW + RAW-TRANSFER RCODE-INFO RCODE-INFOR RCODE-INFORM RCODE-INFORMA RCODE-INFORMAT RCODE-INFORMATI + RCODE-INFORMATIO RCODE-INFORMATION READ READ-AVAILABLE READ-EXACT-NUM READ-FILE READ-JSON READKEY + READ-ONLY READ-RESPONSE READ-XML READ-XMLSCHEMA REAL RECALL RECID RECORD-LEN RECORD-LENG + RECORD-LENGT RECORD-LENGTH RECT RECTA RECTAN RECTANG RECTANGL RECTANGLE RECURSIVE REFERENCE-ONLY + REFRESH REFRESHABLE REFRESH-AUDIT-POLICY REGISTER-DOMAIN REINSTATE REJECT-CHANGES REJECTED + REJECT-ROW-CHANGES RELATION-FI RELATION-FIE RELATION-FIEL RELATION-FIELD RELATION-FIELDS + RELATIONS-ACTIVE RELEASE REMOTE REMOTE-HOST REMOTE-PORT REMOVE-ATTRIBUTE REMOVE-CHILD + REMOVE-EVENTS-PROC REMOVE-EVENTS-PROCE REMOVE-EVENTS-PROCED REMOVE-EVENTS-PROCEDU + REMOVE-EVENTS-PROCEDUR REMOVE-EVENTS-PROCEDURE REMOVE-SUPER-PROC REMOVE-SUPER-PROCE + REMOVE-SUPER-PROCED REMOVE-SUPER-PROCEDU REMOVE-SUPER-PROCEDUR REMOVE-SUPER-PROCEDURE REPEAT REPLACE + REPLACE-CHILD REPLACE-SELECTION-TEXT REPLICATION-CREATE REPLICATION-DELETE REPLICATION-WRITE REPORTS + REPOSITION REPOSITION-BACK REPOSITION-BACKW REPOSITION-BACKWA REPOSITION-BACKWAR REPOSITION-BACKWARD + REPOSITION-BACKWARDS REPOSITION-FORW REPOSITION-FORWA REPOSITION-FORWAR REPOSITION-FORWARD + REPOSITION-FORWARDS REPOSITION-MODE REPOSITION-PARENT-REL REPOSITION-PARENT-RELA + REPOSITION-PARENT-RELAT REPOSITION-PARENT-RELATI REPOSITION-PARENT-RELATIO REPOSITION-PARENT-RELATION + REPOSITION-TO-ROW REPOSITION-TO-ROWID REQUEST REQUEST-INFO RESET RESIZA RESIZAB RESIZABL RESIZABLE + RESIZE RESPONSE-INFO RESTART-ROW RESTART-ROWID RESULT RESUME-DISPLAY RETAIN RETAIN-S RETAIN-SH + RETAIN-SHA RETAIN-SHAP RETAIN-SHAPE RETRY RETRY-CANCEL RETURN RETURN-ALIGN RETURN-INS RETURN-INSE + RETURN-INSER RETURN-INSERT RETURN-INSERTE RETURN-INSERTED RETURNS RETURN-TO-START-DI + RETURN-TO-START-DIR RETURN-VAL RETURN-VALU RETURN-VALUE RETURN-VALUE-DATA-TYPE RETURN-VALUE-DLL-TYPE + REVERSE-FROM REVERT REVOKE RGB-V RGB-VA RGB-VAL RGB-VALU RGB-VALUE RIGHT RIGHT-ALIGN RIGHT-ALIGNE + RIGHT-ALIGNED RIGHT-END RIGHT-TRIM R-INDEX ROLE ROLES ROUND ROUNDED ROUTINE-LEVEL ROW ROW-CREATED + ROW-DELETED ROW-DISPLAY ROW-ENTRY ROW-HEIGHT ROW-HEIGHT-C ROW-HEIGHT-CH ROW-HEIGHT-CHA + ROW-HEIGHT-CHAR ROW-HEIGHT-CHARS ROW-HEIGHT-P ROW-HEIGHT-PI ROW-HEIGHT-PIX ROW-HEIGHT-PIXE + ROW-HEIGHT-PIXEL ROW-HEIGHT-PIXELS ROWID ROW-LEAVE ROW-MA ROW-MAR ROW-MARK ROW-MARKE ROW-MARKER + ROW-MARKERS ROW-MODIFIED ROW-OF ROW-RESIZABLE ROW-STATE ROW-UNMODIFIED RULE RULE-ROW RULE-Y RUN + RUN-PROC RUN-PROCE RUN-PROCED RUN-PROCEDU RUN-PROCEDUR RUN-PROCEDURE SAVE SAVE-AS SAVE-FILE + SAVE-ROW-CHANGES SAVE-WHERE-STRING SAX-ATTRIBUTES SAX-COMPLE SAX-COMPLET SAX-COMPLETE SAX-PARSE + SAX-PARSE-FIRST SAX-PARSE-NEXT SAX-PARSER-ERROR SAX-READER SAX-RUNNING SAX-UNINITIALIZED + SAX-WRITE-BEGIN SAX-WRITE-COMPLETE SAX-WRITE-CONTENT SAX-WRITE-ELEMENT SAX-WRITE-ERROR + SAX-WRITE-IDLE SAX-WRITER SAX-WRITE-TAG SAX-XML SCHEMA SCHEMA-CHANGE SCHEMA-LOCATION SCHEMA-MARSHAL + SCHEMA-PATH SCREEN SCREEN-IO SCREEN-LINES SCREEN-VAL SCREEN-VALU SCREEN-VALUE SCROLL SCROLLABLE + SCROLLBAR-DRAG SCROLLBAR-H SCROLLBAR-HO SCROLLBAR-HOR SCROLLBAR-HORI SCROLLBAR-HORIZ + SCROLLBAR-HORIZO SCROLLBAR-HORIZON SCROLLBAR-HORIZONT SCROLLBAR-HORIZONTA SCROLLBAR-HORIZONTAL + SCROLL-BARS SCROLLBAR-V SCROLLBAR-VE SCROLLBAR-VER SCROLLBAR-VERT SCROLLBAR-VERTI SCROLLBAR-VERTIC + SCROLLBAR-VERTICA SCROLLBAR-VERTICAL SCROLL-DELTA SCROLLED-ROW-POS SCROLLED-ROW-POSI + SCROLLED-ROW-POSIT SCROLLED-ROW-POSITI SCROLLED-ROW-POSITIO SCROLLED-ROW-POSITION SCROLL-HORIZONTAL + SCROLLING SCROLL-LEFT SCROLL-MODE SCROLL-NOTIFY SCROLL-OFFSET SCROLL-RIGHT SCROLL-TO-CURRENT-ROW + SCROLL-TO-I SCROLL-TO-IT SCROLL-TO-ITE SCROLL-TO-ITEM SCROLL-TO-SELECTED-ROW SCROLL-VERTICAL SDBNAME + SEAL SEAL-TIMESTAMP SEARCH SEARCH-SELF SEARCH-TARGER SEARCH-TARGET SECTION SECURITY-POLICY SEEK + SELECT SELECTABLE SELECT-ALL SELECTED SELECTED-ITEMS SELECT-EXTEND SELECT-FOCUSED-ROW SELECTION + SELECTION-END SELECTION-EXTEND SELECTION-LIST SELECTION-START SELECTION-TEXT SELECT-NEXT-ROW + SELECT-ON-JOIN SELECT-PREV-ROW SELECT-REPOSITIONED-ROW SELECT-ROW SELF SEND SEND-SQL + SEND-SQL-STATEMENT SENSITIVE SEPARATE-CONNECTION SEPARATOR-FGC SEPARATOR-FGCO SEPARATOR-FGCOL + SEPARATOR-FGCOLO SEPARATOR-FGCOLOR SEPARATORS SERIALIZABLE SERIALIZE-HIDDEN SERIALIZE-NAME + SERIALIZE-ROW SERVER SERVER-CONNECTION-BO SERVER-CONNECTION-BOU SERVER-CONNECTION-BOUN + SERVER-CONNECTION-BOUND SERVER-CONNECTION-BOUND-RE SERVER-CONNECTION-BOUND-REQ SERVER-CONNECTION-BOUND-REQU + SERVER-CONNECTION-BOUND-REQUE SERVER-CONNECTION-BOUND-REQUES SERVER-CONNECTION-BOUND-REQUEST + SERVER-CONNECTION-CO SERVER-CONNECTION-CON SERVER-CONNECTION-CONT SERVER-CONNECTION-CONTE + SERVER-CONNECTION-CONTEX SERVER-CONNECTION-CONTEXT SERVER-CONNECTION-ID SERVER-OPERATING-MODE + SERVER-SOCKET SESSION SESSION-END SESSION-ID SET SET-ACTOR SET-APPL-CONTEXT SET-ATTR-CALL-TYPE + SET-ATTRIBUTE SET-ATTRIBUTE-NODE SET-BLUE SET-BLUE- SET-BLUE-V SET-BLUE-VA SET-BLUE-VAL + SET-BLUE-VALU SET-BLUE-VALUE SET-BREAK SET-BUFFERS SET-BYTE-ORDER SET-CALLBACK SET-CALLBACK-PROCEDURE + SET-CELL-FOCUS SET-CLIENT SET-COMMIT SET-CONNECT-PROCEDURE SET-CONTENTS SET-CURRENT-VALUE + SET-DB-CLIENT SET-DB-LOGGING SET-DYNAMIC SET-EFFECTIVE-TENANT SET-EVENT-MANAGER-OPTION SET-GREEN + SET-GREEN- SET-GREEN-V SET-GREEN-VA SET-GREEN-VAL SET-GREEN-VALU SET-GREEN-VALUE SET-INPUT-SOURCE + SET-MUST-UNDERSTAND SET-NODE SET-NUMERIC-FORM SET-NUMERIC-FORMA SET-NUMERIC-FORMAT SET-OPTION + SET-OUTPUT-DESTINATION SET-PARAMETER SET-POINTER-VAL SET-POINTER-VALU SET-POINTER-VALUE SET-PROPERTY + SET-READ-RESPONSE-PROCEDURE SET-RED SET-RED- SET-RED-V SET-RED-VA SET-RED-VAL SET-RED-VALU + SET-RED-VALUE SET-REPOSITIONED-ROW SET-RGB SET-RGB- SET-RGB-V SET-RGB-VA SET-RGB-VAL SET-RGB-VALU + SET-RGB-VALUE SET-ROLE SET-ROLLBACK SET-SAFE-USER SET-SELECTION SET-SERIALIZED SET-SIZE + SET-SOCKET-OPTION SET-SORT-ARROW SET-STATE SETTINGS SETUSER SETUSERI SETUSERID SET-WAIT SET-WAIT- + SET-WAIT-S SET-WAIT-ST SET-WAIT-STA SET-WAIT-STAT SET-WAIT-STATE SHA1-DIGEST SHARE SHARE- SHARED + SHARE-L SHARE-LO SHARE-LOC SHARE-LOCK SHORT SHOW-IN-TASK SHOW-IN-TASKB SHOW-IN-TASKBA + SHOW-IN-TASKBAR SHOW-STAT SHOW-STATS SIDE-LAB SIDE-LABE SIDE-LABEL SIDE-LABEL-H SIDE-LABEL-HA + SIDE-LABEL-HAN SIDE-LABEL-HAND SIDE-LABEL-HANDL SIDE-LABEL-HANDLE SIDE-LABELS SIGNATURE + SIGNATURE-VALUE SILENT SIMPLE SINGLE SINGLE-CHARACTER SINGLE-RUN SINGLETON SIZE SIZE-C SIZE-CH + SIZE-CHA SIZE-CHAR SIZE-CHARS SIZE-P SIZE-PI SIZE-PIX SIZE-PIXE SIZE-PIXEL SIZE-PIXELS SKIP + SKIP-DELETED-REC SKIP-DELETED-RECO SKIP-DELETED-RECOR SKIP-DELETED-RECORD SKIP-GROUP-DUPLICATES + SKIP-SCHEMA-CHECK SLIDER SMALL-ICON SMALLINT SMALL-TITLE SOAP-FAULT SOAP-FAULT-ACTOR SOAP-FAULT-CODE + SOAP-FAULT-DETAIL SOAP-FAULT-MISUNDERSTOOD-HEADER SOAP-FAULT-NODE SOAP-FAULT-ROLE SOAP-FAULT-STRING + SOAP-FAULT-SUBCODE SOAP-HEADER SOAP-HEADER-ENTRYREF SOAP-VERSION SOCKET SOME SORT SORT-ASCENDING + SORT-NUMBER SOURCE SOURCE-PROCEDURE SPACE SQL SQRT SSL-SERVER-NAME STANDALONE START + START-BOX-SELECTION START-DOCUMENT START-ELEMENT START-EXTEND-BOX-SELECTION STARTING START-MEM-CHECK + START-MOVE START-RESIZE START-ROW-RESIZE START-SEARCH STARTUP-PARAMETERS STATE-DETAIL STATIC + STATISTICS STATUS STATUS-AREA STATUS-AREA-FONT STATUS-AREA-MSG STDCALL STOMP-DETECTION + STOMP-FREQUENCY STOP STOP-AFTER STOP-DISPLAY STOP-MEM-CHECK STOP-OBJECT STOP-PARSING STOPPE STOPPED + STORED-PROC STORED-PROCE STORED-PROCED STORED-PROCEDU STORED-PROCEDUR STORED-PROCEDURE STREAM + STREAM-HANDLE STREAM-IO STRETCH-TO-FIT STRICT STRICT-ENTITY-RESOLUTION STRING STRING-VALUE + STRING-XREF SUB- SUB-AVE SUB-AVER SUB-AVERA SUB-AVERAG SUB-AVERAGE SUB-COUNT SUB-MAX SUB-MAXI + SUB-MAXIM SUB-MAXIMU SUB-MAXIMUM SUB-MENU SUB-MENU-HELP SUB-MIN SUB-MINI SUB-MINIM SUB-MINIMU + SUB-MINIMUM SUBSCRIBE SUBST SUBSTI SUBSTIT SUBSTITU SUBSTITUT SUBSTITUTE SUBSTR SUBSTRI SUBSTRIN + SUBSTRING SUB-TOTAL SUBTYPE SUM SUMMARY SUM-MAX SUPER SUPER-PROC SUPER-PROCE SUPER-PROCED + SUPER-PROCEDU SUPER-PROCEDUR SUPER-PROCEDURE SUPER-PROCEDURES SUPPRESS-NAMESPACE-PROCESSING + SUPPRESS-W SUPPRESS-WA SUPPRESS-WAR SUPPRESS-WARN SUPPRESS-WARNI SUPPRESS-WARNIN SUPPRESS-WARNING + SUPPRESS-WARNINGS SUPPRESS-WARNINGS-LIST SUSPEND SYMMETRIC-ENCRYPTION-ALGORITHM SYMMETRIC-ENCRYPTION-IV + SYMMETRIC-ENCRYPTION-KEY SYMMETRIC-SUPPORT SYNCHRONIZE SYSTEM-ALERT SYSTEM-ALERT- SYSTEM-ALERT-B + SYSTEM-ALERT-BO SYSTEM-ALERT-BOX SYSTEM-ALERT-BOXE SYSTEM-ALERT-BOXES SYSTEM-DIALOG SYSTEM-HELP + SYSTEM-ID TAB TABLE TABLE-CRC-LIST TABLE-HANDLE TABLE-LIST TABLE-NUM TABLE-NUMB TABLE-NUMBE + TABLE-NUMBER TABLE-SCAN TAB-POSITION TAB-STOP TARGET TARGET-PROCEDURE TEMP-DIR TEMP-DIRE TEMP-DIREC + TEMP-DIRECT TEMP-DIRECTO TEMP-DIRECTOR TEMP-DIRECTORY TEMP-TABLE TEMP-TABLE-PREPAR + TEMP-TABLE-PREPARE TENANT TENANT-ID TENANT-NAME TENANT-NAME-TO-ID TENANT-WHERE TERM TERMINAL + TERMINATE TEXT TEXT-CURSOR TEXT-SEG TEXT-SEG- TEXT-SEG-G TEXT-SEG-GR TEXT-SEG-GRO TEXT-SEG-GROW + TEXT-SEG-GROWT TEXT-SEG-GROWTH TEXT-SELECTED THEN THIS-OBJECT THIS-PROCEDURE THREAD-SAFE THREE-D + THROUGH THROW THRU TIC-MARKS TIME TIME-SOURCE TIMEZONE TITLE TITLE-BGC TITLE-BGCO TITLE-BGCOL + TITLE-BGCOLO TITLE-BGCOLOR TITLE-DC TITLE-DCO TITLE-DCOL TITLE-DCOLO TITLE-DCOLOR TITLE-FGC + TITLE-FGCO TITLE-FGCOL TITLE-FGCOLO TITLE-FGCOLOR TITLE-FO TITLE-FON TITLE-FONT TO TODAY TOGGLE-BOX + TOOLTIP TOOLTIPS TOP TOP-COLUMN TOPIC TOP-NAV-QUERY TOP-ONLY TO-ROWID TOTAL TRACE-FILTER TRACING + TRACKING-CHANGES TRAILING TRANS TRANSACT TRANSACTI TRANSACTIO TRANSACTION TRANSACTION-MODE + TRANS-INIT-PROC TRANS-INIT-PROCE TRANS-INIT-PROCED TRANS-INIT-PROCEDU TRANS-INIT-PROCEDUR + TRANS-INIT-PROCEDURE TRANSPAR TRANSPARE TRANSPAREN TRANSPARENT TRIGGER TRIGGERS TRIM TRUE TRUNC + TRUNCA TRUNCAT TRUNCATE TTCODEPAGE TYPE TYPE-OF UNBOX UNBUFF UNBUFFE UNBUFFER UNBUFFERE UNBUFFERED + UNDERL UNDERLI UNDERLIN UNDERLINE UNDO UNDO-THROW-SCOPE UNFORM UNFORMA UNFORMAT UNFORMATT UNFORMATTE + UNFORMATTED UNION UNIQUE UNIQUE-ID UNIQUE-MATCH UNIX UNIX-END UNLESS-HIDDEN UNLOAD UNSIGNED-BYTE + UNSIGNED-INT64 UNSIGNED-INTEGER UNSIGNED-LONG UNSIGNED-SHORT UNSUBSCRIBE UP UPDATE UPDATE-ATTRIBUTE + UPPER URL URL-DECODE URL-ENCODE URL-PASSWORD URL-USERID USE USE-DIC USE-DICT USE-DICT- USE-DICT-E + USE-DICT-EX USE-DICT-EXP USE-DICT-EXPS USE-FILENAME USE-INDEX USER USER-DATA USE-REVVIDEO USERID + USER-ID USE-TEXT USE-UNDERLINE USE-WIDGET-POOL USING UTC-OFFSET V6DISPLAY V6FRAME VALIDATE + VALIDATE-DOMAIN-ACCESS-CODE VALIDATE-EXPRESSIO VALIDATE-EXPRESSION VALIDATE-MESSAGE VALIDATE-SEAL + VALIDATE-XML VALIDATION-ENABLED VALID-EVENT VALID-HANDLE VALID-OBJECT VALUE VALUE-CHANGED VALUES VAR + VARI VARIA VARIAB VARIABL VARIABLE VERB VERBO VERBOS VERBOSE VERSION VERT VERTI VERTIC VERTICA + VERTICAL VIEW VIEW-AS VIEW-FIRST-COLUMN-ON-REOPEN VIRTUAL-HEIGHT VIRTUAL-HEIGHT-C VIRTUAL-HEIGHT-CH + VIRTUAL-HEIGHT-CHA VIRTUAL-HEIGHT-CHAR VIRTUAL-HEIGHT-CHARS VIRTUAL-HEIGHT-P VIRTUAL-HEIGHT-PI + VIRTUAL-HEIGHT-PIX VIRTUAL-HEIGHT-PIXE VIRTUAL-HEIGHT-PIXEL VIRTUAL-HEIGHT-PIXELS VIRTUAL-WIDTH + VIRTUAL-WIDTH-C VIRTUAL-WIDTH-CH VIRTUAL-WIDTH-CHA VIRTUAL-WIDTH-CHAR VIRTUAL-WIDTH-CHARS + VIRTUAL-WIDTH-P VIRTUAL-WIDTH-PI VIRTUAL-WIDTH-PIX VIRTUAL-WIDTH-PIXE VIRTUAL-WIDTH-PIXEL + VIRTUAL-WIDTH-PIXELS VISIBLE VMS VOID WAIT WAIT-FOR WARNING WC-ADMIN-APP WEB-CON WEB-CONT WEB-CONTE + WEB-CONTEX WEB-CONTEXT WEB-NOTIFY WEEKDAY WHEN WHERE WHERE-STRING WHILE WIDGET WIDGET-E WIDGET-EN + WIDGET-ENT WIDGET-ENTE WIDGET-ENTER WIDGET-H WIDGET-HA WIDGET-HAN WIDGET-HAND WIDGET-HANDL + WIDGET-HANDLE WIDGET-ID WIDGET-L WIDGET-LE WIDGET-LEA WIDGET-LEAV WIDGET-LEAVE WIDGET-POOL WIDTH + WIDTH-C WIDTH-CH WIDTH-CHA WIDTH-CHAR WIDTH-CHARS WIDTH-P WIDTH-PI WIDTH-PIX WIDTH-PIXE WIDTH-PIXEL + WIDTH-PIXELS WINDOW WINDOW-CLOSE WINDOW-DELAYED-MIN WINDOW-DELAYED-MINI WINDOW-DELAYED-MINIM + WINDOW-DELAYED-MINIMI WINDOW-DELAYED-MINIMIZ WINDOW-DELAYED-MINIMIZE WINDOW-MAXIM WINDOW-MAXIMI + WINDOW-MAXIMIZ WINDOW-MAXIMIZE WINDOW-MAXIMIZED WINDOW-MINIM WINDOW-MINIMI WINDOW-MINIMIZ + WINDOW-MINIMIZE WINDOW-MINIMIZED WINDOW-NAME WINDOW-NORMAL WINDOW-RESIZED WINDOW-RESTORED WINDOW-STA + WINDOW-STAT WINDOW-STATE WINDOW-SYS WINDOW-SYST WINDOW-SYSTE WINDOW-SYSTEM WITH WORD-INDEX WORD-WRAP + WORK-AREA-HEIGHT-P WORK-AREA-HEIGHT-PI WORK-AREA-HEIGHT-PIX WORK-AREA-HEIGHT-PIXE + WORK-AREA-HEIGHT-PIXEL WORK-AREA-HEIGHT-PIXELS WORK-AREA-WIDTH-P WORK-AREA-WIDTH-PI + WORK-AREA-WIDTH-PIX WORK-AREA-WIDTH-PIXE WORK-AREA-WIDTH-PIXEL WORK-AREA-WIDTH-PIXELS WORK-AREA-X + WORK-AREA-Y WORKFILE WORK-TAB WORK-TABL WORK-TABLE WRITE WRITE-CDATA WRITE-CHARACTERS WRITE-COMMENT + WRITE-DATA WRITE-DATA-ELEMENT WRITE-EMPTY-ELEMENT WRITE-ENTITY-REF WRITE-EXTERNAL-DTD WRITE-FRAGMENT + WRITE-JSON WRITE-MESSAGE WRITE-PROCESSING-INSTRUCTION WRITE-STATUS WRITE-XML WRITE-XMLSCHEMA X XCODE + XCODE-SESSION-KEY X-DOCUMENT XML-DATA-TYPE XML-ENTITY-EXPANSION-LIMIT XML-NODE-NAME XML-NODE-TYPE + XML-SCHEMA-PAT XML-SCHEMA-PATH XML-STRICT-ENTITY-RESOLUTION XML-SUPPRESS-NAMESPACE-PROCESSING + X-NODEREF X-OF XOR XREF XREF-XML Y YEAR YEAR-OFFSET YES YES-NO YES-NO-CANCEL Y-OF + ) + end + + def self.keywords_prepro + @keywords_prepro ||= Set.new %w( + &ANALYZE-SUSPEND &ANALYZE-RESUME + &ELSE &ELSEIF &ENDIF &GLOB &GLOBAL-DEFINE &IF &MESSAGE &SCOP &SCOPED-DEFINE &THEN &UNDEF &UNDEFINE &WEBSTREAM + {&BATCH} {&BATCH-MODE} {&FILE-NAME} {&LINE-NUMBE} {&LINE-NUMBER} {&OPSYS} {&PROCESS-ARCHITECTURE} {&SEQUENCE} + {&WINDOW-SYS} {&WINDOW-SYSTEM} + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + BLOB CHARACTER CHAR CLOB COM-HANDLE DATE DATETIME DATETIME-TZ DECIMAL + DEC HANDLE INT64 INTEGER INT LOGICAL LONGCHAR MEMPTR RAW RECID ROWID + WIDGET-HANDLE VOID + ) + end + + state :statements do + mixin :singlelinecomment + mixin :multilinecomment + mixin :string + mixin :numeric + mixin :constant + mixin :operator + mixin :whitespace + mixin :preproc + mixin :decorator + mixin :function + end + + state :whitespace do + rule %r/\s+/m, Text + end + + state :singlelinecomment do + rule %r(//.*$), Comment::Single + end + + state :multilinecomment do + rule %r(/[*]), Comment::Multiline, :multilinecomment_content + end + + state :multilinecomment_content do + rule %r([*]/), Comment::Multiline, :pop! + rule %r(/[*]), Comment::Multiline, :multilinecomment_content + rule %r([^*/]+), Comment::Multiline + rule %r([*/]), Comment::Multiline + end + + state :string do + rule %r/"/, Str::Delimiter, :doublequotedstring + rule %r/'/, Str::Delimiter, :singlequotedstring + end + + state :numeric do + rule %r((?:\d+[.]\d*|[.]\d+)(?:e[+-]?\d+[lu]*)?)i, Num::Float + rule %r(\d+e[+-]?\d+[lu]*)i, Num::Float + rule %r/0x[0-9a-f]+[lu]*/i, Num::Hex + rule %r/0[0-7]+[lu]*/i, Num::Oct + rule %r/\d+[lu]*/i, Num::Integer + end + + state :constant do + rule %r/(?:TRUE|FALSE|YES|NO(?!\-)|\?)\b/i, Keyword::Constant + end + + state :operator do + rule %r([~!%^*+=\|?:<>/-]), Operator + rule %r/[()\[\],.]/, Punctuation + end + + state :doublequotedstring do + rule %r/\~[~nrt"]?/, Str::Escape + rule %r/[^\\"]+/, Str::Double + rule %r/"/, Str::Delimiter, :pop! + end + + state :singlequotedstring do + rule %r/\~[~nrt']?/, Str::Escape + rule %r/[^\\']+/, Str::Single + rule %r/'/, Str::Delimiter, :pop! + end + + state :preproc do + rule %r/(\&analyze-suspend|\&analyze-resume)/i, Comment::Preproc, :analyze_suspend_resume_content + rule %r/(\&scoped-define|\&global-define)\s*([\.\w\\\/-]*)/i , Comment::Preproc, :analyze_suspend_resume_content + mixin :include_file + end + + state :analyze_suspend_resume_content do + rule %r/.*(?=(?:\/\/|\/\*))/, Comment::Preproc, :pop! + rule %r/.*\n/, Comment::Preproc, :pop! + rule %r/.*/, Comment::Preproc, :pop! + end + + state :preproc_content do + rule %r/\n/, Text, :pop! + rule %r/\s+/, Text + + rule %r/({?&)(\S+)/ do + groups Comment::Preproc, Name::Other + end + + rule %r/"/, Str, :string + mixin :numeric + + rule %r/\S+/, Name + end + + state :include_file do + rule %r/(\{(?:[^\{\}]|(\g<0>))+\})/i , Comment::Preproc + end + + state :decorator do + rule %r/@#{id}/, Name::Decorator #, :decorator_content + end + + state :function do + rule %r/\!?#{id}(?=\s*\()/i , Name::Function + end + + state :root do + mixin :statements + + rule id do |m| + name = m[0].upcase + if self.class.keywords_prepro.include? name + token Comment::Preproc + elsif self.class.keywords.include? name + token Keyword + elsif self.class.keywords_type.include? name + token Keyword::Type + else + token Name::Variable + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/opentype_feature_file.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/opentype_feature_file.rb new file mode 100644 index 0000000..943d6ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/opentype_feature_file.rb @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class OpenTypeFeatureFile < RegexLexer + title "OpenType Feature File" + desc "Feature specifications for an OpenType font (adobe-type-tools.github.io/afdko)" + tag 'opentype_feature_file' + aliases 'fea', 'opentype', 'opentypefeature' + filenames '*.fea' + + def self.keywords + @keywords ||= %w( + Ascender Attach AxisValue CapHeight CaretOffset CodePageRange + DesignAxis Descender ElidedFallbackName ElidedFallbackNameID + ElidableAxisValueName FeatUILabelNameID FeatUITooltipTextNameID + FontRevision FSType GlyphClassDef HorizAxis.BaseScriptList + HorizAxis.BaseTagList HorizAxis.MinMax IgnoreBaseGlyphs + IgnoreLigatures IgnoreMarks LigatureCaretByDev LigatureCaretByIndex + LigatureCaretByPos LineGap MarkAttachClass MarkAttachmentType NULL + OlderSiblingFontAttribute Panose ParamUILabelNameID RightToLeft + SampleTextNameID TypoAscender TypoDescender TypoLineGap UnicodeRange + UseMarkFilteringSet Vendor VertAdvanceY VertAxis.BaseScriptList + VertAxis.BaseTagList VertAxis.MinMax VertOriginY VertTypoAscender + VertTypoDescender VertTypoLineGap WeightClass WidthClass XHeight + + anchorDef anchor anonymous anon by contour cursive device enumerate + enum exclude_dflt featureNames feature flag from ignore include_dflt + include languagesystem language location lookupflag lookup markClass + mark nameid name parameters position pos required reversesub rsub + script sizemenuname substitute subtable sub table useExtension + valueRecordDef winAscent winDescent + ) + end + + + identifier = %r/[a-z_][a-z0-9\/_.-]*/i + + state :root do + rule %r/\s+/m, Text::Whitespace + rule %r/#.*$/, Comment + + # feature + rule %r/(anonymous|anon|feature|lookup|table)((?:\s)+)/ do + groups Keyword, Text + push :featurename + end + # } ; + rule %r/(\})((?:\s))/ do + groups Punctuation, Text + push :featurename + end + # solve include( ../path) + rule %r/include\b/i, Keyword, :includepath + + rule %r/[\-\[\]\/(){},.:;=%*<>']/, Punctuation + + rule %r/`.*?/, Str::Backtick + rule %r/\"/, Str, :strings + rule %r/\\[^.*\s]+/i, Str::Escape + + # classes, start with @ + rule %r/@#{identifier}/, Name::Class + + # using negative lookbehind so we don't match property names + rule %r/(? << >> \* \| ~ \^ - \+ / + \# \. = != <= >= \+\+ + ) + end + + def self.decls + @decls ||= %w( + control header header_union parser state struct table + value_set + ) + end + + def self.builtins + @builtins ||= %w( + bit bool error extract int isValid setValid setInvalid match_kind + string varbit verify void + ) + end + + state :whitespace do + rule %r/\s+/m, Text + end + + state :comment do + rule %r((//).*$\n?), Comment::Single + rule %r/\/\*(?:(?!\*\/).)*\*\//m, Comment::Multiline + end + + state :number do + rule %r/([0-9]+[sw])?0[oO][0-7_]+/, Num + rule %r/([0-9]+[sw])?0[xX][0-9a-fA-F_]+/, Num + rule %r/([0-9]+[sw])?0[bB][01_]+/, Num + rule %r/([0-9]+[sw])?0[dD][0-9_]+/, Num + rule %r/([0-9]+[sw])?[0-9_]+/, Num + end + + id = /[\p{XID_Start}_]\p{XID_Continue}*/ + string_element = /\\"|[^"]/x + + state :root do + mixin :whitespace + mixin :comment + + rule %r/#\s*#{id}/, Comment::Preproc + rule %r/\b(?:#{P4.keywords.join('|')})\b/, Keyword + rule %r/\b(?:#{P4.decls.join('|')})\b/, Keyword::Declaration + rule %r/\b(?:#{P4.builtins.join('|')})\b/, Name::Builtin + rule %r/\b#{id}_[th]\b/x, Name::Class + rule %r/(?:#{P4.operators.join('|')})/x, Operator + rule %r/[(){}\[\]<>,:;\.]/, Punctuation + mixin :number + rule %r/@#{id}/x, Name::Label + rule %r/#{id}/x, Text + rule %r/"(?: #{string_element} )*"/x, Str::String + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pascal.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pascal.rb new file mode 100644 index 0000000..29491c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pascal.rb @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Pascal < RegexLexer + tag 'pascal' + title "Pascal" + desc 'a procedural programming language commonly used as a teaching language.' + filenames '*.pas', '*.lpr', '*.pp' + + mimetypes 'text/x-pascal' + + id = /@?[_a-z]\w*/i + + keywords = %w( + absolute abstract all and and_then array as asm assembler attribute + begin bindable case class const constructor delay destructor div do + downto else end except exit export exports external far file finalization + finally for forward function goto if implementation import in inc index + inherited initialization inline interface interrupt is label library + message mod module near nil not object of on only operator or or_else + otherwise out overload override packed pascal pow private procedure program + property protected public published qualified raise read record register + repeat resident resourcestring restricted safecall segment set shl shr + stdcall stored string then threadvar to try type unit until uses value var + view virtual while with write writeln xor + ) + + keywords_type = %w( + ansichar ansistring bool boolean byte bytebool cardinal char comp currency + double dword extended int64 integer iunknown longbool longint longword pansichar + pansistring pbool pboolean pbyte pbytearray pcardinal pchar pcomp pcurrency + pdate pdatetime pdouble pdword pextended phandle pint64 pinteger plongint plongword + pointer ppointer pshortint pshortstring psingle psmallint pstring pvariant pwidechar + pwidestring pword pwordarray pwordbool real real48 shortint shortstring single + smallint string tclass tdate tdatetime textfile thandle tobject ttime variant + widechar widestring word wordbool + ) + + state :whitespace do + # Spaces + rule %r/\s+/m, Text + # // Comments + rule %r((//).*$\n?), Comment::Single + # -- Comments + rule %r((--).*$\n?), Comment::Single + # (* Comments *) + rule %r(\(\*.*?\*\))m, Comment::Multiline + # { Comments } + rule %r(\{.*?\})m, Comment::Multiline + end + + state :root do + mixin :whitespace + + rule %r{((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?}, Num + rule %r/\$[0-9A-Fa-f]+/, Num::Hex + rule %r{[~!@#\$%\^&\*\(\)\+`\-={}\[\]:;<>\?,\.\/\|\\]}, Punctuation + rule %r{'([^']|'')*'}, Str + rule %r/(true|false|nil)\b/i, Name::Builtin + rule %r/\b(#{keywords.join('|')})\b/i, Keyword + rule %r/\b(#{keywords_type.join('|')})\b/i, Keyword::Type + rule id, Name + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/perl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/perl.rb new file mode 100644 index 0000000..78d6bc6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/perl.rb @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Perl < RegexLexer + title "Perl" + desc "The Perl scripting language (perl.org)" + + tag 'perl' + aliases 'pl' + + filenames '*.pl', '*.pm', '*.t' + mimetypes 'text/x-perl', 'application/x-perl' + + def self.detect?(text) + return true if text.shebang? 'perl' + end + + keywords = %w( + case continue do else elsif for foreach if last my next our + redo reset then unless until while use print new BEGIN CHECK + INIT END return + ) + + builtins = %w( + abs accept alarm atan2 bind binmode bless caller chdir chmod + chomp chop chown chr chroot close closedir connect continue cos + crypt dbmclose dbmopen defined delete die dump each endgrent + endhostent endnetent endprotoent endpwent endservent eof eval + exec exists exit exp fcntl fileno flock fork format formline getc + getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent + getlogin getnetbyaddr getnetbyname getnetent getpeername + getpgrp getppid getpriority getprotobyname getprotobynumber + getprotoent getpwent getpwnam getpwuid getservbyname getservbyport + getservent getsockname getsockopt glob gmtime goto grep hex + import index int ioctl join keys kill last lc lcfirst length + link listen local localtime log lstat map mkdir msgctl msgget + msgrcv msgsnd my next no oct open opendir ord our pack package + pipe pop pos printf prototype push quotemeta rand read readdir + readline readlink readpipe recv redo ref rename require reverse + rewinddir rindex rmdir scalar seek seekdir select semctl semget + semop send setgrent sethostent setnetent setpgrp setpriority + setprotoent setpwent setservent setsockopt shift shmctl shmget + shmread shmwrite shutdown sin sleep socket socketpair sort splice + split sprintf sqrt srand stat study substr symlink syscall sysopen + sysread sysseek system syswrite tell telldir tie tied time times + tr truncate uc ucfirst umask undef unlink unpack unshift untie + utime values vec wait waitpid wantarray warn write + ) + + re_tok = Str::Regex + + state :balanced_regex do + rule %r(/(\\[\\/]|[^/])*/[egimosx]*)m, re_tok, :pop! + rule %r(!(\\[\\!]|[^!])*![egimosx]*)m, re_tok, :pop! + rule %r(\\(\\\\|[^\\])*\\[egimosx]*)m, re_tok, :pop! + rule %r({(\\[\\}]|[^}])*}[egimosx]*), re_tok, :pop! + rule %r(<(\\[\\>]|[^>])*>[egimosx]*), re_tok, :pop! + rule %r(\[(\\[\\\]]|[^\]])*\][egimosx]*), re_tok, :pop! + rule %r[\((\\[\\\)]|[^\)])*\)[egimosx]*], re_tok, :pop! + rule %r(@(\\[\\@]|[^@])*@[egimosx]*), re_tok, :pop! + rule %r(%(\\[\\%]|[^%])*%[egimosx]*), re_tok, :pop! + rule %r(\$(\\[\\\$]|[^\$])*\$[egimosx]*), re_tok, :pop! + end + + state :root do + rule %r/#.*/, Comment::Single + rule %r/^=[a-zA-Z0-9]+\s+.*?\n=cut/m, Comment::Multiline + rule %r/(?:#{keywords.join('|')})\b/, Keyword + + rule %r/(format)(\s+)([a-zA-Z0-9_]+)(\s*)(=)(\s*\n)/ do + groups Keyword, Text, Name, Text, Punctuation, Text + + push :format + end + + rule %r/(?:eq|lt|gt|le|ge|ne|not|and|or|cmp)\b/, Operator::Word + + # substitution/transliteration: balanced delimiters + rule %r((?:s|tr|y){(\\\\|\\}|[^}])*}\s*), re_tok, :balanced_regex + rule %r((?:s|tr|y)<(\\\\|\\>|[^>])*>\s*), re_tok, :balanced_regex + rule %r((?:s|tr|y)\[(\\\\|\\\]|[^\]])*\]\s*), re_tok, :balanced_regex + rule %r[(?:s|tr|y)\((\\\\|\\\)|[^\)])*\)\s*], re_tok, :balanced_regex + + # substitution/transliteration: arbitrary non-whitespace delimiters + rule %r((?:s|tr|y)\s*([^\w\s])((\\\\|\\\1)|[^\1])*?\1((\\\\|\\\1)|[^\1])*?\1[msixpodualngcr]*)m, re_tok + rule %r((?:s|tr|y)\s+(\w)((\\\\|\\\1)|[^\1])*?\1((\\\\|\\\1)|[^\1])*?\1[msixpodualngcr]*)m, re_tok + + # matches: common case, m-optional + rule %r(m?/(\\\\|\\/|[^/\n])*/[msixpodualngc]*), re_tok + rule %r(m(?=[/!\\{<\[\(@%\$])), re_tok, :balanced_regex + + # arbitrary non-whitespace delimiters + rule %r(m\s*([^\w\s])((\\\\|\\\1)|[^\1])*?\1[msixpodualngc]*)m, re_tok + rule %r(m\s+(\w)((\\\\|\\\1)|[^\1])*?\1[msixpodualngc]*)m, re_tok + + rule %r(((?<==~)|(?<=\())\s*/(\\\\|\\/|[^/])*/[msixpodualngc]*), + re_tok, :balanced_regex + + rule %r/\s+/, Text + + rule(/(?=[a-z_]\w*(\s*#.*\n)*\s*=>)/i) { push :fat_comma } + + rule %r/(?:#{builtins.join('|')})\b/, Name::Builtin + rule %r/((__(DIE|WARN)__)|(DATA|STD(IN|OUT|ERR)))\b/, + Name::Builtin::Pseudo + + rule %r/<<([\'"]?)([a-zA-Z_][a-zA-Z0-9_]*)\1;?\n.*?\n\2\n/m, Str + + rule %r/(__(END|DATA)__)\b/, Comment::Preproc, :end_part + rule %r/\$\^[ADEFHILMOPSTWX]/, Name::Variable::Global + rule %r/\$[\\"'\[\]&`+*.,;=%~?@$!<>(^\|\/_-](?!\w)/, Name::Variable::Global + rule %r/[$@%&*][$@%&*#_]*(?=[a-z{\[;])/i, Name::Variable, :varname + + rule %r/[-+\/*%=<>&^\|!\\~]=?/, Operator + + rule %r/0_?[0-7]+(_[0-7]+)*/, Num::Oct + rule %r/0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*/, Num::Hex + rule %r/0b[01]+(_[01]+)*/, Num::Bin + rule %r/(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?/i, + Num::Float + rule %r/\d+(_\d*)*e[+-]?\d+(_\d*)*/i, Num::Float + rule %r/\d+(_\d+)*/, Num::Integer + + rule %r/'/, Punctuation, :sq + rule %r/"/, Punctuation, :dq + rule %r/`/, Punctuation, :bq + rule %r/<([^\s>]+)>/, re_tok + rule %r/(q|qq|qw|qr|qx)\{/, Str::Other, :cb_string + rule %r/(q|qq|qw|qr|qx)\(/, Str::Other, :rb_string + rule %r/(q|qq|qw|qr|qx)\[/, Str::Other, :sb_string + rule %r/(q|qq|qw|qr|qx)>|>=|<=|<=>|={3}|!=|=~|!~|&&?|\|\||\.{1,3}/, + Operator + rule %r/[()\[\]:;,<>\/?{}]/, Punctuation + rule(/(?=\w)/) { push :name } + end + + state :format do + rule %r/\.\n/, Str::Interpol, :pop! + rule %r/.*?\n/, Str::Interpol + end + + state :fat_comma do + rule %r/#.*/, Comment::Single + rule %r/\w+/, Str + rule %r/\s+/, Text + rule %r/=>/, Operator, :pop! + end + + state :name_common do + rule %r/\w+::/, Name::Namespace + rule %r/[\w:]+/, Name::Variable, :pop! + end + + state :varname do + rule %r/\s+/, Text + rule %r/[{\[]/, Punctuation, :pop! # hash syntax + rule %r/[),]/, Punctuation, :pop! # arg specifier + rule %r/[;]/, Punctuation, :pop! # postfix + mixin :name_common + end + + state :name do + mixin :name_common + rule %r/[A-Z_]+(?=[^a-zA-Z0-9_])/, Name::Constant, :pop! + rule(/(?=\W)/) { pop! } + end + + state :modulename do + rule %r/[a-z_]\w*/i, Name::Namespace, :pop! + end + + state :funcname do + rule %r/[a-zA-Z_]\w*[!?]?/, Name::Function + rule %r/\s+/, Text + + # argument declaration + rule %r/(\([$@%]*\))(\s*)/ do + groups Punctuation, Text + end + + rule %r/.*?{/, Punctuation, :pop! + rule %r/;/, Punctuation, :pop! + end + + state :sq do + rule %r/\\[\\']/, Str::Escape + rule %r/[^\\']+/, Str::Single + rule %r/'/, Punctuation, :pop! + rule %r/\\/, Str::Single + end + + state :dq do + mixin :string_intp + rule %r/\\[\\tnrabefluLUE"$@]/, Str::Escape + rule %r/\\0\d{2}/, Str::Escape + rule %r/\\o\{\d+\}/, Str::Escape + rule %r/\\x\h{2}/, Str::Escape + rule %r/\\x\{\h+\}/, Str::Escape + rule %r/\\c./, Str::Escape + rule %r/\\N\{[^\}]+\}/, Str::Escape + rule %r/[^\\"]+?/, Str::Double + rule %r/"/, Punctuation, :pop! + rule %r/\\/, Str::Escape + end + + state :bq do + mixin :string_intp + rule %r/\\[\\tnr`]/, Str::Escape + rule %r/[^\\`]+?/, Str::Backtick + rule %r/`/, Punctuation, :pop! + end + + [[:cb, '\{', '\}'], + [:rb, '\(', '\)'], + [:sb, '\[', '\]'], + [:lt, '<', '>']].each do |name, open, close| + tok = Str::Other + state :"#{name}_string" do + rule %r/\\[#{open}#{close}\\]/, tok + rule %r/\\/, tok + rule(/#{open}/) { token tok; push } + rule %r/#{close}/, tok, :pop! + rule %r/[^#{open}#{close}\\]+/, tok + end + end + + state :in_interp do + rule %r/}/, Str::Interpol, :pop! + rule %r/\s+/, Text + rule %r/[a-z_]\w*/i, Str::Interpol + end + + state :string_intp do + rule %r/[$@][{]/, Str::Interpol, :in_interp + rule %r/[$@][a-z_]\w*/i, Str::Interpol + end + + state :end_part do + # eat the rest of the stream + rule %r/.+/m, Comment::Preproc, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php.rb new file mode 100644 index 0000000..ebdb265 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php.rb @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class PHP < TemplateLexer + title "PHP" + desc "The PHP scripting language (php.net)" + tag 'php' + aliases 'php', 'php3', 'php4', 'php5' + filenames '*.php', '*.php[345t]','*.phtml', + # Support Drupal file extensions, see: + # https://github.com/gitlabhq/gitlabhq/issues/8900 + '*.module', '*.inc', '*.profile', '*.install', '*.test' + mimetypes 'text/x-php' + + option :start_inline, 'Whether to start with inline php or require . (default: best guess)' + option :funcnamehighlighting, 'Whether to highlight builtin functions (default: true)' + option :disabledmodules, 'Disable certain modules from being highlighted as builtins (default: empty)' + + def initialize(*) + super + + # if truthy, the lexer starts highlighting with php code + # (no / do + token Comment::Preproc + reset_stack + end + end + + state :return do + rule(//) { pop! } + end + + state :start do + # We enter this state if we aren't sure whether the PHP in the text is + # delimited by \/@-]+/, Operator + end + + state :string do + rule %r/"/, Str::Double, :pop! + rule %r/[^\\{$"]+/, Str::Double + rule %r/\\u\{[0-9a-fA-F]+\}/, Str::Escape + rule %r/\\([efrntv\"$\\]|[0-7]{1,3}|[xX][0-9a-fA-F]{1,2})/, Str::Escape + rule %r/\$#{id}(\[\S+\]|->#{id})?/, Name::Variable + + rule %r/\{\$\{/, Str::Interpol, :string_interp_double + rule %r/\{(?=\$)/, Str::Interpol, :string_interp_single + rule %r/(\{)(\S+)(\})/ do + groups Str::Interpol, Name::Variable, Str::Interpol + end + + rule %r/[${\\]+/, Str::Double + end + + state :string_interp_double do + rule %r/\}\}/, Str::Interpol, :pop! + mixin :php + end + + state :string_interp_single do + rule %r/\}/, Str::Interpol, :pop! + mixin :php + end + + state :values do + # heredocs + rule %r/<<<(["']?)(#{id})\1\n.*?\n\s*\2;?/im, Str::Heredoc + + # numbers + rule %r/(\d[_\d]*)?\.(\d[_\d]*)?(e[+-]?\d[_\d]*)?/i, Num::Float + rule %r/0o?[0-7][0-7_]*/i, Num::Oct + rule %r/0b[01][01_]*/i, Num::Bin + rule %r/0x[a-f0-9][a-f0-9_]*/i, Num::Hex + rule %r/\d[_\d]*/, Num::Integer + + # strings + rule %r/'([^'\\]*(?:\\.[^'\\]*)*)'/, Str::Single + rule %r/`([^`\\]*(?:\\.[^`\\]*)*)`/, Str::Backtick + rule %r/"/, Str::Double, :string + + # functions + rule %r/(function|fn)\b/i do + push :in_function_return + push :in_function_params + push :in_function_name + token Keyword + end + + # constants + rule %r/(true|false|null)\b/i, Keyword::Constant + + # objects + rule %r/new\b/i, Keyword, :in_new + end + + state :variables do + rule %r/\$\{\$+#{id}\}/, Name::Variable + rule %r/\$+#{id}/, Name::Variable + end + + state :whitespace do + rule %r/\s+/, Text + rule %r/#[^\[].*?$/, Comment::Single + rule %r(//.*?$), Comment::Single + rule %r(/\*\*(?!/).*?\*/)m, Comment::Doc + rule %r(/\*.*?\*/)m, Comment::Multiline + end + + state :root do + rule %r/<\?(php|=)?/i, Comment::Preproc, :php + rule(/.*?(?=<\?)|.*/m) { delegate parent } + end + + state :php do + mixin :escape + + mixin :whitespace + mixin :variables + mixin :values + + rule %r/(namespace) + (\s+) + (#{id_with_ns})/ix do |m| + groups Keyword::Namespace, Text, Name::Namespace + end + + rule %r/#\[.*\]$/, Name::Attribute + + rule %r/(class|interface|trait|extends|implements) + (\s+) + (#{id_with_ns})/ix do |m| + groups Keyword::Declaration, Text, Name::Class + end + + rule %r/(enum) + (\s+) + (#{id_with_ns})/ix do |m| + groups Keyword::Declaration, Text, Name::Class + push :in_enum + end + + mixin :names + + rule %r/[;,\(\)\{\}\[\]]/, Punctuation + + mixin :operators + rule %r/[=?]/, Operator + end + + state :in_assign do + rule %r/,/, Punctuation, :pop! + rule %r/[\[\]]/, Punctuation + rule %r/\(/, Punctuation, :in_assign_function + mixin :escape + mixin :whitespace + mixin :values + mixin :variables + mixin :names + mixin :operators + mixin :return + end + + state :in_assign_function do + rule %r/\)/, Punctuation, :pop! + rule %r/,/, Punctuation + mixin :in_assign + end + + state :in_catch do + rule %r/\(/, Punctuation + rule %r/\|/, Operator + rule id_with_ns, Name::Class + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_const do + rule %r/(\??#{id})(\s+)(#{id})/i do + groups Keyword::Type, Text, Name::Constant + end + rule id, Name::Constant + rule %r/=/, Operator, :in_assign + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_function_body do + rule %r/{/, Punctuation, :push + rule %r/}/, Punctuation, :pop! + mixin :php + end + + state :in_function_name do + rule %r/&/, Operator + rule id, Name + rule %r/\(/, Punctuation, :pop! + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_function_params do + rule %r/\)/, Punctuation, :pop! + rule %r/,/, Punctuation + rule %r/[.]{3}/, Punctuation + rule %r/=/, Operator, :in_assign + rule %r/\b(?:public|protected|private|readonly)(?:\(set\)|\b)/i, Keyword + rule %r/\breadonly\b/i, Keyword + rule %r/\??#{id}/, Keyword::Type, :in_assign + mixin :escape + mixin :whitespace + mixin :variables + mixin :return + end + + state :in_function_return do + rule %r/:/, Punctuation + rule %r/use\b/i, Keyword, :in_function_use + rule %r/\??#{id}/, Keyword::Type, :in_assign + rule %r/\{/ do + token Punctuation + goto :in_function_body + end + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_function_use do + rule %r/[,\(]/, Punctuation + rule %r/&/, Operator + rule %r/\)/, Punctuation, :pop! + mixin :escape + mixin :whitespace + mixin :variables + mixin :return + end + + state :in_new do + rule %r/class\b/i do + token Keyword::Declaration + goto :in_new_class + end + rule id_with_ns, Name::Class, :pop! + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_new_class do + rule %r/\}/, Punctuation, :pop! + rule %r/\{/, Punctuation + mixin :php + end + + state :in_use do + rule %r/[,\}]/, Punctuation + rule %r/(function|const)\b/i, Keyword + rule %r/(#{ns})(\{)/ do + groups Name::Namespace, Punctuation + end + rule %r/#{id_with_ns}(_#{id})+/, Name::Function + mixin :escape + mixin :whitespace + mixin :names + mixin :return + end + + state :in_visibility do + rule %r/\b(?:public|protected|private)(?:\(set\)|\b)/i, Keyword + rule %r/\b(?:readonly|static)\b/i, Keyword + rule %r/(?=(abstract|const|function)\b)/i, Keyword, :pop! + rule %r/\??#{id}/, Keyword::Type, :pop! + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_enum do + rule %r/:/, Punctuation, :in_enum_base_type + rule %r/\{/, Punctuation, :in_enum_body + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_enum_base_type do + rule id, Keyword::Type, :pop! + mixin :escape + mixin :whitespace + mixin :return + end + + state :in_enum_body do + rule %r/\}/, Punctuation, :pop! + rule %r/(case)(\s+)(#{id})/i do + groups Keyword, Text, Name::Constant + end + mixin :php + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php/keywords.rb new file mode 100644 index 0000000..bf504d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/php/keywords.rb @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# DO NOT EDIT +# This file is automatically generated by `rake builtins:php`. +# See tasks/builtins/php.rake for more info. + +module Rouge + module Lexers + class PHP + def self.builtins + @builtins ||= {}.tap do |b| + b["Apache"] = Set.new ["apache_child_terminate", "apache_get_modules", "apache_get_version", "apache_getenv", "apache_lookup_uri", "apache_note", "apache_request_headers", "apache_response_headers", "apache_setenv", "getallheaders", "virtual"] + b["APCu"] = Set.new ["apcu_add", "apcu_cache_info", "apcu_cas", "apcu_clear_cache", "apcu_dec", "apcu_delete", "apcu_enabled", "apcu_entry", "apcu_exists", "apcu_fetch", "apcu_inc", "apcu_key_info", "apcu_sma_info", "apcu_store"] + b["Array"] = Set.new ["array", "array_all", "array_any", "array_change_key_case", "array_chunk", "array_column", "array_combine", "array_count_values", "array_diff", "array_diff_assoc", "array_diff_key", "array_diff_uassoc", "array_diff_ukey", "array_fill", "array_fill_keys", "array_filter", "array_find", "array_find_key", "array_first", "array_flip", "array_intersect", "array_intersect_assoc", "array_intersect_key", "array_intersect_uassoc", "array_intersect_ukey", "array_is_list", "array_key_exists", "array_key_first", "array_key_last", "array_keys", "array_last", "array_map", "array_merge", "array_merge_recursive", "array_multisort", "array_pad", "array_pop", "array_product", "array_push", "array_rand", "array_reduce", "array_replace", "array_replace_recursive", "array_reverse", "array_search", "array_shift", "array_slice", "array_splice", "array_sum", "array_udiff", "array_udiff_assoc", "array_udiff_uassoc", "array_uintersect", "array_uintersect_assoc", "array_uintersect_uassoc", "array_unique", "array_unshift", "array_values", "array_walk", "array_walk_recursive", "arsort", "asort", "compact", "count", "current", "each", "end", "extract", "in_array", "key", "key_exists", "krsort", "ksort", "list", "natcasesort", "natsort", "next", "pos", "prev", "range", "reset", "rsort", "shuffle", "sizeof", "sort", "uasort", "uksort", "usort"] + b["BC Math"] = Set.new ["bcadd", "bcceil", "bccomp", "bcdiv", "bcdivmod", "bcfloor", "bcmod", "bcmul", "bcpow", "bcpowmod", "bcround", "bcscale", "bcsqrt", "bcsub"] + b["Bzip2"] = Set.new ["bzclose", "bzcompress", "bzdecompress", "bzerrno", "bzerror", "bzerrstr", "bzflush", "bzopen", "bzread", "bzwrite"] + b["Calendar"] = Set.new ["cal_days_in_month", "cal_from_jd", "cal_info", "cal_to_jd", "easter_date", "easter_days", "frenchtojd", "gregoriantojd", "jddayofweek", "jdmonthname", "jdtofrench", "jdtogregorian", "jdtojewish", "jdtojulian", "jdtounix", "jewishtojd", "juliantojd", "unixtojd"] + b["Classes/Object"] = Set.new ["__autoload", "class_alias", "class_exists", "enum_exists", "get_called_class", "get_class", "get_class_methods", "get_class_vars", "get_declared_classes", "get_declared_interfaces", "get_declared_traits", "get_mangled_object_vars", "get_object_vars", "get_parent_class", "interface_exists", "is_a", "is_subclass_of", "method_exists", "property_exists", "trait_exists"] + b["CommonMark"] = Set.new ["CommonMark\\Parse", "CommonMark\\Render", "CommonMark\\Render\\HTML", "CommonMark\\Render\\Latex", "CommonMark\\Render\\Man", "CommonMark\\Render\\XML"] + b["COM"] = Set.new ["com_create_guid", "com_event_sink", "com_get_active_object", "com_load_typelib", "com_message_pump", "com_print_typeinfo", "variant_abs", "variant_add", "variant_and", "variant_cast", "variant_cat", "variant_cmp", "variant_date_from_timestamp", "variant_date_to_timestamp", "variant_div", "variant_eqv", "variant_fix", "variant_get_type", "variant_idiv", "variant_imp", "variant_int", "variant_mod", "variant_mul", "variant_neg", "variant_not", "variant_or", "variant_pow", "variant_round", "variant_set", "variant_set_type", "variant_sub", "variant_xor"] + b["Ctype"] = Set.new ["ctype_alnum", "ctype_alpha", "ctype_cntrl", "ctype_digit", "ctype_graph", "ctype_lower", "ctype_print", "ctype_punct", "ctype_space", "ctype_upper", "ctype_xdigit"] + b["CUBRID"] = Set.new ["cubrid_bind", "cubrid_close_prepare", "cubrid_close_request", "cubrid_col_get", "cubrid_col_size", "cubrid_column_names", "cubrid_column_types", "cubrid_commit", "cubrid_connect", "cubrid_connect_with_url", "cubrid_current_oid", "cubrid_disconnect", "cubrid_drop", "cubrid_error_code", "cubrid_error_code_facility", "cubrid_error_msg", "cubrid_execute", "cubrid_fetch", "cubrid_free_result", "cubrid_get", "cubrid_get_autocommit", "cubrid_get_charset", "cubrid_get_class_name", "cubrid_get_client_info", "cubrid_get_db_parameter", "cubrid_get_query_timeout", "cubrid_get_server_info", "cubrid_insert_id", "cubrid_is_instance", "cubrid_lob_close", "cubrid_lob_export", "cubrid_lob_get", "cubrid_lob_send", "cubrid_lob_size", "cubrid_lob2_bind", "cubrid_lob2_close", "cubrid_lob2_export", "cubrid_lob2_import", "cubrid_lob2_new", "cubrid_lob2_read", "cubrid_lob2_seek", "cubrid_lob2_seek64", "cubrid_lob2_size", "cubrid_lob2_size64", "cubrid_lob2_tell", "cubrid_lob2_tell64", "cubrid_lob2_write", "cubrid_lock_read", "cubrid_lock_write", "cubrid_move_cursor", "cubrid_next_result", "cubrid_num_cols", "cubrid_num_rows", "cubrid_pconnect", "cubrid_pconnect_with_url", "cubrid_prepare", "cubrid_put", "cubrid_rollback", "cubrid_schema", "cubrid_seq_drop", "cubrid_seq_insert", "cubrid_seq_put", "cubrid_set_add", "cubrid_set_autocommit", "cubrid_set_db_parameter", "cubrid_set_drop", "cubrid_set_query_timeout", "cubrid_version"] + b["cURL"] = Set.new ["curl_close", "curl_copy_handle", "curl_errno", "curl_error", "curl_escape", "curl_exec", "curl_getinfo", "curl_init", "curl_multi_add_handle", "curl_multi_close", "curl_multi_errno", "curl_multi_exec", "curl_multi_getcontent", "curl_multi_info_read", "curl_multi_init", "curl_multi_remove_handle", "curl_multi_select", "curl_multi_setopt", "curl_multi_strerror", "curl_pause", "curl_reset", "curl_setopt", "curl_setopt_array", "curl_share_close", "curl_share_errno", "curl_share_init", "curl_share_init_persistent", "curl_share_setopt", "curl_share_strerror", "curl_strerror", "curl_unescape", "curl_upkeep", "curl_version"] + b["Date/Time"] = Set.new ["checkdate", "date", "date_add", "date_create", "date_create_from_format", "date_create_immutable", "date_create_immutable_from_format", "date_date_set", "date_default_timezone_get", "date_default_timezone_set", "date_diff", "date_format", "date_get_last_errors", "date_interval_create_from_date_string", "date_interval_format", "date_isodate_set", "date_modify", "date_offset_get", "date_parse", "date_parse_from_format", "date_sub", "date_sun_info", "date_sunrise", "date_sunset", "date_time_set", "date_timestamp_get", "date_timestamp_set", "date_timezone_get", "date_timezone_set", "getdate", "gettimeofday", "gmdate", "gmmktime", "gmstrftime", "idate", "localtime", "microtime", "mktime", "strftime", "strptime", "strtotime", "time", "timezone_abbreviations_list", "timezone_identifiers_list", "timezone_location_get", "timezone_name_from_abbr", "timezone_name_get", "timezone_offset_get", "timezone_open", "timezone_transitions_get", "timezone_version_get"] + b["DBA"] = Set.new ["dba_close", "dba_delete", "dba_exists", "dba_fetch", "dba_firstkey", "dba_handlers", "dba_insert", "dba_key_split", "dba_list", "dba_nextkey", "dba_open", "dba_optimize", "dba_popen", "dba_replace", "dba_sync"] + b["dBase"] = Set.new ["dbase_add_record", "dbase_close", "dbase_create", "dbase_delete_record", "dbase_get_header_info", "dbase_get_record", "dbase_get_record_with_names", "dbase_numfields", "dbase_numrecords", "dbase_open", "dbase_pack", "dbase_replace_record"] + b["Direct IO"] = Set.new ["dio_close", "dio_fcntl", "dio_open", "dio_read", "dio_seek", "dio_stat", "dio_tcsetattr", "dio_truncate", "dio_write"] + b["Directory"] = Set.new ["chdir", "chroot", "closedir", "dir", "getcwd", "opendir", "readdir", "rewinddir", "scandir"] + b["DOM"] = Set.new ["dom_import_simplexml", "Dom\\import_simplexml"] + b["Eio"] = Set.new ["eio_busy", "eio_cancel", "eio_chmod", "eio_chown", "eio_close", "eio_custom", "eio_dup2", "eio_event_loop", "eio_fallocate", "eio_fchmod", "eio_fchown", "eio_fdatasync", "eio_fstat", "eio_fstatvfs", "eio_fsync", "eio_ftruncate", "eio_futime", "eio_get_event_stream", "eio_get_last_error", "eio_grp", "eio_grp_add", "eio_grp_cancel", "eio_grp_limit", "eio_init", "eio_link", "eio_lstat", "eio_mkdir", "eio_mknod", "eio_nop", "eio_npending", "eio_nready", "eio_nreqs", "eio_nthreads", "eio_open", "eio_poll", "eio_read", "eio_readahead", "eio_readdir", "eio_readlink", "eio_realpath", "eio_rename", "eio_rmdir", "eio_seek", "eio_sendfile", "eio_set_max_idle", "eio_set_max_parallel", "eio_set_max_poll_reqs", "eio_set_max_poll_time", "eio_set_min_parallel", "eio_stat", "eio_statvfs", "eio_symlink", "eio_sync", "eio_sync_file_range", "eio_syncfs", "eio_truncate", "eio_unlink", "eio_utime", "eio_write"] + b["Enchant"] = Set.new ["enchant_broker_describe", "enchant_broker_dict_exists", "enchant_broker_free", "enchant_broker_free_dict", "enchant_broker_get_dict_path", "enchant_broker_get_error", "enchant_broker_init", "enchant_broker_list_dicts", "enchant_broker_request_dict", "enchant_broker_request_pwl_dict", "enchant_broker_set_dict_path", "enchant_broker_set_ordering", "enchant_dict_add", "enchant_dict_add_to_personal", "enchant_dict_add_to_session", "enchant_dict_check", "enchant_dict_describe", "enchant_dict_get_error", "enchant_dict_is_added", "enchant_dict_is_in_session", "enchant_dict_quick_check", "enchant_dict_store_replacement", "enchant_dict_suggest"] + b["Error Handling"] = Set.new ["debug_backtrace", "debug_print_backtrace", "error_clear_last", "error_get_last", "error_log", "error_reporting", "get_error_handler", "get_exception_handler", "restore_error_handler", "restore_exception_handler", "set_error_handler", "set_exception_handler", "trigger_error", "user_error"] + b["Program execution"] = Set.new ["escapeshellarg", "escapeshellcmd", "exec", "passthru", "proc_close", "proc_get_status", "proc_nice", "proc_open", "proc_terminate", "shell_exec", "system"] + b["Exif"] = Set.new ["exif_imagetype", "exif_read_data", "exif_tagname", "exif_thumbnail", "read_exif_data"] + b["Expect"] = Set.new ["expect_expectl", "expect_popen"] + b["Fann"] = Set.new ["fann_cascadetrain_on_data", "fann_cascadetrain_on_file", "fann_clear_scaling_params", "fann_copy", "fann_create_from_file", "fann_create_shortcut", "fann_create_shortcut_array", "fann_create_sparse", "fann_create_sparse_array", "fann_create_standard", "fann_create_standard_array", "fann_create_train", "fann_create_train_from_callback", "fann_descale_input", "fann_descale_output", "fann_descale_train", "fann_destroy", "fann_destroy_train", "fann_duplicate_train_data", "fann_get_activation_function", "fann_get_activation_steepness", "fann_get_bias_array", "fann_get_bit_fail", "fann_get_bit_fail_limit", "fann_get_cascade_activation_functions", "fann_get_cascade_activation_functions_count", "fann_get_cascade_activation_steepnesses", "fann_get_cascade_activation_steepnesses_count", "fann_get_cascade_candidate_change_fraction", "fann_get_cascade_candidate_limit", "fann_get_cascade_candidate_stagnation_epochs", "fann_get_cascade_max_cand_epochs", "fann_get_cascade_max_out_epochs", "fann_get_cascade_min_cand_epochs", "fann_get_cascade_min_out_epochs", "fann_get_cascade_num_candidate_groups", "fann_get_cascade_num_candidates", "fann_get_cascade_output_change_fraction", "fann_get_cascade_output_stagnation_epochs", "fann_get_cascade_weight_multiplier", "fann_get_connection_array", "fann_get_connection_rate", "fann_get_errno", "fann_get_errstr", "fann_get_layer_array", "fann_get_learning_momentum", "fann_get_learning_rate", "fann_get_MSE", "fann_get_network_type", "fann_get_num_input", "fann_get_num_layers", "fann_get_num_output", "fann_get_quickprop_decay", "fann_get_quickprop_mu", "fann_get_rprop_decrease_factor", "fann_get_rprop_delta_max", "fann_get_rprop_delta_min", "fann_get_rprop_delta_zero", "fann_get_rprop_increase_factor", "fann_get_sarprop_step_error_shift", "fann_get_sarprop_step_error_threshold_factor", "fann_get_sarprop_temperature", "fann_get_sarprop_weight_decay_shift", "fann_get_total_connections", "fann_get_total_neurons", "fann_get_train_error_function", "fann_get_train_stop_function", "fann_get_training_algorithm", "fann_init_weights", "fann_length_train_data", "fann_merge_train_data", "fann_num_input_train_data", "fann_num_output_train_data", "fann_print_error", "fann_randomize_weights", "fann_read_train_from_file", "fann_reset_errno", "fann_reset_errstr", "fann_reset_MSE", "fann_run", "fann_save", "fann_save_train", "fann_scale_input", "fann_scale_input_train_data", "fann_scale_output", "fann_scale_output_train_data", "fann_scale_train", "fann_scale_train_data", "fann_set_activation_function", "fann_set_activation_function_hidden", "fann_set_activation_function_layer", "fann_set_activation_function_output", "fann_set_activation_steepness", "fann_set_activation_steepness_hidden", "fann_set_activation_steepness_layer", "fann_set_activation_steepness_output", "fann_set_bit_fail_limit", "fann_set_callback", "fann_set_cascade_activation_functions", "fann_set_cascade_activation_steepnesses", "fann_set_cascade_candidate_change_fraction", "fann_set_cascade_candidate_limit", "fann_set_cascade_candidate_stagnation_epochs", "fann_set_cascade_max_cand_epochs", "fann_set_cascade_max_out_epochs", "fann_set_cascade_min_cand_epochs", "fann_set_cascade_min_out_epochs", "fann_set_cascade_num_candidate_groups", "fann_set_cascade_output_change_fraction", "fann_set_cascade_output_stagnation_epochs", "fann_set_cascade_weight_multiplier", "fann_set_error_log", "fann_set_input_scaling_params", "fann_set_learning_momentum", "fann_set_learning_rate", "fann_set_output_scaling_params", "fann_set_quickprop_decay", "fann_set_quickprop_mu", "fann_set_rprop_decrease_factor", "fann_set_rprop_delta_max", "fann_set_rprop_delta_min", "fann_set_rprop_delta_zero", "fann_set_rprop_increase_factor", "fann_set_sarprop_step_error_shift", "fann_set_sarprop_step_error_threshold_factor", "fann_set_sarprop_temperature", "fann_set_sarprop_weight_decay_shift", "fann_set_scaling_params", "fann_set_train_error_function", "fann_set_train_stop_function", "fann_set_training_algorithm", "fann_set_weight", "fann_set_weight_array", "fann_shuffle_train_data", "fann_subset_train_data", "fann_test", "fann_test_data", "fann_train", "fann_train_epoch", "fann_train_on_data", "fann_train_on_file"] + b["FDF"] = Set.new ["fdf_add_doc_javascript", "fdf_add_template", "fdf_close", "fdf_create", "fdf_enum_values", "fdf_errno", "fdf_error", "fdf_get_ap", "fdf_get_attachment", "fdf_get_encoding", "fdf_get_file", "fdf_get_flags", "fdf_get_opt", "fdf_get_status", "fdf_get_value", "fdf_get_version", "fdf_header", "fdf_next_field_name", "fdf_open", "fdf_open_string", "fdf_remove_item", "fdf_save", "fdf_save_string", "fdf_set_ap", "fdf_set_encoding", "fdf_set_file", "fdf_set_flags", "fdf_set_javascript_action", "fdf_set_on_import_javascript", "fdf_set_opt", "fdf_set_status", "fdf_set_submit_form_action", "fdf_set_target_frame", "fdf_set_value", "fdf_set_version"] + b["Fileinfo"] = Set.new ["finfo_buffer", "finfo_close", "finfo_file", "finfo_open", "finfo_set_flags", "mime_content_type"] + b["Filesystem"] = Set.new ["basename", "chgrp", "chmod", "chown", "clearstatcache", "copy", "delete", "dirname", "disk_free_space", "disk_total_space", "diskfreespace", "fclose", "fdatasync", "feof", "fflush", "fgetc", "fgetcsv", "fgets", "fgetss", "file", "file_exists", "file_get_contents", "file_put_contents", "fileatime", "filectime", "filegroup", "fileinode", "filemtime", "fileowner", "fileperms", "filesize", "filetype", "flock", "fnmatch", "fopen", "fpassthru", "fputcsv", "fputs", "fread", "fscanf", "fseek", "fstat", "fsync", "ftell", "ftruncate", "fwrite", "glob", "is_dir", "is_executable", "is_file", "is_link", "is_readable", "is_uploaded_file", "is_writable", "is_writeable", "lchgrp", "lchown", "link", "linkinfo", "lstat", "mkdir", "move_uploaded_file", "parse_ini_file", "parse_ini_string", "pathinfo", "pclose", "popen", "readfile", "readlink", "realpath", "realpath_cache_get", "realpath_cache_size", "rename", "rewind", "rmdir", "set_file_buffer", "stat", "symlink", "tempnam", "tmpfile", "touch", "umask", "unlink"] + b["Filter"] = Set.new ["filter_has_var", "filter_id", "filter_input", "filter_input_array", "filter_list", "filter_var", "filter_var_array"] + b["FPM"] = Set.new ["fastcgi_finish_request", "fpm_get_status"] + b["FTP"] = Set.new ["ftp_alloc", "ftp_append", "ftp_cdup", "ftp_chdir", "ftp_chmod", "ftp_close", "ftp_connect", "ftp_delete", "ftp_exec", "ftp_fget", "ftp_fput", "ftp_get", "ftp_get_option", "ftp_login", "ftp_mdtm", "ftp_mkdir", "ftp_mlsd", "ftp_nb_continue", "ftp_nb_fget", "ftp_nb_fput", "ftp_nb_get", "ftp_nb_put", "ftp_nlist", "ftp_pasv", "ftp_put", "ftp_pwd", "ftp_quit", "ftp_raw", "ftp_rawlist", "ftp_rename", "ftp_rmdir", "ftp_set_option", "ftp_site", "ftp_size", "ftp_ssl_connect", "ftp_systype"] + b["Function handling"] = Set.new ["call_user_func", "call_user_func_array", "create_function", "forward_static_call", "forward_static_call_array", "func_get_arg", "func_get_args", "func_num_args", "function_exists", "get_defined_functions", "register_shutdown_function", "register_tick_function", "unregister_tick_function"] + b["GeoIP"] = Set.new ["geoip_asnum_by_name", "geoip_continent_code_by_name", "geoip_country_code_by_name", "geoip_country_code3_by_name", "geoip_country_name_by_name", "geoip_database_info", "geoip_db_avail", "geoip_db_filename", "geoip_db_get_all_info", "geoip_domain_by_name", "geoip_id_by_name", "geoip_isp_by_name", "geoip_netspeedcell_by_name", "geoip_org_by_name", "geoip_record_by_name", "geoip_region_by_name", "geoip_region_name_by_code", "geoip_setup_custom_directory", "geoip_time_zone_by_country_and_region"] + b["Gettext"] = Set.new ["_", "bind_textdomain_codeset", "bindtextdomain", "dcgettext", "dcngettext", "dgettext", "dngettext", "gettext", "ngettext", "textdomain"] + b["GMP"] = Set.new ["gmp_abs", "gmp_add", "gmp_and", "gmp_binomial", "gmp_clrbit", "gmp_cmp", "gmp_com", "gmp_div", "gmp_div_q", "gmp_div_qr", "gmp_div_r", "gmp_divexact", "gmp_export", "gmp_fact", "gmp_gcd", "gmp_gcdext", "gmp_hamdist", "gmp_import", "gmp_init", "gmp_intval", "gmp_invert", "gmp_jacobi", "gmp_kronecker", "gmp_lcm", "gmp_legendre", "gmp_mod", "gmp_mul", "gmp_neg", "gmp_nextprime", "gmp_or", "gmp_perfect_power", "gmp_perfect_square", "gmp_popcount", "gmp_pow", "gmp_powm", "gmp_prob_prime", "gmp_random", "gmp_random_bits", "gmp_random_range", "gmp_random_seed", "gmp_root", "gmp_rootrem", "gmp_scan0", "gmp_scan1", "gmp_setbit", "gmp_sign", "gmp_sqrt", "gmp_sqrtrem", "gmp_strval", "gmp_sub", "gmp_testbit", "gmp_xor"] + b["GnuPG"] = Set.new ["gnupg_adddecryptkey", "gnupg_addencryptkey", "gnupg_addsignkey", "gnupg_cleardecryptkeys", "gnupg_clearencryptkeys", "gnupg_clearsignkeys", "gnupg_decrypt", "gnupg_decryptverify", "gnupg_deletekey", "gnupg_encrypt", "gnupg_encryptsign", "gnupg_export", "gnupg_getengineinfo", "gnupg_geterror", "gnupg_geterrorinfo", "gnupg_getprotocol", "gnupg_gettrustlist", "gnupg_import", "gnupg_init", "gnupg_keyinfo", "gnupg_listsignatures", "gnupg_setarmor", "gnupg_seterrormode", "gnupg_setsignmode", "gnupg_sign", "gnupg_verify"] + b["Hash"] = Set.new ["hash", "hash_algos", "hash_copy", "hash_equals", "hash_file", "hash_final", "hash_hkdf", "hash_hmac", "hash_hmac_algos", "hash_hmac_file", "hash_init", "hash_pbkdf2", "hash_update", "hash_update_file", "hash_update_stream"] + b["Firebird/InterBase"] = Set.new ["fbird_add_user", "fbird_affected_rows", "fbird_backup", "fbird_blob_add", "fbird_blob_cancel", "fbird_blob_close", "fbird_blob_create", "fbird_blob_echo", "fbird_blob_get", "fbird_blob_import", "fbird_blob_info", "fbird_blob_open", "fbird_close", "fbird_commit", "fbird_commit_ret", "fbird_connect", "fbird_db_info", "fbird_delete_user", "fbird_drop_db", "fbird_errcode", "fbird_errmsg", "fbird_execute", "fbird_fetch_assoc", "fbird_fetch_object", "fbird_fetch_row", "fbird_field_info", "fbird_free_event_handler", "fbird_free_query", "fbird_free_result", "fbird_gen_id", "fbird_maintain_db", "fbird_modify_user", "fbird_name_result", "fbird_num_fields", "fbird_num_params", "fbird_param_info", "fbird_pconnect", "fbird_prepare", "fbird_query", "fbird_restore", "fbird_rollback", "fbird_rollback_ret", "fbird_server_info", "fbird_service_attach", "fbird_service_detach", "fbird_set_event_handler", "fbird_trans", "fbird_wait_event", "ibase_add_user", "ibase_affected_rows", "ibase_backup", "ibase_blob_add", "ibase_blob_cancel", "ibase_blob_close", "ibase_blob_create", "ibase_blob_echo", "ibase_blob_get", "ibase_blob_import", "ibase_blob_info", "ibase_blob_open", "ibase_close", "ibase_commit", "ibase_commit_ret", "ibase_connect", "ibase_db_info", "ibase_delete_user", "ibase_drop_db", "ibase_errcode", "ibase_errmsg", "ibase_execute", "ibase_fetch_assoc", "ibase_fetch_object", "ibase_fetch_row", "ibase_field_info", "ibase_free_event_handler", "ibase_free_query", "ibase_free_result", "ibase_gen_id", "ibase_maintain_db", "ibase_modify_user", "ibase_name_result", "ibase_num_fields", "ibase_num_params", "ibase_param_info", "ibase_pconnect", "ibase_prepare", "ibase_query", "ibase_restore", "ibase_rollback", "ibase_rollback_ret", "ibase_server_info", "ibase_service_attach", "ibase_service_detach", "ibase_set_event_handler", "ibase_trans", "ibase_wait_event"] + b["IBM DB2"] = Set.new ["db2_autocommit", "db2_bind_param", "db2_client_info", "db2_close", "db2_column_privileges", "db2_columns", "db2_commit", "db2_conn_error", "db2_conn_errormsg", "db2_connect", "db2_cursor_type", "db2_escape_string", "db2_exec", "db2_execute", "db2_fetch_array", "db2_fetch_assoc", "db2_fetch_both", "db2_fetch_object", "db2_fetch_row", "db2_field_display_size", "db2_field_name", "db2_field_num", "db2_field_precision", "db2_field_scale", "db2_field_type", "db2_field_width", "db2_foreign_keys", "db2_free_result", "db2_free_stmt", "db2_get_option", "db2_last_insert_id", "db2_lob_read", "db2_next_result", "db2_num_fields", "db2_num_rows", "db2_pclose", "db2_pconnect", "db2_prepare", "db2_primary_keys", "db2_procedure_columns", "db2_procedures", "db2_result", "db2_rollback", "db2_server_info", "db2_set_option", "db2_special_columns", "db2_statistics", "db2_stmt_error", "db2_stmt_errormsg", "db2_table_privileges", "db2_tables"] + b["iconv"] = Set.new ["iconv", "iconv_get_encoding", "iconv_mime_decode", "iconv_mime_decode_headers", "iconv_mime_encode", "iconv_set_encoding", "iconv_strlen", "iconv_strpos", "iconv_strrpos", "iconv_substr", "ob_iconv_handler"] + b["Igbinary"] = Set.new ["igbinary_serialize", "igbinary_unserialize"] + b["GD and Image"] = Set.new ["gd_info", "getimagesize", "getimagesizefromstring", "image_type_to_extension", "image_type_to_mime_type", "image2wbmp", "imageaffine", "imageaffinematrixconcat", "imageaffinematrixget", "imagealphablending", "imageantialias", "imagearc", "imageavif", "imagebmp", "imagechar", "imagecharup", "imagecolorallocate", "imagecolorallocatealpha", "imagecolorat", "imagecolorclosest", "imagecolorclosestalpha", "imagecolorclosesthwb", "imagecolordeallocate", "imagecolorexact", "imagecolorexactalpha", "imagecolormatch", "imagecolorresolve", "imagecolorresolvealpha", "imagecolorset", "imagecolorsforindex", "imagecolorstotal", "imagecolortransparent", "imageconvolution", "imagecopy", "imagecopymerge", "imagecopymergegray", "imagecopyresampled", "imagecopyresized", "imagecreate", "imagecreatefromavif", "imagecreatefrombmp", "imagecreatefromgd", "imagecreatefromgd2", "imagecreatefromgd2part", "imagecreatefromgif", "imagecreatefromjpeg", "imagecreatefrompng", "imagecreatefromstring", "imagecreatefromtga", "imagecreatefromwbmp", "imagecreatefromwebp", "imagecreatefromxbm", "imagecreatefromxpm", "imagecreatetruecolor", "imagecrop", "imagecropauto", "imagedashedline", "imagedestroy", "imageellipse", "imagefill", "imagefilledarc", "imagefilledellipse", "imagefilledpolygon", "imagefilledrectangle", "imagefilltoborder", "imagefilter", "imageflip", "imagefontheight", "imagefontwidth", "imageftbbox", "imagefttext", "imagegammacorrect", "imagegd", "imagegd2", "imagegetclip", "imagegetinterpolation", "imagegif", "imagegrabscreen", "imagegrabwindow", "imageinterlace", "imageistruecolor", "imagejpeg", "imagelayereffect", "imageline", "imageloadfont", "imageopenpolygon", "imagepalettecopy", "imagepalettetotruecolor", "imagepng", "imagepolygon", "imagerectangle", "imageresolution", "imagerotate", "imagesavealpha", "imagescale", "imagesetbrush", "imagesetclip", "imagesetinterpolation", "imagesetpixel", "imagesetstyle", "imagesetthickness", "imagesettile", "imagestring", "imagestringup", "imagesx", "imagesy", "imagetruecolortopalette", "imagettfbbox", "imagettftext", "imagetypes", "imagewbmp", "imagewebp", "imagexbm", "iptcembed", "iptcparse", "jpeg2wbmp", "png2wbmp"] + b["IMAP"] = Set.new ["imap_8bit", "imap_alerts", "imap_append", "imap_base64", "imap_binary", "imap_body", "imap_bodystruct", "imap_check", "imap_clearflag_full", "imap_close", "imap_create", "imap_createmailbox", "imap_delete", "imap_deletemailbox", "imap_errors", "imap_expunge", "imap_fetch_overview", "imap_fetchbody", "imap_fetchheader", "imap_fetchmime", "imap_fetchstructure", "imap_fetchtext", "imap_gc", "imap_get_quota", "imap_get_quotaroot", "imap_getacl", "imap_getmailboxes", "imap_getsubscribed", "imap_header", "imap_headerinfo", "imap_headers", "imap_is_open", "imap_last_error", "imap_list", "imap_listmailbox", "imap_listscan", "imap_listsubscribed", "imap_lsub", "imap_mail", "imap_mail_compose", "imap_mail_copy", "imap_mail_move", "imap_mailboxmsginfo", "imap_mime_header_decode", "imap_msgno", "imap_mutf7_to_utf8", "imap_num_msg", "imap_num_recent", "imap_open", "imap_ping", "imap_qprint", "imap_rename", "imap_renamemailbox", "imap_reopen", "imap_rfc822_parse_adrlist", "imap_rfc822_parse_headers", "imap_rfc822_write_address", "imap_savebody", "imap_scan", "imap_scanmailbox", "imap_search", "imap_set_quota", "imap_setacl", "imap_setflag_full", "imap_sort", "imap_status", "imap_subscribe", "imap_thread", "imap_timeout", "imap_uid", "imap_undelete", "imap_unsubscribe", "imap_utf7_decode", "imap_utf7_encode", "imap_utf8", "imap_utf8_to_mutf7"] + b["PHP Options/Info"] = Set.new ["assert", "assert_options", "cli_get_process_title", "cli_set_process_title", "dl", "extension_loaded", "gc_collect_cycles", "gc_disable", "gc_enable", "gc_enabled", "gc_mem_caches", "gc_status", "get_cfg_var", "get_current_user", "get_defined_constants", "get_extension_funcs", "get_include_path", "get_included_files", "get_loaded_extensions", "get_magic_quotes_gpc", "get_magic_quotes_runtime", "get_required_files", "get_resources", "getenv", "getlastmod", "getmygid", "getmyinode", "getmypid", "getmyuid", "getopt", "getrusage", "ini_alter", "ini_get", "ini_get_all", "ini_parse_quantity", "ini_restore", "ini_set", "memory_get_peak_usage", "memory_get_usage", "memory_reset_peak_usage", "php_ini_loaded_file", "php_ini_scanned_files", "php_sapi_name", "php_uname", "phpcredits", "phpinfo", "phpversion", "putenv", "restore_include_path", "set_include_path", "set_time_limit", "sys_get_temp_dir", "version_compare", "zend_thread_id", "zend_version"] + b["Inotify"] = Set.new ["inotify_add_watch", "inotify_init", "inotify_queue_len", "inotify_read", "inotify_rm_watch"] + b["Grapheme"] = Set.new ["grapheme_extract", "grapheme_str_split", "grapheme_stripos", "grapheme_stristr", "grapheme_strlen", "grapheme_strpos", "grapheme_strripos", "grapheme_strrpos", "grapheme_strstr", "grapheme_substr"] + b["intl"] = Set.new ["intl_error_name", "intl_get_error_code", "intl_get_error_message", "intl_is_failure"] + b["IDN"] = Set.new ["idn_to_ascii", "idn_to_utf8"] + b["JSON"] = Set.new ["json_decode", "json_encode", "json_last_error", "json_last_error_msg", "json_validate"] + b["LDAP"] = Set.new ["ldap_8859_to_t61", "ldap_add", "ldap_add_ext", "ldap_bind", "ldap_bind_ext", "ldap_close", "ldap_compare", "ldap_connect", "ldap_connect_wallet", "ldap_control_paged_result", "ldap_control_paged_result_response", "ldap_count_entries", "ldap_count_references", "ldap_delete", "ldap_delete_ext", "ldap_dn2ufn", "ldap_err2str", "ldap_errno", "ldap_error", "ldap_escape", "ldap_exop", "ldap_exop_passwd", "ldap_exop_refresh", "ldap_exop_sync", "ldap_exop_whoami", "ldap_explode_dn", "ldap_first_attribute", "ldap_first_entry", "ldap_first_reference", "ldap_free_result", "ldap_get_attributes", "ldap_get_dn", "ldap_get_entries", "ldap_get_option", "ldap_get_values", "ldap_get_values_len", "ldap_list", "ldap_mod_add", "ldap_mod_add_ext", "ldap_mod_del", "ldap_mod_del_ext", "ldap_mod_replace", "ldap_mod_replace_ext", "ldap_modify", "ldap_modify_batch", "ldap_next_attribute", "ldap_next_entry", "ldap_next_reference", "ldap_parse_exop", "ldap_parse_reference", "ldap_parse_result", "ldap_read", "ldap_rename", "ldap_rename_ext", "ldap_sasl_bind", "ldap_search", "ldap_set_option", "ldap_set_rebind_proc", "ldap_sort", "ldap_start_tls", "ldap_t61_to_8859", "ldap_unbind"] + b["libxml"] = Set.new ["libxml_clear_errors", "libxml_disable_entity_loader", "libxml_get_errors", "libxml_get_external_entity_loader", "libxml_get_last_error", "libxml_set_external_entity_loader", "libxml_set_streams_context", "libxml_use_internal_errors"] + b["LZF"] = Set.new ["lzf_compress", "lzf_decompress", "lzf_optimized_for"] + b["Mail"] = Set.new ["ezmlm_hash", "mail"] + b["Mailparse"] = Set.new ["mailparse_determine_best_xfer_encoding", "mailparse_msg_create", "mailparse_msg_extract_part", "mailparse_msg_extract_part_file", "mailparse_msg_extract_whole_part_file", "mailparse_msg_free", "mailparse_msg_get_part", "mailparse_msg_get_part_data", "mailparse_msg_get_structure", "mailparse_msg_parse", "mailparse_msg_parse_file", "mailparse_rfc822_parse_addresses", "mailparse_stream_encode", "mailparse_uudecode_all"] + b["Math"] = Set.new ["abs", "acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "base_convert", "bindec", "ceil", "cos", "cosh", "decbin", "dechex", "decoct", "deg2rad", "exp", "expm1", "fdiv", "floor", "fmod", "fpow", "hexdec", "hypot", "intdiv", "is_finite", "is_infinite", "is_nan", "log", "log10", "log1p", "max", "min", "octdec", "pi", "pow", "rad2deg", "round", "sin", "sinh", "sqrt", "tan", "tanh"] + b["Multibyte String"] = Set.new ["mb_check_encoding", "mb_chr", "mb_convert_case", "mb_convert_encoding", "mb_convert_kana", "mb_convert_variables", "mb_decode_mimeheader", "mb_decode_numericentity", "mb_detect_encoding", "mb_detect_order", "mb_encode_mimeheader", "mb_encode_numericentity", "mb_encoding_aliases", "mb_ereg", "mb_ereg_match", "mb_ereg_replace", "mb_ereg_replace_callback", "mb_ereg_search", "mb_ereg_search_getpos", "mb_ereg_search_getregs", "mb_ereg_search_init", "mb_ereg_search_pos", "mb_ereg_search_regs", "mb_ereg_search_setpos", "mb_eregi", "mb_eregi_replace", "mb_get_info", "mb_http_input", "mb_http_output", "mb_internal_encoding", "mb_language", "mb_lcfirst", "mb_list_encodings", "mb_ltrim", "mb_ord", "mb_output_handler", "mb_parse_str", "mb_preferred_mime_name", "mb_regex_encoding", "mb_regex_set_options", "mb_rtrim", "mb_scrub", "mb_send_mail", "mb_split", "mb_str_pad", "mb_str_split", "mb_strcut", "mb_strimwidth", "mb_stripos", "mb_stristr", "mb_strlen", "mb_strpos", "mb_strrchr", "mb_strrichr", "mb_strripos", "mb_strrpos", "mb_strstr", "mb_strtolower", "mb_strtoupper", "mb_strwidth", "mb_substitute_character", "mb_substr", "mb_substr_count", "mb_trim", "mb_ucfirst"] + b["Mcrypt"] = Set.new ["mcrypt_create_iv", "mcrypt_decrypt", "mcrypt_enc_get_algorithms_name", "mcrypt_enc_get_block_size", "mcrypt_enc_get_iv_size", "mcrypt_enc_get_key_size", "mcrypt_enc_get_modes_name", "mcrypt_enc_get_supported_key_sizes", "mcrypt_enc_is_block_algorithm", "mcrypt_enc_is_block_algorithm_mode", "mcrypt_enc_is_block_mode", "mcrypt_enc_self_test", "mcrypt_encrypt", "mcrypt_generic", "mcrypt_generic_deinit", "mcrypt_generic_init", "mcrypt_get_block_size", "mcrypt_get_cipher_name", "mcrypt_get_iv_size", "mcrypt_get_key_size", "mcrypt_list_algorithms", "mcrypt_list_modes", "mcrypt_module_close", "mcrypt_module_get_algo_block_size", "mcrypt_module_get_algo_key_size", "mcrypt_module_get_supported_key_sizes", "mcrypt_module_is_block_algorithm", "mcrypt_module_is_block_algorithm_mode", "mcrypt_module_is_block_mode", "mcrypt_module_open", "mcrypt_module_self_test", "mdecrypt_generic"] + b["Memcache"] = Set.new ["memcache_debug"] + b["Mhash"] = Set.new ["mhash", "mhash_count", "mhash_get_block_size", "mhash_get_hash_name", "mhash_keygen_s2k"] + b["Misc."] = Set.new ["connection_aborted", "connection_status", "constant", "define", "defined", "die", "eval", "exit", "get_browser", "__halt_compiler", "highlight_file", "highlight_string", "hrtime", "ignore_user_abort", "pack", "php_strip_whitespace", "sapi_windows_cp_conv", "sapi_windows_cp_get", "sapi_windows_cp_is_utf8", "sapi_windows_cp_set", "sapi_windows_generate_ctrl_event", "sapi_windows_set_ctrl_handler", "sapi_windows_vt100_support", "show_source", "sleep", "sys_getloadavg", "time_nanosleep", "time_sleep_until", "uniqid", "unpack", "usleep"] + b["mqseries"] = Set.new ["mqseries_back", "mqseries_begin", "mqseries_close", "mqseries_cmit", "mqseries_conn", "mqseries_connx", "mqseries_disc", "mqseries_get", "mqseries_inq", "mqseries_open", "mqseries_put", "mqseries_put1", "mqseries_set", "mqseries_strerror"] + b["Mysql_xdevapi"] = Set.new ["expression", "getSession"] + b["MySQL"] = Set.new ["mysql_affected_rows", "mysql_client_encoding", "mysql_close", "mysql_connect", "mysql_create_db", "mysql_data_seek", "mysql_db_name", "mysql_db_query", "mysql_drop_db", "mysql_errno", "mysql_error", "mysql_escape_string", "mysql_fetch_array", "mysql_fetch_assoc", "mysql_fetch_field", "mysql_fetch_lengths", "mysql_fetch_object", "mysql_fetch_row", "mysql_field_flags", "mysql_field_len", "mysql_field_name", "mysql_field_seek", "mysql_field_table", "mysql_field_type", "mysql_free_result", "mysql_get_client_info", "mysql_get_host_info", "mysql_get_proto_info", "mysql_get_server_info", "mysql_info", "mysql_insert_id", "mysql_list_dbs", "mysql_list_fields", "mysql_list_processes", "mysql_list_tables", "mysql_num_fields", "mysql_num_rows", "mysql_pconnect", "mysql_ping", "mysql_query", "mysql_real_escape_string", "mysql_result", "mysql_select_db", "mysql_set_charset", "mysql_stat", "mysql_tablename", "mysql_thread_id", "mysql_unbuffered_query"] + b["Aliases and deprecated Mysqli"] = Set.new ["mysqli_connect", "mysqli_execute", "mysqli_get_client_stats", "mysqli_get_links_stats", "mysqli_report"] + b["Network"] = Set.new ["checkdnsrr", "closelog", "dns_check_record", "dns_get_mx", "dns_get_record", "fsockopen", "gethostbyaddr", "gethostbyname", "gethostbynamel", "gethostname", "getmxrr", "getprotobyname", "getprotobynumber", "getservbyname", "getservbyport", "header", "header_register_callback", "header_remove", "headers_list", "headers_sent", "http_clear_last_response_headers", "http_get_last_response_headers", "http_response_code", "inet_ntop", "inet_pton", "ip2long", "long2ip", "net_get_interfaces", "openlog", "pfsockopen", "request_parse_body", "setcookie", "setrawcookie", "socket_get_status", "socket_set_blocking", "socket_set_timeout", "syslog"] + b["OAuth"] = Set.new ["oauth_get_sbs", "oauth_urlencode"] + b["OCI8"] = Set.new ["oci_bind_array_by_name", "oci_bind_by_name", "oci_cancel", "oci_client_version", "oci_close", "oci_commit", "oci_connect", "oci_define_by_name", "oci_error", "oci_execute", "oci_fetch", "oci_fetch_all", "oci_fetch_array", "oci_fetch_assoc", "oci_fetch_object", "oci_fetch_row", "oci_field_is_null", "oci_field_name", "oci_field_precision", "oci_field_scale", "oci_field_size", "oci_field_type", "oci_field_type_raw", "oci_free_descriptor", "oci_free_statement", "oci_get_implicit_resultset", "oci_lob_copy", "oci_lob_is_equal", "oci_new_collection", "oci_new_connect", "oci_new_cursor", "oci_new_descriptor", "oci_num_fields", "oci_num_rows", "oci_parse", "oci_password_change", "oci_pconnect", "oci_register_taf_callback", "oci_result", "oci_rollback", "oci_server_version", "oci_set_action", "oci_set_call_timeout", "oci_set_client_identifier", "oci_set_client_info", "oci_set_db_operation", "oci_set_edition", "oci_set_module_name", "oci_set_prefetch", "oci_set_prefetch_lob", "oci_statement_type", "oci_unregister_taf_callback"] + b["OPcache"] = Set.new ["opcache_compile_file", "opcache_get_configuration", "opcache_get_status", "opcache_invalidate", "opcache_is_script_cached", "opcache_reset"] + b["OpenAL"] = Set.new ["openal_buffer_create", "openal_buffer_data", "openal_buffer_destroy", "openal_buffer_get", "openal_buffer_loadwav", "openal_context_create", "openal_context_current", "openal_context_destroy", "openal_context_process", "openal_context_suspend", "openal_device_close", "openal_device_open", "openal_listener_get", "openal_listener_set", "openal_source_create", "openal_source_destroy", "openal_source_get", "openal_source_pause", "openal_source_play", "openal_source_rewind", "openal_source_set", "openal_source_stop", "openal_stream"] + b["OpenSSL"] = Set.new ["openssl_cipher_iv_length", "openssl_cipher_key_length", "openssl_cms_decrypt", "openssl_cms_encrypt", "openssl_cms_read", "openssl_cms_sign", "openssl_cms_verify", "openssl_csr_export", "openssl_csr_export_to_file", "openssl_csr_get_public_key", "openssl_csr_get_subject", "openssl_csr_new", "openssl_csr_sign", "openssl_decrypt", "openssl_dh_compute_key", "openssl_digest", "openssl_encrypt", "openssl_error_string", "openssl_free_key", "openssl_get_cert_locations", "openssl_get_cipher_methods", "openssl_get_curve_names", "openssl_get_md_methods", "openssl_get_privatekey", "openssl_get_publickey", "openssl_open", "openssl_pbkdf2", "openssl_pkcs12_export", "openssl_pkcs12_export_to_file", "openssl_pkcs12_read", "openssl_pkcs7_decrypt", "openssl_pkcs7_encrypt", "openssl_pkcs7_read", "openssl_pkcs7_sign", "openssl_pkcs7_verify", "openssl_pkey_derive", "openssl_pkey_export", "openssl_pkey_export_to_file", "openssl_pkey_free", "openssl_pkey_get_details", "openssl_pkey_get_private", "openssl_pkey_get_public", "openssl_pkey_new", "openssl_private_decrypt", "openssl_private_encrypt", "openssl_public_decrypt", "openssl_public_encrypt", "openssl_random_pseudo_bytes", "openssl_seal", "openssl_sign", "openssl_spki_export", "openssl_spki_export_challenge", "openssl_spki_new", "openssl_spki_verify", "openssl_verify", "openssl_x509_check_private_key", "openssl_x509_checkpurpose", "openssl_x509_export", "openssl_x509_export_to_file", "openssl_x509_fingerprint", "openssl_x509_free", "openssl_x509_parse", "openssl_x509_read", "openssl_x509_verify"] + b["Output Control"] = Set.new ["flush", "ob_clean", "ob_end_clean", "ob_end_flush", "ob_flush", "ob_get_clean", "ob_get_contents", "ob_get_flush", "ob_get_length", "ob_get_level", "ob_get_status", "ob_implicit_flush", "ob_list_handlers", "ob_start", "output_add_rewrite_var", "output_reset_rewrite_vars"] + b["Password Hashing"] = Set.new ["password_algos", "password_get_info", "password_hash", "password_needs_rehash", "password_verify"] + b["PCNTL"] = Set.new ["pcntl_alarm", "pcntl_async_signals", "pcntl_errno", "pcntl_exec", "pcntl_fork", "pcntl_get_last_error", "pcntl_getcpuaffinity", "pcntl_getpriority", "pcntl_rfork", "pcntl_setcpuaffinity", "pcntl_setpriority", "pcntl_signal", "pcntl_signal_dispatch", "pcntl_signal_get_handler", "pcntl_sigprocmask", "pcntl_sigtimedwait", "pcntl_sigwaitinfo", "pcntl_strerror", "pcntl_unshare", "pcntl_wait", "pcntl_waitid", "pcntl_waitpid", "pcntl_wexitstatus", "pcntl_wifexited", "pcntl_wifsignaled", "pcntl_wifstopped", "pcntl_wstopsig", "pcntl_wtermsig"] + b["PCRE"] = Set.new ["preg_filter", "preg_grep", "preg_last_error", "preg_last_error_msg", "preg_match", "preg_match_all", "preg_quote", "preg_replace", "preg_replace_callback", "preg_replace_callback_array", "preg_split"] + b["PostgreSQL"] = Set.new ["pg_affected_rows", "pg_cancel_query", "pg_client_encoding", "pg_close", "pg_connect", "pg_connect_poll", "pg_connection_busy", "pg_connection_reset", "pg_connection_status", "pg_consume_input", "pg_convert", "pg_copy_from", "pg_copy_to", "pg_dbname", "pg_delete", "pg_end_copy", "pg_escape_bytea", "pg_escape_identifier", "pg_escape_literal", "pg_escape_string", "pg_execute", "pg_fetch_all", "pg_fetch_all_columns", "pg_fetch_array", "pg_fetch_assoc", "pg_fetch_object", "pg_fetch_result", "pg_fetch_row", "pg_field_is_null", "pg_field_name", "pg_field_num", "pg_field_prtlen", "pg_field_size", "pg_field_table", "pg_field_type", "pg_field_type_oid", "pg_flush", "pg_free_result", "pg_get_notify", "pg_get_pid", "pg_get_result", "pg_host", "pg_insert", "pg_last_error", "pg_last_notice", "pg_last_oid", "pg_lo_close", "pg_lo_create", "pg_lo_export", "pg_lo_import", "pg_lo_open", "pg_lo_read", "pg_lo_read_all", "pg_lo_seek", "pg_lo_tell", "pg_lo_truncate", "pg_lo_unlink", "pg_lo_write", "pg_meta_data", "pg_num_fields", "pg_num_rows", "pg_options", "pg_parameter_status", "pg_pconnect", "pg_ping", "pg_port", "pg_prepare", "pg_put_line", "pg_query", "pg_query_params", "pg_result_error", "pg_result_error_field", "pg_result_memory_size", "pg_result_seek", "pg_result_status", "pg_select", "pg_send_execute", "pg_send_prepare", "pg_send_query", "pg_send_query_params", "pg_set_chunked_rows_size", "pg_set_client_encoding", "pg_set_error_context_visibility", "pg_set_error_verbosity", "pg_socket", "pg_trace", "pg_transaction_status", "pg_tty", "pg_unescape_bytea", "pg_untrace", "pg_update", "pg_version"] + b["phpdbg"] = Set.new ["phpdbg_break_file", "phpdbg_break_function", "phpdbg_break_method", "phpdbg_break_next", "phpdbg_clear", "phpdbg_color", "phpdbg_end_oplog", "phpdbg_exec", "phpdbg_get_executable", "phpdbg_prompt", "phpdbg_start_oplog"] + b["POSIX"] = Set.new ["posix_access", "posix_ctermid", "posix_eaccess", "posix_errno", "posix_fpathconf", "posix_get_last_error", "posix_getcwd", "posix_getegid", "posix_geteuid", "posix_getgid", "posix_getgrgid", "posix_getgrnam", "posix_getgroups", "posix_getlogin", "posix_getpgid", "posix_getpgrp", "posix_getpid", "posix_getppid", "posix_getpwnam", "posix_getpwuid", "posix_getrlimit", "posix_getsid", "posix_getuid", "posix_initgroups", "posix_isatty", "posix_kill", "posix_mkfifo", "posix_mknod", "posix_pathconf", "posix_setegid", "posix_seteuid", "posix_setgid", "posix_setpgid", "posix_setrlimit", "posix_setsid", "posix_setuid", "posix_strerror", "posix_sysconf", "posix_times", "posix_ttyname", "posix_uname"] + b["PS"] = Set.new ["ps_add_bookmark", "ps_add_launchlink", "ps_add_locallink", "ps_add_note", "ps_add_pdflink", "ps_add_weblink", "ps_arc", "ps_arcn", "ps_begin_page", "ps_begin_pattern", "ps_begin_template", "ps_circle", "ps_clip", "ps_close", "ps_close_image", "ps_closepath", "ps_closepath_stroke", "ps_continue_text", "ps_curveto", "ps_delete", "ps_end_page", "ps_end_pattern", "ps_end_template", "ps_fill", "ps_fill_stroke", "ps_findfont", "ps_get_buffer", "ps_get_parameter", "ps_get_value", "ps_hyphenate", "ps_include_file", "ps_lineto", "ps_makespotcolor", "ps_moveto", "ps_new", "ps_open_file", "ps_open_image", "ps_open_image_file", "ps_open_memory_image", "ps_place_image", "ps_rect", "ps_restore", "ps_rotate", "ps_save", "ps_scale", "ps_set_border_color", "ps_set_border_dash", "ps_set_border_style", "ps_set_info", "ps_set_parameter", "ps_set_text_pos", "ps_set_value", "ps_setcolor", "ps_setdash", "ps_setflat", "ps_setfont", "ps_setgray", "ps_setlinecap", "ps_setlinejoin", "ps_setlinewidth", "ps_setmiterlimit", "ps_setoverprintmode", "ps_setpolydash", "ps_shading", "ps_shading_pattern", "ps_shfill", "ps_show", "ps_show_boxed", "ps_show_xy", "ps_show_xy2", "ps_show2", "ps_string_geometry", "ps_stringwidth", "ps_stroke", "ps_symbol", "ps_symbol_name", "ps_symbol_width", "ps_translate"] + b["Pspell"] = Set.new ["pspell_add_to_personal", "pspell_add_to_session", "pspell_check", "pspell_clear_session", "pspell_config_create", "pspell_config_data_dir", "pspell_config_dict_dir", "pspell_config_ignore", "pspell_config_mode", "pspell_config_personal", "pspell_config_repl", "pspell_config_runtogether", "pspell_config_save_repl", "pspell_new", "pspell_new_config", "pspell_new_personal", "pspell_save_wordlist", "pspell_store_replacement", "pspell_suggest"] + b["Radius"] = Set.new ["radius_acct_open", "radius_add_server", "radius_auth_open", "radius_close", "radius_config", "radius_create_request", "radius_cvt_addr", "radius_cvt_int", "radius_cvt_string", "radius_demangle", "radius_demangle_mppe_key", "radius_get_attr", "radius_get_tagged_attr_data", "radius_get_tagged_attr_tag", "radius_get_vendor_attr", "radius_put_addr", "radius_put_attr", "radius_put_int", "radius_put_string", "radius_put_vendor_addr", "radius_put_vendor_attr", "radius_put_vendor_int", "radius_put_vendor_string", "radius_request_authenticator", "radius_salt_encrypt_attr", "radius_send_request", "radius_server_secret", "radius_strerror"] + b["Random"] = Set.new ["getrandmax", "lcg_value", "mt_getrandmax", "mt_rand", "mt_srand", "rand", "random_bytes", "random_int", "srand"] + b["Rar"] = Set.new ["rar_wrapper_cache_stats"] + b["Readline"] = Set.new ["readline", "readline_add_history", "readline_callback_handler_install", "readline_callback_handler_remove", "readline_callback_read_char", "readline_clear_history", "readline_completion_function", "readline_info", "readline_list_history", "readline_on_new_line", "readline_read_history", "readline_redisplay", "readline_write_history"] + b["Recode"] = Set.new ["recode", "recode_file", "recode_string"] + b["Rnp"] = Set.new ["rnp_backend_string", "rnp_backend_version", "rnp_decrypt", "rnp_dump_packets", "rnp_dump_packets_to_json", "rnp_ffi_create", "rnp_ffi_destroy", "rnp_ffi_set_pass_provider", "rnp_import_keys", "rnp_import_signatures", "rnp_key_export", "rnp_key_export_autocrypt", "rnp_key_export_revocation", "rnp_key_get_info", "rnp_key_remove", "rnp_key_revoke", "rnp_list_keys", "rnp_load_keys", "rnp_load_keys_from_path", "rnp_locate_key", "rnp_op_encrypt", "rnp_op_generate_key", "rnp_op_sign", "rnp_op_sign_cleartext", "rnp_op_sign_detached", "rnp_op_verify", "rnp_op_verify_detached", "rnp_save_keys", "rnp_save_keys_to_path", "rnp_supported_features", "rnp_version_string", "rnp_version_string_full"] + b["RpmInfo"] = Set.new ["rpmaddtag", "rpmdbinfo", "rpmdbsearch", "rpmdefine", "rpmexpand", "rpmexpandnumeric", "rpmgetsymlink", "rpminfo", "rpmvercmp"] + b["RRD"] = Set.new ["rrd_create", "rrd_error", "rrd_fetch", "rrd_first", "rrd_graph", "rrd_info", "rrd_last", "rrd_lastupdate", "rrd_restore", "rrd_tune", "rrd_update", "rrd_version", "rrd_xport", "rrdc_disconnect"] + b["runkit7"] = Set.new ["runkit7_constant_add", "runkit7_constant_redefine", "runkit7_constant_remove", "runkit7_function_add", "runkit7_function_copy", "runkit7_function_redefine", "runkit7_function_remove", "runkit7_function_rename", "runkit7_import", "runkit7_method_add", "runkit7_method_copy", "runkit7_method_redefine", "runkit7_method_remove", "runkit7_method_rename", "runkit7_object_id", "runkit7_superglobals", "runkit7_zval_inspect"] + b["Scoutapm"] = Set.new ["scoutapm_get_calls", "scoutapm_list_instrumented_functions"] + b["Seaslog"] = Set.new ["seaslog_get_author", "seaslog_get_version"] + b["Semaphore"] = Set.new ["ftok", "msg_get_queue", "msg_queue_exists", "msg_receive", "msg_remove_queue", "msg_send", "msg_set_queue", "msg_stat_queue", "sem_acquire", "sem_get", "sem_release", "sem_remove", "shm_attach", "shm_detach", "shm_get_var", "shm_has_var", "shm_put_var", "shm_remove", "shm_remove_var"] + b["Session"] = Set.new ["session_abort", "session_cache_expire", "session_cache_limiter", "session_commit", "session_create_id", "session_decode", "session_destroy", "session_encode", "session_gc", "session_get_cookie_params", "session_id", "session_module_name", "session_name", "session_regenerate_id", "session_register_shutdown", "session_reset", "session_save_path", "session_set_cookie_params", "session_set_save_handler", "session_start", "session_status", "session_unset", "session_write_close"] + b["Shared Memory"] = Set.new ["shmop_close", "shmop_delete", "shmop_open", "shmop_read", "shmop_size", "shmop_write"] + b["Simdjson"] = Set.new ["simdjson_decode", "simdjson_is_valid", "simdjson_key_count", "simdjson_key_exists", "simdjson_key_value"] + b["SimpleXML"] = Set.new ["simplexml_import_dom", "simplexml_load_file", "simplexml_load_string"] + b["SNMP"] = Set.new ["snmp_get_quick_print", "snmp_get_valueretrieval", "snmp_read_mib", "snmp_set_enum_print", "snmp_set_oid_numeric_print", "snmp_set_oid_output_format", "snmp_set_quick_print", "snmp_set_valueretrieval", "snmp2_get", "snmp2_getnext", "snmp2_real_walk", "snmp2_set", "snmp2_walk", "snmp3_get", "snmp3_getnext", "snmp3_real_walk", "snmp3_set", "snmp3_walk", "snmpget", "snmpgetnext", "snmprealwalk", "snmpset", "snmpwalk", "snmpwalkoid"] + b["SOAP"] = Set.new ["is_soap_fault", "use_soap_error_handler"] + b["Socket"] = Set.new ["socket_accept", "socket_addrinfo_bind", "socket_addrinfo_connect", "socket_addrinfo_explain", "socket_addrinfo_lookup", "socket_atmark", "socket_bind", "socket_clear_error", "socket_close", "socket_cmsg_space", "socket_connect", "socket_create", "socket_create_listen", "socket_create_pair", "socket_export_stream", "socket_get_option", "socket_getopt", "socket_getpeername", "socket_getsockname", "socket_import_stream", "socket_last_error", "socket_listen", "socket_read", "socket_recv", "socket_recvfrom", "socket_recvmsg", "socket_select", "socket_send", "socket_sendmsg", "socket_sendto", "socket_set_block", "socket_set_nonblock", "socket_set_option", "socket_setopt", "socket_shutdown", "socket_strerror", "socket_write", "socket_wsaprotocol_info_export", "socket_wsaprotocol_info_import", "socket_wsaprotocol_info_release"] + b["Sodium"] = Set.new ["sodium_add", "sodium_base642bin", "sodium_bin2base64", "sodium_bin2hex", "sodium_compare", "sodium_crypto_aead_aegis128l_decrypt", "sodium_crypto_aead_aegis128l_encrypt", "sodium_crypto_aead_aegis128l_keygen", "sodium_crypto_aead_aegis256_decrypt", "sodium_crypto_aead_aegis256_encrypt", "sodium_crypto_aead_aegis256_keygen", "sodium_crypto_aead_aes256gcm_decrypt", "sodium_crypto_aead_aes256gcm_encrypt", "sodium_crypto_aead_aes256gcm_is_available", "sodium_crypto_aead_aes256gcm_keygen", "sodium_crypto_aead_chacha20poly1305_decrypt", "sodium_crypto_aead_chacha20poly1305_encrypt", "sodium_crypto_aead_chacha20poly1305_ietf_decrypt", "sodium_crypto_aead_chacha20poly1305_ietf_encrypt", "sodium_crypto_aead_chacha20poly1305_ietf_keygen", "sodium_crypto_aead_chacha20poly1305_keygen", "sodium_crypto_aead_xchacha20poly1305_ietf_decrypt", "sodium_crypto_aead_xchacha20poly1305_ietf_encrypt", "sodium_crypto_aead_xchacha20poly1305_ietf_keygen", "sodium_crypto_auth", "sodium_crypto_auth_keygen", "sodium_crypto_auth_verify", "sodium_crypto_box", "sodium_crypto_box_keypair", "sodium_crypto_box_keypair_from_secretkey_and_publickey", "sodium_crypto_box_open", "sodium_crypto_box_publickey", "sodium_crypto_box_publickey_from_secretkey", "sodium_crypto_box_seal", "sodium_crypto_box_seal_open", "sodium_crypto_box_secretkey", "sodium_crypto_box_seed_keypair", "sodium_crypto_core_ristretto255_add", "sodium_crypto_core_ristretto255_from_hash", "sodium_crypto_core_ristretto255_is_valid_point", "sodium_crypto_core_ristretto255_random", "sodium_crypto_core_ristretto255_scalar_add", "sodium_crypto_core_ristretto255_scalar_complement", "sodium_crypto_core_ristretto255_scalar_invert", "sodium_crypto_core_ristretto255_scalar_mul", "sodium_crypto_core_ristretto255_scalar_negate", "sodium_crypto_core_ristretto255_scalar_random", "sodium_crypto_core_ristretto255_scalar_reduce", "sodium_crypto_core_ristretto255_scalar_sub", "sodium_crypto_core_ristretto255_sub", "sodium_crypto_generichash", "sodium_crypto_generichash_final", "sodium_crypto_generichash_init", "sodium_crypto_generichash_keygen", "sodium_crypto_generichash_update", "sodium_crypto_kdf_derive_from_key", "sodium_crypto_kdf_keygen", "sodium_crypto_kx_client_session_keys", "sodium_crypto_kx_keypair", "sodium_crypto_kx_publickey", "sodium_crypto_kx_secretkey", "sodium_crypto_kx_seed_keypair", "sodium_crypto_kx_server_session_keys", "sodium_crypto_pwhash", "sodium_crypto_pwhash_scryptsalsa208sha256", "sodium_crypto_pwhash_scryptsalsa208sha256_str", "sodium_crypto_pwhash_scryptsalsa208sha256_str_verify", "sodium_crypto_pwhash_str", "sodium_crypto_pwhash_str_needs_rehash", "sodium_crypto_pwhash_str_verify", "sodium_crypto_scalarmult", "sodium_crypto_scalarmult_base", "sodium_crypto_scalarmult_ristretto255", "sodium_crypto_scalarmult_ristretto255_base", "sodium_crypto_secretbox", "sodium_crypto_secretbox_keygen", "sodium_crypto_secretbox_open", "sodium_crypto_secretstream_xchacha20poly1305_init_pull", "sodium_crypto_secretstream_xchacha20poly1305_init_push", "sodium_crypto_secretstream_xchacha20poly1305_keygen", "sodium_crypto_secretstream_xchacha20poly1305_pull", "sodium_crypto_secretstream_xchacha20poly1305_push", "sodium_crypto_secretstream_xchacha20poly1305_rekey", "sodium_crypto_shorthash", "sodium_crypto_shorthash_keygen", "sodium_crypto_sign", "sodium_crypto_sign_detached", "sodium_crypto_sign_ed25519_pk_to_curve25519", "sodium_crypto_sign_ed25519_sk_to_curve25519", "sodium_crypto_sign_keypair", "sodium_crypto_sign_keypair_from_secretkey_and_publickey", "sodium_crypto_sign_open", "sodium_crypto_sign_publickey", "sodium_crypto_sign_publickey_from_secretkey", "sodium_crypto_sign_secretkey", "sodium_crypto_sign_seed_keypair", "sodium_crypto_sign_verify_detached", "sodium_crypto_stream", "sodium_crypto_stream_keygen", "sodium_crypto_stream_xchacha20", "sodium_crypto_stream_xchacha20_keygen", "sodium_crypto_stream_xchacha20_xor", "sodium_crypto_stream_xchacha20_xor_ic", "sodium_crypto_stream_xor", "sodium_hex2bin", "sodium_increment", "sodium_memcmp", "sodium_memzero", "sodium_pad", "sodium_unpad"] + b["Solr"] = Set.new ["solr_get_version"] + b["SPL"] = Set.new ["class_implements", "class_parents", "class_uses", "iterator_apply", "iterator_count", "iterator_to_array", "spl_autoload", "spl_autoload_call", "spl_autoload_extensions", "spl_autoload_functions", "spl_autoload_register", "spl_autoload_unregister", "spl_classes", "spl_object_hash", "spl_object_id"] + b["SQLSRV"] = Set.new ["sqlsrv_begin_transaction", "sqlsrv_cancel", "sqlsrv_client_info", "sqlsrv_close", "sqlsrv_commit", "sqlsrv_configure", "sqlsrv_connect", "sqlsrv_errors", "sqlsrv_execute", "sqlsrv_fetch", "sqlsrv_fetch_array", "sqlsrv_fetch_object", "sqlsrv_field_metadata", "sqlsrv_free_stmt", "sqlsrv_get_config", "sqlsrv_get_field", "sqlsrv_has_rows", "sqlsrv_next_result", "sqlsrv_num_fields", "sqlsrv_num_rows", "sqlsrv_prepare", "sqlsrv_query", "sqlsrv_rollback", "sqlsrv_rows_affected", "sqlsrv_send_stream_data", "sqlsrv_server_info"] + b["ssdeep"] = Set.new ["ssdeep_fuzzy_compare", "ssdeep_fuzzy_hash", "ssdeep_fuzzy_hash_filename"] + b["SSH2"] = Set.new ["ssh2_auth_agent", "ssh2_auth_hostbased_file", "ssh2_auth_none", "ssh2_auth_password", "ssh2_auth_pubkey_file", "ssh2_connect", "ssh2_disconnect", "ssh2_exec", "ssh2_fetch_stream", "ssh2_fingerprint", "ssh2_forward_accept", "ssh2_forward_listen", "ssh2_methods_negotiated", "ssh2_poll", "ssh2_publickey_add", "ssh2_publickey_init", "ssh2_publickey_list", "ssh2_publickey_remove", "ssh2_scp_recv", "ssh2_scp_send", "ssh2_send_eof", "ssh2_sftp", "ssh2_sftp_chmod", "ssh2_sftp_lstat", "ssh2_sftp_mkdir", "ssh2_sftp_readlink", "ssh2_sftp_realpath", "ssh2_sftp_rename", "ssh2_sftp_rmdir", "ssh2_sftp_stat", "ssh2_sftp_symlink", "ssh2_sftp_unlink", "ssh2_shell", "ssh2_tunnel"] + b["Statistic"] = Set.new ["stats_absolute_deviation", "stats_cdf_beta", "stats_cdf_binomial", "stats_cdf_cauchy", "stats_cdf_chisquare", "stats_cdf_exponential", "stats_cdf_f", "stats_cdf_gamma", "stats_cdf_laplace", "stats_cdf_logistic", "stats_cdf_negative_binomial", "stats_cdf_noncentral_chisquare", "stats_cdf_noncentral_f", "stats_cdf_noncentral_t", "stats_cdf_normal", "stats_cdf_poisson", "stats_cdf_t", "stats_cdf_uniform", "stats_cdf_weibull", "stats_covariance", "stats_dens_beta", "stats_dens_cauchy", "stats_dens_chisquare", "stats_dens_exponential", "stats_dens_f", "stats_dens_gamma", "stats_dens_laplace", "stats_dens_logistic", "stats_dens_normal", "stats_dens_pmf_binomial", "stats_dens_pmf_hypergeometric", "stats_dens_pmf_negative_binomial", "stats_dens_pmf_poisson", "stats_dens_t", "stats_dens_uniform", "stats_dens_weibull", "stats_harmonic_mean", "stats_kurtosis", "stats_rand_gen_beta", "stats_rand_gen_chisquare", "stats_rand_gen_exponential", "stats_rand_gen_f", "stats_rand_gen_funiform", "stats_rand_gen_gamma", "stats_rand_gen_ibinomial", "stats_rand_gen_ibinomial_negative", "stats_rand_gen_int", "stats_rand_gen_ipoisson", "stats_rand_gen_iuniform", "stats_rand_gen_noncentral_chisquare", "stats_rand_gen_noncentral_f", "stats_rand_gen_noncentral_t", "stats_rand_gen_normal", "stats_rand_gen_t", "stats_rand_get_seeds", "stats_rand_phrase_to_seeds", "stats_rand_ranf", "stats_rand_setall", "stats_skew", "stats_standard_deviation", "stats_stat_binomial_coef", "stats_stat_correlation", "stats_stat_factorial", "stats_stat_independent_t", "stats_stat_innerproduct", "stats_stat_paired_t", "stats_stat_percentile", "stats_stat_powersum", "stats_variance"] + b["Stomp"] = Set.new ["stomp_connect_error", "stomp_version"] + b["Stream"] = Set.new ["stream_bucket_append", "stream_bucket_make_writeable", "stream_bucket_new", "stream_bucket_prepend", "stream_context_create", "stream_context_get_default", "stream_context_get_options", "stream_context_get_params", "stream_context_set_default", "stream_context_set_option", "stream_context_set_options", "stream_context_set_params", "stream_copy_to_stream", "stream_filter_append", "stream_filter_prepend", "stream_filter_register", "stream_filter_remove", "stream_get_contents", "stream_get_filters", "stream_get_line", "stream_get_meta_data", "stream_get_transports", "stream_get_wrappers", "stream_is_local", "stream_isatty", "stream_notification_callback", "stream_register_wrapper", "stream_resolve_include_path", "stream_select", "stream_set_blocking", "stream_set_chunk_size", "stream_set_read_buffer", "stream_set_timeout", "stream_set_write_buffer", "stream_socket_accept", "stream_socket_client", "stream_socket_enable_crypto", "stream_socket_get_name", "stream_socket_pair", "stream_socket_recvfrom", "stream_socket_sendto", "stream_socket_server", "stream_socket_shutdown", "stream_supports_lock", "stream_wrapper_register", "stream_wrapper_restore", "stream_wrapper_unregister"] + b["String"] = Set.new ["addcslashes", "addslashes", "bin2hex", "chop", "chr", "chunk_split", "convert_cyr_string", "convert_uudecode", "convert_uuencode", "count_chars", "crc32", "crypt", "echo", "explode", "fprintf", "get_html_translation_table", "hebrev", "hebrevc", "hex2bin", "html_entity_decode", "htmlentities", "htmlspecialchars", "htmlspecialchars_decode", "implode", "join", "lcfirst", "levenshtein", "localeconv", "ltrim", "md5", "md5_file", "metaphone", "money_format", "nl_langinfo", "nl2br", "number_format", "ord", "parse_str", "print", "printf", "quoted_printable_decode", "quoted_printable_encode", "quotemeta", "rtrim", "setlocale", "sha1", "sha1_file", "similar_text", "soundex", "sprintf", "sscanf", "str_contains", "str_decrement", "str_ends_with", "str_getcsv", "str_increment", "str_ireplace", "str_pad", "str_repeat", "str_replace", "str_rot13", "str_shuffle", "str_split", "str_starts_with", "str_word_count", "strcasecmp", "strchr", "strcmp", "strcoll", "strcspn", "strip_tags", "stripcslashes", "stripos", "stripslashes", "stristr", "strlen", "strnatcasecmp", "strnatcmp", "strncasecmp", "strncmp", "strpbrk", "strpos", "strrchr", "strrev", "strripos", "strrpos", "strspn", "strstr", "strtok", "strtolower", "strtoupper", "strtr", "substr", "substr_compare", "substr_count", "substr_replace", "trim", "ucfirst", "ucwords", "utf8_decode", "utf8_encode", "vfprintf", "vprintf", "vsprintf", "wordwrap"] + b["SVN"] = Set.new ["svn_add", "svn_auth_get_parameter", "svn_auth_set_parameter", "svn_blame", "svn_cat", "svn_checkout", "svn_cleanup", "svn_client_version", "svn_commit", "svn_delete", "svn_diff", "svn_export", "svn_fs_abort_txn", "svn_fs_apply_text", "svn_fs_begin_txn2", "svn_fs_change_node_prop", "svn_fs_check_path", "svn_fs_contents_changed", "svn_fs_copy", "svn_fs_delete", "svn_fs_dir_entries", "svn_fs_file_contents", "svn_fs_file_length", "svn_fs_is_dir", "svn_fs_is_file", "svn_fs_make_dir", "svn_fs_make_file", "svn_fs_node_created_rev", "svn_fs_node_prop", "svn_fs_props_changed", "svn_fs_revision_prop", "svn_fs_revision_root", "svn_fs_txn_root", "svn_fs_youngest_rev", "svn_import", "svn_log", "svn_ls", "svn_mkdir", "svn_repos_create", "svn_repos_fs", "svn_repos_fs_begin_txn_for_commit", "svn_repos_fs_commit_txn", "svn_repos_hotcopy", "svn_repos_open", "svn_repos_recover", "svn_revert", "svn_status", "svn_update"] + b["Swoole"] = Set.new ["swoole_async_dns_lookup", "swoole_async_read", "swoole_async_readfile", "swoole_async_set", "swoole_async_write", "swoole_async_writefile", "swoole_clear_error", "swoole_client_select", "swoole_cpu_num", "swoole_errno", "swoole_error_log", "swoole_event_add", "swoole_event_defer", "swoole_event_del", "swoole_event_exit", "swoole_event_set", "swoole_event_wait", "swoole_event_write", "swoole_get_local_ip", "swoole_last_error", "swoole_load_module", "swoole_select", "swoole_set_process_name", "swoole_strerror", "swoole_timer_after", "swoole_timer_exists", "swoole_timer_tick", "swoole_version"] + b["Taint"] = Set.new ["is_tainted", "taint", "untaint"] + b["TCP"] = Set.new ["tcpwrap_check"] + b["Tidy"] = Set.new ["ob_tidyhandler", "tidy_access_count", "tidy_config_count", "tidy_error_count", "tidy_get_output", "tidy_warning_count"] + b["Tokenizer"] = Set.new ["token_get_all", "token_name"] + b["Trader"] = Set.new ["trader_acos", "trader_ad", "trader_add", "trader_adosc", "trader_adx", "trader_adxr", "trader_apo", "trader_aroon", "trader_aroonosc", "trader_asin", "trader_atan", "trader_atr", "trader_avgprice", "trader_bbands", "trader_beta", "trader_bop", "trader_cci", "trader_cdl2crows", "trader_cdl3blackcrows", "trader_cdl3inside", "trader_cdl3linestrike", "trader_cdl3outside", "trader_cdl3starsinsouth", "trader_cdl3whitesoldiers", "trader_cdlabandonedbaby", "trader_cdladvanceblock", "trader_cdlbelthold", "trader_cdlbreakaway", "trader_cdlclosingmarubozu", "trader_cdlconcealbabyswall", "trader_cdlcounterattack", "trader_cdldarkcloudcover", "trader_cdldoji", "trader_cdldojistar", "trader_cdldragonflydoji", "trader_cdlengulfing", "trader_cdleveningdojistar", "trader_cdleveningstar", "trader_cdlgapsidesidewhite", "trader_cdlgravestonedoji", "trader_cdlhammer", "trader_cdlhangingman", "trader_cdlharami", "trader_cdlharamicross", "trader_cdlhighwave", "trader_cdlhikkake", "trader_cdlhikkakemod", "trader_cdlhomingpigeon", "trader_cdlidentical3crows", "trader_cdlinneck", "trader_cdlinvertedhammer", "trader_cdlkicking", "trader_cdlkickingbylength", "trader_cdlladderbottom", "trader_cdllongleggeddoji", "trader_cdllongline", "trader_cdlmarubozu", "trader_cdlmatchinglow", "trader_cdlmathold", "trader_cdlmorningdojistar", "trader_cdlmorningstar", "trader_cdlonneck", "trader_cdlpiercing", "trader_cdlrickshawman", "trader_cdlrisefall3methods", "trader_cdlseparatinglines", "trader_cdlshootingstar", "trader_cdlshortline", "trader_cdlspinningtop", "trader_cdlstalledpattern", "trader_cdlsticksandwich", "trader_cdltakuri", "trader_cdltasukigap", "trader_cdlthrusting", "trader_cdltristar", "trader_cdlunique3river", "trader_cdlupsidegap2crows", "trader_cdlxsidegap3methods", "trader_ceil", "trader_cmo", "trader_correl", "trader_cos", "trader_cosh", "trader_dema", "trader_div", "trader_dx", "trader_ema", "trader_errno", "trader_exp", "trader_floor", "trader_get_compat", "trader_get_unstable_period", "trader_ht_dcperiod", "trader_ht_dcphase", "trader_ht_phasor", "trader_ht_sine", "trader_ht_trendline", "trader_ht_trendmode", "trader_kama", "trader_linearreg", "trader_linearreg_angle", "trader_linearreg_intercept", "trader_linearreg_slope", "trader_ln", "trader_log10", "trader_ma", "trader_macd", "trader_macdext", "trader_macdfix", "trader_mama", "trader_mavp", "trader_max", "trader_maxindex", "trader_medprice", "trader_mfi", "trader_midpoint", "trader_midprice", "trader_min", "trader_minindex", "trader_minmax", "trader_minmaxindex", "trader_minus_di", "trader_minus_dm", "trader_mom", "trader_mult", "trader_natr", "trader_obv", "trader_plus_di", "trader_plus_dm", "trader_ppo", "trader_roc", "trader_rocp", "trader_rocr", "trader_rocr100", "trader_rsi", "trader_sar", "trader_sarext", "trader_set_compat", "trader_set_unstable_period", "trader_sin", "trader_sinh", "trader_sma", "trader_sqrt", "trader_stddev", "trader_stoch", "trader_stochf", "trader_stochrsi", "trader_sub", "trader_sum", "trader_t3", "trader_tan", "trader_tanh", "trader_tema", "trader_trange", "trader_trima", "trader_trix", "trader_tsf", "trader_typprice", "trader_ultosc", "trader_var", "trader_wclprice", "trader_willr", "trader_wma"] + b["UI"] = Set.new ["UI\\Draw\\Text\\Font\\fontFamilies", "UI\\quit", "UI\\run"] + b["ODBC"] = Set.new ["odbc_autocommit", "odbc_binmode", "odbc_close", "odbc_close_all", "odbc_columnprivileges", "odbc_columns", "odbc_commit", "odbc_connect", "odbc_connection_string_is_quoted", "odbc_connection_string_quote", "odbc_connection_string_should_quote", "odbc_cursor", "odbc_data_source", "odbc_do", "odbc_error", "odbc_errormsg", "odbc_exec", "odbc_execute", "odbc_fetch_array", "odbc_fetch_into", "odbc_fetch_object", "odbc_fetch_row", "odbc_field_len", "odbc_field_name", "odbc_field_num", "odbc_field_precision", "odbc_field_scale", "odbc_field_type", "odbc_foreignkeys", "odbc_free_result", "odbc_gettypeinfo", "odbc_longreadlen", "odbc_next_result", "odbc_num_fields", "odbc_num_rows", "odbc_pconnect", "odbc_prepare", "odbc_primarykeys", "odbc_procedurecolumns", "odbc_procedures", "odbc_result", "odbc_result_all", "odbc_rollback", "odbc_setoption", "odbc_specialcolumns", "odbc_statistics", "odbc_tableprivileges", "odbc_tables"] + b["Uopz"] = Set.new ["uopz_add_function", "uopz_allow_exit", "uopz_backup", "uopz_compose", "uopz_copy", "uopz_del_function", "uopz_delete", "uopz_extend", "uopz_flags", "uopz_function", "uopz_get_exit_status", "uopz_get_hook", "uopz_get_mock", "uopz_get_property", "uopz_get_return", "uopz_get_static", "uopz_implement", "uopz_overload", "uopz_redefine", "uopz_rename", "uopz_restore", "uopz_set_hook", "uopz_set_mock", "uopz_set_property", "uopz_set_return", "uopz_set_static", "uopz_undefine", "uopz_unset_hook", "uopz_unset_mock", "uopz_unset_return"] + b["URL"] = Set.new ["base64_decode", "base64_encode", "get_headers", "get_meta_tags", "http_build_query", "parse_url", "rawurldecode", "rawurlencode", "urldecode", "urlencode"] + b["var_representation"] = Set.new ["var_representation"] + b["Variable handling"] = Set.new ["boolval", "debug_zval_dump", "doubleval", "empty", "floatval", "get_debug_type", "get_defined_vars", "get_resource_id", "get_resource_type", "gettype", "intval", "is_array", "is_bool", "is_callable", "is_countable", "is_double", "is_float", "is_int", "is_integer", "is_iterable", "is_long", "is_null", "is_numeric", "is_object", "is_real", "is_resource", "is_scalar", "is_string", "isset", "print_r", "serialize", "settype", "strval", "unserialize", "unset", "var_dump", "var_export"] + b["WDDX"] = Set.new ["wddx_add_vars", "wddx_deserialize", "wddx_packet_end", "wddx_packet_start", "wddx_serialize_value", "wddx_serialize_vars"] + b["win32service"] = Set.new ["win32_add_right_access_service", "win32_add_service_env_var", "win32_continue_service", "win32_create_service", "win32_delete_service", "win32_get_last_control_message", "win32_get_service_env_vars", "win32_pause_service", "win32_query_service_status", "win32_read_all_rights_access_service", "win32_read_right_access_service", "win32_remove_right_access_service", "win32_remove_service_env_var", "win32_send_custom_control", "win32_set_service_exit_code", "win32_set_service_exit_mode", "win32_set_service_pause_resume_state", "win32_set_service_status", "win32_start_service", "win32_start_service_ctrl_dispatcher", "win32_stop_service"] + b["WinCache"] = Set.new ["wincache_fcache_fileinfo", "wincache_fcache_meminfo", "wincache_lock", "wincache_ocache_fileinfo", "wincache_ocache_meminfo", "wincache_refresh_if_changed", "wincache_rplist_fileinfo", "wincache_rplist_meminfo", "wincache_scache_info", "wincache_scache_meminfo", "wincache_ucache_add", "wincache_ucache_cas", "wincache_ucache_clear", "wincache_ucache_dec", "wincache_ucache_delete", "wincache_ucache_exists", "wincache_ucache_get", "wincache_ucache_inc", "wincache_ucache_info", "wincache_ucache_meminfo", "wincache_ucache_set", "wincache_unlock"] + b["xattr"] = Set.new ["xattr_get", "xattr_list", "xattr_remove", "xattr_set", "xattr_supported"] + b["xdiff"] = Set.new ["xdiff_file_bdiff", "xdiff_file_bdiff_size", "xdiff_file_bpatch", "xdiff_file_diff", "xdiff_file_diff_binary", "xdiff_file_merge3", "xdiff_file_patch", "xdiff_file_patch_binary", "xdiff_file_rabdiff", "xdiff_string_bdiff", "xdiff_string_bdiff_size", "xdiff_string_bpatch", "xdiff_string_diff", "xdiff_string_diff_binary", "xdiff_string_merge3", "xdiff_string_patch", "xdiff_string_patch_binary", "xdiff_string_rabdiff"] + b["Xhprof"] = Set.new ["xhprof_disable", "xhprof_enable", "xhprof_sample_disable", "xhprof_sample_enable"] + b["XML Parser"] = Set.new ["xml_error_string", "xml_get_current_byte_index", "xml_get_current_column_number", "xml_get_current_line_number", "xml_get_error_code", "xml_parse", "xml_parse_into_struct", "xml_parser_create", "xml_parser_create_ns", "xml_parser_free", "xml_parser_get_option", "xml_parser_set_option", "xml_set_character_data_handler", "xml_set_default_handler", "xml_set_element_handler", "xml_set_end_namespace_decl_handler", "xml_set_external_entity_ref_handler", "xml_set_notation_decl_handler", "xml_set_object", "xml_set_processing_instruction_handler", "xml_set_start_namespace_decl_handler", "xml_set_unparsed_entity_decl_handler"] + b["XML-RPC"] = Set.new ["xmlrpc_decode", "xmlrpc_decode_request", "xmlrpc_encode", "xmlrpc_encode_request", "xmlrpc_get_type", "xmlrpc_is_fault", "xmlrpc_parse_method_descriptions", "xmlrpc_server_add_introspection_data", "xmlrpc_server_call_method", "xmlrpc_server_create", "xmlrpc_server_destroy", "xmlrpc_server_register_introspection_callback", "xmlrpc_server_register_method", "xmlrpc_set_type"] + b["Xpass"] = Set.new ["crypt_checksalt", "crypt_gensalt", "crypt_preferred_method"] + b["Yaml"] = Set.new ["yaml_emit", "yaml_emit_file", "yaml_parse", "yaml_parse_file", "yaml_parse_url"] + b["YAZ"] = Set.new ["yaz_addinfo", "yaz_ccl_conf", "yaz_ccl_parse", "yaz_close", "yaz_connect", "yaz_database", "yaz_element", "yaz_errno", "yaz_error", "yaz_es", "yaz_es_result", "yaz_get_option", "yaz_hits", "yaz_itemorder", "yaz_present", "yaz_range", "yaz_record", "yaz_scan", "yaz_scan_result", "yaz_schema", "yaz_search", "yaz_set_option", "yaz_sort", "yaz_syntax", "yaz_wait"] + b["Zip"] = Set.new ["zip_close", "zip_entry_close", "zip_entry_compressedsize", "zip_entry_compressionmethod", "zip_entry_filesize", "zip_entry_name", "zip_entry_open", "zip_entry_read", "zip_open", "zip_read"] + b["Zlib"] = Set.new ["deflate_add", "deflate_init", "gzclose", "gzcompress", "gzdecode", "gzdeflate", "gzencode", "gzeof", "gzfile", "gzgetc", "gzgets", "gzgetss", "gzinflate", "gzopen", "gzpassthru", "gzputs", "gzread", "gzrewind", "gzseek", "gztell", "gzuncompress", "gzwrite", "inflate_add", "inflate_get_read_len", "inflate_get_status", "inflate_init", "ob_gzhandler", "readgzfile", "zlib_decode", "zlib_encode", "zlib_get_coding_type"] + b["ZooKeeper"] = Set.new ["zookeeper_dispatch"] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plain_text.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plain_text.rb new file mode 100644 index 0000000..db49767 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plain_text.rb @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class PlainText < Lexer + title "Plain Text" + desc "A boring lexer that doesn't highlight anything" + + tag 'plaintext' + aliases 'text' + filenames '*.txt', 'Messages' + mimetypes 'text/plain' + + attr_reader :token + def initialize(*) + super + + @token = token_option(:token) || Text + end + + def stream_tokens(string, &b) + yield self.token, string + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plist.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plist.rb new file mode 100644 index 0000000..bd0ed9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plist.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + class Plist < RegexLexer + desc 'plist' + tag 'plist' + aliases 'plist' + filenames '*.plist', '*.pbxproj' + + mimetypes 'text/x-plist', 'application/x-plist' + + state :whitespace do + rule %r/\s+/, Text::Whitespace + end + + state :root do + rule %r{//.*$}, Comment + rule %r{/\*.+?\*/}m, Comment + mixin :whitespace + rule %r/{/, Punctuation, :dictionary + rule %r/\(/, Punctuation, :array + rule %r/"([^"\\]|\\.)*"/, Literal::String::Double + rule %r/'([^'\\]|\\.)*'/, Literal::String::Single + rule %r//, Punctuation, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plsql.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plsql.rb new file mode 100644 index 0000000..4674cc5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/plsql.rb @@ -0,0 +1,578 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class PLSQL < RegexLexer + title "PLSQL" + desc "Procedural Language Structured Query Language for Oracle relational database" + tag 'plsql' + filenames '*.pls', '*.typ', '*.tps', '*.tpb', '*.pks', '*.pkb', '*.pkg', '*.trg' + mimetypes 'text/x-plsql' + + def self.keywords_reserved + @keywords_reserved ||= Set.new(%w( + ACCESSIBLE AGENT ALL ALTER AND ANY AS ASC BETWEEN BFILE_BASE BLOB_BASE BY + C CALLING CHARSET CHARSETFORM CHARSETID CHAR_BASE CHECK CLOB_BASE CLUSTER + COLLATE COMPILED COMPRESS CONNECT CONNECT_BY_ROOT CONSTRUCTOR CREATE CUSTOMDATUM + DATE_BASE DEFAULT DELETE DESC DISTINCT DROP DURATION ELSE ELSIF EXCEPT EXCLUSIVE + EXISTS EXIT FIXED FOR FORALL FROM GENERAL GRANT GROUP HAVING IDENTIFIED IN INDEX + INDICES INSERT INTERFACE INTERSECT INTO IS LARGE LIKE LIMITED LOCK LOOP MAXLEN + MINUS MODE NOCOMPRESS NOT NOWAIT NULL NUMBER_BASE OCICOLL OCIDATE OCIDATETIME + OCIDURATION OCIINTERVAL OCILOBLOCATOR OCINUMBER OCIRAW OCIREF OCIREFCURSOR + OCIROWID OCISTRING OCITYPE OF ON OPTION OR ORACLE ORADATA ORDER ORLANY ORLVARY + OUT OVERRIDING PARALLEL_ENABLE PARAMETER PASCAL PCTFREE PIPE PIPELINED POLYMORPHIC + PRAGMA PRIOR PUBLIC RAISE RECORD RELIES_ON REM RENAME RESOURCE RESULT REVOKE ROWID + SB1 SB2 SELECT SEPARATE SET SHARE SHORT SIZE SIZE_T SPARSE SQLCODE SQLDATA + SQLNAME SQLSTATE STANDARD START STORED STRUCT STYLE SYNONYM TABLE TDO THEN + TRANSACTIONAL TRIGGER UB1 UB4 UNION UNIQUE UNSIGNED UNTRUSTED UPDATE VALIST + VALUES VARIABLE VIEW VOID WHERE WHILE WITH + )) + end + + def self.keywords + @keywords ||= Set.new(%w( + ABORT ABS ABSENT ACCESS ACCESSED ACCOUNT ACL ACOS ACROSS ACTION ACTIONS + ACTIVATE ACTIVE ACTIVE_COMPONENT ACTIVE_DATA ACTIVE_FUNCTION ACTIVE_TAG ACTIVITY + ADAPTIVE_PLAN ADD ADD_COLUMN ADD_GROUP ADD_MONTHS ADG_REDIRECT_DML ADG_REDIRECT_PLSQL + ADJ_DATE ADMIN ADMINISTER ADMINISTRATOR ADVANCED ADVISE ADVISOR AFD_DISKSTRING + AFFINITY AFTER AGGREGATE AGGREGATES ALGORITHM ALIAS ALLOCATE ALLOW ALL_ROWS + ALTERNATE ALWAYS ANALYTIC ANALYTIC_VIEW_SQL ANALYZE ANCESTOR ANCILLARY AND_EQUAL + ANOMALY ANSI_REARCH ANSWER_QUERY_USING_STATS ANTIJOIN ANYSCHEMA ANY_VALUE + APPEND APPENDCHILDXML APPEND_VALUES APPLICATION APPLY APPROX_COUNT APPROX_COUNT_DISTINCT + APPROX_COUNT_DISTINCT_AGG APPROX_COUNT_DISTINCT_DETAIL APPROX_MEDIAN APPROX_PERCENTILE + APPROX_PERCENTILE_AGG APPROX_PERCENTILE_DETAIL APPROX_RANK APPROX_SUM ARCHIVAL + ARCHIVE ARCHIVED ARCHIVELOG ARRAY ARRAYS ASCII ASCIISTR ASIN ASIS ASSEMBLY + ASSIGN ASSOCIATE ASYNC ASYNCHRONOUS AS_JSON AT ATAN ATAN2 ATTRIBUTE ATTRIBUTES + AUDIT AUTHENTICATED AUTHENTICATION AUTHID AUTHORIZATION AUTO AUTOALLOCATE + AUTOEXTEND AUTOMATIC AUTO_LOGIN AUTO_REOPTIMIZE AVAILABILITY AVCACHE_OP AVERAGE_RANK + AVG AVMDX_OP AVRO AV_AGGREGATE AV_CACHE AW BACKGROUND BACKINGFILE BACKUP BAND_JOIN + BASIC BASICFILE BATCH BATCHSIZE BATCH_TABLE_ACCESS_BY_ROWID BECOME BEFORE + BEGIN BEGINNING BEGIN_OUTLINE_DATA BEHALF BEQUEATH BFILENAME BIGFILE BINARY + BINARY_DOUBLE_INFINITY BINARY_DOUBLE_NAN BINARY_FLOAT_INFINITY BINARY_FLOAT_NAN + BINDING BIND_AWARE BIN_TO_NUM BITAND BITMAP BITMAPS BITMAP_AND BITMAP_BIT_POSITION + BITMAP_BUCKET_NUMBER BITMAP_CONSTRUCT_AGG BITMAP_COUNT BITMAP_OR_AGG BITMAP_TREE + BITOR BITS BITXOR BIT_AND_AGG BIT_OR_AGG BIT_XOR_AGG BLOCK BLOCKCHAIN BLOCKING + BLOCKS BLOCKSIZE BLOCK_RANGE BODY BOOL BOOTSTRAP BOTH BOUND BRANCH BREADTH + BROADCAST BSON BUFFER BUFFER_CACHE BUFFER_POOL BUILD BULK BUSHY_JOIN BYPASS_RECURSIVE_CHECK + BYPASS_UJVC CACHE CACHE_CB CACHE_INSTANCES CACHE_TEMP_TABLE CACHING CALCULATED + CALL CALLBACK CANCEL CAPACITY CAPTION CAPTURE CARDINALITY CASCADE CASE CAST + CATALOG_DBLINK CATEGORY CDB$DEFAULT CDB_HTTP_HANDLER CEIL CELLMEMORY CELL_FLASH_CACHE + CERTIFICATE CFILE CHAINED CHANGE CHANGE_DUPKEY_ERROR_INDEX CHARTOROWID CHAR_CS + CHECKPOINT CHECKSUM CHECK_ACL_REWRITE CHILD CHOOSE CHR CHUNK CLASS CLASSIFICATION + CLASSIFIER CLAUSE CLEAN CLEANUP CLEAR CLIENT CLONE CLOSE CLOSEST CLOSE_CACHED_OPEN_CURSORS + CLOUD_IDENTITY CLUSTERING CLUSTERING_FACTOR CLUSTERS CLUSTER_BY_ROWID CLUSTER_DETAILS + CLUSTER_DISTANCE CLUSTER_ID CLUSTER_PROBABILITY CLUSTER_SET COALESCE COALESCE_SQ + COARSE COLAUTH COLD COLLATE COLLATION COLLECT COLUMN COLUMNAR COLUMNS COLUMN_AUTHORIZATION_INDICATOR + COLUMN_AUTH_INDICATOR COLUMN_STATS COLUMN_VALUE COMMENT COMMIT COMMITTED COMMON + COMMON_DATA_MAP COMPACT COMPATIBILITY COMPILE COMPLETE COMPLIANCE COMPONENT + COMPONENTS COMPOSE COMPOSITE COMPOSITE_LIMIT COMPOUND COMPUTATION COMPUTE + CONCAT CONDITION CONDITIONAL CONFIRM CONFORMING CONNECT_BY_CB_WHR_ONLY CONNECT_BY_COMBINE_SW + CONNECT_BY_COST_BASED CONNECT_BY_ELIM_DUPS CONNECT_BY_FILTERING CONNECT_BY_ISCYCLE + CONNECT_BY_ISLEAF CONNECT_BY_ROOT CONNECT_TIME CONSENSUS CONSIDER CONSISTENT + CONST CONSTANT CONSTRAINT CONSTRAINTS CONTAINER CONTAINERS CONTAINERS_DEFAULT + CONTAINER_DATA CONTAINER_DATA_ADMIT_NULL CONTAINER_MAP CONTAINER_MAP_OBJECT + CONTENT CONTENTS CONTEXT CONTINUE CONTROLFILE CONVERSION CONVERT CON_DBID_TO_ID + CON_GUID_TO_ID CON_ID CON_ID_FILTER CON_ID_TO_CON_NAME CON_ID_TO_DBID CON_ID_TO_GUID + CON_ID_TO_UID CON_NAME_TO_ID CON_UID_TO_ID COOKIE COPY CORR CORRUPTION CORRUPT_XID + CORRUPT_XID_ALL CORR_K CORR_S COS COSH COST COST_XML_QUERY_REWRITE COUNT COVAR_POP + COVAR_SAMP CO_AUTH_IND CPU_COSTING CPU_COUNT CPU_PER_CALL CPU_PER_SESSION + CPU_TIME CRASH CREATE_FILE_DEST CREATE_STORED_OUTLINES CREATION CREDENTIAL + CREDENTIALS CRITICAL CROSS CROSSEDITION CSCONVERT CUBE CUBE_AJ CUBE_GB CUBE_SJ + CUME_DIST CUME_DISTM CURRENT CURRENTV CURRENT_DATE CURRENT_INSTANCE CURRENT_PARTSET_KEY + CURRENT_SCHEMA CURRENT_SHARD_KEY CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER + CURSOR CURSOR_SHARING_EXACT CURSOR_SPECIFIC_SEGMENT CV CYCLE DAGG_OPTIM_GSETS + DANGLING DATA DATABASE DATABASES DATAFILE DATAFILES DATAMOVEMENT DATAOBJNO + DATAOBJ_TO_MAT_PARTITION DATAOBJ_TO_PARTITION DATAPUMP DATASTORE DATA_LINK_DML + DATA_SECURITY_REWRITE_LIMIT DATA_VALIDATE DATE_MODE DAYS DBA DBA_RECYCLEBIN + DBMS_STATS DBSTR2UTF8 DBTIMEZONE DB_ROLE_CHANGE DB_UNIQUE_NAME DB_VERSION + DDL DEALLOCATE DEBUG DEBUGGER DECLARE DECODE DECOMPOSE DECOMPRESS DECORRELATE + DECR DECREMENT DECRYPT DEDUPLICATE DEFAULTS DEFAULT_COLLATION DEFAULT_PDB_HINT + DEFERRABLE DEFERRED DEFINE DEFINED DEFINER DEFINITION DEGREE DELAY DELEGATE + DELETEXML DELETE_ALL DEMAND DENORM_AV DENSE_RANK DENSE_RANKM DEPENDENT DEPTH + DEQUEUE DEREF DEREF_NO_REWRITE DESCENDANT DESCRIPTION DESTROY DETACHED DETERMINED + DETERMINES DETERMINISTIC DG_GATHER_STATS DIAGNOSTICS DICTIONARY DIGEST DIMENSION + DIMENSIONS DIRECT DIRECTORY DIRECT_LOAD DIRECT_PATH DISABLE DISABLE_ALL DISABLE_CONTAINERS_DEFAULT + DISABLE_CONTAINER_MAP DISABLE_PARALLEL_DML DISABLE_PRESET DISABLE_RPKE DISALLOW + DISASSOCIATE DISCARD DISCONNECT DISK DISKGROUP DISKS DISMOUNT DISTINGUISHED + DISTRIBUTE DISTRIBUTED DIST_AGG_PROLLUP_PUSHDOWN DML DML_UPDATE DOCFIDELITY + DOCUMENT DOMAIN_INDEX_FILTER DOMAIN_INDEX_NO_SORT DOMAIN_INDEX_SORT DOWNGRADE + DRAIN_TIMEOUT DRIVING_SITE DROP_COLUMN DROP_GROUP DST_UPGRADE_INSERT_CONV + DUMP DUPLICATE DUPLICATED DV DYNAMIC DYNAMIC_SAMPLING DYNAMIC_SAMPLING_EST_CDN + EACH EDITION EDITIONABLE EDITIONING EDITIONS ELAPSED_TIME ELEMENT ELIMINATE_JOIN + ELIMINATE_OBY ELIMINATE_OUTER_JOIN ELIMINATE_SQ ELIM_GROUPBY EM EMPTY EMPTY_BLOB + EMPTY_CLOB ENABLE ENABLE_ALL ENABLE_PARALLEL_DML ENABLE_PRESET ENCODE ENCODING + ENCRYPT ENCRYPTION END END_OUTLINE_DATA ENFORCE ENFORCED ENQUEUE ENTERPRISE + ENTITYESCAPING ENTRY EQUIPART EQUIVALENT ERROR ERRORS ERROR_ARGUMENT ERROR_ON_OVERLAP_TIME + ESCAPE ESTIMATE EVAL EVALNAME EVALUATE EVALUATION EVEN EVENTS EVERY EXCEPTION + EXCEPTIONS EXCHANGE EXCLUDE EXCLUDING EXECUTE EXEMPT EXISTING EXISTSNODE EXP + EXPAND EXPAND_GSET_TO_UNION EXPAND_TABLE EXPIRE EXPLAIN EXPLOSION EXPORT EXPRESS + EXPR_CORR_CHECK EXTEND EXTENDED EXTENDS EXTENT EXTENTS EXTERNAL EXTERNALLY + EXTRA EXTRACT EXTRACTCLOBXML EXTRACTVALUE FACILITY FACT FACTOR FACTORIZE_JOIN + FAILED FAILED_LOGIN_ATTEMPTS FAILGROUP FAILOVER FAILURE FALSE FAMILY FAR FAST + FBTSCAN FEATURE FEATURE_COMPARE FEATURE_DETAILS FEATURE_ID FEATURE_SET FEATURE_VALUE + FEDERATION FETCH FILE FILEGROUP FILESTORE FILESYSTEM_LIKE_LOGGING FILE_NAME_CONVERT + FILTER FINAL FINE FINISH FIRST FIRSTM FIRST_ROWS FIRST_VALUE FIXED_VIEW_DATA + FLAGGER FLASHBACK FLASH_CACHE FLEX FLOB FLOOR FLUSH FOLDER FOLLOWING FOLLOWS + FORCE FORCE_JSON_TABLE_TRANSFORM FORCE_SPATIAL FORCE_XML_QUERY_REWRITE FOREIGN + FOREVER FORMAT FORWARD FRAGMENT_NUMBER FREE FREELIST FREELISTS FREEPOOLS FRESH + FRESH_MV FROM_TZ FTP FULL FULL_OUTER_JOIN_TO_OUTER FUNCTION FUNCTIONS GATHER_OPTIMIZER_STATISTICS + GATHER_PLAN_STATISTICS GBY_CONC_ROLLUP GBY_PUSHDOWN GENERATED GET GLOBAL GLOBALLY + GLOBAL_NAME GLOBAL_TOPIC_ENABLED GOLDENGATE GOTO GRANTED GRANULAR GREATEST + GROUPING GROUPING_ID GROUPS GROUP_BY GROUP_ID GUARANTEE GUARANTEED GUARD H + HALF_YEARS HASH HASHING HASHKEYS HASHSET_BUILD HASH_AJ HASH_SJ HEADER HEAP + HELP HEXTORAW HEXTOREF HIDDEN HIDE HIERARCHICAL HIERARCHIES HIERARCHY HIER_ANCESTOR + HIER_CAPTION HIER_CHILDREN HIER_CHILD_COUNT HIER_COLUMN HIER_CONDITION HIER_DEPTH + HIER_DESCRIPTION HIER_HAS_CHILDREN HIER_LAG HIER_LEAD HIER_LEVEL HIER_MEMBER_NAME + HIER_MEMBER_UNIQUE_NAME HIER_ORDER HIER_PARENT HIER_WINDOW HIGH HINTSET_BEGIN + HINTSET_END HOST HOT HOUR HOURS HTTP HWM_BROKERED HYBRID ID IDENTIFIER IDENTITY + IDGENERATORS IDLE IDLE_TIME IF IGNORE IGNORE_OPTIM_EMBEDDED_HINTS IGNORE_ROW_ON_DUPKEY_INDEX + IGNORE_WHERE_CLAUSE ILM IMMEDIATE IMMUTABLE IMPACT IMPORT INACTIVE INACTIVE_ACCOUNT_TIME + INCLUDE INCLUDES INCLUDE_VERSION INCLUDING INCOMING INCR INCREMENT INCREMENTAL + INDENT INDEXED INDEXES INDEXING INDEXTYPE INDEXTYPES INDEX_ASC INDEX_COMBINE + INDEX_DESC INDEX_FFS INDEX_FILTER INDEX_JOIN INDEX_ROWS INDEX_RRS INDEX_RS + INDEX_RS_ASC INDEX_RS_DESC INDEX_SCAN INDEX_SKIP_SCAN INDEX_SS INDEX_SS_ASC + INDEX_SS_DESC INDEX_STATS INDICATOR INFINITE INFORMATIONAL INHERIT INITCAP + INITIAL INITIALIZED INITIALLY INITRANS INLINE INLINE_XMLTYPE_NT INLINE_XT + INMEMORY INMEMORY_PRUNING INNER INPLACE INSENSITIVE INSERTCHILDXML INSERTCHILDXMLAFTER + INSERTCHILDXMLBEFORE INSERTXMLAFTER INSERTXMLBEFORE INSTALL INSTANCE INSTANCES + INSTANTIABLE INSTANTLY INSTEAD INSTR INSTR2 INSTR4 INSTRB INSTRC INTERLEAVED + INTERMEDIATE INTERNAL_CONVERT INTERNAL_USE INTERPRETED INTRA_CDB INVALIDATE + INVALIDATION INVISIBLE IN_MEMORY_METADATA IN_XQUERY IOSEEKTIM IOTFRSPEED IO_LOGICAL + IO_MEGABYTES IO_REQUESTS ISOLATE ISOLATION ISOLATION_LEVEL ITERATE ITERATION_NUMBER + JAVA JOB JOIN JSON JSONGET JSONPARSE JSONTOXML JSON_ARRAY JSON_ARRAYAGG JSON_EQUAL + JSON_EQUAL2 JSON_EXISTS JSON_EXISTS2 JSON_HASH JSON_LENGTH JSON_MERGEPATCH + JSON_MKMVI JSON_OBJECT JSON_OBJECTAGG JSON_PATCH JSON_QUERY JSON_SCALAR JSON_SERIALIZE + JSON_TABLE JSON_TEXTCONTAINS JSON_TEXTCONTAINS2 JSON_TRANSFORM JSON_VALUE + KEEP KEEP_DUPLICATES KERBEROS KEY KEYS KEYSIZE KEYSTORE KEY_LENGTH KILL + KURTOSIS_POP KURTOSIS_SAMP LABEL LAG LAG_DIFF LAG_DIFF_PERCENT LANGUAGE LAST + LAST_DAY LAST_VALUE LATERAL LAX LAYER LDAP_REGISTRATION LDAP_REGISTRATION_ENABLED + LDAP_REG_SYNC_INTERVAL LEAD LEADING LEAD_CDB LEAD_CDB_URI LEAD_DIFF LEAD_DIFF_PERCENT + LEAF LEAST LEAVES LEDGER LEFT LENGTH LENGTH2 LENGTH4 LENGTHB LENGTHC LESS + LEVEL LEVELS LIBRARY LIFE LIFECYCLE LIFETIME LIKE2 LIKE4 LIKEC LIMIT LINEAR + LINK LIST LISTAGG LN LNNVL LOAD LOB LOBNVL LOBS LOB_VALUE LOCALTIME LOCALTIMESTAMP + LOCAL_INDEXES LOCATION LOCATOR LOCKDOWN LOCKED LOCKING LOG LOGFILE LOGFILES + LOGGING LOGICAL LOGICAL_READS_PER_CALL LOGICAL_READS_PER_SESSION LOGMINING + LOGOFF LOGON LOG_READ_ONLY_VIOLATIONS LOST LOW LOWER LPAD LTRIM MAIN MAKE_REF + MANAGE MANAGED MANAGEMENT MANAGER MANDATORY MANUAL MAP MAPPER MAPPING MASTER + MATCH MATCHED MATCHES MATCH_NUMBER MATCH_RECOGNIZE MATERIALIZE MATERIALIZED + MATRIX MAX MAXARCHLOGS MAXDATAFILES MAXEXTENTS MAXIMIZE MAXINSTANCES MAXLOGFILES + MAXLOGHISTORY MAXLOGMEMBERS MAXSIZE MAXTRANS MAXVALUE MAX_AUDIT_SIZE MAX_DIAG_SIZE + MAX_PDB_SNAPSHOTS MAX_SHARED_TEMP_SIZE MBRC MEASURE MEASURES MEDIAN MEDIUM + MEMBER MEMCOMPRESS MEMOPTIMIZE MEMOPTIMIZE_WRITE MEMORY MERGE MERGE$ACTIONS + MERGE_AJ MERGE_CONST_ON MERGE_SJ METADATA METADATA_SOURCE_PDB METHOD MIGRATE + MIGRATE_CROSS_CON MIGRATION MIN MINEXTENTS MINIMIZE MINIMUM MINING MINUS_NULL + MINUTE MINUTES MINVALUE MIRROR MIRRORCOLD MIRRORHOT MISMATCH MISSING MLE MLSLABEL + MOD MODEL MODEL_COMPILE_SUBQUERY MODEL_DONTVERIFY_UNIQUENESS MODEL_DYNAMIC_SUBQUERY + MODEL_MIN_ANALYSIS MODEL_NB MODEL_NO_ANALYSIS MODEL_PBY MODEL_PUSH_REF MODEL_SV + MODIFICATION MODIFY MODIFY_COLUMN_TYPE MODULE MONITOR MONITORING MONTHS MONTHS_BETWEEN + MOUNT MOUNTPATH MOUNTPOINT MOVE MOVEMENT MULTIDIMENSIONAL MULTISET MULTIVALUE + MV_MERGE NAME NAMED NAMES NAMESPACE NAN NANVL NATIVE NATIVE_FULL_OUTER_JOIN + NATURAL NAV NCHAR_CS NCHR NEEDED NEG NESTED NESTED_ROLLUP_TOP NESTED_TABLE_FAST_INSERT + NESTED_TABLE_GET_REFS NESTED_TABLE_ID NESTED_TABLE_SET_REFS NESTED_TABLE_SET_SETID + NETWORK NEVER NEW NEW_TIME NEXT NEXT_DAY NLJ_BATCHING NLJ_INDEX_FILTER NLJ_INDEX_SCAN + NLJ_PREFETCH NLSSORT NLS_CALENDAR NLS_CHARACTERSET NLS_CHARSET_DECL_LEN NLS_CHARSET_ID + NLS_CHARSET_NAME NLS_COLLATION_ID NLS_COLLATION_NAME NLS_COMP NLS_CURRENCY + NLS_DATE_FORMAT NLS_DATE_LANGUAGE NLS_INITCAP NLS_ISO_CURRENCY NLS_LANG NLS_LANGUAGE + NLS_LENGTH_SEMANTICS NLS_LOWER NLS_NCHAR_CONV_EXCP NLS_NUMERIC_CHARACTERS + NLS_SORT NLS_SPECIAL_CHARS NLS_TERRITORY NLS_UPPER NL_AJ NL_SJ NO NOAPPEND + NOARCHIVELOG NOAUDIT NOCACHE NOCOPY NOCPU_COSTING NOCYCLE NODELAY NOENTITYESCAPING + NOEXTEND NOFORCE NOGUARANTEE NOKEEP NOLOCAL NOLOGGING NOMAPPING NOMAXVALUE + NOMINIMIZE NOMINVALUE NOMONITORING NONBLOCKING NONE NONEDITIONABLE NONPARTITIONED + NONSCHEMA NOORDER NOOVERRIDE NOPARALLEL NOPARALLEL_INDEX NORELOCATE NORELY + NOREPAIR NOREPLAY NORESETLOGS NOREVERSE NOREWRITE NORMAL NOROWDEPENDENCIES + NOSCALE NOSCHEMACHECK NOSEGMENT NOSHARD NOSORT NOSTRICT NOSWITCH NOTHING NOTIFICATION + NOVALIDATE NOW NO_ACCESS NO_ADAPTIVE_PLAN NO_ANSI_REARCH NO_ANSWER_QUERY_USING_STATS + NO_AUTO_REOPTIMIZE NO_BAND_JOIN NO_BASETABLE_MULTIMV_REWRITE NO_BATCH_TABLE_ACCESS_BY_ROWID + NO_BIND_AWARE NO_BUFFER NO_BUSHY_JOIN NO_CARTESIAN NO_CHECK_ACL_REWRITE NO_CLUSTERING + NO_CLUSTER_BY_ROWID NO_COALESCE_SQ NO_COMMON_DATA NO_CONNECT_BY_CB_WHR_ONLY + NO_CONNECT_BY_COMBINE_SW NO_CONNECT_BY_COST_BASED NO_CONNECT_BY_ELIM_DUPS + NO_CONNECT_BY_FILTERING NO_CONTAINERS NO_COST_XML_QUERY_REWRITE NO_CPU_COSTING + NO_CROSS_CONTAINER NO_DAGG_OPTIM_GSETS NO_DATA_SECURITY_REWRITE NO_DECORRELATE + NO_DIST_AGG_PROLLUP_PUSHDOWN NO_DOMAIN_INDEX_FILTER NO_DST_UPGRADE_INSERT_CONV + NO_ELIMINATE_JOIN NO_ELIMINATE_OBY NO_ELIMINATE_OUTER_JOIN NO_ELIMINATE_SQ + NO_ELIM_GROUPBY NO_EXPAND NO_EXPAND_GSET_TO_UNION NO_EXPAND_TABLE NO_FACT + NO_FACTORIZE_JOIN NO_FILTERING NO_FULL_OUTER_JOIN_TO_OUTER NO_GATHER_OPTIMIZER_STATISTICS + NO_GBY_PUSHDOWN NO_INDEX NO_INDEX_FFS NO_INDEX_SS NO_INMEMORY NO_INMEMORY_PRUNING + NO_JSON_TABLE_TRANSFORM NO_LOAD NO_MERGE NO_MODEL_PUSH_REF NO_MONITOR NO_MONITORING + NO_MULTIMV_REWRITE NO_NATIVE_FULL_OUTER_JOIN NO_NLJ_BATCHING NO_NLJ_PREFETCH + NO_OBJECT_LINK NO_OBY_GBYPD_SEPARATE NO_ORDER_ROLLUPS NO_OR_EXPAND NO_OUTER_JOIN_TO_ANTI + NO_OUTER_JOIN_TO_INNER NO_PARALLEL NO_PARALLEL_INDEX NO_PARTIAL_COMMIT NO_PARTIAL_JOIN + NO_PARTIAL_OSON_UPDATE NO_PARTIAL_ROLLUP_PUSHDOWN NO_PLACE_DISTINCT NO_PLACE_GROUP_BY + NO_PQ_CONCURRENT_UNION NO_PQ_EXPAND_TABLE NO_PQ_MAP NO_PQ_NONLEAF_SKEW NO_PQ_REPLICATE + NO_PQ_SKEW NO_PRUNE_GSETS NO_PULL_PRED NO_PUSH_HAVING_TO_GBY NO_PUSH_PRED + NO_PUSH_SUBQ NO_PX_FAULT_TOLERANCE NO_PX_JOIN_FILTER NO_QKN_BUFF NO_QUERY_TRANSFORMATION + NO_REF_CASCADE NO_REORDER_WIF NO_RESULT_CACHE NO_REWRITE NO_ROOT_SW_FOR_LOCAL + NO_SEMIJOIN NO_SEMI_TO_INNER NO_SET_GBY_PUSHDOWN NO_SET_TO_JOIN NO_SQL_TRANSLATION + NO_SQL_TUNE NO_STAR_TRANSFORMATION NO_STATEMENT_QUEUING NO_STATS_GSETS NO_SUBQUERY_PRUNING + NO_SUBSTRB_PAD NO_SWAP_JOIN_INPUTS NO_TABLE_LOOKUP_BY_NL NO_TEMP_TABLE NO_TRANSFORM_DISTINCT_AGG + NO_UNNEST NO_USE_CUBE NO_USE_DAGG_UNION_ALL_GSETS NO_USE_HASH NO_USE_HASH_AGGREGATION + NO_USE_HASH_GBY_FOR_DAGGPSHD NO_USE_HASH_GBY_FOR_PUSHDOWN NO_USE_INVISIBLE_INDEXES + NO_USE_MERGE NO_USE_NL NO_USE_PARTITION_WISE_DISTINCT NO_USE_PARTITION_WISE_GBY + NO_USE_PARTITION_WISE_WIF NO_USE_SCALABLE_GBY_INVDIST NO_USE_VECTOR_AGGREGATION + NO_VECTOR_TRANSFORM NO_VECTOR_TRANSFORM_DIMS NO_VECTOR_TRANSFORM_FACT NO_XDB_FASTPATH_INSERT + NO_XMLINDEX_REWRITE NO_XMLINDEX_REWRITE_IN_SELECT NO_XML_DML_REWRITE NO_XML_QUERY_REWRITE + NO_ZONEMAP NTH_VALUE NTILE NULLIF NULLS NUMTODSINTERVAL NUMTOYMINTERVAL NUM_INDEX_KEYS + NVL NVL2 OBJECT OBJECT2XML OBJNO OBJNO_REUSE OBJ_ID OBY_GBYPD_SEPARATE OCCURENCES + OCCURRENCES ODD OFF OFFLINE OFFSET OID OIDINDEX OLAP OLD OLD_PUSH_PRED OLS + OLTP OMIT ONE ONLINE ONLY OPAQUE OPAQUE_TRANSFORM OPAQUE_XCANONICAL OPCODE + OPEN OPERATIONS OPERATOR OPTIMAL OPTIMIZE OPTIMIZER_FEATURES_ENABLE OPTIMIZER_GOAL + OPT_ESTIMATE OPT_PARAM ORADEBUG ORA_BRANCH ORA_CHECK_ACL ORA_CHECK_PRIVILEGE + ORA_CHECK_SYS_PRIVILEGE ORA_CLUSTERING ORA_CONCAT_RWKEY ORA_DM_PARTITION_NAME + ORA_DST_AFFECTED ORA_DST_CONVERT ORA_DST_ERROR ORA_GET_ACLIDS ORA_GET_PRIVILEGES + ORA_HASH ORA_INVOKING_USER ORA_INVOKING_USERID ORA_INVOKING_XS_USER ORA_INVOKING_XS_USER_GUID + ORA_NORMALIZE ORA_PARTITION_VALIDATION ORA_RAWCOMPARE ORA_RAWCONCAT ORA_ROWSCN + ORA_ROWSCN_RAW ORA_ROWVERSION ORA_SEARCH_RWKEY ORA_SHARDSPACE_NAME ORA_SHARD_ID + ORA_TABVERSION ORA_WRITE_TIME ORDERED ORDERED_PREDICATES ORDER_KEY_VECTOR_USE + ORDER_SUBQ ORDINALITY ORGANIZATION OR_EXPAND OR_PREDICATES OSON OSON_DIAG + OSON_GET_CONTENT OTHER OTHERS OUTER OUTER_JOIN_TO_ANTI OUTER_JOIN_TO_INNER + OUTLINE OUTLINE_LEAF OUT_OF_LINE OVER OVERFLOW OVERFLOW_NOMOVE OVERLAPS OWN + OWNER OWNERSHIP PACKAGE PACKAGES PARALLEL PARALLEL_INDEX PARAM PARAMETERS + PARENT PARITY PART$NUM$INST PARTIAL PARTIALLY PARTIAL_JOIN PARTIAL_ROLLUP_PUSHDOWN + PARTITION PARTITIONING PARTITIONS PARTITIONSET PARTITION_CONTAINED PARTITION_HASH + PARTITION_LIST PARTITION_RANGE PASSING PASSIVE PASSWORD PASSWORDFILE_METADATA_CACHE + PASSWORD_GRACE_TIME PASSWORD_LIFE_TIME PASSWORD_LOCK_TIME PASSWORD_REUSE_MAX + PASSWORD_REUSE_TIME PASSWORD_ROLLOVER_TIME PASSWORD_VERIFY_FUNCTION PAST PATCH + PATH PATHS PATH_PREFIX PATTERN PBL_HS_BEGIN PBL_HS_END PCTINCREASE PCTTHRESHOLD + PCTUSED PCTVERSION PDB_LOCAL_ONLY PEER PEERS PENDING PER PERCENT PERCENTAGE + PERCENTILE_CONT PERCENTILE_DISC PERCENT_RANK PERCENT_RANKM PERFORMANCE PERIOD + PERMANENT PERMISSION PERMUTE PERSISTABLE PFILE PHV PHYSICAL PIKEY PIVOT PIV_GB + PIV_SSF PLACE_DISTINCT PLACE_GROUP_BY PLAN PLSCOPE_SETTINGS PLSQL_CCFLAGS + PLSQL_CODE_TYPE PLSQL_DEBUG PLSQL_OPTIMIZE_LEVEL PLSQL_WARNINGS PLUGGABLE + PMEM POINT POLICY POOL_16K POOL_2K POOL_32K POOL_4K POOL_8K PORT POSITION + POST_TRANSACTION POWER POWERMULTISET POWERMULTISET_BY_CARDINALITY PQ_CONCURRENT_UNION + PQ_DISTRIBUTE PQ_DISTRIBUTE_WINDOW PQ_EXPAND_TABLE PQ_FILTER PQ_MAP PQ_NOMAP + PQ_NONLEAF_SKEW PQ_REPLICATE PQ_SKEW PREBUILT PRECEDES PRECEDING PRECOMPUTE_SUBQUERY + PREDICATE_REORDERS PREDICTION PREDICTION_BOUNDS PREDICTION_COST PREDICTION_DETAILS + PREDICTION_PROBABILITY PREDICTION_SET PRELOAD PREPARE PRESENT PRESENTNNV PRESENTV + PRESERVE PRESERVE_OID PRETTY PREV PREVIOUS PRIMARY PRINTBLOBTOCLOB PRIORITY + PRIVATE PRIVATE_SGA PRIVILEGE PRIVILEGED PRIVILEGES PROCEDURAL PROCEDURE PROCESS + PROFILE PROGRAM PROJECT PROPAGATE PROPAGATION PROPERTY PROTECTED PROTECTION + PROTOCOL PROXY PRUNING PULL_PRED PURGE PUSH_HAVING_TO_GBY PUSH_PRED PUSH_SUBQ + PX_FAULT_TOLERANCE PX_GRANULE PX_JOIN_FILTER QB_NAME QUALIFY QUARANTINE QUARTERS + QUERY QUERY_BLOCK QUEUE QUEUE_CURR QUEUE_ROWP QUIESCE QUORUM QUOTA QUOTAGROUP + QUOTES RANDOM RANDOM_LOCAL RANGE RANK RANKM RAPIDLY RATIO_TO_REPORT RAWTOHEX + RAWTONHEX RAWTOREF RBA RBO_OUTLINE RDBA READ READS READ_OR_WRITE REALM REBALANCE + REBUILD RECONNECT RECORDS_PER_BLOCK RECOVER RECOVERABLE RECOVERY RECYCLE RECYCLEBIN + REDACTION REDEFINE REDO REDUCED REDUNDANCY REFERENCE REFERENCED REFERENCES + REFERENCING REFRESH REFTOHEX REFTORAW REF_CASCADE_CURSOR REGEXP_COUNT REGEXP_INSTR + REGEXP_LIKE REGEXP_REPLACE REGEXP_SUBSTR REGISTER REGR_AVGX REGR_AVGY REGR_COUNT + REGR_INTERCEPT REGR_R2 REGR_SLOPE REGR_SXX REGR_SXY REGR_SYY REGULAR REJECT + REKEY RELATIONAL RELOCATE RELY REMAINDER REMOTE REMOTE_MAPPED REMOVE REORDER_WIF + REPAIR REPEAT REPLACE REPLICATION REQUIRED RESERVOIR_SAMPLING RESET RESETLOGS + RESIZE RESOLVE RESOLVER RESPECT RESTART RESTORE RESTORE_AS_INTERVALS RESTRICT + RESTRICTED RESTRICT_ALL_REF_CONS RESULT_CACHE RESUMABLE RESUME RETENTION RETRY_ON_ROW_CHANGE + RETURN RETURNING REUSE REVERSE REWRITE REWRITE_OR_ERROR RIGHT RLS_FORCE ROLE + ROLES ROLESET ROLLBACK ROLLING ROLLOVER ROLLUP ROOT ROUND ROUND_TIES_TO_EVEN + ROW ROWDEPENDENCIES ROWIDTOCHAR ROWIDTONCHAR ROWID_MAPPING_TABLE ROWNUM ROWS + ROW_LENGTH ROW_NUMBER RPAD RTRIM RULE RULES RUNNING SALT SAMPLE SAVE SAVEPOINT + SAVE_AS_INTERVALS SB4 SCALAR SCALARS SCALE SCALE_ROWS SCAN SCAN_INSTANCES + SCHEDULER SCHEMA SCHEMACHECK SCN SCN_ASCENDING SCOPE SCRUB SDO_GEOM_KEY SDO_GEOM_MAX_X + SDO_GEOM_MAX_Y SDO_GEOM_MAX_Z SDO_GEOM_MBB SDO_GEOM_MBR SDO_GEOM_MIN_X SDO_GEOM_MIN_Y + SDO_GEOM_MIN_Z SDO_TOLERANCE SD_ALL SD_INHIBIT SD_SHOW SEARCH SECONDS SECRET + SECUREFILE SECUREFILE_DBA SECURITY SEED SEGMENT SEG_BLOCK SEG_FILE SELECTIVITY + SELF SEMIJOIN SEMIJOIN_DRIVER SEMI_TO_INNER SENSITIVE SEQUENCE SEQUENCED SEQUENTIAL + SERIAL SERIALIZABLE SERVERERROR SERVICE SERVICES SERVICE_NAME_CONVERT SESSION + SESSIONS_PER_USER SESSIONTIMEZONE SESSIONTZNAME SESSION_CACHED_CURSORS SETS + SETTINGS SET_GBY_PUSHDOWN SET_TO_JOIN SEVERE SHARD SHARDED SHARDS SHARDSPACE + SHARD_CHUNK_ID SHARED SHARED_POOL SHARE_OF SHARING SHD$COL$MAP SHELFLIFE SHOW + SHRINK SHUTDOWN SIBLING SIBLINGS SID SIGN SIGNAL_COMPONENT SIGNAL_FUNCTION + SIGNATURE SIMPLE SIN SINGLE SINGLETASK SINH SITE SKEWNESS_POP SKEWNESS_SAMP + SKIP SKIP_EXT_OPTIMIZER SKIP_PROXY SKIP_UNQ_UNUSABLE_IDX SKIP_UNUSABLE_INDEXES + SMALLFILE SNAPSHOT SOME SORT SOUNDEX SOURCE SOURCE_FILE_DIRECTORY SOURCE_FILE_NAME_CONVERT + SPACE SPATIAL SPECIFICATION SPFILE SPLIT SPREADSHEET SQL SQLLDR SQL_SCOPE + SQL_TRACE SQL_TRANSLATION_PROFILE SQRT STALE STANDALONE STANDARD_HASH STANDBY + STANDBYS STANDBY_MAX_DATA_DELAY STAR STARTUP STAR_TRANSFORMATION STATE STATEMENT + STATEMENTS STATEMENT_ID STATEMENT_QUEUING STATIC STATISTICS STATS_BINOMIAL_TEST + STATS_CROSSTAB STATS_F_TEST STATS_KS_TEST STATS_MODE STATS_MW_TEST STATS_ONE_WAY_ANOVA + STATS_T_TEST_INDEP STATS_T_TEST_INDEPU STATS_T_TEST_ONE STATS_T_TEST_PAIRED + STATS_WSR_TEST STDDEV STDDEV_POP STDDEV_SAMP STOP STORAGE STORAGE_INDEX STORE + STREAM STREAMS STRICT STRING STRINGS STRIP STRIPE_COLUMNS STRIPE_WIDTH STRUCTURE + SUBMULTISET SUBPARTITION SUBPARTITIONING SUBPARTITIONS SUBPARTITION_REL SUBQUERIES + SUBQUERY_PRUNING SUBSCRIBE SUBSET SUBSTITUTABLE SUBSTR SUBSTR2 SUBSTR4 SUBSTRB + SUBSTRC SUBTYPE SUCCESS SUCCESSFUL SUM SUMMARY SUPPLEMENTAL SUPPRESS_LOAD + SUSPEND SWAP_JOIN_INPUTS SWITCH SWITCHOVER SYNC SYNCHRONOUS SYSASM SYSAUX + SYSBACKUP SYSDATE SYSDBA SYSDG SYSGUID SYSKM SYSOBJ SYSOPER SYSRAC SYSTEM + SYSTEM_DEFINED SYSTEM_STATS SYSTIMESTAMP SYS_AUDIT SYS_CHECKACL SYS_CHECK_PRIVILEGE + SYS_CONNECT_BY_PATH SYS_CONS_ANY_SCALAR SYS_CONTEXT SYS_CTXINFOPK SYS_CTX_CONTAINS2 + SYS_CTX_MKIVIDX SYS_DBURIGEN SYS_DL_CURSOR SYS_DM_RXFORM_CHR SYS_DM_RXFORM_LAB + SYS_DM_RXFORM_NUM SYS_DOM_COMPARE SYS_DST_PRIM2SEC SYS_DST_SEC2PRIM SYS_ET_BFILE_TO_RAW + SYS_ET_BLOB_TO_IMAGE SYS_ET_IMAGE_TO_BLOB SYS_ET_RAW_TO_BFILE SYS_EXTPDTXT + SYS_EXTRACT_UTC SYS_FBT_INSDEL SYS_FILTER_ACLS SYS_FNMATCHES SYS_FNREPLACE + SYS_GETTOKENID SYS_GETXTIVAL SYS_GET_ACLIDS SYS_GET_ANY_SCALAR SYS_GET_COL_ACLIDS + SYS_GET_PRIVILEGES SYS_GUID SYS_MAKEXML SYS_MAKE_XMLNODEID SYS_MKXMLATTR SYS_MKXTI + SYS_OPTLOBPRBSC SYS_OPTXICMP SYS_OPTXQCASTASNQ SYS_OP_ADT2BIN SYS_OP_ADTCONS + SYS_OP_ALSCRVAL SYS_OP_ATG SYS_OP_BIN2ADT SYS_OP_BITVEC SYS_OP_BL2R SYS_OP_BLOOM_FILTER + SYS_OP_BLOOM_FILTER_LIST SYS_OP_C2C SYS_OP_CAST SYS_OP_CEG SYS_OP_CL2C SYS_OP_COMBINED_HASH + SYS_OP_COMP SYS_OP_CONVERT SYS_OP_COUNTCHG SYS_OP_CSCONV SYS_OP_CSCONVTEST + SYS_OP_CSR SYS_OP_CSX_PATCH SYS_OP_CYCLED_SEQ SYS_OP_DECOMP SYS_OP_DESCEND + SYS_OP_DISTINCT SYS_OP_DRA SYS_OP_DSB_DESERIALIZE SYS_OP_DSB_SERIALIZE SYS_OP_DUMP + SYS_OP_DV_CHECK SYS_OP_ENFORCE_NOT_NULL$ SYS_OP_EXTRACT SYS_OP_GROUPING SYS_OP_GUID + SYS_OP_HASH SYS_OP_HCS_TABLE SYS_OP_IIX SYS_OP_INTERVAL_HIGH_BOUND SYS_OP_ITR + SYS_OP_KEY_VECTOR_CREATE SYS_OP_KEY_VECTOR_FILTER SYS_OP_KEY_VECTOR_FILTER_LIST + SYS_OP_KEY_VECTOR_PAYLOAD SYS_OP_KEY_VECTOR_SUCCEEDED SYS_OP_KEY_VECTOR_USE + SYS_OP_LBID SYS_OP_LOBLOC2BLOB SYS_OP_LOBLOC2CLOB SYS_OP_LOBLOC2ID SYS_OP_LOBLOC2NCLOB + SYS_OP_LOBLOC2TYP SYS_OP_LSVI SYS_OP_LVL SYS_OP_MAKEOID SYS_OP_MAP_NONNULL + SYS_OP_MSR SYS_OP_NICOMBINE SYS_OP_NIEXTRACT SYS_OP_NII SYS_OP_NIX SYS_OP_NOEXPAND + SYS_OP_NTCIMG$ SYS_OP_NUMTORAW SYS_OP_OBJ_UPD_IN_TXN SYS_OP_OIDVALUE SYS_OP_OPNSIZE + SYS_OP_PAR SYS_OP_PARGID SYS_OP_PARGID_1 SYS_OP_PART_ID SYS_OP_PAR_1 SYS_OP_PIVOT + SYS_OP_R2O SYS_OP_RAWTONUM SYS_OP_RDTM SYS_OP_REF SYS_OP_RMTD SYS_OP_ROWIDTOOBJ + SYS_OP_RPB SYS_OP_TOSETID SYS_OP_TPR SYS_OP_TRTB SYS_OP_UNDESCEND SYS_OP_VECAND + SYS_OP_VECBIT SYS_OP_VECOR SYS_OP_VECTOR_GROUP_BY SYS_OP_VECXOR SYS_OP_VERSION + SYS_OP_VREF SYS_OP_VVD SYS_OP_XMLCONS_FOR_CSX SYS_OP_XPTHATG SYS_OP_XPTHIDX + SYS_OP_XPTHOP SYS_OP_XTNN SYS_OP_XTXT2SQLT SYS_OP_ZONE_ID SYS_ORDERKEY_DEPTH + SYS_ORDERKEY_MAXCHILD SYS_ORDERKEY_PARENT SYS_PARALLEL_TXN SYS_PATHID_IS_ATTR + SYS_PATHID_IS_NMSPC SYS_PATHID_LASTNAME SYS_PATHID_LASTNMSPC SYS_PATH_REVERSE + SYS_PLSQL_COUNT SYS_PLSQL_CPU SYS_PLSQL_IO SYS_PXQEXTRACT SYS_RAW_TO_XSID + SYS_REMAP_XMLTYPE SYS_RID_ORDER SYS_ROW_DELTA SYS_SC_2_XMLT SYS_SYNRCIREDO + SYS_TYPEID SYS_UMAKEXML SYS_XMLANALYZE SYS_XMLCONTAINS SYS_XMLCONV SYS_XMLEXNSURI + SYS_XMLGEN SYS_XMLINSTR SYS_XMLI_LOC_ISNODE SYS_XMLI_LOC_ISTEXT SYS_XMLLOCATOR_GETSVAL + SYS_XMLNODEID SYS_XMLNODEID_GETCID SYS_XMLNODEID_GETLOCATOR SYS_XMLNODEID_GETOKEY + SYS_XMLNODEID_GETPATHID SYS_XMLNODEID_GETPTRID SYS_XMLNODEID_GETRID SYS_XMLNODEID_GETSVAL + SYS_XMLNODEID_GETTID SYS_XMLTRANSLATE SYS_XMLTYPE2SQL SYS_XMLT_2_SC SYS_XQBASEURI + SYS_XQCASTABLEERRH SYS_XQCODEP2STR SYS_XQCODEPEQ SYS_XQCON2SEQ SYS_XQCONCAT + SYS_XQDELETE SYS_XQDFLTCOLATION SYS_XQDOC SYS_XQDOCURI SYS_XQDURDIV SYS_XQED4URI + SYS_XQENDSWITH SYS_XQERR SYS_XQERRH SYS_XQESHTMLURI SYS_XQEXLOBVAL SYS_XQEXSTWRP + SYS_XQEXTRACT SYS_XQEXTRREF SYS_XQEXVAL SYS_XQFB2STR SYS_XQFNBOOL SYS_XQFNCMP + SYS_XQFNDATIM SYS_XQFNLNAME SYS_XQFNNM SYS_XQFNNSURI SYS_XQFNPREDTRUTH SYS_XQFNQNM + SYS_XQFNROOT SYS_XQFORMATNUM SYS_XQFTCONTAIN SYS_XQFUNCR SYS_XQGETCONTENT + SYS_XQINDXOF SYS_XQINSERT SYS_XQINSPFX SYS_XQIRI2URI SYS_XQLANG SYS_XQLLNMFRMQNM + SYS_XQMKNODEREF SYS_XQNILLED SYS_XQNODENAME SYS_XQNORMSPACE SYS_XQNORMUCODE + SYS_XQNSP4PFX SYS_XQNSPFRMQNM SYS_XQPFXFRMQNM SYS_XQPOLYABS SYS_XQPOLYADD + SYS_XQPOLYCEL SYS_XQPOLYCST SYS_XQPOLYCSTBL SYS_XQPOLYDIV SYS_XQPOLYFLR SYS_XQPOLYMOD + SYS_XQPOLYMUL SYS_XQPOLYRND SYS_XQPOLYSQRT SYS_XQPOLYSUB SYS_XQPOLYUMUS SYS_XQPOLYUPLS + SYS_XQPOLYVEQ SYS_XQPOLYVGE SYS_XQPOLYVGT SYS_XQPOLYVLE SYS_XQPOLYVLT SYS_XQPOLYVNE + SYS_XQREF2VAL SYS_XQRENAME SYS_XQREPLACE SYS_XQRESVURI SYS_XQRNDHALF2EVN SYS_XQRSLVQNM + SYS_XQRYENVPGET SYS_XQRYVARGET SYS_XQRYWRP SYS_XQSEQ2CON SYS_XQSEQ2CON4XC + SYS_XQSEQDEEPEQ SYS_XQSEQINSB SYS_XQSEQRM SYS_XQSEQRVS SYS_XQSEQSUB SYS_XQSEQTYPMATCH + SYS_XQSTARTSWITH SYS_XQSTATBURI SYS_XQSTR2CODEP SYS_XQSTRJOIN SYS_XQSUBSTRAFT + SYS_XQSUBSTRBEF SYS_XQTOKENIZE SYS_XQTREATAS SYS_XQXFORM SYS_XQ_ASQLCNV SYS_XQ_ATOMCNVCHK + SYS_XQ_NRNG SYS_XQ_PKSQL2XML SYS_XQ_UPKXML2SQL SYS_XSID_TO_RAW SYS_ZMAP_FILTER + SYS_ZMAP_REFRESH TABAUTH TABLES TABLESPACE TABLESPACE_NO TABLE_LOOKUP_BY_NL + TABLE_STATS TABNO TAG TAN TANH TARGET TBL$OR$IDX$PART$NUM TEMP TEMPFILE TEMPLATE + TEMPORARY TEMP_TABLE TENANT_ID TEST TEXT THAN THE THREAD THROUGH TIER TIES + TIMEOUT TIMES TIMESTAMP_TO_NUMBER TIMEZONE_ABBR TIMEZONE_HOUR TIMEZONE_MINUTE + TIMEZONE_OFFSET TIMEZONE_REGION TIME_ZONE TIV_GB TIV_SSF TOKEN TOPLEVEL TO_ACLID + TO_APPROX_COUNT_DISTINCT TO_APPROX_PERCENTILE TO_BINARY_DOUBLE TO_BINARY_FLOAT + TO_BLOB TO_CHAR TO_CLOB TO_DATE TO_DSINTERVAL TO_ISO_STRING TO_LOB TO_MULTI_BYTE + TO_NCHAR TO_NCLOB TO_NUMBER TO_SINGLE_BYTE TO_TIME TO_TIMESTAMP TO_TIMESTAMP_TZ + TO_TIME_TZ TO_UTC_TIMESTAMP_TZ TO_YMINTERVAL TRACE TRACING TRACKING TRAILING + TRANSACTION TRANSFORM TRANSFORM_DISTINCT_AGG TRANSITION TRANSITIONAL TRANSLATE + TRANSLATION TRANSPORTABLE TREAT TRIGGERS TRIM TRUE TRUNC TRUNCATE TRUST TRUSTED + TUNING TX TYPE TYPENAME TYPES TZ_OFFSET UB2 UBA UCS2 UID UNARCHIVED UNBOUND + UNBOUNDED UNCONDITIONAL UNDER UNDO UNDROP UNIFORM UNINSTALL UNION_ALL UNISTR + UNITE UNIXTIME UNLIMITED UNLOAD UNLOCK UNMATCHED UNNEST UNNEST_INNERJ_DISTINCT_VIEW + UNNEST_NOSEMIJ_NODISTINCTVIEW UNNEST_SEMIJ_VIEW UNPACKED UNPIVOT UNPLUG UNPROTECTED + UNQUIESCE UNRECOVERABLE UNRESTRICTED UNSUBSCRIBE UNTIL UNUSABLE UNUSED UPDATABLE + UPDATED UPDATEXML UPD_INDEXES UPD_JOININDEX UPGRADE UPPER UPSERT USABLE USAGE + USE USER USERENV USERGROUP USERS USER_DATA USER_DEFINED USER_RECYCLEBIN USER_TABLESPACES + USE_ANTI USE_CONCAT USE_CUBE USE_DAGG_UNION_ALL_GSETS USE_HASH USE_HASH_AGGREGATION + USE_HASH_GBY_FOR_DAGGPSHD USE_HASH_GBY_FOR_PUSHDOWN USE_HIDDEN_PARTITIONS + USE_INVISIBLE_INDEXES USE_MERGE USE_MERGE_CARTESIAN USE_NL USE_NL_WITH_INDEX + USE_PARTITION_WISE_DISTINCT USE_PARTITION_WISE_GBY USE_PARTITION_WISE_WIF + USE_PRIVATE_OUTLINES USE_SCALABLE_GBY_INVDIST USE_SEMI USE_STORED_OUTLINES + USE_TTT_FOR_GSETS USE_VECTOR_AGGREGATION USE_WEAK_NAME_RESL USING USING_NO_EXPAND + UTF16BE UTF16LE UTF32 UTF8 V1 V2 VALIDATE VALIDATE_CONVERSION VALIDATION VALID_TIME_END + VALUE VARIANCE VARRAY VARRAYS VAR_POP VAR_SAMP VECTOR VECTOR_ENCODE VECTOR_READ + VECTOR_READ_TRACE VECTOR_TRANSFORM VECTOR_TRANSFORM_DIMS VECTOR_TRANSFORM_FACT + VERIFIER VERIFY VERSION VERSIONING VERSIONS VERSIONS_ENDSCN VERSIONS_ENDTIME + VERSIONS_OPERATION VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_XID VIEWS + VIOLATION VIRTUAL VISIBILITY VISIBLE VOLUME VSIZE WAIT WALLET WEEK WEEKS WELLFORMED + WHEN WHENEVER WHITESPACE WIDTH_BUCKET WINDOW WITHIN WITHOUT WITH_EXPRESSION + WITH_PLSQL WORK WRAPPED WRAPPER WRITE XDB_FASTPATH_INSERT XID XML XML2OBJECT + XMLATTRIBUTES XMLCAST XMLCDATA XMLCOLATTVAL XMLCOMMENT XMLCONCAT XMLDIFF XMLELEMENT + XMLEXISTS XMLEXISTS2 XMLFOREST XMLINDEX_REWRITE XMLINDEX_REWRITE_IN_SELECT + XMLINDEX_SEL_IDX_TBL XMLISNODE XMLISVALID XMLNAMESPACES XMLPARSE XMLPATCH + XMLPI XMLQUERY XMLQUERYVAL XMLROOT XMLSCHEMA XMLSERIALIZE XMLTABLE XMLTOJSON + XMLTOKENSET XMLTRANSFORM XMLTRANSFORMBLOB XMLTSET_DML_ENABLE XML_DIAG XML_DML_RWT_STMT + XPATHTABLE XS XS_SYS_CONTEXT X_DYN_PRUNE YEARS YES ZONEMAP + )) + end + + def self.keywords_func + @keywords_func ||= Set.new(%w( + ABS ACOS ADD_MONTHS APPROX_COUNT APPROX_COUNT_DISTINCT APPROX_COUNT_DISTINCT_AGG + APPROX_COUNT_DISTINCT_DETAIL APPROX_MEDIAN APPROX_PERCENTILE APPROX_PERCENTILE_AGG + APPROX_PERCENTILE_DETAIL APPROX_RANK APPROX_SUM ASCII ASCIISTR ASIN ATAN ATAN2 + AVG BFILENAME BIN_TO_NUM BITAND CARDINALITY CAST CEIL CHARTOROWID CHR CLUSTER_DETAILS + CLUSTER_DISTANCE CLUSTER_ID CLUSTER_PROBABILITY CLUSTER_SET COALESCE COLLATION + COLLECT COMPOSE CONCAT CONVERT CON_DBID_TO_ID CON_GUID_TO_ID CON_NAME_TO_ID + CON_UID_TO_ID CORR COS COSH COUNT COVAR_POP COVAR_SAMP CUME_DIST CURRENT_DATE + CURRENT_TIMESTAMP CV DATAOBJ_TO_MAT_PARTITION DATAOBJ_TO_PARTITION DBTIMEZONE + DECODE DECOMPOSE DENSE_RANK DEPTH DEREF DUMP EMPTY_BLOB EMPTY_CLOB EXISTSNODE + EXP EXTRACT EXTRACTVALUE FEATURE_COMPARE FEATURE_DETAILS FEATURE_ID FEATURE_SET + FEATURE_VALUE FIRST FIRST_VALUE FLOOR FROM_TZ GREATEST GROUPING GROUPING_ID + GROUP_ID HEXTORAW INITCAP INSTR ITERATION_NUMBER JSON_ARRAY JSON_ARRAYAGG + JSON_OBJECT JSON_OBJECTAGG JSON_QUERY JSON_TABLE JSON_VALUE LAG LAST LAST_DAY + LAST_VALUE LEAD LEAST LENGTH LISTAGG LN LNNVL LOCALTIMESTAMP LOG LOWER LPAD + LTRIM MAKE_REF MAX MEDIAN MIN MOD MONTHS_BETWEEN NANVL NCHR NEW_TIME NEXT_DAY + NLSSORT NLS_CHARSET_DECL_LEN NLS_CHARSET_ID NLS_CHARSET_NAME NLS_COLLATION_ID + NLS_COLLATION_NAME NLS_INITCAP NLS_LOWER NLS_UPPER NTH_VALUE NTILE NULLIF + NUMTODSINTERVAL NUMTOYMINTERVAL NVL NVL2 ORA_DM_PARTITION_NAME ORA_DST_AFFECTED + ORA_DST_CONVERT ORA_DST_ERROR ORA_HASH ORA_INVOKING_USER ORA_INVOKING_USERID + PATH PERCENTILE_CONT PERCENTILE_DISC PERCENT_RANK POWER POWERMULTISET POWERMULTISET_BY_CARDINALITY + PREDICTION PREDICTION_BOUNDS PREDICTION_COST PREDICTION_DETAILS PREDICTION_PROBABILITY + PREDICTION_SET PRESENTNNV PRESENTV PREVIOUS RANK RATIO_TO_REPORT RAWTOHEX + RAWTONHEX REFTOHEX REGEXP_COUNT REGEXP_INSTR REGEXP_REPLACE REGEXP_SUBSTR + REMAINDER REPLACE ROUND ROUND ROWIDTOCHAR ROWIDTONCHAR ROW_NUMBER RPAD RTRIM + SCN_TO_TIMESTAMP SESSIONTIMEZONE SET SIGN SIN SINH SOUNDEX SQRT STANDARD_HASH + STATS_BINOMIAL_TEST STATS_CROSSTAB STATS_F_TEST STATS_KS_TEST STATS_MODE STATS_MW_TEST + STATS_ONE_WAY_ANOVA STATS_WSR_TEST STDDEV STDDEV_POP STDDEV_SAMP SUBSTR SUM + SYSDATE SYSTIMESTAMP SYS_CONNECT_BY_PATH SYS_CONTEXT SYS_DBURIGEN SYS_EXTRACT_UTC + SYS_GUID SYS_OP_ZONE_ID SYS_TYPEID SYS_XMLAGG SYS_XMLGEN TAN TANH TIMESTAMP_TO_SCN + TO_APPROX_COUNT_DISTINCT TO_APPROX_PERCENTILE TO_BINARY_DOUBLE TO_BINARY_FLOAT + TO_BLOB TO_CHAR TO_CLOB TO_DATE TO_DSINTERVAL TO_LOB TO_MULTI_BYTE TO_NCHAR + TO_NCLOB TO_NUMBER TO_SINGLE_BYTE TO_TIMESTAMP TO_TIMESTAMP_TZ TO_YMINTERVAL + TRANSLATE TREAT TRIM TRUNC TZ_OFFSET UID UNISTR UPPER USER USERENV VALIDATE_CONVERSION + VALUE VARIANCE VAR_POP VAR_SAMP VSIZE WIDTH_BUCKET XMLAGG XMLCAST XMLCDATA + XMLCOLATTVAL XMLCOMMENT XMLCONCAT XMLDIFF XMLELEMENT XMLEXISTS XMLFOREST XMLISVALID + XMLPARSE XMLPATCH XMLPI XMLQUERY XMLROOT XMLSEQUENCE XMLSERIALIZE XMLTABLE + XMLTRANSFORM + )) + end + + def self.keywords_type + @keywords_type ||= Set.new(%w( + CHAR BYTE VARCHAR2 NCHAR NVARCHAR2 + NUMBER FLOAT BINARY_FLOAT BINARY_DOUBLE + LONG RAW + DATE TIMESTAMP INTERVAL LOCAL TIME ZONE TO MONTH SECOND YEAR DAY + BLOB CLOB NCLOB BFILE + UROWID + CHARACTER VARYING VARCHAR NATIONAL CHARACTER + NUMERIC DECIMAL DEC INTEGER INT SMALLINT + FLOAT DOUBLE PRECISION REAL + SDO_GEOMETRY SDO_TOPO_GEOMETRY SDO_GEORASTER + REF ANYTYPE ANYDATA ANYDATASET XMLTYPE HTTPURITYPE XDBURITYPE DUBRITYPE + BOOLEAN PLS_INTEGER BINARY_INTEGER SIMPLE_FLOAT SIMPLE_INTEGER SIMPLE_DOUBLE SYS_REFCURSOR + )) + end + + state :root do + delimiter_map = { '{' => '}', '[' => ']', '(' => ')', '<' => '>' } + # eat whitespace including newlines + rule %r/\s+/m, Text + + # Comments + rule %r/--.*/, Comment::Single + rule %r(/\*), Comment::Multiline, :multiline_comments + + # literals + # Q' operator quoted string literal + rule %r/q'(.)/i do |m| + close = Regexp.escape(delimiter_map[m[1]] || m[1]) + # the opening q'X + token Operator + push do + rule %r/(?:#{close}[^']|[^#{close}]'|[^#{close}'])+/m, Str::Other + rule %r/#{close}'/, Operator, :pop! + end + end + rule %r/'/, Operator, :single_string + # A double-quoted string refers to a database object in our default SQL + rule %r/"/, Operator, :double_string + # preprocessor directive treated as special comment + rule %r/(\$(?:IF|THEN|ELSE|ELSIF|ERROR|END|(?:\$\$?[a-z]\w*)))(\s+)/im do + groups Comment::Preproc, Text + end + + # Numbers + rule %r/[+-]?(?:(?:\.\d+(?:[eE][+-]?\d+)?)|\d+\.(?:\d+(?:[eE][+-]?\d+)?)?)[fFdD]?/, Num::Float + rule %r/[+-]?\d+/, Num::Integer + + # Operators + # Special semi-operator, but this seems an appropriate classification + rule %r/%(?:TYPE|ROWTYPE|FOUND|ISOPEN|NOTFOUND|ROWCOUNT)\b/i, Name::Attribute + # longer ones come first on purpose! It matters to regex engine + rule %r/=>|\|\||\*\*|<<|>>|\.\.|<>|[:!~^<>]=|[-+%\/*=<>@&!^\[\]]/, Operator + rule %r/(NOT|AND|OR|LIKE|BETWEEN|IN)(\s)/im do + groups Operator::Word, Text + end + rule %r/(IS)(\s+)(?:(NOT)(\s+))?(NULL\b)/im do + groups Operator::Word, Text, Operator::Word, Text, Operator::Word + end + + # Punctuation + # special case of dot followed by a name. notice the lookahead assertion + rule %r/\.(?=\w)/ do + token Punctuation + push :dotnames + end + rule %r/[;:()\[\],.]/, Punctuation + + # Special processing for keywords with multiple contexts + # + # this madness is to keep the word "replace" from being treated as a builtin function in this context + rule %r/(create)(\s+)(?:(or)(\s+)(replace)(\s+))?(package|function|procedure|type)(?:(\s+)(body))?(\s+)([a-z][\w$]*)/im do + groups Keyword::Reserved, Text, Keyword::Reserved, Text, Keyword::Reserved, Text, Keyword::Reserved, Text, Keyword::Reserved, Text, Name + end + # similar for MERGE keywords + rule %r/(when)(\s+)(?:(not)(\s+))?(matched)(\s+)(then)(\s+)(update|insert)\b(?:(\s+)(set)(\s+))?/im do + groups Keyword::Reserved, Text, Keyword::Reserved, Text, Keyword::Reserved, Text, Keyword::Reserved, Text, Keyword::Reserved, Text, Keyword::Reserved, Text + end + + # + # General keyword classification with sepcial attention to names + # in a chained "dot" notation. + # + rule %r/([a-zA-Z][\w$]*)(\.(?=\w))?/ do |m| + if self.class.keywords_type.include? m[1].upcase + tok = Keyword::Type + elsif self.class.keywords_func.include? m[1].upcase + tok = Name::Function + elsif self.class.keywords_reserved.include? m[1].upcase + tok = Keyword::Reserved + elsif self.class.keywords.include? m[1].upcase + tok = Keyword + else + tok = Name + end + groups tok, Punctuation + + if m[2] == "." + push :dotnames + end + end + end + + state :multiline_comments do + rule %r/([*][^\/]|[^*])+/m, Comment::Multiline + rule %r([*]\/), Comment::Multiline, :pop! + end + + state :single_string do + rule %r/\\./, Str::Escape + rule %r/''/, Str::Escape + rule %r/'/, Operator, :pop! + rule %r/[^\\']+/m, Str::Single + end + + state :double_string do + rule %r/\\./, Str::Escape + rule %r/""/, Str::Escape + rule %r/"/, Operator, :pop! + rule %r/[^\\"]+/m, Name::Variable + end + + state :dotnames do + # if we are followed by a dot and another name, we are an ordinary name + rule %r/([a-zA-Z][\w\$]*)(\.(?=\w))/ do + groups Name, Punctuation + end + # this rule WILL be true if something pushed into our state. That is our state contract + rule %r/[a-zA-Z][\w\$]*/ do |m| + if self.class.keywords_func.include? m[0].upcase + # The Function lookup allows collection methods like COUNT, FIRST, LAST, etc.. to be + # classified correctly. Occasionally misidentifies ordinary names as builtin functions, + # but seems to be as correct as we can get without becoming a full blown parser + token Name::Function + else + token Name + end + pop! + end + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pony.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pony.rb new file mode 100644 index 0000000..b0510b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/pony.rb @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Pony < RegexLexer + tag 'pony' + filenames '*.pony' + + keywords = Set.new %w( + actor addressof and as + be break + class compiler_intrinsic consume continue + do + else elseif embed end error + for fun + if ifdef in interface is isnt + lambda let + match + new not + object + primitive + recover repeat return + struct + then this trait try type + until use + var + where while with + ) + + capabilities = Set.new %w( + box iso ref tag trn val + ) + + types = Set.new %w( + Number Signed Unsigned Float + I8 I16 I32 I64 I128 U8 U32 U64 U128 F32 F64 + EventID Align IntFormat NumberPrefix FloatFormat + Type + ) + + state :whitespace do + rule %r/\s+/m, Text + end + + state :root do + mixin :whitespace + rule %r/"""/, Str::Doc, :docstring + rule %r{//.*}, Comment::Single + rule %r{/(\\\n)?[*](.|\n)*?[*](\\\n)?/}, Comment::Multiline + rule %r/"/, Str, :string + rule %r([~!%^&*+=\|?:<>/-]), Operator + rule %r/(true|false|NULL)\b/, Name::Constant + rule %r{(?:[A-Z_][a-zA-Z0-9_]*)}, Name::Class + rule %r/[()\[\],.';]/, Punctuation + + # Numbers + rule %r/0[xX]([0-9a-fA-F_]*\.[0-9a-fA-F_]+|[0-9a-fA-F_]+)[pP][+\-]?[0-9_]+[fFL]?[i]?/, Num::Float + rule %r/[0-9_]+(\.[0-9_]+[eE][+\-]?[0-9_]+|\.[0-9_]*|[eE][+\-]?[0-9_]+)[fFL]?[i]?/, Num::Float + rule %r/\.(0|[1-9][0-9_]*)([eE][+\-]?[0-9_]+)?[fFL]?[i]?/, Num::Float + rule %r/0[xX][0-9a-fA-F_]+/, Num::Hex + rule %r/(0|[1-9][0-9_]*)([LUu]|Lu|LU|uL|UL)?/, Num::Integer + + rule %r/[a-z_][a-z0-9_]*/io do |m| + match = m[0] + + if capabilities.include?(match) + token Keyword::Declaration + elsif keywords.include?(match) + token Keyword::Reserved + elsif types.include?(match) + token Keyword::Type + else + token Name + end + end + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\([\\abfnrtv"']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})/, Str::Escape + rule %r/[^\\"\n]+/, Str + rule %r/\\\n/, Str + rule %r/\\/, Str # stray backslash + end + + state :docstring do + rule %r/"""/, Str::Doc, :pop! + rule %r/\n/, Str::Doc + rule %r/./, Str::Doc + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/postscript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/postscript.rb new file mode 100644 index 0000000..57e8b61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/postscript.rb @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# Adapted from pygments PostScriptLexer +module Rouge + module Lexers + class PostScript < RegexLexer + title "PostScript" + desc "The PostScript language (adobe.com/devnet/postscript.html)" + tag "postscript" + aliases "postscr", "postscript", "ps", "eps" + filenames "*.ps", "*.eps" + mimetypes "application/postscript" + + def self.detect?(text) + return true if /^%!/ =~ text + end + + delimiter = %s"()<>\[\]{}/%\s" + delimiter_end = Regexp.new("(?=[#{delimiter}])") + valid_name_chars = Regexp.new("[^#{delimiter}]") + valid_name = /#{valid_name_chars}+#{delimiter_end}/ + + # These keywords taken from + # + # Is there an authoritative list anywhere that doesn't involve + # trawling documentation? + keywords = %w/abs add aload arc arcn array atan begin + bind ceiling charpath clip closepath concat + concatmatrix copy cos currentlinewidth currentmatrix + currentpoint curveto cvi cvs def defaultmatrix + dict dictstackoverflow div dtransform dup end + exch exec exit exp fill findfont floor get + getinterval grestore gsave identmatrix idiv + idtransform index invertmatrix itransform length + lineto ln load log loop matrix mod moveto + mul neg newpath pathforall pathbbox pop print + pstack put quit rand rangecheck rcurveto repeat + restore rlineto rmoveto roll rotate round run + save scale scalefont setdash setfont setgray + setlinecap setlinejoin setlinewidth setmatrix + setrgbcolor shfill show showpage sin sqrt + stack stringwidth stroke strokepath sub syntaxerror + transform translate truncate typecheck undefined + undefinedfilename undefinedresult/ + + state :root do + # All comment types + rule %r'^%!.+?$', Comment::Preproc + rule %r'%%.*?$', Comment::Special + rule %r'(^%.*?$){2,}', Comment::Multiline + rule %r'%.*?$', Comment::Single + + # String literals are awkward; enter separate state. + rule %r'\(', Str, :stringliteral + + # References + rule %r'/#{valid_name}', Name::Variable + + rule %r'[{}<>\[\]]', Punctuation + + rule %r'(?:#{keywords.join('|')})#{delimiter_end}', Name::Builtin + + # Conditionals / flow control + rule %r'(eq|ne|g[et]|l[et]|and|or|not|if(?:else)?|for(?:all)?)#{delimiter_end}', Keyword::Reserved + rule %r'(false|true)#{delimiter_end}', Keyword::Constant + + # Numbers + rule %r'<[0-9A-Fa-f]+>#{delimiter_end}', Num::Hex + # Slight abuse: use Oct to signify any explicit base system + rule %r'[0-9]+\#(\-|\+)?([0-9]+\.?|[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)((e|E)[0-9]+)?#{delimiter_end}', Num::Oct + rule %r'(\-|\+)?([0-9]+\.?|[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)((e|E)[0-9]+)?#{delimiter_end}', Num::Float + rule %r'(\-|\+)?[0-9]+#{delimiter_end}', Num::Integer + + # Names + rule valid_name, Name::Function # Anything else is executed + + rule %r'\s+', Text + end + + state :stringliteral do + rule %r'[^()\\]+', Str + rule %r'\\', Str::Escape, :escape + rule %r'\(', Str, :stringliteral + rule %r'\)', Str, :pop! + end + + state :escape do + rule %r'[0-8]{3}|n|r|t|b|f|\\|\(|\)', Str::Escape, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/powershell.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/powershell.rb new file mode 100644 index 0000000..72bb0ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/powershell.rb @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + + class Powershell < RegexLexer + title 'powershell' + desc 'powershell' + tag 'powershell' + aliases 'posh', 'microsoftshell', 'msshell' + filenames '*.ps1', '*.psm1', '*.psd1', '*.psrc', '*.pssc' + mimetypes 'text/x-powershell' + + # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_cmdletbindingattribute?view=powershell-6 + ATTRIBUTES = %w( + ConfirmImpact DefaultParameterSetName HelpURI PositionalBinding + SupportsPaging SupportsShouldProcess + ) + + # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-6 + AUTO_VARS = %w( + \$\$ \$\? \$\^ \$_ + \$args \$ConsoleFileName \$Error \$Event \$EventArgs \$EventSubscriber + \$ExecutionContext \$false \$foreach \$HOME \$Host \$input \$IsCoreCLR + \$IsLinux \$IsMacOS \$IsWindows \$LastExitCode \$Matches \$MyInvocation + \$NestedPromptLevel \$null \$PID \$PROFILE \$PSBoundParameters \$PSCmdlet + \$PSCommandPath \$PSCulture \$PSDebugContext \$PSHOME \$PSItem + \$PSScriptRoot \$PSSenderInfo \$PSUICulture \$PSVersionTable \$PWD + \$REPORTERRORSHOWEXCEPTIONCLASS \$REPORTERRORSHOWINNEREXCEPTION + \$REPORTERRORSHOWSOURCE \$REPORTERRORSHOWSTACKTRACE + \$SENDER \$ShellId \$StackTrace \$switch \$this \$true + ).join('|') + + # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_reserved_words?view=powershell-6 + KEYWORDS = %w( + assembly exit process base filter public begin finally return break for + sequence catch foreach static class from switch command function throw + configuration hidden trap continue if try data in type define + inlinescript until do interface using dynamicparam module var else + namespace while elseif parallel workflow end param enum private + ).join('|') + + # https://devblogs.microsoft.com/scripting/powertip-find-a-list-of-powershell-type-accelerators/ + # ([PSObject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Get).Keys -join ' ' + KEYWORDS_TYPE = %w( + Alias AllowEmptyCollection AllowEmptyString AllowNull ArgumentCompleter + array bool byte char CmdletBinding datetime decimal double DscResource + float single guid hashtable int int32 int16 long int64 ciminstance + cimclass cimtype cimconverter IPEndpoint NullString OutputType + ObjectSecurity Parameter PhysicalAddress pscredential PSDefaultValue + pslistmodifier psobject pscustomobject psprimitivedictionary ref + PSTypeNameAttribute regex DscProperty sbyte string SupportsWildcards + switch cultureinfo bigint securestring timespan uint16 uint32 uint64 + uri ValidateCount ValidateDrive ValidateLength ValidateNotNull + ValidateNotNullOrEmpty ValidatePattern ValidateRange ValidateScript + ValidateSet ValidateTrustedData ValidateUserDrive version void + ipaddress DscLocalConfigurationManager WildcardPattern X509Certificate + X500DistinguishedName xml CimSession adsi adsisearcher wmiclass wmi + wmisearcher mailaddress scriptblock psvariable type psmoduleinfo + powershell runspacefactory runspace initialsessionstate psscriptmethod + psscriptproperty psnoteproperty psaliasproperty psvariableproperty + ).join('|') + + OPERATORS = %w( + -split -isplit -csplit -join -is -isnot -as -eq -ieq -ceq -ne -ine -cne + -gt -igt -cgt -ge -ige -cge -lt -ilt -clt -le -ile -cle -like -ilike + -clike -notlike -inotlike -cnotlike -match -imatch -cmatch -notmatch + -inotmatch -cnotmatch -contains -icontains -ccontains -notcontains + -inotcontains -cnotcontains -replace -ireplace -creplace -shl -shr -band + -bor -bxor -and -or -xor -not \+= -= \*= \/= %= + ).join('|') + + MULTILINE_KEYWORDS = %w( + synopsis description parameter example inputs outputs notes link + component role functionality forwardhelptargetname forwardhelpcategory + remotehelprunspace externalhelp + ).join('|') + + state :variable do + rule %r/#{AUTO_VARS}/, Name::Builtin::Pseudo + rule %r/(\$)(?:(\w+)(:))?(\w+|\{(?:[^`]|`.)+?\})/ do + groups Name::Variable, Name::Namespace, Punctuation, Name::Variable + end + rule %r/\$\w+/, Name::Variable + rule %r/\$\{(?:[^`]|`.)+?\}/, Name::Variable + end + + state :multiline do + rule %r/\.(?:#{MULTILINE_KEYWORDS})/i, Comment::Special + rule %r/#>/, Comment::Multiline, :pop! + rule %r/[^#.]+?/m, Comment::Multiline + rule %r/[#.]+/, Comment::Multiline + end + + state :interpol do + rule %r/\)/, Str::Interpol, :pop! + mixin :root + end + + state :dq do + # NB: "abc$" is literally the string abc$. + # Here we prevent :interp from interpreting $" as a variable. + rule %r/(?:\$#?)?"/, Str::Double, :pop! + rule %r/\$\(/, Str::Interpol, :interpol + rule %r/`$/, Str::Escape # line continuation + rule %r/`./, Str::Escape + rule %r/[^"`$]+/, Str::Double + mixin :variable + end + + state :sq do + rule %r/'/, Str::Single, :pop! + rule %r/[^']+/, Str::Single + end + + state :heredoc do + rule %r/(?:\$#?)?"@/, Str::Heredoc, :pop! + rule %r/\$\(/, Str::Interpol, :interpol + rule %r/`$/, Str::Escape # line continuation + rule %r/`./, Str::Escape + rule %r/[^"`$]+?/m, Str::Heredoc + rule %r/"+/, Str::Heredoc + mixin :variable + end + + state :class do + rule %r/\{/, Punctuation, :pop! + rule %r/\s+/, Text::Whitespace + rule %r/\w+/, Name::Class + rule %r/[:,]/, Punctuation + end + + state :expr do + mixin :comments + rule %r/"/, Str::Double, :dq + rule %r/'/, Str::Single, :sq + rule %r/@"/, Str::Heredoc, :heredoc + rule %r/@'.*?'@/m, Str::Heredoc + rule %r/\d*\.\d+/, Num::Float + rule %r/\d+/, Num::Integer + rule %r/@\{/, Punctuation, :hasht + rule %r/@\(/, Punctuation, :array + rule %r/{/, Punctuation, :brace + rule %r/\[/, Punctuation, :bracket + end + + state :hasht do + rule %r/\}/, Punctuation, :pop! + rule %r/=/, Operator + rule %r/[,;]/, Punctuation + mixin :expr + rule %r/\w+/, Name::Other + mixin :variable + end + + state :array do + rule %r/\s+/, Text::Whitespace + rule %r/\)/, Punctuation, :pop! + rule %r/[,;]/, Punctuation + mixin :expr + mixin :variable + end + + state :brace do + rule %r/[}]/, Punctuation, :pop! + mixin :root + end + + state :bracket do + rule %r/\]/, Punctuation, :pop! + rule %r/[A-Za-z]\w+\./, Name + rule %r/([A-Za-z]\w+)/ do |m| + if ATTRIBUTES.include? m[0] + token Name::Builtin::Pseudo + else + token Name + end + end + mixin :root + end + + state :parameters do + rule %r/`./m, Str::Escape + rule %r/\)/ do + token Punctuation + pop!(2) if in_state?(:interpol) # pop :parameters and :interpol + end + rule %r/\s*?\n/, Text::Whitespace, :pop! + rule %r/[;(){}\]]/, Punctuation, :pop! + rule %r/[|=]/, Operator, :pop! + rule %r/[\/\\~\w][-.:\/\\~\w]*/, Name::Other + rule %r/\w[-\w]+/, Name::Other + mixin :root + end + + state :comments do + rule %r/\s+/, Text::Whitespace + rule %r/#.*/, Comment + rule %r/<#/, Comment::Multiline, :multiline + end + + state :root do + mixin :comments + rule %r/#requires\s-version \d(?:\.\d+)?/, Comment::Preproc + + rule %r/\.\.(?=\.?\d)/, Operator + rule %r/(?:#{OPERATORS})\b/i, Operator + + rule %r/(class)(\s+)(\w+)/i do + groups Keyword::Reserved, Text::Whitespace, Name::Class + push :class + end + rule %r/(function)(\s+)(?:(\w+)(:))?(\w[-\w]+)/i do + groups Keyword::Reserved, Text::Whitespace, Name::Namespace, Punctuation, Name::Function + end + rule %r/(?:#{KEYWORDS})\b(?![-.])/i, Keyword::Reserved + + rule %r/-{1,2}\w+/, Name::Tag + + rule %r/(\.)?([-\w]+)(\[)/ do |m| + groups Operator, Name, Punctuation + push :bracket + end + + rule %r/([\/\\~[a-z]][-.:\/\\~\w]*)(\n)?/i do |m| + groups Name, Text::Whitespace + push :parameters + end + + rule %r/(\.)([-\w]+)(?:(\()|(\n))?/ do |m| + groups Operator, Name::Function, Punctuation, Text::Whitespace + push :parameters unless m[3].nil? + end + + rule %r/\?/, Name::Function, :parameters + + mixin :expr + mixin :variable + + rule %r/[-+*\/%=!.&|]/, Operator + rule %r/[{}(),:;]/, Punctuation + + rule %r/`$/, Str::Escape # line continuation + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/praat.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/praat.rb new file mode 100644 index 0000000..1dc78a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/praat.rb @@ -0,0 +1,438 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Praat < RegexLexer + title "Praat" + desc "The Praat scripting language (praat.org)" + + tag 'praat' + + filenames '*.praat', '*.proc', '*.psc' + + def self.detect?(text) + return true if text.shebang? 'praat' + end + + def self.keywords + @keywords ||= %w( + if then else elsif elif endif fi for from to endfor endproc while + endwhile repeat until select plus minus demo assert stopwatch + nocheck nowarn noprogress editor endeditor clearinfo + ) + end + + def self.functions_string + @functions_string ||= %w( + backslashTrigraphsToUnicode$ chooseDirectory$ chooseReadFile$ + chooseWriteFile$ date$ demoKey$ do$ environment$ extractLine$ extractWord$ + fixed$ info$ left$ mid$ percent$ readFile$ replace$ replace_regex$ right$ + selected$ string$ unicodeToBackslashTrigraphs$ + ) + end + + def self.functions_numeric + @functions_numeric ||= %w( + abs appendFile appendFileLine appendInfo appendInfoLine arccos arccosh + arcsin arcsinh arctan arctan2 arctanh barkToHertz beginPause + beginSendPraat besselI besselK beta beta2 binomialP binomialQ boolean + ceiling chiSquareP chiSquareQ choice comment cos cosh createDirectory + deleteFile demoClicked demoClickedIn demoCommandKeyPressed + demoExtraControlKeyPressed demoInput demoKeyPressed + demoOptionKeyPressed demoShiftKeyPressed demoShow demoWaitForInput + demoWindowTitle demoX demoY differenceLimensToPhon do editor endPause + endSendPraat endsWith erb erbToHertz erf erfc exitScript exp + extractNumber fileReadable fisherP fisherQ floor gaussP gaussQ hash + hertzToBark hertzToErb hertzToMel hertzToSemitones imax imin + incompleteBeta incompleteGammaP index index_regex integer invBinomialP + invBinomialQ invChiSquareQ invFisherQ invGaussQ invSigmoid invStudentQ + length ln lnBeta lnGamma log10 log2 max melToHertz min minusObject + natural number numberOfColumns numberOfRows numberOfSelected + objectsAreIdentical option optionMenu pauseScript + phonToDifferenceLimens plusObject positive randomBinomial randomGauss + randomInteger randomPoisson randomUniform real readFile removeObject + rindex rindex_regex round runScript runSystem runSystem_nocheck + selectObject selected semitonesToHertz sentence sentencetext sigmoid + sin sinc sincpi sinh soundPressureToPhon sqrt startsWith studentP + studentQ tan tanh text variableExists word writeFile writeFileLine + writeInfo writeInfoLine + ) + end + + def self.functions_array + @functions_array ||= %w( + linear# randomGauss# randomInteger# randomUniform# zero# + ) + end + + def self.functions_matrix + @functions_matrix ||= %w( + linear## mul## mul_fast## mul_metal## mul_nt## mul_tn## mul_tt## outer## peaks## + randomGamma## randomGauss## randomInteger## randomUniform## softmaxPerRow## + solve## transpose## zero## + ) + end + + def self.functions_string_vector + @functions_string_vector ||= %w( + empty$# fileNames$# folderNames$# readLinesFromFile$# splitByWhitespace$# + ) + end + + def self.functions_builtin + @functions_builtin ||= + self.functions_string | + self.functions_numeric | + self.functions_array | + self.functions_matrix | + self.functions_string_vector + end + + def self.objects + @objects ||= %w( + Activation AffineTransform AmplitudeTier Art Artword Autosegment + BarkFilter BarkSpectrogram CCA Categories Cepstrogram Cepstrum + Cepstrumc ChebyshevSeries ClassificationTable Cochleagram Collection + ComplexSpectrogram Configuration Confusion ContingencyTable Corpus + Correlation Covariance CrossCorrelationTable CrossCorrelationTableList + CrossCorrelationTables DTW DataModeler Diagonalizer Discriminant + Dissimilarity Distance Distributions DurationTier EEG ERP ERPTier + EditCostsTable EditDistanceTable Eigen Excitation Excitations + ExperimentMFC FFNet FeatureWeights FileInMemory FilesInMemory Formant + FormantFilter FormantGrid FormantModeler FormantPoint FormantTier + GaussianMixture HMM HMM_Observation HMM_ObservationSequence HMM_State + HMM_StateSequence HMMObservation HMMObservationSequence HMMState + HMMStateSequence Harmonicity ISpline Index Intensity IntensityTier + IntervalTier KNN KlattGrid KlattTable LFCC LPC Label LegendreSeries + LinearRegression LogisticRegression LongSound Ltas MFCC MSpline ManPages + Manipulation Matrix MelFilter MelSpectrogram MixingMatrix Movie Network + OTGrammar OTHistory OTMulti PCA PairDistribution ParamCurve Pattern + Permutation Photo Pitch PitchModeler PitchTier PointProcess Polygon + Polynomial PowerCepstrogram PowerCepstrum Procrustes RealPoint RealTier + ResultsMFC Roots SPINET SSCP SVD Salience ScalarProduct Similarity + SimpleString SortedSetOfString Sound Speaker Spectrogram Spectrum + SpectrumTier SpeechSynthesizer SpellingChecker Strings StringsIndex + Table TableOfReal TextGrid TextInterval TextPoint TextTier Tier + Transition VocalTract VocalTractTier Weight WordList + ) + end + + def self.variables_numeric + @variables_numeric ||= %w( + all average e left macintosh mono pi praatVersion right stereo + undefined unix windows + ) + end + + def self.variables_string + @variables_string ||= %w( + praatVersion$ tab$ shellDirectory$ homeDirectory$ + preferencesDirectory$ newline$ temporaryDirectory$ + defaultDirectory$ + ) + end + + def self.object_attributes + @object_attributes ||= %w( + ncol nrow xmin ymin xmax ymax nx ny dx dy + ) + end + + state :root do + rule %r/(\s+)(#.*?$)/ do + groups Text, Comment::Single + end + + rule %r/^#.*?$/, Comment::Single + rule %r/;[^\n]*/, Comment::Single + rule %r/\s+/, Text + + rule %r/(\bprocedure)(\s+)/ do + groups Keyword, Text + push :procedure_definition + end + + rule %r/(\bcall)(\s+)/ do + groups Keyword, Text + push :procedure_call + end + + rule %r/@/, Name::Function, :procedure_call + + mixin :function_call + + rule %r/\b(?:select all)\b/, Keyword + + rule %r/(\bform\b)(\s+)([^\n]+)/ do + groups Keyword, Text, Literal::String + push :old_form + end + + rule %r/(print(?:line|tab)?|echo|exit|asserterror|pause|send(?:praat|socket)|include|execute|system(?:_nocheck)?)(\s+)/ do + groups Keyword, Text + push :string_unquoted + end + + rule %r/(goto|label)(\s+)(\w+)/ do + groups Keyword, Text, Name::Label + end + + mixin :variable_name + mixin :number + mixin :vector_literal + + rule %r/"/, Literal::String, :string + + rule %r/\b([A-Z][a-zA-Z0-9]+)(?=\s+\S+\n)/ do |m| + match = m[0] + if self.class.objects.include?(match) + token Name::Class + push :string_unquoted + else + token Keyword + end + end + + rule %r/\b(?=[A-Z])/, Text, :command + rule %r/(\.{3}|[)(,\$])/, Punctuation + + rule %r/[a_z]+/ do |m| + match = m[0] + if self.class.keywords.include?(match) + token Keyword + else + token Text + end + end + end + + state :command do + rule %r/( ?([^\s:\.'])+ ?)/, Keyword + mixin :string_interpolated + + rule %r/\.{3}/ do + token Keyword + pop! + push :old_arguments + end + + rule %r/:/ do + token Keyword + pop! + push :comma_list + end + + rule %r/[\s]/, Text, :pop! + end + + state :procedure_call do + mixin :string_interpolated + + rule %r/(:|\s*\()/, Punctuation, :pop! + + rule %r/'/, Name::Function + rule %r/[^:\('\s]+/, Name::Function + + rule %r/(?=\s+)/ do + token Text + pop! + push :old_arguments + end + end + + state :procedure_definition do + rule %r/(:|\s*\()/, Punctuation, :pop! + + rule %r/[^:\(\s]+/, Name::Function + + rule %r/(\s+)/, Text, :pop! + end + + state :function_call do + rule %r/\b([a-z][a-zA-Z0-9_.]+)(\$#|##|\$|#)?(?=\s*[:(])/ do |m| + match = m[0] + if self.class.functions_builtin.include?(match) + token Name::Function + push :function + elsif self.class.keywords.include?(match) + token Keyword + else + token Operator::Word + end + end + end + + state :function do + rule %r/\s+/, Text + + rule %r/(?::|\s*\()/ do + token Text + pop! + push :comma_list + end + end + + state :comma_list do + rule %r/(\s*\n\s*)(\.{3})/ do + groups Text, Punctuation + end + + rule %r/\s*[\]\})\n]/, Text, :pop! + + rule %r/\s+/, Text + rule %r/"/, Literal::String, :string + rule %r/\b(if|then|else|fi|endif)\b/, Keyword + + mixin :function_call + mixin :variable_name + mixin :operator + mixin :number + mixin :vector_literal + + rule %r/[()]/, Text + rule %r/,/, Punctuation + end + + state :old_arguments do + rule %r/\n/, Text, :pop! + + mixin :variable_name + mixin :operator + mixin :number + + rule %r/"/, Literal::String, :string + rule %r/[^\n]/, Text + end + + state :number do + rule %r/\n/, Text, :pop! + rule %r/\b\d+(\.\d*)?([eE][-+]?\d+)?%?/, Literal::Number + end + + state :variable_name do + mixin :operator + mixin :number + + rule %r/\b([A-Z][a-zA-Z0-9]+)_/ do |m| + match = m[1] + if (['Object'] | self.class.objects).include?(match) + token Name::Builtin + push :object_reference + else + token Name::Variable + end + end + + rule %r/\.?[a-z][a-zA-Z0-9_.]*(\$#|##|\$|#)?/ do |m| + match = m[0] + if self.class.variables_string.include?(match) || + self.class.variables_numeric.include?(match) + token Name::Builtin + elsif self.class.keywords.include?(match) + token Keyword + else + token Name::Variable + end + end + + rule %r/[\[\]]/, Text, :comma_list + mixin :string_interpolated + end + + state :vector_literal do + rule %r/(\{)/, Text, :comma_list + end + + state :object_reference do + mixin :string_interpolated + rule %r/([a-z][a-zA-Z0-9_]*|\d+)/, Name::Builtin + + rule %r/\.([a-z]+)\b/ do |m| + match = m[1] + if self.class.object_attributes.include?(match) + token Name::Builtin + pop! + end + end + + rule %r/\$/, Name::Builtin + rule %r/\[/, Text, :pop! + end + + state :operator do + # This rule incorrectly matches === or +++++, which are not operators + rule %r/([+\/*<>=!-]=?|[&*|][&*|]?|\^|<>)/, Operator + rule %r/(?/, Punctuation + + rule %r/"[^"]*"/, Str::Double + + rule %r/\d+\.\d+/, Num::Float + rule %r/\d+/, Num + end + + state :atoms do + rule %r/[[:lower:]]([[:word:]])*/, Str::Symbol + rule %r/'[^']*'/, Str::Symbol + end + + state :operators do + rule %r/(<|>|=<|>=|==|=:=|=|\/|\/\/|\*|\+|-)(?=\s|[a-zA-Z0-9\[])/, + Operator + rule %r/is/, Operator + rule %r/(mod|div|not)/, Operator + rule %r/[#&*+-.\/:<=>?@^~]+/, Operator + end + + state :variables do + rule %r/[A-Z]+\w*/, Name::Variable + rule %r/_[[:word:]]*/, Name::Variable + end + + state :root do + mixin :basic + mixin :atoms + mixin :variables + mixin :operators + end + + state :nested_comment do + rule %r(/\*), Comment::Multiline, :push + rule %r/\s*\*[^*\/]+/, Comment::Multiline + rule %r(\*/), Comment::Multiline, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/prometheus.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/prometheus.rb new file mode 100644 index 0000000..c27f7bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/prometheus.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + class Prometheus < RegexLexer + desc 'prometheus' + tag 'prometheus' + aliases 'prometheus' + filenames '*.prometheus' + + mimetypes 'text/x-prometheus', 'application/x-prometheus' + + def self.functions + @functions ||= Set.new %w( + abs absent ceil changes clamp_max clamp_min count_scalar day_of_month + day_of_week days_in_month delta deriv drop_common_labels exp floor + histogram_quantile holt_winters hour idelta increase irate label_replace + ln log2 log10 month predict_linear rate resets round scalar sort + sort_desc sqrt time vector year avg_over_time min_over_time + max_over_time sum_over_time count_over_time quantile_over_time + stddev_over_time stdvar_over_time + ) + end + + state :root do + mixin :strings + mixin :whitespace + + rule %r/-?\d+\.\d+/, Num::Float + rule %r/-?\d+[smhdwy]?/, Num::Integer + + mixin :operators + + rule %r/(ignoring|on)(\()/ do + groups Keyword::Pseudo, Punctuation + push :label_list + end + rule %r/(group_left|group_right)(\()/ do + groups Keyword::Type, Punctuation + end + rule %r/(bool|offset)\b/, Keyword + rule %r/(without|by)\b/, Keyword, :label_list + rule %r/[\w:]+/ do |m| + if self.class.functions.include?(m[0]) + token Name::Builtin + else + token Name + end + end + + mixin :metrics + end + + state :metrics do + rule %r/[a-zA-Z0-9_-]+/, Name + + rule %r/[\(\)\]:.,]/, Punctuation + rule %r/\{/, Punctuation, :filters + rule %r/\[/, Punctuation + end + + state :strings do + rule %r/"/, Str::Double, :double_string_escaped + rule %r/'/, Str::Single, :single_string_escaped + rule %r/`.*`/, Str::Backtick + end + + [ + [:double, Str::Double, '"'], + [:single, Str::Single, "'"] + ].each do |name, tok, fin| + state :"#{name}_string_escaped" do + rule %r/\\[\\abfnrtv#{fin}]/, Str::Escape + rule %r/[^\\#{fin}]+/m, tok + rule %r/#{fin}/, tok, :pop! + end + end + + state :filters do + mixin :inline_whitespace + rule %r/,/, Punctuation + mixin :labels + mixin :filter_matching_operators + mixin :strings + rule %r/}/, Punctuation, :pop! + end + + state :label_list do + rule %r/\(/, Punctuation + rule %r/[a-zA-Z0-9_:-]+/, Name::Attribute + rule %r/,/, Punctuation + mixin :whitespace + rule %r/\)/, Punctuation, :pop! + end + + state :labels do + rule %r/[a-zA-Z0-9_:-]+/, Name::Attribute + end + + state :operators do + rule %r([+\-\*/%\^]), Operator # Arithmetic + rule %r(=|==|!=|<|>|<=|>=), Operator # Comparison + rule %r/and|or|unless/, Operator # Logical/Set + rule %r/(sum|min|max|avg|stddev|stdvar|count|count_values|bottomk|topk)\b/, Name::Function + end + + state :filter_matching_operators do + rule %r/!(=|~)|=~?/, Operator + end + + state :inline_whitespace do + rule %r/[ \t\r]+/, Text + end + + state :whitespace do + mixin :inline_whitespace + rule %r/\n\s*/m, Text + rule %r/#.*?$/, Comment + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/properties.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/properties.rb new file mode 100644 index 0000000..12ec807 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/properties.rb @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Properties < RegexLexer + title ".properties" + desc '.properties config files for Java' + tag 'properties' + + filenames '*.properties' + mimetypes 'text/x-java-properties' + + identifier = /[\w.-]+/ + + state :basic do + rule %r/[!#].*?\n/, Comment + rule %r/\s+/, Text + rule %r/\\\n/, Str::Escape + end + + state :root do + mixin :basic + + rule %r/(#{identifier})(\s*)([=:])/ do + groups Name::Property, Text, Punctuation + push :value + end + end + + state :value do + rule %r/\n/, Text, :pop! + mixin :basic + rule %r/"/, Str, :dq + rule %r/'.*?'/, Str + mixin :esc_str + rule %r/[^\\\n]+/, Str + end + + state :dq do + rule %r/"/, Str, :pop! + mixin :esc_str + rule %r/[^\\"]+/m, Str + end + + state :esc_str do + rule %r/\\u[0-9]{4}/, Str::Escape + rule %r/\\./m, Str::Escape + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/protobuf.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/protobuf.rb new file mode 100644 index 0000000..9ac6c97 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/protobuf.rb @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Protobuf < RegexLexer + title 'Protobuf' + desc 'Google\'s language-neutral, platform-neutral, extensible mechanism for serializing structured data' + tag 'protobuf' + aliases 'proto' + filenames '*.proto' + mimetypes 'text/x-proto' + + kw = /\b(ctype|default|extensions|import|max|oneof|option|optional|packed|repeated|required|returns|rpc|to)\b/ + datatype = /\b(bool|bytes|double|fixed32|fixed64|float|int32|int64|sfixed32|sfixed64|sint32|sint64|string|uint32|uint64)\b/ + + state :root do + rule %r/[\s]+/, Text + rule %r/[,;{}\[\]()]/, Punctuation + rule %r/\/(\\\n)?\/($|(.|\n)*?[^\\]$)/, Comment::Single + rule %r/\/(\\\n)?\*(.|\n)*?\*(\\\n)?\//, Comment::Multiline + rule kw, Keyword + rule datatype, Keyword::Type + rule %r/true|false/, Keyword::Constant + rule %r/(package)(\s+)/ do + groups Keyword::Namespace, Text + push :package + end + + rule %r/(message|extend)(\s+)/ do + groups Keyword::Declaration, Text + push :message + end + + rule %r/(enum|group|service)(\s+)/ do + groups Keyword::Declaration, Text + push :type + end + + rule %r/".*?"/, Str + rule %r/'.*?'/, Str + rule %r/(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*/, Num::Float + rule %r/(\d+\.\d*|\.\d+|\d+[fF])[fF]?/, Num::Float + rule %r/(\-?(inf|nan))\b/, Num::Float + rule %r/0x[0-9a-fA-F]+[LlUu]*/, Num::Hex + rule %r/0[0-7]+[LlUu]*/, Num::Oct + rule %r/\d+[LlUu]*/, Num::Integer + rule %r/[+-=]/, Operator + rule %r/([a-zA-Z_][\w.]*)([ \t]*)(=)/ do + groups Name::Attribute, Text, Operator + end + rule %r/[a-zA-Z_][\w.]*/, Name + end + + state :package do + rule %r/[a-zA-Z_]\w*/, Name::Namespace, :pop! + rule(//) { pop! } + end + + state :message do + rule %r/[a-zA-Z_]\w*/, Name::Class, :pop! + rule(//) { pop! } + end + + state :type do + rule %r/[a-zA-Z_]\w*/, Name, :pop! + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/puppet.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/puppet.rb new file mode 100644 index 0000000..9726bd9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/puppet.rb @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Puppet < RegexLexer + title "Puppet" + desc 'The Puppet configuration management language (puppetlabs.org)' + tag 'puppet' + aliases 'pp' + filenames '*.pp' + + def self.detect?(text) + return true if text.shebang? 'puppet-apply' + return true if text.shebang? 'puppet' + end + + def self.keywords + @keywords ||= Set.new %w( + and case class default define else elsif if in import inherits + node unless + ) + end + + def self.constants + @constants ||= Set.new %w( + false true undef + ) + end + + def self.metaparameters + @metaparameters ||= Set.new %w( + before require notify subscribe + ) + end + + id = /[a-z]\w*/ + cap_id = /[A-Z]\w*/ + qualname = /(::)?(#{id}::)*\w+/ + + state :whitespace do + rule %r/\s+/m, Text + rule %r/#.*?\n/, Comment + end + + state :root do + mixin :whitespace + + rule %r/[$]#{qualname}/, Name::Variable + rule %r/(#{id})(?=\s*[=+]>)/m do |m| + if self.class.metaparameters.include? m[0] + token Keyword::Pseudo + else + token Name::Property + end + end + + rule %r/(#{qualname})(?=\s*[(])/m, Name::Function + rule cap_id, Name::Class + + rule %r/[+=|~-]>|<[|~-]/, Punctuation + rule %r/[|:}();\[\]]/, Punctuation + + # HACK for case statements and selectors + rule %r/{/, Punctuation, :regex_allowed + rule %r/,/, Punctuation, :regex_allowed + + rule %r/(in|and|or)\b/, Operator::Word + rule %r/[=!<>]=/, Operator + rule %r/[=!]~/, Operator, :regex_allowed + rule %r([.=<>!+*/-]), Operator + + rule %r/(class|include)(\s*)(#{qualname})/ do + groups Keyword, Text, Name::Class + end + + rule %r/node\b/, Keyword, :regex_allowed + + rule %r/'(\\[\\']|[^'])*'/m, Str::Single + rule %r/"/, Str::Double, :dquotes + + rule %r/\d+([.]\d+)?(e[+-]\d+)?/, Num + + # a valid regex. TODO: regexes are only allowed + # in certain places in puppet. + rule qualname do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.constants.include? m[0] + token Keyword::Constant + else + token Name + end + end + end + + state :regex_allowed do + mixin :whitespace + rule %r(/), Str::Regex, :regex + + rule(//) { pop! } + end + + state :regex do + rule %r(/), Str::Regex, :pop! + rule %r/\\./, Str::Escape + rule %r/[(){}]/, Str::Interpol + rule %r/\[/, Str::Interpol, :regex_class + rule %r/./, Str::Regex + end + + state :regex_class do + rule %r/\]/, Str::Interpol, :pop! + rule %r/(?>|\/\/|\*\*)=?/, Operator + rule %r/[-~+\/*%=<>&^|@]=?|!=/, Operator + + rule %r/(from)((?:\\\s|\s)+)(#{dotted_identifier})((?:\\\s|\s)+)(import)/ do + groups Keyword::Namespace, + Text, + Name, + Text, + Keyword::Namespace + end + + rule %r/(import)(\s+)(#{dotted_identifier})/ do + groups Keyword::Namespace, Text, Name + end + + rule %r/(def)((?:\s|\\\s)+)/ do + groups Keyword, Text + push :funcname + end + + rule %r/(class)((?:\s|\\\s)+)/ do + groups Keyword, Text + push :classname + end + + rule %r/([a-z_]\w*)[ \t]*(?=(\(.*\)))/m, Name::Function + rule %r/([A-Z_]\w*)[ \t]*(?=(\(.*\)))/m, Name::Class + + # TODO: not in python 3 + rule %r/`.*?`/, Str::Backtick + rule %r/([rtfbu]{0,2})('''|"""|['"])/i do |m| + groups Str::Affix, Str::Heredoc + current_string.register type: m[1].downcase, delim: m[2] + push :generic_string + end + + mixin :soft_keywords + + # using negative lookbehind so we don't match property names + rule %r/(?>>|\.\.\.)\B/, Generic::Prompt, :doctest + rule %r/[^'"\\{]+?/, Str + rule %r/{{/, Str + + rule %r/'''|"""|['"]/ do |m| + token Str::Heredoc + if current_string.delim? m[0] + current_string.remove + pop! + end + end + + rule %r/(?=\\)/, Str, :generic_escape + + rule %r/{/ do |m| + if current_string.type? "f" + token Str::Interpol + push :generic_interpol + else + token Str + end + end + end + + state :generic_escape do + rule %r(\\ + ( [\\abfnrtv"'] + | \n + | newline + | N{[a-zA-Z][a-zA-Z ]+[a-zA-Z]} + | u[a-fA-F0-9]{4} + | U[a-fA-F0-9]{8} + | x[a-fA-F0-9]{2} + | [0-7]{1,3} + ) + )x do + current_string.type?("r") ? token(Str) : token(Str::Escape) + pop! + end + + rule %r/\\./, Str, :pop! + end + + state :doctest do + rule %r/\n\n/, Text, :pop! + + rule %r/'''|"""/ do + token Str::Heredoc + pop!(2) if in_state?(:generic_string) # pop :doctest and :generic_string + end + + mixin :root + end + + state :generic_interpol do + rule %r/[^{}!:]+/ do |m| + recurse m[0] + end + rule %r/![asr]/, Str::Interpol + rule %r/:/, Str::Interpol + rule %r/{/, Str::Interpol, :generic_interpol + rule %r/}/, Str::Interpol, :pop! + end + + class StringRegister < Array + def delim?(delim) + self.last[1] == delim + end + + def register(type: "u", delim: "'") + self.push [type, delim] + end + + def remove + self.pop + end + + def type?(type) + self.last[0].include? type + end + end + + private_constant :StringRegister + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/q.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/q.rb new file mode 100644 index 0000000..b0d49c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/q.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + class Q < RegexLexer + title 'Q' + desc 'The Q programming language (kx.com)' + tag 'q' + aliases 'kdb+' + filenames '*.q' + mimetypes 'text/x-q', 'application/x-q' + + identifier = /\.?[a-z][a-z0-9_.]*/i + + def self.keywords + @keywords ||= %w[do if while select update delete exec from by] + end + + def self.word_operators + @word_operators ||= %w[ + and or except inter like each cross vs sv within where in asof bin binr cor cov cut ej fby + div ij insert lj ljf mavg mcount mdev mmax mmin mmu mod msum over prior peach pj scan scov setenv ss + sublist uj union upsert wavg wsum xasc xbar xcol xcols xdesc xexp xgroup xkey xlog xprev xrank + ] + end + + def self.builtins + @builtins ||= %w[ + first enlist value type get set count string key max min sum prd last flip distinct raze neg + desc differ dsave dev eval exit exp fills fkeys floor getenv group gtime hclose hcount hdel hopen hsym + iasc idesc inv keys load log lsq ltime ltrim maxs md5 med meta mins next parse plist prds prev rand rank ratios + read0 read1 reciprocal reverse rload rotate rsave rtrim save sdev show signum sin sqrt ssr sums svar system + tables tan til trim txf ungroup var view views wj wj1 ww + ] + end + + state :root do + # q allows a file to start with a shebang + rule %r/#!(.*?)$/, Comment::Preproc, :top + rule %r//, Text, :top + end + + state :top do + # indented lines at the top of the file are ignored by q + rule %r/^[ \t\r]+.*$/, Comment::Special + rule %r/\n+/, Text + rule %r//, Text, :base + end + + state :base do + rule %r/\n+/m, Text + rule(/^.\)/, Keyword::Declaration) + + # Identifiers, word operators, etc. + rule %r/#{identifier}/ do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.word_operators.include? m[0] + token Operator::Word + elsif self.class.builtins.include? m[0] + token Name::Builtin + elsif /^\.[zQqho]\./ =~ m[0] + token Name::Constant + else + token Name + end + end + + # White space and comments + rule(%r{\s+/.*}, Comment::Single) + rule(/[ \t\r]+/, Text::Whitespace) + rule(%r{^/$.*?^\\$}m, Comment::Multiline) + rule(%r{^\/[^\n]*$(\n[^\S\n]+.*$)*}, Comment::Multiline) + # til EOF comment + rule(/^\\$/, Comment, :bottom) + rule(/^\\\\\s+/, Keyword, :bottom) + + # Literals + ## strings + rule(/"/, Str, :string) + ## timespan/stamp constants + rule(/(?:\d+D|\d{4}\.[01]\d\.[0123]\d[DT])(?:[012]\d:[0-5]\d(?::[0-5]\d(?:\.\d+)?)?|([012]\d)?)[zpn]?\b/, + Literal::Date) + ## time/minute/second constants + rule(/[012]\d:[0-5]\d(?::[0-5]\d(\.\d+)?)?[uvtpn]?\b/, Literal::Date) + ## date constants + rule(/\d{4}\.[01]\d\.[0-3]\d[dpnzm]?\b/, Literal::Date) + ## special values + rule(/0[nNwW][hijefcpmdznuvt]?/, Keyword::Constant) + + # operators to match before numbers + rule(%r{'|\/:|\\:|':|\\|\/|0:|1:|2:}, Operator) + + ## numbers + rule(/(\d+[.]\d*|[.]\d+)(e[+-]?\d+)?[ef]?/, Num::Float) + rule(/\d+e[+-]?\d+[ef]?/, Num::Float) + rule(/\d+[ef]/, Num::Float) + rule(/0x[0-9a-f]+/i, Num::Hex) + rule(/[01]+b/, Num::Bin) + rule(/[0-9]+[hij]?/, Num::Integer) + ## symbols and paths + rule(%r{(`:[:a-z0-9._\/]*|`(?:[a-z0-9.][:a-z0-9._]*)?)}i, Str::Symbol) + rule(/(?:<=|>=|<>|::)|[?:$%&|@._#*^\-+~,!><=]:?/, Operator) + + rule %r/[{}\[\]();]/, Punctuation + + # commands + rule(/\\.*\n/, Text) + + end + + state :string do + rule %r/\\"/, Str + rule %r/"/, Str, :pop! + rule %r/\\([\\nr]|[01][0-7]{2})/, Str::Escape + rule %r/[^\\"\n]+/, Str + rule %r/\\/, Str # stray backslash + end + + state :bottom do + rule %r/.+\z/m, Comment::Multiline + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/qml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/qml.rb new file mode 100644 index 0000000..577939f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/qml.rb @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'javascript.rb' + + class Qml < Javascript + title "QML" + desc 'QML, a UI markup language' + tag 'qml' + aliases 'qml' + filenames '*.qml' + + mimetypes 'application/x-qml', 'text/x-qml' + + id_with_dots = /[$a-zA-Z_][a-zA-Z0-9_.]*/ + + prepend :root do + rule %r/(#{id_with_dots})(\s*)({)/ do + groups Keyword::Type, Text, Punctuation + push :type_block + end + rule %r/(#{id_with_dots})(\s+)(on)(\s+)(#{id_with_dots})(\s*)({)/ do + groups Keyword::Type, Text, Keyword, Text, Name::Label, Text, Punctuation + push :type_block + end + + rule %r/[{]/, Punctuation, :push + end + + state :type_block do + rule %r/(id)(\s*)(:)(\s*)(#{id_with_dots})/ do + groups Name::Label, Text, Punctuation, Text, Keyword::Declaration + end + + rule %r/(#{id_with_dots})(\s*)(:)/ do + groups Name::Label, Text, Punctuation + push :expr_start + end + + rule %r/(signal)(\s+)(#{id_with_dots})/ do + groups Keyword::Declaration, Text, Name::Label + push :signal + end + + rule %r/(property)(\s+)(#{id_with_dots})(\s+)(#{id_with_dots})(\s*)(:?)/ do + groups Keyword::Declaration, Text, Keyword::Type, Text, Name::Label, Text, Punctuation + push :expr_start + end + + rule %r/[}]/, Punctuation, :pop! + mixin :root + end + + state :signal do + mixin :comments_and_whitespace + rule %r/\(/ do + token Punctuation + goto :signal_args + end + rule %r//, Text, :pop! + end + + state :signal_args do + mixin :comments_and_whitespace + rule %r/(#{id_with_dots})(\s+)(#{id_with_dots})(\s*)(,?)/ do + groups Keyword::Type, Text, Name, Text, Punctuation + end + rule %r/\)/ , Punctuation, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/r.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/r.rb new file mode 100644 index 0000000..dc500e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/r.rb @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class R < RegexLexer + title "R" + desc 'The R statistics language (r-project.org)' + tag 'r' + aliases 'r', 'R', 's', 'S' + filenames '*.R', '*.r', '.Rhistory', '.Rprofile' + mimetypes 'text/x-r-source', 'text/x-r', 'text/x-R' + + mimetypes 'text/x-r', 'application/x-r' + + KEYWORDS = %w(if else for while repeat in next break function) + + KEYWORD_CONSTANTS = %w( + NULL Inf TRUE FALSE NaN NA + NA_integer_ NA_real_ NA_complex_ NA_character_ + ) + + BUILTIN_CONSTANTS = %w(LETTERS letters month.abb month.name pi T F) + + # These are all the functions in `base` that are implemented as a + # `.Primitive`, minus those functions that are also keywords. + PRIMITIVE_FUNCTIONS = %w( + abs acos acosh all any anyNA Arg as.call as.character + as.complex as.double as.environment as.integer as.logical + as.null.default as.numeric as.raw asin asinh atan atanh attr + attributes baseenv browser c call ceiling class Conj cos cosh + cospi cummax cummin cumprod cumsum digamma dim dimnames + emptyenv exp expression floor forceAndCall gamma gc.time + globalenv Im interactive invisible is.array is.atomic is.call + is.character is.complex is.double is.environment is.expression + is.finite is.function is.infinite is.integer is.language + is.list is.logical is.matrix is.na is.name is.nan is.null + is.numeric is.object is.pairlist is.raw is.recursive is.single + is.symbol lazyLoadDBfetch length lgamma list log max min + missing Mod names nargs nzchar oldClass on.exit pos.to.env + proc.time prod quote range Re rep retracemem return round + seq_along seq_len seq.int sign signif sin sinh sinpi sqrt + standardGeneric substitute sum switch tan tanh tanpi tracemem + trigamma trunc unclass untracemem UseMethod xtfrm + ) + + def self.detect?(text) + return true if text.shebang? 'Rscript' + end + + state :root do + rule %r/#'.*?$/, Comment::Doc + rule %r/#.*?$/, Comment::Single + rule %r/\s+/m, Text::Whitespace + + rule %r/`[^`]+?`/, Name + rule %r/'(\\.|.)*?'/m, Str::Single + rule %r/"(\\.|.)*?"/m, Str::Double + + rule %r/%[^%]*?%/, Operator + + rule %r/0[xX][a-fA-F0-9]+([pP][0-9]+)?[Li]?/, Num::Hex + rule %r/[+-]?(\d+([.]\d+)?|[.]\d+)([eE][+-]?\d+)?[Li]?/, Num + + # Only recognize built-in functions when they are actually used as a + # function call, i.e. followed by an opening parenthesis. + # `Name::Builtin` would be more logical, but is usually not + # highlighted specifically; thus use `Name::Function`. + rule %r/\b(??*+^/!=~$@:%&|]), Operator + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/racket.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/racket.rb new file mode 100644 index 0000000..a005439 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/racket.rb @@ -0,0 +1,568 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Racket < RegexLexer + title "Racket" + desc "Racket is a Lisp descended from Scheme (racket-lang.org)" + + tag 'racket' + filenames '*.rkt', '*.rktd', '*.rktl' + mimetypes 'text/x-racket', 'application/x-racket' + + def self.detect?(text) + text =~ /\A#lang\s*(.*?)$/ + lang_attr = $1 + return false unless lang_attr + return true if lang_attr =~ /racket|scribble/ + end + + def self.keywords + @keywords ||= Set.new %w( + ... and begin begin-for-syntax begin0 case case-lambda cond + datum->syntax-object define define-for-syntax define-logger + define-struct define-syntax define-syntax-rule + define-syntaxes define-values define-values-for-syntax delay + do expand-path fluid-let force hash-table-copy + hash-table-count hash-table-for-each hash-table-get + hash-table-iterate-first hash-table-iterate-key + hash-table-iterate-next hash-table-iterate-value + hash-table-map hash-table-put! hash-table-remove! + hash-table? if lambda let let* let*-values let-struct + let-syntax let-syntaxes let-values let/cc let/ec letrec + letrec-syntax letrec-syntaxes letrec-syntaxes+values + letrec-values list-immutable make-hash-table + make-immutable-hash-table make-namespace module module* + module-identifier=? module-label-identifier=? + module-template-identifier=? module-transformer-identifier=? + namespace-transformer-require or parameterize parameterize* + parameterize-break promise? prop:method-arity-error provide + provide-for-label provide-for-syntax quasiquote quasisyntax + quasisyntax/loc quote quote-syntax quote-syntax/prune + require require-for-label require-for-syntax + require-for-template set! set!-values syntax syntax-case + syntax-case* syntax-id-rules syntax-object->datum + syntax-rules syntax/loc tcp-abandon-port tcp-accept + tcp-accept-evt tcp-accept-ready? tcp-accept/enable-break + tcp-addresses tcp-close tcp-connect tcp-connect/enable-break + tcp-listen tcp-listener? tcp-port? time transcript-off + transcript-on udp-addresses udp-bind! udp-bound? udp-close + udp-connect! udp-connected? udp-multicast-interface + udp-multicast-join-group! udp-multicast-leave-group! + udp-multicast-loopback? udp-multicast-set-interface! + udp-multicast-set-loopback! udp-multicast-set-ttl! + udp-multicast-ttl udp-open-socket udp-receive! udp-receive!* + udp-receive!-evt udp-receive!/enable-break + udp-receive-ready-evt udp-send udp-send* udp-send-evt + udp-send-ready-evt udp-send-to udp-send-to* udp-send-to-evt + udp-send-to/enable-break udp-send/enable-break udp? unless + unquote unquote-splicing unsyntax unsyntax-splicing when + with-continuation-mark with-handlers with-handlers* + with-syntax λ) + end + + def self.builtins + @builtins ||= Set.new %w( + * + - / < <= = > >= + abort-current-continuation abs absolute-path? acos add1 + alarm-evt always-evt andmap angle append apply + arithmetic-shift arity-at-least arity-at-least-value + arity-at-least? asin assoc assq assv atan banner bitwise-and + bitwise-bit-field bitwise-bit-set? bitwise-ior bitwise-not + bitwise-xor boolean? bound-identifier=? box box-cas! + box-immutable box? break-enabled break-thread build-path + build-path/convention-type byte-pregexp byte-pregexp? + byte-ready? byte-regexp byte-regexp? byte? bytes + bytes->immutable-bytes bytes->list bytes->path + bytes->path-element bytes->string/latin-1 + bytes->string/locale bytes->string/utf-8 bytes-append + bytes-close-converter bytes-convert bytes-convert-end + bytes-converter? bytes-copy bytes-copy! + bytes-environment-variable-name? bytes-fill! bytes-length + bytes-open-converter bytes-ref bytes-set! bytes-utf-8-index + bytes-utf-8-length bytes-utf-8-ref bytes? + bytes? caaaar caaadr caaar caadar caaddr caadr caar cadaar + cadadr cadar caddar cadddr caddr cadr call-in-nested-thread + call-with-break-parameterization + call-with-composable-continuation + call-with-continuation-barrier call-with-continuation-prompt + call-with-current-continuation + call-with-default-reading-parameterization + call-with-escape-continuation call-with-exception-handler + call-with-immediate-continuation-mark call-with-input-file + call-with-output-file call-with-parameterization + call-with-semaphore call-with-semaphore/enable-break + call-with-values call/cc call/ec car cdaaar cdaadr cdaar + cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr + cdddr cddr cdr ceiling channel-get channel-put + channel-put-evt channel-put-evt? channel-try-get channel? + chaperone-box chaperone-continuation-mark-key chaperone-evt + chaperone-hash chaperone-of? chaperone-procedure + chaperone-prompt-tag chaperone-struct chaperone-struct-type + chaperone-vector chaperone? char->integer char-alphabetic? + char-blank? char-ci<=? char-ci=? + char-ci>? char-downcase char-foldcase char-general-category + char-graphic? char-iso-control? char-lower-case? + char-numeric? char-punctuation? char-ready? char-symbolic? + char-title-case? char-titlecase char-upcase char-upper-case? + char-utf-8-length char-whitespace? char<=? char=? char>? char? check-duplicate-identifier + checked-procedure-check-and-extract choice-evt cleanse-path + close-input-port close-output-port collect-garbage + collection-file-path collection-path compile + compile-allow-set!-undefined + compile-context-preservation-enabled + compile-enforce-module-constants compile-syntax + compiled-expression? compiled-module-expression? + complete-path? complex? cons continuation-mark-key? + continuation-mark-set->context continuation-mark-set->list + continuation-mark-set->list* continuation-mark-set-first + continuation-mark-set? continuation-marks + continuation-prompt-available? continuation-prompt-tag? + continuation? copy-file cos current-break-parameterization + current-code-inspector current-command-line-arguments + current-compile current-compiled-file-roots + current-continuation-marks current-custodian + current-directory current-directory-for-user current-drive + current-environment-variables current-error-port + current-eval current-evt-pseudo-random-generator + current-gc-milliseconds current-get-interaction-input-port + current-inexact-milliseconds current-input-port + current-inspector current-library-collection-paths + current-load current-load-extension + current-load-relative-directory current-load/use-compiled + current-locale current-memory-use current-milliseconds + current-module-declare-name current-module-declare-source + current-module-name-resolver current-module-path-for-load + current-namespace current-output-port + current-parameterization + current-preserved-thread-cell-values current-print + current-process-milliseconds current-prompt-read + current-pseudo-random-generator current-read-interaction + current-reader-guard current-readtable current-seconds + current-security-guard current-subprocess-custodian-mode + current-thread current-thread-group + current-thread-initial-stack-size + current-write-relative-directory custodian-box-value + custodian-box? custodian-limit-memory custodian-managed-list + custodian-memory-accounting-available? + custodian-require-memory custodian-shutdown-all custodian? + custom-print-quotable-accessor custom-print-quotable? + custom-write-accessor custom-write? date date* + date*-nanosecond date*-time-zone-name date*? date-day + date-dst? date-hour date-minute date-month date-second + date-time-zone-offset date-week-day date-year date-year-day + date? datum-intern-literal default-continuation-prompt-tag + delete-directory delete-file denominator directory-exists? + directory-list display displayln dump-memory-stats + dynamic-require dynamic-require-for-syntax dynamic-wind + environment-variables-copy environment-variables-names + environment-variables-ref environment-variables-set! + environment-variables? eof eof-object? ephemeron-value + ephemeron? eprintf eq-hash-code eq? equal-hash-code + equal-secondary-hash-code equal? equal?/recur eqv-hash-code + eqv? error error-display-handler error-escape-handler + error-print-context-length error-print-source-location + error-print-width error-value->string-handler eval + eval-jit-enabled eval-syntax even? evt? exact->inexact + exact-integer? exact-nonnegative-integer? + exact-positive-integer? exact? executable-yield-handler exit + exit-handler exn exn-continuation-marks exn-message + exn:break exn:break-continuation exn:break:hang-up + exn:break:hang-up? exn:break:terminate exn:break:terminate? + exn:break? exn:fail exn:fail:contract + exn:fail:contract:arity exn:fail:contract:arity? + exn:fail:contract:continuation + exn:fail:contract:continuation? + exn:fail:contract:divide-by-zero + exn:fail:contract:divide-by-zero? + exn:fail:contract:non-fixnum-result + exn:fail:contract:non-fixnum-result? + exn:fail:contract:variable exn:fail:contract:variable-id + exn:fail:contract:variable? exn:fail:contract? + exn:fail:filesystem exn:fail:filesystem:errno + exn:fail:filesystem:errno-errno exn:fail:filesystem:errno? + exn:fail:filesystem:exists exn:fail:filesystem:exists? + exn:fail:filesystem:missing-module + exn:fail:filesystem:missing-module-path + exn:fail:filesystem:missing-module? + exn:fail:filesystem:version exn:fail:filesystem:version? + exn:fail:filesystem? exn:fail:network exn:fail:network:errno + exn:fail:network:errno-errno exn:fail:network:errno? + exn:fail:network? exn:fail:out-of-memory + exn:fail:out-of-memory? exn:fail:read exn:fail:read-srclocs + exn:fail:read:eof exn:fail:read:eof? exn:fail:read:non-char + exn:fail:read:non-char? exn:fail:read? exn:fail:syntax + exn:fail:syntax-exprs exn:fail:syntax:missing-module + exn:fail:syntax:missing-module-path + exn:fail:syntax:missing-module? exn:fail:syntax:unbound + exn:fail:syntax:unbound? exn:fail:syntax? + exn:fail:unsupported exn:fail:unsupported? exn:fail:user + exn:fail:user? exn:fail? exn:missing-module-accessor + exn:missing-module? exn:srclocs-accessor exn:srclocs? exn? + exp expand expand-once expand-syntax expand-syntax-once + expand-syntax-to-top-form expand-to-top-form + expand-user-path explode-path expt file-exists? + file-or-directory-identity file-or-directory-modify-seconds + file-or-directory-permissions file-position file-position* + file-size file-stream-buffer-mode file-stream-port? + file-truncate filesystem-change-evt + filesystem-change-evt-cancel filesystem-change-evt? + filesystem-root-list find-executable-path + find-library-collection-paths find-system-path fixnum? + floating-point-bytes->real flonum? floor flush-output + for-each format fprintf free-identifier=? gcd + generate-temporaries gensym get-output-bytes + get-output-string getenv global-port-print-handler guard-evt + handle-evt handle-evt? hash hash-equal? hash-eqv? + hash-has-key? hash-placeholder? hash-ref! hasheq hasheqv + identifier-binding identifier-binding-symbol + identifier-label-binding identifier-prune-lexical-context + identifier-prune-to-source-module + identifier-remove-from-definition-context + identifier-template-binding identifier-transformer-binding + identifier? imag-part immutable? impersonate-box + impersonate-continuation-mark-key impersonate-hash + impersonate-procedure impersonate-prompt-tag + impersonate-struct impersonate-vector impersonator-ephemeron + impersonator-of? impersonator-prop:application-mark + impersonator-property-accessor-procedure? + impersonator-property? impersonator? inexact->exact + inexact-real? inexact? input-port? inspector? integer->char + integer->integer-bytes integer-bytes->integer integer-length + integer-sqrt integer-sqrt/remainder integer? + internal-definition-context-seal + internal-definition-context? keyword->string keywordbytes list->string + list->vector list-ref list-tail list? load load-extension + load-on-demand-enabled load-relative load-relative-extension + load/cd load/use-compiled local-expand + local-expand/capture-lifts local-transformer-expand + local-transformer-expand/capture-lifts + locale-string-encoding log log-max-level magnitude + make-arity-at-least make-bytes make-channel + make-continuation-mark-key make-continuation-prompt-tag + make-custodian make-custodian-box make-date make-date* + make-derived-parameter make-directory + make-environment-variables make-ephemeron make-exn + make-exn:break make-exn:break:hang-up + make-exn:break:terminate make-exn:fail + make-exn:fail:contract make-exn:fail:contract:arity + make-exn:fail:contract:continuation + make-exn:fail:contract:divide-by-zero + make-exn:fail:contract:non-fixnum-result + make-exn:fail:contract:variable make-exn:fail:filesystem + make-exn:fail:filesystem:errno + make-exn:fail:filesystem:exists + make-exn:fail:filesystem:missing-module + make-exn:fail:filesystem:version make-exn:fail:network + make-exn:fail:network:errno make-exn:fail:out-of-memory + make-exn:fail:read make-exn:fail:read:eof + make-exn:fail:read:non-char make-exn:fail:syntax + make-exn:fail:syntax:missing-module + make-exn:fail:syntax:unbound make-exn:fail:unsupported + make-exn:fail:user make-file-or-directory-link + make-hash-placeholder make-hasheq-placeholder make-hasheqv + make-hasheqv-placeholder make-immutable-hasheqv + make-impersonator-property make-input-port make-inspector + make-known-char-range-list make-output-port make-parameter + make-phantom-bytes make-pipe make-placeholder make-polar + make-prefab-struct make-pseudo-random-generator + make-reader-graph make-readtable make-rectangular + make-rename-transformer make-resolved-module-path + make-security-guard make-semaphore make-set!-transformer + make-shared-bytes make-sibling-inspector + make-special-comment make-srcloc make-string + make-struct-field-accessor make-struct-field-mutator + make-struct-type make-struct-type-property + make-syntax-delta-introducer make-syntax-introducer + make-thread-cell make-thread-group make-vector make-weak-box + make-weak-hasheqv make-will-executor map max mcar mcdr mcons + member memq memv min module->exports module->imports + module->language-info module->namespace + module-compiled-cross-phase-persistent? + module-compiled-exports module-compiled-imports + module-compiled-language-info module-compiled-name + module-compiled-submodules module-declared? + module-path-index-join module-path-index-resolve + module-path-index-split module-path-index-submodule + module-path-index? module-path? module-predefined? + module-provide-protected? modulo mpair? nack-guard-evt + namespace-attach-module namespace-attach-module-declaration + namespace-base-phase namespace-mapped-symbols + namespace-module-identifier namespace-module-registry + namespace-require namespace-require/constant + namespace-require/copy namespace-require/expansion-time + namespace-set-variable-value! namespace-symbol->identifier + namespace-syntax-introduce namespace-undefine-variable! + namespace-unprotect-module namespace-variable-value + namespace? negative? never-evt newline normal-case-path not + null null? number->string number? numerator object-name odd? + open-input-bytes open-input-file open-input-output-file + open-input-string open-output-bytes open-output-file + open-output-string ormap output-port? pair? + parameter-procedure=? parameter? parameterization? + path->bytes path->complete-path path->directory-path + path->string path-add-suffix path-convention-type + path-element->bytes path-element->string + path-for-some-system? path-list-string->path-list + path-replace-suffix path-string? path? peek-byte + peek-byte-or-special peek-bytes peek-bytes! + peek-bytes-avail! peek-bytes-avail!* + peek-bytes-avail!/enable-break peek-char + peek-char-or-special peek-string peek-string! phantom-bytes? + pipe-content-length placeholder-get placeholder-set! + placeholder? poll-guard-evt port-closed-evt port-closed? + port-commit-peeked port-count-lines! + port-count-lines-enabled port-counts-lines? + port-display-handler port-file-identity port-file-unlock + port-next-location port-print-handler port-progress-evt + port-provides-progress-evts? port-read-handler + port-try-file-lock? port-write-handler port-writes-atomic? + port-writes-special? port? positive? prefab-key->struct-type + prefab-key? prefab-struct-key pregexp pregexp? + primitive-closure? primitive-result-arity primitive? print + print-as-expression print-boolean-long-form print-box + print-graph print-hash-table print-mpair-curly-braces + print-pair-curly-braces print-reader-abbreviations + print-struct print-syntax-width print-unreadable + print-vector-length printf procedure->method procedure-arity + procedure-arity-includes? procedure-arity? + procedure-closure-contents-eq? procedure-extract-target + procedure-reduce-arity procedure-rename + procedure-struct-type? procedure? progress-evt? + prop:arity-string prop:checked-procedure + prop:custom-print-quotable prop:custom-write prop:equal+hash + prop:evt prop:exn:missing-module prop:exn:srclocs + prop:impersonator-of prop:input-port + prop:liberal-define-context prop:output-port prop:procedure + prop:rename-transformer prop:set!-transformer + pseudo-random-generator->vector + pseudo-random-generator-vector? pseudo-random-generator? + putenv quotient quotient/remainder raise + raise-argument-error raise-arguments-error raise-arity-error + raise-mismatch-error raise-range-error raise-result-error + raise-syntax-error raise-type-error raise-user-error random + random-seed rational? rationalize read read-accept-bar-quote + read-accept-box read-accept-compiled read-accept-dot + read-accept-graph read-accept-infix-dot read-accept-lang + read-accept-quasiquote read-accept-reader read-byte + read-byte-or-special read-bytes read-bytes! + read-bytes-avail! read-bytes-avail!* + read-bytes-avail!/enable-break read-bytes-line + read-case-sensitive read-char read-char-or-special + read-curly-brace-as-paren read-decimal-as-inexact + read-eval-print-loop read-language read-line + read-on-demand-source read-square-bracket-as-paren + read-string read-string! read-syntax read-syntax/recursive + read/recursive readtable-mapping readtable? + real->double-flonum real->floating-point-bytes + real->single-flonum real-part real? regexp regexp-match + regexp-match-peek regexp-match-peek-immediate + regexp-match-peek-positions + regexp-match-peek-positions-immediate + regexp-match-peek-positions-immediate/end + regexp-match-peek-positions/end regexp-match-positions + regexp-match-positions/end regexp-match/end regexp-match? + regexp-max-lookbehind regexp-replace regexp-replace* regexp? + relative-path? remainder rename-file-or-directory + rename-transformer-target rename-transformer? reroot-path + resolve-path resolved-module-path-name resolved-module-path? + reverse round seconds->date security-guard? + semaphore-peek-evt semaphore-peek-evt? semaphore-post + semaphore-try-wait? semaphore-wait + semaphore-wait/enable-break semaphore? + set!-transformer-procedure set!-transformer? set-box! + set-mcar! set-mcdr! set-phantom-bytes! + set-port-next-location! shared-bytes shell-execute + simplify-path sin single-flonum? sleep special-comment-value + special-comment? split-path sqrt srcloc srcloc->string + srcloc-column srcloc-line srcloc-position srcloc-source + srcloc-span srcloc? string string->bytes/latin-1 + string->bytes/locale string->bytes/utf-8 + string->immutable-string string->keyword string->list + string->number string->path string->path-element + string->symbol string->uninterned-symbol + string->unreadable-symbol string-append string-ci<=? + string-ci=? string-ci>? string-copy + string-copy! string-downcase + string-environment-variable-name? string-fill! + string-foldcase string-length string-locale-ci? string-locale-downcase + string-locale-upcase string-locale? string-normalize-nfc string-normalize-nfd + string-normalize-nfkc string-normalize-nfkd string-ref + string-set! string-titlecase string-upcase + string-utf-8-length string<=? string=? + string>? string? struct->vector struct-accessor-procedure? + struct-constructor-procedure? struct-info + struct-mutator-procedure? struct-predicate-procedure? + struct-type-info struct-type-make-constructor + struct-type-make-predicate + struct-type-property-accessor-procedure? + struct-type-property? struct-type? struct:arity-at-least + struct:date struct:date* struct:exn struct:exn:break + struct:exn:break:hang-up struct:exn:break:terminate + struct:exn:fail struct:exn:fail:contract + struct:exn:fail:contract:arity + struct:exn:fail:contract:continuation + struct:exn:fail:contract:divide-by-zero + struct:exn:fail:contract:non-fixnum-result + struct:exn:fail:contract:variable struct:exn:fail:filesystem + struct:exn:fail:filesystem:errno + struct:exn:fail:filesystem:exists + struct:exn:fail:filesystem:missing-module + struct:exn:fail:filesystem:version struct:exn:fail:network + struct:exn:fail:network:errno struct:exn:fail:out-of-memory + struct:exn:fail:read struct:exn:fail:read:eof + struct:exn:fail:read:non-char struct:exn:fail:syntax + struct:exn:fail:syntax:missing-module + struct:exn:fail:syntax:unbound struct:exn:fail:unsupported + struct:exn:fail:user struct:srcloc struct? sub1 subbytes + subprocess subprocess-group-enabled subprocess-kill + subprocess-pid subprocess-status subprocess-wait subprocess? + substring symbol->string symbol-interned? symbol-unreadable? + symbol? sync sync/enable-break sync/timeout + sync/timeout/enable-break syntax->list syntax-arm + syntax-column syntax-disarm syntax-e syntax-line + syntax-local-bind-syntaxes syntax-local-certifier + syntax-local-context syntax-local-expand-expression + syntax-local-get-shadower syntax-local-introduce + syntax-local-lift-context syntax-local-lift-expression + syntax-local-lift-module-end-declaration + syntax-local-lift-provide syntax-local-lift-require + syntax-local-lift-values-expression + syntax-local-make-definition-context + syntax-local-make-delta-introducer + syntax-local-module-defined-identifiers + syntax-local-module-exports + syntax-local-module-required-identifiers syntax-local-name + syntax-local-phase-level syntax-local-submodules + syntax-local-transforming-module-provides? + syntax-local-value syntax-local-value/immediate + syntax-original? syntax-position syntax-property + syntax-property-symbol-keys syntax-protect syntax-rearm + syntax-recertify syntax-shift-phase-level syntax-source + syntax-source-module syntax-span syntax-taint + syntax-tainted? syntax-track-origin + syntax-transforming-module-expression? syntax-transforming? + syntax? system-big-endian? system-idle-evt + system-language+country system-library-subpath + system-path-convention-type system-type tan terminal-port? + thread thread-cell-ref thread-cell-set! thread-cell-values? + thread-cell? thread-dead-evt thread-dead? thread-group? + thread-resume thread-resume-evt thread-rewind-receive + thread-running? thread-suspend thread-suspend-evt + thread-wait thread/suspend-to-kill thread? time-apply + truncate unbox uncaught-exception-handler + use-collection-link-paths use-compiled-file-paths + use-user-specific-search-paths values + variable-reference->empty-namespace + variable-reference->module-base-phase + variable-reference->module-declaration-inspector + variable-reference->module-path-index + variable-reference->module-source + variable-reference->namespace variable-reference->phase + variable-reference->resolved-module-path + variable-reference-constant? variable-reference? vector + vector->immutable-vector vector->list + vector->pseudo-random-generator + vector->pseudo-random-generator! vector->values vector-fill! + vector-immutable vector-length vector-ref vector-set! + vector-set-performance-stats! vector? version void void? + weak-box-value weak-box? will-execute will-executor? + will-register will-try-execute with-input-from-file + with-output-to-file wrap-evt write write-byte write-bytes + write-bytes-avail write-bytes-avail* write-bytes-avail-evt + write-bytes-avail/enable-break write-char write-special + write-special-avail* write-special-evt write-string zero? + ) + end + + # Since Racket allows identifiers to consist of nearly anything, + # it's simpler to describe what an ID is _not_. + id = /[^\s\(\)\[\]\{\}'`,.]+/i + + state :root do + # comments + rule %r/;.*$/, Comment::Single + rule %r/#!.*/, Comment::Single + rule %r/#\|/, Comment::Multiline, :block_comment + rule %r/#;/, Comment::Multiline, :sexp_comment + rule %r/\s+/m, Text + + rule %r/[+-]inf[.][f0]/, Num::Float + rule %r/[+-]nan[.]0/, Num::Float + rule %r/[-]min[.]0/, Num::Float + rule %r/[+]max[.]0/, Num::Float + + rule %r/-?\d+\.\d+/, Num::Float + rule %r/-?\d+/, Num::Integer + + rule %r/#:#{id}+/, Name::Tag # keyword + + rule %r/#b[01]+/, Num::Bin + rule %r/#o[0-7]+/, Num::Oct + rule %r/#d[0-9]+/, Num::Integer + rule %r/#x[0-9a-f]+/i, Num::Hex + rule %r/#[ei][\d.]+/, Num::Other + + rule %r/"(\\\\|\\"|[^"])*"/, Str + rule %r/['`]#{id}/i, Str::Symbol + rule %r/#\\([()\/'"._!\$%& ?=+-]{1}|[a-z0-9]+)/i, + Str::Char + rule %r/#t(rue)?|#f(alse)?/i, Name::Constant + rule %r/(?:'|#|`|,@|,|\.)/, Operator + + rule %r/(['#])(\s*)(\()/m do + groups Str::Symbol, Text, Punctuation + end + + # () [] {} are all permitted as like pairs + rule %r/\(|\[|\{/, Punctuation, :command + rule %r/\)|\]|\}/, Punctuation + + rule id, Name::Variable + end + + state :block_comment do + rule %r/[^|#]+/, Comment::Multiline + rule %r/\|#/, Comment::Multiline, :pop! + rule %r/#\|/, Comment::Multiline, :block_comment + rule %r/[|#]/, Comment::Multiline + end + + state :sexp_comment do + rule %r/[({\[]/, Comment::Multiline, :sexp_comment_inner + rule %r/"(?:\\"|[^"])*?"/, Comment::Multiline, :pop! + rule %r/[^\s]+/, Comment::Multiline, :pop! + rule(//) { pop! } + end + + state :sexp_comment_inner do + rule %r/[^(){}\[\]]+/, Comment::Multiline + rule %r/[)}\]]/, Comment::Multiline, :pop! + rule %r/[({\[]/, Comment::Multiline, :sexp_comment_inner + end + + state :command do + rule id, Name::Function do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.builtins.include? m[0] + token Name::Builtin + else + token Name::Function + end + + pop! + end + + rule(//) { pop! } + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/reasonml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/reasonml.rb new file mode 100644 index 0000000..07c9f6c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/reasonml.rb @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'ocaml/common.rb' + + class ReasonML < OCamlCommon + title "ReasonML" + desc 'New syntax on top of OCaml ecosystem (reasonml.github.io)' + tag 'reasonml' + filenames '*.re', '*.rei' + mimetypes 'text/x-reasonml' + + def self.keywords + @keywords ||= super + Set.new(%w( + switch + )) + end + + state :root do + rule %r/\s+/m, Text + rule %r/false|true|[(][)]|\[\]/, Name::Builtin::Pseudo + rule %r/#{@@upper_id}(?=\s*[.])/, Name::Namespace, :dotted + rule %r/`#{@@id}/, Name::Tag + rule @@upper_id, Name::Class + rule %r(//.*), Comment::Single + rule %r(/\*), Comment::Multiline, :comment + rule @@id do |m| + match = m[0] + if self.class.keywords.include? match + token Keyword + elsif self.class.word_operators.include? match + token Operator::Word + elsif self.class.primitives.include? match + token Keyword::Type + else + token Name + end + end + + rule %r/[(){}\[\];]+/, Punctuation + rule @@operator, Operator + + rule %r/-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i, Num::Float + rule %r/0x\h[\h_]*/i, Num::Hex + rule %r/0o[0-7][0-7_]*/i, Num::Oct + rule %r/0b[01][01_]*/i, Num::Bin + rule %r/\d[\d_]*/, Num::Integer + + rule %r/'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/, Str::Char + rule %r/'[^'\/]'/, Str::Char + rule %r/'/, Keyword + rule %r/"/, Str::Double, :string + rule %r/[~?]#{@@id}/, Name::Variable + end + + state :comment do + rule %r([^/*]+), Comment::Multiline + rule %r(/\*), Comment::Multiline, :comment + rule %r(\*/), Comment::Multiline, :pop! + rule %r([*/]), Comment::Multiline + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rego.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rego.rb new file mode 100644 index 0000000..6ca1a5d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rego.rb @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Rego < RegexLexer + title "Rego" + desc "The Rego open-policy-agent (OPA) policy language (openpolicyagent.org)" + tag 'rego' + filenames '*.rego' + + def self.constants + @constants ||= Set.new %w( + true false null + ) + end + + def self.operators + @operators ||= Set.new %w( + as default else import not package some with + ) + end + + state :basic do + rule %r/\s+/, Text + rule %r/#.*/, Comment::Single + + rule %r/[\[\](){}|.,;!]/, Punctuation + + rule %r/"[^"]*"/, Str::Double + + rule %r/-?\d+\.\d+([eE][+-]?\d+)?/, Num::Float + rule %r/-?\d+([eE][+-]?\d+)?/, Num + + rule %r/\\u[0-9a-fA-F]{4}/, Num::Hex + rule %r/\\["\/bfnrt]/, Str::Escape + end + + state :operators do + rule %r/(=|!=|>=|<=|>|<|\+|-|\*|%|\/|\||&|:=)/, Operator + rule %r/[\/:?@^~]+/, Operator + end + + state :root do + mixin :basic + mixin :operators + + rule %r/[[:word:]]+/ do |m| + if self.class.constants.include? m[0] + token Keyword::Constant + elsif self.class.operators.include? m[0] + token Operator::Word + else + token Name + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rescript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rescript.rb new file mode 100644 index 0000000..35daf12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rescript.rb @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'ocaml/common.rb' + + class ReScript < OCamlCommon + title "ReScript" + desc "The ReScript programming language (rescript-lang.org)" + tag 'rescript' + filenames '*.res', '*.resi' + mimetypes 'text/x-rescript' + + def self.keywords + @keywords ||= Set.new(%w( + open let rec and as exception assert lazy if else + for in to downto while switch when external type private + mutable constraint include module of with try import export + )) + end + + def self.types + @types ||= Set.new(%w( + bool int float char string + unit list array option ref exn format + )) + end + + def self.word_operators + @word_operators ||= Set.new(%w(mod land lor lxor lsl lsr asr or)) + end + + state :root do + rule %r/\s+/m, Text + rule %r([,.:?~\\]), Text + + # Boolean Literal + rule %r/\btrue|false\b/, Keyword::Constant + + # Module chain + rule %r/#{@@upper_id}(?=\s*[.])/, Name::Namespace, :dotted + + # Decorator + rule %r/@#{@@id}(\.#{@@id})*/, Name::Decorator + + # Poly variant + rule %r/\##{@@id}/, Name::Class + + # Variant or Module + rule @@upper_id, Name::Class + + # Comments + rule %r(//.*), Comment::Single + rule %r(/\*), Comment::Multiline, :comment + + # Keywords and identifiers + rule @@id do |m| + match = m[0] + if self.class.keywords.include? match + token Keyword + elsif self.class.word_operators.include? match + token Operator::Word + elsif self.class.types.include? match + token Keyword::Type + else + token Name + end + end + + # Braces + rule %r/[(){}\[\];]+/, Punctuation + + # Operators + rule %r([;_!$%&*+/<=>@^|-]+), Operator + + # Numbers + rule %r/-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i, Num::Float + rule %r/0x\h[\h_]*/i, Num::Hex + rule %r/0o[0-7][0-7_]*/i, Num::Oct + rule %r/0b[01][01_]*/i, Num::Bin + rule %r/\d[\d_]*/, Num::Integer + + # String and Char + rule %r/'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/, Str::Char + rule %r/'[^'\/]'/, Str::Char + rule %r/'/, Keyword + rule %r/"/, Str::Double, :string + + # Interpolated string + rule %r/`/ do + token Str::Double + push :interpolated_string + end + end + + state :comment do + rule %r([^/\*]+), Comment::Multiline + rule %r(/\*), Comment::Multiline, :comment + rule %r(\*/), Comment::Multiline, :pop! + rule %r([*/]), Comment::Multiline + end + + state :interpolated_string do + rule %r/[$]{/, Punctuation, :interpolated_expression + rule %r/`/, Str::Double, :pop! + rule %r/\\[$`]/, Str::Escape + rule %r/[^$`\\]+/, Str::Double + rule %r/[\\$]/, Str::Double + end + + state :interpolated_expression do + rule %r/}/, Punctuation, :pop! + mixin :root + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rml.rb new file mode 100644 index 0000000..0891470 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rml.rb @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class RML < RegexLexer + title "RML" + desc "A system agnostic domain-specific language for runtime monitoring and verification (https://rmlatdibris.github.io/)" + tag 'rml' + filenames '*.rml' + + def self.keywords + @keywords ||= Set.new %w( + matches not with empty + all if else true false + ) + end + + def self.arithmetic_keywords + @arithmetic_keywords ||= Set.new %w( + abs sin cos tan min max + ) + end + + id_char = /[a-zA-Z0-9_]/ + uppercase_id = /[A-Z]#{id_char}*/ + lowercase_id = /[a-z]#{id_char}*/ + + ellipsis = /(\.){3}/ + int = /[0-9]+/ + float = /#{int}\.#{int}/ + string = /'(\\'|[ a-zA-Z0-9_.])*'/ + + whitespace = /[ \t\r\n]+/ + comment = /\/\/[^\r\n]*/ + + state :common_rules do + rule %r/#{whitespace}/, Text + rule %r/#{comment}/, Comment::Single + rule %r/#{string}/, Literal::String + rule %r/#{float}/, Num::Float + rule %r/#{int}/, Num::Integer + end + + state :root do + mixin :common_rules + rule %r/(#{lowercase_id})(\()/ do + groups Name::Function, Operator + push :event_type_params + end + rule %r/#{lowercase_id}/ do |m| + if m[0] == 'with' + token Keyword + push :data_expression_with + elsif self.class.keywords.include? m[0] + token Keyword + else + token Name::Function + end + end + rule %r/\(|\{|\[/, Operator, :event_type_params + rule %r/[_\|]/, Operator + rule %r/#{uppercase_id}/, Name::Class, :equation_block_expression + rule %r/;/, Operator + end + + state :event_type_params do + mixin :common_rules + rule %r/\(|\{|\[/, Operator, :push + rule %r/\)|\}|\]/, Operator, :pop! + rule %r/#{lowercase_id}(?=:)/, Name::Entity + rule %r/(#{lowercase_id})/ do |m| + if self.class.keywords.include? m[0] + token Keyword + else + token Literal::String::Regex + end + end + rule %r/#{ellipsis}/, Literal::String::Symbol + rule %r/[_\|;,:]/, Operator + end + + state :equation_block_expression do + mixin :common_rules + rule %r/[<,>]/, Operator + rule %r/#{lowercase_id}/, Literal::String::Regex + rule %r/=/ do + token Operator + goto :exp + end + rule %r/;/, Operator, :pop! + end + + state :exp do + mixin :common_rules + rule %r/(if)(\()/ do + groups Keyword, Operator + push :data_expression + end + rule %r/let|var/, Keyword, :equation_block_expression + rule %r/(#{lowercase_id})(\()/ do + groups Name::Function, Operator + push :event_type_params + end + rule %r/(#{lowercase_id})/ do |m| + if self.class.keywords.include? m[0] + token Keyword + else + token Name::Function + end + end + rule %r/#{uppercase_id}(?=<)/, Name::Class, :data_expression + rule %r/#{uppercase_id}/, Name::Class + rule %r/[=(){}*+\/\\\|!>?]/, Operator + rule %r/;/, Operator, :pop! + end + + state :data_expression do + mixin :common_rules + rule %r/#{lowercase_id}/ do |m| + if (self.class.arithmetic_keywords | self.class.keywords).include? m[0] + token Keyword + else + token Literal::String::Regex + end + end + rule %r/\(/, Operator, :push + rule %r/\)/, Operator, :pop! + rule %r/(>)(?=[^A-Z;]+[A-Z;>])/, Operator, :pop! + rule %r/[*^?!%&\[\]<>\|+=:,.\/\\_-]/, Operator + rule %r/;/, Operator, :pop! + end + + state :data_expression_with do + mixin :common_rules + rule %r/>/, Operator + mixin :data_expression + + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/robot_framework.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/robot_framework.rb new file mode 100644 index 0000000..cc0fbbf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/robot_framework.rb @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class RobotFramework < RegexLexer + tag 'robot_framework' + aliases 'robot', 'robot-framework' + + title "Robot Framework" + desc 'Robot Framework is a generic open source automation testing framework (robotframework.org)' + + filenames '*.robot', '*.resource' + mimetypes 'text/x-robot' + + def initialize(opts = {}) + super(opts) + @col = 0 + @next = nil + @is_template = false + end + + def self.settings_with_keywords + @settings_with_keywords ||= Set.new [ + "library", "resource", "setup", "teardown", "template", "suite setup", + "suite teardown", "task setup", "task teardown", "task template", + "test setup", "test teardown", "test template", "variables" + ] + end + + def self.settings_with_args + @settings_with_args ||= Set.new [ + "arguments", "default tags", "documentation", "force tags", + "metadata", "return", "tags", "timeout", "task timeout", + "test timeout" + ] + end + + id = %r/(?:\\|[^|$@&% \t\n])+(?: (?:\\.|[^|$@&% \t\n])+)*/ + bdd = %r/(?:Given|When|Then|And|But) /i + sep = %r/ +\| +|[ ]{2,}|\t+/ + + start do + push :prior_text + end + + state :prior_text do + rule %r/^[^*].*/, Text + rule(//) { pop! } + end + + # Mixins + + state :whitespace do + rule %r/\s+/, Text::Whitespace + end + + state :section_include do + mixin :end_section + mixin :sep + mixin :newline + end + + state :end_section do + rule(/(?=^(?:\| )?\*)/) { pop! } + end + + state :return do + rule(//) { pop! } + end + + state :sep do + rule %r/\| /, Text::Whitespace + + rule sep do + token Text::Whitespace + @col = @col + 1 + if @next + push @next + elsif @is_template + push :args + elsif @col == 1 + @next = :keyword + push :keyword + else + push :args + end + push :cell_start + end + + rule %r/\.\.\. */ do + token Text::Whitespace + @col = @col + 1 + push :args + end + + rule %r/ ?\|/, Text::Whitespace + end + + state :newline do + rule %r/\n/ do + token Text::Whitespace + @col = 0 + @next = nil + push :cell_start + end + end + + # States + + state :root do + mixin :whitespace + + rule %r/^(?:\| )?\*[* ]*([A-Z]+(?: [A-Z]+)?).*/i do |m| + token Generic::Heading, m[0] + case m[1].chomp("s").downcase + when "setting" then push :section_settings + when "test case" then push :section_tests + when "task" then push :section_tasks + when "keyword" then push :section_keywords + when "variable" then push :section_variables + end + end + end + + state :section_settings do + mixin :section_include + + rule %r/([A-Z]+(?: [A-Z]+)?)(:?)/i do |m| + match = m[1].downcase + @next = if self.class.settings_with_keywords.include? match + :keyword + elsif self.class.settings_with_args.include? match + :args + end + groups Name::Builtin::Pseudo, Punctuation + end + end + + state :section_tests do + mixin :section_include + + rule %r/[$@&%{}]+/, Name::Label + rule %r/( )(?![ |])/, Name::Label + + rule id do + @is_template = false + token Name::Label + end + end + + state :section_tasks do + mixin :section_tests + end + + state :section_keywords do + mixin :section_include + + rule %r/[$@&%]\{/ do + token Name::Variable + push :var + end + + rule %r/[$@&%{}]+/, Name::Label + rule %r/( )(?![ |])/, Name::Label + + rule id, Name::Label + end + + state :section_variables do + mixin :section_include + + rule %r/[$@&%]\{/ do + token Name::Variable + @next = :args + push :var + end + end + + state :cell_start do + rule %r/#.*/, Comment + mixin :return + end + + state :keyword do + rule %r/(\[)([A-Z]+(?: [A-Z]+)?)(\])/i do |m| + groups Punctuation, Name::Builtin::Pseudo, Punctuation + + match = m[2].downcase + @is_template = true if match == "template" + if self.class.settings_with_keywords.include? match + @next = :keyword + elsif self.class.settings_with_args.include? match + @next = :args + end + + pop! + end + + rule %r/[$@&%]\{/ do + token Name::Variable + @next = :keyword unless @next.nil? + push :var + end + + rule %r/FOR/i do + token Name::Function + @next = :keyword unless @next.nil? + end + + rule %r/( )(?![ |])/, Name::Function + + rule bdd, Name::Builtin + rule id do + token Name::Function + @next = nil + end + + mixin :return + end + + state :args do + rule %r/[$@&%]\{/ do + token Name::Variable + @next = :keyword unless @next.nil? + push :var + end + + rule %r/[$@&%]+/, Str + rule %r/( )(?![ |])/, Str + rule id, Str + + mixin :return + end + + state :var do + rule %r/(\})( )(=)/ do + groups Name::Variable, Text::Whitespace, Punctuation + pop! + end + rule %r/[$@&%]\{/, Name::Variable, :var + rule %r/[{\[]/, Name::Variable, :var + rule %r/[}\]]/, Name::Variable, :pop! + rule %r/[^$@&%{}\[\]]+/, Name::Variable + rule %r/\}\[/, Name::Variable + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ruby.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ruby.rb new file mode 100644 index 0000000..85a4e00 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ruby.rb @@ -0,0 +1,455 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Ruby < RegexLexer + title "Ruby" + desc "The Ruby programming language (ruby-lang.org)" + tag 'ruby' + aliases 'rb' + filenames '*.rb', '*.ruby', '*.rbw', '*.rake', '*.gemspec', '*.podspec', + 'Rakefile', 'Guardfile', 'Gemfile', 'Capfile', 'Podfile', + 'Vagrantfile', '*.ru', '*.prawn', 'Berksfile', '*.arb', + 'Dangerfile', 'Fastfile', 'Deliverfile', 'Appfile', '*.thor', 'Thorfile' + + mimetypes 'text/x-ruby', 'application/x-ruby' + + def self.detect?(text) + return true if text.shebang? 'ruby' + end + + state :symbols do + # symbols + rule %r( + : # initial : + @{0,2} # optional ivar, for :@foo and :@@foo + [\p{Ll}_]\p{Word}*[!?]? # the symbol + )xi, Str::Symbol + + # special symbols + rule %r(:(?:\*\*|[-+]@|[/\%&\|^`~]|\[\]=?|<<|>>|<=?>|<=?|===?)), + Str::Symbol + + rule %r/:'(\\\\|\\'|[^'])*'/, Str::Symbol + rule %r/:"/, Str::Symbol, :simple_sym + end + + state :sigil_strings do + # %-sigiled strings + # %(abc), %[abc], %, %.abc., %r.abc., etc + delimiter_map = { '{' => '}', '[' => ']', '(' => ')', '<' => '>' } + rule %r/%([rqswQWxiI])?([^\p{Word}\s])/ do |m| + open = Regexp.escape(m[2]) + close = Regexp.escape(delimiter_map[m[2]] || m[2]) + interp = /[rQWxI]/ === m[1] || !m[1] + toktype = Str::Other + + puts " open: #{open.inspect}" if @debug + puts " close: #{close.inspect}" if @debug + + # regexes + if m[1] == 'r' + toktype = Str::Regex + push :regex_flags + end + + token toktype + + push do + uniq_chars = [open, close].uniq.join + uniq_chars = '' if open == close && open == "\\#" + rule %r/\\[##{uniq_chars}\\]/, Str::Escape + # nesting rules only with asymmetric delimiters + if open != close + rule %r/#{open}/ do + token toktype + push + end + end + rule %r/#{close}/, toktype, :pop! + + if interp + mixin :string_intp_escaped + rule %r/#/, toktype + else + rule %r/[\\#]/, toktype + end + + rule %r/[^##{uniq_chars}\\]+/m, toktype + end + end + end + + state :strings do + mixin :symbols + rule %r/\b[\p{Ll}_]\p{Word}*?[?!]?:\s+/, Str::Symbol, :expr_start + rule %r/'(\\\\|\\'|[^'])*'/, Str::Single + rule %r/"/, Str::Double, :simple_string + rule %r/(?_*\$?:"]), Name::Variable::Global + rule %r/\$-[0adFiIlpvw]/, Name::Variable::Global + rule %r/::/, Operator + + mixin :strings + + rule %r/(?:#{keywords.join('|')})(?=\W|$)/, Keyword, :expr_start + rule %r/(?:#{keywords_pseudo.join('|')})\b/, Keyword::Pseudo, :expr_start + rule %r/(not|and|or)\b/, Operator::Word, :expr_start + + rule %r( + (module) + (\s+) + ([\p{L}_][\p{L}0-9_]*(::[\p{L}_][\p{L}0-9_]*)*) + )x do + groups Keyword, Text, Name::Namespace + end + + rule %r/(def\b)(\s*)/ do + groups Keyword, Text + push :funcname + end + + rule %r/(class\b)(\s*)/ do + groups Keyword, Text + push :classname + end + + rule %r/(?:#{builtins_q.join('|')})[?]/, Name::Builtin, :expr_start + rule %r/(?:#{builtins_b.join('|')})!/, Name::Builtin, :expr_start + rule %r/(?=])/ do + groups Punctuation, Text, Name::Function + push :method_call + end + + rule %r/[\p{L}_]\p{Word}*[?!]/, Name, :expr_start + rule %r/[\p{L}_]\p{Word}*/, Name, :method_call + rule %r/\*\*|<>?|>=|<=|<=>|=~|={3}|!~|&&?|\|\||\./, + Operator, :expr_start + rule %r/[-+\/*%=<>&!^|~]=?/, Operator, :expr_start + rule(/[?]/) { token Punctuation; push :ternary; push :expr_start } + rule %r<[\[({,:\\;/]>, Punctuation, :expr_start + rule %r<[\])}]>, Punctuation + end + + state :has_heredocs do + rule %r/(?? | <>? | >= | ===? + ) + )x do |m| + puts "matches: #{[m[0], m[1], m[2], m[3]].inspect}" if @debug + groups Name::Class, Operator, Name::Function + pop! + end + + rule(//) { pop! } + end + + state :classname do + rule %r/\s+/, Text + rule %r/\p{Word}+(::\p{Word}+)+/, Name::Class + + rule %r/\(/ do + token Punctuation + push :defexpr + push :expr_start + end + + # class << expr + rule %r/<=0?n[x]:"" + rule %r( + [?](\\[MC]-)* # modifiers + (\\([\\abefnrstv\#"']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S) + (?!\p{Word}) + )x, Str::Char, :pop! + + # special case for using a single space. Ruby demands that + # these be in a single line, otherwise it would make no sense. + rule %r/(\s*)(%[rqswQWxiI]? \S* )/ do + groups Text, Str::Other + pop! + end + + mixin :sigil_strings + + rule(//) { pop! } + end + + state :slash_regex do + mixin :string_intp + rule %r(\\\\), Str::Regex + rule %r(\\/), Str::Regex + rule %r([\\#]), Str::Regex + rule %r([^\\/#]+)m, Str::Regex + rule %r(/) do + token Str::Regex + goto :regex_flags + end + end + + state :end_part do + # eat up the rest of the stream as Comment::Preproc + rule %r/.+/m, Comment::Preproc, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rust.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rust.rb new file mode 100644 index 0000000..4f0aa8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/rust.rb @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Rust < RegexLexer + title "Rust" + desc 'The Rust programming language (rust-lang.org)' + tag 'rust' + aliases 'rs', + # So that directives from https://github.com/budziq/rust-skeptic + # do not prevent highlighting. + 'rust,no_run', 'rs,no_run', + 'rust,ignore', 'rs,ignore', + 'rust,should_panic', 'rs,should_panic' + filenames '*.rs' + mimetypes 'text/x-rust' + + def self.detect?(text) + return true if text.shebang? 'rustc' + end + + def self.keywords + @keywords ||= %w( + as async await break const continue crate dyn else enum extern false + fn for if impl in let log loop match mod move mut pub ref return self + Self static struct super trait true type unsafe use where while + abstract become box do final macro + override priv typeof unsized virtual + yield try + union + ) + end + + def self.builtins + @builtins ||= Set.new %w( + Add BitAnd BitOr BitXor bool c_char c_double c_float char + c_int clock_t c_long c_longlong Copy c_schar c_short + c_uchar c_uint c_ulong c_ulonglong c_ushort c_void dev_t DIR + dirent Div Eq Err f32 f64 FILE float fpos_t + i16 i32 i64 i8 isize Index ino_t int intptr_t mode_t Mul + Neg None off_t Ok Option Ord Owned pid_t ptrdiff_t + Send Shl Shr size_t Some ssize_t str Sub time_t + u16 u32 u64 u8 usize uint uintptr_t + Box Vec String Rc Arc + u128 i128 Result Sync Pin Unpin Sized Drop drop Fn FnMut FnOnce + Clone PartialEq PartialOrd AsMut AsRef From Into Default + DoubleEndedIterator ExactSizeIterator Extend IntoIterator Iterator + FromIterator ToOwned ToString TryFrom TryInto + ) + end + + def macro_closed? + @macro_delims.values.all?(&:zero?) + end + + start { + @macro_delims = { ']' => 0, ')' => 0, '}' => 0 } + push :bol + } + + delim_map = { '[' => ']', '(' => ')', '{' => '}' } + + id = /[\p{XID_Start}_]\p{XID_Continue}*/ + hex = /[0-9a-f]/i + escapes = %r( + \\ ([nrt'"\\0] | x#{hex}{2} | u\{(#{hex}_*){1,6}\}) + )x + size = /8|16|32|64|128|size/ + + # Although not officially part of Rust, the rustdoc tool allows code in + # comments to begin with `#`. Code like this will be evaluated but not + # included in the HTML output produced by rustdoc. So that code intended + # for these comments can be higlighted with Rouge, the Rust lexer needs + # to check if the beginning of the line begins with a `# `. + state :bol do + mixin :whitespace + rule %r/#\s[^\n]*/, Comment::Special + rule(//) { pop! } + end + + state :attribute do + mixin :whitespace + mixin :has_literals + rule %r/[(,)=:]/, Name::Decorator + rule %r/\]/, Name::Decorator, :pop! + rule id, Name::Decorator + end + + state :whitespace do + rule %r/\s+/, Text + mixin :comments + end + + state :comments do + # Only 3 slashes are doc comments, `////` and beyond become normal + # comments again (for some reason), so match this before the + # doc line comments rather than figure out a + rule %r(////+[^\n]*), Comment::Single + # doc line comments — either inner (`//!`), or outer (`///`). + rule %r(//[/!][^\n]*), Comment::Doc + # otherwise, `//` is just a plain line comme + rule %r(//[^\n]*), Comment::Single + # /**/ and /***/ are self-closing block comments, not doc. Because this + # is self-closing, it doesn't enter the states for nested comments + rule %r(/\*\*\*?/), Comment::Multiline + # 3+ stars and it's a normal non-doc block comment. + rule %r(/\*\*\*+), Comment::Multiline, :nested_plain_block + # `/*!` and `/**` begin doc comments. These nest and can have internal + # block/doc comments, but they're still part of the documentation + # inside. + rule %r(/[*][*!]), Comment::Doc, :nested_doc_block + # any other /* is a plain multiline comment + rule %r(/[*]), Comment::Multiline, :nested_plain_block + end + + # Multiline/block comments fully nest. This is true for ones that are + # marked as documentation too. The behavior here is: + # + # - Anything inside a block doc comment is still included in the + # documentation, even if it's a nested non-doc block comment. For + # example: `/** /* still docs */ */` + # - Anything inside of a block non-doc comment is still just a normal + # comment, even if it's a nested block documentation comment. For + # example: `/* /** not docs */ */` + # + # This basically means: if (on the outermost level) the comment starts as + # one kind of block comment (either doc/non-doc), then everything inside + # of it, including nested block comments of the opposite type, needs to + # stay that type. + # + # Also note that single line comments do nothing anywhere inside of block + # comments, thankfully. + # + # We just define this as two states, because this seems easier than + # tracking it with instance vars. + [ + [:nested_plain_block, Comment::Multiline], + [:nested_doc_block, Comment::Doc] + ].each do |state_name, comment_token| + state state_name do + rule %r(\*/), comment_token, :pop! + rule %r(/\*), comment_token, state_name + # We only want to eat at most one `[*/]` at a time, + # but we can skip past non-`[*/]` in bulk. + rule %r([^*/]+|[*/]), comment_token + end + end + + state :root do + rule %r/\n/, Text, :bol + mixin :whitespace + rule %r/#!?\[/, Name::Decorator, :attribute + rule %r/\b(?:#{Rust.keywords.join('|')})\b/, Keyword + mixin :has_literals + + rule %r([=-]>), Keyword + rule %r(<->), Keyword + rule %r/[()\[\]{}|,:;]/, Punctuation + rule %r/[*\/!@~&+%^<>=\?-]|\.{2,3}/, Operator + + rule %r/([.]\s*)?#{id}(?=\s*[(])/m, Name::Function + rule %r/[.]\s*await\b/, Keyword + rule %r/[.]\s*#{id}/, Name::Property + rule %r/[.]\s*\d+/, Name::Attribute + rule %r/(#{id})(::)/m do + groups Name::Namespace, Punctuation + end + + # macros + rule %r/\bmacro_rules!/, Name::Decorator, :macro_rules + rule %r/#{id}!/, Name::Decorator, :macro + + rule %r/'static\b/, Keyword + rule %r/'#{id}/, Name::Variable + rule %r/#{id}/ do |m| + name = m[0] + if self.class.builtins.include? name + token Name::Builtin + else + token Name + end + end + end + + state :macro do + mixin :has_literals + + rule %r/[\[{(]/ do |m| + @macro_delims[delim_map[m[0]]] += 1 + puts " macro_delims: #{@macro_delims.inspect}" if @debug + token Punctuation + end + + rule %r/[\]})]/ do |m| + @macro_delims[m[0]] -= 1 + puts " macro_delims: #{@macro_delims.inspect}" if @debug + pop! if macro_closed? + token Punctuation + end + + # same as the rule in root, but don't push another macro state + rule %r/#{id}!/, Name::Decorator + mixin :root + + # No syntax errors in macros + rule %r/./, Text + end + + state :macro_rules do + rule %r/[$]#{id}(:#{id})?/, Name::Variable + rule %r/[$]/, Name::Variable + + mixin :macro + end + + state :has_literals do + # constants + rule %r/\b(?:true|false)\b/, Keyword::Constant + + # characters/bytes + rule %r( + b?' (?: #{escapes} | [^\\] ) ' + )x, Str::Char + + rule %r/b?"/, Str, :string + rule %r/b?r(#*)".*?"\1/m, Str + + # numbers + dot = /[.][0-9][0-9_]*/ + exp = /[eE][-+]?[0-9_]+/ + flt = /f32|f64/ + + rule %r( + [0-9][0-9_]* + (#{dot} #{exp}? #{flt}? + |#{dot}? #{exp} #{flt}? + |#{dot}? #{exp}? #{flt} + |[.](?![._\p{XID_Start}]) + ) + )x, Num::Float + + rule %r( + ( 0b[10_]+ + | 0x[0-9a-fA-F_]+ + | 0o[0-7_]+ + | [0-9][0-9_]* + ) (u#{size}?|i#{size})? + )x, Num::Integer + + end + + state :string do + rule %r/"/, Str, :pop! + rule escapes, Str::Escape + rule %r/[^"\\]+/m, Str + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sas.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sas.rb new file mode 100644 index 0000000..6095854 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sas.rb @@ -0,0 +1,563 @@ +# -*- coding: utf-8 -*- # + +module Rouge + module Lexers + class SAS < RegexLexer + title "SAS" + desc "SAS (Statistical Analysis Software)" + tag 'sas' + filenames '*.sas' + mimetypes 'application/x-sas', 'application/x-stat-sas', 'application/x-sas-syntax' + + def self.data_step_statements + # from Data step statements - SAS 9.4 Statements reference + # http://support.sas.com/documentation/cdl/en/lestmtsref/68024/PDF/default/lestmtsref.pdf + @data_step_statements ||= Set.new %w( + ABORT ARRAY ATTRIB BY CALL CARDS CARDS4 CATNAME CHECKPOINT + EXECUTE_ALWAYS CONTINUE DATA DATALINES DATALINES4 DELETE DESCRIBE + DISPLAY DM DO UNTIL WHILE DROP END ENDSAS ERROR EXECUTE FILE FILENAME + FOOTNOTE FORMAT GO TO IF THEN ELSE INFILE INFORMAT INPUT + KEEP LABEL LEAVE LENGTH LIBNAME LINK LIST LOCK LOSTCARD MERGE + MISSING MODIFY OPTIONS OUTPUT PAGE PUT PUTLOG REDIRECT REMOVE RENAME + REPLACE RESETLINE RETAIN RETURN RUN SASFILE SELECT SET SKIP STOP + SYSECHO TITLE UPDATE WHERE WINDOW X + ) + # label: + # Sum + end + + def self.sas_functions + # from SAS 9.4 Functions and CALL Routines reference + # http://support.sas.com/documentation/cdl/en/lefunctionsref/67960/PDF/default/lefunctionsref.pdf + @sas_functions ||= Set.new %w( + ABS ADDR ADDRLONG AIRY ALLCOMB ALLPERM ANYALNUM ANYALPHA ANYCNTRL + ANYDIGIT ANYFIRST ANYGRAPH ANYLOWER ANYNAME ANYPRINT ANYPUNCT + ANYSPACE ANYUPPER ANYXDIGIT ARCOS ARCOSH ARSIN ARSINH ARTANH ATAN + ATAN2 ATTRC ATTRN BAND BETA BETAINV BLACKCLPRC BLACKPTPRC + BLKSHCLPRC BLKSHPTPRC BLSHIFT BNOT BOR BRSHIFT BXOR BYTE CAT CATQ + CATS CATT CATX CDF CEIL CEILZ CEXIST CHAR CHOOSEC CHOOSEN CINV + CLOSE CMISS CNONCT COALESCE COALESCEC COLLATE COMB COMPARE COMPBL + COMPFUZZ COMPGED COMPLEV COMPOUND COMPRESS CONSTANT CONVX CONVXP + COS COSH COT COUNT COUNTC COUNTW CSC CSS CUMIPMT CUMPRINC CUROBS + CV DACCDB DACCDBSL DACCSL DACCSYD DACCTAB DAIRY DATDIF DATE + DATEJUL DATEPART DATETIME DAY DCLOSE DCREATE DEPDB DEPDBSL DEPSL + DEPSYD DEPTAB DEQUOTE DEVIANCE DHMS DIF DIGAMMA DIM DINFO DIVIDE + DNUM DOPEN DOPTNAME DOPTNUM DOSUBL DREAD DROPNOTE DSNAME + DSNCATLGD DUR DURP EFFRATE ENVLEN ERF ERFC EUCLID EXIST EXP FACT + FAPPEND FCLOSE FCOL FCOPY FDELETE FETCH FETCHOBS FEXIST FGET + FILEEXIST FILENAME FILEREF FINANCE FIND FINDC FINDW FINFO FINV + FIPNAME FIPNAMEL FIPSTATE FIRST FLOOR FLOORZ FMTINFO FNONCT FNOTE + FOPEN FOPTNAME FOPTNUM FPOINT FPOS FPUT FREAD FREWIND FRLEN FSEP + FUZZ FWRITE GAMINV GAMMA GARKHCLPRC GARKHPTPRC GCD GEODIST + GEOMEAN GEOMEANZ GETOPTION GETVARC GETVARN GRAYCODE HARMEAN + HARMEANZ HBOUND HMS HOLIDAY HOLIDAYCK HOLIDAYCOUNT HOLIDAYNAME + HOLIDAYNX HOLIDAYNY HOLIDAYTEST HOUR HTMLDECODE HTMLENCODE + IBESSEL IFC IFN INDEX INDEXC INDEXW INPUT INPUTC INPUTN INT + INTCINDEX INTCK INTCYCLE INTFIT INTFMT INTGET INTINDEX INTNX + INTRR INTSEAS INTSHIFT INTTEST INTZ IORCMSG IPMT IQR IRR JBESSEL + JULDATE JULDATE7 KURTOSIS LAG LARGEST LBOUND LCM LCOMB LEFT + LENGTH LENGTHC LENGTHM LENGTHN LEXCOMB LEXCOMBI LEXPERK LEXPERM + LFACT LGAMMA LIBNAME LIBREF LOG LOG1PX LOG10 LOG2 LOGBETA LOGCDF + LOGISTIC LOGPDF LOGSDF LOWCASE LPERM LPNORM MAD MARGRCLPRC + MARGRPTPRC MAX MD5 MDY MEAN MEDIAN MIN MINUTE MISSING MOD + MODEXIST MODULE MODULEC MODULEN MODZ MONTH MOPEN MORT MSPLINT + MVALID N NETPV NLITERAL NMISS NOMRATE NORMAL NOTALNUM NOTALPHA + NOTCNTRL NOTDIGIT NOTE NOTFIRST NOTGRAPH NOTLOWER NOTNAME + NOTPRINT NOTPUNCT NOTSPACE NOTUPPER NOTXDIGIT NPV NVALID NWKDOM + OPEN ORDINAL PATHNAME PCTL PDF PEEK PEEKC PEEKCLONG PEEKLONG PERM + PMT POINT POISSON PPMT PROBBETA PROBBNML PROBBNRM PROBCHI PROBF + PROBGAM PROBHYPR PROBIT PROBMC PROBNEGB PROBNORM PROBT PROPCASE + PRXCHANGE PRXMATCH PRXPAREN PRXPARSE PRXPOSN PTRLONGADD PUT PUTC + PUTN PVP QTR QUANTILE QUOTE RANBIN RANCAU RAND RANEXP RANGAM + RANGE RANK RANNOR RANPOI RANTBL RANTRI RANUNI RENAME REPEAT + RESOLVE REVERSE REWIND RIGHT RMS ROUND ROUNDE ROUNDZ SAVING + SAVINGS SCAN SDF SEC SECOND SHA256 SHA256HEX SHA256HMACHEX SIGN + SIN SINH SKEWNESS SLEEP SMALLEST SOAPWEB SOAPWEBMETA + SOAPWIPSERVICE SOAPWIPSRS SOAPWS SOAPWSMETA SOUNDEX SPEDIS SQRT + SQUANTILE STD STDERR STFIPS STNAME STNAMEL STRIP SUBPAD SUBSTR + SUBSTRN SUM SUMABS SYMEXIST SYMGET SYMGLOBL SYMLOCAL SYSEXIST + SYSGET SYSMSG SYSPARM SYSPROCESSID SYSPROCESSNAME SYSPROD SYSRC + SYSTEM TAN TANH TIME TIMEPART TIMEVALUE TINV TNONCT TODAY + TRANSLATE TRANSTRN TRANWRD TRIGAMMA TRIM TRIMN TRUNC TSO TYPEOF + TZONEID TZONENAME TZONEOFF TZONES2U TZONEU2S UNIFORM UPCASE + URLDECODE URLENCODE USS UUIDGEN VAR VARFMT VARINFMT VARLABEL + VARLEN VARNAME VARNUM VARRAY VARRAYX VARTYPE VERIFY VFORMAT + VFORMATD VFORMATDX VFORMATN VFORMATNX VFORMATW VFORMATWX VFORMATX + VINARRAY VINARRAYX VINFORMAT VINFORMATD VINFORMATDX VINFORMATN + VINFORMATNX VINFORMATW VINFORMATWX VINFORMATX VLABEL VLABELX + VLENGTH VLENGTHX VNAME VNAMEX VTYPE VTYPEX VVALUE VVALUEX WEEK + WEEKDAY WHICHC WHICHN WTO YEAR YIELDP YRDIF YYQ ZIPCITY + ZIPCITYDISTANCE ZIPFIPS ZIPNAME ZIPNAMEL ZIPSTATE + ) + end + + def self.sas_macro_statements + # from SAS 9.4 Macro Language Reference + # Chapter 12 + @sas_macro_statements ||= Set.new %w( + %COPY %DISPLAY %GLOBAL %INPUT %LET %MACRO %PUT %SYMDEL %SYSCALL + %SYSEXEC %SYSLPUT %SYSMACDELETE %SYSMSTORECLEAR %SYSRPUT %WINDOW + %ABORT %DO %TO %UNTIL %WHILE %END %GOTO %IF %THEN %ELSE %LOCAL + %RETURN + %INCLUDE %LIST %RUN + ) + # Omitted: + # %label: Identifies the destination of a %GOTO statement. + # %MEND + end + + def self.sas_macro_functions + # from SAS 9.4 Macro Language Reference + # Chapter 12 + + @sas_macro_functions ||= Set.new %w( + %BQUOTE %NRBQUOTE %EVAL %INDEX %LENGTH %QUOTE %NRQUOTE %SCAN + %QSCAN %STR %NRSTR %SUBSTR %QSUBSTR %SUPERQ %SYMEXIST %SYMGLOBL + %SYMLOCAL %SYSEVALF %SYSFUNC %QSYSFUNC %SYSGET %SYSMACEXEC + %SYSMACEXIST %SYSMEXECDEPTH %SYSMEXECNAME %SYSPROD %UNQUOTE + %UPCASE %QUPCASE + ) + end + + def self.sas_auto_macro_vars + # from SAS 9.4 Macro Language Reference + # Chapter 12 + + @sas_auto_macro_vars ||= Set.new %w( + &SYSADDRBITS &SYSBUFFR &SYSCC &SYSCHARWIDTH &SYSCMD &SYSDATASTEPPHASE &SYSDATE + &SYSDATE9 &SYSDAY &SYSDEVIC &SYSDMG &SYSDSN &SYSENCODING &SYSENDIAN &SYSENV + &SYSERR &SYSERRORTEXT &SYSFILRC &SYSHOSTINFOLONG &SYSHOSTNAME &SYSINDEX + &SYSINFO &SYSJOBID &SYSLAST &SYSLCKRC &SYSLIBRC &SYSLOGAPPLNAME &SYSMACRONAME + &SYSMENV &SYSMSG &SYSNCPU &SYSNOBS &SYSODSESCAPECHAR &SYSODSPATH &SYSPARM + &SYSPBUFF &SYSPRINTTOLIST &SYSPRINTTOLOG &SYSPROCESSID &SYSPROCESSMODE + &SYSPROCESSNAME &SYSPROCNAME &SYSRC &SYSSCP &SYSSCPL &SYSSITE &SYSSIZEOFLONG + &SYSSIZEOFPTR &SYSSIZEOFUNICODE &SYSSTARTID &SYSSTARTNAME &SYSTCPIPHOSTNAME + &SYSTIME &SYSTIMEZONE &SYSTIMEZONEIDENT &SYSTIMEZONEOFFSET &SYSUSERID &SYSVER + &SYSVLONG &SYSVLONG4 &SYSWARNINGTEXT + ) + end + + def self.proc_keywords + # Create a hash with keywords for common PROCs, keyed by PROC name + @proc_keywords ||= {} + + @proc_keywords["SQL"] ||= Set.new %w( + ALTER TABLE CONNECT CREATE INDEX VIEW DELETE DESCRIBE DISCONNECT DROP EXECUTE + INSERT RESET SELECT UPDATE VALIDATE ADD CONSTRAINT DROP FOREIGN KEY PRIMARY + MODIFY LIKE AS ORDER BY USING FROM INTO SET VALUES RESET DISTINCT UNIQUE + WHERE GROUP HAVING LEFT RIGHT INNER JOIN ON + ) + # from SAS 9.4 SQL Procedure User's Guide + + @proc_keywords["MEANS"] ||= Set.new %w( + BY CLASS FREQ ID OUTPUT OUT TYPES VAR WAYS WEIGHT + ATTRIB FORMAT LABEL WHERE + DESCENDING NOTSORTED + NOTHREADS NOTRAP PCTLDEF SUMSIZE THREADS CLASSDATA COMPLETETYPES + EXCLUSIVE MISSING FW MAXDEC NONOBS NOPRINT ORDER FORMATTED FREQ + UNFORMATTED PRINT PRINTALLTYPES PRINTIDVARS STACKODSOUTPUT + CHARTYPE DESCENDTYPES IDMIN + ALPHA EXCLNPWGT QMARKERS QMETHOD QNTLDEF VARDEF + CLM CSS CV KURTOSIS KURT LCLM MAX MEAN MIN MODE N + NMISS RANGE SKEWNESS SKEW STDDEV STD STDERR SUM SUMWGT UCLM USS VAR + MEDIAN P50 Q1 P25 Q3 P75 P1 P90 P5 P95 P10 P99 P20 P30 P40 P60 P70 + P80 QRANGE + PROBT PRT T + ASCENDING GROUPINTERNAL MLF PRELOADFMT + MAXID AUTOLABEL AUTONAME KEEPLEN LEVELS NOINHERIT + ) + # from BASE SAS 9.4 Procedures Guide, Fifth Edition + + @proc_keywords["DATASETS"] ||= Set.new %w( + AGE APPEND ATTRIB AUDIT CHANGE CONTENTS COPY DELETE EXCHANGE + EXCLUDE FORMAT IC CREATE DELETE REACTIVATE INDEX CENTILES INFORMAT + INITIATE LABEL LOG MODIFY REBUILD RENAME REPAIR RESUME SAVE SELECT + SUSPEND TERMINATE USER_VAR XATTR ADD OPTIONS REMOVE SET + ) + # from BASE SAS 9.4 Procedures Guide, Fifth Edition + + @proc_keywords["SORT"] ||= Set.new %w( + BY DESCENDING KEY ASCENDING ASC DESC DATECOPY FORCE OVERWRITE + PRESORTED SORTSIZE TAGSORT DUPOUT OUT UNIQUEOUT NODUPKEY NOUNIQUEKEY + NOTHREADS THREADS EQUALS NOEQUALS + ATTRIB FORMAT LABEL WHERE + ) + # from BASE SAS 9.4 Procedures Guide, Fifth Edition + + @proc_keywords["PRINT"] ||= Set.new %w( + BY DESCENDING NOTSORTED PAGEBY SUMBY ID STYLE SUM VAR CONTENTS DATA + GRANDTOTAL_LABEL HEADING LABEL SPLIT SUMLABEL NOSUMLABEL + BLANKLINE COUNT DOUBLE N NOOBS OBS ROUND + ROWS UNIFORM WIDTH + ATTRIB FORMAT LABEL WHERE + ) + # from BASE SAS 9.4 Procedures Guide, Fifth Edition + + @proc_keywords["APPEND"] ||= Set.new %w( + BASE APPENDVER DATA ENCRYPTKEY FORCE GETSORT NOWARN + ATTRIB FORMAT LABEL WHERE + ) + # from BASE SAS 9.4 Procedures Guide, Fifth Edition + + @proc_keywords["TRANSPOSE"] ||= Set.new %w( + DELIMITER LABEL LET NAME OUT PREFIX SUFFIX BY DESCENDING NOTSORTED + COPY ID IDLABEL VAR INDB + ATTRIB FORMAT LABEL WHERE + ) + # from BASE SAS 9.4 Procedures Guide, Fifth Edition + + @proc_keywords["FREQ"] ||= Set.new %w( + BY EXACT OUTPUT TABLES TEST WEIGHT + COMPRESS DATA FORMCHAR NLEVELS NOPRINT ORDER PAGE FORMATTED FREQ + INTERNAL + AGREE BARNARD BINOMIAL BIN CHISQ COMOR EQOR ZELEN FISHER JT KAPPA + KENTB TAUB LRCHI MCNEM MEASURES MHCHI OR ODDSRATIO PCHI PCORR RELRISK + RISKDIFF SCORR SMDCR SMDRC STUTC TAUC TREND WTKAP WTKAPPA + OUT AJCHI ALL BDCHI CMH CMH1 CMH2 CMHCOR CMHGA CMHRMS COCHQ CONTGY + CRAMV EQKAP EQWKP GAMMA GS GAILSIMON LAMCR LAMDAS LAMRC LGOR LGRRC1 + LGRRC2 MHOR MHRRC1 MHRRC2 N NMISS PHI PLCORR RDIF1 RDIF2 RISKDIFF1 + RISKDIFF2 RRC1 RELRISK1 RRC2 RELRISK2 RSK1 RISK1 RSK11 RISK11 RSK12 + RISK12 RSK21 RISK21 RSK22 RISK22 TSYMM BOWKER U UCR URC + CELLCHI2 CUMCOL DEVIATION EXPECTED MISSPRINT PEARSONREF PRINTWKTS + SCOROUT SPARSE STDRES TOTPCT + CONTENTS CROSSLIST FORMAT LIST MAXLEVELS NOCOL NOCUM NOFREQ NOPERCENT + NOPRINT NOROW NOSPARSE NOWARN PLOTS OUT OUTCUM OUTEXPECT OUTPCT + ZEROS + ) + # from Base SAS 9.4 Procedures Guide: Statistical Procedures, Fourth Edition + + @proc_keywords["CORR"] ||= Set.new %w( + BY FREQ ID PARTIAL VAR WEIGHT WITH + DATA OUTH OUTK OUTP OUTPLC OUTPLS OUTS + EXCLNPWGHT FISHER HOEFFDING KENDALL NOMISS PEARSON POLYCHORIC + POLYSERIAL ALPHA COV CSSCP SINGULAR SSCP VARDEF PLOTS MATRIX SCATTER + BEST NOCORR NOPRINT NOPROB NOSIMPLE RANK + ) + # from Base SAS 9.4 Procedures Guide: Statistical Procedures, Fourth Edition + + @proc_keywords["REPORT"] ||= Set.new %w( + BREAK BY DESCENDING NOTSORTED COLUMN COMPUTE STYLE LINE ENDCOMP + CALL DEFINE _ROW_ FREQ RBREAK WEIGHT + ATTRIB FORMAT LABEL WHERE + DATA NOALIAS NOCENTER NOCOMPLETECOLS NOCOMPLETEROWS NOTHREADS + NOWINDOWS OUT PCTLDEF THREADS WINDOWS COMPLETECOLS NOCOMPLETECOLS + COMPLETEROWS NOCOMPLETEROWS CONTENTS SPANROWS COMMAND HELP PROMPT + BOX BYPAGENO CENTER NOCENTER COLWIDTH FORMCHAR LS MISSING PANELS PS + PSPACE SHOWALL SPACING WRAP EXCLNPWGT QMARKERS QMETHOD QNTLDEF VARDEF + NAMED NOHEADER SPLIT HEADLINE HEADSKIP LIST NOEXEC OUTREPT PROFILE + REPORT + COLOR DOL DUL OL PAGE SKIP SUMMARIZE SUPPRESS UL + BLINK COMMAND HIGHLIGHT RVSVIDEO MERGE REPLACE URL URLBP URLP + AFTER BEFORE _PAGE_ LEFT RIGHT CHARACTER LENGTH + EXCLUSIVE MISSING MLF ORDER DATA FORMATTED FREQ INTERNAL PRELOADFMT + WIDTH + ACROSS ANALYSIS COMPUTED DISPLAY GROUP ORDER + CONTENTS FLOW ID NOPRINT NOZERO PAGE + CSS CV MAX MEAN MIN MODE N NMISS PCTN PCTSUM RANGE STD STDERR SUM + SUMWGT USS VAR + MEDIAN P50 Q1 P25 Q3 P75 P1 P90 P5 P95 P10 P99 P20 P30 P40 P60 P70 + P80 QRANGE + PROBT PRT T + ) + # from BASE SAS 9.4 Procedures Guide, Fifth Edition + + @proc_keywords["METALIB"] ||= Set.new %w( + OMR DBAUTH DBUSER DBPASSWORD EXCLUDE SELECT READ FOLDER FOLDERID + IMPACT_LIMIT NOEXEC PREFIX REPORT UPDATE_RULE DELETE NOADD NODELDUP + NOUPDATE + LIBID LIBRARY LIBURI + TYPE DETAIL SUMMARY + ) + # from SAS 9.4 Language Interfaces to Metadata, Third Edition + + @proc_keywords["GCHART"] ||= Set.new %w( + DATA ANNOTATE GOUT IMAGEMAP BLOCK HBAR HBAR3D VBAR VBAR3D PIE PIE3D + DONUT STAR ANNO + BY NOTE FORMAT LABEL WHERE + BLOCKMAX CAXIS COUTLINE CTEXT LEGEND NOHEADING NOLEGEND PATTERNID + GROUP MIDPOINT SUBGROUP WOUTLINE DESCRIPTION NAME DISCRETE LEVELS + OLD MISSING HTML_LEGEND HTML URL FREQ G100 SUMVAR TYPE + CAUTOREF CERROR CFRAME CLM CREF FRAME NOFRAME GSPACE IFRAME + IMAGESTYLE TILE FIT LAUTOREF NOSYMBOL PATTERNID SHAPE SPACE + SUBOUTSIDE WAUTOREF WIDTH WOUTLINE WREF + ASCENDING AUTOREF CLIPREF DESCENDING FRONTREF GAXIS MAXIS MINOR + NOAXIS NOBASEREF NOZERO RANGE AXIS REF CFREQ CFREQLABEL NONE CPERCENT + CPERCENTLABEL ERRORBAR BARS BOTH TOP FREQLABEL INSIDE MEAN MEANLABEL + NOSTATS OUTSIDE PERCENT PERCENTLABEL PERCENTSUM SUM + CFILL COUTLINE DETAIL_RADIUS EXPLODE FILL SOLID X INVISIBLE NOHEADING + RADIUS WOUTLINE DETAIL_THRESHOLD DETAIL_PERCENT DETAIL_SLICE + DETAIL_VALUE DONUTPCT LABEL ACROSS DOWN GROUP NOGROUPHEADING SUBGROUP + MATCHCOLOR OTHERCOLOR OTHERLABEL PERCENT ARROW PLABEL PPERCENT SLICE + VALUE + ANGLE ASCENDING CLOCKWISE DESCENDING JSTYLE + NOCONNECT STARMAX STARMIN + ) + # from SAS GRAPH 9.4 Reference, Fourth Edition + + @proc_keywords["GPLOT"] ||= Set.new %w( + DATA ANNOTATE GOUT IMAGEMAP UNIFORM BUBBLE BUBBLE2 PLOT PLOT2 + BCOLOR BFILL BFONT BLABEL BSCALE AREA RADIUS BSIZE DESCRIPTION NAME + AUTOHREF CAUTOHREF CHREF HAXIS HMINOR HREF HREVERSE HZERO LAUTOHREF + LHREF WAUTOHREF WHREF HTML URL + CAXIS CFRAME CTEXT DATAORDER FRAME NOFRAME FRONTREF GRID IFRAME + IMAGESTYLE TILE FIT NOAXIS + AUTOVREF CAUTOVREF CVREF LAUTOVREF LVREF VAXIS VMINOR VREF VREVERSE + VZERO WAUTOVREF WVREF + CBASELINE COUTLINE + AREAS GRID LEGEND NOLASTAREA NOLEGEND OVERLAY REGEQN SKIPMISS + ) + # from SAS GRAPH 9.4 Reference, Fourth Edition + + @proc_keywords["REG"] ||= Set.new %w( + MODEL BY FREQ ID VAR WEIGHT ADD CODE DELETE MTEST OUTPUT PAINT + PLOT PRINT REFIT RESTRICT REWEIGHT STORE TEST + ) + # from SAS/STAT 15.1 User's Guide + + @proc_keywords["SGPLOT"] ||= Set.new %w( + STYLEATTRS BAND X Y UPPER LOWER BLOCK BUBBLE DENSITY DOT DROPLINE + ELLIPSE ELLIPSEPARM FRINGE GRADLEGEND HBAR HBARBASIC HBARPARM + HBOX HEATMAP HEATMAPPARM HIGHLOW HISTOGRAM HLINE INSET KEYLEGEND + LINEPARM LOESS NEEDLE PBSPLINE POLYGON REFLINE REG SCATTER SERIES + SPLINE STEP SYMBOLCHAR SYMBOLIMAGE TEXT VBAR VBARBASIC VBARPARM + VBOX VECTOR VLINE WATERFALL XAXIS X2AXIS XAXISTABLE YAXIS Y2AXIS + YAXISTABLE + ) + # from ODS Graphics: Procedures Guide, Sixth Edition + return @proc_keywords + end + + def self.sas_proc_names + # from SAS Procedures by Name + # http://support.sas.com/documentation/cdl/en/allprodsproc/68038/HTML/default/viewer.htm#procedures.htm + + @sas_proc_names ||= Set.new %w( + ACCESS ACECLUS ADAPTIVEREG ALLELE ANOM ANOVA APPEND APPSRV ARIMA + AUTHLIB AUTOREG BCHOICE BOM BOXPLOT BTL BUILD CALENDAR CALIS CALLRFC + CANCORR CANDISC CAPABILITY CASECONTROL CATALOG CATMOD CDISC CDISC + CHART CIMPORT CLP CLUSTER COMPARE COMPILE COMPUTAB CONTENTS CONVERT + COPULA COPY CORR CORRESP COUNTREG CPM CPORT CUSUM CV2VIEW DATEKEYS + DATASETS DATASOURCE DB2EXT DB2UTIL DBCSTAB DBF DBLOAD DELETE DIF + DISCRIM DISPLAY DISTANCE DMSRVADM DMSRVDATASVC DMSRVPROCESSSVC + DOCUMENT DOWNLOAD DQLOCLST DQMATCH DQSCHEME DS2 DTREE ENTROPY ESM + EXPAND EXPLODE EXPORT FACTEX FACTOR FAMILY FASTCLUS FCMP FEDSQL FMM + FONTREG FORECAST FORMAT FORMS FREQ FSBROWSE FSEDIT FSLETTER FSLIST + FSVIEW G3D G3GRID GA GAM GAMPL GANNO GANTT GAREABAR GBARLINE GCHART + GCONTOUR GDEVICE GEE GENESELECT GENMOD GEOCODE GFONT GINSIDE GIS GKPI + GLIMMIX GLM GLMMOD GLMPOWER GLMSELECT GMAP GOPTIONS GPLOT GPROJECT + GRADAR GREDUCE GREMOVE GREPLAY GROOVY GSLIDE GTILE HADOOP HAPLOTYPE + HDMD HPBIN HPCANDISC HPCDM HPCOPULA HPCORR HPCOUNTREG HPDMDB HPDS2 + HPFMM HPGENSELECT HPIMPUTE HPLMIXED HPLOGISTIC HPMIXED HPNLMOD + HPPANEL HPPLS HPPRINCOMP HPQUANTSELECT HPQLIM HPREG HPSAMPLE + HPSEVERITY HPSPLIT HPSUMMARY HTSNP HTTP ICLIFETEST ICPHREG IML IMPORT + IMSTAT IMXFER INBREED INFOMAPS INTPOINT IOMOPERATE IRT ISHIKAWA ITEMS + JAVAINFO JSON KDE KRIGE2D LASR LATTICE LIFEREG LIFETEST LOAN + LOCALEDATA LOESS LOGISTIC LP LUA MACONTROL MAPIMPORT MCMC MDC MDDB + MDS MEANS METADATA METALIB METAOPERATE MI MIANALYZE MIGRATE MIXED + MODECLUS MODEL MSCHART MULTTEST MVPDIAGNOSE MVPMODEL MVPMONITOR + NESTED NETDRAW NETFLOW NLIN NLMIXED NLP NPAR1WAY ODSLIST ODSTABLE + ODSTEXT OLAP OLAPCONTENTS OLAPOPERATE OPERATE OPTEX OPTGRAPH OPTIONS + OPTLOAD OPTLP OPTLSO OPTMILP OPTMODEL OPTNET OPTQP OPTSAVE ORTHOREG + PANEL PARETO PDLREG PDS PDSCOPY PHREG PLAN PLM PLOT PLS PM PMENU + POWER PRESENV PRINCOMP PRINQUAL PRINT PRINTTO PROBIT PROTO PRTDEF + PRTEXP PSMOOTH PWENCODE QDEVICE QLIM QUANTLIFE QUANTREG QUANTSELECT + QUEST RANK RAREEVENTS RDC RDPOOL RDSEC RECOMMEND REG REGISTRY RELEASE + RELIABILITY REPORT RISK ROBUSTREG RSREG SCAPROC SCORE SEQDESIGN + SEQTEST SERVER SEVERITY SGDESIGN SGPANEL SGPLOT SGRENDER SGSCATTER + SHEWHART SIM2D SIMILARITY SIMLIN SIMNORMAL SOAP SORT SOURCE SPECTRA + SPP SQL SQOOP SSM STANDARD STATESPACE STDIZE STDRATE STEPDISC STP + STREAM SUMMARY SURVEYFREQ SURVEYIMPUTE SURVEYLOGISTIC SURVEYMEANS + SURVEYPHREG SURVEYREG SURVEYSELECT SYSLIN TABULATE TAPECOPY TAPELABEL + TEMPLATE TIMEDATA TIMEID TIMEPLOT TIMESERIES TPSPLINE TRANSPOSE + TRANSREG TRANTAB TREE TSCSREG TTEST UCM UNIVARIATE UPLOAD VARCLUS + VARCOMP VARIOGRAM VARMAX VASMP X11 X12 X13 XSL + ) + end + + state :basics do + # Rules to be parsed before the keywords (which are different depending + # on the context) + + rule %r/\s+/m, Text + + # Single-line comments (between * and ;) - these can actually go onto multiple lines + # case 1 - where it starts a line + rule %r/^\s*%?\*[^;]*;/m, Comment::Single + # case 2 - where it follows the previous statement on the line (after a semicolon) + rule %r/(;)(\s*)(%?\*[^;]*;)/m do + groups Punctuation, Text, Comment::Single + end + + # True multiline comments! + rule %r(/[*].*?[*]/)m, Comment::Multiline + + # date/time constants (Language Reference pp91-2) + rule %r/'[0-9a-z]+?'d/i, Literal::Date + rule %r/'.+?'dt/i, Literal::Date + rule %r/'[0-9:]+?([a|p]m)?'t/i, Literal::Date + + rule %r/'/, Str::Single, :single_string + rule %r/"/, Str::Double, :double_string + rule %r/&[a-z0-9_&.]+/i, Name::Variable + + # numeric constants (Language Reference p91) + rule %r/\d[0-9a-f]*x/i, Num::Hex + rule %r/\d[0-9e\-.]+/i, Num # scientific notation + + # auto variables from DATA step (Language Reference p46, p37) + rule %r/\b(_n_|_error_|_file_|_infile_|_msg_|_iorc_|_cmd_)\b/i, Name::Builtin::Pseudo + + # auto variable list names + rule %r/\b(_character_|_numeric_|_all_)\b/i, Name::Builtin + + # datalines/cards etc + rule %r/\b(datalines|cards)(\s*)(;)/i do + groups Keyword, Text, Punctuation + push :datalines + end + rule %r/\b(datalines4|cards4)(\s*)(;)/i do + groups Keyword, Text, Punctuation + push :datalines4 + end + + + # operators (Language Reference p96) + rule %r(\*\*|[\*/\+-]), Operator + rule %r/[^¬~]?=:?|[<>]=?:?/, Operator + rule %r/\b(eq|ne|gt|lt|ge|le|in)\b/i, Operator::Word + rule %r/[&|!¦¬∘~]/, Operator + rule %r/\b(and|or|not)\b/i, Operator::Word + rule %r/(<>|><)/, Operator # min/max + rule %r/\|\|/, Operator # concatenation + + # The OF operator should also be highlighted (Language Reference p49) + rule %r/\b(of)\b/i, Operator::Word + rule %r/\b(like)\b/i, Operator::Word # Language Ref p181 + + rule %r/\d+/, Num::Integer + + rule %r/\$/, Keyword::Type + + # Macro definitions + rule %r/(%macro|%mend)(\s*)(\w+)/i do + groups Keyword, Text, Name::Function + end + rule %r/%mend/, Keyword + + rule %r/%\w+/ do |m| + if self.class.sas_macro_statements.include? m[0].upcase + token Keyword + elsif self.class.sas_macro_functions.include? m[0].upcase + token Keyword + else + token Name + end + end + end + + state :basics2 do + # Rules to be parsed after the keywords (which are different depending + # on the context) + + # Missing values (Language Reference p81) + rule %r/\s\.[;\s]/, Keyword::Constant # missing + rule %r/\s\.[a-z_]/, Name::Constant # user-defined missing + + rule %r/[\(\),;:\{\}\[\]\\\.]/, Punctuation + + rule %r/@/, Str::Symbol # line hold specifiers + rule %r/\?/, Str::Symbol # used for format modifiers + + rule %r/[^\s]+/, Text # Fallback for anything we haven't matched so far + end + + state :root do + mixin :basics + + # PROC definitions + rule %r!(proc)(\s+)(\w+)!ix do |m| + @proc_name = m[3].upcase + puts " proc name: #{@proc_name}" if @debug + if self.class.sas_proc_names.include? @proc_name + groups Keyword, Text, Keyword + else + groups Keyword, Text, Name + end + + push :proc + end + + # Data step definitions + rule %r/(data)(\s+)([\w\.]+)/i do + groups Keyword, Text, Name::Variable + end + # Libname definitions + rule %r/(libname)(\s+)(\w+)/i do + groups Keyword, Text, Name::Variable + end + + rule %r/\w+/ do |m| + if self.class.data_step_statements.include? m[0].upcase + token Keyword + elsif self.class.sas_functions.include? m[0].upcase + token Keyword + else + token Name + end + end + + mixin :basics2 + end + + + state :single_string do + rule %r/''/, Str::Escape + rule %r/'/, Str::Single, :pop! + rule %r/[^']+/, Str::Single + end + + state :double_string do + rule %r/&[a-z0-9_&]+\.?/i, Str::Interpol + rule %r/""/, Str::Escape + rule %r/"/, Str::Double, :pop! + + rule %r/[^&"]+/, Str::Double + # Allow & to be used as character if not already matched as macro variable + rule %r/&/, Str::Double + end + + state :datalines do + rule %r/[^;]/, Literal::String::Heredoc + rule %r/;/, Punctuation, :pop! + end + + state :datalines4 do + rule %r/;{4}/, Punctuation, :pop! + rule %r/[^;]/, Literal::String::Heredoc + rule %r/;{,3}/, Literal::String::Heredoc + end + + + # PROCS + state :proc do + rule %r/(quit|run)/i, Keyword, :pop! + + mixin :basics + rule %r/\w+/ do |m| + if self.class.data_step_statements.include? m[0].upcase + token Keyword + elsif self.class.sas_functions.include? m[0].upcase + token Keyword + elsif self.class.proc_keywords.has_key?(@proc_name) and self.class.proc_keywords[@proc_name].include? m[0].upcase + token Keyword + else + token Name + end + end + + mixin :basics2 + end + + end #class SAS + end #module Lexers +end #module Rouge diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass.rb new file mode 100644 index 0000000..7758beb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass.rb @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'sass/common.rb' + + class Sass < SassCommon + include Indentation + + title "Sass" + desc 'The Sass stylesheet language language (sass-lang.com)' + + tag 'sass' + filenames '*.sass' + mimetypes 'text/x-sass' + + id = /[\w-]+/ + + state :root do + rule %r/[ \t]*\n/, Text + rule(/[ \t]*/) { |m| token Text; indentation(m[0]) } + end + + state :content do + # block comments + rule %r(//.*?$) do + token Comment::Single + pop!; starts_block :single_comment + end + + rule %r(/[*].*?\n) do + token Comment::Multiline + pop!; starts_block :multi_comment + end + + rule %r/@import\b/, Keyword, :import + + mixin :content_common + + rule %r(=#{id}), Name::Function, :value + rule %r([+]#{id}), Name::Decorator, :value + + rule %r/:/, Name::Attribute, :old_style_attr + + rule(/(?=[^\[\n]+?:([^a-z]|$))/) { push :attribute } + + rule(//) { push :selector } + end + + state :single_comment do + rule %r/.*?$/, Comment::Single, :pop! + end + + state :multi_comment do + rule %r/.*?\n/, Comment::Multiline, :pop! + end + + state :import do + rule %r/[ \t]+/, Text + rule %r/\S+/, Str + rule %r/\n/, Text, :pop! + end + + state :old_style_attr do + mixin :attr_common + rule(//) { pop!; push :value } + end + + state :end_section do + rule(/\n/) { token Text; reset_stack } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass/common.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass/common.rb new file mode 100644 index 0000000..68b0095 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sass/common.rb @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + # shared states with SCSS + class SassCommon < RegexLexer + id = /[\w-]+/ + + state :content_common do + rule %r/@for\b/, Keyword, :for + rule %r/@(debug|warn|if|each|while|else|return|media)/, Keyword, :value + + rule %r/(@mixin)(\s+)(#{id})/ do + groups Keyword, Text, Name::Function + push :value + end + + rule %r/(@function)(\s+)(#{id})/ do + groups Keyword, Text, Name::Function + push :value + end + + rule %r/@extend\b/, Keyword, :selector + + rule %r/(@include)(\s+)(#{id})/ do + groups Keyword, Text, Name::Decorator + push :value + end + + rule %r/@#{id}/, Keyword, :selector + rule %r/&/, Keyword, :selector + + # $variable: assignment + rule %r/([$]#{id})([ \t]*)(:)/ do + groups Name::Variable, Text, Punctuation + push :value + end + end + + state :value do + mixin :end_section + rule %r/[ \t]+/, Text + rule %r/[$]#{id}/, Name::Variable + rule %r/url[(]/, Str::Other, :string_url + rule %r/#{id}(?=\s*[(])/, Name::Function + rule %r/%#{id}/, Name::Decorator + + # named literals + rule %r/(true|false)\b/, Name::Builtin::Pseudo + rule %r/(and|or|not)\b/, Operator::Word + + # colors and numbers + rule %r/#[a-z0-9]{1,6}/i, Num::Hex + rule %r/-?\d+(%|[a-z]+)?/, Num + rule %r/-?\d*\.\d+(%|[a-z]+)?/, Num::Integer + + mixin :has_strings + mixin :has_interp + + rule %r/[~^*!&%<>\|+=@:,.\/?-]+/, Operator + rule %r/[\[\]()]+/, Punctuation + rule %r(/[*]), Comment::Multiline, :inline_comment + rule %r(//[^\n]*), Comment::Single + + # identifiers + rule(id) do |m| + if CSS.builtins.include? m[0] + token Name::Builtin + elsif CSS.constants.include? m[0] + token Name::Constant + else + token Name + end + end + end + + state :has_interp do + rule %r/[#][{]/, Str::Interpol, :interpolation + end + + state :has_strings do + rule %r/"/, Str::Double, :dq + rule %r/'/, Str::Single, :sq + end + + state :interpolation do + rule %r/}/, Str::Interpol, :pop! + mixin :value + end + + state :selector do + mixin :end_section + + mixin :has_strings + mixin :has_interp + rule %r/[ \t]+/, Text + rule %r/:/, Name::Decorator, :pseudo_class + rule %r/[.]/, Name::Class, :class + rule %r/#/, Name::Namespace, :id + rule %r/%/, Name::Variable, :placeholder + rule id, Name::Tag + rule %r/&/, Keyword + rule %r/[~^*!&\[\]()<>\|+=@:;,.\/?-]/, Operator + end + + state :dq do + rule %r/"/, Str::Double, :pop! + mixin :has_interp + rule %r/(\\.|#(?![{])|[^\n"#])+/, Str::Double + end + + state :sq do + rule %r/'/, Str::Single, :pop! + mixin :has_interp + rule %r/(\\.|#(?![{])|[^\n'#])+/, Str::Single + end + + state :string_url do + rule %r/[)]/, Str::Other, :pop! + rule %r/(\\.|#(?![{])|[^\n)#])+/, Str::Other + mixin :has_interp + end + + state :selector_piece do + mixin :has_interp + rule(//) { pop! } + end + + state :pseudo_class do + rule id, Name::Decorator + mixin :selector_piece + end + + state :class do + rule id, Name::Class + mixin :selector_piece + end + + state :id do + rule id, Name::Namespace + mixin :selector_piece + end + + state :placeholder do + rule id, Name::Variable + mixin :selector_piece + end + + state :for do + rule %r/(from|to|through)/, Operator::Word + mixin :value + end + + state :attr_common do + mixin :has_interp + rule id do |m| + if CSS.properties.include? m[0] + token Name::Label + else + token Name::Attribute + end + end + end + + state :attribute do + mixin :attr_common + + rule %r/([ \t]*)(:)/ do + groups Text, Punctuation + push :value + end + end + + state :inline_comment do + rule %r/(\\#|#(?=[^\n{])|\*(?=[^\n\/])|[^\n#*])+/, Comment::Multiline + mixin :has_interp + rule %r([*]/), Comment::Multiline, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scala.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scala.rb new file mode 100644 index 0000000..0758699 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scala.rb @@ -0,0 +1,172 @@ +# -*- coding: utf-8 # +# frozen_string_literal: true + +module Rouge + module Lexers + class Scala < RegexLexer + title "Scala" + desc "The Scala programming language (scala-lang.org)" + tag 'scala' + aliases 'scala' + filenames '*.scala', '*.sbt' + + mimetypes 'text/x-scala', 'application/x-scala' + + # As documented in the ENBF section of the scala specification + # https://scala-lang.org/files/archive/spec/2.13/13-syntax-summary.html + # https://en.wikipedia.org/wiki/Unicode_character_property#General_Category + whitespace = /\p{Space}/ + letter = /[\p{L}$_]/ + upper = /[\p{Lu}$_]/ + digits = /[0-9]/ + parens = /[(){}\[\]]/ + delims = %r([‘’".;,]) + + # negative lookahead to filter out other classes + op = %r( + (?!#{whitespace}|#{letter}|#{digits}|#{parens}|#{delims}) + [-!#%&*/:?@\\^\p{Sm}\p{So}] + )x + # manually removed +<=>|~ from regexp because they're in property Sm + # pp CHRS:(0x00..0x7f).map(&:chr).grep(/\p{Sm}/) + + idrest = %r(#{letter}(?:#{letter}|#{digits})*(?:(?<=_)#{op}+)?)x + + keywords = %w( + abstract case catch def do else extends final finally for forSome + if implicit lazy match new override private protected requires return + sealed super this throw try val var while with yield + ) + + state :root do + rule %r/(class|trait|object)(\s+)/ do + groups Keyword, Text + push :class + end + rule %r/'#{idrest}(?!')/, Str::Symbol + rule %r/[^\S\n]+/, Text + + rule %r(//.*), Comment::Single + rule %r(/\*), Comment::Multiline, :comment + + rule %r/@#{idrest}/, Name::Decorator + + rule %r/(def)(\s+)(#{idrest}|#{op}+|`[^`]+`)(\s*)/ do + groups Keyword, Text, Name::Function, Text + end + + rule %r/(val)(\s+)(#{idrest}|#{op}+|`[^`]+`)(\s*)/ do + groups Keyword, Text, Name::Variable, Text + end + + rule %r/(this)(\n*)(\.)(#{idrest})/ do + groups Keyword, Text, Operator, Name::Property + end + + rule %r/(#{idrest}|_)(\n*)(\.)(#{idrest})/ do + groups Name::Variable, Text, Operator, Name::Property + end + + rule %r/#{upper}#{idrest}\b/, Name::Class + + rule %r/(#{idrest})(#{whitespace}*)(\()/ do + groups Name::Function, Text, Operator + end + + rule %r/(\.)(#{idrest})/ do + groups Operator, Name::Property + end + + rule %r( + (#{keywords.join("|")})\b| + (<[%:-]|=>|>:|[#=@_\u21D2\u2190])(\b|(?=\s)|$) + )x, Keyword + rule %r/:(?!#{op})/, Keyword, :type + rule %r/(true|false|null)\b/, Keyword::Constant + rule %r/(import|package)(\s+)/ do + groups Keyword, Text + push :import + end + + rule %r/(type)(\s+)/ do + groups Keyword, Text + push :type + end + + rule %r/""".*?"""(?!")/m, Str + rule %r/"(\\\\|\\"|[^"])*"/, Str + rule %r/'\\.'|'[^\\]'|'\\u[0-9a-fA-F]{4}'/, Str::Char + + rule idrest, Name + rule %r/`[^`]+`/, Name + + rule %r/\[/, Operator, :typeparam + rule %r/[\(\)\{\};,.#]/, Operator + rule %r/#{op}+/, Operator + + rule %r/([0-9][0-9]*\.[0-9]*|\.[0-9]+)([eE][+-]?[0-9]+)?[fFdD]?/, Num::Float + rule %r/([0-9][0-9]*[fFdD])/, Num::Float + rule %r/0x[0-9a-fA-F]+/, Num::Hex + rule %r/[0-9]+L?/, Num::Integer + rule %r/\n/, Text + end + + state :class do + rule %r/(#{idrest}|#{op}+|`[^`]+`)(\s*)(\[)/ do + groups Name::Class, Text, Operator + push :typeparam + end + + rule %r/\s+/, Text + rule %r/{/, Operator, :pop! + rule %r/\(/, Operator, :pop! + rule %r(//.*), Comment::Single, :pop! + rule %r(#{idrest}|#{op}+|`[^`]+`), Name::Class, :pop! + end + + state :type do + rule %r/\s+/, Text + rule %r/<[%:]|>:|[#_\u21D2]|forSome|type/, Keyword + rule %r/([,\);}]|=>|=)(\s*)/ do + groups Operator, Text + pop! + end + rule %r/[\(\{]/, Operator, :type + + typechunk = /(?:#{idrest}|#{op}+\`[^`]+`)/ + rule %r/(#{typechunk}(?:\.#{typechunk})*)(\s*)(\[)/ do + groups Keyword::Type, Text, Operator + pop! + push :typeparam + end + + rule %r/(#{typechunk}(?:\.#{typechunk})*)(\s*)$/ do + groups Keyword::Type, Text + pop! + end + + rule %r(//.*), Comment::Single, :pop! + rule %r/\.|#{idrest}|#{op}+|`[^`]+`/, Keyword::Type + end + + state :typeparam do + rule %r/[\s,]+/, Text + rule %r/<[%:]|=>|>:|[#_\u21D2]|forSome|type/, Keyword + rule %r/([\]\)\}])/, Operator, :pop! + rule %r/[\(\[\{]/, Operator, :typeparam + rule %r/\.|#{idrest}|#{op}+|`[^`]+`/, Keyword::Type + end + + state :comment do + rule %r([^/\*]+), Comment::Multiline + rule %r(/\*), Comment::Multiline, :comment + rule %r(\*/), Comment::Multiline, :pop! + rule %r([*/]), Comment::Multiline + end + + state :import do + rule %r((#{idrest}|\.)+), Name::Namespace, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scheme.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scheme.rb new file mode 100644 index 0000000..96965d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scheme.rb @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Scheme < RegexLexer + title "Scheme" + desc "The Scheme variant of Lisp" + + tag 'scheme' + filenames '*.scm', '*.ss' + mimetypes 'text/x-scheme', 'application/x-scheme' + + def self.keywords + @keywords ||= Set.new %w( + lambda define if else cond and or case let let* letrec begin + do delay set! => quote quasiquote unquote unquote-splicing + define-syntax let-syntax letrec-syntax syntax-rules + ) + end + + def self.builtins + @builtins ||= Set.new %w( + * + - / < <= = > >= abs acos angle append apply asin + assoc assq assv atan boolean? caaaar caaadr caaar caadar + caaddr caadr caar cadaar cadadr cadar caddar cadddr caddr + cadr call-with-current-continuation call-with-input-file + call-with-output-file call-with-values call/cc car cdaaar cdaadr + cdaar cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr + cdddr cddr cdr ceiling char->integer char-alphabetic? char-ci<=? + char-ci=? char-ci>? char-downcase + char-lower-case? char-numeric? char-ready? char-upcase + char-upper-case? char-whitespace? char<=? char=? + char>? char? close-input-port close-output-port complex? cons + cos current-input-port current-output-port denominator + display dynamic-wind eof-object? eq? equal? eqv? eval + even? exact->inexact exact? exp expt floor for-each force gcd + imag-part inexact->exact inexact? input-port? integer->char + integer? interaction-environment lcm length list list->string + list->vector list-ref list-tail list? load log magnitude + make-polar make-rectangular make-string make-vector map + max member memq memv min modulo negative? newline not + null-environment null? number->string number? numerator odd? + open-input-file open-output-file output-port? pair? peek-char + port? positive? procedure? quotient rational? rationalize + read read-char real-part real? remainder reverse round + scheme-report-environment set-car! set-cdr! sin sqrt string + string->list string->number string->symbol string-append + string-ci<=? string-ci=? string-ci>? + string-copy string-fill! string-length string-ref + string-set! string<=? string=? + string>? string? substring symbol->string symbol? + tan transcript-off transcript-on truncate values vector + vector->list vector-fill! vector-length vector-ref + vector-set! vector? with-input-from-file with-output-to-file + write write-char zero? + ) + end + + id = /[a-z0-9!$\%&*+,\/:<=>?@^_~|-]+/i + + state :root do + # comments + rule %r/;.*$/, Comment::Single + rule %r/\s+/m, Text + rule %r/-?\d+\.\d+/, Num::Float + rule %r/-?\d+/, Num::Integer + + # Racket infinitites + rule %r/[+-]inf[.][f0]/, Num + + rule %r/#b[01]+/, Num::Bin + rule %r/#o[0-7]+/, Num::Oct + rule %r/#d[0-9]+/, Num::Integer + rule %r/#x[0-9a-f]+/i, Num::Hex + rule %r/#[ei][\d.]+/, Num::Other + + rule %r/"(\\\\|\\"|[^"])*"/, Str + rule %r/'#{id}/i, Str::Symbol + rule %r/#\\([()\/'"._!\$%& ?=+-]{1}|[a-z0-9]+)/i, + Str::Char + rule %r/#t|#f/, Name::Constant + rule %r/(?:'|#|`|,@|,|\.)/, Operator + + rule %r/(['#])(\s*)(\()/m do + groups Str::Symbol, Text, Punctuation + end + + rule %r/\(|\[/, Punctuation, :command + rule %r/\)|\]/, Punctuation + + rule id, Name::Variable + end + + state :command do + rule id, Name::Function do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.builtins.include? m[0] + token Name::Builtin + else + token Name::Function + end + + pop! + end + + rule(//) { pop! } + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scss.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scss.rb new file mode 100644 index 0000000..7cf178c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/scss.rb @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'sass/common.rb' + + class Scss < SassCommon + title "SCSS" + desc "SCSS stylesheets (sass-lang.com)" + tag 'scss' + filenames '*.scss' + mimetypes 'text/x-scss' + + state :root do + rule %r/\s+/, Text + rule %r(//.*?$), Comment::Single + rule %r(/[*].*?[*]/)m, Comment::Multiline + rule %r/@import\b/, Keyword, :value + + mixin :content_common + + rule(/(?=[^;{}][;}])/) { push :attribute } + rule(/(?=[^;{}:\[]+:[^a-z])/) { push :attribute } + + rule(//) { push :selector } + end + + state :end_section do + rule %r/\n/, Text + rule(/[;{}]/) { token Punctuation; reset_stack } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sed.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sed.rb new file mode 100644 index 0000000..b3efe50 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sed.rb @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Sed < RegexLexer + title "sed" + desc 'sed, the ultimate stream editor' + + tag 'sed' + filenames '*.sed' + mimetypes 'text/x-sed' + + def self.detect?(text) + return true if text.shebang? 'sed' + end + + class Regex < RegexLexer + state :root do + rule %r/\\./, Str::Escape + rule %r/\[/, Punctuation, :brackets + rule %r/[$^.*]/, Operator + rule %r/[()]/, Punctuation + rule %r/./, Str::Regex + end + + state :brackets do + rule %r/\^/ do + token Punctuation + goto :brackets_int + end + + rule(//) { goto :brackets_int } + end + + state :brackets_int do + # ranges + rule %r/.-./, Name::Variable + rule %r/\]/, Punctuation, :pop! + rule %r/./, Str::Regex + end + end + + class Replacement < RegexLexer + state :root do + rule %r/\\./m, Str::Escape + rule %r/&/, Operator + rule %r/[^\\&]+/m, Text + end + end + + def regex + @regex ||= Regex.new(options) + end + + def replacement + @replacement ||= Replacement.new(options) + end + + start { regex.reset!; replacement.reset! } + + state :whitespace do + rule %r/\s+/m, Text + rule(/#.*?\n/) { token Comment; reset_stack } + rule(/\n/) { token Text; reset_stack } + rule(/;/) { token Punctuation; reset_stack } + end + + state :root do + mixin :addr_range + end + + edot = /\\.|./m + + state :command do + mixin :whitespace + + # subst and transliteration + rule %r/(s)(.)(#{edot}*?)(\2)(#{edot}*?)(\2)/m do |m| + token Keyword, m[1] + token Punctuation, m[2] + delegate regex, m[3] + token Punctuation, m[4] + delegate replacement, m[5] + token Punctuation, m[6] + + + goto :flags + end + + rule %r/(y)(.)(#{edot}*?)(\2)(#{edot}*?)(\2)/m do |m| + token Keyword, m[1] + token Punctuation, m[2] + delegate replacement, m[3] + token Punctuation, m[4] + delegate replacement, m[5] + token Punctuation, m[6] + + pop! + end + + # commands that take a text segment as an argument + rule %r/([aic])(\s*)/ do + groups Keyword, Text; goto :text + end + + rule %r/[pd]/, Keyword + + # commands that take a number argument + rule %r/([qQl])(\s+)(\d+)/i do + groups Keyword, Text, Num + pop! + end + + # no-argument commands + rule %r/[={}dDgGhHlnpPqx]/, Keyword, :pop! + + # commands that take a filename argument + rule %r/([rRwW])(\s+)(\S+)/ do + groups Keyword, Text, Name + pop! + end + + # commands that take a label argument + rule %r/([:btT])(\s+)(\S+)/ do + groups Keyword, Text, Name::Label + pop! + end + end + + state :addr_range do + mixin :whitespace + + ### address ranges ### + addr_tok = Keyword::Namespace + rule %r/\d+/, addr_tok + rule %r/[$,~+!]/, addr_tok + + rule %r((/)((?:\\.|.)*?)(/)) do |m| + token addr_tok, m[1]; delegate regex, m[2]; token addr_tok, m[3] + end + + # alternate regex rage delimiters + rule %r((\\)(.)((?:\\.|.)*?)(\2)) do |m| + token addr_tok, m[1] + m[2] + delegate regex, m[3] + token addr_tok, m[4] + end + + rule(//) { push :command } + end + + state :text do + rule %r/[^\\\n]+/, Str + rule %r/\\\n/, Str::Escape + rule %r/\\/, Str + rule %r/\n/, Text, :pop! + end + + state :flags do + rule %r/[gp]+/, Keyword, :pop! + + # writing to a file with the subst command. + # who'da thunk...? + rule %r/([wW])(\s+)(\S+)/ do + token Keyword; token Text; token Name + end + + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/shell.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/shell.rb new file mode 100644 index 0000000..3704066 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/shell.rb @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Shell < RegexLexer + title "shell" + desc "Various shell languages, including sh and bash" + + tag 'shell' + aliases 'bash', 'zsh', 'ksh', 'sh' + filenames '*.sh', '*.bash', '*.zsh', '*.ksh', '.bashrc', + '.kshrc', '.profile', + '.zshenv', '.zprofile', '.zshrc', '.zlogin', '.zlogout', + 'zshenv', 'zprofile', 'zshrc', 'zlogin', 'zlogout', + 'APKBUILD', 'PKGBUILD', '*.ebuild', + '*.eclass', '*.exheres-0', '*.exlib' + + mimetypes 'application/x-sh', 'application/x-shellscript', 'text/x-sh', + 'text/x-shellscript' + + def self.detect?(text) + return true if text.shebang?(/(ba|z|k)?sh/) + return true if text.start_with?('#compdef', '#autoload') + end + + KEYWORDS = %w( + if fi else while do done for then return function + select continue until esac elif in + ).join('|') + + BUILTINS = %w( + alias bg bind break builtin caller cd command compgen + complete declare dirs disown enable eval exec exit + export false fc fg getopts hash help history jobs let + local logout mapfile popd pushd pwd read readonly set + shift shopt source suspend test time times trap true type + typeset ulimit umask unalias unset wait + + cat tac nl od base32 base64 fmt pr fold head tail split csplit + wc sum cksum b2sum md5sum sha1sum sha224sum sha256sum sha384sum + sha512sum sort shuf uniq comm ptx tsort cut paste join tr expand + unexpand ls dir vdir dircolors cp dd install mv rm shred link ln + mkdir mkfifo mknod readlink rmdir unlink chown chgrp chmod touch + df du stat sync truncate echo printf yes expr tee basename dirname + pathchk mktemp realpath pwd stty printenv tty id logname whoami + groups users who date arch nproc uname hostname hostid uptime chcon + runcon chroot env nice nohup stdbuf timeout kill sleep factor numfmt + seq tar grep sudo awk sed gzip gunzip + ).join('|') + + state :basic do + rule %r/#.*$/, Comment + + rule %r/\b(#{KEYWORDS})\s*\b/, Keyword + rule %r/\bcase\b/, Keyword, :case + + rule %r/\b(#{BUILTINS})\s*\b(?!(\.|-))/, Name::Builtin + rule %r/[.](?=\s)/, Name::Builtin + + rule %r/(\b\w+)(=)/ do + groups Name::Variable, Operator + end + + rule %r/[\[\]{}()!=>]/, Operator + rule %r/&&|\|\|/, Operator + + # here-string + rule %r/<< ruby, + 'erb' => ERB.new(options), + 'javascript' => Javascript.new(options), + 'css' => CSS.new(options), + 'coffee' => Coffeescript.new(options), + 'markdown' => Markdown.new(options), + 'scss' => Scss.new(options), + 'sass' => Sass.new(options) + } + end + + start { ruby.reset!; html.reset! } + + state :root do + rule %r/\s*\n/, Text + rule(/\s*/) { |m| token Text; indentation(m[0]) } + end + + state :content do + mixin :css + + rule %r/\/#{dot}*/, Comment, :indented_block + + rule %r/(doctype)(\s+)(.*)/ do + groups Name::Namespace, Text::Whitespace, Text + pop! + end + + # filters, shamelessly ripped from HAML + rule %r/(\w*):\s*\n/ do |m| + token Name::Decorator + pop! + starts_block :filter_block + + filter_name = m[1].strip + + @filter_lexer = self.filters[filter_name] + @filter_lexer.reset! unless @filter_lexer.nil? + + puts " slim: filter #{filter_name.inspect} #{@filter_lexer.inspect}" if @debug + end + + # Text + rule %r([\|'](?=\s)) do + token Punctuation + pop! + starts_block :plain_block + goto :plain_block + end + + rule %r/-|==|=/, Punctuation, :ruby_line + + # Dynamic tags + rule %r/(\*)(#{ruby_chars}+\(.*?\))/ do |m| + token Punctuation, m[1] + delegate ruby, m[2] + push :tag + end + + rule %r/(\*)(#{ruby_chars}+)/ do |m| + token Punctuation, m[1] + delegate ruby, m[2] + push :tag + end + + #rule %r/<\w+(?=.*>)/, Keyword::Constant, :tag # Maybe do this, look ahead and stuff + rule %r(()) do |m| # Dirty html + delegate html, m[1] + pop! + end + + # Ordinary slim tags + rule %r/\w+/, Name::Tag, :tag + + end + + state :tag do + mixin :css + mixin :indented_block + mixin :interpolation + + # Whitespace control + rule %r/[<>]/, Punctuation + + # Trim whitespace + rule %r/\s+?/, Text::Whitespace + + # Splats, these two might be mergable? + rule %r/(\*)(#{ruby_chars}+)/ do |m| + token Punctuation, m[1] + delegate ruby, m[2] + end + + rule %r/(\*)(\{#{dot}+?\})/ do |m| + token Punctuation, m[1] + delegate ruby, m[2] + end + + # Attributes + rule %r/([\w\-]+)(\s*)(\=)/ do |m| + token Name::Attribute, m[1] + token Text::Whitespace, m[2] + token Punctuation, m[3] + push :html_attr + end + + # Ruby value + rule %r/(\=)(#{dot}+)/ do |m| + token Punctuation, m[1] + #token Keyword::Constant, m[2] + delegate ruby, m[2] + end + + # HTML Entities + rule(/&\S*?;/, Name::Entity) + + rule %r/#{dot}+?/, Text + + rule %r/\s*\n/, Text::Whitespace, :pop! + end + + state :css do + rule(/\.[\w-]*/) { token Name::Class; goto :tag } + rule(/#[a-zA-Z][\w:-]*/) { token Name::Function; goto :tag } + end + + state :html_attr do + # Strings, double/single quoted + rule(/\s*(['"])#{dot}*?\1/, Literal::String, :pop!) + + # Ruby stuff + rule(/(#{ruby_chars}+\(.*?\))/) { |m| delegate ruby, m[1]; pop! } + rule(/(#{ruby_chars}+)/) { |m| delegate ruby, m[1]; pop! } + + rule %r/\s+/, Text::Whitespace + end + + state :ruby_line do + # Need at top + mixin :indented_block + + rule(/[,\\]\s*\n/) { delegate ruby } + rule %r/[ ]\|[ \t]*\n/, Str::Escape + rule(/.*?(?=([,\\]$| \|)?[ \t]*$)/) { delegate ruby } + end + + state :filter_block do + rule %r/([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/ do + if @filter_lexer + delegate @filter_lexer + else + token Name::Decorator + end + end + + mixin :interpolation + mixin :indented_block + end + + state :plain_block do + mixin :interpolation + + rule %r(()) do |m| # Dirty html + delegate html, m[1] + end + + # HTML Entities + rule(/&\S*?;/, Name::Entity) + + #rule %r/([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/ do + rule %r/#{dot}+?/, Text + + mixin :indented_block + end + + state :interpolation do + rule %r/#[{]/, Str::Interpol, :ruby_interp + end + + state :ruby_interp do + rule %r/[}]/, Str::Interpol, :pop! + mixin :ruby_interp_inner + end + + state :ruby_interp_inner do + rule(/[{]/) { delegate ruby; push :ruby_interp_inner } + rule(/[}]/) { delegate ruby; pop! } + rule(/[^{}]+/) { delegate ruby } + end + + state :indented_block do + rule(/(?=|&!?,@%]) + + state :root do + rule %r/(<)(\w+:)(.*?)(>)/ do + groups Punctuation, Keyword, Text, Punctuation + end + + # mixin :squeak_fileout + mixin :whitespaces + mixin :method_definition + rule %r/([|])([\w\s]*)([|])/ do + groups Punctuation, Name::Variable, Punctuation + end + mixin :objects + rule %r/\^|:=|_/, Operator + + rule %r/[)}\]]/, Punctuation, :after_object + rule %r/[({\[!]/, Punctuation + end + + state :method_definition do + rule %r/([a-z]\w*:)(\s*)(\w+)/i do + groups Name::Function, Text, Name::Variable + end + + rule %r/^(\s*)(\b[a-z]\w*\b)(\s*)$/i do + groups Text, Name::Function, Text + end + + rule %r(^(\s*)(#{ops}+)(\s*)(\w+)(\s*)$) do + groups Text, Name::Function, Text, Name::Variable, Text + end + end + + state :block_variables do + mixin :whitespaces + rule %r/(:)(\s*)(\w+)/ do + groups Operator, Text, Name::Variable + end + + rule %r/[|]/, Punctuation, :pop! + + rule(//) { pop! } + end + + state :literals do + rule %r/'(''|.)*?'/m, Str, :after_object + rule %r/[$]./, Str::Char, :after_object + rule %r/#[(]/, Str::Symbol, :parenth + rule %r/(\d+r)?-?\d+(\.\d+)?(e-?\d+)?/, + Num, :after_object + rule %r/#("[^"]*"|#{ops}+|[\w:]+)/, + Str::Symbol, :after_object + end + + state :parenth do + rule %r/[)]/ do + token Str::Symbol + goto :after_object + end + + mixin :inner_parenth + end + + state :inner_parenth do + rule %r/#[(]/, Str::Symbol, :inner_parenth + rule %r/[)]/, Str::Symbol, :pop! + mixin :whitespaces + mixin :literals + rule %r/(#{ops}|[\w:])+/, Str::Symbol + end + + state :whitespaces do + rule %r/! !$/, Keyword # squeak chunk delimiter + rule %r/\s+/m, Text + rule %r/".*?"/m, Comment + end + + state :objects do + rule %r/\[/, Punctuation, :block_variables + rule %r/(self|super|true|false|nil|thisContext)\b/, + Name::Builtin::Pseudo, :after_object + rule %r/[A-Z]\w*(?!:)\b/, Name::Class, :after_object + rule %r/[a-z]\w*(?!:)\b/, Name::Variable, :after_object + mixin :literals + end + + state :after_object do + mixin :whitespaces + rule %r/(ifTrue|ifFalse|whileTrue|whileFalse|timesRepeat):/, + Name::Builtin, :pop! + rule %r/new(?!:)\b/, Name::Builtin + rule %r/:=|_/, Operator, :pop! + rule %r/[a-z]+\w*:/i, Name::Function, :pop! + rule %r/[a-z]+\w*/i, Name::Function + rule %r/#{ops}+/, Name::Function, :pop! + rule %r/[.]/, Punctuation, :pop! + rule %r/;/, Punctuation + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/smarty.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/smarty.rb new file mode 100644 index 0000000..9870e8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/smarty.rb @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Smarty < TemplateLexer + title "Smarty" + desc 'Smarty Template Engine' + tag 'smarty' + aliases 'smarty' + filenames '*.tpl', '*.smarty' + mimetypes 'application/x-smarty', 'text/x-smarty' + + def self.builtins + @builtins ||= %w( + append assign block call capture config_load debug extends + for foreach foreachelse break continue function if elseif + else include include_php insert ldelim rdelim literal nocache + php section sectionelse setfilter strip while + counter cycle eval fetch html_checkboxes html_image html_options + html_radios html_select_date html_select_time html_table + mailto math textformat + capitalize cat count_characters count_paragraphs + count_sentences count_words date_format default escape + from_charset indent lower nl2br regex_replace replace spacify + string_format strip strip_tags to_charset truncate unescape + upper wordwrap + ) + end + + + state :root do + rule(/\{\s+/) { delegate parent } + + # block comments + rule %r/\{\*.*?\*\}/m, Comment + + rule %r/\{\/?(?![\s*])/ do + token Keyword + push :smarty + end + + + rule(/.+?(?={[\/a-zA-Z0-9$#*"'])/m) { delegate parent } + rule(/.+/m) { delegate parent } + end + + state :comment do + rule(/{\*/) { token Comment; push } + rule(/\*}/) { token Comment; pop! } + rule(/[^{}]+/m) { token Comment } + end + + state :smarty do + # allow nested tags + rule %r/\{\/?(?![\s*])/ do + token Keyword + push :smarty + end + + rule %r/}/, Keyword, :pop! + rule %r/\s+/m, Text + rule %r([~!%^&*()+=|\[\]:;,.<>/@?-]), Operator + rule %r/#[a-zA-Z_]\w*#/, Name::Variable + rule %r/\$[a-zA-Z_]\w*(\.\w+)*/, Name::Variable + rule %r/(true|false|null)\b/, Keyword::Constant + rule %r/[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|0[xX][0-9a-fA-F]+[Ll]?/, Num + rule %r/"(\\.|.)*?"/, Str::Double + rule %r/'(\\.|.)*?'/, Str::Single + + rule %r/([a-zA-Z_]\w*)/ do |m| + if self.class.builtins.include? m[0] + token Name::Builtin + else + token Name::Attribute + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sml.rb new file mode 100644 index 0000000..08ed1bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sml.rb @@ -0,0 +1,345 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SML < RegexLexer + title "SML" + desc 'Standard ML' + tag 'sml' + aliases 'ml' + filenames '*.sml', '*.sig', '*.fun' + + mimetypes 'text/x-standardml', 'application/x-standardml' + + def self.keywords + @keywords ||= Set.new %w( + abstype and andalso as case datatype do else end exception + fn fun handle if in infix infixr let local nonfix of op open + orelse raise rec then type val with withtype while + eqtype functor include sharing sig signature struct structure + where + ) + end + + def self.symbolic_reserved + @symbolic_reserved ||= Set.new %w(: | = => -> # :>) + end + + id = /[\w']+/i + symbol = %r([!%&$#/:<=>?@\\~`^|*+-]+) + + state :whitespace do + rule %r/\s+/m, Text + rule %r/[(][*]/, Comment, :comment + end + + state :delimiters do + rule %r/[(\[{]/, Punctuation, :main + rule %r/[)\]}]/, Punctuation, :pop! + + rule %r/\b(let|if|local)\b(?!')/ do + token Keyword::Reserved + push; push + end + + rule %r/\b(struct|sig|while)\b(?!')/ do + token Keyword::Reserved + push + end + + rule %r/\b(do|else|end|in|then)\b(?!')/, Keyword::Reserved, :pop! + end + + def token_for_id_with_dot(id) + if self.class.keywords.include? id + Error + else + Name::Namespace + end + end + + def token_for_final_id(id) + if self.class.keywords.include? id or self.class.symbolic_reserved.include? id + Error + else + Name + end + end + + def token_for_id(id) + if self.class.keywords.include? id + Keyword::Reserved + elsif self.class.symbolic_reserved.include? id + Punctuation + else + Name + end + end + + state :core do + rule %r/[()\[\]{},;_]|[.][.][.]/, Punctuation + rule %r/#"/, Str::Char, :char + rule %r/"/, Str::Double, :string + rule %r/~?0x[0-9a-fA-F]+/, Num::Hex + rule %r/0wx[0-9a-fA-F]+/, Num::Hex + rule %r/0w\d+/, Num::Integer + rule %r/~?\d+([.]\d+)?[eE]~?\d+/, Num::Float + rule %r/~?\d+[.]\d+/, Num::Float + rule %r/~?\d+/, Num::Integer + + rule %r/#\s*[1-9][0-9]*/, Name::Label + rule %r/#\s*#{id}/, Name::Label + rule %r/#\s+#{symbol}/, Name::Label + + rule %r/\b(datatype|abstype)\b(?!')/, Keyword::Reserved, :dname + rule(/(?=\bexception\b(?!'))/) { push :ename } + rule %r/\b(functor|include|open|signature|structure)\b(?!')/, + Keyword::Reserved, :sname + rule %r/\b(type|eqtype)\b(?!')/, Keyword::Reserved, :tname + + rule %r/'#{id}/, Name::Decorator + rule %r/(#{id})([.])/ do |m| + groups(token_for_id_with_dot(m[1]), Punctuation) + push :dotted + end + + rule id do |m| + token token_for_id(m[0]) + end + + rule symbol do |m| + token token_for_id(m[0]) + end + end + + state :dotted do + rule %r/(#{id})([.])/ do |m| + groups(token_for_id_with_dot(m[1]), Punctuation) + end + + rule id do |m| + token token_for_id(m[0]) + pop! + end + + rule symbol do |m| + token token_for_id(m[0]) + pop! + end + end + + state :root do + rule %r/#!.*?\n/, Comment::Preproc + rule(//) { push :main } + end + + state :main do + mixin :whitespace + + rule %r/\b(val|and)\b(?!')/, Keyword::Reserved, :vname + rule %r/\b(fun)\b(?!')/ do + token Keyword::Reserved + goto :main_fun + push :fname + end + + mixin :delimiters + mixin :core + end + + state :main_fun do + mixin :whitespace + rule %r/\b(fun|and)\b(?!')/, Keyword::Reserved, :fname + rule %r/\bval\b(?!')/ do + token Keyword::Reserved + goto :main + push :vname + end + + rule %r/[|]/, Punctuation, :fname + rule %r/\b(case|handle)\b(?!')/ do + token Keyword::Reserved + goto :main + end + + mixin :delimiters + mixin :core + end + + state :has_escapes do + rule %r/\\[\\"abtnvfr]/, Str::Escape + rule %r/\\\^[\x40-\x5e]/, Str::Escape + rule %r/\\[0-9]{3}/, Str::Escape + rule %r/\\u\h{4}/, Str::Escape + rule %r/\\\s+\\/, Str::Interpol + end + + state :string do + rule %r/[^"\\]+/, Str::Double + rule %r/"/, Str::Double, :pop! + mixin :has_escapes + end + + state :char do + rule %r/[^"\\]+/, Str::Char + rule %r/"/, Str::Char, :pop! + mixin :has_escapes + end + + state :breakout do + rule %r/(?=\b(#{SML.keywords.to_a.join('|')})\b(?!'))/ do + pop! + end + end + + state :sname do + mixin :whitespace + mixin :breakout + rule id, Name::Namespace + rule(//) { pop! } + end + + state :has_annotations do + rule %r/'[\w']*/, Name::Decorator + rule %r/[(]/, Punctuation, :tyvarseq + end + + state :fname do + mixin :whitespace + mixin :has_annotations + + rule id, Name::Function, :pop! + rule symbol, Name::Function, :pop! + end + + state :vname do + mixin :whitespace + mixin :has_annotations + + rule %r/(#{id})(\s*)(=(?!#{symbol}))/m do + groups Name::Variable, Text, Punctuation + pop! + end + + rule %r/(#{symbol})(\s*)(=(?!#{symbol}))/m do + groups Name::Variable, Text, Punctuation + end + + rule id, Name::Variable, :pop! + rule symbol, Name::Variable, :pop! + + rule(//) { pop! } + end + + state :tname do + mixin :whitespace + mixin :breakout + mixin :has_annotations + + rule %r/'[\w']*/, Name::Decorator + rule %r/[(]/, Punctuation, :tyvarseq + + rule %r(=(?!#{symbol})) do + token Punctuation + goto :typbind + end + + rule id, Keyword::Type + rule symbol, Keyword::Type + end + + state :typbind do + mixin :whitespace + + rule %r/\b(and)\b(?!')/ do + token Keyword::Reserved + goto :tname + end + + mixin :breakout + mixin :core + end + + state :dname do + mixin :whitespace + mixin :breakout + mixin :has_annotations + + rule %r/(=)(\s*)(datatype)\b/ do + groups Punctuation, Text, Keyword::Reserved + pop! + end + + rule %r(=(?!#{symbol})) do + token Punctuation + goto :datbind + push :datcon + end + + rule id, Keyword::Type + rule symbol, Keyword::Type + end + + state :datbind do + mixin :whitespace + rule %r/\b(and)\b(?!')/ do + token Keyword::Reserved; goto :dname + end + rule %r/\b(withtype)\b(?!')/ do + token Keyword::Reserved; goto :tname + end + rule %r/\bof\b(?!')/, Keyword::Reserved + rule %r/([|])(\s*)(#{id})/ do + groups(Punctuation, Text, Name::Class) + end + + rule %r/([|])(\s+)(#{symbol})/ do + groups(Punctuation, Text, Name::Class) + end + + mixin :breakout + mixin :core + end + + state :ename do + mixin :whitespace + rule %r/(exception|and)(\s+)(#{id})/ do + groups Keyword::Reserved, Text, Name::Class + end + + rule %r/(exception|and)(\s*)(#{symbol})/ do + groups Keyword::Reserved, Text, Name::Class + end + + rule %r/\b(of)\b(?!')/, Keyword::Reserved + mixin :breakout + mixin :core + end + + state :datcon do + mixin :whitespace + rule id, Name::Class, :pop! + rule symbol, Name::Class, :pop! + end + + state :tyvarseq do + mixin :whitespace + rule %r/'[\w']*/, Name::Decorator + rule id, Name + rule %r/,/, Punctuation + rule %r/[)]/, Punctuation, :pop! + rule symbol, Name + end + + state :comment do + rule %r/[^(*)]+/, Comment::Multiline + rule %r/[(][*]/ do + token Comment::Multiline; push + end + rule %r/[*][)]/, Comment::Multiline, :pop! + rule %r/[(*)]/, Comment::Multiline + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sparql.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sparql.rb new file mode 100644 index 0000000..77b664f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sparql.rb @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SPARQL < RegexLexer + title "SPARQL" + desc "Semantic Query Language, for RDF data" + tag 'sparql' + filenames '*.rq' + mimetypes 'application/sparql-query' + + def self.builtins + @builtins = Set.new %w[ + ABS AVG BNODE BOUND CEIL COALESCE CONCAT CONTAINS COUNT DATATYPE DAY + ENCODE_FOR_URI FLOOR GROUP_CONCAT HOURS IF IRI isBLANK isIRI + isLITERAL isNUMERIC isURI LANG LANGMATCHES LCASE MAX MD5 MIN MINUTES + MONTH NOW RAND REGEX REPLACE ROUND SAMETERM SAMPLE SECONDS SEPARATOR + SHA1 SHA256 SHA384 SHA512 STR STRAFTER STRBEFORE STRDT STRENDS + STRLANG STRLEN STRSTARTS STRUUID SUBSTR SUM TIMEZONE TZ UCASE URI + UUID YEAR + ] + end + + def self.keywords + @keywords = Set.new %w[ + ADD ALL AS ASC ASK BASE BIND BINDINGS BY CLEAR CONSTRUCT COPY CREATE + DATA DEFAULT DELETE DESC DESCRIBE DISTINCT DROP EXISTS FILTER FROM + GRAPH GROUP BY HAVING IN INSERT LIMIT LOAD MINUS MOVE NAMED NOT + OFFSET OPTIONAL ORDER PREFIX SELECT REDUCED SERVICE SILENT TO UNDEF + UNION USING VALUES WHERE WITH + ] + end + + state :root do + rule %r(\s+)m, Text::Whitespace + rule %r(#.*), Comment::Single + + rule %r("""), Str::Double, :string_double_literal + rule %r("), Str::Double, :string_double + rule %r('''), Str::Single, :string_single_literal + rule %r('), Str::Single, :string_single + + rule %r([$?][[:word:]]+), Name::Variable + rule %r(([[:word:]-]*)(:)([[:word:]-]+)?) do |m| + token Name::Namespace, m[1] + token Operator, m[2] + token Str::Symbol, m[3] + end + rule %r(<[^>]*>), Name::Namespace + rule %r(true|false)i, Keyword::Constant + rule %r/a\b/, Keyword + + rule %r([A-Z][[:word:]]+\b)i do |m| + if self.class.builtins.include? m[0].upcase + token Name::Builtin + elsif self.class.keywords.include? m[0].upcase + token Keyword + else + token Error + end + end + + rule %r([+\-]?(?:\d+\.\d*|\.\d+)(?:[e][+\-]?[0-9]+)?)i, Num::Float + rule %r([+\-]?\d+), Num::Integer + rule %r([\]\[(){}.,;=]), Punctuation + rule %r([/?*+=!<>]|&&|\|\||\^\^), Operator + end + + state :string_double_common do + mixin :string_escapes + rule %r(\\), Str::Double + rule %r([^"\\]+), Str::Double + end + + state :string_double do + rule %r(") do + token Str::Double + goto :string_end + end + mixin :string_double_common + end + + state :string_double_literal do + rule %r(""") do + token Str::Double + goto :string_end + end + rule %r("), Str::Double + mixin :string_double_common + end + + state :string_single_common do + mixin :string_escapes + rule %r(\\), Str::Single + rule %r([^'\\]+), Str::Single + end + + state :string_single do + rule %r(') do + token Str::Single + goto :string_end + end + mixin :string_single_common + end + + state :string_single_literal do + rule %r(''') do + token Str::Single + goto :string_end + end + rule %r('), Str::Single + mixin :string_single_common + end + + state :string_escapes do + rule %r(\\[tbnrf"'\\]), Str::Escape + rule %r(\\u\h{4}), Str::Escape + rule %r(\\U\h{8}), Str::Escape + end + + state :string_end do + rule %r((@)([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)) do + groups Operator, Name::Property + end + rule %r(\^\^), Operator + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf.rb new file mode 100644 index 0000000..331dafc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf.rb @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SQF < RegexLexer + tag "sqf" + filenames "*.sqf" + + title "SQF" + desc "Status Quo Function, a Real Virtuality engine scripting language" + + def self.wordoperators + @wordoperators ||= Set.new %w( + and or not + ) + end + + def self.initializers + @initializers ||= Set.new %w( + private param params + ) + end + + def self.controlflow + @controlflow ||= Set.new %w( + if then else exitwith switch do case default while for from to step + foreach + ) + end + + def self.constants + @constants ||= Set.new %w( + true false player confignull controlnull displaynull grpnull + locationnull netobjnull objnull scriptnull tasknull teammembernull + ) + end + + def self.namespaces + @namespaces ||= Set.new %w( + currentnamespace missionnamespace parsingnamespace profilenamespace + uinamespace + ) + end + + def self.diag_commands + @diag_commands ||= Set.new %w( + diag_activemissionfsms diag_activesqfscripts diag_activesqsscripts + diag_activescripts diag_captureframe diag_captureframetofile + diag_captureslowframe diag_codeperformance diag_drawmode diag_enable + diag_enabled diag_fps diag_fpsmin diag_frameno diag_lightnewload + diag_list diag_log diag_logslowframe diag_mergeconfigfile + diag_recordturretlimits diag_setlightnew diag_ticktime diag_toggle + ) + end + + def self.commands + Kernel::load File.join(Lexers::BASE_DIR, "sqf/keywords.rb") + commands + end + + state :root do + # Whitespace + rule %r"\s+", Text + + # Preprocessor instructions + rule %r"/\*.*?\*/"m, Comment::Multiline + rule %r"//.*", Comment::Single + rule %r"#(define|undef|if(n)?def|else|endif|include)", Comment::Preproc + rule %r"\\\r?\n", Comment::Preproc + rule %r"__(EVAL|EXEC|LINE__|FILE__)", Name::Builtin + + # Literals + rule %r"\".*?\"", Literal::String + rule %r"'.*?'", Literal::String + rule %r"(\$|0x)[0-9a-fA-F]+", Literal::Number::Hex + rule %r"[0-9]+(\.)?(e[0-9]+)?", Literal::Number::Float + + # Symbols + rule %r"[\!\%\&\*\+\-\/\<\=\>\^\|\#]", Operator + rule %r"[\(\)\{\}\[\]\,\:\;]", Punctuation + + # Identifiers (variables and functions) + rule %r"[a-zA-Z0-9_]+" do |m| + name = m[0].downcase + if self.class.wordoperators.include? name + token Operator::Word + elsif self.class.initializers.include? name + token Keyword::Declaration + elsif self.class.controlflow.include? name + token Keyword::Reserved + elsif self.class.constants.include? name + token Keyword::Constant + elsif self.class.namespaces.include? name + token Keyword::Namespace + elsif self.class.diag_commands.include? name + token Name::Function + elsif self.class.commands.include? name + token Name::Function + elsif %r"_.+" =~ name + token Name::Variable + else + token Name::Variable::Global + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf/keywords.rb new file mode 100644 index 0000000..c390dd6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sqf/keywords.rb @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SQF + def self.commands + @commands ||= Set.new ["abs", "acos", "actionids", "actionkeys", "actionkeysimages", "actionkeysnames", "actionkeysnamesarray", "actionname", "activateaddons", "activatekey", "add3denconnection", "add3deneventhandler", "addcamshake", "addforcegeneratorrtd", "additempool", "addmagazinepool", "addmissioneventhandler", "addmusiceventhandler", "addswitchableunit", "addtoremainscollector", "addweaponpool", "admin", "agent", "agltoasl", "aimpos", "airdensityrtd", "airplanethrottle", "airportside", "aisfinishheal", "alive", "allcontrols", "allmissionobjects", "allsimpleobjects", "allturrets", "allturrets", "allvariables", "allvariables", "allvariables", "allvariables", "allvariables", "allvariables", "allvariables", "animationnames", "animationstate", "asin", "asltoagl", "asltoatl", "assert", "assignedcargo", "assignedcommander", "assigneddriver", "assignedgunner", "assigneditems", "assignedtarget", "assignedteam", "assignedvehicle", "assignedvehiclerole", "atan", "atg", "atltoasl", "attachedobject", "attachedobjects", "attachedto", "attackenabled", "backpack", "backpackcargo", "backpackcontainer", "backpackitems", "backpackmagazines", "behaviour", "binocular", "boundingbox", "boundingboxreal", "boundingcenter", "breakout", "breakto", "buldozer_enableroaddiag", "buldozer_loadnewroads", "buttonaction", "buttonaction", "buttonsetaction", "calculatepath", "calculateplayervisibilitybyfriendly", "call", "camcommitted", "camdestroy", "cameraeffectenablehud", "camerainterest", "campreloaded", "camtarget", "camusenvg", "cancelsimpletaskdestination", "canfire", "canmove", "canstand", "cantriggerdynamicsimulation", "canunloadincombat", "captive", "captivenum", "case", "cbchecked", "ceil", "channelenabled", "checkaifeature", "classname", "clear3deninventory", "clearallitemsfrombackpack", "clearbackpackcargo", "clearbackpackcargoglobal", "cleargroupicons", "clearitemcargo", "clearitemcargoglobal", "clearmagazinecargo", "clearmagazinecargoglobal", "clearoverlay", "clearweaponcargo", "clearweaponcargoglobal", "closedialog", "closeoverlay", "collapseobjecttree", "collect3denhistory", "collectivertd", "combatmode", "commander", "commandgetout", "commandstop", "comment", "commitoverlay", "compile", "compilefinal", "completedfsm", "composetext", "confighierarchy", "configname", "configproperties", "configsourceaddonlist", "configsourcemod", "configsourcemodlist", "copytoclipboard", "cos", "count", "count", "count", "create3dencomposition", "create3denentity", "createagent", "createcenter", "createdialog", "creatediarylink", "creategeardialog", "creategroup", "createguardedpoint", "createlocation", "createmarker", "createmarkerlocal", "createmine", "createsimpleobject", "createsoundsource", "createteam", "createtrigger", "createvehicle", "createvehiclecrew", "crew", "ctaddheader", "ctaddrow", "ctclear", "ctcursel", "ctheadercount", "ctrlactivate", "ctrlangle", "ctrlautoscrolldelay", "ctrlautoscrollrewind", "ctrlautoscrollspeed", "ctrlchecked", "ctrlclassname", "ctrlcommitted", "ctrldelete", "ctrlenable", "ctrlenabled", "ctrlenabled", "ctrlfade", "ctrlhtmlloaded", "ctrlidc", "ctrlidd", "ctrlmapanimclear", "ctrlmapanimcommit", "ctrlmapanimdone", "ctrlmapmouseover", "ctrlmapscale", "ctrlmodel", "ctrlmodeldirandup", "ctrlmodelscale", "ctrlparent", "ctrlparentcontrolsgroup", "ctrlposition", "ctrlscale", "ctrlsetfocus", "ctrlsettext", "ctrlshow", "ctrlshown", "ctrltext", "ctrltext", "ctrltextheight", "ctrltextsecondary", "ctrltextwidth", "ctrltype", "ctrlvisible", "ctrowcount", "curatoraddons", "curatorcameraarea", "curatorcameraareaceiling", "curatoreditableobjects", "curatoreditingarea", "curatoreditingareatype", "curatorpoints", "curatorregisteredobjects", "curatorwaypointcost", "currentcommand", "currentmagazine", "currentmagazinedetail", "currentmuzzle", "currentpilot", "currenttask", "currenttasks", "currentthrowable", "currentvisionmode", "currentwaypoint", "currentweapon", "currentweaponmode", "currentzeroing", "cutobj", "cutrsc", "cuttext", "damage", "datetonumber", "deactivatekey", "debriefingtext", "debuglog", "decaygraphvalues", "default", "deg", "delete3denentities", "deletecenter", "deletecollection", "deletegroup", "deleteidentity", "deletelocation", "deletemarker", "deletemarkerlocal", "deletesite", "deletestatus", "deleteteam", "deletevehicle", "deletewaypoint", "detach", "detectedmines", "diag_captureframe", "diag_captureframetofile", "diag_captureslowframe", "diag_codeperformance", "diag_dynamicsimulationend", "diag_lightnewload", "diag_log", "diag_logslowframe", "diag_setlightnew", "didjipowner", "difficultyenabled", "difficultyoption", "direction", "direction", "disablemapindicators", "disableremotesensors", "disableuserinput", "displayparent", "dissolveteam", "do3denaction", "dogetout", "dostop", "drawicon3d", "drawline3d", "driver", "drop", "dynamicsimulationdistance", "dynamicsimulationdistancecoef", "dynamicsimulationenabled", "dynamicsimulationenabled", "echo", "edit3denmissionattributes", "effectivecommander", "enableaudiofeature", "enablecamshake", "enablecaustics", "enabledebriefingstats", "enablediaglegend", "enabledynamicsimulationsystem", "enableengineartillery", "enableenvironment", "enableradio", "enablesatnormalondetail", "enablesaving", "enablesentences", "enablestressdamage", "enableteamswitch", "enabletraffic", "enableweapondisassembly", "endmission", "enginesisonrtd", "enginespowerrtd", "enginesrpmrtd", "enginestorquertd", "entities", "entities", "estimatedtimeleft", "everybackpack", "everycontainer", "execfsm", "execvm", "exp", "expecteddestination", "exportjipmessages", "eyedirection", "eyepos", "face", "faction", "failmission", "fillweaponsfrompool", "finddisplay", "finite", "firstbackpack", "flag", "flaganimationphase", "flagowner", "flagside", "flagtexture", "fleeing", "floor", "for", "for", "forceatpositionrtd", "forcegeneratorrtd", "forcemap", "forcerespawn", "format", "formation", "formation", "formationdirection", "formationleader", "formationmembers", "formationposition", "formationtask", "formattext", "formleader", "fromeditor", "fuel", "fullcrew", "fullcrew", "gearidcammocount", "gearslotammocount", "gearslotdata", "get3denactionstate", "get3denconnections", "get3denentity", "get3denentityid", "get3dengrid", "get3denlayerentities", "get3denselected", "getaimingcoef", "getallenvsoundcontrollers", "getallhitpointsdamage", "getallownedmines", "getallsoundcontrollers", "getammocargo", "getanimaimprecision", "getanimspeedcoef", "getarray", "getartilleryammo", "getassignedcuratorlogic", "getassignedcuratorunit", "getbackpackcargo", "getbleedingremaining", "getburningvalue", "getcameraviewdirection", "getcenterofmass", "getconnecteduav", "getcontainermaxload", "getcustomaimcoef", "getcustomsoundcontroller", "getcustomsoundcontrollercount", "getdammage", "getdescription", "getdir", "getdirvisual", "getdiverstate", "getdlcassetsusagebyname", "getdlcs", "getdlcusagetime", "geteditorcamera", "geteditormode", "getenginetargetrpmrtd", "getfatigue", "getfieldmanualstartpage", "getforcedflagtexture", "getfuelcargo", "getgraphvalues", "getgroupiconparams", "getgroupicons", "getitemcargo", "getmagazinecargo", "getmarkercolor", "getmarkerpos", "getmarkerpos", "getmarkersize", "getmarkertype", "getmass", "getmissionconfig", "getmissionconfigvalue", "getmissionlayerentities", "getmissionpath", "getmodelinfo", "getnumber", "getobjectdlc", "getobjectfov", "getobjectmaterials", "getobjecttextures", "getobjecttype", "getoxygenremaining", "getpersonuseddlcs", "getpilotcameradirection", "getpilotcameraposition", "getpilotcamerarotation", "getpilotcameratarget", "getplatenumber", "getplayerchannel", "getplayerscores", "getplayeruid", "getpos", "getpos", "getposasl", "getposaslvisual", "getposaslw", "getposatl", "getposatlvisual", "getposvisual", "getposworld", "getposworldvisual", "getpylonmagazines", "getrepaircargo", "getrotorbrakertd", "getshotparents", "getslingload", "getstamina", "getstatvalue", "getsuppression", "getterrainheightasl", "gettext", "gettrimoffsetrtd", "getunitloadout", "getunitloadout", "getunitloadout", "getusermfdtext", "getusermfdvalue", "getvehiclecargo", "getweaponcargo", "getweaponsway", "getwingsorientationrtd", "getwingspositionrtd", "getwppos", "goggles", "goto", "group", "groupfromnetid", "groupid", "groupowner", "groupselectedunits", "gunner", "handgunitems", "handgunmagazine", "handgunweapon", "handshit", "haspilotcamera", "hcallgroups", "hcleader", "hcremoveallgroups", "hcselected", "hcshowbar", "headgear", "hidebody", "hideobject", "hideobjectglobal", "hint", "hintc", "hintcadet", "hintsilent", "hmd", "hostmission", "if", "image", "importallgroups", "importance", "incapacitatedstate", "inflamed", "infopanel", "infopanels", "ingameuiseteventhandler", "inheritsfrom", "inputaction", "isabletobreathe", "isagent", "isaimprecisionenabled", "isarray", "isautohoveron", "isautonomous", "isautostartupenabledrtd", "isautotrimonrtd", "isbleeding", "isburning", "isclass", "iscollisionlighton", "iscopilotenabled", "isdamageallowed", "isdlcavailable", "isengineon", "isforcedwalk", "isformationleader", "isgroupdeletedwhenempty", "ishidden", "isinremainscollector", "iskeyactive", "islaseron", "islighton", "islocalized", "ismanualfire", "ismarkedforcollection", "isnil", "isnull", "isnull", "isnull", "isnull", "isnull", "isnull", "isnull", "isnull", "isnull", "isnumber", "isobjecthidden", "isobjectrtd", "isonroad", "isplayer", "isrealtime", "isshowing3dicons", "issimpleobject", "issprintallowed", "isstaminaenabled", "istext", "istouchingground", "isturnedout", "isuavconnected", "isvehiclecargo", "isvehicleradaron", "iswalking", "isweapondeployed", "isweaponrested", "itemcargo", "items", "itemswithmagazines", "keyimage", "keyname", "landresult", "lasertarget", "lbadd", "lbclear", "lbclear", "lbcolor", "lbcolorright", "lbcursel", "lbcursel", "lbdata", "lbdelete", "lbpicture", "lbpictureright", "lbselection", "lbsetcolor", "lbsetcolorright", "lbsetcursel", "lbsetdata", "lbsetpicture", "lbsetpicturecolor", "lbsetpicturecolordisabled", "lbsetpicturecolorselected", "lbsetpictureright", "lbsetselectcolor", "lbsetselectcolorright", "lbsettext", "lbsettooltip", "lbsetvalue", "lbsize", "lbsize", "lbsort", "lbsort", "lbsort", "lbsortbyvalue", "lbsortbyvalue", "lbtext", "lbtextright", "lbvalue", "leader", "leader", "leader", "leaderboarddeinit", "leaderboardgetrows", "leaderboardinit", "leaderboardrequestrowsfriends", "leaderboardrequestrowsglobal", "leaderboardrequestrowsglobalarounduser", "leaderboardsrequestuploadscore", "leaderboardsrequestuploadscorekeepbest", "leaderboardstate", "lifestate", "lightdetachobject", "lightison", "linearconversion", "lineintersects", "lineintersectsobjs", "lineintersectssurfaces", "lineintersectswith", "list", "listremotetargets", "listvehiclesensors", "ln", "lnbaddarray", "lnbaddcolumn", "lnbaddrow", "lnbclear", "lnbclear", "lnbcolor", "lnbcolorright", "lnbcurselrow", "lnbcurselrow", "lnbdata", "lnbdeletecolumn", "lnbdeleterow", "lnbgetcolumnsposition", "lnbgetcolumnsposition", "lnbpicture", "lnbpictureright", "lnbsetcolor", "lnbsetcolorright", "lnbsetcolumnspos", "lnbsetcurselrow", "lnbsetdata", "lnbsetpicture", "lnbsetpicturecolor", "lnbsetpicturecolorright", "lnbsetpicturecolorselected", "lnbsetpicturecolorselectedright", "lnbsetpictureright", "lnbsettext", "lnbsettextright", "lnbsettooltip", "lnbsetvalue", "lnbsize", "lnbsize", "lnbsort", "lnbsortbyvalue", "lnbtext", "lnbtextright", "lnbvalue", "load", "loadabs", "loadbackpack", "loadfile", "loaduniform", "loadvest", "local", "local", "localize", "locationposition", "locked", "lockeddriver", "lockidentity", "log", "lognetwork", "lognetworkterminate", "magazinecargo", "magazines", "magazinesallturrets", "magazinesammo", "magazinesammocargo", "magazinesammofull", "magazinesdetail", "magazinesdetailbackpack", "magazinesdetailuniform", "magazinesdetailvest", "mapanimadd", "mapcenteroncamera", "mapgridposition", "markeralpha", "markerbrush", "markercolor", "markerdir", "markerpos", "markerpos", "markershape", "markersize", "markertext", "markertype", "matrixtranspose", "members", "menuaction", "menuadd", "menuchecked", "menuclear", "menuclear", "menucollapse", "menudata", "menudelete", "menuenable", "menuenabled", "menuexpand", "menuhover", "menuhover", "menupicture", "menusetaction", "menusetcheck", "menusetdata", "menusetpicture", "menusetvalue", "menushortcut", "menushortcuttext", "menusize", "menusort", "menutext", "menuurl", "menuvalue", "mineactive", "missiletarget", "missiletargetpos", "modparams", "moonphase", "morale", "move3dencamera", "moveout", "movetime", "movetocompleted", "movetofailed", "name", "name", "namesound", "nearestbuilding", "nearestbuilding", "nearestlocation", "nearestlocations", "nearestlocationwithdubbing", "nearestobject", "nearestobjects", "nearestterrainobjects", "needreload", "netid", "netid", "nextmenuitemindex", "not", "numberofenginesrtd", "numbertodate", "objectcurators", "objectfromnetid", "objectparent", "onbriefinggroup", "onbriefingnotes", "onbriefingplan", "onbriefingteamswitch", "oncommandmodechanged", "oneachframe", "ongroupiconclick", "ongroupiconoverenter", "ongroupiconoverleave", "onhcgroupselectionchanged", "onmapsingleclick", "onplayerconnected", "onplayerdisconnected", "onpreloadfinished", "onpreloadstarted", "onteamswitch", "opendlcpage", "openmap", "openmap", "opensteamapp", "openyoutubevideo", "owner", "param", "params", "parsenumber", "parsenumber", "parsesimplearray", "parsetext", "pickweaponpool", "pitch", "playableslotsnumber", "playersnumber", "playmission", "playmusic", "playmusic", "playscriptedmission", "playsound", "playsound", "playsound3d", "position", "position", "positioncameratoworld", "ppeffectcommitted", "ppeffectcommitted", "ppeffectcreate", "ppeffectdestroy", "ppeffectdestroy", "ppeffectenabled", "precision", "preloadcamera", "preloadsound", "preloadtitleobj", "preloadtitlersc", "preprocessfile", "preprocessfilelinenumbers", "primaryweapon", "primaryweaponitems", "primaryweaponmagazine", "priority", "private", "processdiarylink", "progressloadingscreen", "progressposition", "publicvariable", "publicvariableserver", "putweaponpool", "queryitemspool", "querymagazinepool", "queryweaponpool", "rad", "radiochannelcreate", "random", "random", "rank", "rankid", "rating", "rectangular", "registeredtasks", "reload", "reloadenabled", "remoteexec", "remoteexeccall", "remove3denconnection", "remove3deneventhandler", "remove3denlayer", "removeall3deneventhandlers", "removeallactions", "removeallassigneditems", "removeallcontainers", "removeallcuratoraddons", "removeallcuratorcameraareas", "removeallcuratoreditingareas", "removeallhandgunitems", "removeallitems", "removeallitemswithmagazines", "removeallmissioneventhandlers", "removeallmusiceventhandlers", "removeallownedmines", "removeallprimaryweaponitems", "removeallweapons", "removebackpack", "removebackpackglobal", "removefromremainscollector", "removegoggles", "removeheadgear", "removemissioneventhandler", "removemusiceventhandler", "removeswitchableunit", "removeuniform", "removevest", "requiredversion", "resetsubgroupdirection", "resources", "restarteditorcamera", "reverse", "roadat", "roadsconnectedto", "roledescription", "ropeattachedobjects", "ropeattachedto", "ropeattachenabled", "ropecreate", "ropecut", "ropedestroy", "ropeendposition", "ropelength", "ropes", "ropeunwind", "ropeunwound", "rotorsforcesrtd", "rotorsrpmrtd", "round", "save3deninventory", "saveoverlay", "savevar", "scopename", "score", "scoreside", "screenshot", "screentoworld", "scriptdone", "scriptname", "scudstate", "secondaryweapon", "secondaryweaponitems", "secondaryweaponmagazine", "selectbestplaces", "selectededitorobjects", "selectionnames", "selectmax", "selectmin", "selectplayer", "selectrandom", "selectrandomweighted", "sendaumessage", "sendudpmessage", "servercommand", "servercommandavailable", "servercommandexecutable", "set3denattributes", "set3dengrid", "set3deniconsvisible", "set3denlinesvisible", "set3denmissionattributes", "set3denmodelsvisible", "set3denselected", "setacctime", "setaperture", "setaperturenew", "setarmorypoints", "setcamshakedefparams", "setcamshakeparams", "setcompassoscillation", "setcurrentchannel", "setcustommissiondata", "setcustomsoundcontroller", "setdate", "setdefaultcamera", "setdetailmapblendpars", "setgroupiconsselectable", "setgroupiconsvisible", "sethorizonparallaxcoef", "sethudmovementlevels", "setinfopanel", "setlocalwindparams", "setmouseposition", "setmusiceventhandler", "setobjectviewdistance", "setobjectviewdistance", "setplayable", "setplayerrespawntime", "setshadowdistance", "setsimulweatherlayers", "setstaminascheme", "setstatvalue", "setsystemofunits", "setterraingrid", "settimemultiplier", "settrafficdensity", "settrafficdistance", "settrafficgap", "settrafficspeed", "setviewdistance", "setwind", "setwinddir", "showchat", "showcinemaborder", "showcommandingmenu", "showcompass", "showcuratorcompass", "showgps", "showhud", "showhud", "showmap", "showpad", "showradio", "showscoretable", "showsubtitles", "showuavfeed", "showwarrant", "showwatch", "showwaypoints", "side", "side", "side", "simpletasks", "simulationenabled", "simulclouddensity", "simulcloudocclusion", "simulinclouds", "sin", "size", "sizeof", "skill", "skiptime", "sleep", "sliderposition", "sliderposition", "sliderrange", "sliderrange", "slidersetposition", "slidersetrange", "slidersetspeed", "sliderspeed", "sliderspeed", "soldiermagazines", "someammo", "speaker", "speed", "speedmode", "sqrt", "squadparams", "stance", "startloadingscreen", "stopenginertd", "stopped", "str", "supportinfo", "surfaceiswater", "surfacenormal", "surfacetype", "switch", "switchcamera", "synchronizedobjects", "synchronizedtriggers", "synchronizedwaypoints", "synchronizedwaypoints", "systemchat", "tan", "taskalwaysvisible", "taskchildren", "taskcompleted", "taskcustomdata", "taskdescription", "taskdestination", "taskhint", "taskmarkeroffset", "taskparent", "taskresult", "taskstate", "tasktype", "teammember", "teamname", "teamtype", "terminate", "terrainintersect", "terrainintersectasl", "terrainintersectatasl", "text", "text", "textlog", "textlogformat", "tg", "throw", "titlecut", "titlefadeout", "titleobj", "titlersc", "titletext", "toarray", "tofixed", "tolower", "toloweransi", "tostring", "toupper", "toupperansi", "triggeractivated", "triggeractivation", "triggerammo", "triggerarea", "triggerattachedvehicle", "triggerstatements", "triggertext", "triggertimeout", "triggertimeoutcurrent", "triggertype", "try", "tvadd", "tvclear", "tvclear", "tvcollapse", "tvcollapseall", "tvcollapseall", "tvcount", "tvcursel", "tvcursel", "tvdata", "tvdelete", "tvexpand", "tvexpandall", "tvexpandall", "tvpicture", "tvpictureright", "tvsetcursel", "tvsetdata", "tvsetpicture", "tvsetpicturecolor", "tvsetpictureright", "tvsetpicturerightcolor", "tvsettext", "tvsettooltip", "tvsetvalue", "tvsort", "tvsortbyvalue", "tvtext", "tvtooltip", "tvvalue", "type", "type", "typename", "typeof", "uavcontrol", "uisleep", "unassigncurator", "unassignteam", "unassignvehicle", "underwater", "uniform", "uniformcontainer", "uniformitems", "uniformmagazines", "unitaddons", "unitaimposition", "unitaimpositionvisual", "unitbackpack", "unitisuav", "unitpos", "unitready", "unitrecoilcoefficient", "units", "units", "unlockachievement", "updateobjecttree", "useaiopermapobstructiontest", "useaisteeringcomponent", "vectordir", "vectordirvisual", "vectorlinearconversion", "vectormagnitude", "vectormagnitudesqr", "vectornormalized", "vectorup", "vectorupvisual", "vehicle", "vehiclecargoenabled", "vehiclereceiveremotetargets", "vehiclereportownposition", "vehiclereportremotetargets", "vehiclevarname", "velocity", "velocitymodelspace", "verifysignature", "vest", "vestcontainer", "vestitems", "vestmagazines", "visibleposition", "visiblepositionasl", "waituntil", "waypointattachedobject", "waypointattachedvehicle", "waypointbehaviour", "waypointcombatmode", "waypointcompletionradius", "waypointdescription", "waypointforcebehaviour", "waypointformation", "waypointhouseposition", "waypointloiterradius", "waypointloitertype", "waypointname", "waypointposition", "waypoints", "waypointscript", "waypointsenableduav", "waypointshow", "waypointspeed", "waypointstatements", "waypointtimeout", "waypointtimeoutcurrent", "waypointtype", "waypointvisible", "weaponcargo", "weaponinertia", "weaponlowered", "weapons", "weaponsitems", "weaponsitemscargo", "weaponstate", "weaponstate", "weightrtd", "wfsidetext", "wfsidetext", "wfsidetext", "while", "wingsforcesrtd", "with", "worldtoscreen", "action", "actionparams", "add3denlayer", "addaction", "addbackpack", "addbackpackcargo", "addbackpackcargoglobal", "addbackpackglobal", "addcuratoraddons", "addcuratorcameraarea", "addcuratoreditableobjects", "addcuratoreditingarea", "addcuratorpoints", "addeditorobject", "addeventhandler", "addforce", "addgoggles", "addgroupicon", "addhandgunitem", "addheadgear", "additem", "additemcargo", "additemcargoglobal", "additemtobackpack", "additemtouniform", "additemtovest", "addlivestats", "addmagazine", "addmagazine", "addmagazineammocargo", "addmagazinecargo", "addmagazinecargoglobal", "addmagazineglobal", "addmagazines", "addmagazineturret", "addmenu", "addmenuitem", "addmpeventhandler", "addownedmine", "addplayerscores", "addprimaryweaponitem", "addpublicvariableeventhandler", "addpublicvariableeventhandler", "addrating", "addresources", "addscore", "addscoreside", "addsecondaryweaponitem", "addteammember", "addtorque", "adduniform", "addvehicle", "addvest", "addwaypoint", "addweapon", "addweaponcargo", "addweaponcargoglobal", "addweaponglobal", "addweaponitem", "addweaponturret", "addweaponwithattachmentscargo", "addweaponwithattachmentscargoglobal", "aimedattarget", "allow3dmode", "allowcrewinimmobile", "allowcuratorlogicignoreareas", "allowdamage", "allowdammage", "allowfileoperations", "allowfleeing", "allowgetin", "allowsprint", "ammo", "ammoonpylon", "and", "and", "animate", "animatebay", "animatedoor", "animatepylon", "animatesource", "animationphase", "animationsourcephase", "append", "apply", "arrayintersect", "assignascargo", "assignascargoindex", "assignascommander", "assignasdriver", "assignasgunner", "assignasturret", "assigncurator", "assignitem", "assignteam", "assigntoairport", "atan2", "attachobject", "attachto", "backpackspacefor", "bezierinterpolation", "boundingbox", "boundingboxreal", "breakout", "buildingexit", "buildingpos", "buttonsetaction", "call", "callextension", "callextension", "camcommand", "camcommit", "camcommitprepared", "camconstuctionsetparams", "camcreate", "cameraeffect", "campreload", "campreparebank", "campreparedir", "campreparedive", "campreparefocus", "campreparefov", "campreparefovrange", "campreparepos", "campreparerelpos", "campreparetarget", "campreparetarget", "camsetbank", "camsetdir", "camsetdive", "camsetfocus", "camsetfov", "camsetfovrange", "camsetpos", "camsetrelpos", "camsettarget", "camsettarget", "canadd", "canadditemtobackpack", "canadditemtouniform", "canadditemtovest", "canslingload", "canvehiclecargo", "catch", "cbsetchecked", "checkaifeature", "checkvisibility", "clear3denattribute", "closedisplay", "commandartilleryfire", "commandchat", "commandfire", "commandfollow", "commandfsm", "commandmove", "commandradio", "commandsuppressivefire", "commandtarget", "commandwatch", "commandwatch", "configclasses", "confirmsensortarget", "connectterminaltouav", "controlsgroupctrl", "copywaypoints", "count", "countenemy", "countfriendly", "countside", "counttype", "countunknown", "create3denentity", "creatediaryrecord", "creatediarysubject", "createdisplay", "createmenu", "createmissiondisplay", "createmissiondisplay", "creatempcampaigndisplay", "createsimpletask", "createsite", "createtask", "createunit", "createunit", "createvehicle", "createvehiclelocal", "ctdata", "ctfindheaderrows", "ctfindrowheader", "ctheadercontrols", "ctremoveheaders", "ctremoverows", "ctrladdeventhandler", "ctrlanimatemodel", "ctrlanimationphasemodel", "ctrlchecked", "ctrlcommit", "ctrlcreate", "ctrlenable", "ctrlmapanimadd", "ctrlmapcursor", "ctrlmapscreentoworld", "ctrlmapworldtoscreen", "ctrlremovealleventhandlers", "ctrlremoveeventhandler", "ctrlsetactivecolor", "ctrlsetangle", "ctrlsetautoscrolldelay", "ctrlsetautoscrollrewind", "ctrlsetautoscrollspeed", "ctrlsetbackgroundcolor", "ctrlsetchecked", "ctrlsetchecked", "ctrlsetdisabledcolor", "ctrlseteventhandler", "ctrlsetfade", "ctrlsetfont", "ctrlsetfonth1", "ctrlsetfonth1b", "ctrlsetfonth2", "ctrlsetfonth2b", "ctrlsetfonth3", "ctrlsetfonth3b", "ctrlsetfonth4", "ctrlsetfonth4b", "ctrlsetfonth5", "ctrlsetfonth5b", "ctrlsetfonth6", "ctrlsetfonth6b", "ctrlsetfontheight", "ctrlsetfontheighth1", "ctrlsetfontheighth2", "ctrlsetfontheighth3", "ctrlsetfontheighth4", "ctrlsetfontheighth5", "ctrlsetfontheighth6", "ctrlsetfontheightsecondary", "ctrlsetfontp", "ctrlsetfontp", "ctrlsetfontpb", "ctrlsetfontsecondary", "ctrlsetforegroundcolor", "ctrlsetmodel", "ctrlsetmodeldirandup", "ctrlsetmodelscale", "ctrlsetpixelprecision", "ctrlsetpixelprecision", "ctrlsetposition", "ctrlsetpositionh", "ctrlsetpositionw", "ctrlsetpositionx", "ctrlsetpositiony", "ctrlsetscale", "ctrlsetstructuredtext", "ctrlsettext", "ctrlsettextcolor", "ctrlsettextcolorsecondary", "ctrlsettextsecondary", "ctrlsettooltip", "ctrlsettooltipcolorbox", "ctrlsettooltipcolorshade", "ctrlsettooltipcolortext", "ctrlshow", "ctrowcontrols", "ctsetcursel", "ctsetdata", "ctsetheadertemplate", "ctsetrowtemplate", "ctsetvalue", "ctvalue", "curatorcoef", "currentmagazinedetailturret", "currentmagazineturret", "currentweaponturret", "customchat", "customradio", "cutfadeout", "cutfadeout", "cutobj", "cutobj", "cutrsc", "cutrsc", "cuttext", "cuttext", "debugfsm", "deleteat", "deleteeditorobject", "deletegroupwhenempty", "deleterange", "deleteresources", "deletevehiclecrew", "diarysubjectexists", "directsay", "disableai", "disablecollisionwith", "disableconversation", "disablenvgequipment", "disabletiequipment", "disableuavconnectability", "displayaddeventhandler", "displayctrl", "displayremovealleventhandlers", "displayremoveeventhandler", "displayseteventhandler", "distance", "distance", "distance", "distance", "distance2d", "distancesqr", "distancesqr", "distancesqr", "distancesqr", "do", "do", "do", "do", "doartilleryfire", "dofire", "dofollow", "dofsm", "domove", "doorphase", "dosuppressivefire", "dotarget", "dowatch", "dowatch", "drawarrow", "drawellipse", "drawicon", "drawline", "drawlink", "drawlocation", "drawpolygon", "drawrectangle", "drawtriangle", "editobject", "editorseteventhandler", "else", "emptypositions", "enableai", "enableaifeature", "enableaifeature", "enableaimprecision", "enableattack", "enableautostartuprtd", "enableautotrimrtd", "enablechannel", "enablechannel", "enablecollisionwith", "enablecopilot", "enabledynamicsimulation", "enabledynamicsimulation", "enablefatigue", "enablegunlights", "enableinfopanelcomponent", "enableirlasers", "enablemimics", "enablepersonturret", "enablereload", "enableropeattach", "enablesimulation", "enablesimulationglobal", "enablestamina", "enableuavconnectability", "enableuavwaypoints", "enablevehiclecargo", "enablevehiclesensor", "enableweapondisassembly", "engineon", "evalobjectargument", "exec", "execeditorscript", "execfsm", "execvm", "exitwith", "fademusic", "faderadio", "fadesound", "fadespeech", "find", "find", "findcover", "findeditorobject", "findeditorobject", "findemptyposition", "findemptypositionready", "findif", "findnearestenemy", "fire", "fire", "fireattarget", "flyinheight", "flyinheightasl", "forceadduniform", "forceflagtexture", "forcefollowroad", "forcespeed", "forcewalk", "forceweaponfire", "foreach", "foreachmember", "foreachmemberagent", "foreachmemberteam", "forgettarget", "from", "get3denattribute", "get3denattribute", "get3denattribute", "get3denattribute", "get3denattribute", "get3denmissionattribute", "getartilleryeta", "getcargoindex", "getcompatiblepylonmagazines", "getcompatiblepylonmagazines", "getdir", "geteditorobjectscope", "getenvsoundcontroller", "getfriend", "getfsmvariable", "getgroupicon", "gethidefrom", "gethit", "gethitindex", "gethitpointdamage", "getobjectargument", "getobjectchildren", "getobjectproxy", "getpos", "getreldir", "getrelpos", "getsoundcontroller", "getsoundcontrollerresult", "getspeed", "getunittrait", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "getvariable", "glanceat", "globalchat", "globalradio", "groupchat", "groupradio", "groupselectunit", "hasweapon", "hcgroupparams", "hcremovegroup", "hcselectgroup", "hcsetgroup", "hideobject", "hideobjectglobal", "hideselection", "hintc", "hintc", "hintc", "htmlload", "in", "in", "in", "in", "inarea", "inarea", "inarea", "inarea", "inarea", "inareaarray", "inareaarray", "inareaarray", "inareaarray", "inflame", "infopanelcomponentenabled", "infopanelcomponents", "inpolygon", "inrangeofartillery", "inserteditorobject", "intersect", "isequalto", "isequaltype", "isequaltypeall", "isequaltypeany", "isequaltypearray", "isequaltypeparams", "isflashlighton", "isflatempty", "isirlaseron", "iskindof", "iskindof", "iskindof", "issensortargetconfirmed", "isuavconnectable", "isuniformallowed", "isvehiclesensorenabled", "join", "joinas", "joinassilent", "joinsilent", "joinstring", "kbadddatabase", "kbadddatabasetargets", "kbaddtopic", "kbhastopic", "kbreact", "kbremovetopic", "kbtell", "kbwassaid", "knowsabout", "knowsabout", "land", "landat", "lbadd", "lbcolor", "lbcolorright", "lbdata", "lbdelete", "lbisselected", "lbpicture", "lbpictureright", "lbsetcolor", "lbsetcolorright", "lbsetcursel", "lbsetdata", "lbsetpicture", "lbsetpicturecolor", "lbsetpicturecolordisabled", "lbsetpicturecolorselected", "lbsetpictureright", "lbsetpicturerightcolor", "lbsetpicturerightcolordisabled", "lbsetpicturerightcolorselected", "lbsetselectcolor", "lbsetselectcolorright", "lbsetselected", "lbsettext", "lbsettextright", "lbsettooltip", "lbsetvalue", "lbtext", "lbtextright", "lbvalue", "leavevehicle", "leavevehicle", "lightattachobject", "limitspeed", "linkitem", "listobjects", "lnbaddcolumn", "lnbaddrow", "lnbcolor", "lnbcolorright", "lnbdata", "lnbdeletecolumn", "lnbdeleterow", "lnbpicture", "lnbpictureright", "lnbsetcolor", "lnbsetcolorright", "lnbsetcolumnspos", "lnbsetcurselrow", "lnbsetdata", "lnbsetpicture", "lnbsetpicturecolor", "lnbsetpicturecolorright", "lnbsetpicturecolorselected", "lnbsetpicturecolorselectedright", "lnbsetpictureright", "lnbsettext", "lnbsettextright", "lnbsettooltip", "lnbsetvalue", "lnbsort", "lnbsortbyvalue", "lnbtext", "lnbtextright", "lnbvalue", "loadidentity", "loadmagazine", "loadoverlay", "loadstatus", "lock", "lock", "lockcamerato", "lockcargo", "lockcargo", "lockdriver", "lockedcargo", "lockedturret", "lockturret", "lockwp", "lookat", "lookatpos", "magazinesturret", "magazineturretammo", "mapcenteroncamera", "matrixmultiply", "max", "menuaction", "menuadd", "menuchecked", "menucollapse", "menudata", "menudelete", "menuenable", "menuenabled", "menuexpand", "menupicture", "menusetaction", "menusetcheck", "menusetdata", "menusetpicture", "menusetvalue", "menushortcut", "menushortcuttext", "menusize", "menusort", "menutext", "menuurl", "menuvalue", "min", "minedetectedby", "mod", "modeltoworld", "modeltoworldvisual", "modeltoworldvisualworld", "modeltoworldworld", "move", "moveinany", "moveincargo", "moveincargo", "moveincommander", "moveindriver", "moveingunner", "moveinturret", "moveobjecttoend", "moveto", "nearentities", "nearestobject", "nearestobject", "nearobjects", "nearobjectsready", "nearroads", "nearsupplies", "neartargets", "newoverlay", "nmenuitems", "objstatus", "ondoubleclick", "onmapsingleclick", "onshownewobject", "or", "or", "ordergetin", "param", "params", "playaction", "playactionnow", "playgesture", "playmove", "playmovenow", "posscreentoworld", "posworldtoscreen", "ppeffectadjust", "ppeffectadjust", "ppeffectcommit", "ppeffectcommit", "ppeffectcommit", "ppeffectenable", "ppeffectenable", "ppeffectenable", "ppeffectforceinnvg", "preloadobject", "progresssetposition", "publicvariableclient", "pushback", "pushbackunique", "radiochanneladd", "radiochannelremove", "radiochannelsetcallsign", "radiochannelsetlabel", "random", "registertask", "remotecontrol", "remoteexec", "remoteexeccall", "removeaction", "removealleventhandlers", "removeallmpeventhandlers", "removecuratoraddons", "removecuratorcameraarea", "removecuratoreditableobjects", "removecuratoreditingarea", "removediaryrecord", "removediarysubject", "removedrawicon", "removedrawlinks", "removeeventhandler", "removegroupicon", "removehandgunitem", "removeitem", "removeitemfrombackpack", "removeitemfromuniform", "removeitemfromvest", "removeitems", "removemagazine", "removemagazineglobal", "removemagazines", "removemagazinesturret", "removemagazineturret", "removemenuitem", "removemenuitem", "removempeventhandler", "removeownedmine", "removeprimaryweaponitem", "removesecondaryweaponitem", "removesimpletask", "removeteammember", "removeweapon", "removeweaponattachmentcargo", "removeweaponcargo", "removeweaponglobal", "removeweaponturret", "reportremotetarget", "resize", "respawnvehicle", "reveal", "reveal", "revealmine", "ropeattachto", "ropedetach", "saveidentity", "savestatus", "say", "say", "say2d", "say2d", "say3d", "say3d", "select", "select", "select", "select", "select", "select", "selectdiarysubject", "selecteditorobject", "selectionposition", "selectleader", "selectrandomweighted", "selectweapon", "selectweaponturret", "sendsimplecommand", "sendtask", "sendtaskresult", "servercommand", "set", "set3denattribute", "set3denlayer", "set3denlogictype", "set3denmissionattribute", "set3denobjecttype", "setactualcollectivertd", "setairplanethrottle", "setairportside", "setammo", "setammocargo", "setammoonpylon", "setanimspeedcoef", "setattributes", "setautonomous", "setbehaviour", "setbehaviourstrong", "setbleedingremaining", "setbrakesrtd", "setcamerainterest", "setcamuseti", "setcaptive", "setcenterofmass", "setcollisionlight", "setcombatmode", "setcombatmode", "setconvoyseparation", "setcuratorcameraareaceiling", "setcuratorcoef", "setcuratoreditingareatype", "setcuratorwaypointcost", "setcurrenttask", "setcurrentwaypoint", "setcustomaimcoef", "setcustomweightrtd", "setdamage", "setdammage", "setdebriefingtext", "setdestination", "setdiaryrecordtext", "setdir", "setdirection", "setdrawicon", "setdriveonpath", "setdropinterval", "setdynamicsimulationdistance", "setdynamicsimulationdistancecoef", "seteditormode", "seteditorobjectscope", "seteffectcondition", "seteffectivecommander", "setenginerpmrtd", "setface", "setfaceanimation", "setfatigue", "setfeaturetype", "setflaganimationphase", "setflagowner", "setflagside", "setflagtexture", "setfog", "setforcegeneratorrtd", "setformation", "setformation", "setformationtask", "setformdir", "setfriend", "setfromeditor", "setfsmvariable", "setfuel", "setfuelcargo", "setgroupicon", "setgroupiconparams", "setgroupid", "setgroupidglobal", "setgroupowner", "setgusts", "sethidebehind", "sethit", "sethitindex", "sethitpointdamage", "setidentity", "setimportance", "setleader", "setlightambient", "setlightattenuation", "setlightbrightness", "setlightcolor", "setlightdaylight", "setlightflaremaxdistance", "setlightflaresize", "setlightintensity", "setlightnings", "setlightuseflare", "setmagazineturretammo", "setmarkeralpha", "setmarkeralphalocal", "setmarkerbrush", "setmarkerbrushlocal", "setmarkercolor", "setmarkercolorlocal", "setmarkerdir", "setmarkerdirlocal", "setmarkerpos", "setmarkerposlocal", "setmarkershape", "setmarkershapelocal", "setmarkersize", "setmarkersizelocal", "setmarkertext", "setmarkertextlocal", "setmarkertype", "setmarkertypelocal", "setmass", "setmimic", "setmissiletarget", "setmissiletargetpos", "setmusiceffect", "setname", "setname", "setname", "setnamesound", "setobjectarguments", "setobjectmaterial", "setobjectmaterialglobal", "setobjectproxy", "setobjecttexture", "setobjecttextureglobal", "setovercast", "setowner", "setoxygenremaining", "setparticlecircle", "setparticleclass", "setparticlefire", "setparticleparams", "setparticlerandom", "setpilotcameradirection", "setpilotcamerarotation", "setpilotcameratarget", "setpilotlight", "setpipeffect", "setpitch", "setplatenumber", "setpos", "setposasl", "setposasl2", "setposaslw", "setposatl", "setposition", "setposworld", "setpylonloadout", "setpylonspriority", "setradiomsg", "setrain", "setrainbow", "setrandomlip", "setrank", "setrectangular", "setrepaircargo", "setrotorbrakertd", "setshotparents", "setside", "setsimpletaskalwaysvisible", "setsimpletaskcustomdata", "setsimpletaskdescription", "setsimpletaskdestination", "setsimpletasktarget", "setsimpletasktype", "setsize", "setskill", "setskill", "setslingload", "setsoundeffect", "setspeaker", "setspeech", "setspeedmode", "setstamina", "setsuppression", "settargetage", "settaskmarkeroffset", "settaskresult", "settaskstate", "settext", "settitleeffect", "settriggeractivation", "settriggerarea", "settriggerstatements", "settriggertext", "settriggertimeout", "settriggertype", "settype", "setunconscious", "setunitability", "setunitloadout", "setunitloadout", "setunitloadout", "setunitpos", "setunitposweak", "setunitrank", "setunitrecoilcoefficient", "setunittrait", "setunloadincombat", "setuseractiontext", "setusermfdtext", "setusermfdvalue", "setvariable", "setvariable", "setvariable", "setvariable", "setvariable", "setvariable", "setvariable", "setvariable", "setvectordir", "setvectordirandup", "setvectorup", "setvehicleammo", "setvehicleammodef", "setvehiclearmor", "setvehiclecargo", "setvehicleid", "setvehiclelock", "setvehicleposition", "setvehicleradar", "setvehiclereceiveremotetargets", "setvehiclereportownposition", "setvehiclereportremotetargets", "setvehicletipars", "setvehiclevarname", "setvelocity", "setvelocitymodelspace", "setvelocitytransformation", "setvisibleiftreecollapsed", "setwantedrpmrtd", "setwaves", "setwaypointbehaviour", "setwaypointcombatmode", "setwaypointcompletionradius", "setwaypointdescription", "setwaypointforcebehaviour", "setwaypointformation", "setwaypointhouseposition", "setwaypointloiterradius", "setwaypointloitertype", "setwaypointname", "setwaypointposition", "setwaypointscript", "setwaypointspeed", "setwaypointstatements", "setwaypointtimeout", "setwaypointtype", "setwaypointvisible", "setweaponreloadingtime", "setwinddir", "setwindforce", "setwindstr", "setwingforcescalertd", "setwppos", "show3dicons", "showlegend", "showneweditorobject", "showwaypoint", "sidechat", "sideradio", "skill", "skillfinal", "slidersetposition", "slidersetrange", "slidersetspeed", "sort", "spawn", "splitstring", "step", "stop", "suppressfor", "swimindepth", "switchaction", "switchcamera", "switchgesture", "switchlight", "switchmove", "synchronizeobjectsadd", "synchronizeobjectsremove", "synchronizetrigger", "synchronizewaypoint", "synchronizewaypoint", "targetknowledge", "targets", "targetsaggregate", "targetsquery", "then", "then", "throw", "to", "tofixed", "triggerattachobject", "triggerattachvehicle", "triggerdynamicsimulation", "try", "turretlocal", "turretowner", "turretunit", "tvadd", "tvcollapse", "tvcount", "tvdata", "tvdelete", "tvexpand", "tvpicture", "tvpictureright", "tvsetcolor", "tvsetcursel", "tvsetdata", "tvsetpicture", "tvsetpicturecolor", "tvsetpicturecolordisabled", "tvsetpicturecolorselected", "tvsetpictureright", "tvsetpicturerightcolor", "tvsetpicturerightcolordisabled", "tvsetpicturerightcolorselected", "tvsetselectcolor", "tvsettext", "tvsettooltip", "tvsetvalue", "tvsort", "tvsortbyvalue", "tvtext", "tvtooltip", "tvvalue", "unassignitem", "unitsbelowheight", "unitsbelowheight", "unlinkitem", "unregistertask", "updatedrawicon", "updatemenuitem", "useaudiotimeformoves", "vectoradd", "vectorcos", "vectorcrossproduct", "vectordiff", "vectordistance", "vectordistancesqr", "vectordotproduct", "vectorfromto", "vectormodeltoworld", "vectormodeltoworldvisual", "vectormultiply", "vectorworldtomodel", "vectorworldtomodelvisual", "vehiclechat", "vehicleradio", "waypointattachobject", "waypointattachvehicle", "weaponaccessories", "weaponaccessoriescargo", "weapondirection", "weaponsturret", "worldtomodel", "worldtomodelvisual", "acctime", "activatedaddons", "agents", "airdensitycurvertd", "all3denentities", "allairports", "allcurators", "allcutlayers", "alldead", "alldeadmen", "alldisplays", "allgroups", "allmapmarkers", "allmines", "allplayers", "allsites", "allunits", "allunitsuav", "armorypoints", "benchmark", "blufor", "briefingname", "buldozer_isenabledroaddiag", "buldozer_reloadopermap", "cadetmode", "cameraon", "cameraview", "campaignconfigfile", "cansuspend", "cheatsenabled", "civilian", "clearforcesrtd", "clearitempool", "clearmagazinepool", "clearradio", "clearweaponpool", "clientowner", "commandingmenu", "configfile", "confignull", "controlnull", "copyfromclipboard", "curatorcamera", "curatormouseover", "curatorselected", "current3denoperation", "currentchannel", "currentnamespace", "cursorobject", "cursortarget", "customwaypointposition", "date", "daytime", "diag_activemissionfsms", "diag_activescripts", "diag_activesqfscripts", "diag_activesqsscripts", "diag_deltatime", "diag_fps", "diag_fpsmin", "diag_frameno", "diag_ticktime", "dialog", "didjip", "difficulty", "difficultyenabledrtd", "disabledebriefingstats", "disableserialization", "displaynull", "distributionregion", "dynamicsimulationsystemenabled", "east", "enableenddialog", "endl", "endloadingscreen", "environmentenabled", "estimatedendservertime", "exit", "false", "finishmissioninit", "fog", "fogforecast", "fogparams", "forcedmap", "forceend", "forceweatherchange", "freelook", "get3dencamera", "get3deniconsvisible", "get3denlinesvisible", "get3denmouseover", "getartillerycomputersettings", "getaudiooptionvolumes", "getcalculateplayervisibilitybyfriendly", "getclientstate", "getclientstatenumber", "getcursorobjectparams", "getdlcassetsusage", "getelevationoffset", "getmissiondlcs", "getmissionlayers", "getmouseposition", "getmusicplayedtime", "getobjectviewdistance", "getremotesensorsdisabled", "getresolution", "getshadowdistance", "getsubtitleoptions", "getterraingrid", "gettotaldlcusagetime", "groupiconselectable", "groupiconsvisible", "grpnull", "gusts", "halt", "hasinterface", "hcshownbar", "hudmovementlevels", "humidity", "independent", "initambientlife", "is3den", "is3denmultiplayer", "isactionmenuvisible", "isautotest", "isdedicated", "isfilepatchingenabled", "isgamefocused", "isgamepaused", "isinstructorfigureenabled", "ismultiplayer", "ismultiplayersolo", "ispipenabled", "isremoteexecuted", "isremoteexecutedjip", "isserver", "issteammission", "isstreamfriendlyuienabled", "isstressdamageenabled", "istuthintsenabled", "isuicontext", "language", "librarycredits", "librarydisclaimers", "lightnings", "linebreak", "loadgame", "locationnull", "logentities", "mapanimclear", "mapanimcommit", "mapanimdone", "markasfinishedonsteam", "missionconfigfile", "missiondifficulty", "missionname", "missionnamespace", "missionstart", "missionversion", "moonintensity", "musicvolume", "netobjnull", "nextweatherchange", "nil", "objnull", "opencuratorinterface", "opfor", "overcast", "overcastforecast", "parsingnamespace", "particlesquality", "pi", "pixelgrid", "pixelgridbase", "pixelgridnouiscale", "pixelh", "pixelw", "playableunits", "player", "playerrespawntime", "playerside", "productversion", "profilename", "profilenamespace", "profilenamesteam", "radiovolume", "rain", "rainbow", "remoteexecutedowner", "resetcamshake", "resistance", "reversedmousey", "runinitscript", "safezoneh", "safezonew", "safezonewabs", "safezonex", "safezonexabs", "safezoney", "savegame", "savejoysticks", "saveprofilenamespace", "savingenabled", "scriptnull", "selectnoplayer", "servername", "servertime", "shownartillerycomputer", "shownchat", "showncompass", "showncuratorcompass", "showngps", "shownhud", "shownmap", "shownpad", "shownradio", "shownscoretable", "shownuavfeed", "shownwarrant", "shownwatch", "sideambientlife", "sideempty", "sideenemy", "sidefriendly", "sidelogic", "sideunknown", "simulweathersync", "slingloadassistantshown", "soundvolume", "sunormoon", "switchableunits", "systemofunits", "tasknull", "teammembernull", "teams", "teamswitch", "teamswitchenabled", "time", "timemultiplier", "true", "uinamespace", "userinputdisabled", "vehicles", "viewdistance", "visiblecompass", "visiblegps", "visiblemap", "visiblescoretable", "visiblewatch", "waves", "west", "wind", "winddir", "windrtd", "windstr", "worldname", "worldsize"] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sql.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sql.rb new file mode 100644 index 0000000..ff5c8a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/sql.rb @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SQL < RegexLexer + title "SQL" + desc "Structured Query Language, for relational databases" + tag 'sql' + filenames '*.sql' + mimetypes 'text/x-sql' + + def self.keywords + @keywords ||= Set.new %w( + ABORT ABS ABSOLUTE ACCESS ADA ADD ADMIN AFTER AGGREGATE ALIAS + ALL ALLOCATE ALTER ANALYSE ANALYZE AND ANY ARE AS ASC ASENSITIVE + ASSERTION ASSIGNMENT ASYMMETRIC AT ATOMIC AUTHORIZATION + AVG BACKWARD BEFORE BEGIN BETWEEN BITVAR BIT_LENGTH BOTH + BREADTH BY C CACHE CALL CALLED CARDINALITY CASCADE CASCADED + CASE CAST CATALOG CATALOG_NAME CHAIN CHARACTERISTICS + CHARACTER_LENGTH CHARACTER_SET_CATALOG CHARACTER_SET_NAME + CHARACTER_SET_SCHEMA CHAR_LENGTH CHECK CHECKED CHECKPOINT + CLASS CLASS_ORIGIN CLOB CLOSE CLUSTER COALSECE COBOL COLLATE + COLLATION COLLATION_CATALOG COLLATION_NAME COLLATION_SCHEMA + COLUMN COLUMN_NAME COMMAND_FUNCTION COMMAND_FUNCTION_CODE + COMMENT COMMIT COMMITTED COMPLETION CONDITION_NUMBER + CONNECT CONNECTION CONNECTION_NAME CONSTRAINT CONSTRAINTS + CONSTRAINT_CATALOG CONSTRAINT_NAME CONSTRAINT_SCHEMA + CONSTRUCTOR CONTAINS CONTINUE CONVERSION CONVERT COPY + CORRESPONTING COUNT CREATE CREATEDB CREATEUSER CROSS CUBE + CURRENT CURRENT_DATE CURRENT_PATH CURRENT_ROLE CURRENT_TIME + CURRENT_TIMESTAMP CURRENT_USER CURSOR CURSOR_NAME CYCLE DATA + DATABASE DATETIME_INTERVAL_CODE DATETIME_INTERVAL_PRECISION + DAY DEALLOCATE DECLARE DEFAULT DEFAULTS DEFERRABLE DEFERRED + DEFINED DEFINER DELETE DELIMITER DELIMITERS DEREF DESC DESCRIBE + DESCRIPTOR DESTROY DESTRUCTOR DETERMINISTIC DIAGNOSTICS + DICTIONARY DISCONNECT DISPATCH DISTINCT DO DOMAIN DROP + DYNAMIC DYNAMIC_FUNCTION DYNAMIC_FUNCTION_CODE EACH ELSE + ENCODING ENCRYPTED END END-EXEC EQUALS ESCAPE EVERY EXCEPT + ESCEPTION EXCLUDING EXCLUSIVE EXEC EXECUTE EXISTING EXISTS + EXPLAIN EXTERNAL EXTRACT FALSE FETCH FINAL FIRST FOLLOWING FOR + FORCE FOREIGN FORTRAN FORWARD FOUND FREE FREEZE FROM FULL FUNCTION + G GENERAL GENERATED GET GLOBAL GO GOTO GRANT GRANTED GROUP + GROUPING HANDLER HAVING HIERARCHY HOLD HOST IDENTITY IGNORE + ILIKE IMMEDIATE IMMUTABLE IMPLEMENTATION IMPLICIT IN INCLUDING + INCREMENT INDEX INDITCATOR INFIX INHERITS INITIALIZE INITIALLY + INNER INOUT INPUT INSENSITIVE INSERT INSTANTIABLE INSTEAD + INTERSECT INTO INVOKER IS ISNULL ISOLATION ITERATE JOIN KEY + KEY_MEMBER KEY_TYPE LANCOMPILER LANGUAGE LARGE LAST LATERAL + LEADING LEFT LENGTH LESS LEVEL LIKE LIMIT LISTEN LOAD LOCAL + LOCALTIME LOCALTIMESTAMP LOCATION LOCATOR LOCK LOWER MAP MATCH + MAX MAXVALUE MESSAGE_LENGTH MESSAGE_OCTET_LENGTH MESSAGE_TEXT + METHOD MIN MINUTE MINVALUE MOD MODE MODIFIES MODIFY MONTH + MORE MOVE MUMPS NAMES NATURAL NCLOB NEW NEXT + NO NOCREATEDB NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL + NULL NULLABLE NULLIF OBJECT OCTET_LENGTH OF OFF OFFSET OIDS + OLD ON ONLY OPEN OPERATION OPERATOR OPTION OPTIONS OR ORDER + ORDINALITY OUT OUTER OUTPUT OVERLAPS OVERLAY OVERRIDING + OWNER PAD PARAMETER PARAMETERS PARAMETER_MODE PARAMATER_NAME + PARAMATER_ORDINAL_POSITION PARAMETER_SPECIFIC_CATALOG + PARAMETER_SPECIFIC_NAME PARAMATER_SPECIFIC_SCHEMA PARTIAL PARTITION + PASCAL PENDANT PLACING PLI POSITION POSTFIX PREFIX PRECEDING PREORDER + PREPARE PRESERVE PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE + PUBLIC RANGE READ READS RECHECK RECURSIVE REF REFERENCES REFERENCING + REINDEX RELATIVE RENAME REPEATABLE REPLACE RESET RESTART + RESTRICT RESULT RETURN RETURNED_LENGTH RETURNED_OCTET_LENGTH + RETURNED_SQLSTATE RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + ROUTINE ROUTINE_CATALOG ROUTINE_NAME ROUTINE_SCHEMA ROW ROWS + ROW_COUNT RULE SAVE_POINT SCALE SCHEMA SCHEMA_NAME SCOPE SCROLL + SEARCH SECOND SECURITY SELECT SELF SENSITIVE SERIALIZABLE + SERVER_NAME SESSION SESSION_USER SET SETOF SETS SHARE SHOW + SIMILAR SIMPLE SIZE SOME SOURCE SPACE SPECIFIC SPECIFICTYPE + SPECIFIC_NAME SQL SQLCODE SQLERROR SQLEXCEPTION SQLSTATE + SQLWARNINIG STABLE START STATE STATEMENT STATIC STATISTICS + STDIN STDOUT STORAGE STRICT STRUCTURE STYPE SUBCLASS_ORIGIN + SUBLIST SUBSTRING SUM SYMMETRIC SYSID SYSTEM SYSTEM_USER + TABLE TABLE_NAME TEMP TEMPLATE TEMPORARY TERMINATE THAN THEN + TIMEZONE_HOUR TIMEZONE_MINUTE TO TOAST TRAILING + TRANSATION TRANSACTIONS_COMMITTED TRANSACTIONS_ROLLED_BACK + TRANSATION_ACTIVE TRANSFORM TRANSFORMS TRANSLATE TRANSLATION + TREAT TRIGGER TRIGGER_CATALOG TRIGGER_NAME TRIGGER_SCHEMA TRIM + TRUE TRUNCATE TRUSTED TYPE UNCOMMITTED UNDER UNENCRYPTED UNION + UNIQUE UNKNOWN UNLISTEN UNNAMED UNNEST UNTIL UPDATE UPPER + USAGE USER USER_DEFINED_TYPE_CATALOG USER_DEFINED_TYPE_NAME + USER_DEFINED_TYPE_SCHEMA USING VACUUM VALID VALIDATOR VALUES + VARIABLE VERBOSE VERSION VIEW VOLATILE WHEN WHENEVER WHERE + WINDOW WITH WITHOUT WORK WRITE ZONE + ) + end + + def self.keywords_type + # sources: + # https://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html + # https://dev.mysql.com/doc/refman/5.7/en/date-and-time-type-overview.html + # https://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html + @keywords_type ||= Set.new(%w( + ZEROFILL UNSIGNED SIGNED SERIAL BIT TINYINT BOOL BOOLEAN SMALLINT + MEDIUMINT INT INTEGER BIGINT DECIMAL DEC NUMERIC FIXED FLOAT DOUBLE + PRECISION REAL + DATE DATETIME TIMESTAMP TIME YEAR + NATIONAL CHAR CHARACTER NCHAR BYTE + VARCHAR VARYING BINARY VARBINARY TINYBLOB TINYTEXT BLOB TEXT + MEDIUMBLOB MEDIUMTEXT LONGBLOB LONGTEXT ENUM + )) + end + + state :root do + rule %r/\s+/m, Text + rule %r/--.*/, Comment::Single + rule %r(/\*), Comment::Multiline, :multiline_comments + rule %r/\d+/, Num::Integer + rule %r/'/, Str::Single, :single_string + # A double-quoted string refers to a database object in our default SQL + # dialect, which is apropriate for e.g. MS SQL and PostgreSQL. + rule %r/"/, Name::Variable, :double_string + rule %r/`/, Name::Variable, :backtick + + rule %r/\w+/ do |m| + if self.class.keywords_type.include? m[0].upcase + token Name::Builtin + elsif self.class.keywords.include? m[0].upcase + token Keyword + else + token Name + end + end + + rule %r([+*/<>=~!@#%&|?^-]), Operator + rule %r/[;:()\[\]\{\},.]/, Punctuation + end + + state :multiline_comments do + rule %r(/[*]), Comment::Multiline, :multiline_comments + rule %r([*]/), Comment::Multiline, :pop! + rule %r([^/*]+), Comment::Multiline + rule %r([/*]), Comment::Multiline + end + + state :backtick do + rule %r/\\./, Str::Escape + rule %r/``/, Str::Escape + rule %r/`/, Name::Variable, :pop! + rule %r/[^\\`]+/, Name::Variable + end + + state :single_string do + rule %r/\\./, Str::Escape + rule %r/''/, Str::Escape + rule %r/'/, Str::Single, :pop! + rule %r/[^\\']+/, Str::Single + end + + state :double_string do + rule %r/\\./, Str::Escape + rule %r/""/, Str::Escape + rule %r/"/, Name::Variable, :pop! + rule %r/[^\\"]+/, Name::Variable + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ssh.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ssh.rb new file mode 100644 index 0000000..11369e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ssh.rb @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SSH < RegexLexer + tag 'ssh' + + title "SSH Config File" + desc 'A lexer for SSH configuration files' + filenames 'ssh_config' + + state :root do + rule %r/[a-z0-9]+/i, Keyword, :statement + mixin :base + end + + state :statement do + rule %r/\n/, Text, :pop! + rule %r/(?:yes|no|confirm|ask|always|auto|none|force)\b/, Name::Constant + + rule %r/\d+/, Num + rule %r/[^#\s;{}$\\]+/, Text + mixin :base + end + + state :base do + rule %r/\s+/, Text + rule %r/#.*/, Comment::Single + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stan.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stan.rb new file mode 100644 index 0000000..8208aee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stan.rb @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Stan < RegexLexer + title "Stan" + desc 'Stan Modeling Language (mc-stan.org)' + tag 'stan' + filenames '*.stan', '*.stanfunctions' + + # optional comment or whitespace + WS = %r((?:\s|//.*?\n|/[*].*?[*]/)+) + ID = /[a-zA-Z_][a-zA-Z0-9_]*/ + RT = /(?:(?:[a-z_]\s*(?:\[[0-9, ]\])?)\s+)*/ + OP = Regexp.new([ + # Assigment operators + "=", + + # Comparison operators + "<", "<=", ">", ">=", "==", "!=", + + # Boolean operators + "!", "&&", "\\|\\|", + + # Real-valued arithmetic operators + "\\+", "-", "\\*", "/", "\\^", + + # Transposition operator + "'", + + # Elementwise functions + "\\.\\+", "\\.-", "\\.\\*", "\\./", "\\.\\^", + + # Matrix division operators + "\\\\", + + # Compound assigment operators + "\\+=", "-=", "\\*=", "/=", "\\.\\*=", "\\./=", + + # Sampling + "~", + + # Conditional operator + "\\?", ":" + ].join("|")) + + def self.keywords + @keywords ||= Set.new %w( + if else while for break continue print reject return + ) + end + + def self.types + @types ||= Set.new %w( + int real vector ordered positive_ordered simplex unit_vector + row_vector matrix cholesky_factor_corr cholesky_factor_cov corr_matrix + cov_matrix data void complex array + ) + end + + def self.reserved + @reserved ||= Set.new [ + # Reserved words from Stan language + "for", "in", "while", "repeat", "until", "if", "then", "else", "true", + "false", "target", "functions", "model", "data", "parameters", + "quantities", "transformed", "generated", + + # Reserved names from Stan implementation + "var", "fvar", "STAN_MAJOR", "STAN_MINOR", "STAN_PATCH", + "STAN_MATH_MAJOR", "STAN_MATH_MINOR", "STAN_MATH_PATCH", + + # Reserved names from C++ + "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", + "bitor", "bool", "break", "case", "catch", "char", "char16_t", + "char32_t", "class", "compl", "const", "constexpr", "const_cast", + "continue", "decltype", "default", "delete", "do", "double", + "dynamic_cast", "else", "enum", "explicit", "export", "extern", + "false", "float", "for", "friend", "goto", "if", "inline", "int", + "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", + "nullptr", "operator", "or", "or_eq", "private", "protected", + "public", "register", "reinterpret_cast", "return", "short", "signed", + "sizeof", "static", "static_assert", "static_cast", "struct", + "switch", "template", "this", "thread_local", "throw", "true", "try", + "typedef", "typeid", "typename", "union", "unsigned", "using", + "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq" + ] + end + + def self.builtin_functions + @builtin_functions ||= Set.new [ + # Integer-Valued Basic Functions + + ## Absolute functions + "abs", "int_step", + + ## Bound functions + "min", "max", + + ## Size functions + "size", + + # Real-Valued Basic Functions + + ## Log probability function + "target", "get_lp", + + ## Logical functions + "step", "is_inf", "is_nan", + + ## Step-like functions + "fabs", "fdim", "fmin", "fmax", "fmod", "floor", "ceil", "round", + "trunc", + + ## Power and logarithm functions + "sqrt", "cbrt", "square", "exp", "exp2", "log", "log2", "log10", + "pow", "inv", "inv_sqrt", "inv_square", + + ## Trigonometric functions + "hypot", "cos", "sin", "tan", "acos", "asin", "atan", "atan2", + + ## Hyperbolic trigonometric functions + "cosh", "sinh", "tanh", "acosh", "asinh", "atanh", + + ## Link functions + "logit", "inv_logit", "inv_cloglog", + + ## Probability-related functions + "erf", "erfc", "Phi", "inv_Phi", "Phi_approx", "binary_log_loss", + "owens_t", + + ## Combinatorial functions + "beta", "inc_beta", "lbeta", "tgamma", "lgamma", "digamma", + "trigamma", "lmgamma", "gamma_p", "gamma_q", + "binomial_coefficient_log", "choose", "bessel_first_kind", + "bessel_second_kind", "modified_bessel_first_kind", + "log_modified_bessel_first_kind", "modified_bessel_second_kind", + "falling_factorial", "lchoose", "log_falling_factorial", + "rising_factorial", "log_rising_factorial", + + ## Composed functions + "expm1", "fma", "multiply_log", "ldexp", "lmultiply", "log1p", + "log1m", "log1p_exp", "log1m_exp", "log_diff_exp", "log_mix", + "log_sum_exp", "log_inv_logit", "log_inv_logit_diff", + "log1m_inv_logit", + + ## Special functions + "lambert_w0", "lambert_wm1", + + # Complex-Valued Basic Functions + + ## Complex constructors and accessors + "to_complex", "get_real", "get_imag", + + ## Complex special functions + "arg", "norm", "conj", "proj", "polar", + + # Array Operations + + ## Reductions + "sum", "prod", "log_sum_exp", "mean", "variance", "sd", "distance", + "squared_distance", "quantile", + + ## Array size and dimension function + "dims", "num_elements", + + ## Array broadcasting + "rep_array", + + ## Array concatenation + "append_array", + + ## Sorting functions + "sort_asc", "sort_desc", "sort_indices_asc", "sort_indices_desc", + "rank", + + ## Reversing functions + "reverse", + + # Matrix Operations + + ## Integer-valued matrix size functions + "num_elements", "rows", "cols", + + ## Dot products and specialized products + "dot_product", "columns_dot_product", "rows_dot_product", "dot_self", + "columns_dot_self", "rows_dot_self", "tcrossprod", "crossprod", + "quad_form", "quad_form_diag", "quad_form_sym", "trace_quad_form", + "trace_gen_quad_form", "multiply_lower_tri_self_transpose", + "diag_pre_multiply", "diag_post_multiply", + + ## Broadcast functions + "rep_vector", "rep_row_vector", "rep_matrix", + "symmetrize_from_lower_tri", + + ## Diagonal matrix functions + "add_diag", "diagonal", "diag_matrix", "identity_matrix", + + ## Container construction functions + "linspaced_array", "linspaced_int_array", "linspaced_vector", + "linspaced_row_vector", "one_hot_int_array", "one_hot_array", + "one_hot_vector", "one_hot_row_vector", "ones_int_array", + "ones_array", "ones_vector", "ones_row_vector", "zeros_int_array", + "zeros_array", "zeros_vector", "zeros_row_vector", "uniform_simplex", + + ## Slicing and blocking functions + "col", "row", "block", "sub_col", "sub_row", "head", "tail", + "segment", + + ## Matrix concatenation + "append_col", "append_row", + + ## Special matrix functions + "softmax", "log_softmax", "cumulative_sum", + + ## Covariance functions + "cov_exp_quad", + + ## Linear algebra functions and solvers + "mdivide_left_tri_low", "mdivide_right_tri_low", "mdivide_left_spd", + "mdivide_right_spd", "matrix_exp", "matrix_exp_multiply", + "scale_matrix_exp_multiply", "matrix_power", "trace", "determinant", + "log_determinant", "inverse", "inverse_spd", "chol2inv", + "generalized_inverse", "eigenvalues_sym", "eigenvectors_sym", + "qr_thin_Q", "qr_thin_R", "qr_Q", "qr_R", "cholseky_decompose", + "singular_values", "svd_U", "svd_V", + + # Sparse Matrix Operations + + ## Conversion functions + "csr_extract_w", "csr_extract_v", "csr_extract_u", + "csr_to_dense_matrix", + + ## Sparse matrix arithmetic + "csr_matrix_times_vector", + + # Mixed Operations + "to_matrix", "to_vector", "to_row_vector", "to_array_2d", + "to_array_1d", + + # Higher-Order Functions + + ## Algebraic equation solver + "algebra_solver", "algebra_solver_newton", + + ## Ordinary differential equation + "ode_rk45", "ode_rk45_tol", "ode_ckrk", "ode_ckrk_tol", "ode_adams", + "ode_adams_tol", "ode_bdf", "ode_bdf_tol", "ode_adjoint_tol_ctl", + + ## 1D integrator + "integrate_1d", + + ## Reduce-sum function + "reduce_sum", "reduce_sum_static", + + ## Map-rect function + "map_rect", + + # Deprecated Functions + "integrate_ode_rk45", "integrate_ode", "integrate_ode_adams", + "integrate_ode_bdf", + + # Hidden Markov Models + "hmm_marginal", "hmm_latent_rng", "hmm_hidden_state_prob" + ] + end + + def self.distributions + @distributions ||= Set.new( + [ + # Discrete Distributions + + ## Binary Distributions + "bernoulli", "bernoulli_logit", "bernoulli_logit_glm", + + ## Bounded Discrete Distributions + "binomial", "binomial_logit", "beta_binomial", "hypergeometric", + "categorical", "categorical_logit_glm", "discrete_range", + "ordered_logistic", "ordered_logistic_glm", "ordered_probit", + + ## Unbounded Discrete Distributions + "neg_binomial", "neg_binomial_2", "neg_binomial_2_log", + "neg_binomial_2_log_glm", "poisson", "poisson_log", + "poisson_log_glm", + + ## Multivariate Discrete Distributions + "multinomial", "multinomial_logit", + + # Continuous Distributions + + ## Unbounded Continuous Distributions + "normal", "std_normal", "normal_id_glm", "exp_mod_normal", + "skew_normal", "student_t", "cauchy", "double_exponential", + "logistic", "gumbel", "skew_double_exponential", + + ## Positive Continuous Distributions + "lognormal", "chi_square", "inv_chi_square", + "scaled_inv_chi_square", "exponential", "gamma", "inv_gamma", + "weibull", "frechet", "rayleigh", + + ## Positive Lower-Bounded Distributions + "pareto", "pareto_type_2", "wiener", + + ## Continuous Distributions on [0, 1] + "beta", "beta_proportion", + + ## Circular Distributions + "von_mises", + + ## Bounded Continuous Distributions + "uniform", + + ## Distributions over Unbounded Vectors + "multi_normal", "multi_normal_prec", "multi_normal_cholesky", + "multi_gp", "multi_gp_cholesky", "multi_student_t", + "gaussian_dlm_obs", + + ## Simplex Distributions + "dirichlet", + + ## Correlation Matrix Distributions + "lkj_corr", "lkj_corr_cholesky", + + ## Covariance Matrix Distributions + "wishart", "inv_wishart" + ].product([ + "", "_lpmf", "_lupmf", "_lpdf", "_lcdf", "_lccdf", "_rng", "_log", + "_cdf_log", "_ccdf_log" + ]).map {|s| "#{s[0]}#{s[1]}"} + ) + end + + def self.constants + @constants ||= Set.new [ + # Mathematical constants + "pi", "e", "sqrt2", "log2", "log10", + + # Special values + "not_a_number", "positive_infinity", "negative_infinity", + "machine_precision" + ] + end + + state :root do + mixin :whitespace + rule %r/#include/, Comment::Preproc, :include + rule %r/#.*$/, Generic::Deleted + rule %r( + functions + |(?:transformed\s+)?data + |(?:transformed\s+)?parameters + |model + |generated\s+quantities + )x, Name::Namespace + rule %r(\{), Punctuation, :bracket_scope + mixin :scope + end + + state :include do + rule %r((\s+)(\S+)(\s*)) do |m| + token Text, m[1] + token Comment::PreprocFile, m[2] + token Text, m[3] + pop! + end + end + + state :whitespace do + rule %r(\n+)m, Text + rule %r(//(\\.|.)*?$), Comment::Single + mixin :inline_whitespace + end + + state :inline_whitespace do + rule %r([ \t\r]+), Text + rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline + end + + state :statements do + mixin :whitespace + rule %r/#include/, Comment::Preproc, :include + rule %r/#.*$/, Generic::Deleted + rule %r("), Str, :string + rule %r( + ( + ((\d+[.]\d*|[.]?\d+)e[+-]?\d+|\d*[.]\d+|\d+) + (#{WS})[+-](#{WS}) + ((\d+[.]\d*|[.]?\d+)e[+-]?\d+|\d*[.]\d+|\d+)i + ) + |((\d+[.]\d*|[.]?\d+)e[+-]?\d+|\d*[.]\d+|\d+)i + |((\d+[.]\d*|[.]?\d+)e[+-]?\d+|\d*[.]\d+) + )mx, Num::Float + rule %r/\d+/, Num::Integer + rule %r(\*/), Error + rule OP, Operator + rule %r([\[\],.;]), Punctuation + rule %r([|](?![|])), Punctuation + rule %r(T\b), Keyword::Reserved + rule %r((lower|upper)\b), Name::Attribute + rule ID do |m| + name = m[0] + + if self.class.keywords.include? name + token Keyword + elsif self.class.types.include? name + token Keyword::Type + elsif self.class.reserved.include? name + token Keyword::Reserved + else + token Name::Variable + end + end + end + + state :scope do + mixin :whitespace + rule %r( + (#{RT}) # Return type + (#{ID}) # Function name + (?=\([^;]*?\)) # Signature or arguments + )mx do |m| + recurse m[1] + + name = m[2] + if self.class.builtin_functions.include? name + token Name::Builtin, name + elsif self.class.distributions.include? name + token Name::Builtin, name + elsif self.class.constants.include? name + token Keyword::Constant + else + token Name::Function, name + end + end + rule %r(\{), Punctuation, :bracket_scope + rule %r(\(), Punctuation, :parens_scope + mixin :statements + end + + state :bracket_scope do + mixin :scope + rule %r(\}), Punctuation, :pop! + end + + state :parens_scope do + mixin :scope + rule %r(\)), Punctuation, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stata.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stata.rb new file mode 100644 index 0000000..d002316 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/stata.rb @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Stata < RegexLexer + title "Stata" + desc "The Stata programming language (www.stata.com)" + tag 'stata' + filenames '*.do', '*.ado' + mimetypes 'application/x-stata', 'text/x-stata' + + ### + # Stata reference manual is available online at: https://www.stata.com/features/documentation/ + ### + + # Partial list of common programming and estimation commands, as of Stata 16 + # Note: not all abbreviations are included + KEYWORDS = %w( + do run include clear assert set mata log + by bys bysort cap capt capture char class classutil which cdir confirm new existence creturn + _datasignature discard di dis disp displ displa display ereturn error _estimates exit file open read write seek close query findfile fvexpand + gettoken java home heapmax java_heapmax icd9 icd9p icd10 icd10cm icd10pcs initialize javacall levelsof + tempvar tempname tempfile macro shift uniq dups retokenize clean sizeof posof + makecns matcproc marksample mark markout markin svymarkout matlist + accum define dissimilarity eigenvalues get rowjoinbyname rownames score svd symeigen dir list ren rename + more pause plugin call postfile _predict preserve restore program define drop end python qui quietly noi noisily _return return _rmcoll rmsg _robust + serset locale_functions locale_ui signestimationsample checkestimationsample sleep syntax sysdir adopath adosize + tabdisp timer tokenize trace unab unabcmd varabbrev version viewsource + window fopen fsave manage menu push stopbox + net from cd link search install sj stb ado update uninstall pwd ssc ls + using insheet outsheet mkmat svmat sum summ summarize + graph gr_edit twoway histogram kdensity spikeplot + mi miss missing var varname order compress append + gen gene gener genera generat generate egen replace duplicates + estimates nlcom lincom test testnl predict suest + _regress reg regr regre regres regress probit logit ivregress logistic svy gmm ivprobit ivtobit + bsample assert codebook collapse compare contract copy count cross datasignature d ds desc describe destring tostring + drawnorm edit encode decode erase expand export filefilter fillin format frame frget frlink gsort + import dbase delimited excel fred haver sas sasxport5 sasxport8 spss infile infix input insobs inspect ipolate isid + joinby label language labelbook lookfor memory mem merge mkdir mvencode notes obs odbc order outfile + pctile xtile _pctile putmata range recast recode rename group reshape rm rmdir sample save saveold separate shell snapshot sort split splitsample stack statsby sysuse + type unicode use varmanage vl webuse xpose zipfile + number keep tab table tabulate stset stcox tsset xtset + ) + + # Complete list of functions by name, as of Stata 16 + PRIMITIVE_FUNCTIONS = %w( + abbrev abs acos acosh age age_frac asin asinh atan atan2 atanh autocode + betaden binomial binomialp binomialtail binormal birthday bofd byteorder + c _caller cauchy cauchyden cauchytail Cdhms ceil char chi2 chi2den chi2tail Chms + chop cholesky clip Clock clock clockdiff cloglog Cmdyhms Cofc cofC Cofd cofd coleqnumb + collatorlocale collatorversion colnfreeparms colnumb colsof comb cond corr cos cosh + daily date datediff datediff_frac day det dgammapda dgammapdada dgammapdadx dgammapdxdx dhms + diag diag0cnt digamma dofb dofC dofc dofh dofm dofq dofw dofy dow doy dunnettprob e el epsdouble + epsfloat exp expm1 exponential exponentialden exponentialtail + F Fden fileexists fileread filereaderror filewrite float floor fmtwidth frval _frval Ftail + fammaden gammap gammaptail get hadamard halfyear halfyearly has_eprop hh hhC hms hofd hours + hypergeometric hypergeometricp + I ibeta ibetatail igaussian igaussianden igaussiantail indexnot inlist inrange int inv invbinomial invbinomialtail + invcauchy invcauchytail invchi2 invchi2tail invcloglog invdunnettprob invexponential invexponentialtail invF + invFtail invgammap invgammaptail invibeta invibetatail invigaussian invigaussiantail invlaplace invlaplacetail + invlogistic invlogistictail invlogit invnbinomial invnbinomialtail invnchi2 invnchi2tail invnF invnFtail invnibeta invnormal invnt invnttail + invpoisson invpoissontail invsym invt invttail invtukeyprob invweibull invweibullph invweibullphtail invweibulltail irecode islepyear issymmetric + J laplace laplaceden laplacetail ln ln1m ln1p lncauchyden lnfactorial lngamma lnigammaden lnigaussianden lniwishartden lnlaplaceden lnmvnormalden + lnnormal lnnormalden lnnormalden lnnormalden lnwishartden log log10 log1m log1p logistic logisticden logistictail logit + matmissing matrix matuniform max maxbyte maxdouble maxfloat maxint maxlong mdy mdyhms mi min minbyte mindouble minfloat minint minlong minutes + missing mm mmC mod mofd month monthly mreldif msofhours msofminutes msofseconds + nbetaden nbinomial nbinomialp nbinomialtail nchi2 nchi2den nchi2tail nextbirthday nextleapyear nF nFden nFtail nibeta + normal normalden npnchi2 npnF npnt nt ntden nttail nullmat + plural poisson poissonp poissontail previousbirthday previousleapyear qofd quarter quarterly r rbeta rbinomial rcauchy rchi2 recode + real regexm regexr regexs reldif replay return rexponential rgamma rhypergeometric rigaussian rlaplace rlogistic rnormal + round roweqnumb rownfreeparms rownumb rowsof rpoisson rt runiform runiformint rweibull rweibullph + s scalar seconds sign sin sinh smallestdouble soundex soundex_nara sqrt ss ssC strcat strdup string stritrim strlen strlower + strltrim strmatch strofreal strpos strproper strreverse strrpos strrtrim strtoname strtrim strupper subinstr subinword substr sum sweep + t tan tanh tC tc td tden th tin tm tobytes tq trace trigamma trunc ttail tukeyprob tw twithin + uchar udstrlen udsubstr uisdigit uisletter uniform ustrcompare ustrcompareex ustrfix ustrfrom ustrinvalidcnt ustrleft ustrlen ustrlower + ustrltrim ustrnormalize ustrpos ustrregexm ustrregexra ustrregexrf ustrregexs ustrreverse ustrright ustrrpos ustrrtrim ustrsortkey + ustrsortkeyex ustrtitle ustrto ustrtohex ustrtoname ustrtrim ustrunescape ustrupper ustrword ustrwordcount usubinstr usubstr + vec vecdiag week weekly weibull weibullden weibullph weibullphden weibullphtail weibulltail wofd word wordbreaklocale wordcount + year yearly yh ym yofd yq yw + ) + + # Note: types `str1-str2045` handled separately below + def self.type_keywords + @type_keywords ||= Set.new %w(byte int long float double str strL numeric string integer scalar matrix local global numlist varlist newlist) + end + + # Stata commands used with braces. Includes all valid abbreviations for 'forvalues'. + def self.reserved_keywords + @reserved_keywords ||= Set.new %w(if else foreach forv forva forval forvalu forvalue forvalues to while in of continue break nobreak) + end + + ### + # Lexer state and rules + ### + state :root do + + # Pre-processor commands: # + rule %r/^\s*#.*$/, Comment::Preproc + + # Hashbang comments: *! + rule %r/^\*!.*$/, Comment::Hashbang + + # Single-line comment: * + rule %r/^\s*\*.*$/, Comment::Single + + # Keywords: recognize only when they are the first word + rule %r/^\s*(#{KEYWORDS.join('|')})\b/, Keyword + + # Whitespace. Classify `\n` as `Text` to avoid interference with `Comment` and `Keyword` above + rule(/[ \t]+/, Text::Whitespace) + rule(/[\n\r]+/, Text) + + # In-line comment: // + rule %r/\/\/.*?$/, Comment::Single + + # Multi-line comment: /* and */ + rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline + + # Strings indicated by compound double-quotes (`""') and double-quotes ("") + rule %r/`"(\\.|.)*?"'/, Str::Double + rule %r/"(\\.|.)*?"/, Str::Double + + # Format locals (`') and globals ($) as strings + rule %r/`(\\.|.)*?'/, Str::Double + rule %r/(??*+'^/\\!#.=~:&|]), Operator + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/supercollider.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/supercollider.rb new file mode 100644 index 0000000..b2831a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/supercollider.rb @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SuperCollider < RegexLexer + tag 'supercollider' + filenames '*.sc', '*.scd' + + title "SuperCollider" + desc 'A cross-platform interpreted programming language for sound synthesis, algorithmic composition, and realtime performance' + + def self.keywords + @keywords ||= Set.new %w( + var arg classvar const super this + ) + end + + # these aren't technically keywords, but we treat + # them as such because it makes things clearer 99% + # of the time + def self.reserved + @reserved ||= Set.new %w( + case do for forBy loop if while new newCopyArgs + ) + end + + def self.constants + @constants ||= Set.new %w( + true false nil inf thisThread + thisMethod thisFunction thisProcess + thisFunctionDef currentEnvironment + topEnvironment + ) + end + + state :whitespace do + rule %r/\s+/m, Text + end + + state :comments do + rule %r(//.*?$), Comment::Single + rule %r(/[*]) do + token Comment::Multiline + push :nested_comment + end + end + + state :nested_comment do + rule %r(/[*]), Comment::Multiline, :nested_comment + rule %r([*]/), Comment::Multiline, :pop! + rule %r([^*/]+)m, Comment::Multiline + rule %r/./, Comment::Multiline + end + + state :root do + mixin :whitespace + mixin :comments + + rule %r/[\-+]?0[xX]\h+/, Num::Hex + + # radix float + rule %r/[\-+]?\d+r[0-9a-zA-Z]*(\.[0-9A-Z]*)?/, Num::Float + + # normal float + rule %r/[\-+]?((\d+(\.\d+)?([eE][\-+]?\d+)?(pi)?)|pi)/, Num::Float + + rule %r/[\-+]?\d+/, Num::Integer + + rule %r/\$(\\.|.)/, Str::Char + + rule %r/"([^\\"]|\\.)*"/, Str + + # symbols (single-quote notation) + rule %r/'([^\\']|\\.)*'/, Str::Other + + # symbols (backslash notation) + rule %r/\\\w+/, Str::Other + + # symbol arg + rule %r/[A-Za-z_]\w*:/, Name::Label + + rule %r/[A-Z]\w*/, Name::Class + + # primitive + rule %r/_\w+/, Name::Function + + # main identifiers section + rule %r/[a-z]\w*/ do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.constants.include? m[0] + token Keyword::Constant + elsif self.class.reserved.include? m[0] + token Keyword::Reserved + else + token Name + end + end + + # environment variables + rule %r/~\w+/, Name::Variable::Global + + rule %r/[\{\}()\[\];,\.]/, Punctuation + + # operators. treat # (array unpack) as an operator + rule %r/[\+\-\*\/&\|%<>=]+/, Operator + rule %r/[\^:#]/, Operator + + # treat curry argument as a special operator + rule %r/\b_\b/, Name::Builtin + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/svelte.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/svelte.rb new file mode 100644 index 0000000..733a23c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/svelte.rb @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'html.rb' + + class Svelte < HTML + desc 'Svelte single-file components (https://svelte.dev/)' + tag 'svelte' + filenames '*.svelte' + mimetypes 'text/x-svelte', 'application/x-svelte' + + def initialize(*) + super + # todo add support for typescript script blocks + @js = Javascript.new(options) + end + + # Shorthand syntax for passing attributes - ex, `{src}` instead of `src={src}` + prepend :tag do + rule %r/(\{)\s*([a-zA-Z0-9_]+)\s*(})/m do + groups Str::Interpol, Name::Variable, Str::Interpol + pop! + end + end + + prepend :attr do + # Duplicate template_start mixin here with a pop! + # Because otherwise we'll never exit the attr state + rule %r/\{/ do + token Str::Interpol + pop! + push :template + end + end + + # handle templates within attribute single/double quotes + prepend :dq do + mixin :template_start + end + + prepend :sq do + mixin :template_start + end + + prepend :root do + # detect curly braces within HTML text (outside of tags/attributes) + rule %r/([^<&{]*)(\{)(\s*)/ do + groups Text, Str::Interpol, Text + push :template + end + end + + state :template_start do + # open template + rule %r/\s*\{\s*/, Str::Interpol, :template + end + + state :template do + # template end + rule %r/}/, Str::Interpol, :pop! + + # Allow JS lexer to handle matched curly braces within template + rule(/(?<=^|[^\\])\{+.*?(?<=^|[^\\])\}+/) do + delegate @js + end + + # keywords + rule %r/@(debug|html)\b/, Keyword + rule %r/(#await)(.*)(then|catch)(\s+)(\w+)/ do |m| + token Keyword, m[1] + delegate @js, m[2] + token Keyword, m[3] + token Text, m[4] + delegate @js, m[5] + end + rule %r/([#\/])(await|each|if|key)\b/, Keyword + rule %r/(:else)(\s+)(if)?\b/ do + groups Keyword, Text, Keyword + end + rule %r/:?(catch|then)\b/, Keyword + + # allow JS parser to handle anything that's not a curly brace + rule %r/[^{}]+/ do + delegate @js + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/swift.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/swift.rb new file mode 100644 index 0000000..96b85c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/swift.rb @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Swift < RegexLexer + tag 'swift' + filenames '*.swift' + + title "Swift" + desc 'Multi paradigm, compiled programming language developed by Apple for iOS and OS X development. (developer.apple.com/swift)' + + id_head = /_|(?!\p{Mc})\p{Alpha}|[^\u0000-\uFFFF]/ + id_rest = /[\p{Alnum}_]|[^\u0000-\uFFFF]/ + id = /#{id_head}#{id_rest}*/ + + keywords = Set.new %w( + autoreleasepool await break case catch consume continue default defer discard do each else fallthrough guard if in for repeat return switch throw try where while + + as dynamicType is new super self Self Type + + associativity async didSet get infix inout isolated left mutating none nonmutating operator override postfix precedence precedencegroup prefix rethrows right set throws unowned weak willSet + ) + + declarations = Set.new %w( + actor any associatedtype borrowing class consuming deinit distributed dynamic enum convenience extension fileprivate final func import indirect init internal lazy let macro nonisolated open optional package private protocol public required some static struct subscript typealias var + ) + + constants = Set.new %w( + true false nil + ) + + start do + push :bol + @re_delim = "" # multi-line regex delimiter + end + + # beginning of line + state :bol do + rule %r/#(?![#"\/]).*/, Comment::Preproc + + mixin :inline_whitespace + + rule(//) { pop! } + end + + state :inline_whitespace do + rule %r/\s+/m, Text + mixin :has_comments + end + + state :whitespace do + rule %r/\n+/m, Text, :bol + rule %r(\/\/.*?$), Comment::Single, :bol + mixin :inline_whitespace + end + + state :has_comments do + rule %r(/[*]), Comment::Multiline, :nested_comment + end + + state :nested_comment do + mixin :has_comments + rule %r([*]/), Comment::Multiline, :pop! + rule %r([^*/]+)m, Comment::Multiline + rule %r/./, Comment::Multiline + end + + state :root do + mixin :whitespace + + rule %r/\$(([1-9]\d*)?\d)/, Name::Variable + rule %r/\$#{id}/, Name + rule %r/~Copyable\b/, Keyword::Type + + rule %r{[()\[\]{}:;,?\\]}, Punctuation + rule %r{(#*)/(?!\s).*(?!&|^.~]+), Operator + rule %r/@?"/, Str, :dq + rule %r/'(\\.|.)'/, Str::Char + rule %r/(\d+(?:_\d+)*\*|(?:\d+(?:_\d+)*)*\.\d+(?:_\d)*)(e[+-]?\d+(?:_\d)*)?/i, Num::Float + rule %r/\d+e[+-]?[0-9]+/i, Num::Float + rule %r/0o?[0-7]+(?:_[0-7]+)*/, Num::Oct + rule %r/0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*((\.[0-9A-F]+(?:_[0-9A-F]+)*)?p[+-]?\d+)?/, Num::Hex + rule %r/0b[01]+(?:_[01]+)*/, Num::Bin + rule %r{[\d]+(?:_\d+)*}, Num::Integer + + rule %r/@#{id}/, Keyword::Declaration + rule %r/##{id}/, Keyword + + rule %r/(private|internal)(\([ ]*)(\w+)([ ]*\))/ do |m| + if m[3] == 'set' + token Keyword::Declaration + else + groups Keyword::Declaration, Keyword::Declaration, Error, Keyword::Declaration + end + end + + rule %r/(unowned\([ ]*)(\w+)([ ]*\))/ do |m| + if m[2] == 'safe' || m[2] == 'unsafe' + token Keyword::Declaration + else + groups Keyword::Declaration, Error, Keyword::Declaration + end + end + + rule %r/(let|var)\b(\s*)(#{id})/ do + groups Keyword, Text, Name::Variable + end + + rule %r/(let|var)\b(\s*)([(])/ do + groups Keyword, Text, Punctuation + push :tuple + end + + rule %r/(?!\b(if|while|for|private|internal|unowned|switch|case)\b)\b#{id}(?=(\?|!)?\s*[(])/ do |m| + if m[0] =~ /^[[:upper:]]/ + token Keyword::Type + else + token Name::Function + end + end + + rule %r/as[?!]?(?=\s)/, Keyword + rule %r/try[!]?(?=\s)/, Keyword + + rule %r/(#?(?!default)(?![[:upper:]])#{id})(\s*)(:)/ do + groups Name::Variable, Text, Punctuation + end + + rule id do |m| + if keywords.include? m[0] + token Keyword + elsif declarations.include? m[0] + token Keyword::Declaration + elsif constants.include? m[0] + token Keyword::Constant + elsif m[0] =~ /^[[:upper:]]/ + token Keyword::Type + else + token Name + end + end + + rule %r/(`)(#{id})(`)/ do + groups Punctuation, Name::Variable, Punctuation + end + + rule %r{(#+)/\n} do |m| + @re_delim = m[1] + token Str::Regex + push :re_multi + end + end + + state :tuple do + rule %r/(#{id})/, Name::Variable + rule %r/(`)(#{id})(`)/ do + groups Punctuation, Name::Variable, Punctuation + end + rule %r/,/, Punctuation + rule %r/[(]/, Punctuation, :push + rule %r/[)]/, Punctuation, :pop! + mixin :inline_whitespace + end + + state :dq do + rule %r/\\[\\0tnr'"]/, Str::Escape + rule %r/\\[(]/, Str::Escape, :interp + rule %r/\\u\{\h{1,8}\}/, Str::Escape + rule %r/[^\\"]+/, Str + rule %r/"""/, Str, :pop! + rule %r/"/, Str, :pop! + end + + state :interp do + rule %r/[(]/, Punctuation, :interp_inner + rule %r/[)]/, Str::Escape, :pop! + mixin :root + end + + state :interp_inner do + rule %r/[(]/, Punctuation, :push + rule %r/[)]/, Punctuation, :pop! + mixin :root + end + + state :re_multi do + rule %r{^\s*/#+} do |m| + token Str::Regex + if m[0].end_with?("/#{@re_delim}") + @re_delim = "" + pop! + end + end + + rule %r/#.*/, Comment::Single + rule %r/./m, Str::Regex + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/systemd.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/systemd.rb new file mode 100644 index 0000000..b414abf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/systemd.rb @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class SystemD < RegexLexer + tag 'systemd' + aliases 'unit-file' + filenames '*.service' + mimetypes 'text/x-systemd-unit' + desc 'A lexer for systemd unit files' + + state :root do + rule %r/\s+/, Text + rule %r/[;#].*/, Comment + rule %r/\[.*?\]$/, Keyword + rule %r/(.*?)(=)(.*)(\\\n)/ do + groups Name::Tag, Punctuation, Text, Str::Escape + push :continuation + end + rule %r/(.*?)(=)(.*)/ do + groups Name::Tag, Punctuation, Text + end + end + + state :continuation do + rule %r/(.*?)(\\\n)/ do + groups Text, Str::Escape + end + rule %r/(.*)'?/, Text, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzlang.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzlang.rb new file mode 100644 index 0000000..dbaea03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzlang.rb @@ -0,0 +1,316 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Syzlang < RegexLexer + title "Syzlang" + desc "Syscall description language used by syzkaller" + tag 'syzlang' + + def self.keywords + @keywords ||= Set.new %w( + align breaks_returns dec define disabled hex ignore_return in incdir + include inet inout oct opt out packed parent prog_timeout pseudo + resource size syscall timeout type varlen + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + array bitsize bool16 bool32 bool64 bool8 boolptr buffer bytesize + bytesize2 bytesize4 bytesize8 const csum filename fileoff flags fmt + int16 int16be int32 int32be int64 int64be int8 int8be intptr len + offsetof optional proc ptr ptr64 string stringnoz text vma vma64 void + ) + end + + comment = /#.*$/ + inline_spaces = /[ \t]+/ + spaces = /\s+/ + + state :inline_break do + rule inline_spaces, Text + rule %r//, Text, :pop! + end + + state :space_break do + rule spaces, Text + rule comment, Comment + rule %r//, Text, :pop! + end + + id = /[a-zA-Z_][a-zA-Z0-9_]*/ + num_id = /[a-zA-Z0-9_]+/ + + state :mixin_name do + rule id, Name + end + + state :mixin_number do + rule %r/-?0x[\da-f]+/i, Num::Hex + rule %r/-?\d+/, Num::Integer + rule %r/'[^']?'/, Str::Char + end + + state :mixin_string do + rule %r/"[^"]*"/, Str::Double + rule %r/`[^`]*`/, Str::Backtick + end + + state :mixin_term do + mixin :mixin_number + mixin :mixin_string + + # Keywords. + rule id do |m| + if self.class.keywords.include?(m[0]) + token Keyword + elsif self.class.keywords_type.include?(m[0]) + token Keyword::Type + else + token Name + end + end + + # Ranges. + rule %r/:/, Punctuation + + # "struct$type" struct name format. + rule %r/\$/, Name + end + + state :term_list do + rule spaces, Text + rule comment, Comment + mixin :mixin_term + rule %r/\[/, Punctuation, :term_list + rule %r/,/, Punctuation + rule %r/[\]\)]/, Punctuation, :pop! + end + + state :arg_type do + mixin :mixin_term + rule %r/\[/, Punctuation, :term_list + rule %r//, Text, :pop! + end + + state :include do + rule %r/(<)([^>]+)(>)/ do |m| + groups Punctuation, Str, Punctuation + end + rule %r//, Text, :pop! + end + + state :define_name do + mixin :mixin_name + rule %r//, Text, :pop! + end + + state :define_exp do + mixin :mixin_name + mixin :mixin_number + mixin :mixin_string + rule %r/[~!%\^&\*\-\+\/\|<>\?:]/, Operator + rule %r/[\(\){}\[\];,]/, Punctuation + rule inline_spaces, Text + rule %r//, Text, :pop! + end + + state :resource_name do + mixin :mixin_name + rule %r//, Text, :pop! + end + + state :resource_type do + rule %r/\[/, Punctuation, :arg_type + rule %r/\]/, Punctuation, :pop! + end + + state :resource_values do + rule %r/:/ do + token Punctuation + push :resource_values_list + push :space_break + end + rule %r//, Text, :pop! + end + + state :resource_values_list do + rule inline_spaces, Text + mixin :mixin_name + mixin :mixin_number + mixin :mixin_string + rule %r/,/, Punctuation, :space_break + rule %r//, Text, :pop! + end + + state :flags_list do + rule inline_spaces, Text + rule %r/\./, Punctuation + mixin :mixin_name + mixin :mixin_number + mixin :mixin_string + rule %r/,/, Punctuation, :space_break + rule %r//, Punctuation, :pop! + end + + state :syscall_args do + rule spaces, Text + rule comment, Comment + rule %r/\./, Punctuation + rule id do + token Name + push :arg_type + push :space_break + end + rule %r/,/, Punctuation + rule %r/\)/, Punctuation, :pop! + end + + state :syscall_retval do + mixin :mixin_name + rule %r//, Text, :pop! + end + + state :syscall_mods do + rule %r/\(/, Punctuation, :term_list + rule %r//, Text, :pop! + end + + state :struct_fields do + rule id do + token Name + push :space_break + push :struct_field_mods + push :inline_break + push :arg_type + push :space_break + end + rule %r/[}\]]/, Punctuation, :pop! + end + + state :struct_field_mods do + rule %r/\(/, Punctuation, :term_list + rule %r//, Text, :pop! + end + + state :struct_mods do + rule %r/\[/, Punctuation, :term_list + rule %r//, Text, :pop! + end + + state :type_name do + mixin :mixin_name + rule %r//, Text, :pop! + end + + state :type_args do + rule %r/\[/, Punctuation, :type_args_list + rule %r//, Text, :pop! + end + + state :type_args_list do + rule spaces, Text + rule comment, Comment + mixin :mixin_name + rule %r/,/, Punctuation + rule %r/\]/, Punctuation, :pop! + end + + state :type_body do + rule %r/[{\[]/ do + token Punctuation + pop! + push :space_break + push :struct_mods + push :inline_break + push :struct_fields + push :space_break + end + rule %r// do + pop! + push :arg_type + end + end + + state :root do + # Whitespace. + rule spaces, Text + + # Comments. + rule comment, Comment + + # Includes. + rule %r/(include|incdir)/ do + token Keyword + push :include + push :space_break + end + + # Defines. + rule %r/define/ do + token Keyword + push :define_exp + push :space_break + push :define_name + push :space_break + end + + # Resources. + rule %r/resource/ do + token Keyword + push :resource_values + push :inline_break + push :resource_type + push :inline_break + push :resource_name + push :space_break + end + + # Flags and strings. + rule %r/(#{id}|_)(#{spaces})(=)/ do |m| + if m[1] == "_" + groups Keyword, Text, Punctuation + else + groups Name, Text, Punctuation + end + push :flags_list + push :space_break + end + + # Syscalls. + rule %r/(#{id})(\$)?(#{num_id})?(#{spaces})?(\()/ do |m| + groups Name::Function, Punctuation, Name::Function::Magic, Text, Punctuation + push :syscall_mods + push :inline_break + push :syscall_retval + push :inline_break + push :syscall_args + push :space_break + end + + # Structs and unions. + rule %r/(#{id}|#{id}\$#{num_id})(#{spaces})?([{\[])/ do |m| + groups Name, Text, Punctuation + push :inline_break + push :struct_mods + push :inline_break + push :struct_fields + push :space_break + end + + # Types. + rule %r/type/ do + token Keyword + push :type_body + push :space_break + push :type_args + push :type_name + push :space_break + end + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzprog.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzprog.rb new file mode 100644 index 0000000..8cbcace --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/syzprog.rb @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Syzprog < RegexLexer + title "Syzprog" + desc "Program description language used by syzkaller" + tag 'syzprog' + + def self.keywords + @keywords ||= Set.new %w( + ANY ANYBLOB ANYPTR ANYPTR64 ANYPTRS ANYRES16 ANYRES32 ANYRES64 + ANYRESDEC ANYRESHEX ANYRESOCT ANYUNION AUTO false nil true void + async fail_nth rerun + ) + end + + comment = /#.*$/ + inline_spaces = /[ \t]+/ + eol_spaces = /[\n\r]+/ + spaces = /\s+/ + + id = /[a-zA-Z_][a-zA-Z0-9_]*/ + num_id = /[a-zA-Z0-9_]+/ + res_id = /r[0-9]+/ + + state :inline_break do + rule inline_spaces, Text + rule %r//, Text, :pop! + end + + state :eol_break do + rule eol_spaces, Text + rule comment, Comment + rule %r//, Text, :pop! + end + + state :space_break do + rule spaces, Text + rule comment, Comment + rule %r//, Text, :pop! + end + + state :mixin_number do + rule %r/-?0x[\da-f]+/i, Num::Hex + rule %r/-?\d+/, Num::Integer + end + + state :mixin_string do + rule %r/"[^"]*"/, Str::Double + rule %r/`[^`]*`/, Str::Backtick + rule %r/'[^']*'/, Str::Single + end + + state :mixin_term do + mixin :mixin_number + mixin :mixin_string + + rule %r/#{res_id}/, Keyword::Pseudo + rule id do |m| + if self.class.keywords.include?(m[0]) + token Keyword + else + token Name + end + end + end + + state :mods_list do + rule spaces, Text + rule comment, Comment + mixin :mixin_term + rule %r/[,:]/, Punctuation + rule %r/\)/, Punctuation, :pop! + end + + state :syscall_mods do + rule %r/\(/, Punctuation, :mods_list + rule %r//, Text, :pop! + end + + state :syscall_args do + rule spaces, Text + rule comment, Comment + mixin :mixin_term + mixin :mixin_number + mixin :mixin_string + # This punctuation is a part of the syntax: + rule %r/[@&=,<>{}\[\]]/, Punctuation + # This punctuation is not, highlight just in case: + rule %r/[!#\$%\^\*\-\+\/\|~:;.\?]/, Punctuation + rule %r/\(/, Punctuation, :syscall_args + rule %r/\)/, Punctuation, :pop! + end + + state :root do + # Whitespace. + rule spaces, Text + + # Comments. + rule comment, Comment + + # Return values. + rule %r/(#{res_id})(#{spaces})(=)/ do + groups Keyword::Pseudo, Text, Punctuation + end + + # Syscalls. + rule %r/(#{id})(\$)?(#{num_id})?(#{spaces})?(\()/ do |m| + groups Name::Function, Punctuation, Name::Function::Magic, Text, Punctuation + push :syscall_mods + push :inline_break + push :syscall_args + push :space_break + end + + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tap.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tap.rb new file mode 100644 index 0000000..5fab7fa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tap.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + class Tap < RegexLexer + title 'TAP' + desc 'Test Anything Protocol' + tag 'tap' + aliases 'tap' + filenames '*.tap' + + mimetypes 'text/x-tap', 'application/x-tap' + + state :root do + # A TAP version may be specified. + rule %r/^TAP version \d+\n/, Name::Namespace + + # Specify a plan with a plan line. + rule %r/^1\.\.\d+/, Keyword::Declaration, :plan + + # A test failure + rule %r/^(not ok)([^\S\n]*)(\d*)/ do + groups Generic::Error, Text, Literal::Number::Integer + push :test + end + + # A test success + rule %r/^(ok)([^\S\n]*)(\d*)/ do + groups Keyword::Reserved, Text, Literal::Number::Integer + push :test + end + + # Diagnostics start with a hash. + rule %r/^#.*\n/, Comment + + # TAP's version of an abort statement. + rule %r/^Bail out!.*\n/, Generic::Error + + # # TAP ignores any unrecognized lines. + rule %r/^.*\n/, Text + end + + state :plan do + # Consume whitespace (but not newline). + rule %r/[^\S\n]+/, Text + + # A plan may have a directive with it. + rule %r/#/, Comment, :directive + + # Or it could just end. + rule %r/\n/, Comment, :pop! + + # Anything else is wrong. + rule %r/.*\n/, Generic::Error, :pop! + end + + state :test do + # Consume whitespace (but not newline). + rule %r/[^\S\n]+/, Text + + # A test may have a directive with it. + rule %r/#/, Comment, :directive + + rule %r/\S+/, Text + + rule %r/\n/, Text, :pop! + end + + state :directive do + # Consume whitespace (but not newline). + rule %r/[^\S\n]+/, Comment + + # Extract todo items. + rule %r/(?i)\bTODO\b/, Comment::Preproc + + # Extract skip items. + rule %r/(?i)\bSKIP\S*/, Comment::Preproc + + rule %r/\S+/, Comment + + rule %r/\n/ do + token Comment + pop! 2 + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tcl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tcl.rb new file mode 100644 index 0000000..1bc6c86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tcl.rb @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class TCL < RegexLexer + title "Tcl" + desc "The Tool Command Language (tcl.tk)" + tag 'tcl' + filenames '*.tcl' + mimetypes 'text/x-tcl', 'text/x-script.tcl', 'application/x-tcl' + + def self.detect?(text) + return true if text.shebang? 'tclsh' + return true if text.shebang? 'wish' + return true if text.shebang? 'jimsh' + end + + KEYWORDS = %w( + after apply array break catch continue elseif else error + eval expr for foreach global if namespace proc rename return + set switch then trace unset update uplevel upvar variable + vwait while + ) + + BUILTINS = %w( + append bgerror binary cd chan clock close concat dde dict + encoding eof exec exit fblocked fconfigure fcopy file + fileevent flush format gets glob history http incr info interp + join lappend lassign lindex linsert list llength load loadTk + lrange lrepeat lreplace lreverse lsearch lset lsort mathfunc + mathop memory msgcat open package pid pkg::create pkg_mkIndex + platform platform::shell puts pwd re_syntax read refchan + regexp registry regsub scan seek socket source split string + subst tell time tm unknown unload + ) + + OPEN = %w| \( \[ \{ " | + CLOSE = %w| \) \] \} | + ALL = OPEN + CLOSE + END_LINE = CLOSE + %w(; \n) + END_WORD = END_LINE + %w(\r \t \v) + + CHARS = lambda { |list| Regexp.new %/[#{list.join}]/ } + NOT_CHARS = lambda { |list| Regexp.new %/[^#{list.join}]/ } + + state :word do + rule %r/\{\*\}/, Keyword + + mixin :brace_abort + mixin :interp + rule %r/\{/, Punctuation, :brace + rule %r/\(/, Punctuation, :paren + rule %r/"/, Str::Double, :string + rule %r/#{NOT_CHARS[END_WORD]}+?(?=#{CHARS[OPEN+['\\\\']]})/, Text + end + + def self.gen_command_state(name='') + state(:"command#{name}") do + rule %r/#/, Comment, :comment + + mixin :word + + rule %r/(?=#{CHARS[END_WORD]})/ do + push :"params#{name}" + end + + rule %r/#{NOT_CHARS[END_WORD]}+/ do |m| + if KEYWORDS.include? m[0] + token Keyword + elsif BUILTINS.include? m[0] + token Name::Builtin + else + token Text + end + end + + mixin :whitespace + end + end + + def self.gen_delimiter_states(name, close, opts={}) + gen_command_state("_in_#{name}") + + state :"params_in_#{name}" do + rule close do + token Punctuation + pop! 2 + end + + # mismatched delimiters. Braced strings with mismatched + # closing delimiters should be okay, since this is standard + # practice, like {]]]]} + if opts[:strict] + rule CHARS[CLOSE - [close]], Error + else + rule CHARS[CLOSE - [close]], Text + end + + mixin :params + end + + state name do + rule close, Punctuation, :pop! + mixin :"command_in_#{name}" + end + end + + + # tcl is freaking impossible. If we're in braces and we encounter + # a close brace, we have to drop everything and close the brace. + # This is so silly things like {abc"def} and {abc]def} don't b0rk + # everything after them. + + # TODO: TCL seems to have this aborting behavior quite a lot. + # such things as [ abc" ] are a runtime error, but will still + # parse. Currently something like this will muck up the lex. + state :brace_abort do + rule %r/}/ do + if in_state? :brace + pop! until state? :brace + pop! + token Punctuation + else + token Error + end + end + end + + state :params do + rule %r/;/, Punctuation, :pop! + rule %r/\n/, Text, :pop! + rule %r/else|elseif|then/, Keyword + mixin :word + mixin :whitespace + rule %r/#{NOT_CHARS[END_WORD]}+/, Text + end + + gen_delimiter_states :brace, /\}/, :strict => false + gen_delimiter_states :paren, /\)/, :strict => true + gen_delimiter_states :bracket, /\]/, :strict => true + gen_command_state + + state :root do + mixin :command + end + + state :whitespace do + # not a multiline regex because we want to capture \n sometimes + rule %r/\s+/, Text + end + + state :interp do + rule %r/\[/, Punctuation, :bracket + rule %r/\$[a-z0-9.:-]+/, Name::Variable + rule %r/\$\{.*?\}/m, Name::Variable + rule %r/\$/, Text + + # escape sequences + rule %r/\\[0-7]{3}/, Str::Escape + rule %r/\\x[0-9a-f]{2}/i, Str::Escape + rule %r/\\u[0-9a-f]{4}/i, Str::Escape + rule %r/\\./m, Str::Escape + end + + state :comment do + rule %r/.*[^\\]\n/, Comment, :pop! + rule %r/.*\\\n/, Comment + end + + state :string do + rule %r/"/, Str::Double, :pop! + mixin :interp + rule %r/[^\\\[\$"{}]+/m, Str::Double + + # strings have to keep count of their internal braces, to support + # for example { "{ }" }. + rule %r/{/ do + @brace_count ||= 0 + @brace_count += 1 + + token Str::Double + end + + rule %r/}/ do + if in_state? :brace and @brace_count.to_i == 0 + pop! until state? :brace + pop! + token Punctuation + else + @brace_count -= 1 + token Str::Double + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/terraform.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/terraform.rb new file mode 100644 index 0000000..a41ba5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/terraform.rb @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'hcl.rb' + + class Terraform < Hcl + title "Terraform" + desc "Terraform HCL Interpolations" + + tag 'terraform' + aliases 'tf' + filenames '*.tf', '*.tfvars', '*.tofu' + + def self.keywords + @keywords ||= Set.new %w( + terraform module provider variable resource data provisioner output + ) + end + + def self.declarations + @declarations ||= Set.new %w( + var local + ) + end + + def self.reserved + @reserved ||= Set.new %w() + end + + def self.constants + @constants ||= Set.new %w(true false null) + end + + def self.builtins + @builtins ||= %w() + end + + state :strings do + rule %r/\\./, Str::Escape + rule %r/(\$[\$]+|%[%]+)(\{)/, Str + rule %r/\$\{/ do + token Punctuation + push :interpolation + end + end + + state :dq do + rule %r/[^\\"\$]+/, Str::Double + mixin :strings + rule %r/"/, Str::Double, :pop! + end + + state :sq do + rule %r/[^\\'\$]+/, Str::Single + mixin :strings + rule %r/'/, Str::Single, :pop! + end + + state :heredoc do + rule %r/\n/, Str::Heredoc, :heredoc_nl + rule %r/[^$\n]+/, Str::Heredoc + rule %r/[$]/, Str::Heredoc + mixin :strings + end + + state :interpolation do + rule %r/\}/ do + token Punctuation + pop! + end + + mixin :expression + end + + state :regexps do + rule %r/"\// do + token Str::Delimiter + goto :regexp_inner + end + end + + state :regexp_inner do + rule %r/[^"\/\\]+/, Str::Regex + rule %r/\\./, Str::Regex + rule %r/\/"/, Str::Delimiter, :pop! + rule %r/["\/]/, Str::Regex + end + + id = /[$a-z_\-][a-z0-9_\-]*/io + + state :expression do + mixin :regexps + mixin :primitives + rule %r/\s+/, Text + + rule %r(\+\+ | -- | ~ | && | \|\| | \\(?=\n) | << | >>>? | == | != )x, Operator + rule %r([-<>+*%&|\^/!=?:]=?), Operator + rule %r/[(\[,]/, Punctuation + rule %r/[)\].]/, Punctuation + + rule id do |m| + if self.class.keywords.include? m[0] + token Keyword + elsif self.class.declarations.include? m[0] + token Keyword::Declaration + elsif self.class.reserved.include? m[0] + token Keyword::Reserved + elsif self.class.constants.include? m[0] + token Keyword::Constant + elsif self.class.builtins.include? m[0] + token Name::Builtin + else + token Name::Other + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tex.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tex.rb new file mode 100644 index 0000000..52f4f58 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tex.rb @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class TeX < RegexLexer + title "TeX" + desc "The TeX typesetting system" + tag 'tex' + aliases 'TeX', 'LaTeX', 'latex' + + filenames '*.tex', '*.aux', '*.toc', '*.sty', '*.cls' + mimetypes 'text/x-tex', 'text/x-latex' + + def self.detect?(text) + return true if text =~ /\A\s*\\(documentclass|input|documentstyle|relax|ProvidesPackage|ProvidesClass)/ + end + + command = /\\([a-z]+|\s+|.)/i + + state :general do + rule %r/%.*$/, Comment + rule %r/[{}&_^]/, Punctuation + end + + state :root do + rule %r/\\\[/, Punctuation, :displaymath + rule %r/\\\(/, Punctuation, :inlinemath + rule %r/\$\$/, Punctuation, :displaymath + rule %r/\$/, Punctuation, :inlinemath + rule %r/\\(begin|end)\{.*?\}/, Name::Tag + + rule %r/(\\verb)\b(\S)(.*?)(\2)/ do + groups Name::Builtin, Keyword::Pseudo, Str::Other, Keyword::Pseudo + end + + rule command, Keyword, :command + mixin :general + rule %r/[^\\$%&_^{}]+/, Text + end + + state :math do + rule command, Name::Variable + mixin :general + rule %r/[0-9]+/, Num + rule %r/[-=!+*\/()\[\]]/, Operator + rule %r/[^=!+*\/()\[\]\\$%&_^{}0-9-]+/, Name::Builtin + end + + state :inlinemath do + rule %r/\\\)/, Punctuation, :pop! + rule %r/\$/, Punctuation, :pop! + mixin :math + end + + state :displaymath do + rule %r/\\\]/, Punctuation, :pop! + rule %r/\$\$/, Punctuation, :pop! + rule %r/\$/, Name::Builtin + mixin :math + end + + state :command do + rule %r/\[.*?\]/, Name::Attribute + rule %r/\*/, Keyword + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/toml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/toml.rb new file mode 100644 index 0000000..8670394 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/toml.rb @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class TOML < RegexLexer + title "TOML" + desc 'the TOML configuration format (https://github.com/toml-lang/toml)' + tag 'toml' + + filenames '*.toml', 'Pipfile', 'poetry.lock' + mimetypes 'text/x-toml' + + state :root do + mixin :whitespace + + mixin :key + + rule %r/(=)(\s*)/ do + groups Operator, Text::Whitespace + push :value + end + + rule %r/\[\[?/, Keyword, :table_key + end + + state :key do + rule %r/[A-Za-z0-9_-]+/, Name + + rule %r/"/, Str, :dq + rule %r/'/, Str, :sq + rule %r/\./, Punctuation + end + + state :table_key do + rule %r/[A-Za-z0-9_-]+/, Name + + rule %r/"/, Str, :dq + rule %r/'/, Str, :sq + rule %r/\./, Keyword + rule %r/\]\]?/, Keyword, :pop! + rule %r/[ \t]+/, Text::Whitespace + end + + state :value do + rule %r/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/, Literal::Date, :pop! + rule %r/\d\d:\d\d:\d\d(\.\d+)?/, Literal::Date, :pop! + rule %r/[+-]?\d+(?:_\d+)*\.\d+(?:_\d+)*(?:[eE][+-]?\d+(?:_\d+)*)?/, Num::Float, :pop! + rule %r/[+-]?\d+(?:_\d+)*[eE][+-]?\d+(?:_\d+)*/, Num::Float, :pop! + rule %r/[+-]?(?:nan|inf)/, Num::Float, :pop! + rule %r/0x\h+(?:_\h+)*/, Num::Hex, :pop! + rule %r/0o[0-7]+(?:_[0-7]+)*/, Num::Oct, :pop! + rule %r/0b[01]+(?:_[01]+)*/, Num::Bin, :pop! + rule %r/[+-]?\d+(?:_\d+)*/, Num::Integer, :pop! + + rule %r/"""/, Str, [:pop!, :mdq] + rule %r/"/, Str, [:pop!, :dq] + rule %r/'''/, Str, [:pop!, :msq] + rule %r/'/, Str, [:pop!, :sq] + + rule %r/(true|false)/, Keyword::Constant, :pop! + rule %r/\[/, Punctuation, [:pop!, :array] + rule %r/\{/, Punctuation, [:pop!, :inline] + end + + state :dq do + rule %r/"/, Str, :pop! + rule %r/\n/, Error, :pop! + mixin :esc_str + rule %r/[^\\"\n]+/, Str + end + + state :mdq do + rule %r/"""/, Str, :pop! + mixin :esc_str + rule %r/[^\\"]+/, Str + rule %r/"+/, Str + end + + state :sq do + rule %r/'/, Str, :pop! + rule %r/\n/, Error, :pop! + rule %r/[^'\n]+/, Str + end + + state :msq do + rule %r/'''/, Str, :pop! + rule %r/[^']+/, Str + rule %r/'+/, Str + end + + state :esc_str do + rule %r/\\[0t\tn\n "\\r]/, Str::Escape + end + + state :array do + mixin :whitespace + rule %r/,/, Punctuation + + rule %r/\]/, Punctuation, :pop! + + rule %r//, Token, :value + end + + state :inline do + rule %r/[ \t]+/, Text::Whitespace + + mixin :key + rule %r/(=)(\s*)/ do + groups Punctuation, Text::Whitespace + push :value + end + + rule %r/,/, Punctuation + rule %r/\}/, Punctuation, :pop! + end + + state :whitespace do + rule %r/\s+/, Text + rule %r/#.*?$/, Comment + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tsx.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tsx.rb new file mode 100644 index 0000000..e003bfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tsx.rb @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'jsx.rb' + load_lexer 'typescript/common.rb' + + class TSX < JSX + extend TypescriptCommon + + title 'TSX' + desc 'TypeScript-compatible JSX (www.typescriptlang.org/docs/handbook/jsx.html)' + + tag 'tsx' + filenames '*.tsx' + + prepend :element_name do + rule %r/(\w+)(,)/ do + groups Name::Other, Punctuation + pop! 3 + end + + rule %r//, Punctuation, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ttcn3.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ttcn3.rb new file mode 100644 index 0000000..6ccac4e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/ttcn3.rb @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class TTCN3 < RegexLexer + title "TTCN3" + desc "The TTCN3 programming language (ttcn-3.org)" + + tag 'ttcn3' + filenames '*.ttcn', '*.ttcn3' + mimetypes 'text/x-ttcn3', 'text/x-ttcn' + + def self.keywords + @keywords ||= %w( + module import group type port component signature external + execute const template function altstep testcase var timer if + else select case for while do label goto start stop return + break int2char int2unichar int2bit int2enum int2hex int2oct + int2str int2float float2int char2int char2oct unichar2int + unichar2oct bit2int bit2hex bit2oct bit2str hex2int hex2bit + hex2oct hex2str oct2int oct2bit oct2hex oct2str oct2char + oct2unichar str2int str2hex str2oct str2float enum2int + any2unistr lengthof sizeof ispresent ischosen isvalue isbound + istemplatekind regexp substr replace encvalue decvalue + encvalue_unichar decvalue_unichar encvalue_o decvalue_o + get_stringencoding remove_bom rnd hostid send receive + setverdict + ) + end + + def self.reserved + @reserved ||= %w( + all alt apply assert at configuration conjunct const control + delta deterministic disjunct duration fail finished fuzzy from + history implies inconc inv lazy mod mode notinv now omit + onentry onexit par pass prev realtime seq setstate static + stepsize stream timestamp until values wait + ) + end + + def self.types + @types ||= %w( + anytype address boolean bitstring charstring hexstring octetstring + component enumerated float integer port record set of union universal + ) + end + + id = /[a-zA-Z_]\w*/ + digit = /\d_+\d|\d/ + bin_digit = /[01]_+[01]|[01]/ + oct_digit = /[0-7]_+[0-7]|[0-7]/ + hex_digit = /\h_+\h|\h/ + + state :statements do + rule %r/\n+/m, Text + rule %r/[ \t\r]+/, Text + rule %r/\\\n/, Text # line continuation + + rule %r(//(\\.|.)*?$), Comment::Single + rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline + + rule %r/"/, Str, :string + rule %r/'(?:\\.|[^\\]|\\u[0-9a-f]{4})'/, Str::Char + + rule %r/#{digit}+\.#{digit}+([eE]#{digit}+)?[fd]?/i, Num::Float + rule %r/'#{bin_digit}+'B/i, Num::Bin + rule %r/'#{hex_digit}+'H/i, Num::Hex + rule %r/'#{oct_digit}+'O/i, Num::Oct + rule %r/#{digit}+/i, Num::Integer + + rule %r([~!%^&*+:=\|?<>/-]), Operator + rule %r/[()\[\]{},.;:]/, Punctuation + + rule %r/(?:true|false|null)\b/, Name::Builtin + + rule id do |m| + name = m[0] + if self.class.keywords.include? name + token Keyword + elsif self.class.types.include? name + token Keyword::Type + elsif self.class.reserved.include? name + token Keyword::Reserved + else + token Name + end + end + end + + state :root do + rule %r/module\b/, Keyword::Declaration, :module + rule %r/import\b/, Keyword::Namespace, :import + + mixin :statements + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\([\\abfnrtv"']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})/, Str::Escape + rule %r/[^\\"\n]+/, Str + rule %r/\\\n/, Str + rule %r/\\/, Str # stray backslash + end + + state :module do + rule %r/\s+/m, Text + rule id, Name::Class, :pop! + end + + state :import do + rule %r/\s+/m, Text + rule %r/[\w.]+\*?/, Name::Namespace, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tulip.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tulip.rb new file mode 100644 index 0000000..9767bcb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/tulip.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + class Tulip < RegexLexer + desc 'the tulip programming language (twitter.com/tuliplang)' + tag 'tulip' + aliases 'tulip' + + filenames '*.tlp' + + mimetypes 'text/x-tulip', 'application/x-tulip' + + def self.detect?(text) + return true if text.shebang? 'tulip' + end + + id = /[a-z][\w-]*/i + upper_id = /[A-Z][\w-]*/ + + state :comments_and_whitespace do + rule %r/\s+/, Text + rule %r/#.*?$/, Comment + end + + state :root do + mixin :comments_and_whitespace + + rule %r/@#{id}/, Keyword + + + rule %r/(\\#{id})([{])/ do + groups Name::Function, Str + push :nested_string + end + + rule %r/([+]#{id})([{])/ do + groups Name::Decorator, Str + push :nested_string + end + + rule %r/\\#{id}/, Name::Function + rule %r/[+]#{id}/, Name::Decorator + + rule %r/"[{]/, Str, :dqi + rule %r/"/, Str, :dq + + rule %r/'{/, Str, :nested_string + rule %r/'#{id}/, Str + + rule %r/[.]#{id}/, Name::Tag + rule %r/[$]#{id}?/, Name::Variable + rule %r/-#{id}:?/, Name::Label + rule %r/%#{id}/, Name::Function + rule %r/`#{id}/, Operator::Word + + rule %r/[?~%._>,!\[\]:{}()=;\/-]/, Punctuation + + rule %r/[0-9]+([.][0-9]+)?/, Num + + rule %r/#{id}/, Name + + rule %r//, Comment::Preproc, :pop! + rule %r/[*:]/, Punctuation + rule %r/#{upper_id}/, Keyword::Type + rule %r/#{id}/, Name::Variable + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/turtle.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/turtle.rb new file mode 100644 index 0000000..46d5f4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/turtle.rb @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Turtle < RegexLexer + title "Turtle/TriG" + desc "Terse RDF Triple Language, TriG" + tag 'turtle' + filenames '*.ttl', '*.trig' + mimetypes 'text/turtle', 'application/trig' + + state :root do + rule %r/@base\b/, Keyword::Declaration + rule %r/@prefix\b/, Keyword::Declaration + rule %r/true\b/, Keyword::Constant + rule %r/false\b/, Keyword::Constant + + rule %r/""".*?"""/m, Literal::String + rule %r/"([^"\\]|\\.)*"/, Literal::String + rule %r/'''.*?'''/m, Literal::String + rule %r/'([^'\\]|\\.)*'/, Literal::String + + rule %r/#.*$/, Comment::Single + + rule %r/@[^\s,.;]+/, Name::Attribute + + rule %r/[+-]?[0-9]+\.[0-9]*E[+-]?[0-9]+/, Literal::Number::Float + rule %r/[+-]?\.[0-9]+E[+-]?[0-9]+/, Literal::Number::Float + rule %r/[+-]?[0-9]+E[+-]?[0-9]+/, Literal::Number::Float + + rule %r/[+-]?[0-9]*\.[0-9]+?/, Literal::Number::Float + + rule %r/[+-]?[0-9]+/, Literal::Number::Integer + + rule %r/\./, Punctuation + rule %r/,/, Punctuation + rule %r/;/, Punctuation + rule %r/\(/, Punctuation + rule %r/\)/, Punctuation + rule %r/\{/, Punctuation + rule %r/\}/, Punctuation + rule %r/\[/, Punctuation + rule %r/\]/, Punctuation + rule %r/\^\^/, Punctuation + + rule %r/<[^>]*>/, Name::Label + + rule %r/base\b/i, Keyword::Declaration + rule %r/prefix\b/i, Keyword::Declaration + rule %r/GRAPH\b/, Keyword + rule %r/a\b/, Keyword + + rule %r/\s+/, Text::Whitespace + + rule %r/[^:;<>#\@"\(\).\[\]\{\} ]*:/, Name::Namespace + rule %r/[^:;<>#\@"\(\).\[\]\{\} ]+/, Name + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/twig.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/twig.rb new file mode 100644 index 0000000..036ee38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/twig.rb @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'jinja.rb' + + class Twig < Jinja + title "Twig" + desc "Twig template engine (twig.sensiolabs.org)" + + tag "twig" + + filenames '*.twig' + + mimetypes 'application/x-twig', 'text/html+twig' + + def self.keywords + @keywords ||= %w(as do extends flush from import include use else starts + ends with without autoescape endautoescape block + endblock embed endembed filter endfilter for endfor + if endif macro endmacro sandbox endsandbox set endset + spaceless endspaceless) + end + + def self.tests + @tests ||= %w(constant defined divisibleby empty even iterable null odd + sameas) + end + + def self.pseudo_keywords + @pseudo_keywords ||= %w(true false none) + end + + def self.word_operators + @word_operators ||= %w(b-and b-or b-xor is in and or not) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript.rb new file mode 100644 index 0000000..79a104b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript.rb @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'javascript.rb' + load_lexer 'typescript/common.rb' + + class Typescript < Javascript + extend TypescriptCommon + + title "TypeScript" + desc "TypeScript, a superset of JavaScript (https://www.typescriptlang.org/)" + + tag 'typescript' + aliases 'ts' + + filenames '*.ts', '*.d.ts', '*.cts', '*.mts' + + mimetypes 'text/typescript' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript/common.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript/common.rb new file mode 100644 index 0000000..ec45efc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/typescript/common.rb @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + module TypescriptCommon + def keywords + @keywords ||= super + Set.new(%w( + is namespace static private protected public + implements readonly + )) + end + + def declarations + @declarations ||= super + Set.new(%w( + type abstract + )) + end + + def reserved + @reserved ||= super + Set.new(%w( + string any void number namespace module + declare default interface keyof + )) + end + + def builtins + @builtins ||= super + %w( + Capitalize ConstructorParameters Exclude Extract InstanceType + Lowercase NonNullable Omit OmitThisParameter Parameters + Partial Pick Readonly Record Required + ReturnType ThisParameterType ThisType Uncapitalize Uppercase + ) + end + + def self.extended(base) + base.prepend :root do + rule %r/[?][.]/, base::Punctuation + rule %r/[?]{2}/, base::Operator + + # Positive Examples: + # const cat = { name: "Garfield" } satisfies Person; + # import {something as thingy} from 'module' + # export { foo as default } + # ...spreadOperator as const; + # Negative Example: + # cy.get('kitten').as('friend') + rule %r{(?/, Keyword + + rule %r/[~!%^&*()+=|\[\]{}:;,.<>\/?-]/, Punctuation + rule %r/@"(\\.|.)*?"/, Str + rule %r/"(\\.|.)*?["\n]/, Str + rule %r/'(\\.|.)'/, Str::Char + rule %r/0x[0-9a-f]+[lu]?/i, Num + rule %r( + [0-9] + ([.][0-9]*)? # decimal + (e[+-][0-9]+)? # exponent + [fldu]? # type + )ix, Num + rule %r/\b(#{keywords.join('|')})\b/, Keyword + rule %r/\b(#{keywords_type.join('|')})\b/, Keyword::Type + rule %r/class|struct/, Keyword, :class + rule %r/namespace|using/, Keyword, :namespace + rule %r/#{id}(?=\s*[(])/, Name::Function + rule id, Name + + rule %r/#.*/, Comment::Preproc + end + + state :class do + mixin :whitespace + rule id, Name::Class, :pop! + end + + state :namespace do + mixin :whitespace + rule %r/(?=[(])/, Text, :pop! + rule %r/(#{id}|[.])+/, Name::Namespace, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/varnish.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/varnish.rb new file mode 100644 index 0000000..07c0c67 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/varnish.rb @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Varnish < RegexLexer + title 'VCL: Varnish Configuration Language' + desc 'The configuration language for Varnish HTTP Cache (varnish-cache.org)' + + tag 'vcl' + aliases 'varnishconf', 'varnish' + filenames '*.vcl' + mimetypes 'text/x-varnish', 'text/x-vcl' + + SPACE = '[ \f\n\r\t\v]+' + + # backend acl + def self.keywords + @keywords ||= Set.new %w[ + vcl set unset include import if else elseif elif elsif director probe + backend acl + + declare local + BOOL FLOAT INTEGER IP RTIME STRING TIME + ] + end + + def self.functions + @functions ||= Set.new %w[ + ban call hash_data new regsub regsuball return rollback + std.cache_req_body std.collect std.duration std.fileread std.healthy + std.integer std.ip std.log std.port std.querysort std.random std.real + std.real2time std.rollback std.set_ip_tos std.strstr std.syslog + std.time std.time2integer std.time2real std.timestamp std.tolower + std.toupper synth synthetic + ] + end + + def self.variables + @variables ||= Set.new %w[ + bereq bereq.backend bereq.between_bytes_timeout bereq.connect_timeout + bereq.first_byte_timeout bereq.method bereq.proto bereq.retries + bereq.uncacheable bereq.url bereq.xid beresp beresp.age + beresp.backend beresp.backend.ip beresp.backend.name beresp.do_esi + beresp.do_gunzip beresp.do_gzip beresp.do_stream beresp.grace + beresp.keep beresp.proto beresp.reason beresp.status + beresp.storage_hint beresp.ttl beresp.uncacheable beresp.was_304 + client.identity client.ip local.ip now obj.age obj.grace obj.hits + obj.keep obj.proto obj.reason obj.status obj.ttl obj.uncacheable + remote.ip req req.backend_hint req.can_gzip req.esi req.esi_level + req.hash_always_miss req.hash_ignore_busy req.method req.proto + req.restarts req.ttl req.url req.xid resp resp.proto resp.reason + resp.status server.hostname server.identity server.ip + ] + end + + # This is never used + # def self.routines + # @routines ||= Set.new %w[ + # backend_error backend_fetch backend_response purge deliver fini hash + # hit init miss pass pipe recv synth + # ] + # end + + state :root do + # long strings ({" ... "}) + rule %r/\{".*?"}/m, Str::Single + + # heredoc style long strings ({xyz"..."xyz}) + rule %r/\{(\w+)".*?"(\1)\}/m, Str::Single + + # comments + rule %r'/\*.*?\*/'m, Comment::Multiline + rule %r'(?://|#).*', Comment::Single + + rule %r/true|false/, Keyword::Constant + + # "wildcard variables" + var_prefix = Regexp.union(%w(beresp bereq resp req obj)) + rule %r/(?:#{var_prefix})\.http\.[\w.-]+/ do + token Name::Variable + end + + # local variables (var.*) + rule %r/(?:var)\.[\w.-]+/ do + token Name::Variable + end + + rule %r/(sub)(#{SPACE})([\w-]+)/ do + groups Keyword, Text, Name::Function + end + + # inline C (C{ ... }C) + rule %r/C\{/ do + token Comment::Preproc + push :inline_c + end + + rule %r/\.?[a-z_][\w.-]*/i do |m| + next token Keyword if self.class.keywords.include? m[0] + next token Name::Function if self.class.functions.include? m[0] + next token Name::Variable if self.class.variables.include? m[0] + token Text + end + + ## for number literals + + decimal = %r/[0-9]+/ + hex = %r/[0-9a-f]+/i + + numeric = %r{ + (?: + 0x#{hex} + (?:\.#{hex})? + (?:p[+-]?#{hex})? + ) + | + (?: + #{decimal} + (?:\.#{decimal})? + (?:e[+-]?#{decimal})? + ) + }xi + + # duration literals + duration_suffix = Regexp.union(%w(ms s m h d w y)) + rule %r/#{numeric}#{duration_suffix}/, Num::Other + + # numeric literals (integer / float) + rule numeric do |m| + case m[0] + when /^#{decimal}$/ + token Num::Integer + when /^0x#{hex}$/ + token Num::Integer + else + token Num::Float + end + end + + # standard strings + rule %r/"/, Str::Double, :string + + rule %r'[&|+-]{2}|[<=>!*/+-]=|<<|>>|!~|[-+*/%><=!&|~]', Operator + + rule %r/[{}();.,]/, Punctuation + + rule %r/\r\n?|\n/, Text + rule %r/./, Text + end + + state :string do + rule %r/"/, Str::Double, :pop! + rule %r/\\[\\"nt]/, Str::Escape + + rule %r/\r\n?|\n/, Str::Double + rule %r/./, Str::Double + end + + state :inline_c do + rule %r/}C/, Comment::Preproc, :pop! + rule %r/.*?(?=}C)/m do + delegate C + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vb.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vb.rb new file mode 100644 index 0000000..74870ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vb.rb @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class VisualBasic < RegexLexer + title "Visual Basic" + desc "Visual Basic" + tag 'vb' + aliases 'visualbasic' + filenames '*.vbs', '*.vb' + mimetypes 'text/x-visualbasic', 'application/x-visualbasic' + + def self.keywords + @keywords ||= Set.new %w( + AddHandler Alias ByRef ByVal CBool CByte CChar CDate CDbl CDec + CInt CLng CObj CSByte CShort CSng CStr CType CUInt CULng CUShort + Call Case Catch Class Const Continue Declare Default Delegate + Dim DirectCast Do Each Else ElseIf End EndIf Enum Erase Error + Event Exit False Finally For Friend Function Get Global GoSub + GoTo Handles If Implements Imports Inherits Interface Let + Lib Loop Me Module MustInherit MustOverride MyBase MyClass + Namespace Narrowing New Next Not NotInheritable NotOverridable + Nothing Of On Operator Option Optional Overloads Overridable + Overrides ParamArray Partial Private Property Protected Public + RaiseEvent ReDim ReadOnly RemoveHandler Resume Return Select Set + Shadows Shared Single Static Step Stop Structure Sub SyncLock + Then Throw To True Try TryCast Using Wend When While Widening + With WithEvents WriteOnly + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + Boolean Byte Char Date Decimal Double Integer Long Object + SByte Short Single String Variant UInteger ULong UShort + ) + end + + def self.operator_words + @operator_words ||= Set.new %w( + AddressOf And AndAlso As GetType In Is IsNot Like Mod Or OrElse + TypeOf Xor + ) + end + + def self.builtins + @builtins ||= Set.new %w( + Console ConsoleColor + ) + end + + id = /[a-z_]\w*/i + upper_id = /[A-Z]\w*/ + + state :whitespace do + rule %r/\s+/, Text + rule %r/\n/, Text, :bol + rule %r/rem\b.*?$/i, Comment::Single + rule %r(%\{.*?%\})m, Comment::Multiline + rule %r/'.*$/, Comment::Single + end + + state :bol do + rule %r/\s+/, Text + rule %r/<.*?>/, Name::Attribute + rule(//) { :pop! } + end + + state :root do + mixin :whitespace + rule %r( + [#]If\b .*? \bThen + | [#]ElseIf\b .*? \bThen + | [#]End \s+ If + | [#]Const + | [#]ExternalSource .*? \n + | [#]End \s+ ExternalSource + | [#]Region .*? \n + | [#]End \s+ Region + | [#]ExternalChecksum + )x, Comment::Preproc + rule %r/[.]/, Punctuation, :dotted + rule %r/[(){}!#,:]/, Punctuation + rule %r/Option\s+(Strict|Explicit|Compare)\s+(On|Off|Binary|Text)/, + Keyword::Declaration + rule %r/End\b/, Keyword, :end + rule %r/(Dim|Const)\b/, Keyword, :dim + rule %r/(Function|Sub|Property)\b/, Keyword, :funcname + rule %r/(Class|Structure|Enum)\b/, Keyword, :classname + rule %r/(Module|Namespace|Imports)\b/, Keyword, :namespace + + rule upper_id do |m| + match = m[0] + if self.class.keywords.include? match + token Keyword + elsif self.class.keywords_type.include? match + token Keyword::Type + elsif self.class.operator_words.include? match + token Operator::Word + elsif self.class.builtins.include? match + token Name::Builtin + else + token Name + end + end + + rule( + %r(&=|[*]=|/=|\\=|\^=|\+=|-=|<<=|>>=|<<|>>|:=|<=|>=|<>|[-&*/\\^+=<>.]), + Operator + ) + + rule %r/"/, Str, :string + rule %r/#{id}[%&@!#\$]?/, Name + rule %r/#.*?#/, Literal::Date + + rule %r/(\d+\.\d*|\d*\.\d+)(f[+-]?\d+)?/i, Num::Float + rule %r/\d+([SILDFR]|US|UI|UL)?/, Num::Integer + rule %r/&H[0-9a-f]+([SILDFR]|US|UI|UL)?/, Num::Integer + rule %r/&O[0-7]+([SILDFR]|US|UI|UL)?/, Num::Integer + + rule %r/_\n/, Keyword + end + + state :dotted do + mixin :whitespace + rule id, Name, :pop! + end + + state :string do + rule %r/""/, Str::Escape + rule %r/"C?/, Str, :pop! + rule %r/[^"]+/, Str + end + + state :dim do + mixin :whitespace + rule id, Name::Variable, :pop! + rule(//) { pop! } + end + + state :funcname do + mixin :whitespace + rule id, Name::Function, :pop! + end + + state :classname do + mixin :whitespace + rule id, Name::Class, :pop! + end + + state :namespace do + mixin :whitespace + rule %r/#{id}([.]#{id})*/, Name::Namespace, :pop! + end + + state :end do + mixin :whitespace + rule %r/(Function|Sub|Property|Class|Structure|Enum|Module|Namespace)\b/, + Keyword, :pop! + rule(//) { pop! } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/velocity.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/velocity.rb new file mode 100644 index 0000000..4aa23ad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/velocity.rb @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- # + +module Rouge + module Lexers + class Velocity < TemplateLexer + title 'Velocity' + desc 'Velocity is a Java-based template engine (velocity.apache.org)' + tag 'velocity' + filenames '*.vm', '*.velocity', '*.fhtml' + mimetypes 'text/html+velocity' + + id = /[a-z_]\w*/i + + state :root do + rule %r/[^{#$]+/ do + delegate parent + end + + rule %r/(#)(\*.*?\*)(#)/m, Comment::Multiline + rule %r/(##)(.*?$)/, Comment::Single + + rule %r/(#\{?)(#{id})(\}?)(\s?\()/m do + groups Punctuation, Name::Function, Punctuation, Punctuation + push :directive_params + end + + rule %r/(#\{?)(#{id})(\}|\b)/m do + groups Punctuation, Name::Function, Punctuation + end + + rule %r/\$\{?/, Punctuation, :variable + end + + state :variable do + rule %r/#{id}/, Name::Variable + rule %r/\(/, Punctuation, :func_params + rule %r/(\.)(#{id})/ do + groups Punctuation, Name::Variable + end + rule %r/\}/, Punctuation, :pop! + rule(//) { pop! } + end + + state :directive_params do + rule %r/(&&|\|\||==?|!=?|[-<>+*%&|^\/])|\b(eq|ne|gt|lt|ge|le|not|in)\b/, Operator + rule %r/\[/, Operator, :range_operator + rule %r/\b#{id}\b/, Name::Function + mixin :func_params + end + + state :range_operator do + rule %r/[.]{2}/, Operator + mixin :func_params + rule %r/\]/, Operator, :pop! + end + + state :func_params do + rule %r/\$\{?/, Punctuation, :variable + rule %r/\s+/, Text + rule %r/,/, Punctuation + rule %r/"(\\\\|\\"|[^"])*"/, Str::Double + rule %r/'(\\\\|\\'|[^'])*'/, Str::Single + rule %r/0[xX][0-9a-fA-F]+[Ll]?/, Num::Hex + rule %r/\b[0-9]+\b/, Num::Integer + rule %r/(true|false|null)\b/, Keyword::Constant + rule %r/[(\[]/, Punctuation, :push + rule %r/[)\]}]/, Punctuation, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/verilog.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/verilog.rb new file mode 100644 index 0000000..820c435 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/verilog.rb @@ -0,0 +1,163 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Verilog < RegexLexer + title "Verilog and System Verilog" + desc "The System Verilog hardware description language" + tag 'verilog' + filenames '*.v', '*.sv', '*.svh' + mimetypes 'text/x-verilog', 'text/x-systemverilog' + + id = /[a-zA-Z_][a-zA-Z0-9_]*/ + + def self.keywords + @keywords ||= Set.new %w( + alias always always_comb always_ff always_latch assert assert_strobe + assign assume automatic attribute before begin bind bins binsof break + case casex casez clocking config constraint context continue cover + covergroup coverpoint cross deassign defparam default design dist do + else end endattribute endcase endclass endclocking endconfig + endfunction endgenerate endgroup endinterface endmodule endpackage + endprimitive endprogram endproperty endspecify endsequence endtable + endtask expect export extends extern final first_match for force + foreach fork forkjoin forever function generate genvar if iff ifnone + ignore_bins illegal_bins import incdir include initial inside instance + interface intersect join join_any join_none liblist library local + localparam matches module modport new noshowcancelled null package + parameter primitive priority program property protected + pulsestyle_onevent pulsestyle_ondetect pure rand randc randcase + randsequence release return sequence showcancelled solve specify super + table task this throughout timeprecision timeunit type typedef unique + use wait wait_order while wildcard with within + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + and bit buf bufif0 bufif1 byte cell chandle class cmos const disable + edge enum event highz0 highz1 initial inout input int integer join + logic longint macromodule medium nand negedge nmos nor not + notif0 notif1 or output packed parameter pmos posedge pull0 pull1 + pulldown pullup rcmos real realtime ref reg repeat rnmos rpmos rtran + rtranif0 rtranif1 scalared shortint shortreal signed specparam + static string strength strong0 strong1 struct supply0 supply1 tagged + time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg union + unsigned uwire var vectored virtual void wait wand weak[01] wire wor + xnor xor + ) + end + + def self.keywords_system_task + @keyword_system_task ||= Set.new %w( + acos acosh asin asinh assertfailoff assertfailon assertkill + assertnonvacuouson assertoff asserton assertpassoff assertpasson + assertvacuousoff atan atan2 atanh bits bitstoreal bitstoshortreal + cast ceil changed changed_gclk changing_gclk clog2 cos cosh countones + coverage_control coverage_get coverage_get_max coverage_merge + coverage_save dimensions display displayb displayh displayo + dist_chi_square dist_erlang dist_exponential dist_normal dist_poisson + dist_t dist_uniform dumpall dumpfile dumpflush dumplimit dumpoff + dumpon dumpports dumpportsall dumpportsflush dumpportslimit + dumpportsoff dumpportson dumpvars error exit exp falling_gclk fclose + fdisplay fdisplayb fdisplayh fdisplayo fell fell_gclk feof ferror + fflush fgetc fgets finish floor fmonitor fmonitorb fmonitorh fmonitoro + fopen fread fscanf fseek fstrobe fstrobeb fstrobeh fstrobeo ftell + future_gclk fwrite fwriteb fwriteh fwriteo get_coverage high hypot + increment info isunbounded isunknown itor left ln load_coverage_db + log10 low monitor monitorb monitorh monitoro monitoroff monitoron + onehot onehot0 past past_gclk pow printtimescale q_add q_exam q_full + q_initialize q_remove random readmemb readmemh realtime realtobits + rewind right rising_gclk rose rose_gclk rtoi sampled + set_coverage_db_name sformat sformatf shortrealtobits signed sin sinh + size sqrt sscanf stable stable_gclk steady_gclk stime stop strobe + strobeb strobeh strobeo swrite swriteb swriteh swriteo system tan tanh + time timeformat typename ungetc unpacked_dimensions unsigned warning + write writeb writeh writememb writememh writeo + ) + end + + state :expr_bol do + mixin :inline_whitespace + rule %r/`define/, Comment::Preproc, :macro + + rule(//) { pop! } + end + + # :expr_bol is the same as :bol but without labels, since + # labels can only appear at the beginning of a statement. + state :bol do + rule %r/#{id}:(?!:)/, Name::Label + mixin :expr_bol + end + + state :inline_whitespace do + rule %r/[ \t\r]+/, Text + rule %r/\\\n/, Text # line continuation + rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, Comment::Multiline + end + + state :whitespace do + rule %r/\n+/m, Text, :bol + rule %r(//(\\.|.)*?$), Comment::Single, :bol + mixin :inline_whitespace + end + + state :expr_whitespace do + rule %r/\n+/m, Text, :expr_bol + mixin :whitespace + end + + state :string do + rule %r/"/, Str, :pop! + rule %r/\\([\\abfnrtv"']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})/, Str::Escape + rule %r/[^\\"\n]+/, Str + rule %r/\\\n/, Str + rule %r/\\/, Str # stray backslash + end + + state :statement do + mixin :whitespace + rule %r/L?"/, Str, :string + rule %r/([0-9_]+\.[0-9_]*|[0-9_]*\.[0-9_]+)(e[+-]?[0-9_]+)?/i, Num::Float + rule %r/[0-9_]+e[+-]?[0-9_]+/i, Num::Float + rule %r/[0-9]*'h[0-9a-fA-F_?]+/, Num::Hex + rule %r/[0-9]*'b?[01xz_?]+/, Num::Bin + rule %r/[0-9]*'d[0-9_?]+/, Num::Integer + rule %r/[0-9_]+[lu]*/i, Num::Integer + rule %r([-~!%^&*+=\|?:<>/@{}]), Operator + rule %r/[()\[\],.$\#;]/, Punctuation + rule %r/`(\w+)/, Comment::Preproc + + rule id do |m| + name = m[0] + + if self.class.keywords.include? name + token Keyword + elsif self.class.keywords_type.include? name + token Keyword::Type + elsif self.class.keywords_system_task.include? name + token Name::Builtin + else + token Name + end + end + end + + state :root do + mixin :expr_whitespace + rule(//) { push :statement } + end + + state :macro do + rule %r/\n/, Comment::Preproc, :pop! + mixin :inline_whitespace + rule %r/;/, Punctuation + rule %r/\=/, Operator + rule %r/(\w+)/, Text + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vhdl.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vhdl.rb new file mode 100644 index 0000000..38ff5fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vhdl.rb @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class VHDL < RegexLexer + title "VHDL 2008" + desc "Very High Speed Integrated Circuit Hardware Description Language" + tag 'vhdl' + + filenames '*.vhd', '*.vhdl', '*.vho' + + mimetypes 'text/x-vhdl' + def self.keywords + @keywords ||= Set.new %w( + access after alias all architecture array assert assume assume_guarantee attribute + begin block body buffer bus case component configuration constant context cover + default disconnect downto else elsif end entity exit fairness file for force function + generate generic group guarded if impure in inertial inout is label library linkage + literal loop map new next null of on open others out package parameter port postponed + procedure process property protected pure range record register reject release report + return select sequence severity shared signal strong subtype then to transport type + unaffected units until use variable vmode vprop vunit wait when while with + ) + end + + def self.keywords_type + @keywords_type ||= Set.new %w( + bit bit_vector boolean boolean_vector character integer integer_vector natural positive + real real_vector severity_level signed std_logic std_logic_vector std_ulogic + std_ulogic_vector string unsigned time time_vector + ) + end + + def self.operator_words + @operator_words ||= Set.new %w( + abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor + ) + end + + id = /[a-zA-Z][a-zA-Z0-9_]*/ + + state :whitespace do + rule %r/\s+/, Text + rule %r/\n/, Text + # Find Comments (VHDL doesn't support multiline comments) + rule %r/--.*$/, Comment::Single + end + + state :statements do + + # Find Numbers + rule %r/-?\d+/i, Num::Integer + rule %r/-?\d+[.]\d+/i, Num::Float + + # Find Strings + rule %r/[box]?"[^"]*"/i, Str::Single + rule %r/'[^']?'/i, Str::Char + + # Find Attributes + rule %r/'#{id}/i, Name::Attribute + + # Punctuations + rule %r/[(),:;]/, Punctuation + + # Boolean and NULL + rule %r/(?:true|false|null)\b/i, Name::Builtin + + rule id do |m| + match = m[0].downcase #convert to lower case + if self.class.keywords.include? match + token Keyword + elsif self.class.keywords_type.include? match + token Keyword::Type + elsif self.class.operator_words.include? match + token Operator::Word + else + token Name + end + end + + rule( + %r(=>|[*][*]|:=|\/=|>=|<=|<>|\?\?|\?=|\?\/=|\?>|\?<|\?>=|\?<=|<<|>>|[#&'*+-.\/:<=>\?@^]), + Operator + ) + + end + + state :root do + + mixin :whitespace + mixin :statements + + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml.rb new file mode 100644 index 0000000..9ef1776 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml.rb @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class VimL < RegexLexer + title "VimL" + desc "VimL, the scripting language for the Vim editor (vim.org)" + tag 'viml' + aliases 'vim', 'vimscript', 'ex' + filenames '*.vim', '*.vba', '.vimrc', '.exrc', '.gvimrc', + '_vimrc', '_exrc', '_gvimrc' # _ names for windows + + mimetypes 'text/x-vim' + + def self.keywords + Kernel::load File.join(Lexers::BASE_DIR, 'viml/keywords.rb') + self.keywords + end + + state :root do + rule %r/^(\s*)(".*?)$/ do + groups Text, Comment + end + + rule %r/^\s*\\/, Str::Escape + + rule %r/[ \t]+/, Text + + # TODO: regexes can have other delimiters + rule %r(/(\\\\|\\/|[^\n/])*/), Str::Regex + rule %r("(\\\\|\\"|[^\n"])*"), Str::Double + rule %r('(\\\\|\\'|[^\n'])*'), Str::Single + + # if it's not a string, it's a comment. + rule %r/(?<=\s)"[^-:.%#=*].*?$/, Comment + + rule %r/-?\d+/, Num + rule %r/#[0-9a-f]{6}/i, Num::Hex + rule %r/^:/, Punctuation + rule %r/[():<>+=!\[\]{}\|,~.-]/, Punctuation + rule %r/\b(let|if|else|endif|elseif|fun|function|endfunction)\b/, + Keyword + + rule %r/\b(NONE|bold|italic|underline|dark|light)\b/, Name::Builtin + + rule %r/[absg]:\w+\b/, Name::Variable + rule %r/\b\w+\b/ do |m| + name = m[0] + keywords = self.class.keywords + + if keywords[:command].include? name + token Keyword + elsif keywords[:function].include? name + token Name::Builtin + elsif keywords[:option].include? name + token Name::Builtin + elsif keywords[:auto].include? name + token Name::Builtin + else + token Text + end + end + + # no errors in VimL! + rule %r/./m, Text + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml/keywords.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml/keywords.rb new file mode 100644 index 0000000..662aa21 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/viml/keywords.rb @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# DO NOT EDIT +# This file is automatically generated by `rake builtins:viml`. +# See tasks/builtins/viml.rake for more info. + +module Rouge + module Lexers + class VimL + def self.keywords + @keywords ||= {}.tap do |kw| + kw[:command] = Set.new ["a", "ar", "args", "argl", "arglocal", "ba", "ball", "bm", "bmodified", "breaka", "breakadd", "bun", "bunload", "cabc", "cabclear", "cal", "call", "cc", "cf", "cfile", "changes", "cla", "clast", "cnf", "cnfile", "comc", "comclear", "cp", "cprevious", "cstag", "debugg", "debuggreedy", "deletl", "dep", "diffpu", "diffput", "dl", "dr", "drop", "ec", "em", "emenu", "ene", "enew", "files", "fini", "finish", "folddoc", "folddoclosed", "gr", "grep", "helpc", "helpclose", "his", "history", "il", "ilist", "isp", "isplit", "keepa", "l", "list", "laf", "lafter", "lbel", "lbelow", "lcscope", "lfdo", "lgrepa", "lgrepadd", "lma", "lo", "loadview", "lop", "lopen", "lua", "m", "move", "mes", "mkvie", "mkview", "nbc", "nbclose", "noh", "nohlsearch", "ol", "oldfiles", "pa", "packadd", "po", "pop", "prof", "profile", "pta", "ptag", "ptr", "ptrewind", "py3f", "py3file", "pythonx", "quita", "quitall", "redraws", "redrawstatus", "rew", "rewind", "rubyf", "rubyfile", "sIg", "sa", "sargument", "sba", "sball", "sbr", "sbrewind", "scl", "scscope", "sfir", "sfirst", "sgl", "sic", "sin", "sm", "smap", "snoreme", "spelld", "spelldump", "spellw", "spellwrong", "srg", "st", "stop", "stj", "stjump", "sunmenu", "syn", "tN", "tNext", "tabd", "tabdo", "tabm", "tabmove", "tabr", "tabrewind", "tch", "tchdir", "tf", "tfirst", "tlmenu", "tm", "tmenu", "to", "topleft", "tu", "tunmenu", "undol", "undolist", "up", "update", "vi", "visual", "vmapc", "vmapclear", "wa", "wall", "winp", "winpos", "wundo", "xme", "xr", "xrestore", "ab", "arga", "argadd", "argu", "argument", "bad", "badd", "bn", "bnext", "breakd", "breakdel", "bw", "bwipeout", "cabo", "cabove", "cat", "catch", "ccl", "cclose", "cfdo", "chd", "chdir", "cle", "clearjumps", "cnor", "comp", "compiler", "cpf", "cpfile", "cun", "delc", "delcommand", "deletp", "di", "display", "diffs", "diffsplit", "dli", "dlist", "ds", "dsearch", "echoe", "echoerr", "en", "endif", "eval", "filet", "fir", "first", "foldo", "foldopen", "grepa", "grepadd", "helpf", "helpfind", "i", "imapc", "imapclear", "iuna", "iunabbrev", "keepalt", "la", "last", "lan", "language", "lbo", "lbottom", "ld", "ldo", "lfir", "lfirst", "lh", "lhelpgrep", "lmak", "lmake", "loadk", "lp", "lprevious", "luado", "ma", "mark", "messages", "mod", "mode", "nbs", "nbstart", "nor", "omapc", "omapclear", "packl", "packloadall", "popu", "popup", "profd", "profdel", "ptf", "ptfirst", "pts", "ptselect", "pyx", "r", "read", "redrawt", "redrawtabline", "ri", "right", "rundo", "sIl", "sal", "sall", "sbf", "sbfirst", "sc", "scp", "se", "set", "sg", "sgn", "sie", "sip", "sme", "snoremenu", "spelli", "spellinfo", "spr", "sprevious", "sri", "sta", "stag", "stopi", "stopinsert", "sus", "suspend", "sync", "ta", "tag", "tabe", "tabedit", "tabn", "tabnext", "tabs", "tcld", "tcldo", "th", "throw", "tln", "tma", "tmap", "tp", "tprevious", "tunma", "tunmap", "unh", "unhide", "v", "vie", "view", "vne", "vnew", "wh", "while", "wn", "wnext", "wv", "wviminfo", "xmenu", "xunme", "abc", "abclear", "argd", "argdelete", "as", "ascii", "bd", "bdelete", "bo", "botright", "breakl", "breaklist", "cN", "cNext", "cad", "caddbuffer", "cb", "cbuffer", "cd", "cfir", "cfirst", "che", "checkpath", "clo", "close", "co", "copy", "con", "continue", "cq", "cquit", "cuna", "cunabbrev", "delel", "delf", "delfunction", "dif", "diffupdate", "difft", "diffthis", "do", "dsp", "dsplit", "echom", "echomsg", "endf", "endfunction", "ex", "filetype", "fix", "fixdel", "for", "gui", "helpg", "helpgrep", "ia", "in", "j", "join", "keepj", "keepjumps", "lab", "labove", "lat", "lc", "lcd", "le", "left", "lg", "lgetfile", "lhi", "lhistory", "lmapc", "lmapclear", "loadkeymap", "lpf", "lpfile", "luafile", "mak", "make", "mk", "mkexrc", "mz", "mzscheme", "new", "nore", "on", "only", "pc", "pclose", "pp", "ppop", "promptf", "promptfind", "ptj", "ptjump", "pu", "put", "py", "python", "pyxdo", "rec", "recover", "reg", "registers", "rightb", "rightbelow", "rv", "rviminfo", "sIn", "san", "sandbox", "sbl", "sblast", "scI", "scr", "scriptnames", "setf", "setfiletype", "sgI", "sgp", "sig", "sir", "smenu", "so", "source", "spellr", "spellrare", "sr", "srl", "star", "startinsert", "sts", "stselect", "sv", "sview", "syncbind", "tab", "tabf", "tabfind", "tabnew", "tags", "tclf", "tclfile", "tj", "tjump", "tlnoremenu", "tmapc", "tmapclear", "tr", "trewind", "u", "undo", "unl", "ve", "version", "vim", "vimgrep", "vs", "vsplit", "win", "winsize", "wp", "wprevious", "x", "xit", "xnoreme", "xunmenu", "abo", "aboveleft", "argdo", "au", "bel", "belowright", "bp", "bprevious", "bro", "browse", "cNf", "cNfile", "cadde", "caddexpr", "cbe", "cbefore", "cdo", "cg", "cgetfile", "checkt", "checktime", "cmapc", "cmapclear", "col", "colder", "conf", "confirm", "cr", "crewind", "cw", "cwindow", "delep", "dell", "diffg", "diffget", "dig", "digraphs", "doau", "e", "edit", "echon", "endfo", "endfor", "exi", "exit", "filt", "filter", "fo", "fold", "fu", "function", "gvim", "helpt", "helptags", "iabc", "iabclear", "inor", "ju", "jumps", "keepp", "keeppatterns", "lad", "laddexpr", "later", "lch", "lchdir", "lefta", "leftabove", "lgetb", "lgetbuffer", "ll", "lne", "lnext", "loc", "lockmarks", "lr", "lrewind", "lv", "lvimgrep", "marks", "mks", "mksession", "mzf", "mzfile", "nmapc", "nmapclear", "nos", "noswapfile", "opt", "options", "pe", "perl", "pre", "preserve", "promptr", "promptrepl", "ptl", "ptlast", "pw", "pwd", "pydo", "pyxfile", "red", "redo", "res", "resize", "ru", "runtime", "sI", "sIp", "sav", "saveas", "sbm", "sbmodified", "sce", "scripte", "scriptencoding", "setg", "setglobal", "sgc", "sgr", "sign", "sl", "sleep", "smile", "sor", "sort", "spellrepall", "srI", "srn", "startg", "startgreplace", "sun", "sunhide", "sw", "swapname", "syntime", "tabN", "tabNext", "tabfir", "tabfirst", "tabo", "tabonly", "tc", "tcl", "te", "tearoff", "tl", "tlast", "tlu", "tn", "tnext", "try", "una", "unabbreviate", "unlo", "unlockvar", "verb", "verbose", "vimgrepa", "vimgrepadd", "wN", "wNext", "winc", "wincmd", "wq", "xa", "xall", "xnoremenu", "xwininfo", "addd", "arge", "argedit", "bN", "bNext", "bf", "bfirst", "br", "brewind", "bufdo", "c", "change", "caddf", "caddfile", "cbel", "cbelow", "ce", "center", "cgetb", "cgetbuffer", "chi", "chistory", "cn", "cnext", "colo", "colorscheme", "cons", "const", "cs", "d", "delete", "deletel", "delm", "delmarks", "diffo", "diffoff", "dir", "doaut", "ea", "el", "else", "endt", "endtry", "exu", "exusage", "fin", "find", "foldc", "foldclose", "g", "h", "help", "hi", "if", "intro", "k", "lN", "lNext", "laddb", "laddbuffer", "lb", "lbuffer", "lcl", "lclose", "lex", "lexpr", "lgete", "lgetexpr", "lla", "llast", "lnew", "lnewer", "lockv", "lockvar", "ls", "lvimgrepa", "lvimgrepadd", "mat", "match", "mksp", "mkspell", "n", "next", "noa", "nu", "number", "ownsyntax", "ped", "pedit", "prev", "previous", "ps", "psearch", "ptn", "ptnext", "py3", "pyf", "pyfile", "q", "quit", "redi", "redir", "ret", "retab", "rub", "ruby", "sIc", "sIr", "sbN", "sbNext", "sbn", "sbnext", "scg", "scriptv", "scriptversion", "setl", "setlocal", "sge", "sh", "shell", "sil", "silent", "sla", "slast", "sn", "snext", "sp", "split", "spellrrare", "src", "srp", "startr", "startreplace", "sunme", "sy", "t", "tabc", "tabclose", "tabl", "tablast", "tabp", "tabprevious", "tcd", "ter", "terminal", "tlm", "tlunmenu", "tno", "tnoremap", "ts", "tselect", "undoj", "undojoin", "uns", "unsilent", "vert", "vertical", "viu", "viusage", "w", "write", "windo", "wqa", "wqall", "xmapc", "xmapclear", "xprop", "y", "yank", "al", "all", "argg", "argglobal", "b", "buffer", "bl", "blast", "brea", "break", "buffers", "ca", "caf", "cafter", "cbo", "cbottom", "cex", "cexpr", "cgete", "cgetexpr", "cl", "clist", "cnew", "cnewer", "com", "cope", "copen", "cscope", "debug", "deletep", "delp", "diffp", "diffpatch", "dj", "djump", "dp", "earlier", "elsei", "elseif", "endw", "endwhile", "f", "file", "fina", "finally", "foldd", "folddoopen", "go", "goto", "ha", "hardcopy", "hid", "hide", "ij", "ijump", "is", "isearch", "kee", "keepmarks", "lNf", "lNfile", "laddf", "laddfile", "lbe", "lbefore", "lcs", "lf", "lfile", "lgr", "lgrep", "lli", "llist", "lnf", "lnfile", "lol", "lolder", "lt", "ltag", "lw", "lwindow", "menut", "menutranslate", "mkv", "mkvimrc", "nb", "nbkey", "noautocmd", "o", "open", "p", "print", "perld", "perldo", "pro", "ptN", "ptNext", "ptp", "ptprevious", "py3do", "python3", "qa", "qall", "redr", "redraw", "retu", "return", "rubyd", "rubydo", "sIe", "sN", "sNext", "sb", "sbuffer", "sbp", "sbprevious", "sci", "scs", "sf", "sfind", "sgi", "si", "sim", "simalt", "smagic", "sno", "snomagic", "spe", "spellgood", "spellu", "spellundo", "sre", "srewind", "def", "endd", "enddef", "disa", "disassemble", "vim9", "vim9script", "imp", "import", "exp", "export"] + kw[:option] = Set.new ["acd", "ambw", "arshape", "background", "ballooneval", "bex", "bl", "brk", "buftype", "cf", "cinkeys", "cmdwinheight", "com", "completeslash", "cpoptions", "cscoperelative", "csre", "cursorcolumn", "delcombine", "digraph", "eadirection", "emo", "equalprg", "expandtab", "fdls", "fex", "fileignorecase", "fml", "foldlevel", "formatexpr", "gcr", "go", "guifontset", "helpheight", "history", "hlsearch", "imaf", "ims", "includeexpr", "infercase", "iskeyword", "keywordprg", "laststatus", "lispwords", "lrm", "magic", "maxfuncdepth", "menuitems", "mm", "modifiable", "mousemodel", "mzq", "numberwidth", "opfunc", "patchexpr", "pfn", "pp", "printfont", "pumwidth", "pythonthreehome", "redrawtime", "ri", "rs", "sb", "scroll", "sect", "sft", "shellredir", "shiftwidth", "showmatch", "signcolumn", "smarttab", "sp", "spf", "srr", "startofline", "suffixes", "switchbuf", "ta", "tagfunc", "tbi", "term", "termwintype", "tgc", "titlelen", "toolbariconsize", "ttimeout", "ttymouse", "twt", "undofile", "varsofttabstop", "verbosefile", "viminfofile", "wak", "weirdinvert", "wig", "wildoptions", "winheight", "wm", "wrapscan", "ai", "anti", "autochdir", "backspace", "balloonevalterm", "bexpr", "bo", "browsedir", "casemap", "cfu", "cino", "cmp", "comments", "concealcursor", "cpp", "cscopetag", "cst", "cursorline", "dex", "dip", "eb", "emoji", "errorbells", "exrc", "fdm", "ff", "filetype", "fmr", "foldlevelstart", "formatlistpat", "gd", "gp", "guifontwide", "helplang", "hk", "ic", "imak", "imsearch", "incsearch", "insertmode", "isp", "km", "lazyredraw", "list", "ls", "makeef", "maxmapdepth", "mfd", "mmd", "modified", "mouses", "mzquantum", "nuw", "osfiletype", "patchmode", "ph", "preserveindent", "printheader", "pvh", "pyx", "regexpengine", "rightleft", "rtp", "sbo", "scrollbind", "sections", "sh", "shellslash", "shm", "showmode", "siso", "smc", "spc", "spl", "ss", "statusline", "suffixesadd", "sws", "tabline", "taglength", "tbidi", "termbidi", "terse", "tgst", "titleold", "top", "ttimeoutlen", "ttyscroll", "tx", "undolevels", "vartabstop", "vfile", "virtualedit", "warn", "wfh", "wildchar", "wim", "winminheight", "wmh", "write", "akm", "antialias", "autoindent", "backup", "balloonexpr", "bg", "bomb", "bs", "cb", "ch", "cinoptions", "cms", "commentstring", "conceallevel", "cpt", "cscopetagorder", "csto", "cursorlineopt", "dg", "dir", "ed", "enc", "errorfile", "fcl", "fdn", "ffs", "fillchars", "fo", "foldmarker", "formatoptions", "gdefault", "grepformat", "guiheadroom", "hf", "hkmap", "icon", "imc", "imsf", "inde", "is", "isprint", "kmp", "lbr", "listchars", "lsp", "makeencoding", "maxmem", "mh", "mmp", "more", "mouseshape", "mzschemedll", "odev", "pa", "path", "pheader", "previewheight", "printmbcharset", "pvp", "pyxversion", "relativenumber", "rightleftcmd", "ru", "sbr", "scrollfocus", "secure", "shcf", "shelltemp", "shortmess", "showtabline", "sj", "smd", "spell", "splitbelow", "ssl", "stl", "sw", "sxe", "tabpagemax", "tagrelative", "tbis", "termencoding", "textauto", "thesaurus", "titlestring", "tpm", "ttm", "ttytype", "uc", "undoreload", "vb", "vi", "visualbell", "wb", "wfw", "wildcharm", "winaltkeys", "winminwidth", "wmnu", "writeany", "al", "ar", "autoread", "backupcopy", "bdir", "bh", "breakat", "bsdir", "cc", "charconvert", "cinw", "co", "compatible", "confirm", "crb", "cscopeverbose", "csverb", "cwh", "dict", "directory", "edcompatible", "encoding", "errorformat", "fcs", "fdo", "fic", "fixendofline", "foldclose", "foldmethod", "formatprg", "gfm", "grepprg", "guioptions", "hh", "hkmapp", "iconstring", "imcmdline", "imst", "indentexpr", "isf", "joinspaces", "kp", "lcs", "lm", "luadll", "makeprg", "maxmempattern", "mis", "mmt", "mouse", "mouset", "mzschemegcdll", "oft", "packpath", "pdev", "pi", "previewpopup", "printmbfont", "pvw", "qe", "remap", "rl", "rubydll", "sc", "scrolljump", "sel", "shell", "shelltype", "shortname", "shq", "slm", "sn", "spellcapcheck", "splitright", "ssop", "stmp", "swapfile", "sxq", "tabstop", "tags", "tbs", "termguicolors", "textmode", "tildeop", "tl", "tr", "tty", "tw", "udf", "updatecount", "vbs", "viewdir", "vop", "wc", "wh", "wildignore", "wincolor", "winptydll", "wmw", "writebackup", "aleph", "arab", "autowrite", "backupdir", "bdlay", "bin", "breakindent", "bsk", "ccv", "ci", "cinwords", "cocu", "complete", "copyindent", "cryptmethod", "csl", "cuc", "debug", "dictionary", "display", "ef", "endofline", "esckeys", "fdc", "fdt", "fileencoding", "fixeol", "foldcolumn", "foldminlines", "fp", "gfn", "gtl", "guipty", "hi", "hkp", "ignorecase", "imd", "imstatusfunc", "indentkeys", "isfname", "js", "langmap", "linebreak", "lmap", "lw", "mat", "maxmemtot", "mkspellmem", "mod", "mousef", "mousetime", "nf", "ofu", "para", "penc", "pm", "previewwindow", "printoptions", "pw", "quoteescape", "renderoptions", "rlc", "ruf", "scb", "scrolloff", "selection", "shellcmdflag", "shellxescape", "showbreak", "si", "sm", "so", "spellfile", "spr", "st", "sts", "swapsync", "syn", "tag", "tagstack", "tc", "termwinkey", "textwidth", "timeout", "tm", "ts", "ttybuiltin", "twk", "udir", "updatetime", "vdir", "viewoptions", "vsts", "wcm", "whichwrap", "wildignorecase", "window", "winwidth", "wop", "writedelay", "allowrevins", "arabic", "autowriteall", "backupext", "belloff", "binary", "breakindentopt", "bt", "cd", "cin", "clipboard", "cole", "completefunc", "cot", "cscopepathcomp", "cspc", "cul", "deco", "diff", "dy", "efm", "eol", "et", "fde", "fen", "fileencodings", "fk", "foldenable", "foldnestmax", "fs", "gfs", "gtt", "guitablabel", "hid", "hl", "im", "imdisable", "imstyle", "indk", "isi", "key", "langmenu", "lines", "lnr", "lz", "matchpairs", "mco", "ml", "modeline", "mousefocus", "mp", "nrformats", "omnifunc", "paragraphs", "perldll", "pmbcs", "printdevice", "prompt", "pythondll", "rdt", "report", "rnu", "ruler", "scf", "scrollopt", "selectmode", "shellpipe", "shellxquote", "showcmd", "sidescroll", "smartcase", "softtabstop", "spelllang", "sps", "sta", "su", "swb", "synmaxcol", "tagbsearch", "tal", "tcldll", "termwinscroll", "tf", "timeoutlen", "to", "tsl", "ttyfast", "tws", "ul", "ur", "ve", "vif", "vts", "wcr", "wi", "wildmenu", "winfixheight", "wiv", "wrap", "ws", "altkeymap", "arabicshape", "aw", "backupskip", "beval", "bk", "bri", "bufhidden", "cdpath", "cindent", "cm", "colorcolumn", "completeopt", "cp", "cscopeprg", "csprg", "culopt", "def", "diffexpr", "ea", "ei", "ep", "eventignore", "fdi", "fenc", "fileformat", "fkmap", "foldexpr", "foldopen", "fsync", "gfw", "guicursor", "guitabtooltip", "hidden", "hlg", "imactivatefunc", "imi", "inc", "inex", "isident", "keymap", "langnoremap", "linespace", "loadplugins", "ma", "matchtime", "mef", "mle", "modelineexpr", "mousehide", "mps", "nu", "opendevice", "paste", "pex", "pmbfn", "printencoding", "pt", "pythonhome", "re", "restorescreen", "ro", "rulerformat", "scl", "scs", "sessionoptions", "shellquote", "shiftround", "showfulltag", "sidescrolloff", "smartindent", "sol", "spellsuggest", "sr", "stal", "sua", "swf", "syntax", "tagcase", "tb", "tenc", "termwinsize", "tfu", "title", "toolbar", "tsr", "ttym", "twsl", "undodir", "ut", "verbose", "viminfo", "wa", "wd", "wic", "wildmode", "winfixwidth", "wiw", "wrapmargin", "ww", "ambiwidth", "ari", "awa", "balloondelay", "bevalterm", "bkc", "briopt", "buflisted", "cedit", "cink", "cmdheight", "columns", "completepopup", "cpo", "cscopequickfix", "csqf", "cursorbind", "define", "diffopt", "ead", "ek", "equalalways", "ex", "fdl", "fencs", "fileformats", "flp", "foldignore", "foldtext", "ft", "ghr", "guifont", "helpfile", "highlight", "hls", "imactivatekey", "iminsert", "include", "inf", "isk", "keymodel", "langremap", "lisp", "lpl", "macatsui", "maxcombine", "menc", "mls", "modelines", "mousem", "msm", "number", "operatorfunc", "pastetoggle", "pexpr", "popt", "printexpr", "pumheight", "pythonthreedll", "readonly", "revins", "rop", "runtimepath", "scr", "noacd", "noallowrevins", "noantialias", "noarabic", "noarshape", "noautoread", "noaw", "noballooneval", "nobevalterm", "nobk", "nobreakindent", "nocf", "nocindent", "nocopyindent", "nocscoperelative", "nocsre", "nocuc", "nocursorcolumn", "nodelcombine", "nodigraph", "noed", "noemo", "noeol", "noesckeys", "noexpandtab", "nofic", "nofixeol", "nofoldenable", "nogd", "nohid", "nohkmap", "nohls", "noicon", "noimc", "noimdisable", "noinfercase", "nojoinspaces", "nolangremap", "nolinebreak", "nolnr", "nolrm", "nomacatsui", "noml", "nomod", "nomodelineexpr", "nomodified", "nomousef", "nomousehide", "nonumber", "noopendevice", "nopi", "nopreviewwindow", "nopvw", "norelativenumber", "norestorescreen", "nori", "norl", "noro", "noru", "nosb", "noscb", "noscrollbind", "noscs", "nosft", "noshelltemp", "noshortname", "noshowfulltag", "noshowmode", "nosm", "nosmartindent", "nosmd", "nosol", "nosplitbelow", "nospr", "nossl", "nostartofline", "noswapfile", "nota", "notagrelative", "notbi", "notbs", "noterse", "notextmode", "notgst", "notimeout", "noto", "notr", "nottybuiltin", "notx", "noundofile", "novisualbell", "nowarn", "noweirdinvert", "nowfw", "nowildignorecase", "nowinfixheight", "nowiv", "nowrap", "nowrite", "nowritebackup", "noai", "noaltkeymap", "noar", "noarabicshape", "noautochdir", "noautowrite", "noawa", "noballoonevalterm", "nobin", "nobl", "nobri", "noci", "nocompatible", "nocp", "nocscopetag", "nocst", "nocul", "nocursorline", "nodg", "noea", "noedcompatible", "noemoji", "noequalalways", "noet", "noexrc", "nofileignorecase", "nofk", "nofs", "nogdefault", "nohidden", "nohkmapp", "nohlsearch", "noignorecase", "noimcmdline", "noincsearch", "noinsertmode", "nojs", "nolazyredraw", "nolisp", "noloadplugins", "nolz", "nomagic", "nomle", "nomodeline", "nomodifiable", "nomore", "nomousefocus", "nonu", "noodev", "nopaste", "nopreserveindent", "noprompt", "noreadonly", "noremap", "norevins", "norightleft", "nornu", "nors", "noruler", "nosc", "noscf", "noscrollfocus", "nosecure", "noshellslash", "noshiftround", "noshowcmd", "noshowmatch", "nosi", "nosmartcase", "nosmarttab", "nosn", "nospell", "nosplitright", "nosr", "nosta", "nostmp", "noswf", "notagbsearch", "notagstack", "notbidi", "notermbidi", "notextauto", "notf", "notildeop", "notitle", "notop", "nottimeout", "nottyfast", "noudf", "novb", "nowa", "nowb", "nowfh", "nowic", "nowildmenu", "nowinfixwidth", "nowmnu", "nowrapscan", "nowriteany", "nows", "noakm", "noanti", "noarab", "noari", "noautoindent", "noautowriteall", "nobackup", "nobeval", "nobinary", "nobomb", "nobuflisted", "nocin", "noconfirm", "nocrb", "nocscopeverbose", "nocsverb", "nocursorbind", "nodeco", "nodiff", "noeb", "noek", "noendofline", "noerrorbells", "noex", "nofen", "nofixendofline", "nofkmap", "nofsync", "noguipty", "nohk", "nohkp", "noic", "noim", "noimd", "noinf", "nois", "nolangnoremap", "nolbr", "nolist", "nolpl", "noma", "nomh", "invacd", "invallowrevins", "invantialias", "invarabic", "invarshape", "invautoread", "invaw", "invballooneval", "invbevalterm", "invbk", "invbreakindent", "invcf", "invcindent", "invcopyindent", "invcscoperelative", "invcsre", "invcuc", "invcursorcolumn", "invdelcombine", "invdigraph", "inved", "invemo", "inveol", "invesckeys", "invexpandtab", "invfic", "invfixeol", "invfoldenable", "invgd", "invhid", "invhkmap", "invhls", "invicon", "invimc", "invimdisable", "invinfercase", "invjoinspaces", "invlangremap", "invlinebreak", "invlnr", "invlrm", "invmacatsui", "invml", "invmod", "invmodelineexpr", "invmodified", "invmousef", "invmousehide", "invnumber", "invopendevice", "invpi", "invpreviewwindow", "invpvw", "invrelativenumber", "invrestorescreen", "invri", "invrl", "invro", "invru", "invsb", "invscb", "invscrollbind", "invscs", "invsft", "invshelltemp", "invshortname", "invshowfulltag", "invshowmode", "invsm", "invsmartindent", "invsmd", "invsol", "invsplitbelow", "invspr", "invssl", "invstartofline", "invswapfile", "invta", "invtagrelative", "invtbi", "invtbs", "invterse", "invtextmode", "invtgst", "invtimeout", "invto", "invtr", "invttybuiltin", "invtx", "invundofile", "invvisualbell", "invwarn", "invweirdinvert", "invwfw", "invwildignorecase", "invwinfixheight", "invwiv", "invwrap", "invwrite", "invwritebackup", "invai", "invaltkeymap", "invar", "invarabicshape", "invautochdir", "invautowrite", "invawa", "invballoonevalterm", "invbin", "invbl", "invbri", "invci", "invcompatible", "invcp", "invcscopetag", "invcst", "invcul", "invcursorline", "invdg", "invea", "invedcompatible", "invemoji", "invequalalways", "invet", "invexrc", "invfileignorecase", "invfk", "invfs", "invgdefault", "invhidden", "invhkmapp", "invhlsearch", "invignorecase", "invimcmdline", "invincsearch", "invinsertmode", "invjs", "invlazyredraw", "invlisp", "invloadplugins", "invlz", "invmagic", "invmle", "invmodeline", "invmodifiable", "invmore", "invmousefocus", "invnu", "invodev", "invpaste", "invpreserveindent", "invprompt", "invreadonly", "invremap", "invrevins", "invrightleft", "invrnu", "invrs", "invruler", "invsc", "invscf", "invscrollfocus", "invsecure", "invshellslash", "invshiftround", "invshowcmd", "invshowmatch", "invsi", "invsmartcase", "invsmarttab", "invsn", "invspell", "invsplitright", "invsr", "invsta", "invstmp", "invswf", "invtagbsearch", "invtagstack", "invtbidi", "invtermbidi", "invtextauto", "invtf", "invtildeop", "invtitle", "invtop", "invttimeout", "invttyfast", "invudf", "invvb", "invwa", "invwb", "invwfh", "invwic", "invwildmenu", "invwinfixwidth", "invwmnu", "invwrapscan", "invwriteany", "invws", "invakm", "invanti", "invarab", "invari", "invautoindent", "invautowriteall", "invbackup", "invbeval", "invbinary", "invbomb", "invbuflisted", "invcin", "invconfirm", "invcrb", "invcscopeverbose", "invcsverb", "invcursorbind", "invdeco", "invdiff", "inveb", "invek", "invendofline", "inverrorbells", "invex", "invfen", "invfixendofline", "invfkmap", "invfsync", "invguipty", "invhk", "invhkp", "invic", "invim", "invimd", "invinf", "invis", "invlangnoremap", "invlbr", "invlist", "invlpl", "invma", "invmh", "t_8b", "t_AB", "t_al", "t_bc", "t_BE", "t_ce", "t_cl", "t_Co", "t_Cs", "t_CV", "t_db", "t_DL", "t_EI", "t_F2", "t_F4", "t_F6", "t_F8", "t_fs", "t_IE", "t_k1", "t_k2", "t_K3", "t_K4", "t_K5", "t_K6", "t_K7", "t_K8", "t_K9", "t_kb", "t_KB", "t_kd", "t_KD", "t_ke", "t_KE", "t_KF", "t_KG", "t_kh", "t_KH", "t_kI", "t_KI", "t_KJ", "t_KK", "t_kl", "t_KL", "t_kN", "t_kP", "t_kr", "t_ks", "t_ku", "t_le", "t_mb", "t_md", "t_me", "t_mr", "t_ms", "t_nd", "t_op", "t_PE", "t_PS", "t_RB", "t_RC", "t_RF", "t_Ri", "t_RI", "t_RS", "t_RT", "t_RV", "t_Sb", "t_SC", "t_se", "t_Sf", "t_SH", "t_Si", "t_SI", "t_so", "t_sr", "t_SR", "t_ST", "t_te", "t_Te", "t_TE", "t_ti", "t_TI", "t_ts", "t_Ts", "t_u7", "t_ue", "t_us", "t_ut", "t_vb", "t_ve", "t_vi", "t_vs", "t_VS", "t_WP", "t_WS", "t_xn", "t_xs", "t_ZH", "t_ZR", "t_8f", "t_AF", "t_AL", "t_BD", "t_cd", "t_Ce", "t_cm", "t_cs", "t_CS", "t_da", "t_dl", "t_EC", "t_F1", "t_F3", "t_F5", "t_F7", "t_F9", "t_GP", "t_IS", "t_K1", "t_k3", "t_k4", "t_k5", "t_k6", "t_k7", "t_k8", "t_k9", "t_KA", "t_kB", "t_KC", "t_kD"] + kw[:auto] = Set.new ["BufAdd", "BufDelete", "BufFilePost", "BufHidden", "BufNew", "BufRead", "BufReadPost", "BufUnload", "BufWinEnter", "BufWinLeave", "BufWipeout", "BufWrite", "BufWriteCmd", "BufWritePost", "BufWritePre", "CmdlineChanged", "CmdlineEnter", "CmdlineLeave", "CmdUndefined", "CmdwinEnter", "CmdwinLeave", "ColorScheme", "ColorSchemePre", "CompleteChanged", "CompleteDone", "CompleteDonePre", "CursorHold", "CursorHoldI", "CursorMoved", "CursorMovedI", "DiffUpdated", "DirChanged", "EncodingChanged", "ExitPre", "FileAppendCmd", "FileAppendPost", "FileAppendPre", "FileChangedRO", "FileChangedShell", "FileChangedShellPost", "FileEncoding", "FileReadCmd", "FileReadPost", "FileReadPre", "FileType", "FileWriteCmd", "FileWritePost", "FileWritePre", "FilterReadPost", "FilterReadPre", "FilterWritePost", "FilterWritePre", "FocusGained", "FocusLost", "FuncUndefined", "GUIEnter", "GUIFailed", "InsertChange", "InsertCharPre", "InsertEnter", "InsertLeave", "MenuPopup", "OptionSet", "QuickFixCmdPost", "QuickFixCmdPre", "QuitPre", "RemoteReply", "SafeState", "SafeStateAgain", "SessionLoadPost", "ShellCmdPost", "ShellFilterPost", "SourceCmd", "SourcePost", "SourcePre", "SpellFileMissing", "StdinReadPost", "StdinReadPre", "SwapExists", "Syntax", "TabClosed", "TabEnter", "TabLeave", "TabNew", "TermChanged", "TerminalOpen", "TerminalWinOpen", "TermResponse", "TextChanged", "TextChangedI", "TextChangedP", "TextYankPost", "User", "VimEnter", "VimLeave", "VimLeavePre", "VimResized", "WinEnter", "WinLeave", "WinNew", "BufCreate", "BufEnter", "BufFilePre", "BufLeave", "BufNewFile", "BufReadCmd", "BufReadPre"] + kw[:function] = Set.new ["abs", "appendbufline", "asin", "assert_fails", "assert_notmatch", "balloon_gettext", "bufadd", "bufname", "byteidx", "char2nr", "ch_evalexpr", "ch_log", "ch_readraw", "cindent", "complete_check", "cosh", "deepcopy", "diff_hlID", "eval", "exists", "feedkeys", "findfile", "fnamemodify", "foldtextresult", "get", "getchar", "getcmdtype", "getenv", "getftype", "getmatches", "getreg", "gettagstack", "getwinvar", "has_key", "histget", "iconv", "inputlist", "interrupt", "isnan", "job_start", "js_encode", "libcall", "list2str", "log", "mapcheck", "matchdelete", "max", "nextnonblank", "popup_atcursor", "popup_dialog", "popup_getoptions", "popup_notification", "prevnonblank", "prop_add", "prop_type_add", "pum_getpos", "rand", "reg_recording", "remote_foreground", "remove", "round", "screencol", "searchdecl", "serverlist", "setenv", "setpos", "settagstack", "sign_define", "sign_placelist", "sin", "sound_playevent", "split", "str2list", "strftime", "strpart", "submatch", "synID", "systemlist", "taglist", "term_dumpload", "term_getcursor", "term_getstatus", "term_sendkeys", "term_setsize", "test_autochdir", "test_getvalue", "test_null_dict", "test_null_string", "test_scrollbar", "test_unknown", "timer_start", "toupper", "type", "values", "winbufnr", "win_findbuf", "winheight", "winline", "winsaveview", "winwidth", "acos", "argc", "assert_beeps", "assert_false", "assert_report", "balloon_show", "bufexists", "bufnr", "byteidxcomp", "ch_canread", "ch_evalraw", "ch_logfile", "ch_sendexpr", "clearmatches", "complete_info", "count", "delete", "echoraw", "eventhandler", "exp", "filereadable", "float2nr", "foldclosed", "foreground", "getbufinfo", "getcharmod", "getcmdwintype", "getfontname", "getimstatus", "getmousepos", "getregtype", "getwininfo", "glob", "haslocaldir", "histnr", "indent", "inputrestore", "invert", "items", "job_status", "json_decode", "libcallnr", "listener_add", "log10", "match", "matchend", "min", "nr2char", "popup_beval", "popup_filter_menu", "popup_getpos", "popup_setoptions", "printf", "prop_clear", "prop_type_change", "pumvisible", "range", "reltime", "remote_peek", "rename", "rubyeval", "screenpos", "searchpair", "setbufline", "setfperm", "setqflist", "setwinvar", "sign_getdefined", "sign_undefine", "sinh", "sound_playfile", "sqrt", "str2nr", "strgetchar", "strptime", "substitute", "synIDattr", "tabpagebuflist", "tan", "term_dumpwrite", "term_getjob", "term_gettitle", "term_setansicolors", "term_start", "test_feedinput", "test_ignore_error", "test_null_job", "test_option_not_set", "test_setmouse", "test_void", "timer_stop", "tr", "undofile", "virtcol", "wincol", "win_getid", "win_id2tabwin", "winnr", "win_screenpos", "wordcount", "add", "argidx", "assert_equal", "assert_inrange", "assert_true", "balloon_split", "buflisted", "bufwinid", "call", "ch_close", "ch_getbufnr", "ch_open", "ch_sendraw", "col", "confirm", "cscope_connection", "deletebufline", "empty", "executable", "expand", "filewritable", "floor", "foldclosedend", "funcref", "getbufline", "getcharsearch", "getcompletion", "getfperm", "getjumplist", "getpid", "gettabinfo", "getwinpos", "glob2regpat", "hasmapto", "hlexists", "index", "inputsave", "isdirectory", "job_getchannel", "job_stop", "json_encode", "line", "listener_flush", "luaeval", "matchadd", "matchlist", "mkdir", "or", "popup_clear", "popup_filter_yesno", "popup_hide", "popup_settext", "prompt_setcallback", "prop_find", "prop_type_delete", "py3eval", "readdir", "reltimefloat", "remote_read", "repeat", "screenattr", "screenrow", "searchpairpos", "setbufvar", "setline", "setreg", "sha256", "sign_getplaced", "sign_unplace", "sort", "sound_stop", "srand", "strcharpart", "stridx", "strridx", "swapinfo", "synIDtrans", "tabpagenr", "tanh", "term_getaltscreen", "term_getline", "term_gettty", "term_setapi", "term_wait", "test_garbagecollect_now", "test_null_blob", "test_null_list", "test_override", "test_settime", "timer_info", "timer_stopall", "trim", "undotree", "visualmode", "windowsversion", "win_gettype", "win_id2win", "winrestcmd", "win_splitmove", "writefile", "and", "arglistid", "assert_equalfile", "assert_match", "atan", "browse", "bufload", "bufwinnr", "ceil", "ch_close_in", "ch_getjob", "ch_read", "ch_setoptions", "complete", "copy", "cursor", "did_filetype", "environ", "execute", "expandcmd", "filter", "fmod", "foldlevel", "function", "getbufvar", "getcmdline", "getcurpos", "getfsize", "getline", "getpos", "gettabvar", "getwinposx", "globpath", "histadd", "hlID", "input", "inputsecret", "isinf", "job_info", "join", "keys", "line2byte", "listener_remove", "map", "matchaddpos", "matchstr", "mode", "pathshorten", "popup_close", "popup_findinfo", "popup_menu", "popup_show", "prompt_setinterrupt", "prop_list", "prop_type_get", "pyeval", "readfile", "reltimestr", "remote_send", "resolve", "screenchar", "screenstring", "searchpos", "setcharsearch", "setloclist", "settabvar", "shellescape", "sign_jump", "sign_unplacelist", "sound_clear", "spellbadword", "state", "strchars", "string", "strtrans", "swapname", "synstack", "tabpagewinnr", "tempname", "term_getansicolors", "term_getscrolled", "term_list", "term_setkill", "test_alloc_fail", "test_garbagecollect_soon", "test_null_channel", "test_null_partial", "test_refcount", "test_srand_seed", "timer_pause", "tolower", "trunc", "uniq", "wildmenumode", "win_execute", "win_gotoid", "winlayout", "winrestview", "win_type", "xor", "append", "argv", "assert_exception", "assert_notequal", "atan2", "browsedir", "bufloaded", "byte2line", "changenr", "chdir", "ch_info", "ch_readblob", "ch_status", "complete_add", "cos", "debugbreak", "diff_filler", "escape", "exepath", "extend", "finddir", "fnameescape", "foldtext", "garbagecollect", "getchangelist", "getcmdpos", "getcwd", "getftime", "getloclist", "getqflist", "gettabwinvar", "getwinposy", "has", "histdel", "hostname", "inputdialog", "insert", "islocked", "job_setoptions", "js_decode", "len", "lispindent", "localtime", "maparg", "matcharg", "matchstrpos", "mzeval", "perleval", "popup_create", "popup_findpreview", "popup_move", "pow", "prompt_setprompt", "prop_remove", "prop_type_list", "pyxeval", "reg_executing", "remote_expr", "remote_startserver", "reverse", "screenchars", "search", "server2client", "setcmdpos", "setmatches", "settabwinvar", "shiftwidth", "sign_place", "simplify", "soundfold", "spellsuggest", "str2float", "strdisplaywidth", "strlen", "strwidth", "synconcealed", "system", "tagfiles", "term_dumpdiff", "term_getattr", "term_getsize", "term_scrape", "term_setrestore"] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vue.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vue.rb new file mode 100644 index 0000000..5b64f3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/vue.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'html.rb' + + class Vue < HTML + desc 'Vue.js single-file components' + tag 'vue' + aliases 'vuejs' + filenames '*.vue' + + mimetypes 'text/x-vue', 'application/x-vue' + + def initialize(*) + super + @js = Javascript.new(options) + end + + def lookup_lang(lang) + lang.downcase! + lang = lang.gsub(/["']*/, '') + case lang + when 'html' then HTML + when 'css' then CSS + when 'javascript' then Javascript + when 'sass' then Sass + when 'scss' then Scss + when 'coffee' then Coffeescript + # TODO: add more when the lexers are done + else + PlainText + end + end + + start { @js.reset! } + + prepend :root do + rule %r/(<)(\s*)(template)/ do + groups Name::Tag, Text, Keyword + @lang = HTML + push :template + push :lang_tag + end + + rule %r/(<)(\s*)(style)/ do + groups Name::Tag, Text, Keyword + @lang = CSS + push :style + push :lang_tag + end + + rule %r/(<)(\s*)(script)/ do + groups Name::Tag, Text, Keyword + @lang = Javascript + push :script + push :lang_tag + end + end + + prepend :tag do + rule %r/[a-zA-Z0-9_:#\[\]()*.-]+\s*=\s*/m, Name::Attribute, :attr + end + + state :style do + rule %r/(<\s*\/\s*)(style)(\s*>)/ do + groups Name::Tag, Keyword, Name::Tag + pop! + end + + mixin :style_content + mixin :embed + end + + state :script do + rule %r/(<\s*\/\s*)(script)(\s*>)/ do + groups Name::Tag, Keyword, Name::Tag + pop! + end + + mixin :script_content + mixin :embed + end + + state :lang_tag do + rule %r/(lang\s*=)(\s*)("(?:\\.|[^\\])*?"|'(\\.|[^\\])*?'|[^\s>]+)/ do |m| + groups Name::Attribute, Text, Str + @lang = lookup_lang(m[3]) + end + + mixin :tag + end + + state :template do + rule %r((<\s*/\s*)(template)(\s*>)) do + groups Name::Tag, Keyword, Name::Tag + pop! + end + + rule %r/{{/ do + token Str::Interpol + push :template_interpol + @js.reset! + end + + mixin :embed + end + + state :template_interpol do + rule %r/}}/, Str::Interpol, :pop! + rule %r/}/, Error + mixin :template_interpol_inner + end + + state :template_interpol_inner do + rule(/{/) { delegate @js; push } + rule(/}/) { delegate @js; pop! } + rule(/[^{}]+/) { delegate @js } + end + + state :embed do + rule(/[^{<]+/) { delegate @lang } + rule(/[<{][^<{]*/) { delegate @lang } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/wollok.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/wollok.rb new file mode 100644 index 0000000..5f46176 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/wollok.rb @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Wollok < RegexLexer + title 'Wollok' + desc 'Wollok lang' + tag 'wollok' + filenames '*.wlk', '*.wtest', '*.wpgm' + + keywords = %w(new super return if else var const override constructor) + + entity_name = /[a-zA-Z][a-zA-Z0-9]*/ + variable_naming = /_?#{entity_name}/ + + state :whitespaces_and_comments do + rule %r/\s+/m, Text::Whitespace + rule %r(//.*$), Comment::Single + rule %r(/\*(.|\s)*?\*/)m, Comment::Multiline + end + + state :root do + mixin :whitespaces_and_comments + rule %r/(import)(.+$)/ do + groups Keyword::Reserved, Text + end + rule %r/(class|object|mixin)/, Keyword::Reserved, :foo + rule %r/test|program/, Keyword::Reserved #, :chunk_naming + rule %r/(package)(\s+)(#{entity_name})/ do + groups Keyword::Reserved, Text::Whitespace, Name::Class + end + rule %r/{|}/, Text + mixin :keywords + mixin :symbols + mixin :objects + end + + state :foo do + mixin :whitespaces_and_comments + rule %r/inherits|mixed|with|and/, Keyword::Reserved + rule %r/#{entity_name}(?=\s*{)/ do |m| + token Name::Class + entities << m[0] + pop! + end + rule %r/#{entity_name}/ do |m| + token Name::Class + entities << m[0] + end + end + + state :keywords do + def any(expressions) + /#{expressions.map { |keyword| "#{keyword}\\b" }.join('|')}/ + end + + rule %r/self\b/, Name::Builtin::Pseudo + rule any(keywords), Keyword::Reserved + rule %r/(method)(\s+)(#{variable_naming})/ do + groups Keyword::Reserved, Text::Whitespace, Text + end + end + + state :objects do + rule variable_naming do |m| + variable = m[0] + if entities.include?(variable) || ('A'..'Z').cover?(variable[0]) + token Name::Class + else + token Keyword::Variable + end + end + rule %r/\.#{entity_name}/, Text + mixin :literals + end + + state :literals do + mixin :whitespaces_and_comments + rule %r/[0-9]+\.?[0-9]*/, Literal::Number + rule %r/"[^"]*"/m, Literal::String + rule %r/\[|\#{/, Punctuation, :lists + end + + state :lists do + rule %r/,/, Punctuation + rule %r/]|}/, Punctuation, :pop! + mixin :objects + end + + state :symbols do + rule %r/\+\+|--|\+=|-=|\*\*|!/, Operator + rule %r/\+|-|\*|\/|%/, Operator + rule %r/<=|=>|===|==|<|>/, Operator + rule %r/and\b|or\b|not\b/, Operator + rule %r/\(|\)|=/, Text + rule %r/,/, Punctuation + end + + private + + def entities + @entities ||= [] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xml.rb new file mode 100644 index 0000000..e313e02 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xml.rb @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class XML < RegexLexer + title "XML" + desc %q(XML) + tag 'xml' + filenames '*.xml', '*.xsl', '*.rss', '*.xslt', '*.xsd', '*.wsdl', '*.svg', + '*.plist' + mimetypes 'text/xml', 'application/xml', 'image/svg+xml', + 'application/rss+xml', 'application/atom+xml' + + # Documentation: https://www.w3.org/TR/xml11/#charsets and https://www.w3.org/TR/xml11/#sec-suggested-names + + def self.detect?(text) + return false if text.doctype?(/html/) + return true if text =~ /\A<\?xml\b/ + return true if text.doctype? + end + + state :root do + rule %r/[^<&]+/, Text + rule %r/&\S*?;/, Name::Entity + rule %r//, Comment::Preproc + rule %r//, Comment, :pop! + rule %r/-/, Comment + end + + state :tag do + rule %r/\s+/m, Text + rule %r/[\p{L}:_][\p{Word}\p{Cf}:.·-]*\s*=/m, Name::Attribute, :attr + rule %r(/?\s*>), Name::Tag, :pop! + end + + state :attr do + rule %r/\s+/m, Text + rule %r/".*?"|'.*?'|[^\s>]+/m, Str, :pop! + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xojo.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xojo.rb new file mode 100644 index 0000000..6c7d013 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xojo.rb @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Xojo < RegexLexer + title "Xojo" + desc "Xojo" + tag 'xojo' + aliases 'realbasic' + filenames '*.xojo_code', '*.xojo_window', '*.xojo_toolbar', '*.xojo_menu', '*.xojo_image', '*.rbbas', '*.rbfrm', '*.rbmnu', '*.rbres', '*.rbtbar' + + keywords = %w( + addhandler aggregates array asc assigns attributes begin break + byref byval call case catch class const continue color ctype declare + delegate dim do downto each else elseif end enum event exception + exit extends false finally for function global goto if + implements inherits interface lib loop mod module + new next nil object of optional paramarray + private property protected public raise raiseevent rect redim + removehandler return select shared soft static step sub super + then to true try until using var wend while + ) + + keywords_type = %w( + boolean byte cfstringref cgfloat cstring currency date datetime double int8 int16 + int32 int64 integer ostype pair pstring ptr short single + string structure variant uinteger uint8 uint16 uint32 uint64 + ushort windowptr wstring + ) + + operator_words = %w( + addressof weakaddressof and as in is isa mod not or xor + ) + + state :root do + rule %r/\s+/, Text::Whitespace + + rule %r/rem\b.*?$/i, Comment::Single + rule %r((?://|').*$), Comment::Single + rule %r/\#tag Note.*?\#tag EndNote/mi, Comment::Preproc + rule %r/\s*[#].*$/x, Comment::Preproc + + rule %r/".*?"/, Literal::String::Double + rule %r/[(){}!#,:]/, Punctuation + + rule %r/\b(?:#{keywords.join('|')})\b/i, Keyword + rule %r/\b(?:#{keywords_type.join('|')})\b/i, Keyword::Declaration + + rule %r/\b(?:#{operator_words.join('|')})\b/i, Operator + rule %r/[+-]?(\d+\.\d*|\d*\.\d+)/i, Literal::Number::Float + rule %r/[+-]?\d+/, Literal::Number::Integer + rule %r/&[CH][0-9a-f]+/i, Literal::Number::Hex + rule %r/&O[0-7]+/i, Literal::Number::Oct + + rule %r/\b[\w\.]+\b/i, Text + rule(%r(<=|>=|<>|[=><\+\-\*\/\\]), Operator) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xpath.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xpath.rb new file mode 100644 index 0000000..fb1d4a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xpath.rb @@ -0,0 +1,332 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class XPath < RegexLexer + title 'XPath' + desc 'XML Path Language (XPath) 3.1' + tag 'xpath' + filenames '*.xpath' + + # Terminal literals: + # https://www.w3.org/TR/xpath-31/#terminal-symbols + def self.digits + @digits ||= %r/[0-9]+/ + end + + def self.decimalLiteral + @decimalLiteral ||= %r/\.#{digits}|#{digits}\.[0-9]*/ + end + + def self.doubleLiteral + @doubleLiteral ||= %r/(\.#{digits})|#{digits}(\.[0-9]*)?[eE][+-]?#{digits}/ + end + + def self.stringLiteral + @stringLiteral ||= %r/("(("")|[^"])*")|('(('')|[^'])*')/ + end + + def self.ncName + @ncName ||= %r/[a-z_][a-z_\-.0-9]*/i + end + + def self.qName + @qName ||= %r/(?:#{ncName})(?::#{ncName})?/ + end + + def self.uriQName + @uriQName ||= %r/Q\{[^{}]*\}#{ncName}/ + end + + def self.eqName + @eqName ||= %r/(?:#{uriQName}|#{qName})/ + end + + def self.commentStart + @commentStart ||= %r/\(:/ + end + + def self.openParen + @openParen ||= %r/\((?!:)/ + end + + # Terminal symbols: + # https://www.w3.org/TR/xpath-30/#id-terminal-delimitation + def self.kindTest + @kindTest ||= Regexp.union %w( + element attribute schema-element schema-attribute + comment text node document-node namespace-node + ) + end + + def self.kindTestForPI + @kindTestForPI ||= Regexp.union %w(processing-instruction) + end + + def self.axes + @axes ||= Regexp.union %w( + child descendant attribute self descendant-or-self + following-sibling following namespace + parent ancestor preceding-sibling preceding ancestor-or-self + ) + end + + def self.operators + @operators ||= Regexp.union %w(, => = := : >= >> > <= << < - * != + // / || |) + end + + def self.keywords + @keywords ||= Regexp.union %w(let for some every if then else return in satisfies) + end + + def self.word_operators + @word_operators ||= Regexp.union %w( + and or eq ge gt le lt ne is + div mod idiv + intersect except union + to + ) + end + + def self.constructorTypes + @constructorTypes ||= Regexp.union %w(function array map empty-sequence) + end + + # Mixin states: + + state :commentsAndWhitespace do + rule XPath.commentStart, Comment, :comment + rule %r/\s+/m, Text::Whitespace + end + + # Lexical states: + # https://www.w3.org/TR/xquery-xpath-parsing/#XPath-lexical-states + # https://lists.w3.org/Archives/Public/public-qt-comments/2004Aug/0127.html + # https://www.w3.org/TR/xpath-30/#id-revision-log + # https://www.w3.org/TR/xpath-31/#id-revision-log + + state :root do + mixin :commentsAndWhitespace + + # Literals + rule XPath.doubleLiteral, Num::Float + rule XPath.decimalLiteral, Num::Float + rule XPath.digits, Num + rule XPath.stringLiteral, Literal::String + + # Variables + rule %r/\$/, Name::Variable, :varname + + # Operators + rule XPath.operators, Operator + rule %r/#{XPath.word_operators}\b/, Operator::Word + rule %r/#{XPath.keywords}\b/, Keyword + rule %r/[?,{}()\[\]]/, Punctuation + + # Functions + rule %r/(function)(\s*)(#{XPath.openParen})/ do # function declaration + groups Keyword, Text::Whitespace, Punctuation + end + rule %r/(map|array|empty-sequence)/, Keyword # constructors + rule %r/(#{XPath.kindTest})(\s*)(#{XPath.openParen})/ do # kindtest + groups Keyword, Text::Whitespace, Punctuation + push :kindtest + end + rule %r/(#{XPath.kindTestForPI})(\s*)(#{XPath.openParen})/ do # processing instruction kindtest + groups Keyword, Text::Whitespace, Punctuation + push :kindtestforpi + end + rule %r/(#{XPath.eqName})(\s*)(#{XPath.openParen})/ do # function call + groups Name::Function, Text::Whitespace, Punctuation + end + rule %r/(#{XPath.eqName})(\s*)(#)(\s*)(\d+)/ do # namedFunctionRef + groups Name::Function, Text::Whitespace, Name::Function, Text::Whitespace, Name::Function + end + + # Type commands + rule %r/(cast|castable)(\s+)(as)/ do + groups Keyword, Text::Whitespace, Keyword + push :singletype + end + rule %r/(treat)(\s+)(as)/ do + groups Keyword, Text::Whitespace, Keyword + push :itemtype + end + rule %r/(instance)(\s+)(of)/ do + groups Keyword, Text::Whitespace, Keyword + push :itemtype + end + rule %r/(as)\b/ do + token Keyword + push :itemtype + end + + # Paths + rule %r/(#{XPath.ncName})(\s*)(:)(\s*)(\*)/ do + groups Name::Tag, Text::Whitespace, Punctuation, Text::Whitespace, Operator + end + rule %r/(\*)(\s*)(:)(\s*)(#{XPath.ncName})/ do + groups Operator, Text::Whitespace, Punctuation, Text::Whitespace, Name::Tag + end + rule %r/(#{XPath.axes})(\s*)(::)/ do + groups Keyword, Text::Whitespace, Operator + end + rule %r/\.\.|\.|\*/, Operator + rule %r/@/, Name::Attribute, :attrname + rule XPath.eqName, Name::Tag + end + + state :singletype do + mixin :commentsAndWhitespace + + # Type name + rule XPath.eqName do + token Keyword::Type + pop! + end + end + + state :itemtype do + mixin :commentsAndWhitespace + + # Type tests + rule %r/(#{XPath.kindTest})(\s*)(#{XPath.openParen})/ do + groups Keyword::Type, Text::Whitespace, Punctuation + # go to kindtest then occurrenceindicator + goto :occurrenceindicator + push :kindtest + end + rule %r/(#{XPath.kindTestForPI})(\s*)(#{XPath.openParen})/ do + groups Keyword::Type, Text::Whitespace, Punctuation + # go to kindtestforpi then occurrenceindicator + goto :occurrenceindicator + push :kindtestforpi + end + rule %r/(item)(\s*)(#{XPath.openParen})(\s*)(\))/ do + groups Keyword::Type, Text::Whitespace, Punctuation, Text::Whitespace, Punctuation + goto :occurrenceindicator + end + rule %r/(#{XPath.constructorTypes})(\s*)(#{XPath.openParen})/ do + groups Keyword::Type, Text::Whitespace, Punctuation + end + + # Type commands + rule %r/(cast|castable)(\s+)(as)/ do + groups Keyword, Text::Whitespace, Keyword + goto :singletype + end + rule %r/(treat)(\s+)(as)/ do + groups Keyword, Text::Whitespace, Keyword + goto :itemtype + end + rule %r/(instance)(\s+)(of)/ do + groups Keyword, Text::Whitespace, Keyword + goto :itemtype + end + rule %r/(as)\b/, Keyword + + # Operators + rule XPath.operators do + token Operator + pop! + end + rule %r/#{XPath.word_operators}\b/ do + token Operator::Word + pop! + end + rule %r/#{XPath.keywords}\b/ do + token Keyword + pop! + end + rule %r/[\[),]/ do + token Punctuation + pop! + end + + # Other types (e.g. xs:double) + rule XPath.eqName do + token Keyword::Type + goto :occurrenceindicator + end + end + + # For pseudo-parameters for the KindTest productions + state :kindtest do + mixin :commentsAndWhitespace + + # Pseudo-parameters: + rule %r/[?*]/, Operator + rule %r/,/, Punctuation + rule %r/(element|schema-element)(\s*)(#{XPath.openParen})/ do + groups Keyword::Type, Text::Whitespace, Punctuation + push :kindtest + end + rule XPath.eqName, Name::Tag + + # End of pseudo-parameters + rule %r/\)/, Punctuation, :pop! + end + + # Similar to :kindtest, but recognizes NCNames instead of EQNames + state :kindtestforpi do + mixin :commentsAndWhitespace + + # Pseudo-parameters + rule XPath.ncName, Name + rule XPath.stringLiteral, Literal::String + + # End of pseudo-parameters + rule %r/\)/, Punctuation, :pop! + end + + state :occurrenceindicator do + mixin :commentsAndWhitespace + + # Occurrence indicator + rule %r/[?*+]/ do + token Operator + pop! + end + + # Otherwise, lex it in root state: + rule %r/(?![?*+])/ do + pop! + end + end + + state :varname do + mixin :commentsAndWhitespace + + # Function call + rule %r/(#{XPath.eqName})(\s*)(#{XPath.openParen})/ do + groups Name::Variable, Text::Whitespace, Punctuation + pop! + end + + # Variable name + rule XPath.eqName, Name::Variable, :pop! + end + + state :attrname do + mixin :commentsAndWhitespace + + # Attribute name + rule XPath.eqName, Name::Attribute, :pop! + rule %r/\*/, Operator, :pop! + end + + state :comment do + # Comment end + rule %r/:\)/, Comment, :pop! + + # Nested comment + rule XPath.commentStart, Comment, :comment + + # Comment contents + rule %r/[^:(]+/m, Comment + rule %r/[:(]/, Comment + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xquery.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xquery.rb new file mode 100644 index 0000000..eb0d7a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/xquery.rb @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + load_lexer 'xpath.rb' + class XQuery < XPath + title 'XQuery' + desc 'XQuery 3.1: An XML Query Language' + tag 'xquery' + filenames '*.xquery', '*.xq', '*.xqm' + mimetypes 'application/xquery' + + def self.keywords + @keywords ||= Regexp.union super, Regexp.union(%w( + xquery encoding version declare module + namespace copy-namespaces boundary-space construction + default collation base-uri preserve strip + ordering ordered unordered order empty greatest least + preserve no-preserve inherit no-inherit + decimal-format decimal-separator grouping-separator + infinity minus-sign NaN percent per-mille + zero-digit digit pattern-separator exponent-separator + import schema at element option + function external context item + typeswitch switch case + try catch + validate lax strict type + document element attribute text comment processing-instruction + for let where order group by return + allowing tumbling stable sliding window + start end only when previous next count collation + ascending descending + )) + end + + # Mixin states: + + state :tags do + rule %r/<#{XPath.qName}/, Name::Tag, :start_tag + rule %r//, Comment, :pop! + rule %r/-/, Comment + end + + state :start_tag do + rule %r/\s+/m, Text::Whitespace + rule %r/([\w.:-]+\s*=)(")/m do + groups Name::Attribute, Str + push :quot_attr + end + rule %r/([\w.:-]+\s*=)(')/m do + groups Name::Attribute, Str + push :apos_attr + end + rule %r/>/, Name::Tag, :tag_content + rule %r(/>), Name::Tag, :pop! + end + + state :quot_attr do + rule %r/"/, Str, :pop! + rule %r/\{\{/, Str + rule %r/\{/, Punctuation, :root + rule %r/[^"{>]+/m, Str + end + + state :apos_attr do + rule %r/'/, Str, :pop! + rule %r/\{\{/, Str + rule %r/\{/, Punctuation, :root + rule %r/[^'{>]+/m, Str + end + + state :tag_content do + rule %r/\s+/m, Text::Whitespace + mixin :tags + + rule %r/(\{\{|\}\})/, Text + rule %r/\{/, Punctuation, :root + + rule %r/[^{}<&]/, Text + + rule %r() do + token Name::Tag + pop! 2 # pop self and tag_start + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yaml.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yaml.rb new file mode 100644 index 0000000..1e949a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yaml.rb @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class YAML < RegexLexer + title "YAML" + desc "Yaml Ain't Markup Language (yaml.org)" + mimetypes 'text/x-yaml' + tag 'yaml' + aliases 'yml' + filenames '*.yaml', '*.yml' + + # Documentation: https://yaml.org/spec/1.2/spec.html + + def self.detect?(text) + # look for the %YAML directive + return true if text =~ /\A\s*%YAML/m + end + + # NB: Tabs are forbidden in YAML, which is why you see things + # like /[ ]+/. + + # reset the indentation levels + def reset_indent + puts " yaml: reset_indent" if @debug + @indent_stack = [0] + @next_indent = 0 + @block_scalar_indent = nil + end + + def indent + raise 'empty indent stack!' if @indent_stack.empty? + @indent_stack.last + end + + def dedent?(level) + level < self.indent + end + + def indent?(level) + level > self.indent + end + + # Save a possible indentation level + def save_indent(match) + @next_indent = match.size + puts " yaml: indent: #{self.indent}/#@next_indent" if @debug + puts " yaml: popping indent stack - before: #@indent_stack" if @debug + if dedent?(@next_indent) + @indent_stack.pop while dedent?(@next_indent) + puts " yaml: popping indent stack - after: #@indent_stack" if @debug + puts " yaml: indent: #{self.indent}/#@next_indent" if @debug + + # dedenting to a state not previously indented to is an error + [match[0...self.indent], match[self.indent..-1]] + else + [match, ''] + end + end + + def continue_indent(match) + puts " yaml: continue_indent" if @debug + @next_indent += match.size + end + + def set_indent(match, opts={}) + if indent < @next_indent + puts " yaml: indenting #{indent}/#{@next_indent}" if @debug + @indent_stack << @next_indent + end + + @next_indent += match.size unless opts[:implicit] + end + + plain_scalar_start = /[^ \t\n\r\f\v?:,\[\]{}#&*!\|>'"%@`]/ + + start { reset_indent } + + state :basic do + rule %r/#.*$/, Comment::Single + end + + state :root do + mixin :basic + + rule %r/\n+/, Text + + # trailing or pre-comment whitespace + rule %r/[ ]+(?=#|$)/, Text + + rule %r/^%YAML\b/ do + token Name::Tag + reset_indent + push :yaml_directive + end + + rule %r/^%TAG\b/ do + token Name::Tag + reset_indent + push :tag_directive + end + + # doc-start and doc-end indicators + rule %r/^(?:---|\.\.\.)(?= |$)/ do + token Name::Namespace + reset_indent + push :block_line + end + + # indentation spaces + rule %r/[ ]*(?!\s|$)/ do |m| + text, err = save_indent(m[0]) + token Text, text + token Error, err + push :block_line; push :indentation + end + end + + state :indentation do + rule(/\s*?\n/) { token Text; pop! 2 } + # whitespace preceding block collection indicators + rule %r/[ ]+(?=[-:?](?:[ ]|$))/ do |m| + token Text + continue_indent(m[0]) + end + + # block collection indicators + rule(/[?:-](?=[ ]|$)/) do |m| + set_indent m[0] + token Punctuation::Indicator + end + + # the beginning of a block line + rule(/[ ]*/) { |m| token Text; continue_indent(m[0]); pop! } + end + + # indented line in the block context + state :block_line do + # line end + rule %r/[ ]*(?=#|$)/, Text, :pop! + rule %r/[ ]+/, Text + # tags, anchors, and aliases + mixin :descriptors + # block collections and scalars + mixin :block_nodes + # flow collections and quoed scalars + mixin :flow_nodes + + # a plain scalar + rule %r/(?=#{plain_scalar_start}|[?:-][^ \t\n\r\f\v])/ do + token Name::Variable + push :plain_scalar_in_block_context + end + end + + state :descriptors do + # a full-form tag + rule %r/!<[0-9A-Za-z;\/?:@&=+$,_.!~*'()\[\]%-]+>/, Keyword::Type + + # a tag in the form '!', '!suffix' or '!handle!suffix' + rule %r( + (?:![\w-]+)? # handle + !(?:[\w;/?:@&=+$,.!~*\'()\[\]%-]*) # suffix + )x, Keyword::Type + + # an anchor + rule %r/&[\p{L}\p{Nl}\p{Nd}_-]+/, Name::Label + + # an alias + rule %r/\*[\p{L}\p{Nl}\p{Nd}_-]+/, Name::Variable + end + + state :block_nodes do + # implicit key + rule %r/([^#,?\[\]{}"'\n]+)(:)(?=\s|$)/ do |m| + groups Name::Attribute, Punctuation::Indicator + set_indent m[0], :implicit => true + end + + # literal and folded scalars + rule %r/[\|>][+-]?/ do + token Punctuation::Indicator + push :block_scalar_content + push :block_scalar_header + end + end + + state :flow_nodes do + rule %r/\[/, Punctuation::Indicator, :flow_sequence + rule %r/\{/, Punctuation::Indicator, :flow_mapping + rule %r/'/, Str::Single, :single_quoted_scalar + rule %r/"/, Str::Double, :double_quoted_scalar + end + + state :flow_collection do + rule %r/\s+/m, Text + mixin :basic + rule %r/[?:,]/, Punctuation::Indicator + mixin :descriptors + mixin :flow_nodes + + rule %r/(?=#{plain_scalar_start})/ do + push :plain_scalar_in_flow_context + end + end + + state :flow_sequence do + rule %r/\]/, Punctuation::Indicator, :pop! + mixin :flow_collection + end + + state :flow_mapping do + rule %r/\}/, Punctuation::Indicator, :pop! + mixin :flow_collection + end + + state :block_scalar_content do + rule %r/\n+/, Text + + # empty lines never dedent, but they might be part of the scalar. + rule %r/^[ ]+$/ do |m| + text = m[0] + indent_size = text.size + + indent_mark = @block_scalar_indent || indent_size + + token Text, text[0...indent_mark] + token Name::Constant, text[indent_mark..-1] + end + + # TODO: ^ doesn't actually seem to affect the match at all. + # Find a way to work around this limitation. + rule %r/^[ ]*/ do |m| + token Text + + indent_size = m[0].size + + dedent_level = @block_scalar_indent || self.indent + @block_scalar_indent ||= indent_size + + if indent_size < dedent_level + save_indent m[0] + pop! + push :indentation + end + end + + rule %r/[^\n\r\f\v]+/, Str + end + + state :block_scalar_header do + # optional indentation indicator and chomping flag, in either order + rule %r( + ( + ([1-9])[+-]? | [+-]?([1-9])? + )(?=[ ]|$) + )x do |m| + @block_scalar_indent = nil + goto :ignored_line + next if m[0].empty? + + increment = m[1] || m[2] + if increment + @block_scalar_indent = indent + increment.to_i + end + + token Punctuation::Indicator + end + end + + state :ignored_line do + mixin :basic + rule %r/[ ]+/, Text + rule %r/\n/, Text, :pop! + end + + state :quoted_scalar_whitespaces do + # leading and trailing whitespace is ignored + rule %r/^[ ]+/, Text + rule %r/[ ]+$/, Text + + rule %r/\n+/m, Text + + rule %r/[ ]+/, Name::Variable + end + + state :single_quoted_scalar do + mixin :quoted_scalar_whitespaces + rule %r/\\'/, Str::Escape + rule %r/'/, Str, :pop! + rule %r/[^\s']+/, Str + end + + state :double_quoted_scalar do + rule %r/"/, Str, :pop! + mixin :quoted_scalar_whitespaces + # escapes + rule %r/\\[0abt\tn\nvfre "\\N_LP]/, Str::Escape + rule %r/\\(?:x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, + Str::Escape + rule %r/[^ \t\n\r\f\v"\\]+/, Str + end + + state :plain_scalar_in_block_context_new_line do + rule %r/^[ ]+\n/, Text + rule %r/\n+/m, Text + rule %r/^(?=---|\.\.\.)/ do + pop! 3 + end + + # dedent detection + rule %r/^[ ]*/ do |m| + token Text + pop! + + indent_size = m[0].size + + # dedent = end of scalar + if indent_size <= self.indent + pop! + save_indent(m[0]) + push :indentation + end + end + end + + state :plain_scalar_in_block_context do + # the : indicator ends a scalar + rule %r/[ ]*(?=:[ \n]|:$)/, Text, :pop! + rule %r/[ ]*:\S+/, Str + rule %r/[ ]+(?=#)/, Text, :pop! + rule %r/[ ]+$/, Text + # check for new documents or dedents at the new line + rule %r/\n+/ do + token Text + push :plain_scalar_in_block_context_new_line + end + + rule %r/[ ]+/, Str + rule %r((true|false|null)\b), Keyword::Constant + rule %r/\d+(?:\.\d+)?(?=(\r?\n)| +#)/, Literal::Number, :pop! + + # regular non-whitespace characters + rule %r/[^\s:]+/, Str + end + + state :plain_scalar_in_flow_context do + rule %r/[ ]*(?=[,:?\[\]{}])/, Text, :pop! + rule %r/[ ]+(?=#)/, Text, :pop! + rule %r/^[ ]+/, Text + rule %r/[ ]+$/, Text + rule %r/\n+/, Text + rule %r/[ ]+/, Name::Variable + rule %r/[^\s,:?\[\]{}]+/, Name::Variable + end + + state :yaml_directive do + rule %r/([ ]+)(\d+\.\d+)/ do + groups Text, Num + goto :ignored_line + end + end + + state :tag_directive do + rule %r( + ([ ]+)(!|![\w-]*!) # prefix + ([ ]+)(!|!?[\w;/?:@&=+$,.!~*'()\[\]%-]+) # tag handle + )x do + groups Text, Keyword::Type, Text, Keyword::Type + goto :ignored_line + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yang.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yang.rb new file mode 100644 index 0000000..a9d54f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/yang.rb @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class YANG < RegexLexer + title 'YANG' + desc "Lexer for the YANG 1.1 modeling language (RFC7950)" + tag 'yang' + filenames '*.yang' + mimetypes 'application/yang' + + id = /[\w-]+(?=[^\w\-\:])\b/ + + #Keywords from RFC7950 ; oriented at BNF style + def self.top_stmts_keywords + @top_stms_keywords ||= Set.new %w( + module submodule + ) + end + + def self.module_header_stmts_keywords + @module_header_stmts_keywords ||= Set.new %w( + belongs-to namespace prefix yang-version + ) + end + + def self.meta_stmts_keywords + @meta_stmts_keywords ||= Set.new %w( + contact description organization reference revision + ) + end + + def self.linkage_stmts_keywords + @linkage_stmts_keywords ||= Set.new %w( + import include revision-date + ) + end + + def self.body_stmts_keywords + @body_stms_keywords ||= Set.new %w( + action argument augment deviation extension feature grouping identity + if-feature input notification output rpc typedef + ) + end + + def self.data_def_stmts_keywords + @data_def_stms_keywords ||= Set.new %w( + anydata anyxml case choice config container deviate leaf leaf-list + list must presence refine uses when + ) + end + + def self.type_stmts_keywords + @type_stmts_keywords ||= Set.new %w( + base bit default enum error-app-tag error-message fraction-digits + length max-elements min-elements modifier ordered-by path pattern + position range require-instance status type units value yin-element + ) + end + + def self.list_stmts_keywords + @list_stmts_keywords ||= Set.new %w( + key mandatory unique + ) + end + + #RFC7950 other keywords + def self.constants_keywords + @constants_keywords ||= Set.new %w( + add current delete deprecated false invert-match max min + not-supported obsolete replace true unbounded user + ) + end + + #RFC7950 Built-In Types + def self.types + @types ||= Set.new %w( + binary bits boolean decimal64 empty enumeration identityref + instance-identifier int16 int32 int64 int8 leafref string uint16 + uint32 uint64 uint8 union + ) + end + + state :comment do + rule %r/[^*\/]/, Comment + rule %r/\/\*/, Comment, :comment + rule %r/\*\//, Comment, :pop! + rule %r/[*\/]/, Comment + end + + #Keyword::Reserved + #groups Name::Tag, Text::Whitespace + state :root do + rule %r/\s+/, Text::Whitespace + rule %r/[\{\}\;]+/, Punctuation + rule %r/(?=\?-]|\.{1,3}/, Operator + end + + state :literals do + rule %r/\b(?:true|false|null)\b/, Keyword::Constant + rule %r( + ' (?: #{escapes} | [^\\] ) ' + )x, Str::Char + + rule %r/"/, Str, :string + rule %r/r(#*)".*?"\1/m, Str + + dot = /[.][0-9_]+/ + exp = /e[-+]?[0-9_]+/ + + rule %r( + [0-9]+ + (#{dot} #{exp}? + |#{dot}? #{exp} + ) + )x, Num::Float + + rule %r( + ( 0b[10_]+ + | 0x[0-9a-fA-F_]+ + | [0-9_]+ + ) + )x, Num::Integer + end + + state :string do + rule %r/"/, Str, :pop! + rule escapes, Str::Escape + rule %r/[^"\\]+/m, Str + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/plugins/redcarpet.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/plugins/redcarpet.rb new file mode 100644 index 0000000..2558e1b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/plugins/redcarpet.rb @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# this file is not require'd from the root. To use this plugin, run: +# +# require 'rouge/plugins/redcarpet' + +module Rouge + module Plugins + module Redcarpet + def block_code(code, language) + lexer = + begin + Lexer.find_fancy(language, code) + rescue Guesser::Ambiguous => e + e.alternatives.first + end + lexer ||= Lexers::PlainText + + # XXX HACK: Redcarpet strips hard tabs out of code blocks, + # so we assume you're not using leading spaces that aren't tabs, + # and just replace them here. + if lexer.tag == 'make' + code.gsub! %r/^ /, "\t" + end + + formatter = rouge_formatter(lexer) + formatter.format(lexer.lex(code)) + end + + # override this method for custom formatting behavior + def rouge_formatter(lexer) + Formatters::HTMLLegacy.new(:css_class => "highlight #{lexer.tag}") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/regex_lexer.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/regex_lexer.rb new file mode 100644 index 0000000..02eba21 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/regex_lexer.rb @@ -0,0 +1,511 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + # @abstract + # A stateful lexer that uses sets of regular expressions to + # tokenize a string. Most lexers are instances of RegexLexer. + class RegexLexer < Lexer + class InvalidRegex < StandardError + def initialize(re) + @re = re + end + + def to_s + "regex #{@re.inspect} matches empty string, but has no predicate!" + end + end + + class ClosedState < StandardError + attr_reader :state + def initialize(state) + @state = state + end + + def rule + @state.rules.last + end + + def to_s + rule = @state.rules.last + msg = "State :#{state.name} cannot continue after #{rule.inspect}, which will always match." + if rule.re.source.include?('*') + msg += " Consider replacing * with +." + end + + msg + end + end + + # A rule is a tuple of a regular expression to test, and a callback + # to perform if the test succeeds. + # + # @see StateDSL#rule + class Rule + attr_reader :callback + attr_reader :re + attr_reader :beginning_of_line + def initialize(re, callback) + @re = re + @callback = callback + @beginning_of_line = re.source[0] == ?^ + end + + def inspect + "#" + end + end + + # a State is a named set of rules that can be tested for or + # mixed in. + # + # @see RegexLexer.state + class State + attr_reader :name, :rules + def initialize(name, rules) + @name = name + @rules = rules + end + + def inspect + "#<#{self.class.name} #{@name.inspect}>" + end + end + + class StateDSL + attr_reader :rules, :name + def initialize(name, &defn) + @name = name + @defn = defn + @rules = [] + @loaded = false + @closed = false + end + + def to_state(lexer_class) + load! + rules = @rules.map do |rule| + rule.is_a?(String) ? lexer_class.get_state(rule) : rule + end + State.new(@name, rules) + end + + def prepended(&defn) + parent_defn = @defn + StateDSL.new(@name) do + instance_eval(&defn) + instance_eval(&parent_defn) + end + end + + def appended(&defn) + parent_defn = @defn + StateDSL.new(@name) do + instance_eval(&parent_defn) + instance_eval(&defn) + end + end + + protected + # Define a new rule for this state. + # + # @overload rule(re, token, next_state=nil) + # @overload rule(re, &callback) + # + # @param [Regexp] re + # a regular expression for this rule to test. + # @param [String] tok + # the token type to yield if `re` matches. + # @param [#to_s] next_state + # (optional) a state to push onto the stack if `re` matches. + # If `next_state` is `:pop!`, the state stack will be popped + # instead. + # @param [Proc] callback + # a block that will be evaluated in the context of the lexer + # if `re` matches. This block has access to a number of lexer + # methods, including {RegexLexer#push}, {RegexLexer#pop!}, + # {RegexLexer#token}, and {RegexLexer#delegate}. The first + # argument can be used to access the match groups. + def rule(re, tok=nil, next_state=nil, &callback) + raise ClosedState.new(self) if @closed + + if tok.nil? && callback.nil? + raise "please pass `rule` a token to yield or a callback" + end + + matches_empty = re =~ '' + + callback ||= case next_state + when :pop! + proc do |stream| + puts " yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug + @output_stream.call(tok, stream[0]) + puts " popping stack: 1" if @debug + @stack.pop or raise 'empty stack!' + end + when :push + proc do |stream| + puts " yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug + @output_stream.call(tok, stream[0]) + puts " pushing :#{@stack.last.name}" if @debug + @stack.push(@stack.last) + end + when Symbol + proc do |stream| + puts " yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug + @output_stream.call(tok, stream[0]) + state = @states[next_state] || self.class.get_state(next_state) + puts " pushing :#{state.name}" if @debug + @stack.push(state) + end + when nil + # cannot use an empty-matching regexp with no predicate + raise InvalidRegex.new(re) if matches_empty + + proc do |stream| + puts " yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug + @output_stream.call(tok, stream[0]) + end + when Array + proc do |stream| + puts " yielding: #{tok.qualname}, #{stream[0].inspect}" if @debug + @output_stream.call(tok, stream[0]) + for i_next_state in next_state do + next @stack.pop if i_next_state == :pop! + next @stack.push(@stack.last) if i_next_state == :push + + state = @states[i_next_state] || self.class.get_state(i_next_state) + puts " pushing :#{state.name}" if @debug + @stack.push(state) + end + end + else + raise "invalid next state: #{next_state.inspect}" + end + + rules << Rule.new(re, callback) + + close! if matches_empty && !context_sensitive?(re) + end + + def context_sensitive?(re) + source = re.source + return true if source =~ /[(][?] MAX_NULL_SCANS + puts " warning: too many scans without consuming the string!" if @debug + return false + end + else + @null_steps = 0 + end + + return true + end + end + end + + false + end + + # Yield a token. + # + # @param tok + # the token type + # @param val + # (optional) the string value to yield. If absent, this defaults + # to the entire last match. + def token(tok, val=@current_stream[0]) + yield_token(tok, val) + end + + # @deprecated + # + # Yield a token with the next matched group. Subsequent calls + # to this method will yield subsequent groups. + def group(tok) + raise "RegexLexer#group is deprecated: use #groups instead" + end + + # Yield tokens corresponding to the matched groups of the current + # match. + def groups(*tokens) + tokens.each_with_index do |tok, i| + yield_token(tok, @current_stream[i+1]) + end + end + + # Delegate the lex to another lexer. We use the `continue_lex` method + # so that #reset! will not be called. In this way, a single lexer + # can be repeatedly delegated to while maintaining its own internal + # state stack. + # + # @param [#lex] lexer + # The lexer or lexer class to delegate to + # @param [String] text + # The text to delegate. This defaults to the last matched string. + def delegate(lexer, text=nil) + puts " delegating to: #{lexer.inspect}" if @debug + text ||= @current_stream[0] + + lexer.continue_lex(text) do |tok, val| + puts " delegated token: #{tok.inspect}, #{val.inspect}" if @debug + yield_token(tok, val) + end + end + + def recurse(text=nil) + delegate(self.class, text) + end + + # Push a state onto the stack. If no state name is given and you've + # passed a block, a state will be dynamically created using the + # {StateDSL}. + def push(state_name=nil, &b) + push_state = if state_name + get_state(state_name) + elsif block_given? + StateDSL.new(b.inspect, &b).to_state(self.class) + else + # use the top of the stack by default + self.state + end + + puts " pushing: :#{push_state.name}" if @debug + stack.push(push_state) + end + + # Pop the state stack. If a number is passed in, it will be popped + # that number of times. + def pop!(times=1) + raise 'empty stack!' if stack.empty? + + puts " popping stack: #{times}" if @debug + + stack.pop(times) + + nil + end + + # replace the head of the stack with the given state + def goto(state_name) + raise 'empty stack!' if stack.empty? + + puts " going to: state :#{state_name} " if @debug + stack[-1] = get_state(state_name) + end + + # reset the stack back to `[:root]`. + def reset_stack + puts ' resetting stack' if @debug + stack.clear + stack.push get_state(:root) + end + + # Check if `state_name` is in the state stack. + def in_state?(state_name) + state_name = state_name.to_sym + stack.any? do |state| + state.name == state_name.to_sym + end + end + + # Check if `state_name` is the state on top of the state stack. + def state?(state_name) + state_name.to_sym == state.name + end + + private + def yield_token(tok, val) + return if val.nil? || val.empty? + puts " yielding: #{tok.qualname}, #{val.inspect}" if @debug + @output_stream.yield(tok, val) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/template_lexer.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/template_lexer.rb new file mode 100644 index 0000000..384b37b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/template_lexer.rb @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + # @abstract + # A TemplateLexer is one that accepts a :parent option, to specify + # which language is being templated. The lexer class can specify its + # own default for the parent lexer, which is otherwise defaulted to + # HTML. + class TemplateLexer < RegexLexer + # the parent lexer - the one being templated. + def parent + return @parent if instance_variable_defined? :@parent + @parent = lexer_option(:parent) || Lexers::HTML.new(@options) + end + + option :parent, "the parent language (default: html)" + + start { parent.reset! } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/tex_theme_renderer.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/tex_theme_renderer.rb new file mode 100644 index 0000000..e912e2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/tex_theme_renderer.rb @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + class TexThemeRenderer + def initialize(theme, opts={}) + @theme = theme + @prefix = opts.fetch(:prefix) { 'RG' } + end + + # Our general strategy is this: + # + # * First, define the \RG{tokname}{content} command, which will + # expand into \RG@tok@tokname{content}. We use \csname...\endcsname + # to interpolate into a command. + # + # * Define the default RG* environment, which will enclose the whole + # thing. By default this will simply set \ttfamily (select monospace font) + # but it can be overridden with \renewcommand by the user to be + # any other formatting. + # + # * Define all the colors using xcolors \definecolor command. First we define + # every palette color with a name such as RG@palette@themneame@colorname. + # Then we find all foreground and background colors that have literal html + # colors embedded in them and define them with names such as + # RG@palette@themename@000000. While html allows three-letter colors such + # as #FFF, xcolor requires all six characters to be present, so we make sure + # to normalize that as well as the case convention in #inline_name. + # + # * Define the token commands RG@tok@xx. These will take the content as the + # argument and format it according to the theme, referring to the color + # in the palette. + def render(&b) + yield <<'END'.gsub('RG', @prefix) +\makeatletter +\def\RG#1#2{\csname RG@tok@#1\endcsname{#2}}% +\newenvironment{RG*}{\ttfamily}{\relax}% +END + + base = @theme.class.base_style + yield "\\definecolor{#{@prefix}@fgcolor}{HTML}{#{inline_name(base.fg || '#000000')}}" + yield "\\definecolor{#{@prefix}@bgcolor}{HTML}{#{inline_name(base.bg || '#FFFFFF')}}" + + render_palette(@theme.palette, &b) + + @theme.styles.each do |tok, style| + render_inline_pallete(style, &b) + end + + Token.each_token do |tok| + style = @theme.class.get_own_style(tok) + style ? render_style(tok, style, &b) : render_blank(tok, &b) + end + yield '\makeatother' + end + + def render_palette(palette, &b) + palette.each do |name, color| + hex = inline_name(color) + + yield "\\definecolor{#{palette_name(name)}}{HTML}{#{hex}}%" + end + end + + def render_inline_pallete(style, &b) + gen_inline(style[:fg], &b) + gen_inline(style[:bg], &b) + end + + def inline_name(color) + color =~ /^#(\h+)/ or return nil + + # xcolor does not support 3-character HTML colors, + # so we convert them here + case $1.size + when 6 + $1 + when 3 + # duplicate every character: abc -> aabbcc + $1.gsub(/\h/, '\0\0') + else + raise "invalid HTML color: #{$1}" + end.upcase + end + + def gen_inline(name, &b) + # detect inline colors + hex = inline_name(name) + return unless hex + + @gen_inline ||= {} + @gen_inline[hex] ||= begin + yield "\\definecolor{#{palette_name(hex)}}{HTML}{#{hex}}%" + end + end + + def camelize(name) + name.gsub(/_(.)/) { $1.upcase } + end + + def palette_name(name) + name = inline_name(name) || name.to_s + + "#{@prefix}@palette@#{camelize(@theme.name)}@#{camelize(name.to_s)}" + end + + def token_name(tok) + "\\csname #@prefix@tok@#{tok.shortname}\\endcsname" + end + + def render_blank(tok, &b) + "\\expandafter\\def#{token_name(tok)}#1{#1}" + end + + def render_style(tok, style, &b) + out = String.new('') + out << "\\expandafter\\def#{token_name(tok)}#1{" + out << "\\fboxsep=0pt\\colorbox{#{palette_name(style[:bg])}}{" if style[:bg] + out << '\\textbf{' if style[:bold] + out << '\\textit{' if style[:italic] + out << "\\textcolor{#{palette_name(style[:fg])}}{" if style[:fg] + out << "#1" + # close the right number of curlies + out << "}" if style[:bold] + out << "}" if style[:italic] + out << "}" if style[:fg] + out << "}" if style[:bg] + out << "}%" + yield out + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/text_analyzer.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/text_analyzer.rb new file mode 100644 index 0000000..0540ca4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/text_analyzer.rb @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + class TextAnalyzer < String + # Find a shebang. Returns nil if no shebang is present. + def shebang + return @shebang if instance_variable_defined? :@shebang + + self =~ /\A\s*#!(.*)$/ + @shebang = $1 + end + + # Check if the given shebang is present. + # + # This normalizes things so that `text.shebang?('bash')` will detect + # `#!/bash`, '#!/bin/bash', '#!/usr/bin/env bash', and '#!/bin/bash -x' + def shebang?(match) + return false unless shebang + match = /\b#{match}(\s|$)/ + match === shebang + end + + # Return the contents of the doctype tag if present, nil otherwise. + def doctype + return @doctype if instance_variable_defined? :@doctype + + self =~ %r(\A\s* + (?:<\?.*?\?>\s*)? # possible tag + + )xm + @doctype = $1 + end + + # Check if the doctype matches a given regexp or string + def doctype?(type=//) + type === doctype + end + + # Return true if the result of lexing with the given lexer contains no + # error tokens. + def lexes_cleanly?(lexer) + lexer.lex(self) do |(tok, _)| + return false if tok.name == 'Error' + end + + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/theme.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/theme.rb new file mode 100644 index 0000000..4fae98b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/theme.rb @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + class Theme + include Token::Tokens + + class Style < Hash + def initialize(theme, hsh={}) + super() + @theme = theme + merge!(hsh) + end + + [:fg, :bg].each do |mode| + define_method mode do + return self[mode] unless @theme + @theme.palette(self[mode]) if self[mode] + end + end + + def render(selector, &b) + return enum_for(:render, selector).to_a.join("\n") unless b + + return if empty? + + yield "#{selector} {" + rendered_rules.each do |rule| + yield " #{rule};" + end + yield "}" + end + + def rendered_rules(&b) + return enum_for(:rendered_rules) unless b + yield "color: #{fg}" if fg + yield "background-color: #{bg}" if bg + yield "font-weight: bold" if self[:bold] + yield "font-style: italic" if self[:italic] + yield "text-decoration: underline" if self[:underline] + + (self[:rules] || []).each(&b) + end + end + + def styles + @styles ||= self.class.styles.dup + end + + @palette = {} + def self.palette(arg={}) + @palette ||= InheritableHash.new(superclass.palette) + + if arg.is_a? Hash + @palette.merge! arg + @palette + else + case arg + when /#[0-9a-f]+/i + arg + else + @palette[arg] or raise "not in palette: #{arg.inspect}" + end + end + end + + def palette(*a) self.class.palette(*a) end + + @styles = {} + def self.styles + @styles ||= InheritableHash.new(superclass.styles) + end + + def self.render(opts={}, &b) + new(opts).render(&b) + end + + def get_own_style(token) + self.class.get_own_style(token) + end + + def get_style(token) + self.class.get_style(token) + end + + def name + self.class.name + end + + class << self + def style(*tokens) + style = tokens.last.is_a?(Hash) ? tokens.pop : {} + + tokens.each do |tok| + styles[tok] = style + end + end + + def get_own_style(token) + token.token_chain.reverse_each do |anc| + return Style.new(self, styles[anc]) if styles[anc] + end + + nil + end + + def get_style(token) + get_own_style(token) || base_style + end + + def base_style + get_own_style(Token::Tokens::Text) + end + + def name(n=nil) + return @name if n.nil? + + @name = n.to_s + register(@name) + end + + def register(name) + Theme.registry[name.to_s] = self + end + + def find(n) + registry[n.to_s] + end + + def registry + @registry ||= {} + end + end + end + + module HasModes + def mode(arg=:absent) + return @mode if arg == :absent + + @modes ||= {} + @modes[arg] ||= get_mode(arg) + end + + def get_mode(mode) + return self if self.mode == mode + + new_name = "#{self.name}.#{mode}" + Class.new(self) { name(new_name); set_mode!(mode) } + end + + def set_mode!(mode) + @mode = mode + send("make_#{mode}!") + end + + def mode!(arg) + alt_name = "#{self.name}.#{arg}" + register(alt_name) + set_mode!(arg) + end + end + + class CSSTheme < Theme + def initialize(opts={}) + @scope = opts[:scope] || '.highlight' + end + + def render(&b) + return enum_for(:render).to_a.join("\n") unless b + + # shared styles for tableized line numbers + yield "#{@scope} table td { padding: 5px; }" + yield "#{@scope} table pre { margin: 0; }" + + styles.each do |tok, style| + Style.new(self, style).render(css_selector(tok), &b) + end + end + + def render_base(selector, &b) + self.class.base_style.render(selector, &b) + end + + def style_for(tok) + self.class.get_style(tok) + end + + private + def css_selector(token) + inflate_token(token).map do |tok| + raise "unknown token: #{tok.inspect}" if tok.shortname.nil? + + single_css_selector(tok) + end.join(', ') + end + + def single_css_selector(token) + return @scope if token == Text + + "#{@scope} .#{token.shortname}" + end + + # yield all of the tokens that should be styled the same + # as the given token. Essentially this recursively all of + # the subtokens, except those which are more specifically + # styled. + def inflate_token(tok, &b) + return enum_for(:inflate_token, tok) unless block_given? + + yield tok + tok.sub_tokens.each do |(_, st)| + next if styles[st] + + inflate_token(st, &b) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/base16.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/base16.rb new file mode 100644 index 0000000..6e77c6a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/base16.rb @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + # author Chris Kempson + # base16 default dark + # https://github.com/chriskempson/base16-default-schemes + class Base16 < CSSTheme + name 'base16' + + palette base00: "#181818" + palette base01: "#282828" + palette base02: "#383838" + palette base03: "#585858" + palette base04: "#b8b8b8" + palette base05: "#d8d8d8" + palette base06: "#e8e8e8" + palette base07: "#f8f8f8" + palette base08: "#ab4642" + palette base09: "#dc9656" + palette base0A: "#f7ca88" + palette base0B: "#a1b56c" + palette base0C: "#86c1b9" + palette base0D: "#7cafc2" + palette base0E: "#ba8baf" + palette base0F: "#a16946" + + extend HasModes + + def self.light! + mode :dark # indicate that there is a dark variant + mode! :light + end + + def self.dark! + mode :light # indicate that there is a light variant + mode! :dark + end + + def self.make_dark! + style Text, :fg => :base05, :bg => :base00 + end + + def self.make_light! + style Text, :fg => :base02 + end + + light! + + style Error, :fg => :base00, :bg => :base08 + style Comment, :fg => :base03 + + style Comment::Preproc, + Name::Tag, :fg => :base0A + + style Operator, + Punctuation, :fg => :base05 + + style Generic::Inserted, :fg => :base0B + style Generic::Deleted, :fg => :base08 + style Generic::Heading, :fg => :base0D, :bg => :base00, :bold => true + + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + + style Keyword, :fg => :base0E + style Keyword::Constant, + Keyword::Type, :fg => :base09 + + style Keyword::Declaration, :fg => :base09 + + style Literal::String, :fg => :base0B + style Literal::String::Affix, :fg => :base0E + style Literal::String::Regex, :fg => :base0C + + style Literal::String::Interpol, + Literal::String::Escape, :fg => :base0F + + style Name::Namespace, + Name::Class, + Name::Constant, :fg => :base0A + + style Name::Attribute, :fg => :base0D + + style Literal::Number, + Literal::String::Symbol, :fg => :base0B + + class Solarized < Base16 + name 'base16.solarized' + light! + # author "Ethan Schoonover (http://ethanschoonover.com/solarized)" + + palette base00: "#002b36" + palette base01: "#073642" + palette base02: "#586e75" + palette base03: "#657b83" + palette base04: "#839496" + palette base05: "#93a1a1" + palette base06: "#eee8d5" + palette base07: "#fdf6e3" + palette base08: "#dc322f" + palette base09: "#cb4b16" + palette base0A: "#b58900" + palette base0B: "#859900" + palette base0C: "#2aa198" + palette base0D: "#268bd2" + palette base0E: "#6c71c4" + palette base0F: "#d33682" + end + + class Monokai < Base16 + name 'base16.monokai' + dark! + + # author "Wimer Hazenberg (http://www.monokai.nl)" + palette base00: "#272822" + palette base01: "#383830" + palette base02: "#49483e" + palette base03: "#75715e" + palette base04: "#a59f85" + palette base05: "#f8f8f2" + palette base06: "#f5f4f1" + palette base07: "#f9f8f5" + palette base08: "#f92672" + palette base09: "#fd971f" + palette base0A: "#f4bf75" + palette base0B: "#a6e22e" + palette base0C: "#a1efe4" + palette base0D: "#66d9ef" + palette base0E: "#ae81ff" + palette base0F: "#cc6633" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/bw.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/bw.rb new file mode 100644 index 0000000..779359a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/bw.rb @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + # A port of the bw style from Pygments. + # See https://bitbucket.org/birkenfeld/pygments-main/src/default/pygments/styles/bw.py + class BlackWhiteTheme < CSSTheme + name 'bw' + + style Text, :fg => '#000000', :bg => '#ffffff' + + style Comment, :italic => true + style Comment::Preproc, :italic => false + + style Keyword, :bold => true + style Keyword::Pseudo, :bold => false + style Keyword::Type, :bold => false + + style Operator, :bold => true + + style Name::Class, :bold => true + style Name::Namespace, :bold => true + style Name::Exception, :bold => true + style Name::Entity, :bold => true + style Name::Tag, :bold => true + + style Literal::String, :italic => true + style Literal::String::Affix, :bold => true + style Literal::String::Interpol, :bold => true + style Literal::String::Escape, :bold => true + + style Generic::Heading, :bold => true + style Generic::Subheading, :bold => true + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + style Generic::Prompt, :bold => true + + style Error, :fg => '#FF0000' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/colorful.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/colorful.rb new file mode 100644 index 0000000..43acc90 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/colorful.rb @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + # stolen from pygments + class Colorful < CSSTheme + name 'colorful' + + style Text, :fg => "#bbbbbb", :bg => '#000' + + style Comment, :fg => "#888" + style Comment::Preproc, :fg => "#579" + style Comment::Special, :fg => "#cc0000", :bold => true + + style Keyword, :fg => "#080", :bold => true + style Keyword::Pseudo, :fg => "#038" + style Keyword::Type, :fg => "#339" + + style Operator, :fg => "#333" + style Operator::Word, :fg => "#000", :bold => true + + style Name::Builtin, :fg => "#007020" + style Name::Function, :fg => "#06B", :bold => true + style Name::Class, :fg => "#B06", :bold => true + style Name::Namespace, :fg => "#0e84b5", :bold => true + style Name::Exception, :fg => "#F00", :bold => true + style Name::Variable, :fg => "#963" + style Name::Variable::Instance, :fg => "#33B" + style Name::Variable::Class, :fg => "#369" + style Name::Variable::Global, :fg => "#d70", :bold => true + style Name::Constant, :fg => "#036", :bold => true + style Name::Label, :fg => "#970", :bold => true + style Name::Entity, :fg => "#800", :bold => true + style Name::Attribute, :fg => "#00C" + style Name::Tag, :fg => "#070" + style Name::Decorator, :fg => "#555", :bold => true + + style Literal::String, :bg => "#fff0f0" + style Literal::String::Affix, :fg => "#080", :bold => true + style Literal::String::Char, :fg => "#04D" + style Literal::String::Doc, :fg => "#D42" + style Literal::String::Interpol, :bg => "#eee" + style Literal::String::Escape, :fg => "#666", :bold => true + style Literal::String::Regex, :fg => "#000", :bg => "#fff0ff" + style Literal::String::Symbol, :fg => "#A60" + style Literal::String::Other, :fg => "#D20" + + style Literal::Number, :fg => "#60E", :bold => true + style Literal::Number::Integer, :fg => "#00D", :bold => true + style Literal::Number::Float, :fg => "#60E", :bold => true + style Literal::Number::Hex, :fg => "#058", :bold => true + style Literal::Number::Oct, :fg => "#40E", :bold => true + + style Generic::Heading, :fg => "#000080", :bold => true + style Generic::Subheading, :fg => "#800080", :bold => true + style Generic::Deleted, :fg => "#A00000" + style Generic::Inserted, :fg => "#00A000" + style Generic::Error, :fg => "#FF0000" + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + style Generic::Prompt, :fg => "#c65d09", :bold => true + style Generic::Output, :fg => "#888" + style Generic::Traceback, :fg => "#04D" + + style Error, :fg => "#F00", :bg => "#FAA" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/github.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/github.rb new file mode 100644 index 0000000..27b8a5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/github.rb @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class Github < CSSTheme + name 'github' + + # Primer primitives + # https://github.com/primer/primitives/tree/main/src/tokens + P_RED_0 = {:light => '#ffebe9', :dark => '#ffdcd7'} + P_RED_3 = {:dark => '#ff7b72'} + P_RED_5 = {:light => '#cf222e'} + P_RED_7 = {:light => '#82071e', :dark => '#8e1519'} + P_RED_8 = {:dark => '#67060c'} + P_ORANGE_2 = {:dark => '#ffa657'} + P_ORANGE_6 = {:light => '#953800'} + P_GREEN_0 = {:light => '#dafbe1', :dark => '#aff5b4'} + P_GREEN_1 = {:dark => '#7ee787'} + P_GREEN_6 = {:light => '#116329'} + P_GREEN_8 = {:dark => '#033a16'} + P_BLUE_1 = {:dark => '#a5d6ff'} + P_BLUE_2 = {:dark => '#79c0ff'} + P_BLUE_5 = {:dark => '#1f6feb'} + P_BLUE_6 = {:light => '#0550ae'} + P_BLUE_8 = {:light => '#0a3069'} + P_PURPLE_2 = {:dark => '#d2a8ff'} + P_PURPLE_5 = {:light => '#8250df'} + P_GRAY_0 = {:light => '#f6f8fa', :dark => '#f0f6fc'} + P_GRAY_1 = {:dark => '#c9d1d9'} + P_GRAY_3 = {:dark => '#8b949e'} + P_GRAY_5 = {:light => '#6e7781'} + P_GRAY_8 = {:dark => '#161b22'} + P_GRAY_9 = {:light => '#24292f'} + + extend HasModes + + def self.light! + mode :dark # indicate that there is a dark variant + mode! :light + end + + def self.dark! + mode :light # indicate that there is a light variant + mode! :dark + end + + def self.make_dark! + palette :comment => P_GRAY_3[@mode] + palette :constant => P_BLUE_2[@mode] + palette :entity => P_PURPLE_2[@mode] + palette :heading => P_BLUE_5[@mode] + palette :keyword => P_RED_3[@mode] + palette :string => P_BLUE_1[@mode] + palette :tag => P_GREEN_1[@mode] + palette :variable => P_ORANGE_2[@mode] + + palette :fgDefault => P_GRAY_1[@mode] + palette :bgDefault => P_GRAY_8[@mode] + + palette :fgInserted => P_GREEN_0[@mode] + palette :bgInserted => P_GREEN_8[@mode] + + palette :fgDeleted => P_RED_0[@mode] + palette :bgDeleted => P_RED_8[@mode] + + palette :fgError => P_GRAY_0[@mode] + palette :bgError => P_RED_7[@mode] + end + + def self.make_light! + palette :comment => P_GRAY_5[@mode] + palette :constant => P_BLUE_6[@mode] + palette :entity => P_PURPLE_5[@mode] + palette :heading => P_BLUE_6[@mode] + palette :keyword => P_RED_5[@mode] + palette :string => P_BLUE_8[@mode] + palette :tag => P_GREEN_6[@mode] + palette :variable => P_ORANGE_6[@mode] + + palette :fgDefault => P_GRAY_9[@mode] + palette :bgDefault => P_GRAY_0[@mode] + + palette :fgInserted => P_GREEN_6[@mode] + palette :bgInserted => P_GREEN_0[@mode] + + palette :fgDeleted => P_RED_7[@mode] + palette :bgDeleted => P_RED_0[@mode] + + palette :fgError => P_GRAY_0[@mode] + palette :bgError => P_RED_7[@mode] + end + + light! + + style Text, :fg => :fgDefault, :bg => :bgDefault + + style Keyword, :fg => :keyword + + style Generic::Error, :fg => :fgError + + style Generic::Deleted, :fg => :fgDeleted, :bg => :bgDeleted + + style Name::Builtin, + Name::Class, + Name::Constant, + Name::Namespace, :fg => :variable + + style Literal::String::Regex, + Name::Attribute, + Name::Tag, :fg => :tag + + style Generic::Inserted, :fg => :fgInserted, :bg => :bgInserted + style Generic::EmphStrong, :italic => true, :bold => true + + style Keyword::Constant, + Literal, + Literal::String::Backtick, + Name::Builtin::Pseudo, + Name::Exception, + Name::Label, + Name::Property, + Name::Variable, + Operator, :fg => :constant + + style Generic::Heading, + Generic::Subheading, :fg => :heading, :bold => true + + style Literal::String, :fg => :string + + style Name::Decorator, + Name::Function, :fg => :entity + + style Error, :fg => :fgError, :bg => :bgError + + style Comment, + Generic::Lineno, + Generic::Traceback, :fg => :comment + + style Name::Entity, + Literal::String::Interpol, :fg => :fgDefault + + style Generic::Emph, :fg => :fgDefault, :italic => true + + style Generic::Strong, :fg => :fgDefault, :bold => true + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/gruvbox.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/gruvbox.rb new file mode 100644 index 0000000..8faf4cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/gruvbox.rb @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +# TODO how are we going to handle soft/hard contrast? + +module Rouge + module Themes + # Based on https://github.com/morhetz/gruvbox, with help from + # https://github.com/daveyarwood/gruvbox-pygments + class Gruvbox < CSSTheme + name 'gruvbox' + + # global Gruvbox colours {{{ + C_dark0_hard = '#1d2021' + C_dark0 ='#282828' + C_dark0_soft = '#32302f' + C_dark1 = '#3c3836' + C_dark2 = '#504945' + C_dark3 = '#665c54' + C_dark4 = '#7c6f64' + C_dark4_256 = '#7c6f64' + + C_gray_245 = '#928374' + C_gray_244 = '#928374' + + C_light0_hard = '#f9f5d7' + C_light0 = '#fbf1c7' + C_light0_soft = '#f2e5bc' + C_light1 = '#ebdbb2' + C_light2 = '#d5c4a1' + C_light3 = '#bdae93' + C_light4 = '#a89984' + C_light4_256 = '#a89984' + + C_bright_red = '#fb4934' + C_bright_green = '#b8bb26' + C_bright_yellow = '#fabd2f' + C_bright_blue = '#83a598' + C_bright_purple = '#d3869b' + C_bright_aqua = '#8ec07c' + C_bright_orange = '#fe8019' + + C_neutral_red = '#cc241d' + C_neutral_green = '#98971a' + C_neutral_yellow = '#d79921' + C_neutral_blue = '#458588' + C_neutral_purple = '#b16286' + C_neutral_aqua = '#689d6a' + C_neutral_orange = '#d65d0e' + + C_faded_red = '#9d0006' + C_faded_green = '#79740e' + C_faded_yellow = '#b57614' + C_faded_blue = '#076678' + C_faded_purple = '#8f3f71' + C_faded_aqua = '#427b58' + C_faded_orange = '#af3a03' + # }}} + + extend HasModes + + def self.light! + mode :dark # indicate that there is a dark variant + mode! :light + end + + def self.dark! + mode :light # indicate that there is a light variant + mode! :dark + end + + def self.make_dark! + palette bg0: C_dark0 + palette bg1: C_dark1 + palette bg2: C_dark2 + palette bg3: C_dark3 + palette bg4: C_dark4 + + palette gray: C_gray_245 + + palette fg0: C_light0 + palette fg1: C_light1 + palette fg2: C_light2 + palette fg3: C_light3 + palette fg4: C_light4 + + palette fg4_256: C_light4_256 + + palette red: C_bright_red + palette green: C_bright_green + palette yellow: C_bright_yellow + palette blue: C_bright_blue + palette purple: C_bright_purple + palette aqua: C_bright_aqua + palette orange: C_bright_orange + + end + + def self.make_light! + palette bg0: C_light0 + palette bg1: C_light1 + palette bg2: C_light2 + palette bg3: C_light3 + palette bg4: C_light4 + + palette gray: C_gray_244 + + palette fg0: C_dark0 + palette fg1: C_dark1 + palette fg2: C_dark2 + palette fg3: C_dark3 + palette fg4: C_dark4 + + palette fg4_256: C_dark4_256 + + palette red: C_faded_red + palette green: C_faded_green + palette yellow: C_faded_yellow + palette blue: C_faded_blue + palette purple: C_faded_purple + palette aqua: C_faded_aqua + palette orange: C_faded_orange + end + + dark! + mode :light + + style Text, :fg => :fg0, :bg => :bg0 + style Error, :fg => :red, :bg => :bg0, :bold => true + style Comment, :fg => :gray, :italic => true + + style Comment::Preproc, :fg => :aqua + + style Name::Tag, :fg => :red + + style Operator, + Punctuation, :fg => :fg0 + + style Generic::Inserted, :fg => :green, :bg => :bg0 + style Generic::Deleted, :fg => :red, :bg => :bg0 + style Generic::Heading, :fg => :green, :bold => true + + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + + style Keyword, :fg => :red + style Keyword::Constant, :fg => :purple + style Keyword::Type, :fg => :yellow + + style Keyword::Declaration, :fg => :orange + + style Literal::String, + Literal::String::Interpol, + Literal::String::Regex, :fg => :green, :italic => true + + style Literal::String::Affix, :fg => :red + + style Literal::String::Escape, :fg => :orange + + style Name::Namespace, + Name::Class, :fg => :aqua + + style Name::Constant, :fg => :purple + + style Name::Attribute, :fg => :green + + style Literal::Number, :fg => :purple + + style Literal::String::Symbol, :fg => :blue + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/igor_pro.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/igor_pro.rb new file mode 100644 index 0000000..abcc758 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/igor_pro.rb @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class IgorPro < CSSTheme + name 'igorpro' + + style Text, :fg => '#444444' + style Comment::Preproc, :fg => '#CC00A3' + style Comment::Special, :fg => '#CC00A3' + style Comment, :fg => '#FF0000' + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + style Keyword::Constant, :fg => '#C34E00' + style Keyword::Declaration, :fg => '#0000FF' + style Keyword::Reserved, :fg => '#007575' + style Keyword, :fg => '#0000FF' + style Literal::String, :fg => '#009C00' + style Literal::String::Affix, :fg => '#0000FF' + style Name::Builtin, :fg => '#C34E00' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/magritte.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/magritte.rb new file mode 100644 index 0000000..09fc1ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/magritte.rb @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class Magritte < CSSTheme + name 'magritte' + + palette :dragon => '#006c6c' + palette :black => '#000000' + palette :forest => '#007500' + palette :candy => '#ff0089' + palette :wine => '#7c0000' + palette :grape => '#4c48fe' + palette :dark => '#000707' + palette :cherry => '#f22700' + palette :white => '#ffffff' + palette :royal => '#19003a' + + palette :purple => '#840084' + palette :chocolate => '#920241' + palette :lavender => '#d8d9ff' + palette :eggshell => '#f3ffff' + palette :yellow => '#ffff3f' + + palette :lightgray => '#BBBBBB' + palette :darkgray => '#999999' + + style Text, :fg => :dark, :bg => :eggshell + style Generic::Lineno, :fg => :eggshell, :bg => :dark + + # style Generic::Prompt, :fg => :chilly, :bold => true + + style Comment, :fg => :dragon, :italic => true + style Comment::Preproc, :fg => :chocolate, :bold => true + style Error, :fg => :eggshell, :bg => :cherry + style Generic::Error, :fg => :cherry, :italic => true, :bold => true + style Keyword, :fg => :royal, :bold => true + style Operator, :fg => :grape, :bold => true + style Punctuation, :fg => :grape + style Generic::Deleted, :fg => :cherry + style Generic::Inserted, :fg => :forest + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + style Generic::Traceback, :fg => :black, :bg => :lavender + style Keyword::Constant, :fg => :forest, :bold => true + style Keyword::Namespace, + Keyword::Pseudo, + Keyword::Reserved, + Generic::Heading, + Generic::Subheading, :fg => :forest, :bold => true + style Keyword::Type, + Name::Constant, + Name::Class, + Name::Decorator, + Name::Namespace, + Name::Builtin::Pseudo, + Name::Exception, :fg => :chocolate, :bold => true + style Name::Label, + Name::Tag, :fg => :purple, :bold => true + style Literal::Number, + Literal::Date, :fg => :forest, :bold => true + style Literal::String::Symbol, :fg => :forest + style Literal::String, :fg => :wine, :bold => true + style Literal::String::Affix, :fg => :royal, :bold => true + style Literal::String::Escape, + Literal::String::Char, + Literal::String::Interpol, :fg => :purple, :bold => true + style Name::Builtin, :bold => true + style Name::Entity, :fg => :darkgray, :bold => true + style Text::Whitespace, :fg => :lightgray + style Generic::Output, :fg => :royal + style Name::Function, + Name::Property, + Name::Attribute, :fg => :candy + style Name::Variable, :fg => :candy, :bold => true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/molokai.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/molokai.rb new file mode 100644 index 0000000..33d0391 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/molokai.rb @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class Molokai < CSSTheme + name 'molokai' + + palette :black => '#1b1d1e' + palette :white => '#f8f8f2' + palette :blue => '#66d9ef' + palette :green => '#a6e22e' + palette :grey => '#403d3d' + palette :red => '#f92672' + palette :light_grey => '#465457' + palette :dark_blue => '#5e5d83' + palette :violet => '#af87ff' + palette :yellow => '#d7d787' + + style Comment, + Comment::Multiline, + Comment::Single, :fg => :dark_blue, :italic => true + style Comment::Preproc, :fg => :light_grey, :bold => true + style Comment::Special, :fg => :light_grey, :italic => true, :bold => true + style Error, :fg => :white, :bg => :grey + style Generic::Inserted, :fg => :green + style Generic::Deleted, :fg => :red + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Error, + Generic::Traceback, :fg => :red + style Generic::Heading, :fg => :grey + style Generic::Output, :fg => :grey + style Generic::Prompt, :fg => :blue + style Generic::Strong, :bold => true + style Generic::Subheading, :fg => :light_grey + style Keyword, + Keyword::Constant, + Keyword::Declaration, + Keyword::Pseudo, + Keyword::Reserved, + Keyword::Type, :fg => :blue, :bold => true + style Keyword::Namespace, + Operator::Word, + Operator, :fg => :red, :bold => true + style Literal::Number::Float, + Literal::Number::Hex, + Literal::Number::Integer::Long, + Literal::Number::Integer, + Literal::Number::Oct, + Literal::Number, + Literal::String::Escape, :fg => :violet + style Literal::String::Backtick, + Literal::String::Char, + Literal::String::Doc, + Literal::String::Double, + Literal::String::Heredoc, + Literal::String::Interpol, + Literal::String::Other, + Literal::String::Regex, + Literal::String::Single, + Literal::String::Symbol, + Literal::String, :fg => :yellow + style Name::Attribute, :fg => :green + style Name::Class, + Name::Decorator, + Name::Exception, + Name::Function, :fg => :green, :bold => true + style Name::Constant, :fg => :blue + style Name::Builtin::Pseudo, + Name::Builtin, + Name::Entity, + Name::Namespace, + Name::Variable::Class, + Name::Variable::Global, + Name::Variable::Instance, + Name::Variable, + Text::Whitespace, :fg => :white + style Name::Label, :fg => :white, :bold => true + style Name::Tag, :fg => :red + style Text, :fg => :white, :bg => :black + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai.rb new file mode 100644 index 0000000..412f860 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai.rb @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class Monokai < CSSTheme + name 'monokai' + + palette :black => '#000000' + palette :bright_green => '#a6e22e' + palette :bright_pink => '#f92672' + palette :carmine => '#960050' + palette :dark => '#49483e' + palette :dark_grey => '#888888' + palette :dark_red => '#aa0000' + palette :dimgrey => '#75715e' + palette :dimgreen => '#324932' + palette :dimred => '#493131' + palette :emperor => '#555555' + palette :grey => '#999999' + palette :light_grey => '#aaaaaa' + palette :light_violet => '#ae81ff' + palette :soft_cyan => '#66d9ef' + palette :soft_yellow => '#e6db74' + palette :very_dark => '#1e0010' + palette :whitish => '#f8f8f2' + palette :orange => '#f6aa11' + palette :white => '#ffffff' + + style Comment, + Comment::Multiline, + Comment::Single, :fg => :dimgrey, :italic => true + style Comment::Preproc, :fg => :dimgrey, :bold => true + style Comment::Special, :fg => :dimgrey, :italic => true, :bold => true + style Error, :fg => :carmine, :bg => :very_dark + style Generic::Inserted, :fg => :white, :bg => :dimgreen + style Generic::Deleted, :fg => :white, :bg => :dimred + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Error, + Generic::Traceback, :fg => :dark_red + style Generic::Heading, :fg => :grey + style Generic::Output, :fg => :dark_grey + style Generic::Prompt, :fg => :emperor + style Generic::Strong, :bold => true + style Generic::Subheading, :fg => :light_grey + style Keyword, + Keyword::Constant, + Keyword::Declaration, + Keyword::Pseudo, + Keyword::Reserved, + Keyword::Type, :fg => :soft_cyan, :bold => true + style Keyword::Namespace, + Operator::Word, + Operator, :fg => :bright_pink, :bold => true + style Literal::Number::Float, + Literal::Number::Hex, + Literal::Number::Integer::Long, + Literal::Number::Integer, + Literal::Number::Oct, + Literal::Number, + Literal::String::Escape, :fg => :light_violet + style Literal::String::Affix, :fg => :soft_cyan, :bold => true + style Literal::String::Backtick, + Literal::String::Char, + Literal::String::Doc, + Literal::String::Double, + Literal::String::Heredoc, + Literal::String::Interpol, + Literal::String::Other, + Literal::String::Regex, + Literal::String::Single, + Literal::String::Symbol, + Literal::String, :fg => :soft_yellow + style Name::Attribute, :fg => :bright_green + style Name::Class, + Name::Decorator, + Name::Exception, + Name::Function, :fg => :bright_green, :bold => true + style Name::Constant, :fg => :soft_cyan + style Name::Builtin::Pseudo, + Name::Builtin, + Name::Entity, + Name::Namespace, + Name::Variable::Class, + Name::Variable::Global, + Name::Variable::Instance, + Name::Variable, + Text::Whitespace, :fg => :whitish + style Name::Label, :fg => :whitish, :bold => true + style Name::Tag, :fg => :bright_pink + style Text, :fg => :whitish, :bg => :dark + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai_sublime.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai_sublime.rb new file mode 100644 index 0000000..b0f2cd6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/monokai_sublime.rb @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class MonokaiSublime < CSSTheme + name 'monokai.sublime' + + palette :black => '#000000' + palette :bright_green => '#a6e22e' + palette :bright_pink => '#f92672' + palette :carmine => '#960050' + palette :dark => '#49483e' + palette :dark_graphite => '#272822' + palette :dark_grey => '#888888' + palette :dark_red => '#aa0000' + palette :dimgrey => '#75715e' + palette :emperor => '#555555' + palette :grey => '#999999' + palette :light_grey => '#aaaaaa' + palette :light_violet => '#ae81ff' + palette :soft_cyan => '#66d9ef' + palette :soft_yellow => '#e6db74' + palette :very_dark => '#1e0010' + palette :whitish => '#f8f8f2' + palette :orange => '#f6aa11' + palette :white => '#ffffff' + + style Generic::Heading, :fg => :grey + style Literal::String::Regex, :fg => :orange + style Generic::Output, :fg => :dark_grey + style Generic::Prompt, :fg => :emperor + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + style Generic::Subheading, :fg => :light_grey + style Name::Builtin, :fg => :orange + style Comment::Multiline, + Comment::Preproc, + Comment::Single, + Comment::Special, + Comment, :fg => :dimgrey + style Error, + Generic::Error, + Generic::Traceback, :fg => :carmine + style Generic::Deleted, + Generic::Inserted, :fg => :dark + style Keyword::Constant, + Keyword::Declaration, + Keyword::Reserved, + Name::Constant, + Keyword::Type, :fg => :soft_cyan + style Literal::Number::Float, + Literal::Number::Hex, + Literal::Number::Integer::Long, + Literal::Number::Integer, + Literal::Number::Oct, + Literal::Number, + Literal::String::Char, + Literal::String::Escape, + Literal::String::Symbol, :fg => :light_violet + style Literal::String::Doc, + Literal::String::Double, + Literal::String::Backtick, + Literal::String::Heredoc, + Literal::String::Interpol, + Literal::String::Other, + Literal::String::Single, + Literal::String, :fg => :soft_yellow + style Name::Attribute, + Name::Class, + Name::Decorator, + Name::Exception, + Name::Function, :fg => :bright_green + style Name::Variable::Class, + Name::Namespace, + Name::Label, + Name::Entity, + Name::Builtin::Pseudo, + Name::Variable::Global, + Name::Variable::Instance, + Name::Variable, + Text::Whitespace, + Text, + Name, :fg => :white, :bg => :dark_graphite + style Operator::Word, + Name::Tag, + Keyword, + Keyword::Namespace, + Keyword::Pseudo, + Operator, :fg => :bright_pink + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/pastie.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/pastie.rb new file mode 100644 index 0000000..f10c7b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/pastie.rb @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + # A port of the pastie style from Pygments. + # See https://bitbucket.org/birkenfeld/pygments-main/src/default/pygments/styles/pastie.py + class Pastie < CSSTheme + name 'pastie' + + style Comment, :fg => '#888888' + style Comment::Preproc, :fg => '#cc0000', :bold => true + style Comment::Special, :fg => '#cc0000', :bg => '#fff0f0', :bold => true + + style Error, :fg => '#a61717', :bg => '#e3d2d2' + style Generic::Error, :fg => '#aa0000' + + style Generic::Heading, :fg => '#333333' + style Generic::Subheading, :fg => '#666666' + + style Generic::Deleted, :fg => '#000000', :bg => '#ffdddd' + style Generic::Inserted, :fg => '#000000', :bg => '#ddffdd' + + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + + style Generic::Lineno, :fg => '#888888' + style Generic::Output, :fg => '#888888' + style Generic::Prompt, :fg => '#555555' + style Generic::Traceback, :fg => '#aa0000' + + style Keyword, :fg => '#008800', :bold => true + style Keyword::Pseudo, :fg => '#008800' + style Keyword::Type, :fg => '#888888', :bold => true + + style Num, :fg => '#0000dd', :bold => true + + style Str, :fg => '#dd2200', :bg => '#fff0f0' + style Str::Affix, :fg => '#008800', :bold => true + style Str::Escape, :fg => '#0044dd', :bg => '#fff0f0' + style Str::Interpol, :fg => '#3333bb', :bg => '#fff0f0' + style Str::Other, :fg => '#22bb22', :bg => '#f0fff0' + #style Str::Regex, :fg => '#008800', :bg => '#fff0ff' + # The background color on regex really doesn't look good, so let's drop it + style Str::Regex, :fg => '#008800' + style Str::Symbol, :fg => '#aa6600', :bg => '#fff0f0' + + style Name::Attribute, :fg => '#336699' + style Name::Builtin, :fg => '#003388' + style Name::Class, :fg => '#bb0066', :bold => true + style Name::Constant, :fg => '#003366', :bold => true + style Name::Decorator, :fg => '#555555' + style Name::Exception, :fg => '#bb0066', :bold => true + style Name::Function, :fg => '#0066bb', :bold => true + #style Name::Label, :fg => '#336699', :italic => true + # Name::Label is used for built-in CSS properties in Rouge, so let's drop italics + style Name::Label, :fg => '#336699' + style Name::Namespace, :fg => '#bb0066', :bold => true + style Name::Property, :fg => '#336699', :bold => true + style Name::Tag, :fg => '#bb0066', :bold => true + style Name::Variable, :fg => '#336699' + style Name::Variable::Global, :fg => '#dd7700' + style Name::Variable::Instance, :fg => '#3333bb' + + style Operator::Word, :fg => '#008800' + + style Text, {} + style Text::Whitespace, :fg => '#bbbbbb' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/thankful_eyes.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/thankful_eyes.rb new file mode 100644 index 0000000..2f84209 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/thankful_eyes.rb @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class ThankfulEyes < CSSTheme + name 'thankful_eyes' + + # pallette, from GTKSourceView's ThankfulEyes + palette :cool_as_ice => '#6c8b9f' + palette :slate_blue => '#4e5d62' + palette :eggshell_cloud => '#dee5e7' + palette :krasna => '#122b3b' + palette :aluminum1 => '#fefeec' + palette :scarletred2 => '#cc0000' + palette :butter3 => '#c4a000' + palette :go_get_it => '#b2fd6d' + palette :chilly => '#a8e1fe' + palette :unicorn => '#faf6e4' + palette :sandy => '#f6dd62' + palette :pink_merengue => '#f696db' + palette :dune => '#fff0a6' + palette :backlit => '#4df4ff' + palette :schrill => '#ffb000' + + style Text, :fg => :unicorn, :bg => :krasna + style Generic::Lineno, :fg => :eggshell_cloud, :bg => :slate_blue + + style Generic::Prompt, :fg => :chilly, :bold => true + + style Comment, :fg => :cool_as_ice, :italic => true + style Comment::Preproc, :fg => :go_get_it, :bold => true + style Error, :fg => :aluminum1, :bg => :scarletred2 + style Generic::Error, :fg => :scarletred2, :italic => true, :bold => true + style Keyword, :fg => :sandy, :bold => true + style Operator, :fg => :backlit, :bold => true + style Punctuation, :fg => :backlit + style Generic::Deleted, :fg => :scarletred2 + style Generic::Inserted, :fg => :go_get_it + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + style Generic::Traceback, :fg => :eggshell_cloud, :bg => :slate_blue + style Keyword::Constant, :fg => :pink_merengue, :bold => true + style Keyword::Namespace, + Keyword::Pseudo, + Keyword::Reserved, + Generic::Heading, + Generic::Subheading, :fg => :schrill, :bold => true + style Keyword::Type, + Name::Constant, + Name::Class, + Name::Decorator, + Name::Namespace, + Name::Builtin::Pseudo, + Name::Exception, :fg => :go_get_it, :bold => true + style Name::Label, + Name::Tag, :fg => :schrill, :bold => true + style Literal::Number, + Literal::Date, + Literal::String::Symbol, :fg => :pink_merengue, :bold => true + style Literal::String, :fg => :dune, :bold => true + style Literal::String::Affix, :fg => :sandy, :bold => true + style Literal::String::Escape, + Literal::String::Char, + Literal::String::Interpol, :fg => :backlit, :bold => true + style Name::Builtin, :bold => true + style Name::Entity, :fg => '#999999', :bold => true + style Text::Whitespace, + Generic::Output, :fg => '#BBBBBB' + style Name::Function, + Name::Property, + Name::Attribute, :fg => :chilly + style Name::Variable, :fg => :chilly, :bold => true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/tulip.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/tulip.rb new file mode 100644 index 0000000..5429a66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/themes/tulip.rb @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Themes + class Tulip < CSSTheme + name 'tulip' + + palette :purple => '#766DAF' + palette :lpurple => '#9f93e6' + palette :orange => '#FAAF4C' + palette :green => '#3FB34F' + palette :lgreen => '#41ff5b' + palette :yellow => '#FFF02A' + palette :black => '#000000' + palette :gray => '#6D6E70' + palette :red => '#CC0000' + palette :dark_purple => '#231529' + palette :lunicorn => '#faf8ed' + palette :white => '#FFFFFF' + palette :earth => '#181a27' + palette :dune => '#fff0a6' + + style Text, :fg => :white, :bg => :dark_purple + + style Comment, :fg => :gray, :italic => true + style Comment::Preproc, :fg => :lgreen, :bold => true + style Error, + Generic::Error, :fg => :white, :bg => :red + style Keyword, :fg => :yellow, :bold => true + style Operator, + Punctuation, :fg => :lgreen + style Generic::Deleted, :fg => :red + style Generic::Inserted, :fg => :green + style Generic::Emph, :italic => true + style Generic::EmphStrong, :italic => true, :bold => true + style Generic::Strong, :bold => true + style Generic::Traceback, + Generic::Lineno, :fg => :white, :bg => :purple + style Keyword::Constant, :fg => :lpurple, :bold => true + style Keyword::Namespace, + Keyword::Pseudo, + Keyword::Reserved, + Generic::Heading, + Generic::Subheading, :fg => :white, :bold => true + style Keyword::Type, + Name::Constant, + Name::Class, + Name::Decorator, + Name::Namespace, + Name::Builtin::Pseudo, + Name::Exception, :fg => :orange, :bold => true + style Name::Label, + Name::Tag, :fg => :lpurple, :bold => true + style Literal::Number, + Literal::Date, + Literal::String::Symbol, :fg => :lpurple, :bold => true + style Literal::String, :fg => :dune, :bold => true + style Literal::String::Affix, :fg => :yellow, :bold => true + style Literal::String::Escape, + Literal::String::Char, + Literal::String::Interpol, :fg => :orange, :bold => true + style Name::Builtin, :bold => true + style Name::Entity, :fg => '#999999', :bold => true + style Text::Whitespace, :fg => '#BBBBBB' + style Name::Function, + Name::Property, + Name::Attribute, :fg => :lgreen + style Name::Variable, :fg => :lgreen, :bold => true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/token.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/token.rb new file mode 100644 index 0000000..9c3f867 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/token.rb @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + class Token + class << self + attr_reader :name + attr_reader :parent + attr_reader :shortname + + def cache + @cache ||= {} + end + + def sub_tokens + @sub_tokens ||= {} + end + + def [](qualname) + return qualname unless qualname.is_a? ::String + + Token.cache[qualname] + end + + def inspect + "" + end + + def matches?(other) + other.token_chain.include? self + end + + def token_chain + @token_chain ||= ancestors.take_while { |x| x != Token }.reverse + end + + def qualname + @qualname ||= token_chain.map(&:name).join('.') + end + + def register! + Token.cache[self.qualname] = self + parent.sub_tokens[self.name] = self + end + + def make_token(name, shortname, &b) + parent = self + Class.new(parent) do + @parent = parent + @name = name + @shortname = shortname + register! + class_eval(&b) if b + end + end + + def token(name, shortname, &b) + tok = make_token(name, shortname, &b) + const_set(name, tok) + end + + def each_token(&b) + Token.cache.each do |(_, t)| + b.call(t) + end + end + end + + module Tokens + def self.token(name, shortname, &b) + tok = Token.make_token(name, shortname, &b) + const_set(name, tok) + end + + # XXX IMPORTANT XXX + # For compatibility, this list must be kept in sync with + # pygments.token.STANDARD_TYPES + # please see https://github.com/jneen/rouge/wiki/List-of-tokens + token :Text, '' do + token :Whitespace, 'w' + end + + token :Escape, 'esc' + token :Error, 'err' + token :Other, 'x' + + token :Keyword, 'k' do + token :Constant, 'kc' + token :Declaration, 'kd' + token :Namespace, 'kn' + token :Pseudo, 'kp' + token :Reserved, 'kr' + token :Type, 'kt' + token :Variable, 'kv' + end + + token :Name, 'n' do + token :Attribute, 'na' + token :Builtin, 'nb' do + token :Pseudo, 'bp' + end + token :Class, 'nc' + token :Constant, 'no' + token :Decorator, 'nd' + token :Entity, 'ni' + token :Exception, 'ne' + token :Function, 'nf' do + token :Magic, 'fm' + end + token :Property, 'py' + token :Label, 'nl' + token :Namespace, 'nn' + token :Other, 'nx' + token :Tag, 'nt' + token :Variable, 'nv' do + token :Class, 'vc' + token :Global, 'vg' + token :Instance, 'vi' + token :Magic, 'vm' + end + end + + token :Literal, 'l' do + token :Date, 'ld' + + token :String, 's' do + token :Affix, 'sa' + token :Backtick, 'sb' + token :Char, 'sc' + token :Delimiter, 'dl' + token :Doc, 'sd' + token :Double, 's2' + token :Escape, 'se' + token :Heredoc, 'sh' + token :Interpol, 'si' + token :Other, 'sx' + token :Regex, 'sr' + token :Single, 's1' + token :Symbol, 'ss' + end + + token :Number, 'm' do + token :Bin, 'mb' + token :Float, 'mf' + token :Hex, 'mh' + token :Integer, 'mi' do + token :Long, 'il' + end + token :Oct, 'mo' + token :Other, 'mx' + end + end + + token :Operator, 'o' do + token :Word, 'ow' + end + + token :Punctuation, 'p' do + token :Indicator, 'pi' + end + + token :Comment, 'c' do + token :Hashbang, 'ch' + token :Doc, 'cd' + token :Multiline, 'cm' + token :Preproc, 'cp' + token :PreprocFile, 'cpf' + token :Single, 'c1' + token :Special, 'cs' + end + + token :Generic, 'g' do + token :Deleted, 'gd' + token :Emph, 'ge' + token :EmphStrong, 'ges' + token :Error, 'gr' + token :Heading, 'gh' + token :Inserted, 'gi' + token :Lineno, 'gl' + token :Output, 'go' + token :Prompt, 'gp' + token :Strong, 'gs' + token :Subheading, 'gu' + token :Traceback, 'gt' + end + + # convenience + Num = Literal::Number + Str = Literal::String + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/util.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/util.rb new file mode 100644 index 0000000..d204686 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/util.rb @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + class InheritableHash < Hash + def initialize(parent=nil) + @parent = parent + end + + def [](k) + value = super + return value if own_keys.include?(k) + + value || parent[k] + end + + def parent + @parent ||= {} + end + + def include?(k) + super or parent.include?(k) + end + + def each(&b) + keys.each do |k| + b.call(k, self[k]) + end + end + + alias own_keys keys + def keys + keys = own_keys.concat(parent.keys) + keys.uniq! + keys + end + end + + class InheritableList + include Enumerable + + def initialize(parent=nil) + @parent = parent + end + + def parent + @parent ||= [] + end + + def each(&b) + return enum_for(:each) unless block_given? + + parent.each(&b) + own_entries.each(&b) + end + + def own_entries + @own_entries ||= [] + end + + def push(o) + own_entries << o + end + alias << push + end + + # shared methods for some indentation-sensitive lexers + module Indentation + def reset! + super + @block_state = @block_indentation = nil + end + + # push a state for the next indented block + def starts_block(block_state) + @block_state = block_state + @block_indentation = @last_indentation || '' + puts " starts_block: #{block_state.inspect}" if @debug + puts " block_indentation: #{@block_indentation.inspect}" if @debug + end + + # handle a single indented line + def indentation(indent_str) + puts " indentation: #{indent_str.inspect}" if @debug + puts " block_indentation: #{@block_indentation.inspect}" if @debug + @last_indentation = indent_str + + # if it's an indent and we know where to go next, + # push that state. otherwise, push content and + # clear the block state. + if (@block_state && + indent_str.start_with?(@block_indentation) && + indent_str != @block_indentation + ) + push @block_state + else + @block_state = @block_indentation = nil + push :content + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/version.rb b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/version.rb new file mode 100644 index 0000000..3eaa132 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/version.rb @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + def self.version + "4.7.0" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/rouge.gemspec b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/rouge.gemspec new file mode 100644 index 0000000..f1a6509 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/rouge.gemspec @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require './lib/rouge/version' + +Gem::Specification.new do |s| + s.name = "rouge" + s.version = Rouge.version + s.authors = ["Jeanine Adkisson"] + s.email = ["jneen@jneen.net"] + s.summary = "A pure-ruby colorizer based on pygments" + s.description = <<-desc.strip.gsub(/\s+/, ' ') + Rouge aims to a be a simple, easy-to-extend drop-in replacement + for pygments. + desc + s.homepage = "http://rouge.jneen.net/" + s.files = Dir['Gemfile', 'LICENSE', 'rouge.gemspec', 'lib/**/*.rb', 'lib/**/*.yml', 'bin/rougify', 'lib/rouge/demos/*'] + s.executables = %w(rougify) + s.licenses = ['MIT', 'BSD-2-Clause'] + s.required_ruby_version = '>= 2.7' + s.metadata = { + "bug_tracker_uri" => "https://github.com/rouge-ruby/rouge/issues", + "changelog_uri" => "https://github.com/rouge-ruby/rouge/blob/master/CHANGELOG.md", + "documentation_uri" => "https://rouge-ruby.github.io/docs/", + "source_code_uri" => "https://github.com/rouge-ruby/rouge" + } +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/LICENSE b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/LICENSE new file mode 100644 index 0000000..acbabf4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 なつき + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/README.md b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/README.md new file mode 100644 index 0000000..ec72d6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/README.md @@ -0,0 +1,48 @@ +# Embedded Sass Host for Ruby + +[![build](https://github.com/sass-contrib/sass-embedded-host-ruby/actions/workflows/build.yml/badge.svg)](https://github.com/sass-contrib/sass-embedded-host-ruby/actions/workflows/build.yml) +[![gem](https://badge.fury.io/rb/sass-embedded.svg)](https://rubygems.org/gems/sass-embedded) + +This is a Ruby library that implements the host side of the [Embedded Sass protocol](https://github.com/sass/sass/blob/HEAD/spec/embedded-protocol.md). + +It exposes a Ruby API for Sass that's backed by a native [Dart Sass](https://sass-lang.com/dart-sass) executable on [supported hardware architectures and platforms](https://dart.dev/get-dart#system-requirements) or a Node.js Dart Sass executable everywhere else. + +## Install + +``` sh +gem install sass-embedded +``` + +## Usage + +The Ruby API provides two entrypoints for compiling Sass to CSS. + +- `Sass.compile` takes a path to a Sass file and return the result of compiling that file to CSS. + +``` ruby +require 'sass-embedded' + +result = Sass.compile('style.scss') +puts result.css + +compressed = Sass.compile('style.scss', style: :compressed) +puts compressed.css +``` + +- `Sass.compile_string` takes a string that represents the contents of a Sass file and return the result of compiling that file to CSS. + +``` ruby +require 'sass-embedded' + +result = Sass.compile_string('h1 { font-size: 40px; }') +puts result.css + +compressed = Sass.compile_string('h1 { font-size: 40px; }', style: :compressed) +puts compressed.css +``` + +See [rubydoc.info/gems/sass-embedded/Sass](https://rubydoc.info/gems/sass-embedded/Sass) for full API documentation. + +--- + +Disclaimer: this is not an official Google product. diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/exe/sass b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/exe/sass new file mode 100755 index 0000000..3a0111d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/exe/sass @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'sass/cli' + +module Sass + # The `sass` command line interface + module CLI + Kernel.exec(*COMMAND, *ARGV) + end + + private_constant :CLI +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass-embedded.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass-embedded.rb new file mode 100755 index 0000000..91324f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass-embedded.rb @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require_relative 'sass/embedded' diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value.rb new file mode 100644 index 0000000..68f69de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Sass + # The type of values that can be arguments to a SassCalculation. + # + # @see https://sass-lang.com/documentation/js-api/types/calculationvalue/ + module CalculationValue + private + + def assert_calculation_value(value, name = nil) + if !value.is_a?(Sass::CalculationValue) || (value.is_a?(Sass::Value::String) && value.quoted?) + raise Sass::ScriptError.new( + "#{value} must be one of SassNumber, unquoted SassString, SassCalculation, CalculationOperation", name + ) + end + + value + end + end +end + +require_relative 'calculation_value/calculation_operation' diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value/calculation_operation.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value/calculation_operation.rb new file mode 100644 index 0000000..55347d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/calculation_value/calculation_operation.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Sass + module CalculationValue + # A binary operation that can appear in a SassCalculation. + # + # @see https://sass-lang.com/documentation/js-api/classes/calculationoperation/ + class CalculationOperation + include CalculationValue + + OPERATORS = %w[+ - * /].freeze + + private_constant :OPERATORS + + # @param operator [::String] + # @param left [CalculationValue] + # @param right [CalculationValue] + def initialize(operator, left, right) + raise Sass::ScriptError, "Invalid operator: #{operator}" unless OPERATORS.include?(operator) + + @operator = operator.freeze + @left = assert_calculation_value(left, 'left') + @right = assert_calculation_value(right, 'right') + end + + # @return [::String] + attr_reader :operator + + # @return [CalculationValue] + attr_reader :left + + # @return [CalculationValue] + attr_reader :right + + # @return [::Boolean] + def ==(other) + other.is_a?(Sass::CalculationValue::CalculationOperation) && + other.operator == operator && + other.left == left && + other.right == right + end + + # @return [Integer] + def hash + @hash ||= [operator, left, right].hash + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/canonicalize_context.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/canonicalize_context.rb new file mode 100644 index 0000000..2f48dc8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/canonicalize_context.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Sass + # Contextual information passed to `canonicalize` and `find_file_url`. + # Not all importers will need this information to resolve loads, but some may find it useful. + # + # @see https://sass-lang.com/documentation/js-api/interfaces/canonicalizecontext/ + class CanonicalizeContext + # @return [String, nil] + def containing_url + @containing_url_unused = false + @containing_url + end + + # @return [Boolean] + attr_reader :from_import + + # @!visibility private + def initialize(canonicalize_request) + @containing_url_unused = true + @containing_url = canonicalize_request.containing_url == '' ? nil : canonicalize_request.containing_url + @from_import = canonicalize_request.from_import + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/cli.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/cli.rb new file mode 100644 index 0000000..e98400b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/cli.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Sass + module CLI + COMMAND = [ + File.absolute_path('dart-sass/src/dart', __dir__).freeze, + File.absolute_path('dart-sass/src/sass.snapshot', __dir__).freeze + ].freeze + end + + private_constant :CLI +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compile_result.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compile_result.rb new file mode 100644 index 0000000..9ed7a92 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compile_result.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Sass + # The result of compiling Sass to CSS. Returned by {Sass.compile} and {Sass.compile_string}. + # + # @see https://sass-lang.com/documentation/js-api/interfaces/compileresult/ + class CompileResult + # @return [String] + attr_reader :css + + # @return [String, nil] + attr_reader :source_map + + # @return [Array] + attr_reader :loaded_urls + + # @!visibility private + def initialize(css, source_map, loaded_urls) + @css = css + @source_map = source_map + @loaded_urls = loaded_urls + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler.rb new file mode 100644 index 0000000..2675d2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler.rb @@ -0,0 +1,214 @@ +# frozen_string_literal: true + +require_relative 'canonicalize_context' +require_relative 'compile_result' +require_relative 'compiler/channel' +require_relative 'compiler/connection' +require_relative 'compiler/dispatcher' +require_relative 'compiler/session' +require_relative 'compiler/varint' +require_relative 'embedded/version' +require_relative 'embedded_protocol' +require_relative 'exception' +require_relative 'fork_tracker' +require_relative 'gem_package_importer' +require_relative 'logger/silent' +require_relative 'logger/source_location' +require_relative 'logger/source_span' +require_relative 'node_package_importer' +require_relative 'serializer' +require_relative 'uri' +require_relative 'value' + +module Sass + # A synchronous {Compiler}. + # Each compiler instance exposes the {#compile} and {#compile_string} methods within the lifespan of the compiler. + # + # @example + # sass = Sass::Compiler.new + # result = sass.compile_string('h1 { font-size: 40px; }') + # result = sass.compile('style.scss') + # sass.close + # @see https://sass-lang.com/documentation/js-api/classes/compiler/ + class Compiler + def initialize + @channel = Channel.new + end + + # Compiles the Sass file at +path+ to CSS. + # @param path [String] + # @param load_paths [Array] Paths in which to look for stylesheets loaded by rules like + # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/]. + # @param charset [Boolean] By default, if the CSS document contains non-ASCII characters, Sass adds a +@charset+ + # declaration (in expanded output mode) or a byte-order mark (in compressed mode) to indicate its encoding to + # browsers or other consumers. If +charset+ is +false+, these annotations are omitted. + # @param source_map [Boolean] Whether or not Sass should generate a source map. + # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map. + # @param style [Symbol] The OutputStyle of the compiled CSS. + # @param functions [Hash] Additional built-in Sass functions that are available in all stylesheets. + # @param importers [Array] Custom importers that control how Sass resolves loads from rules like + # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/]. + # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error + # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well. + # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and + # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or + # not to use colors depending on whether the user is using an interactive terminal. + # @param fatal_deprecations [Array] A set of deprecations to treat as fatal. + # @param future_deprecations [Array] A set of future deprecations to opt into early. + # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass. + # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by + # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+. + # Stylesheets that are imported relative to the entrypoint are not considered dependencies. + # @param silence_deprecations [Array] A set of active deprecations to ignore. + # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per + # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every + # deprecation warning it encounters. + # @return [CompileResult] + # @raise [ArgumentError, CompileError, IOError] + # @see https://sass-lang.com/documentation/js-api/functions/compile/ + def compile(path, + load_paths: [], + + charset: true, + source_map: false, + source_map_include_sources: false, + style: :expanded, + + functions: {}, + importers: [], + + alert_ascii: false, + alert_color: nil, + fatal_deprecations: [], + future_deprecations: [], + logger: nil, + quiet_deps: false, + silence_deprecations: [], + verbose: false) + raise ArgumentError, 'path must be set' if path.nil? + + Session.new(@channel).compile_request( + path:, + source: nil, + importer: nil, + load_paths:, + syntax: nil, + url: nil, + charset:, + source_map:, + source_map_include_sources:, + style:, + functions:, + importers:, + alert_color:, + alert_ascii:, + fatal_deprecations:, + future_deprecations:, + logger:, + quiet_deps:, + silence_deprecations:, + verbose: + ) + end + + # Compiles a stylesheet whose contents is +source+ to CSS. + # @param source [String] + # @param importer [Object] The importer to use to handle loads that are relative to the entrypoint stylesheet. + # @param load_paths [Array] Paths in which to look for stylesheets loaded by rules like + # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/]. + # @param syntax [Symbol] The Syntax to use to parse the entrypoint stylesheet. + # @param url [String] The canonical URL of the entrypoint stylesheet. If this is passed along with +importer+, it's + # used to resolve relative loads in the entrypoint stylesheet. + # @param charset [Boolean] By default, if the CSS document contains non-ASCII characters, Sass adds a +@charset+ + # declaration (in expanded output mode) or a byte-order mark (in compressed mode) to indicate its encoding to + # browsers or other consumers. If +charset+ is +false+, these annotations are omitted. + # @param source_map [Boolean] Whether or not Sass should generate a source map. + # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map. + # @param style [Symbol] The OutputStyle of the compiled CSS. + # @param functions [Hash] Additional built-in Sass functions that are available in all stylesheets. + # @param importers [Array] Custom importers that control how Sass resolves loads from rules like + # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/]. + # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error + # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well. + # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and + # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or + # not to use colors depending on whether the user is using an interactive terminal. + # @param fatal_deprecations [Array] A set of deprecations to treat as fatal. + # @param future_deprecations [Array] A set of future deprecations to opt into early. + # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass. + # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by + # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+. + # Stylesheets that are imported relative to the entrypoint are not considered dependencies. + # @param silence_deprecations [Array] A set of active deprecations to ignore. + # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per + # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every + # deprecation warning it encounters. + # @return [CompileResult] + # @raise [ArgumentError, CompileError, IOError] + # @see https://sass-lang.com/documentation/js-api/functions/compilestring/ + def compile_string(source, + importer: nil, + load_paths: [], + syntax: :scss, + url: nil, + + charset: true, + source_map: false, + source_map_include_sources: false, + style: :expanded, + + functions: {}, + importers: [], + + alert_ascii: false, + alert_color: nil, + fatal_deprecations: [], + future_deprecations: [], + logger: nil, + quiet_deps: false, + silence_deprecations: [], + verbose: false) + raise ArgumentError, 'source must be set' if source.nil? + + Session.new(@channel).compile_request( + path: nil, + source:, + importer:, + load_paths:, + syntax:, + url:, + charset:, + source_map:, + source_map_include_sources:, + style:, + functions:, + importers:, + alert_color:, + alert_ascii:, + fatal_deprecations:, + future_deprecations:, + logger:, + quiet_deps:, + silence_deprecations:, + verbose: + ) + end + + # @return [String] Information about the Sass implementation. + # @see https://sass-lang.com/documentation/js-api/variables/info/ + def info + @info ||= [ + ['sass-embedded', Embedded::VERSION, '(Embedded Host)', '[Ruby]'].join("\t"), + Session.new(@channel).version_request.join("\t") + ].join("\n").freeze + end + + def close + @channel.close + end + + def closed? + @channel.closed? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/channel.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/channel.rb new file mode 100644 index 0000000..51b46b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/channel.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Sass + class Compiler + # The {Channel} class. + # + # It manages the lifecycle of {Dispatcher}. + class Channel + def initialize(*args, **kwargs, &block) + @args = args + @kwargs = kwargs + @block = block + @dispatcher = Dispatcher.new(*@args, **@kwargs, &@block) + @mutex = Mutex.new + end + + def close + @mutex.synchronize do + unless @dispatcher.nil? + @dispatcher.close + @dispatcher = nil + end + end + end + + def closed? + @mutex.synchronize do + @dispatcher.nil? + end + end + + def stream(session) + @mutex.synchronize do + raise IOError, 'closed compiler' if @dispatcher.nil? + + Stream.new(@dispatcher, session) + rescue Errno::EBUSY + @dispatcher = Dispatcher.new(*@args, **@kwargs, &@block) + Stream.new(@dispatcher, session) + end + end + + # The {Stream} between {Dispatcher} and {Session}. + class Stream + attr_reader :id + + def initialize(dispatcher, session) + @dispatcher = dispatcher + @id = @dispatcher.subscribe(session) + end + + def close + @dispatcher.unsubscribe(@id) + end + + def error(...) + @dispatcher.error(...) + end + + def send_proto(...) + @dispatcher.send_proto(...) + end + end + + private_constant :Stream + end + + private_constant :Channel + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/connection.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/connection.rb new file mode 100644 index 0000000..50c722a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/connection.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require 'open3' + +require 'sass/cli' + +module Sass + class Compiler + # The stdio based {Connection} between the {Dispatcher} and the compiler. + # + # It runs the `sass --embedded` command. + class Connection + def initialize + @mutex = Mutex.new + @stdin, @stdout, @stderr, @wait_thread = Open3.popen3(*CLI::COMMAND, '--embedded', chdir: __dir__) + + @stdin.binmode + + # # https://dart.dev/tools/dart-devtools + # if %w[dart dartvm].include?(File.basename(CLI::COMMAND.first, '.exe')) && + # %w[--enable-vm-service --observe].intersect?(CLI::COMMAND.map { |argument| argument.partition('=').first }) + # Kernel.warn(@stdout.readline, uplevel: 0) + # Kernel.warn(@stdout.readline, uplevel: 0) + # end + + @stdout.binmode + + @wait_thread.name = "sass-embedded-process-waiter-#{id}" + end + + def id + @wait_thread.pid + end + + def listen(dispatcher) + Thread.new do + Thread.current.name = "sass-embedded-process-stdout-poller-#{id}" + loop do + length = Varint.read(@stdout) + id = Varint.read(@stdout) + proto = @stdout.read(length - Varint.length(id)) + dispatcher.receive_proto(id, proto) + end + rescue IOError, Errno::EBADF, Errno::EPROTO => e + dispatcher.error(e) + @mutex.synchronize do + @stdout.close + end + end + + Thread.new do + Thread.current.name = "sass-embedded-process-stderr-poller-#{id}" + loop do + Kernel.warn(@stderr.readline, uplevel: 0) + end + rescue IOError, Errno::EBADF + @mutex.synchronize do + @stderr.close + end + end + end + + def close + @mutex.synchronize do + @stdin.close + @wait_thread.join + @stdout.close + @stderr.close + end + end + + def closed? + @mutex.synchronize do + @stdin.closed? && !@wait_thread.alive? + end + end + + def write(id, proto) + buffer = [] + Varint.write(buffer, Varint.length(id) + proto.length) + Varint.write(buffer, id) + @mutex.synchronize do + @stdin.write(buffer.pack('C*'), proto) + end + end + end + + private_constant :Connection + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/dispatcher.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/dispatcher.rb new file mode 100644 index 0000000..202a2ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/dispatcher.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +module Sass + class Compiler + # The {Dispatcher} class. + # + # It dispatches messages between multiple instances of {Session} and a single {Connection} to the compiler. + class Dispatcher + def initialize(idle_timeout: 0) + @id = 1 + @observers = {}.compare_by_identity + @mutex = Mutex.new + @connection = Connection.new + @connection.listen(self) + ForkTracker.add(self) + + return unless idle_timeout.positive? + + @last_accessed_time = current_time + Thread.new do + Thread.current.name = "sass-embedded-connection-reaper-#{@connection.id}" + duration = idle_timeout + loop do + sleep(duration.negative? ? idle_timeout : duration) + break if @mutex.synchronize do + raise Errno::EBUSY if _closed? + + duration = idle_timeout - (current_time - @last_accessed_time) + duration.negative? && _idle? && _close + end + end + close + rescue Errno::EBUSY + # do nothing + end + end + + def subscribe(observer) + @mutex.synchronize do + raise Errno::EBUSY if _closed? + + id = @id + @id = id.next + @observers[id] = observer + id + end + end + + def unsubscribe(id) + @mutex.synchronize do + @observers.delete(id) + + return unless @observers.empty? + + if _closed? + Thread.new do + close + end + else + _idle + end + end + end + + def close + @mutex.synchronize do + _close + end + @connection.close + ForkTracker.delete(self) + end + + def closed? + @connection.closed? + end + + def error(error) + observers = @mutex.synchronize do + _close + @observers.values + end + + if observers.empty? + close + else + observers.each do |observer| + observer.error(error) + end + end + end + + def receive_proto(id, proto) + case id + when 1...0xffffffff + @mutex.synchronize { @observers[id] }&.receive_proto(proto) + when 0 + outbound_message = EmbeddedProtocol::OutboundMessage.decode(proto) + oneof = outbound_message.message + message = outbound_message.public_send(oneof) + @mutex.synchronize { @observers[message.id] }&.public_send(oneof, message) + when 0xffffffff + outbound_message = EmbeddedProtocol::OutboundMessage.decode(proto) + oneof = outbound_message.message + message = outbound_message.public_send(oneof) + raise Errno::EPROTO, message.message + else + raise Errno::EPROTO + end + end + + def send_proto(...) + @connection.write(...) + end + + private + + def current_time + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + + def _close + @id = 0xffffffff + end + + def _closed? + @id == 0xffffffff + end + + def _idle + @last_accessed_time = current_time if defined?(@last_accessed_time) + + @id = 1 + end + + def _idle? + @id == 1 + end + end + + private_constant :Dispatcher + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session.rb new file mode 100644 index 0000000..bc455e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session.rb @@ -0,0 +1,233 @@ +# frozen_string_literal: true + +require_relative 'session/function_registry' +require_relative 'session/importer_registry' +require_relative 'session/logger_registry' +require_relative 'session/path' +require_relative 'session/protofier' +require_relative 'session/stack_trace' +require_relative 'session/struct' + +module Sass + class Compiler + # The {Session} class. + # + # It communicates with {Dispatcher} and handles the host logic. + class Session + attr_writer :backtrace + + def initialize(channel) + @channel = channel + @backtrace = nil + end + + def compile_request(path:, + source:, + importer:, + load_paths:, + syntax:, + url:, + charset:, + source_map:, + source_map_include_sources:, + style:, + functions:, + importers:, + alert_ascii:, + alert_color:, + fatal_deprecations:, + future_deprecations:, + logger:, + quiet_deps:, + silence_deprecations:, + verbose:) + alert_color = Exception.to_tty? if alert_color.nil? + + @function_registry = FunctionRegistry.new(functions, session: self) + @importer_registry = ImporterRegistry.new(importers, load_paths, session: self) + @logger_registry = LoggerRegistry.new(logger) + + compile_request = EmbeddedProtocol::InboundMessage::CompileRequest.new( + string: unless source.nil? + EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new( + source: source.to_str, + url: url&.to_s, + syntax: @importer_registry.syntax_to_proto(syntax), + importer: (@importer_registry.register(importer) unless importer.nil?) + ) + end, + path: (File.absolute_path(path) unless path.nil?), + style: case style&.to_sym + when :expanded + EmbeddedProtocol::OutputStyle::EXPANDED + when :compressed + EmbeddedProtocol::OutputStyle::COMPRESSED + else + raise ArgumentError, 'style must be one of :expanded, :compressed' + end, + charset:, + source_map:, + source_map_include_sources:, + importers: @importer_registry.importers, + global_functions: @function_registry.global_functions, + alert_ascii:, + alert_color:, + fatal_deprecation: fatal_deprecations.map(&:to_s), + future_deprecation: future_deprecations.map(&:to_s), + quiet_deps:, + silent: logger == Logger.silent, + silence_deprecation: silence_deprecations.map(&:to_s), + verbose: + ) + + compile_response = await do + send_message(compile_request:) + end + + oneof = compile_response.result + result = compile_response.public_send(oneof) + case oneof + when :failure + compile_error = CompileError.new( + result.message, + result.formatted == '' ? nil : StackTrace.pretty_formatted!(+result.formatted, result.stack_trace), + result.stack_trace == '' ? nil : result.stack_trace, + result.span.nil? ? nil : Logger::SourceSpan.new(result.span), + compile_response.loaded_urls.to_a + ) + compile_error.set_backtrace(@backtrace) unless @backtrace.nil? + raise compile_error + when :success + CompileResult.new( + result.css, + result.source_map == '' ? nil : result.source_map, + compile_response.loaded_urls.to_a + ) + else + raise ArgumentError, "Unknown CompileResponse.result #{result}" + end + end + + def version_request + version_response = await0 do + send_message0(version_request: EmbeddedProtocol::InboundMessage::VersionRequest.new( + id: + )) + end + + info = [ + version_response.implementation_name, + version_response.implementation_version, + '(Sass Compiler)' + ] + + case version_response.implementation_name + when 'dart-sass' + info << (File.basename(CLI::COMMAND.first, '.exe') == 'node' ? '[JavaScript]' : '[Dart]') + end + + info + end + + def compile_response(message) + @result = message + @queue.close + end + + def version_response(message) + @result = message + @queue.close + end + + def error(message) + case message + when EmbeddedProtocol::ProtocolError + raise Errno::EPROTO, message.message + else + @error ||= message + @queue.close + end + end + + def log_event(message) + @logger_registry.log(message) + end + + def canonicalize_request(message) + send_message(canonicalize_response: @importer_registry.canonicalize(message)) + end + + def import_request(message) + send_message(import_response: @importer_registry.import(message)) + end + + def file_import_request(message) + send_message(file_import_response: @importer_registry.file_import(message)) + end + + def function_call_request(message) + send_message(function_call_response: @function_registry.function_call(message)) + end + + def receive_proto(proto) + @queue.push(proto) + end + + private + + def await0 + listen do + yield + + @queue.pop + end + end + + def await + listen do + yield + + while (proto = @queue.pop) + outbound_message = EmbeddedProtocol::OutboundMessage.decode(proto) + oneof = outbound_message.message + message = outbound_message.public_send(oneof) + public_send(oneof, message) + end + rescue Exception => e # rubocop:disable Lint/RescueException + @stream.error(e) + raise + end + end + + def listen + @queue = Queue.new + @stream = @channel.stream(self) + + yield + + raise @error if @error + + @result + ensure + @stream&.close + @queue&.close + end + + def id + @stream.id + end + + def send_message0(...) + inbound_message = EmbeddedProtocol::InboundMessage.new(...) + @stream.send_proto(0, EmbeddedProtocol::InboundMessage.encode(inbound_message)) + end + + def send_message(...) + inbound_message = EmbeddedProtocol::InboundMessage.new(...) + @stream.send_proto(id, EmbeddedProtocol::InboundMessage.encode(inbound_message)) + end + end + + private_constant :Session + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/function_registry.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/function_registry.rb new file mode 100644 index 0000000..65bfae2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/function_registry.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Session + # The {FunctionRegistry} class. + # + # It stores sass custom functions and handles function calls. + class FunctionRegistry + attr_reader :compile_context, :global_functions + + def initialize(functions, session:) + @compile_context = Object.new + @global_functions = functions.keys.map!(&:to_s) + @functions_by_name = functions.transform_keys do |signature| + signature = signature.to_s + index = signature.index('(') + if index + signature.slice(0, index) + else + signature + end + end + + @id = 0 + @functions_by_id = {}.compare_by_identity + @ids_by_function = {}.compare_by_identity + + @session = session + end + + def register(function) + @ids_by_function.fetch(function) do |fn| + id = @id + @id = id.next + + @functions_by_id[id] = fn + @ids_by_function[fn] = id + end + end + + def function_call(function_call_request) + oneof = function_call_request.identifier + identifier = function_call_request.public_send(oneof) + function = case oneof + when :name + @functions_by_name[identifier] + when :function_id + @functions_by_id[identifier] + else + raise ArgumentError, "Unknown FunctionCallRequest.identifier #{identifier}" + end + + arguments = function_call_request.arguments.map do |argument| + protofier.from_proto(argument) + end + + success = protofier.to_proto(function.call(arguments)) + accessed_argument_lists = arguments.filter_map do |argument| + if argument.is_a?(Sass::Value::ArgumentList) && argument.instance_variable_get(:@keywords_accessed) + argument.instance_variable_get(:@id) + end + end + + EmbeddedProtocol::InboundMessage::FunctionCallResponse.new( + id: function_call_request.id, + success:, + accessed_argument_lists: + ) + rescue StandardError => e + @session.backtrace = e.backtrace + EmbeddedProtocol::InboundMessage::FunctionCallResponse.new( + id: function_call_request.id, + error: if e.respond_to?(:detailed_message) + e.detailed_message(highlight: false) + else # TODO: remove once ruby 3.1 support is dropped + "#{e.message} (#{e.class.name})" + end + ) + end + + private + + def protofier + @protofier ||= Protofier.new(self) + end + end + + private_constant :FunctionRegistry + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/importer_registry.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/importer_registry.rb new file mode 100644 index 0000000..78168fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/importer_registry.rb @@ -0,0 +1,162 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Session + # The {ImporterRegistry} class. + # + # It stores importers and handles import requests. + class ImporterRegistry + attr_reader :importers + + def initialize(importers, load_paths, session:) + @id = 0 + @importers_by_id = {}.compare_by_identity + @importers = importers + .map { |importer| register(importer) } + .concat( + load_paths.map do |load_path| + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + path: File.absolute_path(load_path) + ) + end + ) + + @session = session + end + + IMPORTER_ATTRS = %i[non_canonical_scheme].freeze + + IMPORTER_METHODS = %i[canonicalize load find_file_url].freeze + + private_constant :IMPORTER_ATTRS, :IMPORTER_METHODS + + def register(importer) + if importer.is_a?(Sass::NodePackageImporter) + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + node_package_importer: EmbeddedProtocol::NodePackageImporter.new( + entry_point_directory: importer.instance_variable_get(:@entry_point_directory) + ) + ) + else + importer = Struct.new(importer, attrs: IMPORTER_ATTRS, methods: IMPORTER_METHODS) if importer.is_a?(::Hash) + + is_importer = importer.respond_to?(:canonicalize) && importer.respond_to?(:load) + is_file_importer = importer.respond_to?(:find_file_url) + + raise ArgumentError, 'importer must be an Importer or a FileImporter' if is_importer == is_file_importer + + id = @id + @id = id.next + + @importers_by_id[id] = importer + if is_importer + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + importer_id: id, + non_canonical_scheme: if importer.respond_to?(:non_canonical_scheme) + Array(importer.non_canonical_scheme) + else + [] + end + ) + else + EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new( + file_importer_id: id + ) + end + end + end + + def canonicalize(canonicalize_request) + importer = @importers_by_id[canonicalize_request.importer_id] + canonicalize_context = CanonicalizeContext.new(canonicalize_request) + url = importer.canonicalize(canonicalize_request.url, + canonicalize_context)&.to_s + + EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new( + id: canonicalize_request.id, + url:, + containing_url_unused: canonicalize_context.instance_variable_get(:@containing_url_unused) + ) + rescue StandardError => e + @session.backtrace = e.backtrace + EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new( + id: canonicalize_request.id, + error: if e.respond_to?(:detailed_message) + e.detailed_message(highlight: false) + else # TODO: remove once ruby 3.1 support is dropped + "#{e.message} (#{e.class.name})" + end + ) + end + + IMPORTER_RESULT_ATTRS = %i[contents syntax source_map_url].freeze + + private_constant :IMPORTER_RESULT_ATTRS + + def import(import_request) + importer = @importers_by_id[import_request.importer_id] + importer_result = importer.load(import_request.url) + importer_result = Struct.new(importer_result, attrs: IMPORTER_RESULT_ATTRS) if importer_result.is_a?(::Hash) + + EmbeddedProtocol::InboundMessage::ImportResponse.new( + id: import_request.id, + success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new( + contents: importer_result.contents.to_str, + syntax: syntax_to_proto(importer_result.syntax), + source_map_url: (importer_result.source_map_url&.to_s if importer_result.respond_to?(:source_map_url)) + ) + ) + rescue StandardError => e + @session.backtrace = e.backtrace + EmbeddedProtocol::InboundMessage::ImportResponse.new( + id: import_request.id, + error: if e.respond_to?(:detailed_message) + e.detailed_message(highlight: false) + else # TODO: remove once ruby 3.1 support is dropped + "#{e.message} (#{e.class.name})" + end + ) + end + + def file_import(file_import_request) + importer = @importers_by_id[file_import_request.importer_id] + canonicalize_context = CanonicalizeContext.new(file_import_request) + file_url = importer.find_file_url(file_import_request.url, + canonicalize_context)&.to_s + + EmbeddedProtocol::InboundMessage::FileImportResponse.new( + id: file_import_request.id, + file_url:, + containing_url_unused: canonicalize_context.instance_variable_get(:@containing_url_unused) + ) + rescue StandardError => e + @session.backtrace = e.backtrace + EmbeddedProtocol::InboundMessage::FileImportResponse.new( + id: file_import_request.id, + error: if e.respond_to?(:detailed_message) + e.detailed_message(highlight: false) + else # TODO: remove once ruby 3.1 support is dropped + "#{e.message} (#{e.class.name})" + end + ) + end + + def syntax_to_proto(syntax) + case syntax&.to_sym + when :scss + EmbeddedProtocol::Syntax::SCSS + when :indented + EmbeddedProtocol::Syntax::INDENTED + when :css + EmbeddedProtocol::Syntax::CSS + else + raise ArgumentError, 'syntax must be one of :scss, :indented, :css' + end + end + end + + private_constant :ImporterRegistry + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/logger_registry.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/logger_registry.rb new file mode 100644 index 0000000..402d4f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/logger_registry.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Session + # The {LoggerRegistry} class. + # + # It stores logger and handles log events. + class LoggerRegistry + LOGGER_METHODS = %i[debug warn].freeze + + private_constant :LOGGER_METHODS + + def initialize(logger) + logger = Struct.new(logger, methods: LOGGER_METHODS) if logger.is_a?(::Hash) + @logger = logger + @logger_respond_to_debug = logger.respond_to?(:debug) + @logger_respond_to_warn = logger.respond_to?(:warn) + end + + def log(event) + case event.type + when :DEBUG + if @logger_respond_to_debug + @logger.debug(event.message, DebugContext.new(event)) + else + Kernel.warn(Path.pretty_formatted!(+event.formatted, event.span.url)) + end + when :DEPRECATION_WARNING, :WARNING + if @logger_respond_to_warn + @logger.warn(event.message, WarnContext.new(event)) + else + Kernel.warn(StackTrace.pretty_formatted!(+event.formatted, event.stack_trace)) + end + else + raise ArgumentError, "Unknown LogEvent.type #{event.type}" + end + end + + # Contextual information passed to `debug`. + class DebugContext + # @return [Logger::SourceSpan, nil] + attr_reader :span + + def initialize(event) + @span = event.span.nil? ? nil : Logger::SourceSpan.new(event.span) + end + end + + private_constant :DebugContext + + # Contextual information passed to `warn`. + class WarnContext < DebugContext + # @return [Boolean] + attr_reader :deprecation + + # @return [String, nil] + attr_reader :deprecation_type + + # @return [String] + attr_reader :stack + + def initialize(event) + super + @deprecation = event.type == :DEPRECATION_WARNING + @deprecation_type = (event.deprecation_type if @deprecation) + @stack = event.stack_trace + end + end + + private_constant :WarnContext + end + + private_constant :LoggerRegistry + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/path.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/path.rb new file mode 100644 index 0000000..f5b109f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/path.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Session + # @see https://pub.dev/documentation/path/latest/path/ + module Path + module_function + + # @see https://pub.dev/documentation/path/latest/path/Context/prettyUri.html + def pretty_uri(uri) + return uri unless uri&.start_with?('file:') + + absolute_path = Uri.file_uri_to_path(uri) + relative_path = Uri.decode_uri_component(Uri.relative(uri, Uri.pwd)) + relative_path.count('/') > absolute_path.count('/') ? absolute_path : relative_path + end + + def pretty_formatted!(formatted, uri) + index = formatted.index(uri) + return formatted unless index + + replacement = pretty_uri(uri) + return formatted if uri == replacement + + formatted[index, uri.length] = replacement + formatted + end + end + + private_constant :Path + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/protofier.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/protofier.rb new file mode 100644 index 0000000..47d6688 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/protofier.rb @@ -0,0 +1,376 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Session + # The {Protofier} class. + # + # It converts Pure Ruby types and Protobuf Ruby types. + class Protofier + def initialize(function_registry) + @function_registry = function_registry + end + + def to_proto(obj) + case obj + when Sass::Value::String + EmbeddedProtocol::Value.new( + string: EmbeddedProtocol::Value::String.new( + text: obj.text.to_str, + quoted: obj.quoted? + ) + ) + when Sass::Value::Number + EmbeddedProtocol::Value.new( + number: Number.to_proto(obj) + ) + when Sass::Value::Color + EmbeddedProtocol::Value.new( + color: EmbeddedProtocol::Value::Color.new( + channel1: obj.send(:channel0_or_nil), + channel2: obj.send(:channel1_or_nil), + channel3: obj.send(:channel2_or_nil), + alpha: obj.send(:alpha_or_nil), + space: obj.space + ) + ) + when Sass::Value::ArgumentList + if obj.instance_variable_get(:@compile_context) == @function_registry.compile_context + EmbeddedProtocol::Value.new( + argument_list: EmbeddedProtocol::Value::ArgumentList.new( + id: obj.instance_variable_get(:@id) + ) + ) + else + EmbeddedProtocol::Value.new( + argument_list: EmbeddedProtocol::Value::ArgumentList.new( + contents: obj.to_a.map { |element| to_proto(element) }, + keywords: obj.keywords.each_with_object({}) { |(key, value), hash| hash[key.to_s] = to_proto(value) }, + separator: ListSeparator.to_proto(obj.separator) + ) + ) + end + when Sass::Value::List + EmbeddedProtocol::Value.new( + list: EmbeddedProtocol::Value::List.new( + contents: obj.to_a.map { |element| to_proto(element) }, + separator: ListSeparator.to_proto(obj.separator), + has_brackets: obj.bracketed? + ) + ) + when Sass::Value::Map + EmbeddedProtocol::Value.new( + map: EmbeddedProtocol::Value::Map.new( + entries: obj.contents.map do |key, value| + EmbeddedProtocol::Value::Map::Entry.new( + key: to_proto(key), + value: to_proto(value) + ) + end + ) + ) + when Sass::Value::Function + if obj.instance_variable_defined?(:@id) + EmbeddedProtocol::Value.new( + compiler_function: EmbeddedProtocol::Value::CompilerFunction.new( + id: assert_compiler_value(obj).instance_variable_get(:@id) + ) + ) + else + EmbeddedProtocol::Value.new( + host_function: EmbeddedProtocol::Value::HostFunction.new( + id: @function_registry.register(obj.callback), + signature: obj.signature + ) + ) + end + when Sass::Value::Mixin + EmbeddedProtocol::Value.new( + compiler_mixin: EmbeddedProtocol::Value::CompilerMixin.new( + id: assert_compiler_value(obj).instance_variable_get(:@id) + ) + ) + when Sass::Value::Calculation + EmbeddedProtocol::Value.new( + calculation: Calculation.to_proto(obj) + ) + when Sass::Value::Boolean + EmbeddedProtocol::Value.new( + singleton: obj.value ? :TRUE : :FALSE + ) + when Sass::Value::Null + EmbeddedProtocol::Value.new( + singleton: :NULL + ) + else + raise Sass::ScriptError, "Unknown Sass::Value #{obj}" + end + end + + def from_proto(proto) + oneof = proto.value + obj = proto.public_send(oneof) + case oneof + when :string + Sass::Value::String.new( + obj.text, + quoted: obj.quoted + ) + when :number + Number.from_proto(obj) + when :color + Sass::Value::Color.send( + :for_space, + obj.space, + obj.has_channel1? ? obj.channel1 : nil, + obj.has_channel2? ? obj.channel2 : nil, + obj.has_channel3? ? obj.channel3 : nil, + obj.has_alpha? ? obj.alpha : nil + ) + when :argument_list + compiler_value( + Sass::Value::ArgumentList.new( + obj.contents.map do |element| + from_proto(element) + end, + obj.keywords.to_enum.with_object({}) do |(key, value), hash| + hash[key.to_sym] = from_proto(value) + end, + ListSeparator.from_proto(obj.separator) + ), + obj.id + ) + when :list + Sass::Value::List.new( + obj.contents.map do |element| + from_proto(element) + end, + separator: ListSeparator.from_proto(obj.separator), + bracketed: obj.has_brackets + ) + when :map + Sass::Value::Map.new( + obj.entries.to_enum.with_object({}) do |entry, hash| + hash[from_proto(entry.key)] = from_proto(entry.value) + end + ) + when :compiler_function + compiler_value(Sass::Value::Function.allocate, obj.id) + when :host_function + raise Sass::ScriptError, 'The compiler may not send Value.host_function to host' + when :compiler_mixin + compiler_value(Sass::Value::Mixin.allocate, obj.id) + when :calculation + Calculation.from_proto(obj) + when :singleton + case obj + when :TRUE + Sass::Value::Boolean::TRUE + when :FALSE + Sass::Value::Boolean::FALSE + when :NULL + Sass::Value::Null::NULL + else + raise Sass::ScriptError, "Unknown Value.singleton #{obj}" + end + else + raise Sass::ScriptError, "Unknown Value.value #{obj}" + end + end + + private + + def assert_compiler_value(value) + unless value.instance_variable_get(:@compile_context) == @function_registry.compile_context + raise Sass::ScriptError, "Value #{value} does not belong to this compilation" + end + + value + end + + def compiler_value(value, id) + value.instance_variable_set(:@compile_context, @function_registry.compile_context) + value.instance_variable_set(:@id, id) + value + end + + # The {Number} Protofier. + module Number + module_function + + def to_proto(obj) + EmbeddedProtocol::Value::Number.new( + value: obj.value.to_f, + numerators: obj.numerator_units, + denominators: obj.denominator_units + ) + end + + def from_proto(obj) + Sass::Value::Number.new( + obj.value, { + numerator_units: obj.numerators.to_a, + denominator_units: obj.denominators.to_a + } + ) + end + end + + private_constant :Number + + # The {Calculation} Protofier. + module Calculation + module_function + + def to_proto(obj) + EmbeddedProtocol::Value::Calculation.new( + name: obj.name, + arguments: obj.arguments.map { |argument| CalculationValue.to_proto(argument) } + ) + end + + def from_proto(obj) + Sass::Value::Calculation.send( + :new, + obj.name, + obj.arguments.map { |argument| CalculationValue.from_proto(argument) } + ) + end + end + + private_constant :Calculation + + # The {CalculationValue} Protofier. + module CalculationValue + module_function + + def to_proto(value) + case value + when Sass::Value::Number + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + number: Number.to_proto(value) + ) + when Sass::Value::Calculation + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + calculation: Calculation.to_proto(value) + ) + when Sass::Value::String + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + string: value.text + ) + when Sass::CalculationValue::CalculationOperation + EmbeddedProtocol::Value::Calculation::CalculationValue.new( + operation: EmbeddedProtocol::Value::Calculation::CalculationOperation.new( + operator: CalculationOperator.to_proto(value.operator), + left: to_proto(value.left), + right: to_proto(value.right) + ) + ) + else + raise Sass::ScriptError, "Unknown CalculationValue #{value}" + end + end + + def from_proto(value) + oneof = value.value + obj = value.public_send(oneof) + case oneof + when :number + Number.from_proto(obj) + when :calculation + Calculation.from_proto(obj) + when :string + Sass::Value::String.new(obj, quoted: false) + when :operation + Sass::CalculationValue::CalculationOperation.new( + CalculationOperator.from_proto(obj.operator), + from_proto(obj.left), + from_proto(obj.right) + ) + else + raise Sass::ScriptError, "Unknown CalculationValue #{value}" + end + end + end + + private_constant :CalculationValue + + # The {CalculationOperator} Protofier. + module CalculationOperator + module_function + + def to_proto(operator) + case operator + when '+' + :PLUS + when '-' + :MINUS + when '*' + :TIMES + when '/' + :DIVIDE + else + raise Sass::ScriptError, "Unknown CalculationOperator #{separator}" + end + end + + def from_proto(operator) + case operator + when :PLUS + '+' + when :MINUS + '-' + when :TIMES + '*' + when :DIVIDE + '/' + else + raise Sass::ScriptError, "Unknown CalculationOperator #{separator}" + end + end + end + + private_constant :CalculationOperator + + # The {ListSeparator} Protofier. + module ListSeparator + module_function + + def to_proto(separator) + case separator + when ',' + :COMMA + when ' ' + :SPACE + when '/' + :SLASH + when nil + :UNDECIDED + else + raise Sass::ScriptError, "Unknown ListSeparator #{separator}" + end + end + + def from_proto(separator) + case separator + when :COMMA + ',' + when :SPACE + ' ' + when :SLASH + '/' + when :UNDECIDED + nil + else + raise Sass::ScriptError, "Unknown ListSeparator #{separator}" + end + end + end + + private_constant :ListSeparator + end + + private_constant :Protofier + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/stack_trace.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/stack_trace.rb new file mode 100644 index 0000000..1768e04 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/stack_trace.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Session + # @see https://pub.dev/documentation/stack_trace/latest/stack_trace/ + module StackTrace + module_function + + # @see https://pub.dev/documentation/stack_trace/latest/stack_trace/Trace/toString.html + def pretty_formatted!(formatted, stack_trace) + longest = 0 + + frames = stack_trace.lines("\n", chomp: true).map do |frame| + location, member = frame.split(/ +/, 2) + uri, line_column = location.split(' ', 2) + + uri = Path.pretty_uri(uri) + location = line_column.nil? ? uri : "#{uri} #{line_column}" + + longest = location.length if location.length > longest + [frame, location, member] + end + + offset = formatted.length + + frames.reverse_each do |frame, location, member| + index = formatted.rindex(frame, offset) + next unless index + + offset = index + + replacement = "#{location.ljust(longest)} #{member}" + next if frame == replacement + + formatted[index, frame.length] = replacement + end + + formatted + end + end + + private_constant :StackTrace + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/struct.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/struct.rb new file mode 100644 index 0000000..a5d3e81 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/session/struct.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Sass + class Compiler + class Session + # The {Struct} class. + # + # It creates {::Struct}-like objects from {::Hash}. + class Struct + def initialize(hash, attrs: nil, methods: nil) + @hash = hash + @attrs = attrs + @methods = methods + end + + def method_missing(symbol, ...) + return super unless @hash.key?(symbol) + + if @attrs&.include?(symbol) + @hash.send(:[], symbol, ...) + elsif @methods&.include?(symbol) + @hash[symbol].call(...) + else + super + end + end + + def respond_to_missing?(symbol, _include_all) + @hash.key?(symbol) && (@attrs&.include?(symbol) || @methods&.include?(symbol)) + end + end + + private_constant :Struct + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/varint.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/varint.rb new file mode 100644 index 0000000..7987779 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/compiler/varint.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Sass + class Compiler + # The {Varint} module. + # + # It reads and writes varints. + module Varint + module_function + + def length(value) + return 1 if value < 128 + + (value.bit_length + 6) / 7 + end + + def read(readable) + value = bits = 0 + loop do + byte = readable.readbyte + value |= (byte & 0x7f) << bits + bits += 7 + break if byte < 0x80 + end + value + end + + def write(writeable, value) + until value < 0x80 + writeable << ((value & 0x7f) | 0x80) + value >>= 7 + end + writeable << value + end + end + + private_constant :Varint + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/sass b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/sass new file mode 100755 index 0000000..cb4fd25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/sass @@ -0,0 +1,20 @@ +#!/bin/sh + +# This script drives the standalone dart-sass package, which bundles together a +# Dart executable and a snapshot of dart-sass. + +follow_links() { + # Use `readlink -f` if it exists, but fall back to manually following symlnks + # for systems (like older Mac OS) where it doesn't. + file="$1" + if readlink -f "$file" 2>&-; then return; fi + + while [ -h "$file" ]; do + file="$(readlink "$file")" + done + echo "$file" +} + +# Unlike $0, $BASH_SOURCE points to the absolute path of this file. +path=`dirname "$(follow_links "$0")"` +exec "$path/src/dart" "$path/src/sass.snapshot" "$@" diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/LICENSE b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/LICENSE new file mode 100644 index 0000000..5ebf51b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/LICENSE @@ -0,0 +1,1720 @@ +Dart Sass license: + +Copyright (c) 2016, Google Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------------------------------------------------------------------- + +Dart SDK license: + +Copyright 2012, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +_fe_analyzer_shared license: + +Copyright 2019, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +analyzer, protobuf and protoc_plugin license: + +Copyright 2013, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +archive license: + +The MIT License + +Copyright (c) 2013-2021 Brendan Duncan. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +-------------------------------------------------------------------------------- + +args, csslib and logging license: + +Copyright 2013, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +async, cli_util, collection, mime, stream_channel and typed_data license: + +Copyright 2015, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +boolean_selector, meta and shelf_packages_handler license: + +Copyright 2016, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +charcode license: + +Copyright 2014, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +checked_yaml license: + +Copyright 2019, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +cli_config license: + +Copyright 2023, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------------------- + +cli_pkg license: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +-------------------------------------------------------------------------------- + +cli_repl license: + +Copyright (c) 2018, Jennifer Thakar. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the project nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +convert, crypto, shelf_static, source_map_stack_trace and vm_service license: + +Copyright 2015, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +coverage, dart_style, dartdoc, glob, http, http_parser, matcher, path, pool, +pub_semver, source_span, string_scanner, test and watcher license: + +Copyright 2014, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +dart_mappable and type_plus license: + +MIT License + +Copyright (c) 2021 Kilian Schulte + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +-------------------------------------------------------------------------------- + +ffi and package_config license: + +Copyright 2019, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +file license: + +Copyright 2017, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------------------- + +fixnum, http_multi_server, oauth2, shelf, shelf_web_socket, source_maps and +stack_trace license: + +Copyright 2014, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +frontend_server_client license: + +Copyright 2020, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +grinder and webkit_inspection_protocol license: + +Copyright 2013, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +html license: + +Copyright (c) 2006-2012 The Authors + +Contributors: +James Graham - jg307@cam.ac.uk +Anne van Kesteren - annevankesteren@gmail.com +Lachlan Hunt - lachlan.hunt@lachy.id.au +Matt McDonald - kanashii@kanashii.ca +Sam Ruby - rubys@intertwingly.net +Ian Hickson (Google) - ian@hixie.ch +Thomas Broyer - t.broyer@ltgt.net +Jacques Distler - distler@golem.ph.utexas.edu +Henri Sivonen - hsivonen@iki.fi +Adam Barth - abarth@webkit.org +Eric Seidel - eric@webkit.org +The Mozilla Foundation (contributions from Henri Sivonen since 2008) +David Flanagan (Mozilla) - dflanagan@mozilla.com +Google LLC (contributed the Dart port) - misc@dartlang.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------------------------------------------------------------------- + +io, stream_transform and term_glyph license: + +Copyright 2017, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +js license: + +Copyright 2012, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +json_annotation license: + +Copyright 2017, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +lints license: + +Copyright 2021, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +markdown license: + +Copyright 2012, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +native_stack_traces license: + +Copyright 2020, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +native_synchronization license: + +Copyright 2023, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +node_interop license: + +Copyright (c) 2017, Anatoly Pulyaevskiy. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +node_preamble license: + +The MIT License (MIT) + +Copyright (c) 2015 Michael Bullington + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +=== + +Copyright 2012, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +petitparser license: + +The MIT License + +Copyright (c) 2006-2024 Lukas Renggli. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +-------------------------------------------------------------------------------- + +posix license: + +MIT License + +Copyright (c) 2020 Brett Sutton + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------------------------------------------------------------------- + +pub_api_client license: + +MIT License + +Copyright (c) 2020 Leo Farias + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------------------------------------------------------------------- + +pubspec_parse license: + +Copyright 2018, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +retry license: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------- + +test_api and test_core license: + +Copyright 2018, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +test_descriptor and web_socket_channel license: + +Copyright 2016, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +test_process license: + +Copyright 2017, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +web license: + +Copyright 2023, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +web_socket license: + +Copyright 2024, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- + +xml license: + +The MIT License + +Copyright (c) 2006-2025 Lukas Renggli. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +-------------------------------------------------------------------------------- + +yaml license: + +Copyright (c) 2014, the Dart project authors. +Copyright (c) 2006, Kirill Simonov. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/dart b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/dart new file mode 100755 index 0000000..5b87007 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/dart differ diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/sass.snapshot b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/sass.snapshot new file mode 100644 index 0000000..a454c62 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/dart-sass/src/sass.snapshot differ diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/elf.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/elf.rb new file mode 100644 index 0000000..1305caa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/elf.rb @@ -0,0 +1,386 @@ +# frozen_string_literal: true + +module Sass + # The {ELF} class. + # + # It parses ELF header to extract interpreter. + # @see https://github.com/torvalds/linux/blob/HEAD/include/uapi/linux/elf.h + # @see https://github.com/torvalds/linux/blob/HEAD/kernel/kexec_elf.c + class ELF + # The {PackInfo} class. + class PackInfo + def initialize(format:, sizeof:, struct:) + @format_le = format.freeze + @format_be = format.tr('<', '>').freeze + @sizeof = sizeof.freeze + @struct = struct.freeze + end + + attr_reader :sizeof + + def pack(io, data, little_endian) + raise ArgumentError if io.write(data.values_at(*@struct).pack(format(little_endian))) != @sizeof + end + + def unpack(io, little_endian) + @struct.zip(io.read(@sizeof).unpack(format(little_endian))).to_h + end + + private + + def format(little_endian) + little_endian ? @format_le : @format_be + end + end + + private_constant :PackInfo + + # These constants are for the segment types stored in the image headers + PT_NULL = 0 + PT_LOAD = 1 + PT_DYNAMIC = 2 + PT_INTERP = 3 + PT_NOTE = 4 + PT_SHLIB = 5 + PT_PHDR = 6 + PT_TLS = 7 + PT_LOOS = 0x60000000 + PT_HIOS = 0x6fffffff + PT_LOPROC = 0x70000000 + PT_HIPROC = 0x7fffffff + + PN_XNUM = 0xffff + + # These constants define the different elf file types + ET_NONE = 0 + ET_REL = 1 + ET_EXEC = 2 + ET_DYN = 3 + ET_CORE = 4 + ET_LOPROC = 0xff00 + ET_HIPROC = 0xffff + + EI_NIDENT = 16 + + Elf32_Ehdr = PackInfo.new( + format: "a#{EI_NIDENT}S<2L<5S<6", + sizeof: 52, + struct: %i[ + e_ident + e_type + e_machine + e_version + e_entry + e_phoff + e_shoff + e_flags + e_ehsize + e_phentsize + e_phnum + e_shentsize + e_shnum + e_shstrndx + ] + ).freeze + + Elf64_Ehdr = PackInfo.new( + format: "a#{EI_NIDENT}S<2L.sass.embedded_protocol.InboundMessage.CompileRequest.Importer\x12\x18\n\x10global_functions\x18\x07 \x03(\t\x12\x13\n\x0b\x61lert_color\x18\x08 \x01(\x08\x12\x13\n\x0b\x61lert_ascii\x18\t \x01(\x08\x12\x0f\n\x07verbose\x18\n \x01(\x08\x12\x12\n\nquiet_deps\x18\x0b \x01(\x08\x12\"\n\x1asource_map_include_sources\x18\x0c \x01(\x08\x12\x0f\n\x07\x63harset\x18\r \x01(\x08\x12\x0e\n\x06silent\x18\x0e \x01(\x08\x12\x19\n\x11\x66\x61tal_deprecation\x18\x0f \x03(\t\x12\x1b\n\x13silence_deprecation\x18\x10 \x03(\t\x12\x1a\n\x12\x66uture_deprecation\x18\x11 \x03(\t\x1a\xac\x01\n\x0bStringInput\x12\x0e\n\x06source\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12.\n\x06syntax\x18\x03 \x01(\x0e\x32\x1e.sass.embedded_protocol.Syntax\x12P\n\x08importer\x18\x04 \x01(\x0b\x32>.sass.embedded_protocol.InboundMessage.CompileRequest.Importer\x1a\xc5\x01\n\x08Importer\x12\x0e\n\x04path\x18\x01 \x01(\tH\x00\x12\x15\n\x0bimporter_id\x18\x02 \x01(\rH\x00\x12\x1a\n\x10\x66ile_importer_id\x18\x03 \x01(\rH\x00\x12L\n\x15node_package_importer\x18\x05 \x01(\x0b\x32+.sass.embedded_protocol.NodePackageImporterH\x00\x12\x1c\n\x14non_canonical_scheme\x18\x04 \x03(\tB\n\n\x08importerB\x07\n\x05inputJ\x04\x08\x01\x10\x02\x1ak\n\x14\x43\x61nonicalizeResponse\x12\n\n\x02id\x18\x01 \x01(\r\x12\r\n\x03url\x18\x02 \x01(\tH\x00\x12\x0f\n\x05\x65rror\x18\x03 \x01(\tH\x00\x12\x1d\n\x15\x63ontaining_url_unused\x18\x04 \x01(\x08\x42\x08\n\x06result\x1a\x93\x02\n\x0eImportResponse\x12\n\n\x02id\x18\x01 \x01(\r\x12V\n\x07success\x18\x02 \x01(\x0b\x32\x43.sass.embedded_protocol.InboundMessage.ImportResponse.ImportSuccessH\x00\x12\x0f\n\x05\x65rror\x18\x03 \x01(\tH\x00\x1a\x81\x01\n\rImportSuccess\x12\x10\n\x08\x63ontents\x18\x01 \x01(\t\x12.\n\x06syntax\x18\x02 \x01(\x0e\x32\x1e.sass.embedded_protocol.Syntax\x12\x1b\n\x0esource_map_url\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x11\n\x0f_source_map_urlB\x08\n\x06result\x1an\n\x12\x46ileImportResponse\x12\n\n\x02id\x18\x01 \x01(\r\x12\x12\n\x08\x66ile_url\x18\x02 \x01(\tH\x00\x12\x0f\n\x05\x65rror\x18\x03 \x01(\tH\x00\x12\x1d\n\x15\x63ontaining_url_unused\x18\x04 \x01(\x08\x42\x08\n\x06result\x1a\x90\x01\n\x14\x46unctionCallResponse\x12\n\n\x02id\x18\x01 \x01(\r\x12\x30\n\x07success\x18\x02 \x01(\x0b\x32\x1d.sass.embedded_protocol.ValueH\x00\x12\x0f\n\x05\x65rror\x18\x03 \x01(\tH\x00\x12\x1f\n\x17\x61\x63\x63\x65ssed_argument_lists\x18\x04 \x03(\rB\x08\n\x06resultB\t\n\x07message\"\xcb\x0f\n\x0fOutboundMessage\x12\x36\n\x05\x65rror\x18\x01 \x01(\x0b\x32%.sass.embedded_protocol.ProtocolErrorH\x00\x12S\n\x10\x63ompile_response\x18\x02 \x01(\x0b\x32\x37.sass.embedded_protocol.OutboundMessage.CompileResponseH\x00\x12\x45\n\tlog_event\x18\x03 \x01(\x0b\x32\x30.sass.embedded_protocol.OutboundMessage.LogEventH\x00\x12[\n\x14\x63\x61nonicalize_request\x18\x04 \x01(\x0b\x32;.sass.embedded_protocol.OutboundMessage.CanonicalizeRequestH\x00\x12O\n\x0eimport_request\x18\x05 \x01(\x0b\x32\x35.sass.embedded_protocol.OutboundMessage.ImportRequestH\x00\x12X\n\x13\x66ile_import_request\x18\x06 \x01(\x0b\x32\x39.sass.embedded_protocol.OutboundMessage.FileImportRequestH\x00\x12\\\n\x15\x66unction_call_request\x18\x07 \x01(\x0b\x32;.sass.embedded_protocol.OutboundMessage.FunctionCallRequestH\x00\x12S\n\x10version_response\x18\x08 \x01(\x0b\x32\x37.sass.embedded_protocol.OutboundMessage.VersionResponseH\x00\x1a\x8e\x01\n\x0fVersionResponse\x12\n\n\x02id\x18\x05 \x01(\r\x12\x18\n\x10protocol_version\x18\x01 \x01(\t\x12\x18\n\x10\x63ompiler_version\x18\x02 \x01(\t\x12\x1e\n\x16implementation_version\x18\x03 \x01(\t\x12\x1b\n\x13implementation_name\x18\x04 \x01(\t\x1a\xa2\x03\n\x0f\x43ompileResponse\x12Y\n\x07success\x18\x02 \x01(\x0b\x32\x46.sass.embedded_protocol.OutboundMessage.CompileResponse.CompileSuccessH\x00\x12Y\n\x07\x66\x61ilure\x18\x03 \x01(\x0b\x32\x46.sass.embedded_protocol.OutboundMessage.CompileResponse.CompileFailureH\x00\x12\x13\n\x0bloaded_urls\x18\x04 \x03(\t\x1a\x37\n\x0e\x43ompileSuccess\x12\x0b\n\x03\x63ss\x18\x01 \x01(\t\x12\x12\n\nsource_map\x18\x02 \x01(\tJ\x04\x08\x03\x10\x04\x1a{\n\x0e\x43ompileFailure\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x30\n\x04span\x18\x02 \x01(\x0b\x32\".sass.embedded_protocol.SourceSpan\x12\x13\n\x0bstack_trace\x18\x03 \x01(\t\x12\x11\n\tformatted\x18\x04 \x01(\tB\x08\n\x06resultJ\x04\x08\x01\x10\x02\x1a\xf1\x01\n\x08LogEvent\x12\x32\n\x04type\x18\x02 \x01(\x0e\x32$.sass.embedded_protocol.LogEventType\x12\x0f\n\x07message\x18\x03 \x01(\t\x12\x35\n\x04span\x18\x04 \x01(\x0b\x32\".sass.embedded_protocol.SourceSpanH\x00\x88\x01\x01\x12\x13\n\x0bstack_trace\x18\x05 \x01(\t\x12\x11\n\tformatted\x18\x06 \x01(\t\x12\x1d\n\x10\x64\x65precation_type\x18\x07 \x01(\tH\x01\x88\x01\x01\x42\x07\n\x05_spanB\x13\n\x11_deprecation_typeJ\x04\x08\x01\x10\x02\x1a\x8e\x01\n\x13\x43\x61nonicalizeRequest\x12\n\n\x02id\x18\x01 \x01(\r\x12\x13\n\x0bimporter_id\x18\x03 \x01(\r\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\x13\n\x0b\x66rom_import\x18\x05 \x01(\x08\x12\x1b\n\x0e\x63ontaining_url\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x11\n\x0f_containing_urlJ\x04\x08\x02\x10\x03\x1a\x43\n\rImportRequest\x12\n\n\x02id\x18\x01 \x01(\r\x12\x13\n\x0bimporter_id\x18\x03 \x01(\r\x12\x0b\n\x03url\x18\x04 \x01(\tJ\x04\x08\x02\x10\x03\x1a\x8c\x01\n\x11\x46ileImportRequest\x12\n\n\x02id\x18\x01 \x01(\r\x12\x13\n\x0bimporter_id\x18\x03 \x01(\r\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\x13\n\x0b\x66rom_import\x18\x05 \x01(\x08\x12\x1b\n\x0e\x63ontaining_url\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x11\n\x0f_containing_urlJ\x04\x08\x02\x10\x03\x1a\x8e\x01\n\x13\x46unctionCallRequest\x12\n\n\x02id\x18\x01 \x01(\r\x12\x0e\n\x04name\x18\x03 \x01(\tH\x00\x12\x15\n\x0b\x66unction_id\x18\x04 \x01(\rH\x00\x12\x30\n\targuments\x18\x05 \x03(\x0b\x32\x1d.sass.embedded_protocol.ValueB\x0c\n\nidentifierJ\x04\x08\x02\x10\x03\x42\t\n\x07message\"e\n\rProtocolError\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).sass.embedded_protocol.ProtocolErrorType\x12\n\n\x02id\x18\x02 \x01(\r\x12\x0f\n\x07message\x18\x03 \x01(\t\"\x87\x02\n\nSourceSpan\x12\x0c\n\x04text\x18\x01 \x01(\t\x12@\n\x05start\x18\x02 \x01(\x0b\x32\x31.sass.embedded_protocol.SourceSpan.SourceLocation\x12\x43\n\x03\x65nd\x18\x03 \x01(\x0b\x32\x31.sass.embedded_protocol.SourceSpan.SourceLocationH\x00\x88\x01\x01\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\x0f\n\x07\x63ontext\x18\x05 \x01(\t\x1a>\n\x0eSourceLocation\x12\x0e\n\x06offset\x18\x01 \x01(\r\x12\x0c\n\x04line\x18\x02 \x01(\r\x12\x0e\n\x06\x63olumn\x18\x03 \x01(\rB\x06\n\x04_end\"\xf8\x11\n\x05Value\x12\x36\n\x06string\x18\x01 \x01(\x0b\x32$.sass.embedded_protocol.Value.StringH\x00\x12\x36\n\x06number\x18\x02 \x01(\x0b\x32$.sass.embedded_protocol.Value.NumberH\x00\x12\x32\n\x04list\x18\x05 \x01(\x0b\x32\".sass.embedded_protocol.Value.ListH\x00\x12\x30\n\x03map\x18\x06 \x01(\x0b\x32!.sass.embedded_protocol.Value.MapH\x00\x12;\n\tsingleton\x18\x07 \x01(\x0e\x32&.sass.embedded_protocol.SingletonValueH\x00\x12K\n\x11\x63ompiler_function\x18\x08 \x01(\x0b\x32..sass.embedded_protocol.Value.CompilerFunctionH\x00\x12\x43\n\rhost_function\x18\t \x01(\x0b\x32*.sass.embedded_protocol.Value.HostFunctionH\x00\x12\x43\n\rargument_list\x18\n \x01(\x0b\x32*.sass.embedded_protocol.Value.ArgumentListH\x00\x12@\n\x0b\x63\x61lculation\x18\x0c \x01(\x0b\x32).sass.embedded_protocol.Value.CalculationH\x00\x12\x45\n\x0e\x63ompiler_mixin\x18\r \x01(\x0b\x32+.sass.embedded_protocol.Value.CompilerMixinH\x00\x12\x34\n\x05\x63olor\x18\x0e \x01(\x0b\x32#.sass.embedded_protocol.Value.ColorH\x00\x1a&\n\x06String\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x0e\n\x06quoted\x18\x02 \x01(\x08\x1a\x41\n\x06Number\x12\r\n\x05value\x18\x01 \x01(\x01\x12\x12\n\nnumerators\x18\x02 \x03(\t\x12\x14\n\x0c\x64\x65nominators\x18\x03 \x03(\t\x1a\xa0\x01\n\x05\x43olor\x12\r\n\x05space\x18\x01 \x01(\t\x12\x15\n\x08\x63hannel1\x18\x02 \x01(\x01H\x00\x88\x01\x01\x12\x15\n\x08\x63hannel2\x18\x03 \x01(\x01H\x01\x88\x01\x01\x12\x15\n\x08\x63hannel3\x18\x04 \x01(\x01H\x02\x88\x01\x01\x12\x12\n\x05\x61lpha\x18\x05 \x01(\x01H\x03\x88\x01\x01\x42\x0b\n\t_channel1B\x0b\n\t_channel2B\x0b\n\t_channel3B\x08\n\x06_alpha\x1a\x87\x01\n\x04List\x12\x38\n\tseparator\x18\x01 \x01(\x0e\x32%.sass.embedded_protocol.ListSeparator\x12\x14\n\x0chas_brackets\x18\x02 \x01(\x08\x12/\n\x08\x63ontents\x18\x03 \x03(\x0b\x32\x1d.sass.embedded_protocol.Value\x1a\xa2\x01\n\x03Map\x12\x38\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\'.sass.embedded_protocol.Value.Map.Entry\x1a\x61\n\x05\x45ntry\x12*\n\x03key\x18\x01 \x01(\x0b\x32\x1d.sass.embedded_protocol.Value\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x1d.sass.embedded_protocol.Value\x1a\x1e\n\x10\x43ompilerFunction\x12\n\n\x02id\x18\x01 \x01(\r\x1a-\n\x0cHostFunction\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\tsignature\x18\x02 \x01(\t\x1a\x1b\n\rCompilerMixin\x12\n\n\x02id\x18\x01 \x01(\r\x1a\xa1\x02\n\x0c\x41rgumentList\x12\n\n\x02id\x18\x01 \x01(\r\x12\x38\n\tseparator\x18\x02 \x01(\x0e\x32%.sass.embedded_protocol.ListSeparator\x12/\n\x08\x63ontents\x18\x03 \x03(\x0b\x32\x1d.sass.embedded_protocol.Value\x12J\n\x08keywords\x18\x04 \x03(\x0b\x32\x38.sass.embedded_protocol.Value.ArgumentList.KeywordsEntry\x1aN\n\rKeywordsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x1d.sass.embedded_protocol.Value:\x02\x38\x01\x1a\xef\x04\n\x0b\x43\x61lculation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12M\n\targuments\x18\x02 \x03(\x0b\x32:.sass.embedded_protocol.Value.Calculation.CalculationValue\x1a\x95\x02\n\x10\x43\x61lculationValue\x12\x36\n\x06number\x18\x01 \x01(\x0b\x32$.sass.embedded_protocol.Value.NumberH\x00\x12\x10\n\x06string\x18\x02 \x01(\tH\x00\x12\x17\n\rinterpolation\x18\x03 \x01(\tH\x00\x12S\n\toperation\x18\x04 \x01(\x0b\x32>.sass.embedded_protocol.Value.Calculation.CalculationOperationH\x00\x12@\n\x0b\x63\x61lculation\x18\x05 \x01(\x0b\x32).sass.embedded_protocol.Value.CalculationH\x00\x42\x07\n\x05value\x1a\xea\x01\n\x14\x43\x61lculationOperation\x12=\n\x08operator\x18\x01 \x01(\x0e\x32+.sass.embedded_protocol.CalculationOperator\x12H\n\x04left\x18\x02 \x01(\x0b\x32:.sass.embedded_protocol.Value.Calculation.CalculationValue\x12I\n\x05right\x18\x03 \x01(\x0b\x32:.sass.embedded_protocol.Value.Calculation.CalculationValueB\x07\n\x05value\"4\n\x13NodePackageImporter\x12\x1d\n\x15\x65ntry_point_directory\x18\x01 \x01(\t*+\n\x0bOutputStyle\x12\x0c\n\x08\x45XPANDED\x10\x00\x12\x0e\n\nCOMPRESSED\x10\x01*)\n\x06Syntax\x12\x08\n\x04SCSS\x10\x00\x12\x0c\n\x08INDENTED\x10\x01\x12\x07\n\x03\x43SS\x10\x02*?\n\x0cLogEventType\x12\x0b\n\x07WARNING\x10\x00\x12\x17\n\x13\x44\x45PRECATION_WARNING\x10\x01\x12\t\n\x05\x44\x45\x42UG\x10\x02*8\n\x11ProtocolErrorType\x12\t\n\x05PARSE\x10\x00\x12\n\n\x06PARAMS\x10\x01\x12\x0c\n\x08INTERNAL\x10\x02*?\n\rListSeparator\x12\t\n\x05\x43OMMA\x10\x00\x12\t\n\x05SPACE\x10\x01\x12\t\n\x05SLASH\x10\x02\x12\r\n\tUNDECIDED\x10\x03*/\n\x0eSingletonValue\x12\x08\n\x04TRUE\x10\x00\x12\t\n\x05\x46\x41LSE\x10\x01\x12\x08\n\x04NULL\x10\x02*A\n\x13\x43\x61lculationOperator\x12\x08\n\x04PLUS\x10\x00\x12\t\n\x05MINUS\x10\x01\x12\t\n\x05TIMES\x10\x02\x12\n\n\x06\x44IVIDE\x10\x03\x42#\n\x1f\x63om.sass_lang.embedded_protocolP\x01\x62\x06proto3" + +pool = ::Google::Protobuf::DescriptorPool.generated_pool +pool.add_serialized_file(descriptor_data) + +module Sass + module EmbeddedProtocol + InboundMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage").msgclass + InboundMessage::VersionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.VersionRequest").msgclass + InboundMessage::CompileRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.CompileRequest").msgclass + InboundMessage::CompileRequest::StringInput = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.CompileRequest.StringInput").msgclass + InboundMessage::CompileRequest::Importer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.CompileRequest.Importer").msgclass + InboundMessage::CanonicalizeResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.CanonicalizeResponse").msgclass + InboundMessage::ImportResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.ImportResponse").msgclass + InboundMessage::ImportResponse::ImportSuccess = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.ImportResponse.ImportSuccess").msgclass + InboundMessage::FileImportResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.FileImportResponse").msgclass + InboundMessage::FunctionCallResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.InboundMessage.FunctionCallResponse").msgclass + OutboundMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage").msgclass + OutboundMessage::VersionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.VersionResponse").msgclass + OutboundMessage::CompileResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.CompileResponse").msgclass + OutboundMessage::CompileResponse::CompileSuccess = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.CompileResponse.CompileSuccess").msgclass + OutboundMessage::CompileResponse::CompileFailure = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.CompileResponse.CompileFailure").msgclass + OutboundMessage::LogEvent = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.LogEvent").msgclass + OutboundMessage::CanonicalizeRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.CanonicalizeRequest").msgclass + OutboundMessage::ImportRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.ImportRequest").msgclass + OutboundMessage::FileImportRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.FileImportRequest").msgclass + OutboundMessage::FunctionCallRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutboundMessage.FunctionCallRequest").msgclass + ProtocolError = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.ProtocolError").msgclass + SourceSpan = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.SourceSpan").msgclass + SourceSpan::SourceLocation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.SourceSpan.SourceLocation").msgclass + Value = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value").msgclass + Value::String = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.String").msgclass + Value::Number = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.Number").msgclass + Value::Color = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.Color").msgclass + Value::List = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.List").msgclass + Value::Map = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.Map").msgclass + Value::Map::Entry = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.Map.Entry").msgclass + Value::CompilerFunction = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.CompilerFunction").msgclass + Value::HostFunction = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.HostFunction").msgclass + Value::CompilerMixin = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.CompilerMixin").msgclass + Value::ArgumentList = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.ArgumentList").msgclass + Value::Calculation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.Calculation").msgclass + Value::Calculation::CalculationValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.Calculation.CalculationValue").msgclass + Value::Calculation::CalculationOperation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Value.Calculation.CalculationOperation").msgclass + NodePackageImporter = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.NodePackageImporter").msgclass + OutputStyle = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.OutputStyle").enummodule + Syntax = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.Syntax").enummodule + LogEventType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.LogEventType").enummodule + ProtocolErrorType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.ProtocolErrorType").enummodule + ListSeparator = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.ListSeparator").enummodule + SingletonValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.SingletonValue").enummodule + CalculationOperator = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sass.embedded_protocol.CalculationOperator").enummodule + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/exception.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/exception.rb new file mode 100644 index 0000000..200d727 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/exception.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +module Sass + # An exception thrown because a Sass compilation failed. + class CompileError < StandardError + # @return [String, nil] + attr_reader :sass_stack + + # @return [Logger::SourceSpan, nil] + attr_reader :span + + # @return [Array] + attr_reader :loaded_urls + + if Exception.public_method_defined?(:detailed_message, false) + # @!visibility private + def initialize(message, detailed_message, sass_stack, span, loaded_urls) + super(message) + + @detailed_message = detailed_message + @sass_stack = sass_stack + @span = span + @loaded_urls = loaded_urls + end + + # @!visibility private + def detailed_message(highlight: nil, **) + return super if @detailed_message.nil? + + highlight = Exception.to_tty? if highlight.nil? + + detailed_message = @detailed_message.sub(message, super) + detailed_message.gsub!(/\e\[[0-9;]*m/, '') unless highlight + detailed_message + end + else # TODO: remove once ruby 3.1 support is dropped + # @!visibility private + def initialize(message, detailed_message, sass_stack, span, loaded_urls) + super(detailed_message.nil? ? message : detailed_message) + + @message = message + @detailed_message = detailed_message + @sass_stack = sass_stack + @span = span + @loaded_urls = loaded_urls + end + + # @!visibility private + def message + return @message if @detailed_message.nil? || @full_message.nil? + + @detailed_message + end + + # @!visibility private + def detailed_message(highlight: nil, **) + highlight = Exception.to_tty? if highlight.nil? + + super_ = if highlight + lines = message.split("\n") + lines[0] += " (\e[1;4m#{self.class.name}\e[m\e[1m)" unless lines.empty? + lines.map { |line| "\e[1m#{line}\e[m" }.join("\n") + else + lines = message.split("\n", 2) + lines[0] += " (#{self.class.name})" unless lines.empty? + lines.join("\n") + end + + return super_ if @detailed_message.nil? + + detailed_message = @detailed_message.sub(message, super_) + detailed_message.gsub!(/\e\[[0-9;]*m/, '') unless highlight + detailed_message + end + + # @!visibility private + def full_message(highlight: nil, order: :top, **) + highlight = Exception.to_tty? if highlight.nil? + + @full_message = true + full_message = super.force_encoding(message.encoding) + full_message.gsub!(/\e\[[0-9;]*m/, '') unless highlight + full_message + ensure + @full_message = nil + end + end + + # @return [String] + def to_css + content = full_message(highlight: false, order: :top) + + <<~CSS.freeze + /* #{content.gsub('*/', "*\u2060/").gsub("\r\n", "\n").split("\n").join("\n * ")} */ + + body::before { + position: static; + display: block; + padding: 1em; + margin: 0 0 1em; + border-width: 0 0 2px; + border-bottom-style: solid; + font-family: monospace, monospace; + white-space: pre; + content: #{Serializer.serialize_quoted_string(content).gsub(/[^[:ascii:]][\h\t ]?/) do |match| + ordinal = match.ord + replacement = "\\#{ordinal.to_s(16)}" + if match.length > 1 + replacement << ' ' if ordinal < 0x100000 + replacement << match[1] + end + replacement + end}; + } + CSS + end + end + + # An exception thrown by Sass Script. + class ScriptError < StandardError + # @!visibility private + def initialize(message, name = nil) + super(name.nil? ? message : "$#{name}: #{message}") + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/fork_tracker.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/fork_tracker.rb new file mode 100644 index 0000000..386f941 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/fork_tracker.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Sass + # The {ForkTracker} module. + # + # It tracks objects that need to be closed after `Process.fork`. + module ForkTracker + module_function + + if Process.respond_to?(:_fork) + # TODO: remove next line once ruby 3.1 support is dropped + require 'set' unless defined?(::Set) + + SET = Set.new.compare_by_identity + + MUTEX = Mutex.new + + private_constant :SET, :MUTEX + + def add(object) + MUTEX.synchronize do + SET.add(object) + end + end + + def delete(object) + MUTEX.synchronize do + SET.delete(object) + end + end + + def each(&) + MUTEX.synchronize do + SET.to_a + end.each(&) + end + + # The {CoreExt} module. + # + # It closes objects after `Process.fork`. + module CoreExt + def _fork + pid = super + ForkTracker.each(&:close) if pid.zero? + pid + end + end + + private_constant :CoreExt + + Process.singleton_class.prepend(CoreExt) + else + def add(object); end + def delete(object); end + end + end + + private_constant :ForkTracker +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/gem_package_importer.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/gem_package_importer.rb new file mode 100644 index 0000000..052ded1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/gem_package_importer.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sass + # The built-in RubyGems package importer. This loads pkg: URLs from gems. + # + # @example + # require 'bundler/inline' + # + # gemfile do + # source 'https://rubygems.org' + # gem 'bootstrap', require: false + # gem 'sass-embedded' + # end + # + # puts Sass.compile_string('@use "pkg:bootstrap/assets/stylesheets/bootstrap";', importers: [Sass::GemPackageImporter.new]).css + class GemPackageImporter + # @!visibility private + def find_file_url(url, _canonicalize_context) + return unless url.start_with?('pkg:') + + library, _, path = url[4..].partition('/') + gem_dir = Gem::Dependency.new(Uri.decode_uri_component(library)).to_spec.gem_dir + "#{Uri.path_to_file_uri(gem_dir)}/#{path}" + rescue Gem::MissingSpecError + nil + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/silent.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/silent.rb new file mode 100644 index 0000000..f090efa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/silent.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sass + # A namespace for built-in Loggers. + # + # @see https://sass-lang.com/documentation/js-api/modules/logger/ + module Logger + module_function + + # A Logger that silently ignores all warnings and debug messages. + # + # @see https://sass-lang.com/documentation/js-api/variables/logger.silent/ + def silent + Silent + end + + # A Logger that silently ignores all warnings and debug messages. + module Silent + module_function + + def warn(message, options); end + + def debug(message, options); end + end + + private_constant :Silent + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_location.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_location.rb new file mode 100644 index 0000000..19a4d32 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_location.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Sass + module Logger + # A specific location within a source file. + # + # This is always associated with a {SourceSpan} which indicates which file it refers to. + # + # @see https://sass-lang.com/documentation/js-api/interfaces/sourcelocation/ + class SourceLocation + # @return [Integer] + attr_reader :offset, :line, :column + + # @!visibility private + def initialize(source_location) + @offset = source_location.offset + @line = source_location.line + @column = source_location.column + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_span.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_span.rb new file mode 100644 index 0000000..3f22ca3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/logger/source_span.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sass + module Logger + # A span of text within a source file. + # + # @see https://sass-lang.com/documentation/js-api/interfaces/sourcespan/ + class SourceSpan + # @return [SourceLocation] + attr_reader :start, :end + + # @return [String] + attr_reader :text + + # @return [String, nil] + attr_reader :url, :context + + # @!visibility private + def initialize(source_span) + @start = source_span.start.nil? ? nil : Logger::SourceLocation.new(source_span.start) + @end = source_span.end.nil? ? nil : Logger::SourceLocation.new(source_span.end) + @text = source_span.text + @url = source_span.url == '' ? nil : source_span.url + @context = source_span.context == '' ? nil : source_span.context + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/node_package_importer.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/node_package_importer.rb new file mode 100644 index 0000000..07d6d54 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/node_package_importer.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Sass + # The built-in Node.js package importer. This loads pkg: URLs from node_modules + # according to the standard Node.js resolution algorithm. + # + # @see https://sass-lang.com/documentation/js-api/classes/nodepackageimporter/ + class NodePackageImporter + # @param entry_point_directory [String] The directory where the {NodePackageImporter} should start when resolving + # `pkg:` URLs in sources other than files on disk. + def initialize(entry_point_directory) + raise ArgumentError, 'entry_point_directory must be set' if entry_point_directory.nil? + + @entry_point_directory = File.absolute_path(entry_point_directory) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/serializer.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/serializer.rb new file mode 100644 index 0000000..6a3bc98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/serializer.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Sass + # The {Serializer} module. + module Serializer + module_function + + CSS_ESCAPE = [*"\x01".."\x08", *"\x0A".."\x1F", "\x7F"] + .product([*'0'..'9', *'a'..'f', *'A'..'F', "\t", ' ', nil]) + .each_with_object({ "\0" => "\uFFFD", '\\' => '\\\\', '"' => '\\"', "'" => "\\'" }) do |(c, x), h| + h["#{c}#{x}".freeze] = "\\#{c.ord.to_s(16)}#{" #{x}" if x}".freeze + end.freeze + + private_constant :CSS_ESCAPE + + def serialize_quoted_string(string) + if !string.include?('"') || string.include?("'") + %("#{string.gsub(/[\0\\"]|[\x01-\x08\x0A-\x1F\x7F][\h\t ]?/, CSS_ESCAPE)}") + else + %('#{string.gsub(/[\0\\']|[\x01-\x08\x0A-\x1F\x7F][\h\t ]?/, CSS_ESCAPE)}') + end + end + + def serialize_unquoted_string(string) + string.tr("\0", "\uFFFD").gsub(/\n */, ' ') + end + end + + private_constant :Serializer +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/uri.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/uri.rb new file mode 100644 index 0000000..2e0f9b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/uri.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'uri' + +module Sass + # The {Uri} class. + # + # It follows RFC3986 to match the behavior of Uri class from Dart. + # + # @see https://www.rfc-editor.org/info/rfc3986/ + module Uri + module_function + + def decode_uri_component(str) + str.b.gsub(/%\h\h/, ::URI::TBLDECWWWCOMP_).force_encoding(str.encoding) + end + + def encode_uri_component(str) + str.b.gsub(/[^0-9A-Za-z\-._~]/n, ::URI::TBLENCURICOMP_).force_encoding(str.encoding) + end + + def encode_uri_path_component(str) + str.b.gsub(%r{[^0-9A-Za-z\-._~!$&'()*+,;=:@/]}n, ::URI::TBLENCURICOMP_).force_encoding(str.encoding) + end + + def encode_uri_query_component(str) + str.b.gsub(%r{[^0-9A-Za-z\-._~!$&'()*+,;=:@/?]}n, ::URI::TBLENCURICOMP_).force_encoding(str.encoding) + end + + def file_uri_to_path(uri) + path = decode_uri_component(::URI::RFC3986_PARSER.parse(uri).path) + if path.start_with?('/') + windows_path = path[1..] + path = windows_path if File.absolute_path?(windows_path) + end + path + end + + def path_to_file_uri(path) + path = "/#{path}" unless path.start_with?('/') + "file://#{encode_uri_path_component(path)}" + end + + def pwd + pwd = Dir.pwd + pwd += '/' unless pwd.end_with?('/') + path_to_file_uri(pwd) + end + + def relative(to, from) + ::URI::RFC3986_PARSER.parse(to).route_from(from).to_s + end + end + + private_constant :Uri +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value.rb new file mode 100644 index 0000000..abb3636 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +module Sass + # The abstract base class of Sass's value types. + # + # @see https://sass-lang.com/documentation/js-api/classes/value/ + module Value + # @return [::String, nil] + def separator + nil + end + + # @return [::Boolean] + def bracketed? + false + end + + # @return [::Boolean] + def eql?(other) + self == other + end + + # @param index [Numeric] + # @return [Value] + def [](index) + at(index) + end + + # @param index [Numeric] + # @return [Value] + def at(index) + index < 1 && index >= -1 ? self : nil + end + + # @return [Array] + def to_a + [self] + end + + # @return [::Boolean] + def to_bool # rubocop:disable Naming/PredicateMethod + true + end + + # @return [Map, nil] + def to_map + nil + end + + # @return [Value, nil] + def to_nil + self + end + + # @return [Boolean] + # @raise [ScriptError] + def assert_boolean(name = nil) + raise Sass::ScriptError.new("#{self} is not a boolean", name) + end + + # @return [Calculation] + # @raise [ScriptError] + def assert_calculation(name = nil) + raise Sass::ScriptError.new("#{self} is not a calculation", name) + end + + # @return [Color] + # @raise [ScriptError] + def assert_color(name = nil) + raise Sass::ScriptError.new("#{self} is not a color", name) + end + + # @return [Function] + # @raise [ScriptError] + def assert_function(name = nil) + raise Sass::ScriptError.new("#{self} is not a function", name) + end + + # @return [Map] + # @raise [ScriptError] + def assert_map(name = nil) + raise Sass::ScriptError.new("#{self} is not a map", name) + end + + # @return [Mixin] + # @raise [ScriptError] + def assert_mixin(name = nil) + raise Sass::ScriptError.new("#{self} is not a mixin", name) + end + + # @return [Number] + # @raise [ScriptError] + def assert_number(name = nil) + raise Sass::ScriptError.new("#{self} is not a number", name) + end + + # @return [String] + # @raise [ScriptError] + def assert_string(name = nil) + raise Sass::ScriptError.new("#{self} is not a string", name) + end + + # @param sass_index [Number] + # @return [Integer] + def sass_index_to_array_index(sass_index, name = nil) + index = sass_index.assert_number(name).assert_integer(name) + raise Sass::ScriptError.new('List index may not be 0', name) if index.zero? + + if index.abs > to_a_length + raise Sass::ScriptError.new("Invalid index #{sass_index} for a list with #{to_a_length} elements", name) + end + + index.negative? ? to_a_length + index : index - 1 + end + + private + + def to_a_length + 1 + end + end +end + +require_relative 'calculation_value' +require_relative 'value/list' +require_relative 'value/argument_list' +require_relative 'value/boolean' +require_relative 'value/calculation' +require_relative 'value/color' +require_relative 'value/function' +require_relative 'value/fuzzy_math' +require_relative 'value/map' +require_relative 'value/mixin' +require_relative 'value/null' +require_relative 'value/number' +require_relative 'value/string' diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/argument_list.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/argument_list.rb new file mode 100644 index 0000000..34d0f94 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/argument_list.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's argument list type. + # + # An argument list comes from a rest argument. It's distinct from a normal {List} in that it may contain a keyword + # map as well as the positional arguments. + # + # @see https://sass-lang.com/documentation/js-api/classes/sassargumentlist/ + class ArgumentList < List + # @param contents [Array] + # @param keywords [Hash] + # @param separator [::String] + def initialize(contents = [], keywords = {}, separator = ',') + super(contents, separator:) + + @keywords_accessed = false + @keywords = keywords.freeze + end + + # @return [Hash] + def keywords + @keywords_accessed = true + @keywords + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/boolean.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/boolean.rb new file mode 100644 index 0000000..ea4d418 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/boolean.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's boolean type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sassboolean/ + class Boolean + include Value + + # @param value [::Boolean] + def initialize(value) + @value = value + end + + # @return [::Boolean] + attr_reader :value + + # @return [Boolean] + def ! + value ? Boolean::FALSE : Boolean::TRUE + end + + # @return [::Boolean] + def ==(other) + other.is_a?(Sass::Value::Boolean) && other.value == value + end + + # @return [Integer] + def hash + @hash ||= value.hash + end + + alias to_bool value + + # @return [Boolean] + def assert_boolean(_name = nil) + self + end + + # Sass's true value. + TRUE = Boolean.new(true) + + # Sass's false value. + FALSE = Boolean.new(false) + + def self.new(value) + value ? Boolean::TRUE : Boolean::FALSE + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/calculation.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/calculation.rb new file mode 100644 index 0000000..32f26c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/calculation.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's calculation type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sasscalculation/ + class Calculation + include Value + include CalculationValue + + class << self + private :new + + # @param argument [CalculationValue] + # @return [Calculation] + def calc(argument) + new('calc', [argument]) + end + + # @param arguments [Array] + # @return [Calculation] + def min(arguments) + new('min', arguments) + end + + # @param arguments [Array] + # @return [Calculation] + def max(arguments) + new('max', arguments) + end + + # @param min [CalculationValue] + # @param value [CalculationValue] + # @param max [CalculationValue] + # @return [Calculation] + def clamp(min, value = nil, max = nil) + if (value.nil? && !valid_clamp_arg?(min)) || + (max.nil? && [min, value].none? { |x| x && valid_clamp_arg?(x) }) + raise Sass::ScriptError, 'Argument must be an unquoted SassString.' + end + + new('clamp', [min, value, max].compact) + end + + private + + def valid_clamp_arg?(value) + value.is_a?(Sass::Value::String) && !value.quoted? + end + end + + private + + def initialize(name, arguments) + arguments.each do |value| + assert_calculation_value(value) + end + + @name = name.freeze + @arguments = arguments.freeze + end + + public + + # @return [::String] + attr_reader :name + + # @return [Array] + attr_reader :arguments + + # @return [Calculation] + def assert_calculation(_name = nil) + self + end + + # @return [::Boolean] + def ==(other) + other.is_a?(Sass::Value::Calculation) && + other.name == name && + other.arguments == arguments + end + + # @return [Integer] + def hash + @hash ||= [name, *arguments].hash + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color.rb new file mode 100644 index 0000000..c2f42ba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color.rb @@ -0,0 +1,630 @@ +# frozen_string_literal: true + +require_relative 'color/channel' +require_relative 'color/conversions' +require_relative 'color/gamut_map_method' +require_relative 'color/interpolation_method' +require_relative 'color/space' + +module Sass + module Value + # Sass's color type. + # + # No matter what representation was originally used to create this color, all of its channels are accessible. + # + # @see https://sass-lang.com/documentation/js-api/classes/sasscolor/ + class Color + include Value + + # @param red [Numeric] + # @param green [Numeric] + # @param blue [Numeric] + # @param hue [Numeric] + # @param saturation [Numeric] + # @param lightness [Numeric] + # @param whiteness [Numeric] + # @param blackness [Numeric] + # @param a [Numeric] + # @param b [Numeric] + # @param chroma [Numeric] + # @param x [Numeric] + # @param y [Numeric] + # @param z [Numeric] + # @param alpha [Numeric] + # @param space [::String] + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'rgb') + # @overload initialize(hue: nil, saturation: nil, lightness: nil, alpha: nil, space: 'hsl') + # @overload initialize(hue: nil, whiteness: nil, blackness: nil, alpha: nil, space: 'hwb') + # @overload initialize(lightness: nil, a: nil, b: nil, alpha: nil, space: 'lab') + # @overload initialize(lightness: nil, a: nil, b: nil, alpha: nil, space: 'oklab') + # @overload initialize(lightness: nil, chroma: nil, hue: nil, alpha: nil, space: 'lch') + # @overload initialize(lightness: nil, chroma: nil, hue: nil, alpha: nil, space: 'oklch') + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'a98-rgb') + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'display-p3') + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'display-p3-linear') + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'prophoto-rgb') + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'rec2020') + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'srgb') + # @overload initialize(red: nil, green: nil, blue: nil, alpha: nil, space: 'srgb-linear') + # @overload initialize(x: nil, y: nil, z: nil, alpha: nil, space: 'xyz') + # @overload initialize(x: nil, y: nil, z: nil, alpha: nil, space: 'xyz-d50') + # @overload initialize(x: nil, y: nil, z: nil, alpha: nil, space: 'xyz-d65') + def initialize(**options) + unless options.key?(:space) + options[:space] = case options + in { red: _, green: _, blue: _ } + 'rgb' + in { hue: _, saturation: _, lightness: _ } + 'hsl' + in { hue: _, whiteness: _, blackness: _ } + 'hwb' + else + raise Sass::ScriptError.new('No color space found', 'space') + end + end + + space = Space.from_name(options[:space]) + + keys = _assert_options(space, options) + + _initialize_for_space_internal(space, + options[keys[0]], + options[keys[1]], + options[keys[2]], + options.fetch(:alpha, 1)) + end + + # @return [::String] + def space + _space.name + end + + # @param space [::String] + # @return [Color] + def to_space(space) + _to_space(Space.from_name(space)) + end + + # @param space [::String] + # @return [::Boolean] + def in_gamut?(space = nil) + return to_space(space)._in_gamut? unless space.nil? + + _in_gamut? + end + + # @param method [::String] + # @param space [::String] + # @return [Color] + def to_gamut(method:, space: nil) + return to_space(space).to_gamut(method:)._to_space(_space) unless space.nil? + + _to_gamut(GamutMapMethod.from_name(method, 'method')) + end + + # @return [Array] + def channels_or_nil + [channel0_or_nil, channel1_or_nil, channel2_or_nil].freeze + end + + # @return [Array] + def channels + [channel0, channel1, channel2].freeze + end + + # @param channel [::String] + # @param space [::String] + # @return [Numeric] + def channel(channel, space: nil) + return to_space(space).channel(channel) unless space.nil? + + channels = _space.channels + return channel0 if channel == channels[0].name + return channel1 if channel == channels[1].name + return channel2 if channel == channels[2].name + return alpha if channel == 'alpha' + + raise Sass::ScriptError.new("Color #{self} doesn't have a channel named \"#{channel}\".", channel) + end + + # @param channel [::String] + # @return [::Boolean] + def channel_missing?(channel) + channels = _space.channels + return channel0_missing? if channel == channels[0].name + return channel1_missing? if channel == channels[1].name + return channel2_missing? if channel == channels[2].name + return alpha_missing? if channel == 'alpha' + + raise Sass::ScriptError.new("Color #{self} doesn't have a channel named \"#{channel}\".", channel) + end + + # @param channel [::String] + # @param space [::String] + # @return [::Boolean] + def channel_powerless?(channel, space: nil) + return to_space(space).channel_powerless?(channel) unless space.nil? + + channels = _space.channels + return channel0_powerless? if channel == channels[0].name + return channel1_powerless? if channel == channels[1].name + return channel2_powerless? if channel == channels[2].name + return false if channel == 'alpha' + + raise Sass::ScriptError.new("Color #{self} doesn't have a channel named \"#{channel}\".", channel) + end + + # @param other [Color] + # @param method [::String] + # @param weight [Numeric] + # @return [Color] + def interpolate(other, method: nil, weight: nil) + interpolation_method = if !method.nil? + InterpolationMethod.new(_space, HueInterpolationMethod.from_name(method)) + elsif !_space.polar? + InterpolationMethod.new(_space) + else + InterpolationMethod.new(_space, :shorter) + end + _interpolate(other, interpolation_method, weight:) + end + + # @param red [Numeric] + # @param green [Numeric] + # @param blue [Numeric] + # @param hue [Numeric] + # @param saturation [Numeric] + # @param lightness [Numeric] + # @param whiteness [Numeric] + # @param blackness [Numeric] + # @param a [Numeric] + # @param b [Numeric] + # @param chroma [Numeric] + # @param x [Numeric] + # @param y [Numeric] + # @param z [Numeric] + # @param alpha [Numeric] + # @param space [::String] + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'rgb') + # @overload change(hue: nil, saturation: nil, lightness: nil, alpha: nil, space: 'hsl') + # @overload change(hue: nil, whiteness: nil, blackness: nil, alpha: nil, space: 'hwb') + # @overload change(lightness: nil, a: nil, b: nil, alpha: nil, space: 'lab') + # @overload change(lightness: nil, a: nil, b: nil, alpha: nil, space: 'oklab') + # @overload change(lightness: nil, chroma: nil, hue: nil, alpha: nil, space: 'lch') + # @overload change(lightness: nil, chroma: nil, hue: nil, alpha: nil, space: 'oklch') + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'a98-rgb') + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'display-p3') + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'display-p3-linear') + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'prophoto-rgb') + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'rec2020') + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'srgb') + # @overload change(red: nil, green: nil, blue: nil, alpha: nil, space: 'srgb-linear') + # @overload change(x: nil, y: nil, z: nil, alpha: nil, space: 'xyz') + # @overload change(x: nil, y: nil, z: nil, alpha: nil, space: 'xyz-d50') + # @overload change(x: nil, y: nil, z: nil, alpha: nil, space: 'xyz-d65') + # @return [Color] + def change(**options) + space_set_explictly = !options[:space].nil? + space = space_set_explictly ? Space.from_name(options[:space]) : _space + + if legacy? && !space_set_explictly + case options + in { whiteness: _ } | { blackness: _ } + space = Space::HWB + in { saturation: _ } | { lightness: _ } + space = Space::HSL + in { hue: _ } + space = if _space == Space::HWB + Space::HWB + else + Space::HSL + end + in { red: _ } | { blue: _ } | { green: _ } + space = Space::RGB + else + end + + if space != _space + # deprecated + end + end + + keys = _assert_options(space, options) + + color = _to_space(space) + + changed_color = if space_set_explictly + Color.send(:for_space_internal, + space, + options.fetch(keys[0], color.channel0_or_nil), + options.fetch(keys[1], color.channel1_or_nil), + options.fetch(keys[2], color.channel2_or_nil), + options.fetch(:alpha, color.alpha_or_nil)) + else + changed_channel0_or_nil = options[keys[0]] + changed_channel1_or_nil = options[keys[1]] + changed_channel2_or_nil = options[keys[2]] + changed_alpha_or_nil = options[:alpha] + Color.send(:for_space_internal, + space, + changed_channel0_or_nil.nil? ? color.channel0_or_nil : changed_channel0_or_nil, + changed_channel1_or_nil.nil? ? color.channel1_or_nil : changed_channel1_or_nil, + changed_channel2_or_nil.nil? ? color.channel2_or_nil : changed_channel2_or_nil, + changed_alpha_or_nil.nil? ? color.alpha_or_nil : changed_alpha_or_nil) + end + + changed_color._to_space(_space) + end + + # @return [Numeric] + def alpha + @alpha_or_nil.nil? ? 0 : @alpha_or_nil + end + + # @return [::Boolean] + def legacy? + _space.legacy? + end + + # @deprecated + # @return [Numeric] + def red + _to_space(Space::RGB).channel('red').round + end + + # @deprecated + # @return [Numeric] + def green + _to_space(Space::RGB).channel('green').round + end + + # @deprecated + # @return [Numeric] + def blue + _to_space(Space::RGB).channel('blue').round + end + + # @deprecated + # @return [Numeric] + def hue + _to_space(Space::HSL).channel('hue') + end + + # @deprecated + # @return [Numeric] + def saturation + _to_space(Space::HSL).channel('saturation') + end + + # @deprecated + # @return [Numeric] + def lightness + _to_space(Space::HSL).channel('lightness') + end + + # @deprecated + # @return [Numeric] + def whiteness + _to_space(Space::HWB).channel('whiteness') + end + + # @deprecated + # @return [Numeric] + def blackness + _to_space(Space::HWB).channel('blackness') + end + + # @return [::Boolean] + def ==(other) + return false unless other.is_a?(Sass::Value::Color) + + if legacy? + return false unless other.legacy? + return false unless FuzzyMath.equals_nilable?(other.alpha_or_nil, alpha_or_nil) + + if _space == other._space + FuzzyMath.equals_nilable?(other.channel0_or_nil, channel0_or_nil) && + FuzzyMath.equals_nilable?(other.channel1_or_nil, channel1_or_nil) && + FuzzyMath.equals_nilable?(other.channel2_or_nil, channel2_or_nil) + else + _to_space(Space::RGB) == other._to_space(Space::RGB) + end + else + other._space == _space && + FuzzyMath.equals_nilable?(other.channel0_or_nil, channel0_or_nil) && + FuzzyMath.equals_nilable?(other.channel1_or_nil, channel1_or_nil) && + FuzzyMath.equals_nilable?(other.channel2_or_nil, channel2_or_nil) && + FuzzyMath.equals_nilable?(other.alpha_or_nil, alpha_or_nil) + end + end + + # @return [Integer] + def hash + @hash ||= [ + _space.name, + FuzzyMath._hash(channel0_or_nil), + FuzzyMath._hash(channel1_or_nil), + FuzzyMath._hash(channel2_or_nil), + FuzzyMath._hash(alpha_or_nil) + ].hash + end + + # @return [Color] + def assert_color(_name = nil) + self + end + + protected + + attr_reader :channel0_or_nil, :channel1_or_nil, :channel2_or_nil, :alpha_or_nil + + def channel0 + @channel0_or_nil.nil? ? 0 : @channel0_or_nil + end + + def channel0_missing? + @channel0_or_nil.nil? + end + + def channel0_powerless? + case _space + when Space::HSL + FuzzyMath.equals?(channel1, 0) + when Space::HWB + FuzzyMath.greater_than_or_equals?(channel1 + channel2, 100) + else + false + end + end + + def channel1 + @channel1_or_nil.nil? ? 0 : @channel1_or_nil + end + + def channel1_missing? + @channel1_or_nil.nil? + end + + def channel1_powerless? + false + end + + def channel2 + @channel2_or_nil.nil? ? 0 : @channel2_or_nil + end + + def channel2_missing? + @channel2_or_nil.nil? + end + + def channel2_powerless? + case _space + when Space::LCH, Space::OKLCH + FuzzyMath.equals?(channel1, 0) + else + false + end + end + + def alpha_missing? + @alpha_or_nil.nil? + end + + def _space + @space + end + + def _to_space(space) + return self if _space == space + + _space.convert(space, channel0_or_nil, channel1_or_nil, channel2_or_nil, alpha) + end + + def _in_gamut? + return true unless _space.bounded? + + _is_channel_in_gamut?(channel0, _space.channels[0]) && + _is_channel_in_gamut?(channel1, _space.channels[1]) && + _is_channel_in_gamut?(channel2, _space.channels[2]) + end + + def _to_gamut(method) + _in_gamut? ? self : method.map(self) + end + + private + + def _assert_options(space, options) + keys = space.channels.map do |channel| + channel.name.to_sym + end << :alpha << :space + options.each_key do |key| + unless keys.include?(key) + raise Sass::ScriptError.new("`#{key}` is not a valid channel in `#{space.name}`.", key) + end + end + keys + end + + def _initialize_for_space_internal(space, channel0, channel1, channel2, alpha = 1) + case space + when Space::HSL + _initialize_for_space( + space, + _normalize_hue(channel0, invert: !channel1.nil? && FuzzyMath.less_than?(channel1, 0)), + channel1&.abs, + channel2, + alpha + ) + when Space::HWB + _initialize_for_space(space, _normalize_hue(channel0, invert: false), channel1, channel2, alpha) + when Space::LCH, Space::OKLCH + _initialize_for_space( + space, + channel0, + channel1&.abs, + _normalize_hue(channel2, invert: !channel1.nil? && FuzzyMath.less_than?(channel1, 0)), + alpha + ) + else + _initialize_for_space(space, channel0, channel1, channel2, alpha) + end + end + + def _initialize_for_space(space, channel0_or_nil, channel1_or_nil, channel2_or_nil, alpha) + @space = space + @channel0_or_nil = channel0_or_nil + @channel1_or_nil = channel1_or_nil + @channel2_or_nil = channel2_or_nil + @alpha_or_nil = alpha + + FuzzyMath.assert_between(@alpha_or_nil, 0, 1, 'alpha') unless @alpha_or_nil.nil? + end + + def _normalize_hue(hue, invert:) + return hue if hue.nil? + + ((hue % 360) + 360 + (invert ? 180 : 0)) % 360 + end + + def _is_channel_in_gamut?(value, channel) + case channel + when LinearChannel + FuzzyMath.less_than_or_equals?(value, channel.max) && FuzzyMath.greater_than_or_equals?(value, channel.min) + else + true + end + end + + def _interpolate(other, method, weight: nil) + weight = 0.5 if weight.nil? + if weight.negative? || weight > 1 + raise Sass::ScriptError.new("Expected #{wieght} to be within 0 and 1.", 'weight') + end + + return other if FuzzyMath.equals?(weight, 0) + return self if FuzzyMath.equals?(weight, 1) + + color1 = _to_space(method.space) + color2 = other._to_space(method.space) + + c1_missing0 = _analogous_channel_missing?(self, color1, 0) + c1_missing1 = _analogous_channel_missing?(self, color1, 1) + c1_missing2 = _analogous_channel_missing?(self, color1, 2) + c2_missing0 = _analogous_channel_missing?(other, color2, 0) + c2_missing1 = _analogous_channel_missing?(other, color2, 1) + c2_missing2 = _analogous_channel_missing?(other, color2, 2) + c1_channel0 = (c1_missing0 ? color2 : color1).channel0 + c1_channel1 = (c1_missing1 ? color2 : color1).channel1 + c1_channel2 = (c1_missing2 ? color2 : color1).channel2 + c2_channel0 = (c2_missing0 ? color1 : color2).channel0 + c2_channel1 = (c2_missing1 ? color1 : color2).channel1 + c2_channel2 = (c2_missing2 ? color1 : color2).channel2 + c1_alpha = alpha_or_nil.nil? ? other.alpha : alpha_or_nil + c2_alpha = other.alpha_or_nil.nil? ? alpha : other.alpha_or_nil + + c1_multiplier = (alpha_or_nil.nil? ? 1 : alpha_or_nil) * weight + c2_multiplier = (other.alpha_or_nil.nil? ? 1 : other.alpha_or_nil) * (1 - weight) + mixed_alpha = alpha_missing? && other.alpha_missing? ? nil : (c1_alpha * weight) + (c2_alpha * (1 - weight)) + mixed0 = if c1_missing0 && c2_missing0 + nil + else + ((c1_channel0 * c1_multiplier) + (c2_channel0 * c2_multiplier)) / + (mixed_alpha.nil? ? 1 : mixed_alpha) + end + mixed1 = if c1_missing1 && c2_missing1 + nil + else + ((c1_channel1 * c1_multiplier) + (c2_channel1 * c2_multiplier)) / + (mixed_alpha.nil? ? 1 : mixed_alpha) + end + mixed2 = if c1_missing2 && c2_missing2 + nil + else + ((c1_channel2 * c1_multiplier) + (c2_channel2 * c2_multiplier)) / + (mixed_alpha.nil? ? 1 : mixed_alpha) + end + + case method.space + when Space::HSL, Space::HWB + Color.send(:for_space_internal, + method.space, + c1_missing0 && c2_missing0 ? nil : _interpolate_hues(c1_channel0, c2_channel0, method.hue, weight), + mixed1, + mixed2, + mixed_alpha) + when Space::LCH, Space::OKLCH + Color.send(:for_space_internal, + method.space, + mixed0, + mixed1, + c1_missing2 && c2_missing2 ? nil : _interpolate_hues(c1_channel2, c2_channel2, method.hue, weight), + mixed_alpha) + else + Color.send(:_for_space, + method.space, mixed0, mixed1, mixed2, mixed_alpha) + end._to_space(_space) + end + + def _analogous_channel_missing?(original, output, output_channel_index) + return true if output.channels_or_nil[output_channel_index].nil? + + return false if original.equal?(output) + + output_channel = output._space.channels[output_channel_index] + original_channel = original._space.channels.find do |channel| + output_channel.analogous?(channel) + end + + return false if original_channel.nil? + + original.channel_missing?(original_channel.name) + end + + def _interpolate_hues(hue1, hue2, method, weight) + case method + when :shorter + diff = hue2 - hue1 + if diff > 180 + hue1 += 360 + elsif diff < -180 + hue2 += 360 + end + when :longer + diff = hue2 - hue1 + if diff.positive? && diff < 180 + hue2 += 360 + elsif diff > -180 && diff <= 0 + hue1 += 360 + end + when :increasing + hue2 += 360 if hue2 < hue1 + when :decreasing + hue1 += 360 if hue1 < hue2 + end + + (hue1 * weight) + (hue2 * (1 - weight)) + end + + class << self + private + + def for_space(space, channel0_or_nil, channel1_or_nil, channel2_or_nil, alpha) + _for_space(Space.from_name(space), channel0_or_nil, channel1_or_nil, channel2_or_nil, alpha) + end + + def for_space_internal(space, channel0, channel1, channel2, alpha) + o = allocate + o.send(:_initialize_for_space_internal, space, channel0, channel1, channel2, alpha) + o + end + + def _for_space(space, channel0_or_nil, channel1_or_nil, channel2_or_nil, alpha) + o = allocate + o.send(:_initialize_for_space, space, channel0_or_nil, channel1_or_nil, channel2_or_nil, alpha) + o + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/channel.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/channel.rb new file mode 100644 index 0000000..ec7089a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/channel.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/channel.dart + class ColorChannel + # @return [::String] + attr_reader :name + + # @return [::Boolean] + def polar_angle? + @polar_angle + end + + # @return [::String, nil] + attr_reader :associated_unit + + # @param name [::String] + # @param polar_angle [::Boolean] + # @param associated_unit [::String] + def initialize(name, polar_angle:, associated_unit: nil) + @name = name + @polar_angle = polar_angle + @associated_unit = associated_unit + end + + # @return [::Boolean] + def analogous?(other) + case [name, other.name] + in ['red' | 'x', 'red' | 'x'] | + ['green' | 'y', 'green' | 'y'] | + ['blue' | 'z', 'blue' | 'z'] | + ['chroma' | 'saturation', 'chroma' | 'saturation'] | + ['lightness', 'lightness'] | + ['hue', 'hue'] + true + else + false + end + end + end + + private_constant :ColorChannel + + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/channel.dart + class LinearChannel < ColorChannel + # @return [Numeric] + attr_reader :min, :max + + # @return [::Boolean] + attr_reader :requires_percent, :lower_clamped, :upper_clamped + + # @param name [::String] + # @param min [Numeric] + # @param max [Numeric] + # @param requires_percent [::Boolean] + # @param lower_clamped [::Boolean] + # @param upper_clamped [::Boolean] + # @param conventionally_percent [::Boolean] + def initialize(name, min, max, requires_percent: false, lower_clamped: false, upper_clamped: false, + conventionally_percent: nil) + super(name, + polar_angle: false, + associated_unit: if conventionally_percent.nil? ? (min.zero? && max == 100) : conventionally_percent + '%' + end) + @min = min + @max = max + @requires_percent = requires_percent + @lower_clamped = lower_clamped + @upper_clamped = upper_clamped + end + end + + private_constant :LinearChannel + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/conversions.rb new file mode 100644 index 0000000..331d218 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/conversions.rb @@ -0,0 +1,473 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + # @see https:#www.w3.org/TR/css-color-4/#color-conversion-code. + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/conversions.dart + module Conversions + # The D50 white point. + # + # Definition from https://www.w3.org/TR/css-color-4/#color-conversion-code. + D50 = [0.3457 / 0.3585, 1.00000, (1.0 - 0.3457 - 0.3585) / 0.3585].freeze + + # Matrix values from https://www.w3.org/TR/css-color-4/#color-conversion-code. + + # The transformation matrix for converting LMS colors to OKLab. + # + # Note that this can't be directly multiplied with [XYZ_D65_TO_LMS]; see Color + # Level 4 spec for details on how to convert between XYZ and OKLab. + LMS_TO_OKLAB = [ + 0.21045426830931400, 0.79361777470230540, -0.00407204301161930, + 1.97799853243116840, -2.42859224204858000, 0.45059370961741100, + 0.02590404246554780, 0.78277171245752960, -0.80867575492307740 + ].freeze + + # The transformation matrix for converting OKLab colors to LMS. + # + # Note that this can't be directly multiplied with [LMS_TO_XYZ_D65]; see Color + # Level 4 spec for details on how to convert between XYZ and OKLab. + OKLAB_TO_LMS = [ + 1.00000000000000020, 0.39633777737617490, 0.21580375730991360, + 0.99999999999999980, -0.10556134581565854, -0.06385417282581334, + 0.99999999999999990, -0.08948417752981180, -1.29148554801940940 + ].freeze + + # The following matrices were precomputed using + # https://gist.github.com/nex3/3d7ecfef467b22e02e7a666db1b8a316. + + # The transformation matrix for converting linear-light srgb colors to + # linear-light display-p3. + LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = [ + 0.82246196871436230, 0.17753803128563775, 0.00000000000000000, + 0.03319419885096161, 0.96680580114903840, 0.00000000000000000, + 0.01708263072112003, 0.07239744066396346, 0.91051992861491650 + ].freeze + + # The transformation matrix for converting linear-light display-p3 colors to + # linear-light srgb. + LINEAR_DISPLAY_P3_TO_LINEAR_SRGB = [ + 1.22494017628055980, -0.22494017628055996, 0.00000000000000000, + -0.04205695470968816, 1.04205695470968800, 0.00000000000000000, + -0.01963755459033443, -0.07863604555063188, 1.09827360014096630 + ].freeze + + # The transformation matrix for converting linear-light srgb colors to + # linear-light a98-rgb. + LINEAR_SRGB_TO_LINEAR_A98_RGB = [ + 0.71512560685562470, 0.28487439314437535, 0.00000000000000000, + 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, + 0.00000000000000000, 0.04116194845011846, 0.95883805154988160 + ].freeze + + # The transformation matrix for converting linear-light a98-rgb colors to + # linear-light srgb. + LINEAR_A98_RGB_TO_LINEAR_SRGB = [ + 1.39835574396077830, -0.39835574396077830, 0.00000000000000000, + 0.00000000000000000, 1.00000000000000000, 0.00000000000000000, + 0.00000000000000000, -0.04292898929447326, 1.04292898929447330 + ].freeze + + # The transformation matrix for converting linear-light srgb colors to + # linear-light rec2020. + LINEAR_SRGB_TO_LINEAR_REC2020 = [ + 0.62740389593469900, 0.32928303837788370, 0.04331306568741722, + 0.06909728935823208, 0.91954039507545870, 0.01136231556630917, + 0.01639143887515027, 0.08801330787722575, 0.89559525324762400 + ].freeze + + # The transformation matrix for converting linear-light rec2020 colors to + # linear-light srgb. + LINEAR_REC2020_TO_LINEAR_SRGB = [ + 1.66049100210843450, -0.58764113878854950, -0.07284986331988487, + -0.12455047452159074, 1.13289989712596030, -0.00834942260436947, + -0.01815076335490530, -0.10057889800800737, 1.11872966136291270 + ].freeze + + # The transformation matrix for converting linear-light srgb colors to xyz. + LINEAR_SRGB_TO_XYZ_D65 = [ + 0.41239079926595950, 0.35758433938387796, 0.18048078840183430, + 0.21263900587151036, 0.71516867876775590, 0.07219231536073371, + 0.01933081871559185, 0.11919477979462598, 0.95053215224966060 + ].freeze + + # The transformation matrix for converting xyz colors to linear-light srgb. + XYZ_D65_TO_LINEAR_SRGB = [ + 3.24096994190452130, -1.53738317757009350, -0.49861076029300330, + -0.96924363628087980, 1.87596750150772060, 0.04155505740717561, + 0.05563007969699360, -0.20397695888897657, 1.05697151424287860 + ].freeze + + # The transformation matrix for converting linear-light srgb colors to lms. + LINEAR_SRGB_TO_LMS = [ + 0.41222146947076300, 0.53633253726173480, 0.05144599326750220, + 0.21190349581782520, 0.68069955064523420, 0.10739695353694050, + 0.08830245919005641, 0.28171883913612150, 0.62997870167382210 + ].freeze + + # The transformation matrix for converting lms colors to linear-light srgb. + LMS_TO_LINEAR_SRGB = [ + 4.07674163607595800, -3.30771153925806200, 0.23096990318210417, + -1.26843797328503200, 2.60975734928768900, -0.34131937600265710, + -0.00419607613867551, -0.70341861793593630, 1.70761469407461200 + ].freeze + + # The transformation matrix for converting linear-light srgb colors to + # linear-light prophoto-rgb. + LINEAR_SRGB_TO_LINEAR_PROPHOTO_RGB = [ + 0.52927697762261160, 0.33015450197849283, 0.14056852039889556, + 0.09836585954044917, 0.87347071290696180, 0.02816342755258900, + 0.01687534092138684, 0.11765941425612084, 0.86546524482249230 + ].freeze + + # The transformation matrix for converting linear-light prophoto-rgb colors to + # linear-light srgb. + LINEAR_PROPHOTO_RGB_TO_LINEAR_SRGB = [ + 2.03438084951699600, -0.72763578993413420, -0.30674505958286180, + -0.22882573163305037, 1.23174254119010480, -0.00291680955705449, + -0.00855882878391742, -0.15326670213803720, 1.16182553092195470 + ].freeze + + # The transformation matrix for converting linear-light srgb colors to + # xyz-d50. + LINEAR_SRGB_TO_XYZ_D50 = [ + 0.43606574687426936, 0.38515150959015960, 0.14307841996513868, + 0.22249317711056518, 0.71688701309448240, 0.06061980979495235, + 0.01392392146316939, 0.09708132423141015, 0.71409935681588070 + ].freeze + + # The transformation matrix for converting xyz-d50 colors to linear-light + # srgb. + XYZ_D50_TO_LINEAR_SRGB = [ + 3.13413585290011780, -1.61738599801804200, -0.49066221791109754, + -0.97879547655577770, 1.91625437739598840, 0.03344287339036693, + 0.07195539255794733, -0.22897675981518200, 1.40538603511311820 + ].freeze + + # The transformation matrix for converting linear-light display-p3 colors to + # linear-light a98-rgb. + LINEAR_DISPLAY_P3_TO_LINEAR_A98_RGB = [ + 0.86400513747404840, 0.13599486252595164, 0.00000000000000000, + -0.04205695470968816, 1.04205695470968800, 0.00000000000000000, + -0.02056038078232985, -0.03250613804550798, 1.05306651882783790 + ].freeze + + # The transformation matrix for converting linear-light a98-rgb colors to + # linear-light display-p3. + LINEAR_A98_RGB_TO_LINEAR_DISPLAY_P3 = [ + 1.15009441814101840, -0.15009441814101834, 0.00000000000000000, + 0.04641729862941844, 0.95358270137058150, 0.00000000000000000, + 0.02388759479083904, 0.02650477632633013, 0.94960762888283080 + ].freeze + + # The transformation matrix for converting linear-light display-p3 colors to + # linear-light rec2020. + LINEAR_DISPLAY_P3_TO_LINEAR_REC2020 = [ + 0.75383303436172180, 0.19859736905261630, 0.04756959658566187, + 0.04574384896535833, 0.94177721981169350, 0.01247893122294812, + -0.00121034035451832, 0.01760171730108989, 0.98360862305342840 + ].freeze + + # The transformation matrix for converting linear-light rec2020 colors to + # linear-light display-p3. + LINEAR_REC2020_TO_LINEAR_DISPLAY_P3 = [ + 1.34357825258433200, -0.28217967052613570, -0.06139858205819628, + -0.06529745278911953, 1.07578791584857460, -0.01049046305945495, + 0.00282178726170095, -0.01959849452449406, 1.01677670726279310 + ].freeze + + # The transformation matrix for converting linear-light display-p3 colors to + # xyz. + LINEAR_DISPLAY_P3_TO_XYZ_D65 = [ + 0.48657094864821626, 0.26566769316909294, 0.19821728523436250, + 0.22897456406974884, 0.69173852183650620, 0.07928691409374500, + 0.00000000000000000, 0.04511338185890257, 1.04394436890097570 + ].freeze + + # The transformation matrix for converting xyz colors to linear-light + # display-p3. + XYZ_D65_TO_LINEAR_DISPLAY_P3 = [ + 2.49349691194142450, -0.93138361791912360, -0.40271078445071684, + -0.82948896956157490, 1.76266406031834680, 0.02362468584194359, + 0.03584583024378433, -0.07617238926804170, 0.95688452400768730 + ].freeze + + # The transformation matrix for converting linear-light display-p3 colors to + # lms. + LINEAR_DISPLAY_P3_TO_LMS = [ + 0.48137985274995443, 0.46211837101131803, 0.05650177623872756, + 0.22883194181124472, 0.65321681938356760, 0.11795123880518774, + 0.08394575232299319, 0.22416527097756642, 0.69188897669944040 + ].freeze + + # The transformation matrix for converting lms colors to linear-light + # display-p3. + LMS_TO_LINEAR_DISPLAY_P3 = [ + 3.12776897136187370, -2.25713576259163860, 0.12936679122976494, + -1.09100901843779790, 2.41333171030692250, -0.32232269186912466, + -0.02601080193857045, -0.50804133170416700, 1.53405213364273730 + ].freeze + + # The transformation matrix for converting linear-light display-p3 colors to + # linear-light prophoto-rgb. + LINEAR_DISPLAY_P3_TO_LINEAR_PROPHOTO_RGB = [ + 0.63168691934035890, 0.21393038569465722, 0.15438269496498390, + 0.08320371426648458, 0.88586513676302430, 0.03093114897049121, + -0.00127273456473881, 0.05075510433665735, 0.95051763022808140 + ].freeze + + # The transformation matrix for converting linear-light prophoto-rgb colors to + # linear-light display-p3. + LINEAR_PROPHOTO_RGB_TO_LINEAR_DISPLAY_P3 = [ + 1.63257560870691790, -0.37977161848259840, -0.25280399022431950, + -0.15370040233755072, 1.16670254724250140, -0.01300214490495082, + 0.01039319529676572, -0.06280731264959440, 1.05241411735282870 + ].freeze + + # The transformation matrix for converting linear-light display-p3 colors to + # xyz-d50. + LINEAR_DISPLAY_P3_TO_XYZ_D50 = [ + 0.51514644296811600, 0.29200998206385770, 0.15713925139759397, + 0.24120032212525520, 0.69222254113138180, 0.06657713674336294, + -0.00105013914714014, 0.04187827018907460, 0.78427647146852570 + ].freeze + + # The transformation matrix for converting xyz-d50 colors to linear-light + # display-p3. + XYZ_D50_TO_LINEAR_DISPLAY_P3 = [ + 2.40393412185549730, -0.99003044249559310, -0.39761363181465614, + -0.84227001614546880, 1.79895801610670820, 0.01604562477090472, + 0.04819381686413303, -0.09738519815446048, 1.27367136933212730 + ].freeze + + # The transformation matrix for converting linear-light a98-rgb colors to + # linear-light rec2020. + LINEAR_A98_RGB_TO_LINEAR_REC2020 = [ + 0.87733384166365680, 0.07749370651571998, 0.04517245182062317, + 0.09662259146620378, 0.89152732024418050, 0.01185008828961569, + 0.02292106270284839, 0.04303668501067932, 0.93404225228647230 + ].freeze + + # The transformation matrix for converting linear-light rec2020 colors to + # linear-light a98-rgb. + LINEAR_REC2020_TO_LINEAR_A98_RGB = [ + 1.15197839471591630, -0.09750305530240860, -0.05447533941350766, + -0.12455047452159074, 1.13289989712596030, -0.00834942260436947, + -0.02253038278105590, -0.04980650742838876, 1.07233689020944460 + ].freeze + + # The transformation matrix for converting linear-light a98-rgb colors to xyz. + LINEAR_A98_RGB_TO_XYZ_D65 = [ + 0.57666904291013080, 0.18555823790654627, 0.18822864623499472, + 0.29734497525053616, 0.62736356625546600, 0.07529145849399789, + 0.02703136138641237, 0.07068885253582714, 0.99133753683763890 + ].freeze + + # The transformation matrix for converting xyz colors to linear-light a98-rgb. + XYZ_D65_TO_LINEAR_A98_RGB = [ + 2.04158790381074600, -0.56500697427885960, -0.34473135077832950, + -0.96924363628087980, 1.87596750150772060, 0.04155505740717561, + 0.01344428063203102, -0.11836239223101823, 1.01517499439120540 + ].freeze + + # The transformation matrix for converting linear-light a98-rgb colors to lms. + LINEAR_A98_RGB_TO_LMS = [ + 0.57643225961839410, 0.36991322261987963, 0.05365451776172635, + 0.29631647054222465, 0.59167613325218850, 0.11200739620558686, + 0.12347825101427760, 0.21949869837199862, 0.65702305061372380 + ].freeze + + # The transformation matrix for converting lms colors to linear-light a98-rgb. + LMS_TO_LINEAR_A98_RGB = [ + 2.55403683861155660, -1.62197618068286990, 0.06793934207131327, + -1.26843797328503200, 2.60975734928768900, -0.34131937600265710, + -0.05623473593749381, -0.56704183956690610, 1.62327657550439990 + ].freeze + + # The transformation matrix for converting linear-light a98-rgb colors to + # linear-light prophoto-rgb. + LINEAR_A98_RGB_TO_LINEAR_PROPHOTO_RGB = [ + 0.74011750180477920, 0.11327951328898105, 0.14660298490623970, + 0.13755046469802620, 0.83307708026948400, 0.02937245503248977, + 0.02359772990871766, 0.07378347703906656, 0.90261879305221580 + ].freeze + + # The transformation matrix for converting linear-light prophoto-rgb colors to + # linear-light a98-rgb. + LINEAR_PROPHOTO_RGB_TO_LINEAR_A98_RGB = [ + 1.38965124815152000, -0.16945907691487766, -0.22019217123664242, + -0.22882573163305037, 1.23174254119010480, -0.00291680955705449, + -0.01762544368426068, -0.09625702306122665, 1.11388246674548740 + ].freeze + + # The transformation matrix for converting linear-light a98-rgb colors to + # xyz-d50. + LINEAR_A98_RGB_TO_XYZ_D50 = [ + 0.60977504188618140, 0.20530000261929401, 0.14922063192409227, + 0.31112461220464155, 0.62565323083468560, 0.06322215696067286, + 0.01947059555648168, 0.06087908649415867, 0.74475492045981980 + ].freeze + + # The transformation matrix for converting xyz-d50 colors to linear-light + # a98-rgb. + XYZ_D50_TO_LINEAR_A98_RGB = [ + 1.96246703637688060, -0.61074234048150730, -0.34135809808271540, + -0.97879547655577770, 1.91625437739598840, 0.03344287339036693, + 0.02870443944957101, -0.14067486633170680, 1.34891418141379370 + ].freeze + + # The transformation matrix for converting linear-light rec2020 colors to xyz. + LINEAR_REC2020_TO_XYZ_D65 = [ + 0.63695804830129130, 0.14461690358620838, 0.16888097516417205, + 0.26270021201126703, 0.67799807151887100, 0.05930171646986194, + 0.00000000000000000, 0.02807269304908750, 1.06098505771079090 + ].freeze + + # The transformation matrix for converting xyz colors to linear-light rec2020. + XYZ_D65_TO_LINEAR_REC2020 = [ + 1.71665118797126760, -0.35567078377639240, -0.25336628137365980, + -0.66668435183248900, 1.61648123663493900, 0.01576854581391113, + 0.01763985744531091, -0.04277061325780865, 0.94210312123547400 + ].freeze + + # The transformation matrix for converting linear-light rec2020 colors to lms. + LINEAR_REC2020_TO_LMS = [ + 0.61675578486544440, 0.36019840122646335, 0.02304581390809228, + 0.26513305939263670, 0.63583937206784910, 0.09902756853951408, + 0.10010262952034828, 0.20390652261661452, 0.69599084786303720 + ].freeze + + # The transformation matrix for converting lms colors to linear-light rec2020. + LMS_TO_LINEAR_REC2020 = [ + 2.13990673043465130, -1.24638949376061800, 0.10648276332596668, + -0.88473583575776740, 2.16323093836120070, -0.27849510260343340, + -0.04857374640044396, -0.45450314971409640, 1.50307689611454040 + ].freeze + + # The transformation matrix for converting linear-light rec2020 colors to + # linear-light prophoto-rgb. + LINEAR_REC2020_TO_LINEAR_PROPHOTO_RGB = [ + 0.83518733312972350, 0.04886884858605698, 0.11594381828421951, + 0.05403324519953363, 0.92891840856920440, 0.01704834623126199, + -0.00234203897072539, 0.03633215316169465, 0.96600988580903070 + ].freeze + + # The transformation matrix for converting linear-light prophoto-rgb colors to + # linear-light rec2020. + LINEAR_PROPHOTO_RGB_TO_LINEAR_REC2020 = [ + 1.20065932951740800, -0.05756805370122346, -0.14309127581618444, + -0.06994154955888504, 1.08061789759721400, -0.01067634803832895, + 0.00554147334294746, -0.04078219298657951, 1.03524071964363200 + ].freeze + + # The transformation matrix for converting linear-light rec2020 colors to + # xyz-d50. + LINEAR_REC2020_TO_XYZ_D50 = [ + 0.67351546318827600, 0.16569726370390453, 0.12508294953738705, + 0.27905900514112060, 0.67531800574910980, 0.04562298910976962, + -0.00193242713400438, 0.02997782679282923, 0.79705920285163550 + ].freeze + + # The transformation matrix for converting xyz-d50 colors to linear-light + # rec2020. + XYZ_D50_TO_LINEAR_REC2020 = [ + 1.64718490467176600, -0.39368189813164710, -0.23595963848828266, + -0.68266410741738180, 1.64771461274440760, 0.01281708338512084, + 0.02966887665275675, -0.06292589642970030, 1.25355782018657710 + ].freeze + + # The transformation matrix for converting xyz colors to lms. + XYZ_D65_TO_LMS = [ + 0.81902243799670300, 0.36190626005289034, -0.12887378152098788, + 0.03298365393238846, 0.92928686158634330, 0.03614466635064235, + 0.04817718935962420, 0.26423953175273080, 0.63354782846943080 + ].freeze + + # The transformation matrix for converting lms colors to xyz. + LMS_TO_XYZ_D65 = [ + 1.22687987584592430, -0.55781499446021710, 0.28139104566596460, + -0.04057574521480084, 1.11228680328031730, -0.07171105806551635, + -0.07637293667466007, -0.42149333240224324, 1.58692401983678180 + ].freeze + + # The transformation matrix for converting xyz colors to linear-light + # prophoto-rgb. + XYZ_D65_TO_LINEAR_PROPHOTO_RGB = [ + 1.40319046337749790, -0.22301514479051668, -0.10160668507413790, + -0.52623840216330720, 1.48163196292346440, 0.01701879027252688, + -0.01120226528622150, 0.01824640347962099, 0.91124722749150480 + ].freeze + + # The transformation matrix for converting linear-light prophoto-rgb colors to + # xyz. + LINEAR_PROPHOTO_RGB_TO_XYZ_D65 = [ + 0.75559074229692100, 0.11271984265940525, 0.08214534209534540, + 0.26832184357857190, 0.71511525666179120, 0.01656289975963685, + 0.00391597276242580, -0.01293344283684181, 1.09807522083429450 + ].freeze + + # The transformation matrix for converting xyz colors to xyz-d50. + XYZ_D65_TO_XYZ_D50 = [ + 1.04792979254499660, 0.02294687060160952, -0.05019226628920519, + 0.02962780877005567, 0.99043442675388000, -0.01707379906341879, + -0.00924304064620452, 0.01505519149029816, 0.75187428142813700 + ].freeze + + # The transformation matrix for converting xyz-d50 colors to xyz. + XYZ_D50_TO_XYZ_D65 = [ + 0.95547342148807520, -0.02309845494876452, 0.06325924320057065, + -0.02836970933386358, 1.00999539808130410, 0.02104144119191730, + 0.01231401486448199, -0.02050764929889898, 1.33036592624212400 + ].freeze + + # The transformation matrix for converting lms colors to linear-light + # prophoto-rgb. + LMS_TO_LINEAR_PROPHOTO_RGB = [ + 1.73835514811572070, -0.98795094275144580, 0.24959579463572504, + -0.70704940153292660, 1.93437004444013820, -0.22732064290721150, + -0.08407882206239634, -0.35754060521141334, 1.44161942727380970 + ].freeze + + # The transformation matrix for converting linear-light prophoto-rgb colors to + # lms. + LINEAR_PROPHOTO_RGB_TO_LMS = [ + 0.71544846056555340, 0.35279155007721186, -0.06824001064276530, + 0.27441164900156710, 0.66779764984123670, 0.05779070115719616, + 0.10978443261622942, 0.18619829115002018, 0.70401727623375040 + ].freeze + + # The transformation matrix for converting lms colors to xyz-d50. + LMS_TO_XYZ_D50 = [ + 1.28858621817270600, -0.53787174449737450, 0.21358120275423640, + -0.00253387643187372, 1.09231679887191650, -0.08978292244004273, + -0.06937382305734124, -0.29500839894431263, 1.18948682451211420 + ].freeze + + # The transformation matrix for converting xyz-d50 colors to lms. + XYZ_D50_TO_LMS = [ + 0.77070004204311720, 0.34924840261939616, -0.11202351884164681, + 0.00559649248368848, 0.93707234011367690, 0.06972568836252771, + 0.04633714262191069, 0.25277531574310524, 0.85145807674679600 + ].freeze + + # The transformation matrix for converting linear-light prophoto-rgb colors to + # xyz-d50. + LINEAR_PROPHOTO_RGB_TO_XYZ_D50 = [ + 0.79776664490064230, 0.13518129740053308, 0.03134773412839220, + 0.28807482881940130, 0.71183523424187300, 0.00008993693872564, + 0.00000000000000000, 0.00000000000000000, 0.82510460251046020 + ].freeze + + # The transformation matrix for converting xyz-d50 colors to linear-light + # prophoto-rgb. + XYZ_D50_TO_LINEAR_PROPHOTO_RGB = [ + 1.34578688164715830, -0.25557208737979464, -0.05110186497554526, + -0.54463070512490190, 1.50824774284514680, 0.02052744743642139, + 0.00000000000000000, 0.00000000000000000, 1.21196754563894520 + ].freeze + end + + private_constant :Conversions + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method.rb new file mode 100644 index 0000000..5742ffb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/gamut_map_method.dart + module GamutMapMethod + # @return [::String] + attr_reader :name + + # @param name [::String] + def initialize(name) + @name = name + end + + class << self + # @param name [::String] + # @param argument_name [::String] + # @return [GamutMapMethod] + def from_name(name, argument_name = nil) + case name + when 'clip' + CLIP + when 'local-minde' + LOCAL_MINDE + else + raise Sass::ScriptError.new("Unknown gamut map method \"#{name}\".", argument_name) + end + end + end + + # @param color [Color] + # @return [Color] + def map(color) + raise NotImplementedError, "[BUG] gamut map method #{name} doesn't implement map." + end + end + + private_constant :GamutMapMethod + end + end +end + +require_relative 'gamut_map_method/clip' +require_relative 'gamut_map_method/local_minde' diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/clip.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/clip.rb new file mode 100644 index 0000000..81978b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/clip.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module GamutMapMethod + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/gamut_map_method/local_minde.dart + class Clip + include GamutMapMethod + + def initialize + super('clip') + end + + def map(color) + space = color.send(:_space) + Color.send(:for_space_internal, + space, + _clamp_channel(color.send(:channel0_or_nil), space.channels[0]), + _clamp_channel(color.send(:channel1_or_nil), space.channels[1]), + _clamp_channel(color.send(:channel2_or_nil), space.channels[2]), + color.send(:alpha_or_nil)) + end + + private + + def _clamp_channel(value, channel) + return nil if value.nil? + + case channel + when LinearChannel + FuzzyMath._clamp_like_css(value, channel.min, channel.max) + else + value + end + end + end + + private_constant :Clip + + CLIP = Clip.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/local_minde.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/local_minde.rb new file mode 100644 index 0000000..3aee459 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/gamut_map_method/local_minde.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module GamutMapMethod + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/gamut_map_method/local_minde.dart + class LocalMinde + include GamutMapMethod + + # A constant from the gamut-mapping algorithm. + JND = 0.02 + + private_constant :JND + + # A constant from the gamut-mapping algorithm. + EPSILON = 0.0001 + + private_constant :EPSILON + + def initialize + super('local-minde') + end + + def map(color) + original_oklch = color.send(:_to_space, Space::OKLCH) + lightness = original_oklch.send(:channel0_or_nil) + hue = original_oklch.send(:channel2_or_nil) + alpha = original_oklch.send(:alpha_or_nil) + + if FuzzyMath.greater_than_or_equals?(lightness.nil? ? 0 : lightness, 1) + if color.legacy? + return Color.send(:_for_space, + Space::RGB, 255, 255, 255, color.send(:alpha_or_nil)) + .send(:_to_space, color.send(:_space)) + else + return Color.send(:for_space_internal, + color.send(:_space), 1, 1, 1, color.send(:alpha_or_nil)) + end + elsif FuzzyMath.less_than_or_equals?(lightness.nil? ? 0 : lightness, 0) + return Color.send(:_for_space, + Space::RGB, 0, 0, 0, color.send(:alpha_or_nil)) + .send(:_to_space, color.send(:_space)) + end + + clipped = color.send(:_to_gamut, CLIP) + return clipped if _delta_eok(clipped, color) < JND + + min = 0.0 + max = original_oklch.send(:channel1) + min_in_gamut = true + while max - min > EPSILON + chroma = (min + max) / 2 + + current = Space::OKLCH.convert(color.send(:_space), lightness, chroma, hue, alpha) + + if min_in_gamut && current.in_gamut? + min = chroma + next + end + + clipped = current.send(:_to_gamut, CLIP) + e = _delta_eok(clipped, current) + + if e < JND + return clipped if JND - e < EPSILON + + min_in_gamut = false + min = chroma + else + max = chroma + end + end + clipped + end + + private + + def _delta_eok(color1, color2) + lab1 = color1.send(:_to_space, Space::OKLAB) + lab2 = color2.send(:_to_space, Space::OKLAB) + Math.sqrt(((lab1.send(:channel0) - lab2.send(:channel0))**2) + + ((lab1.send(:channel1) - lab2.send(:channel1))**2) + + ((lab1.send(:channel2) - lab2.send(:channel2))**2)) + end + end + + private_constant :LocalMinde + + LOCAL_MINDE = LocalMinde.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/interpolation_method.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/interpolation_method.rb new file mode 100644 index 0000000..a4cc1e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/interpolation_method.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/interpolation_method.dart + class InterpolationMethod + # @return [Space] + attr_reader :space + + # @return [Symbol, nil] + attr_reader :hue + + # @param space [Space] + # @param hue [Symbol] + def initialize(space, hue = nil) + @space = space + @hue = if space.polar? + hue.nil? ? :shorter : hue + end + + return unless !space.polar? && !hue.nil? + + raise Sass::ScriptError, + "Hue interpolation method may not be set for rectangular color space #{space.name}." + end + end + + private_constant :InterpolationMethod + + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/interpolation_method.dart + module HueInterpolationMethod + class << self + # @param name [::String] + # @param argument_name [::String] + # @return [Symbol] + def from_name(name, argument_name = nil) + case name + when 'decreasing', 'increasing', 'longer', 'shorter' + name.to_sym + else + raise Sass::ScriptError.new("Unknown hue interpolation method \"#{name}\".", argument_name) + end + end + end + end + + private_constant :HueInterpolationMethod + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space.rb new file mode 100644 index 0000000..ea00a0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space.rb @@ -0,0 +1,201 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space.dart + module Space + # @return [::String] + attr_reader :name + + # @return [Array] + attr_reader :channels + + # @return [::Boolean] + def bounded? + raise NotImplementedError + end + + # @return [::Boolean] + def legacy? + false + end + + # @return [::Boolean] + def polar? + false + end + + # @param name [::String] + # @param channels [Array] + def initialize(name, channels) + @name = name + @channels = channels + end + + class << self + # @param name [::String] + # @param argument_name [::String] + # @return [Space] + def from_name(name, argument_name = nil) + case name.downcase + when 'rgb' + RGB + when 'hwb' + HWB + when 'hsl' + HSL + when 'srgb' + SRGB + when 'srgb-linear' + SRGB_LINEAR + when 'display-p3' + DISPLAY_P3 + when 'display-p3-linear' + DISPLAY_P3_LINEAR + when 'a98-rgb' + A98_RGB + when 'prophoto-rgb' + PROPHOTO_RGB + when 'rec2020' + REC2020 + when 'xyz', 'xyz-d65' + XYZ_D65 + when 'xyz-d50' + XYZ_D50 + when 'lab' + LAB + when 'lch' + LCH + when 'oklab' + OKLAB + when 'oklch' + OKLCH + else + raise Sass::ScriptError.new("Unknown color space \"#{name}\".", argument_name) + end + end + end + + # @param dest [Space] + # @param channel0 [Numeric] + # @param channel1 [Numeric] + # @param channel2 [Numeric] + # @param alpha [Numeric] + # @return [Color] + def convert(dest, channel0, channel1, channel2, alpha) + convert_linear(dest, channel0, channel1, channel2, alpha) + end + + protected + + def convert_linear(dest, red, green, blue, alpha, + missing_lightness: false, + missing_chroma: false, + missing_hue: false, + missing_a: false, + missing_b: false) + linear_dest = case dest + when HSL, HWB + SRGB + when LAB, LCH + XYZ_D50 + when OKLAB, OKLCH + LMS + else + dest + end + if linear_dest == self + transformed_red = red + transformed_green = green + transformed_blue = blue + else + linear_red = to_linear(red.nil? ? 0 : red) + linear_green = to_linear(green.nil? ? 0 : green) + linear_blue = to_linear(blue.nil? ? 0 : blue) + matrix = transformation_matrix(linear_dest) + + # (matrix * [linear_red, linear_green, linear_blue]).map(linear_dest.from_linear) + transformed_red = linear_dest.from_linear((matrix[0] * linear_red) + + (matrix[1] * linear_green) + + (matrix[2] * linear_blue)) + transformed_green = linear_dest.from_linear((matrix[3] * linear_red) + + (matrix[4] * linear_green) + + (matrix[5] * linear_blue)) + transformed_blue = linear_dest.from_linear((matrix[6] * linear_red) + + (matrix[7] * linear_green) + + (matrix[8] * linear_blue)) + end + + case dest + when HSL, HWB + SRGB.convert(dest, transformed_red, transformed_green, transformed_blue, alpha, + missing_lightness:, + missing_chroma:, + missing_hue:) + when LAB, LCH + XYZ_D50.convert(dest, transformed_red, transformed_green, transformed_blue, alpha, + missing_lightness:, + missing_chroma:, + missing_hue:, + missing_a:, + missing_b:) + when OKLAB, OKLCH + LMS.convert(dest, transformed_red, transformed_green, transformed_blue, alpha, + missing_lightness:, + missing_chroma:, + missing_hue:, + missing_a:, + missing_b:) + else + Color.send(:_for_space, + dest, + red.nil? ? nil : transformed_red, + green.nil? ? nil : transformed_green, + blue.nil? ? nil : transformed_blue, + alpha) + end + end + + # @param channel [Numeric] + # @return [Numeric] + def to_linear(channel) + raise NotImplementedError, "[BUG] Color space #{name} doesn't support linear conversions." + end + + # @param channel [Numeric] + # @return [Numeric] + def from_linear(channel) + raise NotImplementedError, "[BUG] Color space #{name} doesn't support linear conversions." + end + + # @param dest [Space] + # @return [Array] + def transformation_matrix(dest) + raise NotImplementedError, "[BUG] Color space conversion from #{name} to #{dest.name} not implemented." + end + end + + private_constant :Space + end + end +end + +require_relative 'space/utils' +require_relative 'space/a98_rgb' +require_relative 'space/display_p3' +require_relative 'space/display_p3_linear' +require_relative 'space/hsl' +require_relative 'space/hwb' +require_relative 'space/lab' +require_relative 'space/lch' +require_relative 'space/lms' +require_relative 'space/oklab' +require_relative 'space/oklch' +require_relative 'space/prophoto_rgb' +require_relative 'space/rec2020' +require_relative 'space/rgb' +require_relative 'space/srgb' +require_relative 'space/srgb_linear' +require_relative 'space/xyz_d50' +require_relative 'space/xyz_d65' diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/a98_rgb.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/a98_rgb.rb new file mode 100644 index 0000000..a826e68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/a98_rgb.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/a98_rgb.dart + class A98Rgb + include Space + + def bounded? + true + end + + def initialize + super('a98-rgb', Utils::RGB_CHANNELS) + end + + def to_linear(channel) + (channel <=> 0) * (channel.abs**(563 / 256.0)) + end + + def from_linear(channel) + (channel <=> 0) * (channel.abs**(256 / 563.0)) + end + + private + + def transformation_matrix(dest) + case dest + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::LINEAR_A98_RGB_TO_LINEAR_DISPLAY_P3 + when LMS + Conversions::LINEAR_A98_RGB_TO_LMS + when PROPHOTO_RGB + Conversions::LINEAR_A98_RGB_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::LINEAR_A98_RGB_TO_LINEAR_REC2020 + when RGB, SRGB, SRGB_LINEAR + Conversions::LINEAR_A98_RGB_TO_LINEAR_SRGB + when XYZ_D50 + Conversions::LINEAR_A98_RGB_TO_XYZ_D50 + when XYZ_D65 + Conversions::LINEAR_A98_RGB_TO_XYZ_D65 + else + super + end + end + end + + private_constant :A98Rgb + + A98_RGB = A98Rgb.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3.rb new file mode 100644 index 0000000..a8f4995 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/display_p3.dart + class DisplayP3 + include Space + + def bounded? + true + end + + def initialize + super('display-p3', Utils::RGB_CHANNELS) + end + + def convert(dest, red, green, blue, alpha) + if dest == DISPLAY_P3_LINEAR + Color.send( + :for_space_internal, + dest, + red.nil? ? nil : to_linear(red), + green.nil? ? nil : to_linear(green), + blue.nil? ? nil : to_linear(blue), + alpha + ) + else + convert_linear(dest, red, green, blue, alpha) + end + end + + def to_linear(channel) + Utils.srgb_and_display_p3_to_linear(channel) + end + + def from_linear(channel) + Utils.srgb_and_display_p3_from_linear(channel) + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_A98_RGB + when LMS + Conversions::LINEAR_DISPLAY_P3_TO_LMS + when PROPHOTO_RGB + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_REC2020 + when RGB, SRGB, SRGB_LINEAR + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_SRGB + when XYZ_D50 + Conversions::LINEAR_DISPLAY_P3_TO_XYZ_D50 + when XYZ_D65 + Conversions::LINEAR_DISPLAY_P3_TO_XYZ_D65 + else + super + end + end + end + + private_constant :DisplayP3 + + DISPLAY_P3 = DisplayP3.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3_linear.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3_linear.rb new file mode 100644 index 0000000..2b8b1a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/display_p3_linear.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/display_p3_linear.dart + class DisplayP3Linear + include Space + + def bounded? + true + end + + def initialize + super('display-p3-linear', Utils::RGB_CHANNELS) + end + + def convert(dest, red, green, blue, alpha) + if dest == DISPLAY_P3 + Color.send( + :for_space_internal, + dest, + red.nil? ? nil : Utils.srgb_and_display_p3_from_linear(red), + green.nil? ? nil : Utils.srgb_and_display_p3_from_linear(green), + blue.nil? ? nil : Utils.srgb_and_display_p3_from_linear(blue), + alpha + ) + else + super + end + end + + def to_linear(channel) + channel + end + + def from_linear(channel) + channel + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_A98_RGB + when LMS + Conversions::LINEAR_DISPLAY_P3_TO_LMS + when PROPHOTO_RGB + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_REC2020 + when RGB, SRGB, SRGB_LINEAR + Conversions::LINEAR_DISPLAY_P3_TO_LINEAR_SRGB + when XYZ_D50 + Conversions::LINEAR_DISPLAY_P3_TO_XYZ_D50 + when XYZ_D65 + Conversions::LINEAR_DISPLAY_P3_TO_XYZ_D65 + else + super + end + end + end + + private_constant :DisplayP3Linear + + DISPLAY_P3_LINEAR = DisplayP3Linear.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hsl.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hsl.rb new file mode 100644 index 0000000..78b4702 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hsl.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/hsl.dart + class Hsl + include Space + + def bounded? + true + end + + def legacy? + true + end + + def polar? + true + end + + def initialize + super('hsl', [ + Utils::HUE_CHANNEL, + LinearChannel.new('saturation', 0, 100, requires_percent: true, lower_clamped: true).freeze, + LinearChannel.new('lightness', 0, 100, requires_percent: true).freeze + ].freeze) + end + + def convert(dest, hue, saturation, lightness, alpha) + missing_lightness = lightness.nil? + missing_chroma = saturation.nil? + missing_hue = hue.nil? + + hue = ((hue.nil? ? 0 : hue) % 360) / 30.0 + saturation = (saturation.nil? ? 0 : saturation) / 100.0 + lightness = (lightness.nil? ? 0 : lightness) / 100.0 + + a = saturation * [lightness, 1 - lightness].min + f = lambda do |n| + k = (n + hue) % 12 + lightness - (a * [-1, [k - 3, 9 - k, 1].min].max) + end + + SRGB.convert( + dest, + f.call(0), + f.call(8), + f.call(4), + alpha, + missing_lightness:, + missing_chroma:, + missing_hue: + ) + end + end + + private_constant :Hsl + + HSL = Hsl.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hwb.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hwb.rb new file mode 100644 index 0000000..76d141a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/hwb.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/hwb.dart + class Hwb + include Space + + def bounded? + true + end + + def legacy? + true + end + + def polar? + true + end + + def initialize + super('hwb', [ + Utils::HUE_CHANNEL, + LinearChannel.new('whiteness', 0, 100, requires_percent: true).freeze, + LinearChannel.new('blackness', 0, 100, requires_percent: true).freeze + ].freeze) + end + + def convert(dest, hue, whiteness, blackness, alpha) + missing_hue = hue.nil? + + hue = ((hue.nil? ? 0 : hue) % 360) / 30.0 + whiteness = (whiteness.nil? ? 0 : whiteness) / 100.0 + blackness = (blackness.nil? ? 0 : blackness) / 100.0 + + sum = whiteness + blackness + if sum > 1 + gray = whiteness / sum + SRGB.convert(dest, + gray, + gray, + gray, + alpha, + missing_hue:) + else + f = lambda do |n| + k = (n + hue) % 12 + 0.5 - ([-1, [k - 3, 9 - k, 1].min].max / 2.0) + end + + factor = 1 - sum + SRGB.convert(dest, + (f.call(0) * factor) + whiteness, + (f.call(8) * factor) + whiteness, + (f.call(4) * factor) + whiteness, + alpha, + missing_hue:) + end + end + end + + private_constant :Hwb + + HWB = Hwb.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lab.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lab.rb new file mode 100644 index 0000000..02b17e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lab.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/lab.dart + class Lab + include Space + + def bounded? + false + end + + def initialize + super('lab', [ + LinearChannel.new('lightness', 0, 100, lower_clamped: true, upper_clamped: true).freeze, + LinearChannel.new('a', -125, 125).freeze, + LinearChannel.new('b', -125, 125).freeze + ].freeze) + end + + def convert(dest, lightness, a, b, alpha, # rubocop:disable Naming/MethodParameterName + missing_chroma: false, missing_hue: false) + case dest + when LAB + powerless_ab = lightness.nil? || FuzzyMath.equals?(lightness, 0) + Color.send( + :_for_space, + dest, + lightness, + a.nil? || powerless_ab ? nil : a, + b.nil? || powerless_ab ? nil : b, + alpha + ) + when LCH + Utils.lab_to_lch(dest, lightness, a, b, alpha) + else + missing_lightness = lightness.nil? + lightness = 0 if missing_lightness + + f1 = (lightness + 16) / 116.0 + + XYZ_D50.convert( + dest, + _convert_f_to_x_or_z(((a.nil? ? 0 : a) / 500.0) + f1) * Conversions::D50[0], + (if lightness > Utils::LAB_KAPPA * Utils::LAB_EPSILON + (((lightness + 16) / 116.0)**3) + else + lightness / Utils::LAB_KAPPA + end) * Conversions::D50[1], + _convert_f_to_x_or_z(f1 - ((b.nil? ? 0 : b) / 200.0)) * Conversions::D50[2], + alpha, + missing_lightness:, + missing_chroma:, + missing_hue:, + missing_a: a.nil?, + missing_b: b.nil? + ) + end + end + + private + + def _convert_f_to_x_or_z(component) + cubed = component**3 + cubed > Utils::LAB_EPSILON ? cubed : ((116 * component) - 16) / Utils::LAB_KAPPA + end + end + + private_constant :Lab + + LAB = Lab.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lch.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lch.rb new file mode 100644 index 0000000..7731902 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lch.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/lch.dart + class Lch + include Space + + def bounded? + false + end + + def polar? + true + end + + def initialize + super('lch', [ + LinearChannel.new('lightness', 0, 100, lower_clamped: true, upper_clamped: true).freeze, + LinearChannel.new('chroma', 0, 150, lower_clamped: true).freeze, + Utils::HUE_CHANNEL + ].freeze) + end + + def convert(dest, lightness, chroma, hue, alpha) + missing_chroma = chroma.nil? + missing_hue = hue.nil? + + chroma = 0 if missing_chroma + hue = 0 if missing_hue + + hue_radians = hue * Math::PI / 180 + LAB.convert( + dest, + lightness, + chroma * Math.cos(hue_radians), + chroma * Math.sin(hue_radians), + alpha, + missing_chroma:, + missing_hue: + ) + end + end + + private_constant :Lch + + LCH = Lch.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lms.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lms.rb new file mode 100644 index 0000000..13d16d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/lms.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/lms.dart + class Lms + include Space + + def bounded? + false + end + + def initialize + super('lms', [ + LinearChannel.new('long', 0, 1).freeze, + LinearChannel.new('medium', 0, 1).freeze, + LinearChannel.new('short', 0, 1).freeze + ].freeze) + end + + def convert(dest, long, medium, short, alpha, + missing_lightness: false, + missing_chroma: false, + missing_hue: false, + missing_a: false, + missing_b: false) + case dest + when OKLAB + long_scaled = Math.cbrt(long.nil? ? 0 : long) + medium_scaled = Math.cbrt(medium.nil? ? 0 : medium) + short_scaled = Math.cbrt(short.nil? ? 0 : short) + + Color.send( + :_for_space, + dest, + unless missing_lightness + (Conversions::LMS_TO_OKLAB[0] * long_scaled) + + (Conversions::LMS_TO_OKLAB[1] * medium_scaled) + + (Conversions::LMS_TO_OKLAB[2] * short_scaled) + end, + unless missing_a + (Conversions::LMS_TO_OKLAB[3] * long_scaled) + + (Conversions::LMS_TO_OKLAB[4] * medium_scaled) + + (Conversions::LMS_TO_OKLAB[5] * short_scaled) + end, + unless missing_b + (Conversions::LMS_TO_OKLAB[6] * long_scaled) + + (Conversions::LMS_TO_OKLAB[7] * medium_scaled) + + (Conversions::LMS_TO_OKLAB[8] * short_scaled) + end, + alpha + ) + when OKLCH + long_scaled = Math.cbrt(long.nil? ? 0 : long) + medium_scaled = Math.cbrt(medium.nil? ? 0 : medium) + short_scaled = Math.cbrt(short.nil? ? 0 : short) + + Utils.lab_to_lch( + dest, + unless missing_lightness + (Conversions::LMS_TO_OKLAB[0] * long_scaled) + + (Conversions::LMS_TO_OKLAB[1] * medium_scaled) + + (Conversions::LMS_TO_OKLAB[2] * short_scaled) + end, + unless missing_a + (Conversions::LMS_TO_OKLAB[3] * long_scaled) + + (Conversions::LMS_TO_OKLAB[4] * medium_scaled) + + (Conversions::LMS_TO_OKLAB[5] * short_scaled) + end, + unless missing_b + (Conversions::LMS_TO_OKLAB[6] * long_scaled) + + (Conversions::LMS_TO_OKLAB[7] * medium_scaled) + + (Conversions::LMS_TO_OKLAB[8] * short_scaled) + end, + alpha + ) + else + convert_linear(dest, long, medium, short, alpha, + missing_lightness:, + missing_chroma:, + missing_hue:, + missing_a:, + missing_b:) + end + end + + def to_linear(channel) + channel + end + + def from_linear(channel) + channel + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::LMS_TO_LINEAR_A98_RGB + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::LMS_TO_LINEAR_DISPLAY_P3 + when PROPHOTO_RGB + Conversions::LMS_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::LMS_TO_LINEAR_REC2020 + when RGB, SRGB, SRGB_LINEAR + Conversions::LMS_TO_LINEAR_SRGB + when XYZ_D50 + Conversions::LMS_TO_XYZ_D50 + when XYZ_D65 + Conversions::LMS_TO_XYZ_D65 + else + super + end + end + end + + private_constant :Lms + + LMS = Lms.new + + private_constant :LMS + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklab.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklab.rb new file mode 100644 index 0000000..d3179c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklab.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/oklab.dart + class Oklab + include Space + + def bounded? + false + end + + def initialize + super('oklab', [ + LinearChannel.new('lightness', 0, 1, + conventionally_percent: true, lower_clamped: true, upper_clamped: true).freeze, + LinearChannel.new('a', -0.4, 0.4).freeze, + LinearChannel.new('b', -0.4, 0.4).freeze + ].freeze) + end + + def convert(dest, lightness, a, b, alpha, # rubocop:disable Naming/MethodParameterName + missing_chroma: false, missing_hue: false) + case dest + when OKLCH + Utils.lab_to_lch(dest, lightness, a, b, alpha) + else + missing_lightness = lightness.nil? + missing_a = a.nil? + missing_b = b.nil? + + lightness = 0 if missing_lightness + a = 0 if missing_a + b = 0 if missing_b + + LMS.convert( + dest, + ((Conversions::OKLAB_TO_LMS[0] * lightness) + + (Conversions::OKLAB_TO_LMS[1] * a) + + (Conversions::OKLAB_TO_LMS[2] * b))**3, + ((Conversions::OKLAB_TO_LMS[3] * lightness) + + (Conversions::OKLAB_TO_LMS[4] * a) + + (Conversions::OKLAB_TO_LMS[5] * b))**3, + ((Conversions::OKLAB_TO_LMS[6] * lightness) + + (Conversions::OKLAB_TO_LMS[7] * a) + + (Conversions::OKLAB_TO_LMS[8] * b))**3, + alpha, + missing_lightness:, + missing_chroma:, + missing_hue:, + missing_a:, + missing_b: + ) + end + end + end + + private_constant :Oklab + + OKLAB = Oklab.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklch.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklch.rb new file mode 100644 index 0000000..3096320 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/oklch.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/oklch.dart + class Oklch + include Space + + def bounded? + false + end + + def polar? + true + end + + def initialize + super('oklch', [ + LinearChannel.new('lightness', 0, 1, + conventionally_percent: true, lower_clamped: true, upper_clamped: true).freeze, + LinearChannel.new('chroma', 0, 0.4, lower_clamped: true).freeze, + Utils::HUE_CHANNEL + ].freeze) + end + + def convert(dest, lightness, chroma, hue, alpha) + missing_chroma = chroma.nil? + missing_hue = hue.nil? + + chroma = 0 if missing_chroma + hue = 0 if missing_hue + + hue_radians = hue * Math::PI / 180 + OKLAB.convert( + dest, + lightness, + chroma * Math.cos(hue_radians), + chroma * Math.sin(hue_radians), + alpha, + missing_chroma:, + missing_hue: + ) + end + end + + private_constant :Oklch + + OKLCH = Oklch.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/prophoto_rgb.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/prophoto_rgb.rb new file mode 100644 index 0000000..9699805 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/prophoto_rgb.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/prophoto_rgb.dart + class ProphotoRgb + include Space + + def bounded? + true + end + + def initialize + super('prophoto-rgb', Utils::RGB_CHANNELS) + end + + def to_linear(channel) + abs = channel.abs + abs <= 16 / 512.0 ? channel / 16.0 : (channel <=> 0) * (abs**1.8) + end + + def from_linear(channel) + abs = channel.abs + abs >= 1 / 512.0 ? (channel <=> 0) * (abs**(1 / 1.8)) : 16 * channel + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::LINEAR_PROPHOTO_RGB_TO_LINEAR_A98_RGB + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::LINEAR_PROPHOTO_RGB_TO_LINEAR_DISPLAY_P3 + when LMS + Conversions::LINEAR_PROPHOTO_RGB_TO_LMS + when REC2020 + Conversions::LINEAR_PROPHOTO_RGB_TO_LINEAR_REC2020 + when RGB, SRGB, SRGB_LINEAR + Conversions::LINEAR_PROPHOTO_RGB_TO_LINEAR_SRGB + when XYZ_D50 + Conversions::LINEAR_PROPHOTO_RGB_TO_XYZ_D50 + when XYZ_D65 + Conversions::LINEAR_PROPHOTO_RGB_TO_XYZ_D65 + else + super + end + end + end + + private_constant :ProphotoRgb + + PROPHOTO_RGB = ProphotoRgb.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rec2020.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rec2020.rb new file mode 100644 index 0000000..29a3828 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rec2020.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/rec2020.dart + class Rec2020 + include Space + + # A constant used in the rec2020 gamma encoding/decoding functions. + ALPHA = 1.09929682680944 + + private_constant :ALPHA + + # A constant used in the rec2020 gamma encoding/decoding functions. + BETA = 0.018053968510807 + + private_constant :BETA + + def bounded? + true + end + + def initialize + super('rec2020', Utils::RGB_CHANNELS) + end + + def to_linear(channel) + abs = channel.abs + abs < BETA * 4.5 ? channel / 4.5 : (channel <=> 0) * (((abs + ALPHA - 1) / ALPHA)**(1 / 0.45)) + end + + def from_linear(channel) + abs = channel.abs + abs > BETA ? (channel <=> 0) * ((ALPHA * (abs**0.45)) - (ALPHA - 1)) : 4.5 * channel + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::LINEAR_REC2020_TO_LINEAR_A98_RGB + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::LINEAR_REC2020_TO_LINEAR_DISPLAY_P3 + when LMS + Conversions::LINEAR_REC2020_TO_LMS + when PROPHOTO_RGB + Conversions::LINEAR_REC2020_TO_LINEAR_PROPHOTO_RGB + when RGB, SRGB, SRGB_LINEAR + Conversions::LINEAR_REC2020_TO_LINEAR_SRGB + when XYZ_D50 + Conversions::LINEAR_REC2020_TO_XYZ_D50 + when XYZ_D65 + Conversions::LINEAR_REC2020_TO_XYZ_D65 + else + super + end + end + end + + private_constant :Rec2020 + + REC2020 = Rec2020.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rgb.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rgb.rb new file mode 100644 index 0000000..a872e0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/rgb.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/rgb.dart + class Rgb + include Space + + def bounded? + true + end + + def legacy? + true + end + + def initialize + super('rgb', [ + LinearChannel.new('red', 0, 255, lower_clamped: true, upper_clamped: true).freeze, + LinearChannel.new('green', 0, 255, lower_clamped: true, upper_clamped: true).freeze, + LinearChannel.new('blue', 0, 255, lower_clamped: true, upper_clamped: true).freeze + ].freeze) + end + + def convert(dest, red, green, blue, alpha) + SRGB.convert( + dest, + red.nil? ? nil : red / 255.0, + green.nil? ? nil : green / 255.0, + blue.nil? ? nil : blue / 255.0, + alpha + ) + end + + def to_linear(channel) + Utils.srgb_and_display_p3_to_linear(channel / 255.0) + end + + def from_linear(channel) + Utils.srgb_and_display_p3_from_linear(channel) * 255 + end + end + + private_constant :Rgb + + RGB = Rgb.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb.rb new file mode 100644 index 0000000..0524572 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/srgb.dart + class Srgb + include Space + + def bounded? + true + end + + def initialize + super('srgb', Utils::RGB_CHANNELS) + end + + def convert(dest, red, green, blue, alpha, + missing_lightness: false, + missing_chroma: false, + missing_hue: false) + case dest + when HSL, HWB + red = 0 if red.nil? + green = 0 if green.nil? + blue = 0 if blue.nil? + + min, max = [red, green, blue].minmax + delta = max - min + + hue = if max == min + 0.0 + elsif max == red + (60.0 * (green - blue) / delta) + 360 + elsif max == green + (60.0 * (blue - red) / delta) + 120 + else # max == blue + (60.0 * (red - green) / delta) + 240 + end + + if dest == HSL + lightness = (min + max) / 2.0 + + saturation = if [0, 1].include?(lightness) + 0.0 + else + 100.0 * (max - lightness) / [lightness, 1 - lightness].min + end + if saturation.negative? + hue += 180 + saturation = saturation.abs + end + + Color.send( + :for_space_internal, + dest, + missing_hue || FuzzyMath.equals?(saturation, 0) ? nil : hue % 360, + missing_chroma ? nil : saturation, + missing_lightness ? nil : lightness * 100, + alpha + ) + else + whiteness = min * 100 + blackness = 100 - (max * 100) + + Color.send( + :for_space_internal, + dest, + missing_hue || FuzzyMath.greater_than_or_equals?(whiteness + blackness, 100) ? nil : hue % 360, + whiteness, + blackness, + alpha + ) + end + when RGB + Color.send( + :_for_space, + dest, + red.nil? ? nil : red * 255, + green.nil? ? nil : green * 255, + blue.nil? ? nil : blue * 255, + alpha + ) + when SRGB_LINEAR + Color.send( + :_for_space, + dest, + red.nil? ? nil : to_linear(red), + green.nil? ? nil : to_linear(green), + blue.nil? ? nil : to_linear(blue), + alpha + ) + else + convert_linear(dest, red, green, blue, alpha, + missing_lightness:, + missing_chroma:, + missing_hue:) + end + end + + def to_linear(channel) + Utils.srgb_and_display_p3_to_linear(channel) + end + + def from_linear(channel) + Utils.srgb_and_display_p3_from_linear(channel) + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::LINEAR_SRGB_TO_LINEAR_A98_RGB + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 + when LMS + Conversions::LINEAR_SRGB_TO_LMS + when PROPHOTO_RGB + Conversions::LINEAR_SRGB_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::LINEAR_SRGB_TO_LINEAR_REC2020 + when XYZ_D50 + Conversions::LINEAR_SRGB_TO_XYZ_D50 + when XYZ_D65 + Conversions::LINEAR_SRGB_TO_XYZ_D65 + else + super + end + end + end + + private_constant :Srgb + + SRGB = Srgb.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb_linear.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb_linear.rb new file mode 100644 index 0000000..b2b0f39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/srgb_linear.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/srgb_linear.dart + class SrgbLinear + include Space + + def bounded? + true + end + + def initialize + super('srgb-linear', Utils::RGB_CHANNELS) + end + + def convert(dest, red, green, blue, alpha) + case dest + when HSL, HWB, RGB, SRGB + SRGB.convert( + dest, + red.nil? ? nil : Utils.srgb_and_display_p3_from_linear(red), + green.nil? ? nil : Utils.srgb_and_display_p3_from_linear(green), + blue.nil? ? nil : Utils.srgb_and_display_p3_from_linear(blue), + alpha + ) + else + super + end + end + + def to_linear(channel) + channel + end + + def from_linear(channel) + channel + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::LINEAR_SRGB_TO_LINEAR_A98_RGB + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 + when PROPHOTO_RGB + Conversions::LINEAR_SRGB_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::LINEAR_SRGB_TO_LINEAR_REC2020 + when XYZ_D65 + Conversions::LINEAR_SRGB_TO_XYZ_D65 + when XYZ_D50 + Conversions::LINEAR_SRGB_TO_XYZ_D50 + when LMS + Conversions::LINEAR_SRGB_TO_LMS + else + super + end + end + end + + private_constant :SrgbLinear + + SRGB_LINEAR = SrgbLinear.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/utils.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/utils.rb new file mode 100644 index 0000000..6029266 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/utils.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/utils.dart + module Utils + module_function + + # A constant used to convert Lab to/from XYZ. + LAB_KAPPA = Rational(24_389, 27) # 29^3/3^3 + + # A constant used to convert Lab to/from XYZ. + LAB_EPSILON = Rational(216, 24_389) # 6^3/29^3 + + # The hue channel shared across all polar color spaces. + HUE_CHANNEL = ColorChannel.new('hue', polar_angle: true, associated_unit: 'deg').freeze + + # The color channels shared across all RGB color spaces (except the legacy RGB space). + RGB_CHANNELS = [ + LinearChannel.new('red', 0, 1).freeze, + LinearChannel.new('green', 0, 1).freeze, + LinearChannel.new('blue', 0, 1).freeze + ].freeze + + # The color channels shared across both XYZ color spaces. + XYZ_CHANNELS = [ + LinearChannel.new('x', 0, 1).freeze, + LinearChannel.new('y', 0, 1).freeze, + LinearChannel.new('z', 0, 1).freeze + ].freeze + + # The algorithm for converting a single `srgb` or `display-p3` channel to + # linear-light form. + # @param channel [Numeric] + # @return [Numeric] + def srgb_and_display_p3_to_linear(channel) + abs = channel.abs + abs <= 0.04045 ? channel / 12.92 : (channel <=> 0) * (((abs + 0.055) / 1.055)**2.4) + end + + # The algorithm for converting a single `srgb` or `display-p3` channel to + # gamma-corrected form. + # @param channel [Numeric] + # @return [Numeric] + def srgb_and_display_p3_from_linear(channel) + abs = channel.abs + abs <= 0.0031308 ? channel * 12.92 : (channel <=> 0) * ((1.055 * (abs**(1 / 2.4))) - 0.055) + end + + # Converts a Lab or OKLab color to LCH or OKLCH, respectively. + # + # The [missing_chroma] and [missing_hue] arguments indicate whether this came + # from a color that was missing its chroma or hue channels, respectively. + # @param dest [Space] + # @param lightness [Numeric] + # @param a [Numeric] + # @param b [Numeric] + # @param alpha [Numeric] + # @return [Color] + def lab_to_lch(dest, lightness, a, b, alpha, # rubocop:disable Naming/MethodParameterName + missing_chroma: false, missing_hue: false) + chroma = Math.sqrt(((a.nil? ? 0 : a)**2) + ((b.nil? ? 0 : b)**2)) + hue = if missing_hue || FuzzyMath.equals?(chroma, 0) + nil + else + Math.atan2(b.nil? ? 0 : b, a.nil? ? 0 : a) * 180 / Math::PI + end + + Color.send( + :for_space_internal, + dest, + lightness, + missing_chroma ? nil : chroma, + hue.nil? || hue >= 0 ? hue : hue + 360, + alpha + ) + end + end + + private_constant :Utils + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d50.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d50.rb new file mode 100644 index 0000000..b00c37d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d50.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/xyz_d50.dart + class XyzD50 + include Space + + def bounded? + false + end + + def initialize + super('xyz-d50', Utils::XYZ_CHANNELS) + end + + def convert(dest, x, y, z, alpha, # rubocop:disable Naming/MethodParameterName + missing_lightness: false, + missing_chroma: false, + missing_hue: false, + missing_a: false, + missing_b: false) + case dest + when LAB, LCH + f0 = _convert_component_to_lab_f((x.nil? ? 0 : x) / Conversions::D50[0]) + f1 = _convert_component_to_lab_f((y.nil? ? 0 : y) / Conversions::D50[1]) + f2 = _convert_component_to_lab_f((z.nil? ? 0 : z) / Conversions::D50[2]) + lightness = missing_lightness ? nil : (116 * f1) - 16 + a = 500 * (f0 - f1) + b = 200 * (f1 - f2) + + if dest == LAB + Color.send(:_for_space, + dest, + lightness, + missing_a ? nil : a, + missing_b ? nil : b, + alpha) + else + Utils.lab_to_lch(dest, lightness, a, b, alpha, missing_chroma:, missing_hue:) + end + else + convert_linear(dest, x, y, z, alpha, + missing_lightness:, + missing_chroma:, + missing_hue:, + missing_a:, + missing_b:) + end + end + + def to_linear(channel) + channel + end + + def from_linear(channel) + channel + end + + private + + def _convert_component_to_lab_f(component) + if component > Utils::LAB_EPSILON + Math.cbrt(component) + else + ((Utils::LAB_KAPPA * component) + 16) / 116.0 + end + end + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::XYZ_D50_TO_LINEAR_A98_RGB + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::XYZ_D50_TO_LINEAR_DISPLAY_P3 + when LMS + Conversions::XYZ_D50_TO_LMS + when PROPHOTO_RGB + Conversions::XYZ_D50_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::XYZ_D50_TO_LINEAR_REC2020 + when RGB, SRGB, SRGB_LINEAR + Conversions::XYZ_D50_TO_LINEAR_SRGB + when XYZ_D65 + Conversions::XYZ_D50_TO_XYZ_D65 + else + super + end + end + end + + private_constant :XyzD50 + + XYZ_D50 = XyzD50.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d65.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d65.rb new file mode 100644 index 0000000..2f9be68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/color/space/xyz_d65.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Sass + module Value + class Color + module Space + # @see https://github.com/sass/dart-sass/blob/main/lib/src/value/color/space/xyz_d65.dart + class XyzD65 + include Space + + def bounded? + false + end + + def initialize + super('xyz', Utils::XYZ_CHANNELS) + end + + def to_linear(channel) + channel + end + + def from_linear(channel) + channel + end + + private + + def transformation_matrix(dest) + case dest + when A98_RGB + Conversions::XYZ_D65_TO_LINEAR_A98_RGB + when DISPLAY_P3, DISPLAY_P3_LINEAR + Conversions::XYZ_D65_TO_LINEAR_DISPLAY_P3 + when LMS + Conversions::XYZ_D65_TO_LMS + when PROPHOTO_RGB + Conversions::XYZ_D65_TO_LINEAR_PROPHOTO_RGB + when REC2020 + Conversions::XYZ_D65_TO_LINEAR_REC2020 + when RGB, SRGB, SRGB_LINEAR + Conversions::XYZ_D65_TO_LINEAR_SRGB + when XYZ_D50 + Conversions::XYZ_D65_TO_XYZ_D50 + else + super + end + end + end + + private_constant :XyzD65 + + XYZ_D65 = XyzD65.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/function.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/function.rb new file mode 100644 index 0000000..7e926d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/function.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's function type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sassfunction/ + class Function + include Value + + # @param signature [::String] + # @param callback [Proc] + def initialize(signature, &callback) + @signature = signature.freeze + @callback = callback.freeze + end + + # @return [Object, nil] + protected attr_reader :compile_context + + # @return [Integer, nil] + protected attr_reader :id + + # @return [::String, nil] + attr_reader :signature + + # @return [Proc, nil] + attr_reader :callback + + # @return [::Boolean] + def ==(other) + return false unless other.is_a?(Sass::Value::Function) + + if defined?(@id) + other.compile_context == compile_context && other.id == id + else + other.signature == signature && other.callback == callback + end + end + + # @return [Integer] + def hash + @hash ||= defined?(@id) ? [compile_context, id].hash : [signature, callback].hash + end + + # @return [Function] + def assert_function(_name = nil) + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/fuzzy_math.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/fuzzy_math.rb new file mode 100644 index 0000000..37dcb14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/fuzzy_math.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's {FuzzyMath} module. + module FuzzyMath + PRECISION = 10 + + EPSILON = 10**(-PRECISION - 1) + + INVERSE_EPSILON = 10**(PRECISION + 1) + + module_function + + def equals?(number1, number2) + return true if number1 == number2 + + (number1 - number2).abs <= EPSILON && + (number1 * INVERSE_EPSILON).round == + (number2 * INVERSE_EPSILON).round + end + + def equals_nilable?(number1, number2) + return true if number1 == number2 + return false if number1.nil? || number2.nil? + + (number1 - number2).abs <= EPSILON && + (number1 * INVERSE_EPSILON).round == + (number2 * INVERSE_EPSILON).round + end + + def less_than?(number1, number2) + number1 < number2 && !equals?(number1, number2) + end + + def less_than_or_equals?(number1, number2) + number1 < number2 || equals?(number1, number2) + end + + def greater_than?(number1, number2) + number1 > number2 && !equals?(number1, number2) + end + + def greater_than_or_equals?(number1, number2) + number1 > number2 || equals?(number1, number2) + end + + def integer?(number) + return false unless number.finite? + + equals?(number, number.round) + end + + def to_i(number) + integer?(number) ? number.round : nil + end + + def between(number, min, max) + return min if equals?(number, min) + return max if equals?(number, max) + return number if number > min && number < max + + nil + end + + def assert_between(number, min, max, name) + result = between(number, min, max) + return result unless result.nil? + + raise Sass::ScriptError.new("#{number} must be between #{min} and #{max}.", name) + end + + def _clamp_like_css(number, lower_bound, upper_bound) + number.to_f.nan? ? lower_bound : number.clamp(lower_bound, upper_bound) + end + + def _hash(number) + number&.finite? ? (number * INVERSE_EPSILON).round : number + end + end + + private_constant :FuzzyMath + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/list.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/list.rb new file mode 100644 index 0000000..dac01e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/list.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's list type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sasslist/ + class List + include Value + + # @param contents [Array] + # @param separator [::String] + # @param bracketed [::Boolean] + def initialize(contents = [], separator: ',', bracketed: false) + if separator.nil? && contents.length > 1 + raise Sass::ScriptError, 'A list with more than one element must have an explicit separator' + end + + @contents = contents.freeze + @separator = separator.freeze + @bracketed = bracketed.freeze + end + + # @return [::String, nil] + attr_reader :separator + + # @return [::Boolean] + def bracketed? + @bracketed + end + + # @return [::Boolean] + def ==(other) + (other.is_a?(Sass::Value::List) && + other.to_a == to_a && + other.separator == separator && + other.bracketed? == bracketed?) || + (to_a.empty? && other.is_a?(Sass::Value::Map) && other.to_a.empty?) + end + + # @param index [Numeric] + # @return [Value] + def at(index) + index = index.floor + index = to_a.length + index if index.negative? + return nil if index.negative? || index >= to_a.length + + to_a[index] + end + + # @return [Integer] + def hash + @hash ||= contents.hash + end + + # @return [Array] + def to_a + @contents + end + + # @return [Map, nil] + def to_map + to_a.empty? ? Sass::Value::Map.new({}) : nil + end + + # @return [Map] + # @raise [ScriptError] + def assert_map(name = nil) + to_a.empty? ? Sass::Value::Map.new({}) : super.assert_map(name) + end + + private + + def to_a_length + to_a.length + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/map.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/map.rb new file mode 100644 index 0000000..8e1a62f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/map.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's map type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sassmap/ + class Map + include Value + + # @param contents [Hash] + def initialize(contents = {}) + @contents = contents.freeze + end + + # @return [Hash] + attr_reader :contents + + # @return [::String, nil] + def separator + contents.empty? ? nil : ',' + end + + # @return [::Boolean] + def ==(other) + (other.is_a?(Sass::Value::Map) && other.contents == contents) || + (contents.empty? && other.is_a?(Sass::Value::List) && other.to_a.empty?) + end + + # @param index [Numeric, Value] + # @return [List<(Value, Value)>, Value] + def at(index) + if index.is_a?(Numeric) + index = index.floor + index = to_a_length + index if index.negative? + return nil if index.negative? || index >= to_a_length + + Sass::Value::List.new(contents.to_a[index], separator: ' ') + else + contents[index] + end + end + + # @return [Integer] + def hash + @hash ||= contents.hash + end + + # @return [Array>] + def to_a + contents.map { |key, value| Sass::Value::List.new([key, value], separator: ' ') } + end + + # @return [Map] + def to_map + self + end + + # @return [Map] + def assert_map(_name = nil) + self + end + + private + + def to_a_length + contents.length + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/mixin.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/mixin.rb new file mode 100644 index 0000000..13b72ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/mixin.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's mixin type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sassmixin/ + class Mixin + include Value + + class << self + private :new + end + + # @return [Object] + protected attr_reader :compile_context + + # @return [Integer] + protected attr_reader :id + + # @return [::Boolean] + def ==(other) + other.is_a?(Sass::Value::Mixin) && other.compile_context == compile_context && other.id == id + end + + # @return [Integer] + def hash + @hash ||= [compile_context, id].hash + end + + # @return [Mixin] + def assert_mixin(_name = nil) + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/null.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/null.rb new file mode 100644 index 0000000..57e2391 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/null.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's null type. + # + # @see https://sass-lang.com/documentation/js-api/variables/sassnull/ + class Null + include Value + + def initialize + @value = nil + end + + # @return [nil] + attr_reader :value + + # @return [Boolean] + def ! + Boolean::TRUE + end + + # @return [::Boolean] + def ==(other) + other.is_a?(Sass::Value::Null) + end + + # @return [Integer] + def hash + @hash ||= value.hash + end + + # @return [::Boolean] + def to_bool # rubocop:disable Naming/PredicateMethod + false + end + + alias to_nil value + + # Sass's null value. + NULL = Null.new + + def self.new + NULL + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number.rb new file mode 100644 index 0000000..fe10901 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number.rb @@ -0,0 +1,364 @@ +# frozen_string_literal: true + +require_relative 'number/unit' + +module Sass + module Value + # Sass's number type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sassnumber/ + class Number + include Value + include CalculationValue + + # @param value [Numeric] + # @param unit [::String, Hash] + # @option unit [Array<::String>] :numerator_units + # @option unit [Array<::String>] :denominator_units + def initialize(value, unit = nil) + case unit + when nil + numerator_units = [] + denominator_units = [] + when ::String + numerator_units = [unit] + denominator_units = [] + when ::Hash + numerator_units = unit.fetch(:numerator_units, []) + unless numerator_units.is_a?(::Array) + raise Sass::ScriptError, "invalid numerator_units #{numerator_units.inspect}" + end + + denominator_units = unit.fetch(:denominator_units, []) + unless denominator_units.is_a?(::Array) + raise Sass::ScriptError, "invalid denominator_units #{denominator_units.inspect}" + end + else + raise Sass::ScriptError, "invalid unit #{unit.inspect}" + end + + unless denominator_units.empty? && numerator_units.empty? + value = value.dup + numerator_units = numerator_units.dup + new_denominator_units = [] + + denominator_units.each do |denominator_unit| + index = numerator_units.find_index do |numerator_unit| + factor = Unit.conversion_factor(denominator_unit, numerator_unit) + if factor.nil? + false + else + value *= factor + true + end + end + if index.nil? + new_denominator_units.push(denominator_unit) + else + numerator_units.delete_at(index) + end + end + + denominator_units = new_denominator_units + end + + @value = value.freeze + @numerator_units = numerator_units.each(&:freeze).freeze + @denominator_units = denominator_units.each(&:freeze).freeze + end + + # @return [Numeric] + attr_reader :value + + # @return [Array<::String>] + attr_reader :numerator_units, :denominator_units + + # @return [::Boolean] + def ==(other) + return false unless other.is_a?(Sass::Value::Number) + + return false if numerator_units.length != other.numerator_units.length || + denominator_units.length != other.denominator_units.length + + return FuzzyMath.equals?(value, other.value) if unitless? + + if Unit.canonicalize_units(numerator_units) != Unit.canonicalize_units(other.numerator_units) && + Unit.canonicalize_units(denominator_units) != Unit.canonicalize_units(other.denominator_units) + return false + end + + FuzzyMath.equals?( + value * + Unit.canonical_multiplier(numerator_units) / + Unit.canonical_multiplier(denominator_units), + other.value * + Unit.canonical_multiplier(other.numerator_units) / + Unit.canonical_multiplier(other.denominator_units) + ) + end + + # @return [Integer] + def hash + @hash ||= FuzzyMath._hash(canonical_units_value).hash + end + + # @return [::Boolean] + def unitless? + numerator_units.empty? && denominator_units.empty? + end + + # @return [Number] + # @raise [ScriptError] + def assert_unitless(name = nil) + raise Sass::ScriptError.new("Expected #{self} to have no units", name) unless unitless? + + self + end + + # @return [::Boolean] + def units? + !unitless? + end + + # @param unit [::String] + # @return [::Boolean] + def unit?(unit) + single_unit? && numerator_units.first == unit + end + + # @param unit [::String] + # @return [Number] + # @raise [ScriptError] + def assert_unit(unit, name = nil) + raise Sass::ScriptError.new("Expected #{self} to have unit #{unit.inspect}", name) unless unit?(unit) + + self + end + + # @return [::Boolean] + def integer? + FuzzyMath.integer?(value) + end + + # @return [Integer] + # @raise [ScriptError] + def assert_integer(name = nil) + raise Sass::ScriptError.new("#{self} is not an integer", name) unless integer? + + to_i + end + + # @return [Integer] + def to_i + FuzzyMath.to_i(value) + end + + # @param min [Numeric] + # @param max [Numeric] + # @return [Numeric] + # @raise [ScriptError] + def assert_between(min, max, name = nil) + FuzzyMath.assert_between(value, min, max, name) + end + + # @param unit [::String] + # @return [::Boolean] + def compatible_with_unit?(unit) + single_unit? && !Unit.conversion_factor(numerator_units.first, unit).nil? + end + + # @param new_numerator_units [Array<::String>] + # @param new_denominator_units [Array<::String>] + # @return [Number] + def convert(new_numerator_units, new_denominator_units, name = nil) + Number.new(convert_value(new_numerator_units, new_denominator_units, name), { + numerator_units: new_numerator_units, + denominator_units: new_denominator_units + }) + end + + # @param new_numerator_units [Array<::String>] + # @param new_denominator_units [Array<::String>] + # @return [Numeric] + def convert_value(new_numerator_units, new_denominator_units, name = nil) + coerce_or_convert_value(new_numerator_units, new_denominator_units, + coerce_unitless: false, + name:) + end + + # @param other [Number] + # @return [Number] + def convert_to_match(other, name = nil, other_name = nil) + Number.new(convert_value_to_match(other, name, other_name), { + numerator_units: other.numerator_units, + denominator_units: other.denominator_units + }) + end + + # @param other [Number] + # @return [Numeric] + def convert_value_to_match(other, name = nil, other_name = nil) + coerce_or_convert_value(other.numerator_units, other.denominator_units, + coerce_unitless: false, + name:, + other:, + other_name:) + end + + # @param new_numerator_units [Array<::String>] + # @param new_denominator_units [Array<::String>] + # @return [Number] + def coerce(new_numerator_units, new_denominator_units, name = nil) + Number.new(coerce_value(new_numerator_units, new_denominator_units, name), { + numerator_units: new_numerator_units, + denominator_units: new_denominator_units + }) + end + + # @param new_numerator_units [Array<::String>] + # @param new_denominator_units [Array<::String>] + # @return [Numeric] + def coerce_value(new_numerator_units, new_denominator_units, name = nil) + coerce_or_convert_value(new_numerator_units, new_denominator_units, + coerce_unitless: true, + name:) + end + + # @param unit [::String] + # @return [Numeric] + def coerce_value_to_unit(unit, name = nil) + coerce_value([unit], [], name) + end + + # @param other [Number] + # @return [Number] + def coerce_to_match(other, name = nil, other_name = nil) + Number.new(coerce_value_to_match(other, name, other_name), { + numerator_units: other.numerator_units, + denominator_units: other.denominator_units + }) + end + + # @param other [Number] + # @return [Numeric] + def coerce_value_to_match(other, name = nil, other_name = nil) + coerce_or_convert_value(other.numerator_units, other.denominator_units, + coerce_unitless: true, + name:, + other:, + other_name:) + end + + # @return [Number] + def assert_number(_name = nil) + self + end + + private + + def single_unit? + numerator_units.length == 1 && denominator_units.empty? + end + + def canonical_units_value + if unitless? + value + elsif single_unit? + value * Unit.canonical_multiplier_for_unit(numerator_units.first) + else + value * Unit.canonical_multiplier(numerator_units) / Unit.canonical_multiplier(denominator_units) + end + end + + def coerce_or_convert_value(new_numerator_units, new_denominator_units, + coerce_unitless:, + name: nil, + other: nil, + other_name: nil) + unless other.nil? || + (other.numerator_units == new_numerator_units && other.denominator_units == new_denominator_units) + raise Sass::ScriptError, + "Expected #{other} to have units #{unit_string(new_numerator_units, new_denominator_units).inspect}" + end + + return value if numerator_units == new_numerator_units && denominator_units == new_denominator_units + + other_unitless = new_numerator_units.empty? && new_denominator_units.empty? + return value if coerce_unitless && (unitless? || other_unitless) + + compatibility_error = lambda { + unless other.nil? + message = "#{self} and" + message << " $#{other_name}:" unless other_name.nil? + message << " #{other} have incompatible units" + message << " (one has units and the other doesn't)" if unitless? || other_unitless + return Sass::ScriptError.new(message, name) + end + + return Sass::ScriptError.new("Expected #{self} to have no units", name) unless other_unitless + + if new_numerator_units.length == 1 && new_denominator_units.empty? + type = Unit::TYPES_BY_UNIT[new_numerator_units.first] + return Sass::ScriptError.new( + "Expected #{self} to have a #{type} unit (#{Unit::UNITS_BY_TYPE[type].join(', ')})", name + ) + end + + unit_length = new_numerator_units.length + new_denominator_units.length + units = unit_string(new_numerator_units, new_denominator_units) + Sass::ScriptError.new("Expected #{self} to have unit#{'s' if unit_length > 1} #{units}", name) + } + + result = value + + old_numerator_units = numerator_units.dup + new_numerator_units.each do |new_numerator_unit| + index = old_numerator_units.find_index do |old_numerator_unit| + factor = Unit.conversion_factor(new_numerator_unit, old_numerator_unit) + if factor.nil? + false + else + result *= factor + true + end + end + raise compatibility_error.call if index.nil? + + old_numerator_units.delete_at(index) + end + + old_denominator_units = denominator_units.dup + new_denominator_units.each do |new_denominator_unit| + index = old_denominator_units.find_index do |old_denominator_unit| + factor = Unit.conversion_factor(new_denominator_unit, old_denominator_unit) + if factor.nil? + false + else + result /= factor + true + end + end + raise compatibility_error.call if index.nil? + + old_denominator_units.delete_at(index) + end + + raise compatibility_error.call unless old_numerator_units.empty? && old_denominator_units.empty? + + result + end + + def unit_string(numerator_units, denominator_units) + if numerator_units.empty? + return 'no units' if denominator_units.empty? + + return denominator_units.length == 1 ? "#{denominator_units.first}^-1" : "(#{denominator_units.join('*')})^-1" + end + + return numerator_units.join('*') if denominator_units.empty? + + "#{numerator_units.join('*')}/#{denominator_units.join('*')}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number/unit.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number/unit.rb new file mode 100644 index 0000000..7d7c776 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/number/unit.rb @@ -0,0 +1,187 @@ +# frozen_string_literal: true + +module Sass + module Value + class Number + # The {Unit} module. + module Unit + CONVERSIONS = { + # Length + 'in' => { + 'in' => Rational(1), + 'cm' => Rational(1, 2.54), + 'pc' => Rational(1, 6), + 'mm' => Rational(1, 25.4), + 'q' => Rational(1, 101.6), + 'pt' => Rational(1, 72), + 'px' => Rational(1, 96) + }, + 'cm' => { + 'in' => Rational(2.54), + 'cm' => Rational(1), + 'pc' => Rational(2.54, 6), + 'mm' => Rational(1, 10), + 'q' => Rational(1, 40), + 'pt' => Rational(2.54, 72), + 'px' => Rational(2.54, 96) + }, + 'pc' => { + 'in' => Rational(6), + 'cm' => Rational(6, 2.54), + 'pc' => Rational(1), + 'mm' => Rational(6, 25.4), + 'q' => Rational(6, 101.6), + 'pt' => Rational(1, 12), + 'px' => Rational(1, 16) + }, + 'mm' => { + 'in' => Rational(25.4), + 'cm' => Rational(10), + 'pc' => Rational(25.4, 6), + 'mm' => Rational(1), + 'q' => Rational(1, 4), + 'pt' => Rational(25.4, 72), + 'px' => Rational(25.4, 96) + }, + 'q' => { + 'in' => Rational(101.6), + 'cm' => Rational(40), + 'pc' => Rational(101.6, 6), + 'mm' => Rational(4), + 'q' => Rational(1), + 'pt' => Rational(101.6, 72), + 'px' => Rational(101.6, 96) + }, + 'pt' => { + 'in' => Rational(72), + 'cm' => Rational(72, 2.54), + 'pc' => Rational(12), + 'mm' => Rational(72, 25.4), + 'q' => Rational(72, 101.6), + 'pt' => Rational(1), + 'px' => Rational(3, 4) + }, + 'px' => { + 'in' => Rational(96), + 'cm' => Rational(96, 2.54), + 'pc' => Rational(16), + 'mm' => Rational(96, 25.4), + 'q' => Rational(96, 101.6), + 'pt' => Rational(4, 3), + 'px' => Rational(1) + }, + + # Rotation + 'deg' => { + 'deg' => Rational(1), + 'grad' => Rational(9, 10), + 'rad' => Rational(180, Math::PI), + 'turn' => Rational(360) + }, + 'grad' => { + 'deg' => Rational(10, 9), + 'grad' => Rational(1), + 'rad' => Rational(200, Math::PI), + 'turn' => Rational(400) + }, + 'rad' => { + 'deg' => Rational(Math::PI, 180), + 'grad' => Rational(Math::PI, 200), + 'rad' => Rational(1), + 'turn' => Rational(Math::PI * 2) + }, + 'turn' => { + 'deg' => Rational(1, 360), + 'grad' => Rational(1, 400), + 'rad' => Rational(1, Math::PI * 2), + 'turn' => Rational(1) + }, + + # Time + 's' => { + 's' => Rational(1), + 'ms' => Rational(1, 1000) + }, + 'ms' => { + 's' => Rational(1000), + 'ms' => Rational(1) + }, + + # Frequency + 'Hz' => { + 'Hz' => Rational(1), + 'kHz' => Rational(1000) + }, + 'kHz' => { + 'Hz' => Rational(1, 1000), + 'kHz' => Rational(1) + }, + + # Pixel density + 'dpi' => { + 'dpi' => Rational(1), + 'dpcm' => Rational(2.54), + 'dppx' => Rational(96) + }, + 'dpcm' => { + 'dpi' => Rational(1, 2.54), + 'dpcm' => Rational(1), + 'dppx' => Rational(96, 2.54) + }, + 'dppx' => { + 'dpi' => Rational(1, 96), + 'dpcm' => Rational(2.54, 96), + 'dppx' => Rational(1) + } + }.freeze + + UNITS_BY_TYPE = { + time: %w[s ms], + frequency: %w[Hz kHz], + 'pixel density': %w[dpi dpcm dppx] + }.freeze + + TYPES_BY_UNIT = UNITS_BY_TYPE.each_with_object({}) do |(key, values), hash| + values.each do |value| + hash[value] = key + end + end + + module_function + + def conversion_factor(unit1, unit2) + return 1 if unit1 == unit2 + + CONVERSIONS.dig(unit1, unit2) + end + + def canonicalize_units(units) + return units if units.empty? + + if units.length == 1 + type = TYPES_BY_UNIT[units.first] + return type.nil? ? units : [UNITS_BY_TYPE[type].first] + end + + units.map do |unit| + type = TYPES_BY_UNIT[unit] + type.nil? ? units : [UNITS_BY_TYPE[type].first] + end.sort + end + + def canonical_multiplier(units) + units.reduce(1) do |multiplier, unit| + multiplier * canonical_multiplier_for_unit(unit) + end + end + + def canonical_multiplier_for_unit(unit) + inner_map = CONVERSIONS[unit] + inner_map.nil? ? 1 : 1 / inner_map.values.first + end + end + + private_constant :Unit + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/string.rb b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/string.rb new file mode 100644 index 0000000..618dc76 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/sass-embedded-1.101.0-arm64-darwin/lib/sass/value/string.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module Sass + module Value + # Sass's string type. + # + # @see https://sass-lang.com/documentation/js-api/classes/sassstring/ + class String + include Value + include CalculationValue + + # @param text [::String] + # @param quoted [::Boolean] + def initialize(text = '', quoted: true) + @text = text.freeze + @quoted = quoted + end + + # @return [::String] + attr_reader :text + + # @return [::Boolean] + def quoted? + @quoted + end + + # @return [::Boolean] + def ==(other) + other.is_a?(Sass::Value::String) && other.text == text + end + + # @return [Integer] + def hash + @hash ||= text.hash + end + + # @return [String] + def assert_string(_name = nil) + self + end + + # @param sass_index [Number] + # @return [Integer] + def sass_index_to_string_index(sass_index, name = nil) + index = sass_index.assert_number(name).assert_integer(name) + raise Sass::ScriptError.new('String index may not be 0', name) if index.zero? + + if index.abs > text.length + raise Sass::ScriptError.new("Invalid index #{sass_index} for a string with #{text.length} characters", name) + end + + index.negative? ? text.length + index : index - 1 + end + + # @return [::String] + def to_s + @quoted ? Serializer.serialize_quoted_string(@text) : Serializer.serialize_unquoted_string(@text) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Gemfile b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Gemfile new file mode 100644 index 0000000..d069402 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Gemfile @@ -0,0 +1,10 @@ +source 'https://rubygems.org' + +gemspec + +gem "rake" +gem "test-unit" +gem "test-unit-ruby-core" + +# rbs requires ruby 3.0+ +gem "rbs", require: false if !RUBY_VERSION.start_with?('2.') diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/LICENSE.txt new file mode 100644 index 0000000..a009cae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/README.md b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/README.md new file mode 100644 index 0000000..685dc84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/README.md @@ -0,0 +1,63 @@ +# Webrick + +WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server. + +WEBrick features complete logging of both server operations and HTTP access. + +WEBrick supports both basic and digest authentication in addition to algorithms not in RFC 2617. + +A WEBrick server can be composed of multiple WEBrick servers or servlets to provide differing behavior on a per-host or per-path basis. WEBrick includes servlets for handling CGI scripts, ERB pages, Ruby blocks and directory listings. + +WEBrick also includes tools for daemonizing a process and starting a process at a higher privilege level and dropping permissions. + +WEBrick is suitable for use in testing and for development. However, while the developers of WEBrick will attempt to fix security issues, they do not encourage the use of WEBrick to serve production web applications that may be subject to hostile input. + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'webrick' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install webrick + +## Usage + +To create a new WEBrick::HTTPServer that will listen to connections on port 8000 and serve documents from the current user's public_html folder: + +```ruby +require 'webrick' + +root = File.expand_path '~/public_html' +server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root +``` + +To run the server you will need to provide a suitable shutdown hook as +starting the server blocks the current thread: + +```ruby +trap 'INT' do server.shutdown end + +server.start +``` + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/webrick. + +## License + +The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Rakefile b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Rakefile new file mode 100644 index 0000000..5d512c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/Rakefile @@ -0,0 +1,10 @@ +require "bundler/gem_tasks" +require "rake/testtask" + +Rake::TestTask.new(:test) do |t| + t.libs << "test/lib" + t.ruby_opts << "-rhelper" + t.test_files = FileList["test/**/test_*.rb"] +end + +task :default => :test diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick.rb new file mode 100644 index 0000000..b854b68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick.rb @@ -0,0 +1,232 @@ +# frozen_string_literal: false +## +# = WEB server toolkit. +# +# WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, +# a proxy server, and a virtual-host server. WEBrick features complete +# logging of both server operations and HTTP access. WEBrick supports both +# basic and digest authentication in addition to algorithms not in RFC 2617. +# +# A WEBrick server can be composed of multiple WEBrick servers or servlets to +# provide differing behavior on a per-host or per-path basis. WEBrick +# includes servlets for handling CGI scripts, ERB pages, Ruby blocks and +# directory listings. +# +# WEBrick also includes tools for daemonizing a process and starting a process +# at a higher privilege level and dropping permissions. +# +# == Security +# +# *Warning:* WEBrick is not recommended for production. It only implements +# basic security checks. +# +# == Starting an HTTP server +# +# To create a new WEBrick::HTTPServer that will listen to connections on port +# 8000 and serve documents from the current user's public_html folder: +# +# require 'webrick' +# +# root = File.expand_path '~/public_html' +# server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root +# +# To run the server you will need to provide a suitable shutdown hook as +# starting the server blocks the current thread: +# +# trap 'INT' do server.shutdown end +# +# server.start +# +# == Custom Behavior +# +# The easiest way to have a server perform custom operations is through +# WEBrick::HTTPServer#mount_proc. The block given will be called with a +# WEBrick::HTTPRequest with request info and a WEBrick::HTTPResponse which +# must be filled in appropriately: +# +# server.mount_proc '/' do |req, res| +# res.body = 'Hello, world!' +# end +# +# Remember that +server.mount_proc+ must precede +server.start+. +# +# == Servlets +# +# Advanced custom behavior can be obtained through mounting a subclass of +# WEBrick::HTTPServlet::AbstractServlet. Servlets provide more modularity +# when writing an HTTP server than mount_proc allows. Here is a simple +# servlet: +# +# class Simple < WEBrick::HTTPServlet::AbstractServlet +# def do_GET request, response +# status, content_type, body = do_stuff_with request +# +# response.status = 200 +# response['Content-Type'] = 'text/plain' +# response.body = 'Hello, World!' +# end +# end +# +# To initialize the servlet you mount it on the server: +# +# server.mount '/simple', Simple +# +# See WEBrick::HTTPServlet::AbstractServlet for more details. +# +# == Virtual Hosts +# +# A server can act as a virtual host for multiple host names. After creating +# the listening host, additional hosts that do not listen can be created and +# attached as virtual hosts: +# +# server = WEBrick::HTTPServer.new # ... +# +# vhost = WEBrick::HTTPServer.new :ServerName => 'vhost.example', +# :DoNotListen => true, # ... +# vhost.mount '/', ... +# +# server.virtual_host vhost +# +# If no +:DocumentRoot+ is provided and no servlets or procs are mounted on the +# main server it will return 404 for all URLs. +# +# == HTTPS +# +# To create an HTTPS server you only need to enable SSL and provide an SSL +# certificate name: +# +# require 'webrick' +# require 'webrick/https' +# +# cert_name = [ +# %w[CN localhost], +# ] +# +# server = WEBrick::HTTPServer.new(:Port => 8000, +# :SSLEnable => true, +# :SSLCertName => cert_name) +# +# This will start the server with a self-generated self-signed certificate. +# The certificate will be changed every time the server is restarted. +# +# To create a server with a pre-determined key and certificate you can provide +# them: +# +# require 'webrick' +# require 'webrick/https' +# require 'openssl' +# +# cert = OpenSSL::X509::Certificate.new File.read '/path/to/cert.pem' +# pkey = OpenSSL::PKey::RSA.new File.read '/path/to/pkey.pem' +# +# server = WEBrick::HTTPServer.new(:Port => 8000, +# :SSLEnable => true, +# :SSLCertificate => cert, +# :SSLPrivateKey => pkey) +# +# == Proxy Server +# +# WEBrick can act as a proxy server: +# +# require 'webrick' +# require 'webrick/httpproxy' +# +# proxy = WEBrick::HTTPProxyServer.new :Port => 8000 +# +# trap 'INT' do proxy.shutdown end +# +# See WEBrick::HTTPProxy for further details including modifying proxied +# responses. +# +# == Basic and Digest authentication +# +# WEBrick provides both Basic and Digest authentication for regular and proxy +# servers. See WEBrick::HTTPAuth, WEBrick::HTTPAuth::BasicAuth and +# WEBrick::HTTPAuth::DigestAuth. +# +# == WEBrick as a daemonized Web Server +# +# WEBrick can be run as a daemonized server for small loads. +# +# === Daemonizing +# +# To start a WEBrick server as a daemon simple run WEBrick::Daemon.start +# before starting the server. +# +# === Dropping Permissions +# +# WEBrick can be started as one user to gain permission to bind to port 80 or +# 443 for serving HTTP or HTTPS traffic then can drop these permissions for +# regular operation. To listen on all interfaces for HTTP traffic: +# +# sockets = WEBrick::Utils.create_listeners nil, 80 +# +# Then drop privileges: +# +# WEBrick::Utils.su 'www' +# +# Then create a server that does not listen by default: +# +# server = WEBrick::HTTPServer.new :DoNotListen => true, # ... +# +# Then overwrite the listening sockets with the port 80 sockets: +# +# server.listeners.replace sockets +# +# === Logging +# +# WEBrick can separately log server operations and end-user access. For +# server operations: +# +# log_file = File.open '/var/log/webrick.log', 'a+' +# log = WEBrick::Log.new log_file +# +# For user access logging: +# +# access_log = [ +# [log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT], +# ] +# +# server = WEBrick::HTTPServer.new :Logger => log, :AccessLog => access_log +# +# See WEBrick::AccessLog for further log formats. +# +# === Log Rotation +# +# To rotate logs in WEBrick on a HUP signal (like syslogd can send), open the +# log file in 'a+' mode (as above) and trap 'HUP' to reopen the log file: +# +# trap 'HUP' do log_file.reopen '/path/to/webrick.log', 'a+' +# +# == Copyright +# +# Author: IPR -- Internet Programming with Ruby -- writers +# +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +#-- +# $IPR: webrick.rb,v 1.12 2002/10/01 17:16:31 gotoyuzo Exp $ + +module WEBrick +end + +require 'webrick/compat.rb' + +require 'webrick/version.rb' +require 'webrick/config.rb' +require 'webrick/log.rb' +require 'webrick/server.rb' +require_relative 'webrick/utils.rb' +require 'webrick/accesslog' + +require 'webrick/htmlutils.rb' +require 'webrick/httputils.rb' +require 'webrick/cookie.rb' +require 'webrick/httpversion.rb' +require 'webrick/httpstatus.rb' +require 'webrick/httprequest.rb' +require 'webrick/httpresponse.rb' +require 'webrick/httpserver.rb' +require 'webrick/httpservlet.rb' +require 'webrick/httpauth.rb' diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/accesslog.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/accesslog.rb new file mode 100644 index 0000000..fccfd65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/accesslog.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true +#-- +# accesslog.rb -- Access log handling utilities +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 keita yamaguchi +# Copyright (c) 2002 Internet Programming with Ruby writers +# +# $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $ + +module WEBrick + + ## + # AccessLog provides logging to various files in various formats. + # + # Multiple logs may be written to at the same time: + # + # access_log = [ + # [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT], + # [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT], + # ] + # + # server = WEBrick::HTTPServer.new :AccessLog => access_log + # + # Custom log formats may be defined. WEBrick::AccessLog provides a subset + # of the formatting from Apache's mod_log_config + # http://httpd.apache.org/docs/mod/mod_log_config.html#formats. See + # AccessLog::setup_params for a list of supported options + + module AccessLog + + ## + # Raised if a parameter such as %e, %i, %o or %n is used without fetching + # a specific field. + + class AccessLogError < StandardError; end + + ## + # The Common Log Format's time format + + CLF_TIME_FORMAT = "[%d/%b/%Y:%H:%M:%S %Z]" + + ## + # Common Log Format + + COMMON_LOG_FORMAT = "%h %l %u %t \"%r\" %s %b" + + ## + # Short alias for Common Log Format + + CLF = COMMON_LOG_FORMAT + + ## + # Referer Log Format + + REFERER_LOG_FORMAT = "%{Referer}i -> %U" + + ## + # User-Agent Log Format + + AGENT_LOG_FORMAT = "%{User-Agent}i" + + ## + # Combined Log Format + + COMBINED_LOG_FORMAT = "#{CLF} \"%{Referer}i\" \"%{User-agent}i\"" + + module_function + + # This format specification is a subset of mod_log_config of Apache: + # + # %a:: Remote IP address + # %b:: Total response size + # %e{variable}:: Given variable in ENV + # %f:: Response filename + # %h:: Remote host name + # %{header}i:: Given request header + # %l:: Remote logname, always "-" + # %m:: Request method + # %{attr}n:: Given request attribute from req.attributes + # %{header}o:: Given response header + # %p:: Server's request port + # %{format}p:: The canonical port of the server serving the request or the + # actual port or the client's actual port. Valid formats are + # canonical, local or remote. + # %q:: Request query string + # %r:: First line of the request + # %s:: Request status + # %t:: Time the request was received + # %T:: Time taken to process the request + # %u:: Remote user from auth + # %U:: Unparsed URI + # %%:: Literal % + + def setup_params(config, req, res) + params = Hash.new("") + params["a"] = req.peeraddr[3] + params["b"] = res.sent_size + params["e"] = ENV + params["f"] = res.filename || "" + params["h"] = req.peeraddr[2] + params["i"] = req + params["l"] = "-" + params["m"] = req.request_method + params["n"] = req.attributes + params["o"] = res + params["p"] = req.port + params["q"] = req.query_string + params["r"] = req.request_line.sub(/\x0d?\x0a\z/o, '') + params["s"] = res.status # won't support "%>s" + params["t"] = req.request_time + params["T"] = Time.now - req.request_time + params["u"] = req.user || "-" + params["U"] = req.unparsed_uri + params["v"] = config[:ServerName] + params + end + + ## + # Formats +params+ according to +format_string+ which is described in + # setup_params. + + def format(format_string, params) + format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){ + param, spec = $1, $2 + case spec[0] + when ?e, ?i, ?n, ?o + raise AccessLogError, + "parameter is required for \"#{spec}\"" unless param + (param = params[spec][param]) ? escape(param) : "-" + when ?t + params[spec].strftime(param || CLF_TIME_FORMAT) + when ?p + case param + when 'remote' + escape(params["i"].peeraddr[1].to_s) + else + escape(params["p"].to_s) + end + when ?% + "%" + else + escape(params[spec].to_s) + end + } + end + + ## + # Escapes control characters in +data+ + + def escape(data) + data = data.gsub(/[[:cntrl:]\\]+/) {$&.dump[1...-1]} + data.untaint if RUBY_VERSION < '2.7' + data + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cgi.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cgi.rb new file mode 100644 index 0000000..c86d36c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cgi.rb @@ -0,0 +1,313 @@ +# frozen_string_literal: true +# +# cgi.rb -- Yet another CGI library +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $Id$ + +require_relative "httprequest" +require_relative "httpresponse" +require_relative "config" +require "stringio" + +module WEBrick + + # A CGI library using WEBrick requests and responses. + # + # Example: + # + # class MyCGI < WEBrick::CGI + # def do_GET req, res + # res.body = 'it worked!' + # res.status = 200 + # end + # end + # + # MyCGI.new.start + + class CGI + + # The CGI error exception class + + CGIError = Class.new(StandardError) + + ## + # The CGI configuration. This is based on WEBrick::Config::HTTP + + attr_reader :config + + ## + # The CGI logger + + attr_reader :logger + + ## + # Creates a new CGI interface. + # + # The first argument in +args+ is a configuration hash which would update + # WEBrick::Config::HTTP. + # + # Any remaining arguments are stored in the @options instance + # variable for use by a subclass. + + def initialize(*args) + if defined?(MOD_RUBY) + unless ENV.has_key?("GATEWAY_INTERFACE") + Apache.request.setup_cgi_env + end + end + if %r{HTTP/(\d+\.\d+)} =~ ENV["SERVER_PROTOCOL"] + httpv = $1 + end + @config = WEBrick::Config::HTTP.dup.update( + :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null", + :HTTPVersion => HTTPVersion.new(httpv || "1.0"), + :RunOnCGI => true, # to detect if it runs on CGI. + :NPH => false # set true to run as NPH script. + ) + if config = args.shift + @config.update(config) + end + @config[:Logger] ||= WEBrick::BasicLog.new($stderr) + @logger = @config[:Logger] + @options = args + end + + ## + # Reads +key+ from the configuration + + def [](key) + @config[key] + end + + ## + # Starts the CGI process with the given environment +env+ and standard + # input and output +stdin+ and +stdout+. + + def start(env=ENV, stdin=$stdin, stdout=$stdout) + sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout) + req = HTTPRequest.new(@config) + res = HTTPResponse.new(@config) + unless @config[:NPH] or defined?(MOD_RUBY) + def res.setup_header + unless @header["status"] + phrase = HTTPStatus::reason_phrase(@status) + @header["status"] = "#{@status} #{phrase}" + end + super + end + def res.status_line + "" + end + end + + begin + req.parse(sock) + req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup + req.path_info = (env["PATH_INFO"] || "").dup + req.query_string = env["QUERY_STRING"] + req.user = env["REMOTE_USER"] + res.request_method = req.request_method + res.request_uri = req.request_uri + res.request_http_version = req.http_version + res.keep_alive = req.keep_alive? + self.service(req, res) + rescue HTTPStatus::Error => ex + res.set_error(ex) + rescue HTTPStatus::Status => ex + res.status = ex.code + rescue Exception => ex + @logger.error(ex) + res.set_error(ex, true) + ensure + req.fixup + if defined?(MOD_RUBY) + res.setup_header + Apache.request.status_line = "#{res.status} #{res.reason_phrase}" + Apache.request.status = res.status + table = Apache.request.headers_out + res.header.each{|key, val| + case key + when /^content-encoding$/i + Apache::request.content_encoding = val + when /^content-type$/i + Apache::request.content_type = val + else + table[key] = val.to_s + end + } + res.cookies.each{|cookie| + table.add("Set-Cookie", cookie.to_s) + } + Apache.request.send_http_header + res.send_body(sock) + else + res.send_response(sock) + end + end + end + + ## + # Services the request +req+ which will fill in the response +res+. See + # WEBrick::HTTPServlet::AbstractServlet#service for details. + + def service(req, res) + method_name = "do_" + req.request_method.gsub(/-/, "_") + if respond_to?(method_name) + __send__(method_name, req, res) + else + raise HTTPStatus::MethodNotAllowed, + "unsupported method '#{req.request_method}'." + end + end + + ## + # Provides HTTP socket emulation from the CGI environment + + class Socket # :nodoc: + include Enumerable + + private + + def initialize(config, env, stdin, stdout) + @config = config + @env = env + @header_part = StringIO.new + @body_part = stdin + @out_port = stdout + @out_port.binmode + + @server_addr = @env["SERVER_ADDR"] || "0.0.0.0" + @server_name = @env["SERVER_NAME"] + @server_port = @env["SERVER_PORT"] + @remote_addr = @env["REMOTE_ADDR"] + @remote_host = @env["REMOTE_HOST"] || @remote_addr + @remote_port = @env["REMOTE_PORT"] || 0 + + begin + @header_part << request_line << CRLF + setup_header + @header_part << CRLF + @header_part.rewind + rescue Exception + raise CGIError, "invalid CGI environment" + end + end + + def request_line + meth = @env["REQUEST_METHOD"] || "GET" + unless url = @env["REQUEST_URI"] + url = (@env["SCRIPT_NAME"] || File.expand_path($0)).dup + url << @env["PATH_INFO"].to_s + url = WEBrick::HTTPUtils.escape_path(url) + if query_string = @env["QUERY_STRING"] + unless query_string.empty? + url << "?" << query_string + end + end + end + # we cannot get real HTTP version of client ;) + httpv = @config[:HTTPVersion] + return "#{meth} #{url} HTTP/#{httpv}" + end + + def setup_header + @env.each{|key, value| + case key + when "CONTENT_TYPE", "CONTENT_LENGTH" + add_header(key.gsub(/_/, "-"), value) + when /^HTTP_(.*)/ + add_header($1.gsub(/_/, "-"), value) + end + } + end + + def add_header(hdrname, value) + unless value.empty? + @header_part << hdrname << ": " << value << CRLF + end + end + + def input + @header_part.eof? ? @body_part : @header_part + end + + public + + def peeraddr + [nil, @remote_port, @remote_host, @remote_addr] + end + + def addr + [nil, @server_port, @server_name, @server_addr] + end + + def gets(eol=LF, size=nil) + input.gets(eol, size) + end + + def read(size=nil) + input.read(size) + end + + def each + input.each{|line| yield(line) } + end + + def eof? + input.eof? + end + + def <<(data) + @out_port << data + end + + def write(data) + @out_port.write(data) + end + + def cert + return nil unless defined?(OpenSSL) + if pem = @env["SSL_SERVER_CERT"] + OpenSSL::X509::Certificate.new(pem) unless pem.empty? + end + end + + def peer_cert + return nil unless defined?(OpenSSL) + if pem = @env["SSL_CLIENT_CERT"] + OpenSSL::X509::Certificate.new(pem) unless pem.empty? + end + end + + def peer_cert_chain + return nil unless defined?(OpenSSL) + if @env["SSL_CLIENT_CERT_CHAIN_0"] + keys = @env.keys + certs = keys.sort.collect{|k| + if /^SSL_CLIENT_CERT_CHAIN_\d+$/ =~ k + if pem = @env[k] + OpenSSL::X509::Certificate.new(pem) unless pem.empty? + end + end + } + certs.compact + end + end + + def cipher + return nil unless defined?(OpenSSL) + if cipher = @env["SSL_CIPHER"] + ret = [ cipher ] + ret << @env["SSL_PROTOCOL"] + ret << @env["SSL_CIPHER_USEKEYSIZE"] + ret << @env["SSL_CIPHER_ALGKEYSIZE"] + ret + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/compat.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/compat.rb new file mode 100644 index 0000000..842da1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/compat.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true +# +# compat.rb -- cross platform compatibility +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: compat.rb,v 1.6 2002/10/01 17:16:32 gotoyuzo Exp $ + +## +# System call error module used by webrick for cross platform compatibility. +# +# EPROTO:: protocol error +# ECONNRESET:: remote host reset the connection request +# ECONNABORTED:: Client sent TCP reset (RST) before server has accepted the +# connection requested by client. +# +module Errno + ## + # Protocol error. + + class EPROTO < SystemCallError; end + + ## + # Remote host reset the connection request. + + class ECONNRESET < SystemCallError; end + + ## + # Client sent TCP reset (RST) before server has accepted the connection + # requested by client. + + class ECONNABORTED < SystemCallError; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/config.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/config.rb new file mode 100644 index 0000000..d67375c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/config.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true +# +# config.rb -- Default configurations. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $ + +require_relative 'version' +require_relative 'httpversion' +require_relative 'httputils' +require_relative 'utils' +require_relative 'log' + +module WEBrick + module Config + LIBDIR = File::dirname(__FILE__) # :nodoc: + + # for GenericServer + General = Hash.new { |hash, key| + case key + when :ServerName + hash[key] = Utils.getservername + else + nil + end + }.update( + :BindAddress => nil, # "0.0.0.0" or "::" or nil + :Port => nil, # users MUST specify this!! + :MaxClients => 100, # maximum number of the concurrent connections + :ServerType => nil, # default: WEBrick::SimpleServer + :Logger => nil, # default: WEBrick::Log.new + :ServerSoftware => "WEBrick/#{WEBrick::VERSION} " + + "(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})", + :TempDir => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp', + :DoNotListen => false, + :StartCallback => nil, + :StopCallback => nil, + :AcceptCallback => nil, + :DoNotReverseLookup => true, + :ShutdownSocketWithoutClose => false, + ) + + # for HTTPServer, HTTPRequest, HTTPResponse ... + HTTP = General.dup.update( + :Port => 80, + :RequestTimeout => 30, + :HTTPVersion => HTTPVersion.new("1.1"), + :AccessLog => nil, + :MimeTypes => HTTPUtils::DefaultMimeTypes, + :DirectoryIndex => ["index.html","index.htm","index.cgi","index.rhtml"], + :DocumentRoot => nil, + :DocumentRootOptions => { :FancyIndexing => true }, + :RequestCallback => nil, + :ServerAlias => nil, + :InputBufferSize => 65536, # input buffer size in reading request body + :OutputBufferSize => 65536, # output buffer size in sending File or IO + + # for HTTPProxyServer + :ProxyAuthProc => nil, + :ProxyContentHandler => nil, + :ProxyVia => true, + :ProxyTimeout => true, + :ProxyURI => nil, + + :CGIInterpreter => nil, + :CGIPathEnv => nil, + + # workaround: if Request-URIs contain 8bit chars, + # they should be escaped before calling of URI::parse(). + :Escape8bitURI => false + ) + + ## + # Default configuration for WEBrick::HTTPServlet::FileHandler + # + # :AcceptableLanguages:: + # Array of languages allowed for accept-language. There is no default + # :DirectoryCallback:: + # Allows preprocessing of directory requests. There is no default + # callback. + # :FancyIndexing:: + # If true, show an index for directories. The default is true. + # :FileCallback:: + # Allows preprocessing of file requests. There is no default callback. + # :HandlerCallback:: + # Allows preprocessing of requests. There is no default callback. + # :HandlerTable:: + # Maps file suffixes to file handlers. DefaultFileHandler is used by + # default but any servlet can be used. + # :NondisclosureName:: + # Do not show files matching this array of globs. .ht* and *~ are + # excluded by default. + # :UserDir:: + # Directory inside ~user to serve content from for /~user requests. + # Only works if mounted on /. Disabled by default. + + FileHandler = { + :NondisclosureName => [".ht*", "*~"], + :FancyIndexing => false, + :HandlerTable => {}, + :HandlerCallback => nil, + :DirectoryCallback => nil, + :FileCallback => nil, + :UserDir => nil, # e.g. "public_html" + :AcceptableLanguages => [] # ["en", "ja", ... ] + } + + ## + # Default configuration for WEBrick::HTTPAuth::BasicAuth + # + # :AutoReloadUserDB:: Reload the user database provided by :UserDB + # automatically? + + BasicAuth = { + :AutoReloadUserDB => true, + } + + ## + # Default configuration for WEBrick::HTTPAuth::DigestAuth. + # + # :Algorithm:: MD5, MD5-sess (default), SHA1, SHA1-sess + # :Domain:: An Array of URIs that define the protected space + # :Qop:: 'auth' for authentication, 'auth-int' for integrity protection or + # both + # :UseOpaque:: Should the server send opaque values to the client? This + # helps prevent replay attacks. + # :CheckNc:: Should the server check the nonce count? This helps the + # server detect replay attacks. + # :UseAuthenticationInfoHeader:: Should the server send an + # AuthenticationInfo header? + # :AutoReloadUserDB:: Reload the user database provided by :UserDB + # automatically? + # :NonceExpirePeriod:: How long should we store used nonces? Default is + # 30 minutes. + # :NonceExpireDelta:: How long is a nonce valid? Default is 1 minute + # :InternetExplorerHack:: Hack which allows Internet Explorer to work. + # :OperaHack:: Hack which allows Opera to work. + + DigestAuth = { + :Algorithm => 'MD5-sess', # or 'MD5' + :Domain => nil, # an array includes domain names. + :Qop => [ 'auth' ], # 'auth' or 'auth-int' or both. + :UseOpaque => true, + :UseNextNonce => false, + :CheckNc => false, + :UseAuthenticationInfoHeader => true, + :AutoReloadUserDB => true, + :NonceExpirePeriod => 30*60, + :NonceExpireDelta => 60, + :InternetExplorerHack => true, + :OperaHack => true, + } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cookie.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cookie.rb new file mode 100644 index 0000000..7b18782 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/cookie.rb @@ -0,0 +1,172 @@ +# frozen_string_literal: true +# +# cookie.rb -- Cookie class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $ + +require 'time' +require_relative 'httputils' + +module WEBrick + + ## + # Processes HTTP cookies + + class Cookie + + ## + # The cookie name + + attr_reader :name + + ## + # The cookie value + + attr_accessor :value + + ## + # The cookie version + + attr_accessor :version + + ## + # The cookie domain + attr_accessor :domain + + ## + # The cookie path + + attr_accessor :path + + ## + # Is this a secure cookie? + + attr_accessor :secure + + ## + # The cookie comment + + attr_accessor :comment + + ## + # The maximum age of the cookie + + attr_accessor :max_age + + #attr_accessor :comment_url, :discard, :port + + ## + # Creates a new cookie with the given +name+ and +value+ + + def initialize(name, value) + @name = name + @value = value + @version = 0 # Netscape Cookie + + @domain = @path = @secure = @comment = @max_age = + @expires = @comment_url = @discard = @port = nil + end + + ## + # Sets the cookie expiration to the time +t+. The expiration time may be + # a false value to disable expiration or a Time or HTTP format time string + # to set the expiration date. + + def expires=(t) + @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s) + end + + ## + # Retrieves the expiration time as a Time + + def expires + @expires && Time.parse(@expires) + end + + ## + # The cookie string suitable for use in an HTTP header + + def to_s + ret = +"" + ret << @name << "=" << @value + ret << "; " << "Version=" << @version.to_s if @version > 0 + ret << "; " << "Domain=" << @domain if @domain + ret << "; " << "Expires=" << @expires if @expires + ret << "; " << "Max-Age=" << @max_age.to_s if @max_age + ret << "; " << "Comment=" << @comment if @comment + ret << "; " << "Path=" << @path if @path + ret << "; " << "Secure" if @secure + ret + end + + ## + # Parses a Cookie field sent from the user-agent. Returns an array of + # cookies. + + def self.parse(str) + if str + ret = [] + cookie = nil + ver = 0 + str.split(/;\s+/).each{|x| + key, val = x.split(/=/,2) + val = val ? HTTPUtils::dequote(val) : "" + case key + when "$Version"; ver = val.to_i + when "$Path"; cookie.path = val + when "$Domain"; cookie.domain = val + when "$Port"; cookie.port = val + else + ret << cookie if cookie + cookie = self.new(key, val) + cookie.version = ver + end + } + ret << cookie if cookie + ret + end + end + + ## + # Parses the cookie in +str+ + + def self.parse_set_cookie(str) + cookie_elem = str.split(/;/) + first_elem = cookie_elem.shift + first_elem.strip! + key, value = first_elem.split(/=/, 2) + cookie = new(key, HTTPUtils.dequote(value)) + cookie_elem.each{|pair| + pair.strip! + key, value = pair.split(/=/, 2) + if value + value = HTTPUtils.dequote(value.strip) + end + case key.downcase + when "domain" then cookie.domain = value + when "path" then cookie.path = value + when "expires" then cookie.expires = value + when "max-age" then cookie.max_age = Integer(value) + when "comment" then cookie.comment = value + when "version" then cookie.version = Integer(value) + when "secure" then cookie.secure = true + end + } + return cookie + end + + ## + # Parses the cookies in +str+ + + def self.parse_set_cookies(str) + return str.split(/,(?=[^;,]*=)|,$/).collect{|c| + parse_set_cookie(c) + } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/htmlutils.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/htmlutils.rb new file mode 100644 index 0000000..7ff0bde --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/htmlutils.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +#-- +# htmlutils.rb -- HTMLUtils Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htmlutils.rb,v 1.7 2002/09/21 12:23:35 gotoyuzo Exp $ + +module WEBrick + module HTMLUtils + + ## + # Escapes &, ", > and < in +string+ + + def escape(string) + return "" unless string + str = string.b + str.gsub!(/&/n, '&') + str.gsub!(/\"/n, '"') + str.gsub!(/>/n, '>') + str.gsub!(/ 'DigestAuth example realm' } + # + # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file' + # htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth + # htpasswd.set_passwd config[:Realm], 'username', 'password' + # htpasswd.flush + # + # The +:Realm+ is used to provide different access to different groups + # across several resources on a server. Typically you'll need only one + # realm for a server. + # + # This database can be used to create an authenticator: + # + # config[:UserDB] = htpasswd + # + # digest_auth = WEBrick::HTTPAuth::DigestAuth.new config + # + # To authenticate a request call #authenticate with a request and response + # object in a servlet: + # + # def do_GET req, res + # @authenticator.authenticate req, res + # end + # + # For digest authentication the authenticator must not be created every + # request, it must be passed in as an option via WEBrick::HTTPServer#mount. + + module HTTPAuth + module_function + + def _basic_auth(req, res, realm, req_field, res_field, err_type, + block) # :nodoc: + user = pass = nil + if /^Basic\s+(.*)/o =~ req[req_field] + userpass = $1 + user, pass = userpass.unpack("m*")[0].split(":", 2) + end + if block.call(user, pass) + req.user = user + return + end + res[res_field] = "Basic realm=\"#{realm}\"" + raise err_type + end + + ## + # Simple wrapper for providing basic authentication for a request. When + # called with a request +req+, response +res+, authentication +realm+ and + # +block+ the block will be called with a +username+ and +password+. If + # the block returns true the request is allowed to continue, otherwise an + # HTTPStatus::Unauthorized error is raised. + + def basic_auth(req, res, realm, &block) # :yield: username, password + _basic_auth(req, res, realm, "Authorization", "WWW-Authenticate", + HTTPStatus::Unauthorized, block) + end + + ## + # Simple wrapper for providing basic authentication for a proxied request. + # When called with a request +req+, response +res+, authentication +realm+ + # and +block+ the block will be called with a +username+ and +password+. + # If the block returns true the request is allowed to continue, otherwise + # an HTTPStatus::ProxyAuthenticationRequired error is raised. + + def proxy_basic_auth(req, res, realm, &block) # :yield: username, password + _basic_auth(req, res, realm, "Proxy-Authorization", "Proxy-Authenticate", + HTTPStatus::ProxyAuthenticationRequired, block) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/authenticator.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/authenticator.rb new file mode 100644 index 0000000..13b1c7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/authenticator.rb @@ -0,0 +1,117 @@ +# frozen_string_literal: true +#-- +# httpauth/authenticator.rb -- Authenticator mix-in module. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: authenticator.rb,v 1.3 2003/02/20 07:15:47 gotoyuzo Exp $ + +module WEBrick + module HTTPAuth + + ## + # Module providing generic support for both Digest and Basic + # authentication schemes. + + module Authenticator + + RequestField = "Authorization" # :nodoc: + ResponseField = "WWW-Authenticate" # :nodoc: + ResponseInfoField = "Authentication-Info" # :nodoc: + AuthException = HTTPStatus::Unauthorized # :nodoc: + + ## + # Method of authentication, must be overridden by the including class + + AuthScheme = nil + + ## + # The realm this authenticator covers + + attr_reader :realm + + ## + # The user database for this authenticator + + attr_reader :userdb + + ## + # The logger for this authenticator + + attr_reader :logger + + private + + # :stopdoc: + + ## + # Initializes the authenticator from +config+ + + def check_init(config) + [:UserDB, :Realm].each{|sym| + unless config[sym] + raise ArgumentError, "Argument #{sym.inspect} missing." + end + } + @realm = config[:Realm] + @userdb = config[:UserDB] + @logger = config[:Logger] || Log::new($stderr) + @reload_db = config[:AutoReloadUserDB] + @request_field = self::class::RequestField + @response_field = self::class::ResponseField + @resp_info_field = self::class::ResponseInfoField + @auth_exception = self::class::AuthException + @auth_scheme = self::class::AuthScheme + end + + ## + # Ensures +req+ has credentials that can be authenticated. + + def check_scheme(req) + unless credentials = req[@request_field] + error("no credentials in the request.") + return nil + end + unless match = /^#{@auth_scheme}\s+/i.match(credentials) + error("invalid scheme in %s.", credentials) + info("%s: %s", @request_field, credentials) if $DEBUG + return nil + end + return match.post_match + end + + def log(meth, fmt, *args) + msg = format("%s %s: ", @auth_scheme, @realm) + msg << fmt % args + @logger.__send__(meth, msg) + end + + def error(fmt, *args) + if @logger.error? + log(:error, fmt, *args) + end + end + + def info(fmt, *args) + if @logger.info? + log(:info, fmt, *args) + end + end + + # :startdoc: + end + + ## + # Module providing generic support for both Digest and Basic + # authentication schemes for proxies. + + module ProxyAuthenticator + RequestField = "Proxy-Authorization" # :nodoc: + ResponseField = "Proxy-Authenticate" # :nodoc: + ResponseInfoField = "Proxy-Authentication-Info" # :nodoc: + AuthException = HTTPStatus::ProxyAuthenticationRequired # :nodoc: + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/basicauth.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/basicauth.rb new file mode 100644 index 0000000..cc8137a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/basicauth.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true +# +# httpauth/basicauth.rb -- HTTP basic access authentication +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: basicauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $ + +require_relative '../config' +require_relative '../httpstatus' +require_relative 'authenticator' + +module WEBrick + module HTTPAuth + + ## + # Basic Authentication for WEBrick + # + # Use this class to add basic authentication to a WEBrick servlet. + # + # Here is an example of how to set up a BasicAuth: + # + # config = { :Realm => 'BasicAuth example realm' } + # + # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file', password_hash: :bcrypt + # htpasswd.set_passwd config[:Realm], 'username', 'password' + # htpasswd.flush + # + # config[:UserDB] = htpasswd + # + # basic_auth = WEBrick::HTTPAuth::BasicAuth.new config + + class BasicAuth + include Authenticator + + AuthScheme = "Basic" # :nodoc: + + ## + # Used by UserDB to create a basic password entry + + def self.make_passwd(realm, user, pass) + pass ||= "" + pass.crypt(Utils::random_string(2)) + end + + attr_reader :realm, :userdb, :logger + + ## + # Creates a new BasicAuth instance. + # + # See WEBrick::Config::BasicAuth for default configuration entries + # + # You must supply the following configuration entries: + # + # :Realm:: The name of the realm being protected. + # :UserDB:: A database of usernames and passwords. + # A WEBrick::HTTPAuth::Htpasswd instance should be used. + + def initialize(config, default=Config::BasicAuth) + check_init(config) + @config = default.dup.update(config) + end + + ## + # Authenticates a +req+ and returns a 401 Unauthorized using +res+ if + # the authentication was not correct. + + def authenticate(req, res) + unless basic_credentials = check_scheme(req) + challenge(req, res) + end + userid, password = basic_credentials.unpack("m*")[0].split(":", 2) + password ||= "" + if userid.empty? + error("user id was not given.") + challenge(req, res) + end + unless encpass = @userdb.get_passwd(@realm, userid, @reload_db) + error("%s: the user is not allowed.", userid) + challenge(req, res) + end + + case encpass + when /\A\$2[aby]\$/ + password_matches = BCrypt::Password.new(encpass.sub(/\A\$2[aby]\$/, '$2a$')) == password + else + password_matches = password.crypt(encpass) == encpass + end + + unless password_matches + error("%s: password unmatch.", userid) + challenge(req, res) + end + info("%s: authentication succeeded.", userid) + req.user = userid + end + + ## + # Returns a challenge response which asks for authentication information + + def challenge(req, res) + res[@response_field] = "#{@auth_scheme} realm=\"#{@realm}\"" + raise @auth_exception + end + end + + ## + # Basic authentication for proxy servers. See BasicAuth for details. + + class ProxyBasicAuth < BasicAuth + include ProxyAuthenticator + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/digestauth.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/digestauth.rb new file mode 100644 index 0000000..25ce8ba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/digestauth.rb @@ -0,0 +1,395 @@ +# frozen_string_literal: true +# +# httpauth/digestauth.rb -- HTTP digest access authentication +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. +# Copyright (c) 2003 H.M. +# +# The original implementation is provided by H.M. +# URL: http://rwiki.jin.gr.jp/cgi-bin/rw-cgi.rb?cmd=view;name= +# %C7%A7%BE%DA%B5%A1%C7%BD%A4%F2%B2%FE%C2%A4%A4%B7%A4%C6%A4%DF%A4%EB +# +# $IPR: digestauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $ + +require_relative '../config' +require_relative '../httpstatus' +require_relative 'authenticator' +require 'digest/md5' +require 'digest/sha1' + +module WEBrick + module HTTPAuth + + ## + # RFC 2617 Digest Access Authentication for WEBrick + # + # Use this class to add digest authentication to a WEBrick servlet. + # + # Here is an example of how to set up DigestAuth: + # + # config = { :Realm => 'DigestAuth example realm' } + # + # htdigest = WEBrick::HTTPAuth::Htdigest.new 'my_password_file' + # htdigest.set_passwd config[:Realm], 'username', 'password' + # htdigest.flush + # + # config[:UserDB] = htdigest + # + # digest_auth = WEBrick::HTTPAuth::DigestAuth.new config + # + # When using this as with a servlet be sure not to create a new DigestAuth + # object in the servlet's #initialize. By default WEBrick creates a new + # servlet instance for every request and the DigestAuth object must be + # used across requests. + + class DigestAuth + include Authenticator + + AuthScheme = "Digest" # :nodoc: + + ## + # Struct containing the opaque portion of the digest authentication + + OpaqueInfo = Struct.new(:time, :nonce, :nc) # :nodoc: + + ## + # Digest authentication algorithm + + attr_reader :algorithm + + ## + # Quality of protection. RFC 2617 defines "auth" and "auth-int" + + attr_reader :qop + + ## + # Used by UserDB to create a digest password entry + + def self.make_passwd(realm, user, pass) + pass ||= "" + Digest::MD5::hexdigest([user, realm, pass].join(":")) + end + + ## + # Creates a new DigestAuth instance. Be sure to use the same DigestAuth + # instance for multiple requests as it saves state between requests in + # order to perform authentication. + # + # See WEBrick::Config::DigestAuth for default configuration entries + # + # You must supply the following configuration entries: + # + # :Realm:: The name of the realm being protected. + # :UserDB:: A database of usernames and passwords. + # A WEBrick::HTTPAuth::Htdigest instance should be used. + + def initialize(config, default=Config::DigestAuth) + check_init(config) + @config = default.dup.update(config) + @algorithm = @config[:Algorithm] + @domain = @config[:Domain] + @qop = @config[:Qop] + @use_opaque = @config[:UseOpaque] + @use_next_nonce = @config[:UseNextNonce] + @check_nc = @config[:CheckNc] + @use_auth_info_header = @config[:UseAuthenticationInfoHeader] + @nonce_expire_period = @config[:NonceExpirePeriod] + @nonce_expire_delta = @config[:NonceExpireDelta] + @internet_explorer_hack = @config[:InternetExplorerHack] + + case @algorithm + when 'MD5','MD5-sess' + @h = Digest::MD5 + when 'SHA1','SHA1-sess' # it is a bonus feature :-) + @h = Digest::SHA1 + else + msg = format('Algorithm "%s" is not supported.', @algorithm) + raise ArgumentError.new(msg) + end + + @instance_key = hexdigest(self.__id__, Time.now.to_i, Process.pid) + @opaques = {} + @last_nonce_expire = Time.now + @mutex = Thread::Mutex.new + end + + ## + # Authenticates a +req+ and returns a 401 Unauthorized using +res+ if + # the authentication was not correct. + + def authenticate(req, res) + unless result = @mutex.synchronize{ _authenticate(req, res) } + challenge(req, res) + end + if result == :nonce_is_stale + challenge(req, res, true) + end + return true + end + + ## + # Returns a challenge response which asks for authentication information + + def challenge(req, res, stale=false) + nonce = generate_next_nonce(req) + if @use_opaque + opaque = generate_opaque(req) + @opaques[opaque].nonce = nonce + end + + param = Hash.new + param["realm"] = HTTPUtils::quote(@realm) + param["domain"] = HTTPUtils::quote(@domain.to_a.join(" ")) if @domain + param["nonce"] = HTTPUtils::quote(nonce) + param["opaque"] = HTTPUtils::quote(opaque) if opaque + param["stale"] = stale.to_s + param["algorithm"] = @algorithm + param["qop"] = HTTPUtils::quote(@qop.to_a.join(",")) if @qop + + res[@response_field] = + "#{@auth_scheme} " + param.map{|k,v| "#{k}=#{v}" }.join(", ") + info("%s: %s", @response_field, res[@response_field]) if $DEBUG + raise @auth_exception + end + + private + + # :stopdoc: + + MustParams = ['username','realm','nonce','uri','response'] + MustParamsAuth = ['cnonce','nc'] + + def _authenticate(req, res) + unless digest_credentials = check_scheme(req) + return false + end + + auth_req = split_param_value(digest_credentials) + if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int" + req_params = MustParams + MustParamsAuth + else + req_params = MustParams + end + req_params.each{|key| + unless auth_req.has_key?(key) + error('%s: parameter missing. "%s"', auth_req['username'], key) + raise HTTPStatus::BadRequest + end + } + + if !check_uri(req, auth_req) + raise HTTPStatus::BadRequest + end + + if auth_req['realm'] != @realm + error('%s: realm unmatch. "%s" for "%s"', + auth_req['username'], auth_req['realm'], @realm) + return false + end + + auth_req['algorithm'] ||= 'MD5' + if auth_req['algorithm'].upcase != @algorithm.upcase + error('%s: algorithm unmatch. "%s" for "%s"', + auth_req['username'], auth_req['algorithm'], @algorithm) + return false + end + + if (@qop.nil? && auth_req.has_key?('qop')) || + (@qop && (! @qop.member?(auth_req['qop']))) + error('%s: the qop is not allowed. "%s"', + auth_req['username'], auth_req['qop']) + return false + end + + password = @userdb.get_passwd(@realm, auth_req['username'], @reload_db) + unless password + error('%s: the user is not allowed.', auth_req['username']) + return false + end + + nonce_is_invalid = false + if @use_opaque + info("@opaque = %s", @opaque.inspect) if $DEBUG + if !(opaque = auth_req['opaque']) + error('%s: opaque is not given.', auth_req['username']) + nonce_is_invalid = true + elsif !(opaque_struct = @opaques[opaque]) + error('%s: invalid opaque is given.', auth_req['username']) + nonce_is_invalid = true + elsif !check_opaque(opaque_struct, req, auth_req) + @opaques.delete(auth_req['opaque']) + nonce_is_invalid = true + end + elsif !check_nonce(req, auth_req) + nonce_is_invalid = true + end + + if /-sess$/i =~ auth_req['algorithm'] + ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce']) + else + ha1 = password + end + + if auth_req['qop'] == "auth" || auth_req['qop'] == nil + ha2 = hexdigest(req.request_method, auth_req['uri']) + ha2_res = hexdigest("", auth_req['uri']) + elsif auth_req['qop'] == "auth-int" + body_digest = @h.new + req.body { |chunk| body_digest.update(chunk) } + body_digest = body_digest.hexdigest + ha2 = hexdigest(req.request_method, auth_req['uri'], body_digest) + ha2_res = hexdigest("", auth_req['uri'], body_digest) + end + + if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int" + param2 = ['nonce', 'nc', 'cnonce', 'qop'].map{|key| + auth_req[key] + }.join(':') + digest = hexdigest(ha1, param2, ha2) + digest_res = hexdigest(ha1, param2, ha2_res) + else + digest = hexdigest(ha1, auth_req['nonce'], ha2) + digest_res = hexdigest(ha1, auth_req['nonce'], ha2_res) + end + + if digest != auth_req['response'] + error("%s: digest unmatch.", auth_req['username']) + return false + elsif nonce_is_invalid + error('%s: digest is valid, but nonce is not valid.', + auth_req['username']) + return :nonce_is_stale + elsif @use_auth_info_header + auth_info = { + 'nextnonce' => generate_next_nonce(req), + 'rspauth' => digest_res + } + if @use_opaque + opaque_struct.time = req.request_time + opaque_struct.nonce = auth_info['nextnonce'] + opaque_struct.nc = "%08x" % (auth_req['nc'].hex + 1) + end + if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int" + ['qop','cnonce','nc'].each{|key| + auth_info[key] = auth_req[key] + } + end + res[@resp_info_field] = auth_info.keys.map{|key| + if key == 'nc' + key + '=' + auth_info[key] + else + key + "=" + HTTPUtils::quote(auth_info[key]) + end + }.join(', ') + end + info('%s: authentication succeeded.', auth_req['username']) + req.user = auth_req['username'] + return true + end + + def split_param_value(string) + ret = {} + string.scan(/\G\s*([\w\-.*%!]+)=\s*(?:\"((?>\\.|[^\"])*)\"|([^,\"]*))\s*,?/) do + ret[$1] = $3 || $2.gsub(/\\(.)/, "\\1") + end + ret + end + + def generate_next_nonce(req) + now = "%012d" % req.request_time.to_i + pk = hexdigest(now, @instance_key)[0,32] + nonce = [now + ":" + pk].pack("m0") # it has 60 length of chars. + nonce + end + + def check_nonce(req, auth_req) + username = auth_req['username'] + nonce = auth_req['nonce'] + + pub_time, pk = nonce.unpack("m*")[0].split(":", 2) + if (!pub_time || !pk) + error("%s: empty nonce is given", username) + return false + elsif (hexdigest(pub_time, @instance_key)[0,32] != pk) + error("%s: invalid private-key: %s for %s", + username, hexdigest(pub_time, @instance_key)[0,32], pk) + return false + end + + diff_time = req.request_time.to_i - pub_time.to_i + if (diff_time < 0) + error("%s: difference of time-stamp is negative.", username) + return false + elsif diff_time > @nonce_expire_period + error("%s: nonce is expired.", username) + return false + end + + return true + end + + def generate_opaque(req) + @mutex.synchronize{ + now = req.request_time + if now - @last_nonce_expire > @nonce_expire_delta + @opaques.delete_if{|key,val| + (now - val.time) > @nonce_expire_period + } + @last_nonce_expire = now + end + begin + opaque = Utils::random_string(16) + end while @opaques[opaque] + @opaques[opaque] = OpaqueInfo.new(now, nil, '00000001') + opaque + } + end + + def check_opaque(opaque_struct, req, auth_req) + if (@use_next_nonce && auth_req['nonce'] != opaque_struct.nonce) + error('%s: nonce unmatched. "%s" for "%s"', + auth_req['username'], auth_req['nonce'], opaque_struct.nonce) + return false + elsif !check_nonce(req, auth_req) + return false + end + if (@check_nc && auth_req['nc'] != opaque_struct.nc) + error('%s: nc unmatched."%s" for "%s"', + auth_req['username'], auth_req['nc'], opaque_struct.nc) + return false + end + true + end + + def check_uri(req, auth_req) + uri = auth_req['uri'] + if uri != req.request_uri.to_s && uri != req.unparsed_uri && + (@internet_explorer_hack && uri != req.path) + error('%s: uri unmatch. "%s" for "%s"', auth_req['username'], + auth_req['uri'], req.request_uri.to_s) + return false + end + true + end + + def hexdigest(*args) + @h.hexdigest(args.join(":")) + end + + # :startdoc: + end + + ## + # Digest authentication for proxy servers. See DigestAuth for details. + + class ProxyDigestAuth < DigestAuth + include ProxyAuthenticator + + private + def check_uri(req, auth_req) # :nodoc: + return true + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htdigest.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htdigest.rb new file mode 100644 index 0000000..c7e853b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htdigest.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true +# +# httpauth/htdigest.rb -- Apache compatible htdigest file +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $ + +require_relative 'userdb' +require_relative 'digestauth' +require 'tempfile' + +module WEBrick + module HTTPAuth + + ## + # Htdigest accesses apache-compatible digest password files. Passwords are + # matched to a realm where they are valid. For security, the path for a + # digest password database should be stored outside of the paths available + # to the HTTP server. + # + # Htdigest is intended for use with WEBrick::HTTPAuth::DigestAuth and + # stores passwords using cryptographic hashes. + # + # htpasswd = WEBrick::HTTPAuth::Htdigest.new 'my_password_file' + # htpasswd.set_passwd 'my realm', 'username', 'password' + # htpasswd.flush + + class Htdigest + include UserDB + + ## + # Open a digest password database at +path+ + + def initialize(path) + @path = path + @mtime = Time.at(0) + @digest = Hash.new + @mutex = Thread::Mutex::new + @auth_type = DigestAuth + File.open(@path,"a").close unless File.exist?(@path) + reload + end + + ## + # Reloads passwords from the database + + def reload + mtime = File::mtime(@path) + if mtime > @mtime + @digest.clear + File.open(@path){|io| + while line = io.gets + line.chomp! + user, realm, pass = line.split(/:/, 3) + unless @digest[realm] + @digest[realm] = Hash.new + end + @digest[realm][user] = pass + end + } + @mtime = mtime + end + end + + ## + # Flush the password database. If +output+ is given the database will + # be written there instead of to the original path. + + def flush(output=nil) + output ||= @path + tmp = Tempfile.create("htpasswd", File::dirname(output)) + renamed = false + begin + each{|item| tmp.puts(item.join(":")) } + tmp.close + File::rename(tmp.path, output) + renamed = true + ensure + tmp.close + File.unlink(tmp.path) if !renamed + end + end + + ## + # Retrieves a password from the database for +user+ in +realm+. If + # +reload_db+ is true the database will be reloaded first. + + def get_passwd(realm, user, reload_db) + reload() if reload_db + if hash = @digest[realm] + hash[user] + end + end + + ## + # Sets a password in the database for +user+ in +realm+ to +pass+. + + def set_passwd(realm, user, pass) + @mutex.synchronize{ + unless @digest[realm] + @digest[realm] = Hash.new + end + @digest[realm][user] = make_passwd(realm, user, pass) + } + end + + ## + # Removes a password from the database for +user+ in +realm+. + + def delete_passwd(realm, user) + if hash = @digest[realm] + hash.delete(user) + end + end + + ## + # Iterate passwords in the database. + + def each # :yields: [user, realm, password_hash] + @digest.keys.sort.each{|realm| + hash = @digest[realm] + hash.keys.sort.each{|user| + yield([user, realm, hash[user]]) + } + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htgroup.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htgroup.rb new file mode 100644 index 0000000..df19b85 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htgroup.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true +# +# httpauth/htgroup.rb -- Apache compatible htgroup file +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htgroup.rb,v 1.1 2003/02/16 22:22:56 gotoyuzo Exp $ + +require 'tempfile' + +module WEBrick + module HTTPAuth + + ## + # Htgroup accesses apache-compatible group files. Htgroup can be used to + # provide group-based authentication for users. Currently Htgroup is not + # directly integrated with any authenticators in WEBrick. For security, + # the path for a digest password database should be stored outside of the + # paths available to the HTTP server. + # + # Example: + # + # htgroup = WEBrick::HTTPAuth::Htgroup.new 'my_group_file' + # htgroup.add 'superheroes', %w[spiderman batman] + # + # htgroup.members('superheroes').include? 'magneto' # => false + + class Htgroup + + ## + # Open a group database at +path+ + + def initialize(path) + @path = path + @mtime = Time.at(0) + @group = Hash.new + File.open(@path,"a").close unless File.exist?(@path) + reload + end + + ## + # Reload groups from the database + + def reload + if (mtime = File::mtime(@path)) > @mtime + @group.clear + File.open(@path){|io| + while line = io.gets + line.chomp! + group, members = line.split(/:\s*/, 2) + @group[group] = members.split(/\s+/) + end + } + @mtime = mtime + end + end + + ## + # Flush the group database. If +output+ is given the database will be + # written there instead of to the original path. + + def flush(output=nil) + output ||= @path + tmp = Tempfile.create("htgroup", File::dirname(output)) + begin + @group.keys.sort.each{|group| + tmp.puts(format("%s: %s", group, self.members(group).join(" "))) + } + ensure + tmp.close + if $! + File.unlink(tmp.path) + else + return File.rename(tmp.path, output) + end + end + end + + ## + # Retrieve the list of members from +group+ + + def members(group) + reload + @group[group] || [] + end + + ## + # Add an Array of +members+ to +group+ + + def add(group, members) + @group[group] = members(group) | members + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htpasswd.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htpasswd.rb new file mode 100644 index 0000000..db70125 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/htpasswd.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true +# +# httpauth/htpasswd -- Apache compatible htpasswd file +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $ + +require_relative 'userdb' +require_relative 'basicauth' +require 'tempfile' + +module WEBrick + module HTTPAuth + + ## + # Htpasswd accesses apache-compatible password files. Passwords are + # matched to a realm where they are valid. For security, the path for a + # password database should be stored outside of the paths available to the + # HTTP server. + # + # Htpasswd is intended for use with WEBrick::HTTPAuth::BasicAuth. + # + # To create an Htpasswd database with a single user: + # + # htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file' + # htpasswd.set_passwd 'my realm', 'username', 'password' + # htpasswd.flush + + class Htpasswd + include UserDB + + ## + # Open a password database at +path+ + + def initialize(path, password_hash: nil) + @path = path + @mtime = Time.at(0) + @passwd = Hash.new + @auth_type = BasicAuth + @password_hash = password_hash + + case @password_hash + when nil + # begin + # require "string/crypt" + # rescue LoadError + # warn("Unable to load string/crypt, proceeding with deprecated use of String#crypt, consider using password_hash: :bcrypt") + # end + @password_hash = :crypt + when :crypt + # require "string/crypt" + when :bcrypt + require "bcrypt" + else + raise ArgumentError, "only :crypt and :bcrypt are supported for password_hash keyword argument" + end + + File.open(@path,"a").close unless File.exist?(@path) + reload + end + + ## + # Reload passwords from the database + + def reload + mtime = File::mtime(@path) + if mtime > @mtime + @passwd.clear + File.open(@path){|io| + while line = io.gets + line.chomp! + case line + when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z! + if @password_hash == :bcrypt + raise StandardError, ".htpasswd file contains crypt password, only bcrypt passwords supported" + end + user, pass = line.split(":", 2) + when %r!\A[^:]+:\$2[aby]\$\d{2}\$.{53}\z! + if @password_hash == :crypt + raise StandardError, ".htpasswd file contains bcrypt password, only crypt passwords supported" + end + user, pass = line.split(":", 2) + when /:\$/, /:{SHA}/ + raise NotImplementedError, + 'MD5, SHA1 .htpasswd file not supported' + else + raise StandardError, 'bad .htpasswd file' + end + @passwd[user] = pass + end + } + @mtime = mtime + end + end + + ## + # Flush the password database. If +output+ is given the database will + # be written there instead of to the original path. + + def flush(output=nil) + output ||= @path + tmp = Tempfile.create("htpasswd", File::dirname(output)) + renamed = false + begin + each{|item| tmp.puts(item.join(":")) } + tmp.close + File::rename(tmp.path, output) + renamed = true + ensure + tmp.close + File.unlink(tmp.path) if !renamed + end + end + + ## + # Retrieves a password from the database for +user+ in +realm+. If + # +reload_db+ is true the database will be reloaded first. + + def get_passwd(realm, user, reload_db) + reload() if reload_db + @passwd[user] + end + + ## + # Sets a password in the database for +user+ in +realm+ to +pass+. + + def set_passwd(realm, user, pass) + if @password_hash == :bcrypt + # Cost of 5 to match Apache default, and because the + # bcrypt default of 10 will introduce significant delays + # for every request. + @passwd[user] = BCrypt::Password.create(pass, :cost=>5) + else + @passwd[user] = make_passwd(realm, user, pass) + end + end + + ## + # Removes a password from the database for +user+ in +realm+. + + def delete_passwd(realm, user) + @passwd.delete(user) + end + + ## + # Iterate passwords in the database. + + def each # :yields: [user, password] + @passwd.keys.sort.each{|user| + yield([user, @passwd[user]]) + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/userdb.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/userdb.rb new file mode 100644 index 0000000..0d0f72b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpauth/userdb.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true +#-- +# httpauth/userdb.rb -- UserDB mix-in module. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: userdb.rb,v 1.2 2003/02/20 07:15:48 gotoyuzo Exp $ + +module WEBrick + module HTTPAuth + + ## + # User database mixin for HTTPAuth. This mixin dispatches user record + # access to the underlying auth_type for this database. + + module UserDB + + ## + # The authentication type. + # + # WEBrick::HTTPAuth::BasicAuth or WEBrick::HTTPAuth::DigestAuth are + # built-in. + + attr_accessor :auth_type + + ## + # Creates an obscured password in +realm+ with +user+ and +password+ + # using the auth_type of this database. + + def make_passwd(realm, user, pass) + @auth_type::make_passwd(realm, user, pass) + end + + ## + # Sets a password in +realm+ with +user+ and +password+ for the + # auth_type of this database. + + def set_passwd(realm, user, pass) + self[user] = pass + end + + ## + # Retrieves a password in +realm+ for +user+ for the auth_type of this + # database. +reload_db+ is a dummy value. + + def get_passwd(realm, user, reload_db=false) + make_passwd(realm, user, self[user]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpproxy.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpproxy.rb new file mode 100644 index 0000000..189faa9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpproxy.rb @@ -0,0 +1,354 @@ +# frozen_string_literal: true +# +# httpproxy.rb -- HTTPProxy Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 GOTO Kentaro +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpproxy.rb,v 1.18 2003/03/08 18:58:10 gotoyuzo Exp $ +# $kNotwork: straw.rb,v 1.3 2002/02/12 15:13:07 gotoken Exp $ + +require_relative "httpserver" +require "net/http" + +module WEBrick + + NullReader = Object.new # :nodoc: + class << NullReader # :nodoc: + def read(*args) + nil + end + alias gets read + end + + FakeProxyURI = Object.new # :nodoc: + class << FakeProxyURI # :nodoc: + def method_missing(meth, *args) + if %w(scheme host port path query userinfo).member?(meth.to_s) + return nil + end + super + end + end + + # :startdoc: + + ## + # An HTTP Proxy server which proxies GET, HEAD and POST requests. + # + # To create a simple proxy server: + # + # require 'webrick' + # require 'webrick/httpproxy' + # + # proxy = WEBrick::HTTPProxyServer.new Port: 8000 + # + # trap 'INT' do proxy.shutdown end + # trap 'TERM' do proxy.shutdown end + # + # proxy.start + # + # See ::new for proxy-specific configuration items. + # + # == Modifying proxied responses + # + # To modify content the proxy server returns use the +:ProxyContentHandler+ + # option: + # + # handler = proc do |req, res| + # if res['content-type'] == 'text/plain' then + # res.body << "\nThis content was proxied!\n" + # end + # end + # + # proxy = + # WEBrick::HTTPProxyServer.new Port: 8000, ProxyContentHandler: handler + + class HTTPProxyServer < HTTPServer + + ## + # Proxy server configurations. The proxy server handles the following + # configuration items in addition to those supported by HTTPServer: + # + # :ProxyAuthProc:: Called with a request and response to authorize a + # request + # :ProxyVia:: Appended to the via header + # :ProxyURI:: The proxy server's URI + # :ProxyContentHandler:: Called with a request and response and allows + # modification of the response + # :ProxyTimeout:: Sets the proxy timeouts to 30 seconds for open and 60 + # seconds for read operations + + def initialize(config={}, default=Config::HTTP) + super(config, default) + c = @config + @via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}" + end + + # :stopdoc: + def service(req, res) + if req.request_method == "CONNECT" + do_CONNECT(req, res) + elsif req.unparsed_uri =~ %r!^http://! + proxy_service(req, res) + else + super(req, res) + end + end + + def proxy_auth(req, res) + if proc = @config[:ProxyAuthProc] + proc.call(req, res) + end + req.header.delete("proxy-authorization") + end + + def proxy_uri(req, res) + # should return upstream proxy server's URI + return @config[:ProxyURI] + end + + def proxy_service(req, res) + # Proxy Authentication + proxy_auth(req, res) + + begin + public_send("do_#{req.request_method}", req, res) + rescue NoMethodError + raise HTTPStatus::MethodNotAllowed, + "unsupported method '#{req.request_method}'." + rescue => err + logger.debug("#{err.class}: #{err.message}") + raise HTTPStatus::ServiceUnavailable, err.message + end + + # Process contents + if handler = @config[:ProxyContentHandler] + handler.call(req, res) + end + end + + def do_CONNECT(req, res) + # Proxy Authentication + proxy_auth(req, res) + + ua = Thread.current[:WEBrickSocket] # User-Agent + raise HTTPStatus::InternalServerError, + "[BUG] cannot get socket" unless ua + + host, port = req.unparsed_uri.split(":", 2) + # Proxy authentication for upstream proxy server + if proxy = proxy_uri(req, res) + proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0" + if proxy.userinfo + credentials = "Basic " + [proxy.userinfo].pack("m0") + end + host, port = proxy.host, proxy.port + end + + begin + @logger.debug("CONNECT: upstream proxy is '#{host}:#{port}'.") + os = TCPSocket.new(host, port) # origin server + + if proxy + @logger.debug("CONNECT: sending a Request-Line") + os << proxy_request_line << CRLF + @logger.debug("CONNECT: > #{proxy_request_line}") + if credentials + @logger.debug("CONNECT: sending credentials") + os << "Proxy-Authorization: " << credentials << CRLF + end + os << CRLF + proxy_status_line = os.gets(LF) + @logger.debug("CONNECT: read Status-Line from the upstream server") + @logger.debug("CONNECT: < #{proxy_status_line}") + if %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line + while line = os.gets(LF) + break if /\A(#{CRLF}|#{LF})\z/om =~ line + end + else + raise HTTPStatus::BadGateway + end + end + @logger.debug("CONNECT #{host}:#{port}: succeeded") + res.status = HTTPStatus::RC_OK + rescue => ex + @logger.debug("CONNECT #{host}:#{port}: failed '#{ex.message}'") + res.set_error(ex) + raise HTTPStatus::EOFError + ensure + if handler = @config[:ProxyContentHandler] + handler.call(req, res) + end + res.send_response(ua) + access_log(@config, req, res) + + # Should clear request-line not to send the response twice. + # see: HTTPServer#run + req.parse(NullReader) rescue nil + end + + begin + while fds = IO::select([ua, os]) + if fds[0].member?(ua) + buf = ua.readpartial(1024); + @logger.debug("CONNECT: #{buf.bytesize} byte from User-Agent") + os.write(buf) + elsif fds[0].member?(os) + buf = os.readpartial(1024); + @logger.debug("CONNECT: #{buf.bytesize} byte from #{host}:#{port}") + ua.write(buf) + end + end + rescue + os.close + @logger.debug("CONNECT #{host}:#{port}: closed") + end + + raise HTTPStatus::EOFError + end + + def do_GET(req, res) + perform_proxy_request(req, res, Net::HTTP::Get) + end + + def do_HEAD(req, res) + perform_proxy_request(req, res, Net::HTTP::Head) + end + + def do_POST(req, res) + perform_proxy_request(req, res, Net::HTTP::Post, req.body_reader) + end + + def do_OPTIONS(req, res) + res['allow'] = "GET,HEAD,POST,OPTIONS,CONNECT" + end + + private + + # Some header fields should not be transferred. + HopByHop = %w( connection keep-alive proxy-authenticate upgrade + proxy-authorization te trailers transfer-encoding ) + ShouldNotTransfer = %w( set-cookie proxy-connection ) + def split_field(f) f ? f.split(/,\s+/).collect{|i| i.downcase } : [] end + + def choose_header(src, dst) + connections = split_field(src['connection']) + src.each{|key, value| + key = key.downcase + if HopByHop.member?(key) || # RFC2616: 13.5.1 + connections.member?(key) || # RFC2616: 14.10 + ShouldNotTransfer.member?(key) # pragmatics + @logger.debug("choose_header: '#{key}: #{value}'") + next + end + dst[key] = value + } + end + + # Net::HTTP is stupid about the multiple header fields. + # Here is workaround: + def set_cookie(src, dst) + if str = src['set-cookie'] + cookies = [] + str.split(/,\s*/).each{|token| + if /^[^=]+;/o =~ token + cookies[-1] << ", " << token + elsif /=/o =~ token + cookies << token + else + cookies[-1] << ", " << token + end + } + dst.cookies.replace(cookies) + end + end + + def set_via(h) + if @config[:ProxyVia] + if h['via'] + h['via'] << ", " << @via + else + h['via'] = @via + end + end + end + + def setup_proxy_header(req, res) + # Choose header fields to transfer + header = Hash.new + choose_header(req, header) + set_via(header) + return header + end + + def setup_upstream_proxy_authentication(req, res, header) + if upstream = proxy_uri(req, res) + if upstream.userinfo + header['proxy-authorization'] = + "Basic " + [upstream.userinfo].pack("m0") + end + return upstream + end + return FakeProxyURI + end + + def create_net_http(uri, upstream) + Net::HTTP.new(uri.host, uri.port, upstream.host, upstream.port) + end + + def perform_proxy_request(req, res, req_class, body_stream = nil) + uri = req.request_uri + path = uri.path.dup + path << "?" << uri.query if uri.query + header = setup_proxy_header(req, res) + upstream = setup_upstream_proxy_authentication(req, res, header) + + body_tmp = [] + http = create_net_http(uri, upstream) + req_fib = Fiber.new do + http.start do + if @config[:ProxyTimeout] + ################################## these issues are + http.open_timeout = 30 # secs # necessary (maybe because + http.read_timeout = 60 # secs # Ruby's bug, but why?) + ################################## + end + if body_stream && req['transfer-encoding'] =~ /\bchunked\b/i + header['Transfer-Encoding'] = 'chunked' + end + http_req = req_class.new(path, header) + http_req.body_stream = body_stream if body_stream + http.request(http_req) do |response| + # Persistent connection requirements are mysterious for me. + # So I will close the connection in every response. + res['proxy-connection'] = "close" + res['connection'] = "close" + + # stream Net::HTTP::HTTPResponse to WEBrick::HTTPResponse + res.status = response.code.to_i + res.chunked = response.chunked? + choose_header(response, res) + set_cookie(response, res) + set_via(res) + response.read_body do |buf| + body_tmp << buf + Fiber.yield # wait for res.body Proc#call + end + end # http.request + end + end + req_fib.resume # read HTTP response headers and first chunk of the body + res.body = ->(socket) do + while buf = body_tmp.shift + socket.write(buf) + buf.clear + req_fib.resume # continue response.read_body + end + end + end + # :stopdoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httprequest.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httprequest.rb new file mode 100644 index 0000000..7f9c002 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httprequest.rb @@ -0,0 +1,668 @@ +# frozen_string_literal: true +# +# httprequest.rb -- HTTPRequest Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $ + +require 'fiber' +require 'uri' +require_relative 'httpversion' +require_relative 'httpstatus' +require_relative 'httputils' +require_relative 'cookie' + +module WEBrick + + ## + # An HTTP request. This is consumed by service and do_* methods in + # WEBrick servlets + + class HTTPRequest + + BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ] # :nodoc: + + # :section: Request line + + ## + # The complete request line such as: + # + # GET / HTTP/1.1 + + attr_reader :request_line + + ## + # The request method, GET, POST, PUT, etc. + + attr_reader :request_method + + ## + # The unparsed URI of the request + + attr_reader :unparsed_uri + + ## + # The HTTP version of the request + + attr_reader :http_version + + # :section: Request-URI + + ## + # The parsed URI of the request + + attr_reader :request_uri + + ## + # The request path + + attr_reader :path + + ## + # The script name (CGI variable) + + attr_accessor :script_name + + ## + # The path info (CGI variable) + + attr_accessor :path_info + + ## + # The query from the URI of the request + + attr_accessor :query_string + + # :section: Header and entity body + + ## + # The raw header of the request + + attr_reader :raw_header + + ## + # The parsed header of the request + + attr_reader :header + + ## + # The parsed request cookies + + attr_reader :cookies + + ## + # The Accept header value + + attr_reader :accept + + ## + # The Accept-Charset header value + + attr_reader :accept_charset + + ## + # The Accept-Encoding header value + + attr_reader :accept_encoding + + ## + # The Accept-Language header value + + attr_reader :accept_language + + # :section: + + ## + # The remote user (CGI variable) + + attr_accessor :user + + ## + # The socket address of the server + + attr_reader :addr + + ## + # The socket address of the client + + attr_reader :peeraddr + + ## + # Hash of request attributes + + attr_reader :attributes + + ## + # Is this a keep-alive connection? + + attr_reader :keep_alive + + ## + # The local time this request was received + + attr_reader :request_time + + ## + # Creates a new HTTP request. WEBrick::Config::HTTP is the default + # configuration. + + def initialize(config) + @config = config + @buffer_size = @config[:InputBufferSize] + @logger = config[:Logger] + + @request_line = @request_method = + @unparsed_uri = @http_version = nil + + @request_uri = @host = @port = @path = nil + @script_name = @path_info = nil + @query_string = nil + @query = nil + + @raw_header = Array.new + @header = nil + @cookies = [] + @accept = [] + @accept_charset = [] + @accept_encoding = [] + @accept_language = [] + @body = +"" + + @addr = [] + @peeraddr = [] + @attributes = {} + @user = nil + @keep_alive = false + @request_time = nil + + @remaining_size = nil + @socket = nil + + @forwarded_proto = @forwarded_host = @forwarded_port = + @forwarded_server = @forwarded_for = nil + end + + ## + # Parses a request from +socket+. This is called internally by + # WEBrick::HTTPServer. + + def parse(socket=nil) + @socket = socket + begin + @peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : [] + @addr = socket.respond_to?(:addr) ? socket.addr : [] + rescue Errno::ENOTCONN + raise HTTPStatus::EOFError + end + + read_request_line(socket) + if @http_version.major > 0 + read_header(socket) + @header['cookie'].each{|cookie| + @cookies += Cookie::parse(cookie) + } + @accept = HTTPUtils.parse_qvalues(self['accept']) + @accept_charset = HTTPUtils.parse_qvalues(self['accept-charset']) + @accept_encoding = HTTPUtils.parse_qvalues(self['accept-encoding']) + @accept_language = HTTPUtils.parse_qvalues(self['accept-language']) + end + return if @request_method == "CONNECT" + return if @unparsed_uri == "*" + + begin + setup_forwarded_info + @request_uri = parse_uri(@unparsed_uri) + @path = HTTPUtils::unescape(@request_uri.path) + @path = HTTPUtils::normalize_path(@path) + @host = @request_uri.host + @port = @request_uri.port + @query_string = @request_uri.query + @script_name = "" + @path_info = @path.dup + rescue + raise HTTPStatus::BadRequest, "bad URI '#{@unparsed_uri}'." + end + + if /\Aclose\z/io =~ self["connection"] + @keep_alive = false + elsif /\Akeep-alive\z/io =~ self["connection"] + @keep_alive = true + elsif @http_version < "1.1" + @keep_alive = false + else + @keep_alive = true + end + end + + ## + # Generate HTTP/1.1 100 continue response if the client expects it, + # otherwise does nothing. + + def continue # :nodoc: + if self['expect'] == '100-continue' && @config[:HTTPVersion] >= "1.1" + @socket << "HTTP/#{@config[:HTTPVersion]} 100 continue#{CRLF}#{CRLF}" + @header.delete('expect') + end + end + + ## + # Returns the request body. + + def body(&block) # :yields: body_chunk + block ||= Proc.new{|chunk| @body << chunk } + read_body(@socket, block) + @body.empty? ? nil : @body + end + + ## + # Prepares the HTTPRequest object for use as the + # source for IO.copy_stream + + def body_reader + @body_tmp = [] + @body_rd = Fiber.new do + body do |buf| + @body_tmp << buf + Fiber.yield + end + end + @body_rd.resume # grab the first chunk and yield + self + end + + # for IO.copy_stream. + def readpartial(size, buf = ''.b) # :nodoc + res = @body_tmp.shift or raise EOFError, 'end of file reached' + if res.length > size + @body_tmp.unshift(res[size..-1]) + res = res[0..size - 1] + end + buf.replace(res) + res.clear + # get more chunks - check alive? because we can take a partial chunk + @body_rd.resume if @body_rd.alive? + buf + end + + ## + # Request query as a Hash + + def query + unless @query + parse_query() + end + @query + end + + ## + # The content-length header + + def content_length + return Integer(self['content-length']) + end + + ## + # The content-type header + + def content_type + return self['content-type'] + end + + ## + # Retrieves +header_name+ + + def [](header_name) + if @header + value = @header[header_name.downcase] + value.empty? ? nil : value.join + end + end + + ## + # Iterates over the request headers + + def each + if @header + @header.each{|k, v| + value = @header[k] + yield(k, value.empty? ? nil : value.join) + } + end + end + + ## + # The host this request is for + + def host + return @forwarded_host || @host + end + + ## + # The port this request is for + + def port + return @forwarded_port || @port + end + + ## + # The server name this request is for + + def server_name + return @forwarded_server || @config[:ServerName] + end + + ## + # The client's IP address + + def remote_ip + return self["client-ip"] || @forwarded_for || @peeraddr[3] + end + + ## + # Is this an SSL request? + + def ssl? + return @request_uri.scheme == "https" + end + + ## + # Should the connection this request was made on be kept alive? + + def keep_alive? + @keep_alive + end + + def to_s # :nodoc: + ret = @request_line.dup + @raw_header.each{|line| ret << line } + ret << CRLF + ret << body if body + ret + end + + ## + # Consumes any remaining body and updates keep-alive status + + def fixup() # :nodoc: + begin + body{|chunk| } # read remaining body + rescue HTTPStatus::Error => ex + @logger.error("HTTPRequest#fixup: #{ex.class} occurred.") + @keep_alive = false + rescue => ex + @logger.error(ex) + @keep_alive = false + end + end + + # This method provides the metavariables defined by the revision 3 + # of "The WWW Common Gateway Interface Version 1.1" + # To browse the current document of CGI Version 1.1, see below: + # https://www.rfc-editor.org/rfc/rfc3875 + + def meta_vars + meta = Hash.new + + cl = self["Content-Length"] + ct = self["Content-Type"] + meta["CONTENT_LENGTH"] = cl if cl.to_i > 0 + meta["CONTENT_TYPE"] = ct.dup if ct + meta["GATEWAY_INTERFACE"] = "CGI/1.1" + meta["PATH_INFO"] = @path_info ? @path_info.dup : "" + #meta["PATH_TRANSLATED"] = nil # no plan to be provided + meta["QUERY_STRING"] = @query_string ? @query_string.dup : "" + meta["REMOTE_ADDR"] = @peeraddr[3] + meta["REMOTE_HOST"] = @peeraddr[2] + #meta["REMOTE_IDENT"] = nil # no plan to be provided + meta["REMOTE_USER"] = @user + meta["REQUEST_METHOD"] = @request_method.dup + meta["REQUEST_URI"] = @request_uri.to_s + meta["SCRIPT_NAME"] = @script_name.dup + meta["SERVER_NAME"] = @host + meta["SERVER_PORT"] = @port.to_s + meta["SERVER_PROTOCOL"] = "HTTP/" + @config[:HTTPVersion].to_s + meta["SERVER_SOFTWARE"] = @config[:ServerSoftware].dup + + self.each{|key, val| + next if /^content-type$/i =~ key + next if /^content-length$/i =~ key + name = "HTTP_" + key + name.gsub!(/-/o, "_") + name.upcase! + meta[name] = val + } + + meta + end + + private + + # :stopdoc: + + MAX_URI_LENGTH = 2083 # :nodoc: + + # same as Mongrel, Thin and Puma + MAX_HEADER_LENGTH = (112 * 1024) # :nodoc: + + def read_request_line(socket) + @request_line = read_line(socket, MAX_URI_LENGTH) if socket + raise HTTPStatus::EOFError unless @request_line + + @request_bytes = @request_line.bytesize + if @request_bytes >= MAX_URI_LENGTH and @request_line[-1, 1] != LF + raise HTTPStatus::RequestURITooLarge + end + + @request_time = Time.now + if /^(\S+) (\S++)(?: HTTP\/(\d+\.\d+))?\r\n/mo =~ @request_line + @request_method = $1 + @unparsed_uri = $2 + @http_version = HTTPVersion.new($3 ? $3 : "0.9") + else + rl = @request_line.sub(/\x0d?\x0a\z/o, '') + raise HTTPStatus::BadRequest, "bad Request-Line '#{rl}'." + end + end + + def read_header(socket) + if socket + end_of_headers = false + + while line = read_line(socket) + if line == CRLF + end_of_headers = true + break + end + if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH + raise HTTPStatus::RequestEntityTooLarge, 'headers too large' + end + if line.include?("\x00") + raise HTTPStatus::BadRequest, 'null byte in header' + end + @raw_header << line + end + + # Allow if @header already set to support chunked trailers + raise HTTPStatus::EOFError unless end_of_headers || @header + end + @header = HTTPUtils::parse_header(@raw_header.join) + + if (content_length = @header['content-length']) && content_length.length != 0 + if content_length.length > 1 + raise HTTPStatus::BadRequest, "multiple content-length request headers" + elsif !/\A\d+\z/.match?(content_length[0]) + raise HTTPStatus::BadRequest, "invalid content-length request header" + end + end + end + + def parse_uri(str, scheme="http") + if @config[:Escape8bitURI] + str = HTTPUtils::escape8bit(str) + end + str.sub!(%r{\A/+}o, '/') + uri = URI::parse(str) + return uri if uri.absolute? + if @forwarded_host + host, port = @forwarded_host, @forwarded_port + elsif self["host"] + host, port = parse_host_request_line(self["host"]) + elsif @addr.size > 0 + host, port = @addr[2], @addr[1] + else + host, port = @config[:ServerName], @config[:Port] + end + uri.scheme = @forwarded_proto || scheme + uri.host = host + uri.port = port ? port.to_i : nil + return URI::parse(uri.to_s) + end + + host_pattern = URI::RFC2396_Parser.new.pattern.fetch(:HOST) + HOST_PATTERN = /\A(#{host_pattern})(?::(\d+))?\z/n + def parse_host_request_line(host) + host.scan(HOST_PATTERN)[0] + end + + def read_body(socket, block) + return unless socket + if tc = self['transfer-encoding'] + if self['content-length'] + raise HTTPStatus::BadRequest, "request with both transfer-encoding and content-length, possible request smuggling" + end + + case tc + when /\Achunked\z/io then read_chunked(socket, block) + else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}." + end + elsif self['content-length'] || @remaining_size + @remaining_size ||= self['content-length'].to_i + while @remaining_size > 0 + sz = [@buffer_size, @remaining_size].min + break unless buf = read_data(socket, sz) + @remaining_size -= buf.bytesize + block.call(buf) + end + if @remaining_size > 0 && @socket.eof? + raise HTTPStatus::BadRequest, "invalid body size." + end + elsif BODY_CONTAINABLE_METHODS.member?(@request_method) + raise HTTPStatus::LengthRequired + end + return @body + end + + def read_chunk_size(socket) + line = read_line(socket) + if /\A([0-9a-fA-F]+)(?:;(\S+(?:=\S+)?))?\r\n\z/ =~ line + chunk_size = $1.hex + chunk_ext = $2 + [ chunk_size, chunk_ext ] + else + raise HTTPStatus::BadRequest, "bad chunk '#{line}'." + end + end + + def read_chunked(socket, block) + chunk_size, = read_chunk_size(socket) + while chunk_size > 0 + begin + sz = [ chunk_size, @buffer_size ].min + data = read_data(socket, sz) # read chunk-data + if data.nil? || data.bytesize != sz + raise HTTPStatus::BadRequest, "bad chunk data size." + end + block.call(data) + end while (chunk_size -= sz) > 0 + + line = read_line(socket) # skip CRLF + unless line == "\r\n" + raise HTTPStatus::BadRequest, "extra data after chunk '#{line}'." + end + + chunk_size, = read_chunk_size(socket) + end + read_header(socket) # trailer + CRLF + @header.delete("transfer-encoding") + @remaining_size = 0 + end + + def _read_data(io, method, *arg) + begin + WEBrick::Utils.timeout(@config[:RequestTimeout]){ + return io.__send__(method, *arg) + } + rescue Errno::ECONNRESET + return nil + rescue Timeout::Error + raise HTTPStatus::RequestTimeout + end + end + + def read_line(io, size=4096) + _read_data(io, :gets, LF, size) + end + + def read_data(io, size) + _read_data(io, :read, size) + end + + def parse_query() + begin + if @request_method == "GET" || @request_method == "HEAD" + @query = HTTPUtils::parse_query(@query_string) + elsif self['content-type'] =~ /^application\/x-www-form-urlencoded/ + @query = HTTPUtils::parse_query(body) + elsif self['content-type'] =~ /^multipart\/form-data; boundary=(.+)/ + boundary = HTTPUtils::dequote($1) + @query = HTTPUtils::parse_form_data(body, boundary) + else + @query = Hash.new + end + rescue => ex + raise HTTPStatus::BadRequest, ex.message + end + end + + PrivateNetworkRegexp = / + ^unknown$| + ^((::ffff:)?127.0.0.1|::1)$| + ^(::ffff:)?(10|172\.(1[6-9]|2[0-9]|3[01])|192\.168)\. + /ixo + + # It's said that all X-Forwarded-* headers will contain more than one + # (comma-separated) value if the original request already contained one of + # these headers. Since we could use these values as Host header, we choose + # the initial(first) value. (apr_table_mergen() adds new value after the + # existing value with ", " prefix) + def setup_forwarded_info + if @forwarded_server = self["x-forwarded-server"] + @forwarded_server = @forwarded_server.split(",", 2).first + end + if @forwarded_proto = self["x-forwarded-proto"] + @forwarded_proto = @forwarded_proto.split(",", 2).first + end + if host_port = self["x-forwarded-host"] + host_port = host_port.split(",", 2).first + if host_port =~ /\A(\[[0-9a-fA-F:]+\])(?::(\d+))?\z/ + @forwarded_host = $1 + tmp = $2 + else + @forwarded_host, tmp = host_port.split(":", 2) + end + @forwarded_port = (tmp || (@forwarded_proto == "https" ? 443 : 80)).to_i + end + if addrs = self["x-forwarded-for"] + addrs = addrs.split(",").collect(&:strip) + addrs.reject!{|ip| PrivateNetworkRegexp =~ ip } + @forwarded_for = addrs.first + end + end + + # :startdoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpresponse.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpresponse.rb new file mode 100644 index 0000000..4ad9cc2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpresponse.rb @@ -0,0 +1,588 @@ +# frozen_string_literal: true +# +# httpresponse.rb -- HTTPResponse Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpresponse.rb,v 1.45 2003/07/11 11:02:25 gotoyuzo Exp $ + +require 'time' +require 'uri' +require_relative 'httpversion' +require_relative 'htmlutils' +require_relative 'httputils' +require_relative 'httpstatus' + +module WEBrick + ## + # An HTTP response. This is filled in by the service or do_* methods of a + # WEBrick HTTP Servlet. + + class HTTPResponse + class InvalidHeader < StandardError + end + + ## + # HTTP Response version + + attr_reader :http_version + + ## + # Response status code (200) + + attr_reader :status + + ## + # Response header + + attr_reader :header + + ## + # Response cookies + + attr_reader :cookies + + ## + # Response reason phrase ("OK") + + attr_accessor :reason_phrase + + ## + # Body may be: + # * a String; + # * an IO-like object that responds to +#read+ and +#readpartial+; + # * a Proc-like object that responds to +#call+. + # + # In the latter case, either #chunked= should be set to +true+, + # or header['content-length'] explicitly provided. + # Example: + # + # server.mount_proc '/' do |req, res| + # res.chunked = true + # # or + # # res.header['content-length'] = 10 + # res.body = proc { |out| out.write(Time.now.to_s) } + # end + + attr_accessor :body + + ## + # Request method for this response + + attr_accessor :request_method + + ## + # Request URI for this response + + attr_accessor :request_uri + + ## + # Request HTTP version for this response + + attr_accessor :request_http_version + + ## + # Filename of the static file in this response. Only used by the + # FileHandler servlet. + + attr_accessor :filename + + ## + # Is this a keep-alive response? + + attr_accessor :keep_alive + + ## + # Configuration for this response + + attr_reader :config + + ## + # Bytes sent in this response + + attr_reader :sent_size + + ## + # Set the response body proc as an streaming/upgrade response. + + attr_accessor :upgrade + + ## + # Creates a new HTTP response object. WEBrick::Config::HTTP is the + # default configuration. + + def initialize(config) + @config = config + @buffer_size = config[:OutputBufferSize] + @logger = config[:Logger] + @header = Hash.new + @status = HTTPStatus::RC_OK + @reason_phrase = nil + @http_version = HTTPVersion::convert(@config[:HTTPVersion]) + @body = +"" + @keep_alive = true + @cookies = [] + @request_method = nil + @request_uri = nil + @request_http_version = @http_version # temporary + @chunked = false + @filename = nil + @sent_size = 0 + @bodytempfile = nil + end + + ## + # The response's HTTP status line + + def status_line + "HTTP/#@http_version #@status #@reason_phrase".rstrip << CRLF + end + + ## + # Sets the response's status to the +status+ code + + def status=(status) + @status = status + @reason_phrase = HTTPStatus::reason_phrase(status) + end + + ## + # Retrieves the response header +field+ + + def [](field) + @header[field.downcase] + end + + ## + # Sets the response header +field+ to +value+ + + def []=(field, value) + @chunked = value.to_s.downcase == 'chunked' if field.downcase == 'transfer-encoding' + @header[field.downcase] = value.to_s + end + + ## + # The content-length header + + def content_length + if len = self['content-length'] + return Integer(len) + end + end + + ## + # Sets the content-length header to +len+ + + def content_length=(len) + self['content-length'] = len.to_s + end + + ## + # The content-type header + + def content_type + self['content-type'] + end + + ## + # Sets the content-type header to +type+ + + def content_type=(type) + self['content-type'] = type + end + + ## + # Iterates over each header in the response + + def each + @header.each{|field, value| yield(field, value) } + end + + ## + # Will this response body be returned using chunked transfer-encoding? + + def chunked? + @chunked + end + + ## + # Enables chunked transfer encoding. + + def chunked=(val) + @chunked = val ? true : false + end + + ## + # Will this response's connection be kept alive? + + def keep_alive? + @keep_alive + end + + ## + # Sets the response to be a streaming/upgrade response. + # This will disable keep-alive and chunked transfer encoding. + + def upgrade!(protocol) + @upgrade = protocol + @keep_alive = false + @chunked = false + end + + ## + # Sends the response on +socket+ + + def send_response(socket) # :nodoc: + begin + setup_header() + send_header(socket) + send_body(socket) + rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex + @logger.debug(ex) + @keep_alive = false + rescue Exception => ex + @logger.error(ex) + @keep_alive = false + end + end + + ## + # Sets up the headers for sending + + def setup_header() # :nodoc: + @reason_phrase ||= HTTPStatus::reason_phrase(@status) + @header['server'] ||= @config[:ServerSoftware] + @header['date'] ||= Time.now.httpdate + + if @upgrade + @header['connection'] = 'upgrade' + @header['upgrade'] = @upgrade + @keep_alive = false + + return + end + + # HTTP/0.9 features + if @request_http_version < "1.0" + @http_version = HTTPVersion.new("0.9") + @keep_alive = false + end + + # HTTP/1.0 features + if @request_http_version < "1.1" + if chunked? + @chunked = false + ver = @request_http_version.to_s + msg = "chunked is set for an HTTP/#{ver} request. (ignored)" + @logger.warn(msg) + end + end + + # Determine the message length (RFC2616 -- 4.4 Message Length) + if @status == 304 || @status == 204 || HTTPStatus::info?(@status) + @header.delete('content-length') + @body = "" + elsif chunked? + @header["transfer-encoding"] = "chunked" + @header.delete('content-length') + elsif %r{^multipart/byteranges} =~ @header['content-type'] + @header.delete('content-length') + elsif @header['content-length'].nil? + if @body.respond_to?(:bytesize) + @header['content-length'] = @body.bytesize.to_s + else + @header['connection'] = 'close' + end + end + + # Keep-Alive connection. + if @header['connection'] == "close" + @keep_alive = false + elsif keep_alive? + if chunked? || @header['content-length'] || @status == 304 || @status == 204 || HTTPStatus.info?(@status) + @header['connection'] = "Keep-Alive" + else + msg = "Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true" + @logger.warn(msg) + @header['connection'] = "close" + @keep_alive = false + end + else + @header['connection'] = "close" + end + + # Location is a single absoluteURI. + if location = @header['location'] + if @request_uri + @header['location'] = @request_uri.merge(location).to_s + end + end + end + + def make_body_tempfile # :nodoc: + return if @bodytempfile + bodytempfile = Tempfile.create("webrick") + if @body.nil? + # nothing + elsif @body.respond_to? :readpartial + IO.copy_stream(@body, bodytempfile) + @body.close + elsif @body.respond_to? :call + @body.call(bodytempfile) + else + bodytempfile.write @body + end + bodytempfile.rewind + @body = @bodytempfile = bodytempfile + @header['content-length'] = bodytempfile.stat.size.to_s + end + + def remove_body_tempfile # :nodoc: + if @bodytempfile + @bodytempfile.close + File.unlink @bodytempfile.path + @bodytempfile = nil + end + end + + + ## + # Sends the headers on +socket+ + + def send_header(socket) # :nodoc: + if @http_version.major > 0 + data = status_line().dup + @header.each{|key, value| + tmp = key.gsub(/\bwww|^te$|\b\w/){ $&.upcase } + data << "#{tmp}: #{check_header(value)}" << CRLF + } + @cookies.each{|cookie| + data << "Set-Cookie: " << check_header(cookie.to_s) << CRLF + } + data << CRLF + socket.write(data) + end + rescue InvalidHeader => e + @header.clear + @cookies.clear + set_error e + retry + end + + ## + # Sends the body on +socket+ + + def send_body(socket) # :nodoc: + if @body.respond_to? :readpartial then + send_body_io(socket) + elsif @body.respond_to?(:call) then + send_body_proc(socket) + else + send_body_string(socket) + end + end + + ## + # Redirects to +url+ with a WEBrick::HTTPStatus::Redirect +status+. + # + # Example: + # + # res.set_redirect WEBrick::HTTPStatus::TemporaryRedirect + + def set_redirect(status, url) + url = URI(url).to_s + @body = "#{url}.\n" + @header['location'] = url + raise status + end + + ## + # Creates an error page for exception +ex+ with an optional +backtrace+ + + def set_error(ex, backtrace=false) + case ex + when HTTPStatus::Status + @keep_alive = false if HTTPStatus::error?(ex.code) + self.status = ex.code + else + @keep_alive = false + self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR + end + @header['content-type'] = "text/html; charset=ISO-8859-1" + + if respond_to?(:create_error_page) + create_error_page() + return + end + + if @request_uri + host, port = @request_uri.host, @request_uri.port + else + host, port = @config[:ServerName], @config[:Port] + end + + error_body(backtrace, ex, host, port) + end + + private + + def check_header(header_value) + header_value = header_value.to_s + if /[\r\n]/ =~ header_value + raise InvalidHeader + else + header_value + end + end + + # :stopdoc: + + def error_body(backtrace, ex, host, port) + @body = +"" + @body << <<-_end_of_html_ + + + #{HTMLUtils::escape(@reason_phrase)} + +

    #{HTMLUtils::escape(@reason_phrase)}

    + #{HTMLUtils::escape(ex.message)} +
    + _end_of_html_ + + if backtrace && $DEBUG + @body << "backtrace of '#{HTMLUtils::escape(ex.class.to_s)}' " + @body << "#{HTMLUtils::escape(ex.message)}" + @body << "
    "
    +        ex.backtrace.each{|line| @body << "\t#{line}\n"}
    +        @body << "

    " + end + + @body << <<-_end_of_html_ +
    + #{HTMLUtils::escape(@config[:ServerSoftware])} at + #{host}:#{port} +
    + + + _end_of_html_ + end + + def send_body_io(socket) + begin + if @request_method == "HEAD" + # do nothing + elsif chunked? + buf = +'' + begin + @body.readpartial(@buffer_size, buf) + size = buf.bytesize + data = +"#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}" + socket.write(data) + data.clear + @sent_size += size + rescue EOFError + break + end while true + buf.clear + socket.write("0#{CRLF}#{CRLF}") + else + if %r{\Abytes (\d+)-(\d+)/\d+\z} =~ @header['content-range'] + offset = $1.to_i + size = $2.to_i - offset + 1 + else + offset = nil + size = @header['content-length'] + size = size.to_i if size + end + begin + @sent_size = IO.copy_stream(@body, socket, size, offset) + rescue NotImplementedError + @body.seek(offset, IO::SEEK_SET) + @sent_size = IO.copy_stream(@body, socket, size) + end + end + ensure + @body.close + end + remove_body_tempfile + end + + def send_body_string(socket) + if @request_method == "HEAD" + # do nothing + elsif chunked? + body ? @body.bytesize : 0 + while buf = @body[@sent_size, @buffer_size] + break if buf.empty? + size = buf.bytesize + data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}" + buf.clear + socket.write(data) + @sent_size += size + end + socket.write("0#{CRLF}#{CRLF}") + else + if @body && @body.bytesize > 0 + socket.write(@body) + @sent_size = @body.bytesize + end + end + end + + def send_body_proc(socket) + if @request_method == "HEAD" + # do nothing + elsif chunked? + @body.call(ChunkedWrapper.new(socket, self)) + socket.write("0#{CRLF}#{CRLF}") + else + if @bodytempfile + @bodytempfile.rewind + IO.copy_stream(@bodytempfile, socket) + else + @body.call(socket) + end + + if content_length = @header['content-length'] + @sent_size = content_length.to_i + end + end + end + + class ChunkedWrapper + def initialize(socket, resp) + @socket = socket + @resp = resp + end + + def write(buf) + return 0 if buf.empty? + socket = @socket + @resp.instance_eval { + size = buf.bytesize + data = +"#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}" + socket.write(data) + data.clear + @sent_size += size + size + } + end + + def <<(*buf) + write(buf) + self + end + end + + # preserved for compatibility with some 3rd-party handlers + def _write_data(socket, data) + socket << data + end + + # :startdoc: + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/https.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/https.rb new file mode 100644 index 0000000..7f00b30 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/https.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true +# +# https.rb -- SSL/TLS enhancement for HTTPServer +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $ + +require_relative 'ssl' +require_relative 'httpserver' + +module WEBrick + module Config + HTTP.update(SSL) + end + + ## + #-- + # Adds SSL functionality to WEBrick::HTTPRequest + + class HTTPRequest + + ## + # HTTP request SSL cipher + + attr_reader :cipher + + ## + # HTTP request server certificate + + attr_reader :server_cert + + ## + # HTTP request client certificate + + attr_reader :client_cert + + # :stopdoc: + + alias orig_parse parse + + def parse(socket=nil) + if socket.respond_to?(:cert) + @server_cert = socket.cert || @config[:SSLCertificate] + @client_cert = socket.peer_cert + @client_cert_chain = socket.peer_cert_chain + @cipher = socket.cipher + end + orig_parse(socket) + end + + alias orig_parse_uri parse_uri + + def parse_uri(str, scheme="https") + if server_cert + return orig_parse_uri(str, scheme) + end + return orig_parse_uri(str) + end + private :parse_uri + + alias orig_meta_vars meta_vars + + def meta_vars + meta = orig_meta_vars + if server_cert + meta["HTTPS"] = "on" + meta["SSL_SERVER_CERT"] = @server_cert.to_pem + meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : "" + if @client_cert_chain + @client_cert_chain.each_with_index{|cert, i| + meta["SSL_CLIENT_CERT_CHAIN_#{i}"] = cert.to_pem + } + end + meta["SSL_CIPHER"] = @cipher[0] + meta["SSL_PROTOCOL"] = @cipher[1] + meta["SSL_CIPHER_USEKEYSIZE"] = @cipher[2].to_s + meta["SSL_CIPHER_ALGKEYSIZE"] = @cipher[3].to_s + end + meta + end + + # :startdoc: + end + + ## + #-- + # Fake WEBrick::HTTPRequest for lookup_server + + class SNIRequest + + ## + # The SNI hostname + + attr_reader :host + + ## + # The socket address of the server + + attr_reader :addr + + ## + # The port this request is for + + attr_reader :port + + ## + # Creates a new SNIRequest. + + def initialize(sslsocket, hostname) + @host = hostname + @addr = sslsocket.addr + @port = @addr[1] + end + end + + + ## + #-- + # Adds SSL functionality to WEBrick::HTTPServer + + class HTTPServer < ::WEBrick::GenericServer + ## + # ServerNameIndication callback + + def ssl_servername_callback(sslsocket, hostname = nil) + req = SNIRequest.new(sslsocket, hostname) + server = lookup_server(req) + server ? server.ssl_context : nil + end + + # :stopdoc: + + ## + # Check whether +server+ is also SSL server. + # Also +server+'s SSL context will be created. + + alias orig_virtual_host virtual_host + + def virtual_host(server) + if @config[:SSLEnable] && !server.ssl_context + raise ArgumentError, "virtual host must set SSLEnable to true" + end + orig_virtual_host(server) + end + + # :startdoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpserver.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpserver.rb new file mode 100644 index 0000000..6d9dc26 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpserver.rb @@ -0,0 +1,294 @@ +# frozen_string_literal: true +# +# httpserver.rb -- HTTPServer Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $ + +require 'io/wait' +require_relative 'server' +require_relative 'httputils' +require_relative 'httpstatus' +require_relative 'httprequest' +require_relative 'httpresponse' +require_relative 'httpservlet' +require_relative 'accesslog' + +module WEBrick + class HTTPServerError < ServerError; end + + ## + # An HTTP Server + + class HTTPServer < ::WEBrick::GenericServer + ## + # Creates a new HTTP server according to +config+ + # + # An HTTP server uses the following attributes: + # + # :AccessLog:: An array of access logs. See WEBrick::AccessLog + # :BindAddress:: Local address for the server to bind to + # :DocumentRoot:: Root path to serve files from + # :DocumentRootOptions:: Options for the default HTTPServlet::FileHandler + # :HTTPVersion:: The HTTP version of this server + # :Port:: Port to listen on + # :RequestCallback:: Called with a request and response before each + # request is serviced. + # :RequestTimeout:: Maximum time to wait between requests + # :ServerAlias:: Array of alternate names for this server for virtual + # hosting + # :ServerName:: Name for this server for virtual hosting + + def initialize(config={}, default=Config::HTTP) + super(config, default) + @http_version = HTTPVersion::convert(@config[:HTTPVersion]) + + @mount_tab = MountTable.new + if @config[:DocumentRoot] + mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot], + @config[:DocumentRootOptions]) + end + + unless @config[:AccessLog] + @config[:AccessLog] = [ + [ $stderr, AccessLog::COMMON_LOG_FORMAT ], + [ $stderr, AccessLog::REFERER_LOG_FORMAT ] + ] + end + + @virtual_hosts = Array.new + end + + ## + # Processes requests on +sock+ + + def run(sock) + while true + req = create_request(@config) + res = create_response(@config) + server = self + begin + timeout = @config[:RequestTimeout] + while timeout > 0 + break if sock.to_io.wait_readable(0.5) + break if @status != :Running + timeout -= 0.5 + end + raise HTTPStatus::EOFError if timeout <= 0 || @status != :Running + raise HTTPStatus::EOFError if sock.eof? + req.parse(sock) + res.request_method = req.request_method + res.request_uri = req.request_uri + res.request_http_version = req.http_version + res.keep_alive = req.keep_alive? + server = lookup_server(req) || self + if callback = server[:RequestCallback] + callback.call(req, res) + elsif callback = server[:RequestHandler] + msg = ":RequestHandler is deprecated, please use :RequestCallback" + @logger.warn(msg) + callback.call(req, res) + end + server.service(req, res) + rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex + res.set_error(ex) + rescue HTTPStatus::Error => ex + @logger.error(ex.message) + res.set_error(ex) + rescue HTTPStatus::Status => ex + res.status = ex.code + rescue StandardError => ex + @logger.error(ex) + res.set_error(ex, true) + ensure + if req.request_line + if req.keep_alive? && res.keep_alive? + req.fixup() + end + res.send_response(sock) + server.access_log(@config, req, res) + end + end + break if @http_version < "1.1" + break unless req.keep_alive? + break unless res.keep_alive? + end + end + + ## + # Services +req+ and fills in +res+ + + def service(req, res) + if req.unparsed_uri == "*" + if req.request_method == "OPTIONS" + do_OPTIONS(req, res) + raise HTTPStatus::OK + end + raise HTTPStatus::NotFound, "'#{req.unparsed_uri}' not found." + end + + servlet, options, script_name, path_info = search_servlet(req.path) + raise HTTPStatus::NotFound, "'#{req.path}' not found." unless servlet + req.script_name = script_name + req.path_info = path_info + si = servlet.get_instance(self, *options) + @logger.debug(format("%s is invoked.", si.class.name)) + si.service(req, res) + end + + ## + # The default OPTIONS request handler says GET, HEAD, POST and OPTIONS + # requests are allowed. + + def do_OPTIONS(req, res) + res["allow"] = "GET,HEAD,POST,OPTIONS" + end + + ## + # Mounts +servlet+ on +dir+ passing +options+ to the servlet at creation + # time + + def mount(dir, servlet, *options) + @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir)) + @mount_tab[dir] = [ servlet, options ] + end + + ## + # Mounts +proc+ or +block+ on +dir+ and calls it with a + # WEBrick::HTTPRequest and WEBrick::HTTPResponse + + def mount_proc(dir, proc=nil, &block) + proc ||= block + raise HTTPServerError, "must pass a proc or block" unless proc + mount(dir, HTTPServlet::ProcHandler.new(proc)) + end + + ## + # Unmounts +dir+ + + def unmount(dir) + @logger.debug(sprintf("unmount %s.", dir)) + @mount_tab.delete(dir) + end + alias umount unmount + + ## + # Finds a servlet for +path+ + + def search_servlet(path) + script_name, path_info = @mount_tab.scan(path) + servlet, options = @mount_tab[script_name] + if servlet + [ servlet, options, script_name, path_info ] + end + end + + ## + # Adds +server+ as a virtual host. + + def virtual_host(server) + @virtual_hosts << server + @virtual_hosts = @virtual_hosts.sort_by{|s| + num = 0 + num -= 4 if s[:BindAddress] + num -= 2 if s[:Port] + num -= 1 if s[:ServerName] + num + } + end + + ## + # Finds the appropriate virtual host to handle +req+ + + def lookup_server(req) + @virtual_hosts.find{|s| + (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) && + (s[:Port].nil? || req.port == s[:Port]) && + ((s[:ServerName].nil? || req.host == s[:ServerName]) || + (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host})) + } + end + + ## + # Logs +req+ and +res+ in the access logs. +config+ is used for the + # server name. + + def access_log(config, req, res) + param = AccessLog::setup_params(config, req, res) + @config[:AccessLog].each{|logger, fmt| + logger << AccessLog::format(fmt+"\n", param) + } + end + + ## + # Creates the HTTPRequest used when handling the HTTP + # request. Can be overridden by subclasses. + def create_request(with_webrick_config) + HTTPRequest.new(with_webrick_config) + end + + ## + # Creates the HTTPResponse used when handling the HTTP + # request. Can be overridden by subclasses. + def create_response(with_webrick_config) + HTTPResponse.new(with_webrick_config) + end + + ## + # Mount table for the path a servlet is mounted on in the directory space + # of the server. Users of WEBrick can only access this indirectly via + # WEBrick::HTTPServer#mount, WEBrick::HTTPServer#unmount and + # WEBrick::HTTPServer#search_servlet + + class MountTable # :nodoc: + def initialize + @tab = Hash.new + compile + end + + def [](dir) + dir = normalize(dir) + @tab[dir] + end + + def []=(dir, val) + dir = normalize(dir) + @tab[dir] = val + compile + val + end + + def delete(dir) + dir = normalize(dir) + res = @tab.delete(dir) + compile + res + end + + def scan(path) + @scanner =~ path + [ $&, $' ] + end + + private + + def compile + k = @tab.keys + k.sort! + k.reverse! + k.collect!{|path| Regexp.escape(path) } + @scanner = Regexp.new("\\A(" + k.join("|") +")(?=/|\\z)") + end + + def normalize(dir) + ret = dir ? dir.dup : +"" + ret.sub!(%r|/+\z|, "") + ret + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet.rb new file mode 100644 index 0000000..4cb1822 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# +# httpservlet.rb -- HTTPServlet Utility File +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $ + +require_relative 'httpservlet/abstract' +require_relative 'httpservlet/filehandler' +require_relative 'httpservlet/cgihandler' +require_relative 'httpservlet/erbhandler' +require_relative 'httpservlet/prochandler' + +module WEBrick + module HTTPServlet + FileHandler.add_handler("cgi", CGIHandler) + FileHandler.add_handler("rhtml", ERBHandler) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/abstract.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/abstract.rb new file mode 100644 index 0000000..280a4d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/abstract.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true +# +# httpservlet.rb -- HTTPServlet Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $ + +require_relative '../htmlutils' +require_relative '../httputils' +require_relative '../httpstatus' + +module WEBrick + module HTTPServlet + class HTTPServletError < StandardError; end + + ## + # AbstractServlet allows HTTP server modules to be reused across multiple + # servers and allows encapsulation of functionality. + # + # By default a servlet will respond to GET, HEAD (through an alias to GET) + # and OPTIONS requests. + # + # By default a new servlet is initialized for every request. A servlet + # instance can be reused by overriding ::get_instance in the + # AbstractServlet subclass. + # + # == A Simple Servlet + # + # class Simple < WEBrick::HTTPServlet::AbstractServlet + # def do_GET request, response + # status, content_type, body = do_stuff_with request + # + # response.status = status + # response['Content-Type'] = content_type + # response.body = body + # end + # + # def do_stuff_with request + # return 200, 'text/plain', 'you got a page' + # end + # end + # + # This servlet can be mounted on a server at a given path: + # + # server.mount '/simple', Simple + # + # == Servlet Configuration + # + # Servlets can be configured via initialize. The first argument is the + # HTTP server the servlet is being initialized for. + # + # class Configurable < Simple + # def initialize server, color, size + # super server + # @color = color + # @size = size + # end + # + # def do_stuff_with request + # content = "

    Hello, World!" + # + # return 200, "text/html", content + # end + # end + # + # This servlet must be provided two arguments at mount time: + # + # server.mount '/configurable', Configurable, 'red', '2em' + + class AbstractServlet + + ## + # Factory for servlet instances that will handle a request from +server+ + # using +options+ from the mount point. By default a new servlet + # instance is created for every call. + + def self.get_instance(server, *options) + self.new(server, *options) + end + + ## + # Initializes a new servlet for +server+ using +options+ which are + # stored as-is in +@options+. +@logger+ is also provided. + + def initialize(server, *options) + @server = @config = server + @logger = @server[:Logger] + @options = options + end + + ## + # Dispatches to a +do_+ method based on +req+ if such a method is + # available. (+do_GET+ for a GET request). Raises a MethodNotAllowed + # exception if the method is not implemented. + + def service(req, res) + method_name = "do_" + req.request_method.gsub(/-/, "_") + if respond_to?(method_name) + __send__(method_name, req, res) + else + raise HTTPStatus::MethodNotAllowed, + "unsupported method '#{req.request_method}'." + end + end + + ## + # Raises a NotFound exception + + def do_GET(req, res) + raise HTTPStatus::NotFound, "not found." + end + + ## + # Dispatches to do_GET + + def do_HEAD(req, res) + do_GET(req, res) + end + + ## + # Returns the allowed HTTP request methods + + def do_OPTIONS(req, res) + m = self.methods.grep(/\Ado_([A-Z]+)\z/) {$1} + m.sort! + res["allow"] = m.join(",") + end + + private + + ## + # Redirects to a path ending in / + + def redirect_to_directory_uri(req, res) + if req.path[-1] != ?/ + location = WEBrick::HTTPUtils.escape_path(req.path + "/") + if req.query_string && req.query_string.bytesize > 0 + location << "?" << req.query_string + end + res.set_redirect(HTTPStatus::MovedPermanently, location) + end + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgi_runner.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgi_runner.rb new file mode 100644 index 0000000..b0948ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgi_runner.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true +# +# cgi_runner.rb -- CGI launcher. +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $ + +def sysread(io, size) + buf = +"" + while size > 0 + tmp = io.sysread(size) + buf << tmp + size -= tmp.bytesize + end + return buf +end + +STDIN.binmode + +len = sysread(STDIN, 8).to_i +out = sysread(STDIN, len) +STDOUT.reopen(File.open(out, "w")) + +len = sysread(STDIN, 8).to_i +err = sysread(STDIN, len) +STDERR.reopen(File.open(err, "w")) + +len = sysread(STDIN, 8).to_i +dump = sysread(STDIN, len) +hash = Marshal.restore(dump) +ENV.keys.each{|name| ENV.delete(name) } +hash.each{|k, v| ENV[k] = v if v } + +dir = File::dirname(ENV["SCRIPT_FILENAME"]) +Dir::chdir dir + +if ARGV[0] + argv = ARGV.dup + argv << ENV["SCRIPT_FILENAME"] + exec(*argv) + # NOTREACHED +end +exec ENV["SCRIPT_FILENAME"] diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgihandler.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgihandler.rb new file mode 100644 index 0000000..450aa38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/cgihandler.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true +# +# cgihandler.rb -- CGIHandler Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $ + +require 'rbconfig' +require 'tempfile' +require_relative '../config' +require_relative 'abstract' + +module WEBrick + module HTTPServlet + + ## + # Servlet for handling CGI scripts + # + # Example: + # + # server.mount('/cgi/my_script', WEBrick::HTTPServlet::CGIHandler, + # '/path/to/my_script') + + class CGIHandler < AbstractServlet + Ruby = RbConfig.ruby # :nodoc: + CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\"" # :nodoc: + CGIRunnerArray = [Ruby, "#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb".freeze].freeze # :nodoc: + + ## + # Creates a new CGI script servlet for the script at +name+ + + def initialize(server, name) + super(server, name) + @script_filename = name + @tempdir = server[:TempDir] + interpreter = server[:CGIInterpreter] + if interpreter.is_a?(Array) + @cgicmd = CGIRunnerArray + interpreter + else + @cgicmd = "#{CGIRunner} #{interpreter}" + end + end + + # :stopdoc: + + def do_GET(req, res) + cgi_in = IO::popen(@cgicmd, "wb") + cgi_out = Tempfile.new("webrick.cgiout.", @tempdir, mode: IO::BINARY) + cgi_out.set_encoding("ASCII-8BIT") + cgi_err = Tempfile.new("webrick.cgierr.", @tempdir, mode: IO::BINARY) + cgi_err.set_encoding("ASCII-8BIT") + begin + cgi_in.sync = true + meta = req.meta_vars + meta["SCRIPT_FILENAME"] = @script_filename + meta["PATH"] = @config[:CGIPathEnv] + meta.delete("HTTP_PROXY") + if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM + meta["SystemRoot"] = ENV["SystemRoot"] + end + dump = Marshal.dump(meta) + + cgi_in.write("%8d" % cgi_out.path.bytesize) + cgi_in.write(cgi_out.path) + cgi_in.write("%8d" % cgi_err.path.bytesize) + cgi_in.write(cgi_err.path) + cgi_in.write("%8d" % dump.bytesize) + cgi_in.write(dump) + + req.body { |chunk| cgi_in.write(chunk) } + ensure + cgi_in.close + status = $?.exitstatus + sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM + data = cgi_out.read + cgi_out.close(true) + if errmsg = cgi_err.read + if errmsg.bytesize > 0 + @logger.error("CGIHandler: #{@script_filename}:\n" + errmsg) + end + end + cgi_err.close(true) + end + + if status != 0 + @logger.error("CGIHandler: #{@script_filename} exit with #{status}") + end + + data = "" unless data + raw_header, body = data.split(/^[\xd\xa]+/, 2) + raise HTTPStatus::InternalServerError, + "Premature end of script headers: #{@script_filename}" if body.nil? + + begin + header = HTTPUtils::parse_header(raw_header) + if /^(\d+)/ =~ header['status'][0] + res.status = $1.to_i + header.delete('status') + end + if header.has_key?('location') + # RFC 3875 6.2.3, 6.2.4 + res.status = 302 unless (300...400) === res.status + end + if header.has_key?('set-cookie') + header['set-cookie'].each{|k| + res.cookies << Cookie.parse_set_cookie(k) + } + header.delete('set-cookie') + end + header.each{|key, val| res[key] = val.join(", ") } + rescue => ex + raise HTTPStatus::InternalServerError, ex.message + end + res.body = body + end + alias do_POST do_GET + + # :startdoc: + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/erbhandler.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/erbhandler.rb new file mode 100644 index 0000000..3b232f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/erbhandler.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true +# +# erbhandler.rb -- ERBHandler Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $ + +require_relative 'abstract' + +require 'erb' + +module WEBrick + module HTTPServlet + + ## + # ERBHandler evaluates an ERB file and returns the result. This handler + # is automatically used if there are .rhtml files in a directory served by + # the FileHandler. + # + # ERBHandler supports GET and POST methods. + # + # The ERB file is evaluated with the local variables +servlet_request+ and + # +servlet_response+ which are a WEBrick::HTTPRequest and + # WEBrick::HTTPResponse respectively. + # + # Example .rhtml file: + # + # Request to <%= servlet_request.request_uri %> + # + # Query params <%= servlet_request.query.inspect %> + + class ERBHandler < AbstractServlet + + ## + # Creates a new ERBHandler on +server+ that will evaluate and serve the + # ERB file +name+ + + def initialize(server, name) + super(server, name) + @script_filename = name + end + + ## + # Handles GET requests + + def do_GET(req, res) + unless defined?(ERB) + @logger.warn "#{self.class}: ERB not defined." + raise HTTPStatus::Forbidden, "ERBHandler cannot work." + end + begin + data = File.open(@script_filename, &:read) + res.body = evaluate(ERB.new(data), req, res) + res['content-type'] ||= + HTTPUtils::mime_type(@script_filename, @config[:MimeTypes]) + rescue StandardError + raise + rescue Exception => ex + @logger.error(ex) + raise HTTPStatus::InternalServerError, ex.message + end + end + + ## + # Handles POST requests + + alias do_POST do_GET + + private + + ## + # Evaluates +erb+ providing +servlet_request+ and +servlet_response+ as + # local variables. + + def evaluate(erb, servlet_request, servlet_response) + Module.new.module_eval{ + servlet_request.meta_vars + servlet_request.query + erb.result(binding) + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/filehandler.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/filehandler.rb new file mode 100644 index 0000000..4e759d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/filehandler.rb @@ -0,0 +1,552 @@ +# frozen_string_literal: true +# +# filehandler.rb -- FileHandler Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $ + +require 'time' + +require_relative '../htmlutils' +require_relative '../httputils' +require_relative '../httpstatus' + +module WEBrick + module HTTPServlet + + ## + # Servlet for serving a single file. You probably want to use the + # FileHandler servlet instead as it handles directories and fancy indexes. + # + # Example: + # + # server.mount('/my_page.txt', WEBrick::HTTPServlet::DefaultFileHandler, + # '/path/to/my_page.txt') + # + # This servlet handles If-Modified-Since and Range requests. + + class DefaultFileHandler < AbstractServlet + + ## + # Creates a DefaultFileHandler instance for the file at +local_path+. + + def initialize(server, local_path) + super(server, local_path) + @local_path = local_path + end + + # :stopdoc: + + def do_GET(req, res) + st = File::stat(@local_path) + mtime = st.mtime + res['etag'] = sprintf("%x-%x-%x", st.ino, st.size, st.mtime.to_i) + + if not_modified?(req, res, mtime, res['etag']) + res.body = '' + raise HTTPStatus::NotModified + elsif req['range'] + make_partial_content(req, res, @local_path, st.size) + raise HTTPStatus::PartialContent + else + mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes]) + res['content-type'] = mtype + res['content-length'] = st.size.to_s + res['last-modified'] = mtime.httpdate + res.body = File.open(@local_path, "rb") + end + end + + def not_modified?(req, res, mtime, etag) + if ir = req['if-range'] + begin + if Time.httpdate(ir) >= mtime + return true + end + rescue + if HTTPUtils::split_header_value(ir).member?(res['etag']) + return true + end + end + end + + if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime + return true + end + + if (inm = req['if-none-match']) && + HTTPUtils::split_header_value(inm).member?(res['etag']) + return true + end + + return false + end + + # returns a lambda for webrick/httpresponse.rb send_body_proc + def multipart_body(body, parts, boundary, mtype, filesize) + lambda do |socket| + begin + begin + first = parts.shift + last = parts.shift + socket.write( + "--#{boundary}#{CRLF}" \ + "Content-Type: #{mtype}#{CRLF}" \ + "Content-Range: bytes #{first}-#{last}/#{filesize}#{CRLF}" \ + "#{CRLF}" + ) + + begin + IO.copy_stream(body, socket, last - first + 1, first) + rescue NotImplementedError + body.seek(first, IO::SEEK_SET) + IO.copy_stream(body, socket, last - first + 1) + end + socket.write(CRLF) + end while parts[0] + socket.write("--#{boundary}--#{CRLF}") + ensure + body.close + end + end + end + + def make_partial_content(req, res, filename, filesize) + mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes]) + unless ranges = HTTPUtils::parse_range_header(req['range']) + raise HTTPStatus::BadRequest, + "Unrecognized range-spec: \"#{req['range']}\"" + end + File.open(filename, "rb"){|io| + if ranges.size > 1 + time = Time.now + boundary = "#{time.sec}_#{time.usec}_#{Process::pid}" + parts = [] + ranges.each {|range| + prange = prepare_range(range, filesize) + next if prange[0] < 0 + parts.concat(prange) + } + raise HTTPStatus::RequestRangeNotSatisfiable if parts.empty? + res["content-type"] = "multipart/byteranges; boundary=#{boundary}" + if req.http_version < '1.1' + res['connection'] = 'close' + else + res.chunked = true + end + res.body = multipart_body(io.dup, parts, boundary, mtype, filesize) + elsif range = ranges[0] + first, last = prepare_range(range, filesize) + raise HTTPStatus::RequestRangeNotSatisfiable if first < 0 + res['content-type'] = mtype + res['content-range'] = "bytes #{first}-#{last}/#{filesize}" + res['content-length'] = (last - first + 1).to_s + res.body = io.dup + else + raise HTTPStatus::BadRequest + end + } + end + + def prepare_range(range, filesize) + first = range.first < 0 ? filesize + range.first : range.first + return -1, -1 if first < 0 || first >= filesize + last = range.last < 0 ? filesize + range.last : range.last + last = filesize - 1 if last >= filesize + return first, last + end + + # :startdoc: + end + + ## + # Serves a directory including fancy indexing and a variety of other + # options. + # + # Example: + # + # server.mount('/assets', WEBrick::HTTPServlet::FileHandler, + # '/path/to/assets') + + class FileHandler < AbstractServlet + HandlerTable = Hash.new # :nodoc: + + ## + # Allow custom handling of requests for files with +suffix+ by class + # +handler+ + + def self.add_handler(suffix, handler) + HandlerTable[suffix] = handler + end + + ## + # Remove custom handling of requests for files with +suffix+ + + def self.remove_handler(suffix) + HandlerTable.delete(suffix) + end + + ## + # Creates a FileHandler servlet on +server+ that serves files starting + # at directory +root+ + # + # +options+ may be a Hash containing keys from + # WEBrick::Config::FileHandler or +true+ or +false+. + # + # If +options+ is true or false then +:FancyIndexing+ is enabled or + # disabled respectively. + + def initialize(server, root, options={}, default=Config::FileHandler) + @config = server.config + @logger = @config[:Logger] + @root = File.expand_path(root) + if options == true || options == false + options = { :FancyIndexing => options } + end + @options = default.dup.update(options) + end + + # :stopdoc: + + def set_filesystem_encoding(str) + enc = Encoding.find('filesystem') + if enc == Encoding::US_ASCII + str.b + else + str.dup.force_encoding(enc) + end + end + + def service(req, res) + # if this class is mounted on "/" and /~username is requested. + # we're going to override path information before invoking service. + if defined?(Etc) && @options[:UserDir] && req.script_name.empty? + if %r|^(/~([^/]+))| =~ req.path_info + script_name, user = $1, $2 + path_info = $' + begin + passwd = Etc::getpwnam(user) + @root = File::join(passwd.dir, @options[:UserDir]) + req.script_name = script_name + req.path_info = path_info + rescue + @logger.debug "#{self.class}#do_GET: getpwnam(#{user}) failed" + end + end + end + prevent_directory_traversal(req, res) + super(req, res) + end + + def do_GET(req, res) + unless exec_handler(req, res) + set_dir_list(req, res) + end + end + + def do_POST(req, res) + unless exec_handler(req, res) + raise HTTPStatus::NotFound, "'#{req.path}' not found." + end + end + + def do_OPTIONS(req, res) + unless exec_handler(req, res) + super(req, res) + end + end + + # ToDo + # RFC2518: HTTP Extensions for Distributed Authoring -- WEBDAV + # + # PROPFIND PROPPATCH MKCOL DELETE PUT COPY MOVE + # LOCK UNLOCK + + # RFC3253: Versioning Extensions to WebDAV + # (Web Distributed Authoring and Versioning) + # + # VERSION-CONTROL REPORT CHECKOUT CHECK_IN UNCHECKOUT + # MKWORKSPACE UPDATE LABEL MERGE ACTIVITY + + private + + def trailing_pathsep?(path) + # check for trailing path separator: + # File.dirname("/aaaa/bbbb/") #=> "/aaaa") + # File.dirname("/aaaa/bbbb/x") #=> "/aaaa/bbbb") + # File.dirname("/aaaa/bbbb") #=> "/aaaa") + # File.dirname("/aaaa/bbbbx") #=> "/aaaa") + return File.dirname(path) != File.dirname(path+"x") + end + + def prevent_directory_traversal(req, res) + # Preventing directory traversal on Windows platforms; + # Backslashes (0x5c) in path_info are not interpreted as special + # character in URI notation. So the value of path_info should be + # normalize before accessing to the filesystem. + + # dirty hack for filesystem encoding; in nature, File.expand_path + # should not be used for path normalization. [Bug #3345] + path = req.path_info.dup.force_encoding(Encoding.find("filesystem")) + if trailing_pathsep?(req.path_info) + # File.expand_path removes the trailing path separator. + # Adding a character is a workaround to save it. + # File.expand_path("/aaa/") #=> "/aaa" + # File.expand_path("/aaa/" + "x") #=> "/aaa/x" + expanded = File.expand_path(path + "x") + expanded.chop! # remove trailing "x" + else + expanded = File.expand_path(path) + end + expanded.force_encoding(req.path_info.encoding) + req.path_info = expanded + end + + def exec_handler(req, res) + raise HTTPStatus::NotFound, "'#{req.path}' not found." unless @root + if set_filename(req, res) + handler = get_handler(req, res) + call_callback(:HandlerCallback, req, res) + h = handler.get_instance(@config, res.filename) + h.service(req, res) + return true + end + call_callback(:HandlerCallback, req, res) + return false + end + + def get_handler(req, res) + suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase + if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename + if @options[:AcceptableLanguages].include?($2.downcase) + suffix2 = $1.downcase + end + end + handler_table = @options[:HandlerTable] + return handler_table[suffix1] || handler_table[suffix2] || + HandlerTable[suffix1] || HandlerTable[suffix2] || + DefaultFileHandler + end + + def set_filename(req, res) + res.filename = @root + path_info = req.path_info.scan(%r|/[^/]*|) + + path_info.unshift("") # dummy for checking @root dir + while base = path_info.first + base = set_filesystem_encoding(base) + break if base == "/" + break unless File.directory?(File.expand_path(res.filename + base)) + shift_path_info(req, res, path_info) + call_callback(:DirectoryCallback, req, res) + end + + if base = path_info.first + base = set_filesystem_encoding(base) + if base == "/" + if file = search_index_file(req, res) + shift_path_info(req, res, path_info, file) + call_callback(:FileCallback, req, res) + return true + end + shift_path_info(req, res, path_info) + elsif file = search_file(req, res, base) + shift_path_info(req, res, path_info, file) + call_callback(:FileCallback, req, res) + return true + else + raise HTTPStatus::NotFound, "'#{req.path}' not found." + end + end + + return false + end + + def check_filename(req, res, name) + if nondisclosure_name?(name) || windows_ambiguous_name?(name) + @logger.warn("the request refers nondisclosure name '#{name}'.") + raise HTTPStatus::NotFound, "'#{req.path}' not found." + end + end + + def shift_path_info(req, res, path_info, base=nil) + tmp = path_info.shift + base = base || set_filesystem_encoding(tmp) + req.path_info = path_info.join + req.script_name << base + res.filename = File.expand_path(res.filename + base) + check_filename(req, res, File.basename(res.filename)) + end + + def search_index_file(req, res) + @config[:DirectoryIndex].each{|index| + if file = search_file(req, res, "/"+index) + return file + end + } + return nil + end + + def search_file(req, res, basename) + langs = @options[:AcceptableLanguages] + path = res.filename + basename + if File.file?(path) + return basename + elsif langs.size > 0 + req.accept_language.each{|lang| + path_with_lang = path + ".#{lang}" + if langs.member?(lang) && File.file?(path_with_lang) + return basename + ".#{lang}" + end + } + (langs - req.accept_language).each{|lang| + path_with_lang = path + ".#{lang}" + if File.file?(path_with_lang) + return basename + ".#{lang}" + end + } + end + return nil + end + + def call_callback(callback_name, req, res) + if cb = @options[callback_name] + cb.call(req, res) + end + end + + def windows_ambiguous_name?(name) + return true if /[. ]+\z/ =~ name + return true if /::\$DATA\z/ =~ name + return false + end + + def nondisclosure_name?(name) + @options[:NondisclosureName].each{|pattern| + if File.fnmatch(pattern, name, File::FNM_CASEFOLD) + return true + end + } + return false + end + + def set_dir_list(req, res) + redirect_to_directory_uri(req, res) + unless @options[:FancyIndexing] + raise HTTPStatus::Forbidden, "no access permission to '#{req.path}'" + end + local_path = res.filename + list = Dir::entries(local_path).collect{|name| + next if name == "." || name == ".." + next if nondisclosure_name?(name) + next if windows_ambiguous_name?(name) + st = (File::stat(File.join(local_path, name)) rescue nil) + if st.nil? + [ name, nil, -1 ] + elsif st.directory? + [ name + "/", st.mtime, -1 ] + else + [ name, st.mtime, st.size ] + end + } + list.compact! + + query = req.query + + d0 = nil + idx = nil + %w[N M S].each_with_index do |q, i| + if d = query.delete(q) + idx ||= i + d0 ||= d + end + end + d0 ||= "A" + idx ||= 0 + d1 = (d0 == "A") ? "D" : "A" + + if d0 == "A" + list.sort!{|a,b| a[idx] <=> b[idx] } + else + list.sort!{|a,b| b[idx] <=> a[idx] } + end + + namewidth = query["NameWidth"] + if namewidth == "*" + namewidth = nil + elsif !namewidth or (namewidth = namewidth.to_i) < 2 + namewidth = 25 + end + query = query.inject('') {|s, (k, v)| s << '&' << HTMLUtils::escape("#{k}=#{v}")}.dup + + type = +"text/html" + case enc = Encoding.find('filesystem') + when Encoding::US_ASCII, Encoding::ASCII_8BIT + else + type << "; charset=\"#{enc.name}\"" + end + res['content-type'] = type + + title = "Index of #{HTMLUtils::escape(req.path)}" + res.body = +<<-_end_of_html_ + + + + #{title} + + + +

    #{title}

    + _end_of_html_ + + res.body << "\n" + res.body << "" + res.body << "" + res.body << "\n" + res.body << "\n" + res.body << "\n" + + query.sub!(/\A&/, '?') + list.unshift [ "..", File::mtime(local_path+"/.."), -1 ] + list.each{ |name, time, size| + if name == ".." + dname = "Parent Directory" + elsif namewidth and name.size > namewidth + dname = name[0...(namewidth - 2)] << '..' + else + dname = name + end + s = +"" + s << "" + s << "\n" + res.body << s + } + res.body << "
    NameLast modifiedSize
    #{HTMLUtils::escape(dname)}" << (time ? time.strftime("%Y/%m/%d %H:%M") : "") << "" << (size >= 0 ? size.to_s : "-") << "
    " + res.body << "
    " + + res.body << <<-_end_of_html_ +
    + #{HTMLUtils::escape(@config[:ServerSoftware])}
    + at #{req.host}:#{req.port} +
    + + + _end_of_html_ + end + + # :startdoc: + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/prochandler.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/prochandler.rb new file mode 100644 index 0000000..92e4f80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpservlet/prochandler.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +# +# prochandler.rb -- ProcHandler Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: prochandler.rb,v 1.7 2002/09/21 12:23:42 gotoyuzo Exp $ + +require_relative 'abstract' + +module WEBrick + module HTTPServlet + + ## + # Mounts a proc at a path that accepts a request and response. + # + # Instead of mounting this servlet with WEBrick::HTTPServer#mount use + # WEBrick::HTTPServer#mount_proc: + # + # server.mount_proc '/' do |req, res| + # res.body = 'it worked!' + # res.status = 200 + # end + + class ProcHandler < AbstractServlet + # :stopdoc: + def get_instance(server, *options) + self + end + + def initialize(proc) + @proc = proc + end + + def do_GET(request, response) + @proc.call(request, response) + end + + alias do_POST do_GET + alias do_PUT do_GET + # :startdoc: + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpstatus.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpstatus.rb new file mode 100644 index 0000000..c21c1d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpstatus.rb @@ -0,0 +1,194 @@ +# frozen_string_literal: true +#-- +# httpstatus.rb -- HTTPStatus Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $ + +require_relative 'accesslog' + +module WEBrick + + ## + # This module is used to manager HTTP status codes. + # + # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for more + # information. + module HTTPStatus + + ## + # Root of the HTTP status class hierarchy + class Status < StandardError + class << self + attr_reader :code, :reason_phrase # :nodoc: + end + + # Returns the HTTP status code + def code() self::class::code end + + # Returns the HTTP status description + def reason_phrase() self::class::reason_phrase end + + alias to_i code # :nodoc: + end + + # Root of the HTTP info statuses + class Info < Status; end + # Root of the HTTP success statuses + class Success < Status; end + # Root of the HTTP redirect statuses + class Redirect < Status; end + # Root of the HTTP error statuses + class Error < Status; end + # Root of the HTTP client error statuses + class ClientError < Error; end + # Root of the HTTP server error statuses + class ServerError < Error; end + + class EOFError < StandardError; end + + # HTTP status codes and descriptions + StatusMessage = { # :nodoc: + 100 => 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Large', + 415 => 'Unsupported Media Type', + 416 => 'Request Range Not Satisfiable', + 417 => 'Expectation Failed', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 424 => 'Failed Dependency', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 451 => 'Unavailable For Legal Reasons', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 507 => 'Insufficient Storage', + 511 => 'Network Authentication Required', + } + + # Maps a status code to the corresponding Status class + CodeToError = {} # :nodoc: + + # Creates a status or error class for each status code and + # populates the CodeToError map. + StatusMessage.each{|code, message| + message.freeze + var_name = message.gsub(/[ \-]/,'_').upcase + err_name = message.gsub(/[ \-]/,'') + + case code + when 100...200; parent = Info + when 200...300; parent = Success + when 300...400; parent = Redirect + when 400...500; parent = ClientError + when 500...600; parent = ServerError + end + + const_set("RC_#{var_name}", code) + err_class = Class.new(parent) + err_class.instance_variable_set(:@code, code) + err_class.instance_variable_set(:@reason_phrase, message) + const_set(err_name, err_class) + CodeToError[code] = err_class + } + + ## + # Returns the description corresponding to the HTTP status +code+ + # + # WEBrick::HTTPStatus.reason_phrase 404 + # => "Not Found" + def reason_phrase(code) + StatusMessage[code.to_i] + end + + ## + # Is +code+ an informational status? + def info?(code) + code.to_i >= 100 and code.to_i < 200 + end + + ## + # Is +code+ a successful status? + def success?(code) + code.to_i >= 200 and code.to_i < 300 + end + + ## + # Is +code+ a redirection status? + def redirect?(code) + code.to_i >= 300 and code.to_i < 400 + end + + ## + # Is +code+ an error status? + def error?(code) + code.to_i >= 400 and code.to_i < 600 + end + + ## + # Is +code+ a client error status? + def client_error?(code) + code.to_i >= 400 and code.to_i < 500 + end + + ## + # Is +code+ a server error status? + def server_error?(code) + code.to_i >= 500 and code.to_i < 600 + end + + ## + # Returns the status class corresponding to +code+ + # + # WEBrick::HTTPStatus[302] + # => WEBrick::HTTPStatus::NotFound + # + def self.[](code) + CodeToError[code] + end + + module_function :reason_phrase + module_function :info?, :success?, :redirect?, :error? + module_function :client_error?, :server_error? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httputils.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httputils.rb new file mode 100644 index 0000000..e2c2a40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httputils.rb @@ -0,0 +1,543 @@ +# frozen_string_literal: true +# +# httputils.rb -- HTTPUtils Module +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httputils.rb,v 1.34 2003/06/05 21:34:08 gotoyuzo Exp $ + +require 'socket' +require 'tempfile' + +module WEBrick + CR = "\x0d" # :nodoc: + LF = "\x0a" # :nodoc: + CRLF = "\x0d\x0a" # :nodoc: + + ## + # HTTPUtils provides utility methods for working with the HTTP protocol. + # + # This module is generally used internally by WEBrick + + module HTTPUtils + + ## + # Normalizes a request path. Raises an exception if the path cannot be + # normalized. + + def normalize_path(path) + raise "abnormal path '#{path}'" if path[0] != ?/ + ret = path.dup + + ret.gsub!(%r{/+}o, '/') # // => / + while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => / + while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo + + raise "abnormal path '#{path}'" if %r{/\.\.(/|\Z)} =~ ret + ret + end + module_function :normalize_path + + ## + # Default mime types + + DefaultMimeTypes = { + "ai" => "application/postscript", + "asc" => "text/plain", + "avi" => "video/x-msvideo", + "avif" => "image/avif", + "bin" => "application/octet-stream", + "bmp" => "image/bmp", + "class" => "application/octet-stream", + "cer" => "application/pkix-cert", + "crl" => "application/pkix-crl", + "crt" => "application/x-x509-ca-cert", + "css" => "text/css", + "dms" => "application/octet-stream", + "doc" => "application/msword", + "dvi" => "application/x-dvi", + "eps" => "application/postscript", + "etx" => "text/x-setext", + "exe" => "application/octet-stream", + "gif" => "image/gif", + "htm" => "text/html", + "html" => "text/html", + "ico" => "image/x-icon", + "jpe" => "image/jpeg", + "jpeg" => "image/jpeg", + "jpg" => "image/jpeg", + "js" => "application/javascript", + "json" => "application/json", + "lha" => "application/octet-stream", + "lzh" => "application/octet-stream", + "mjs" => "application/javascript", + "mov" => "video/quicktime", + "mp4" => "video/mp4", + "mpe" => "video/mpeg", + "mpeg" => "video/mpeg", + "mpg" => "video/mpeg", + "otf" => "font/otf", + "pbm" => "image/x-portable-bitmap", + "pdf" => "application/pdf", + "pgm" => "image/x-portable-graymap", + "png" => "image/png", + "pnm" => "image/x-portable-anymap", + "ppm" => "image/x-portable-pixmap", + "ppt" => "application/vnd.ms-powerpoint", + "ps" => "application/postscript", + "qt" => "video/quicktime", + "ras" => "image/x-cmu-raster", + "rb" => "text/plain", + "rd" => "text/plain", + "rtf" => "application/rtf", + "sgm" => "text/sgml", + "sgml" => "text/sgml", + "svg" => "image/svg+xml", + "tif" => "image/tiff", + "tiff" => "image/tiff", + "ttc" => "font/collection", + "ttf" => "font/ttf", + "txt" => "text/plain", + "wasm" => "application/wasm", + "webm" => "video/webm", + "webmanifest" => "application/manifest+json", + "webp" => "image/webp", + "woff" => "font/woff", + "woff2" => "font/woff2", + "xbm" => "image/x-xbitmap", + "xhtml" => "text/html", + "xls" => "application/vnd.ms-excel", + "xml" => "text/xml", + "xpm" => "image/x-xpixmap", + "xwd" => "image/x-xwindowdump", + "zip" => "application/zip", + } + + ## + # Loads Apache-compatible mime.types in +file+. + + def load_mime_types(file) + # note: +file+ may be a "| command" for now; some people may + # rely on this, but currently we do not use this method by default. + File.open(file){ |io| + hash = Hash.new + io.each{ |line| + next if /^#/ =~ line + line.chomp! + mimetype, ext0 = line.split(/\s+/, 2) + next unless ext0 + next if ext0.empty? + ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype } + } + hash + } + end + module_function :load_mime_types + + ## + # Returns the mime type of +filename+ from the list in +mime_tab+. If no + # mime type was found application/octet-stream is returned. + + def mime_type(filename, mime_tab) + suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase) + suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase) + mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream" + end + module_function :mime_type + + ## + # Parses an HTTP header +raw+ into a hash of header fields with an Array + # of values. + + class SplitHeader < Array + def join(separator = ", ") + super + end + end + + class CookieHeader < Array + def join(separator = "; ") + super + end + end + + HEADER_CLASSES = Hash.new(SplitHeader).update({ + "cookie" => CookieHeader, + }) + + def parse_header(raw) + header = Hash.new([].freeze) + field = nil + raw.each_line{|line| + case line + when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):([^\r\n\0]*?)\r\n\z/om + field, value = $1, $2 + field.downcase! + header[field] = HEADER_CLASSES[field].new unless header.has_key?(field) + header[field] << value + when /^[ \t]+([^\r\n\0]*?)\r\n/om + unless field + raise HTTPStatus::BadRequest, "bad header '#{line}'." + end + value = line + value.gsub!(/\A[ \t]+/, '') + value.slice!(-2..-1) + header[field][-1] << " " << value + else + raise HTTPStatus::BadRequest, "bad header '#{line}'." + end + } + header.each{|key, values| + values.each{|value| + value.gsub!(/\A[ \t]+/, '') + value.gsub!(/[ \t]+\z/, '') + } + } + header + end + module_function :parse_header + + ## + # Splits a header value +str+ according to HTTP specification. + + def split_header_value(str) + str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]++)+) + (?:,[ \t]*|\Z)'xn).flatten + end + module_function :split_header_value + + ## + # Parses a Range header value +ranges_specifier+ + + def parse_range_header(ranges_specifier) + if /^bytes=(.*)/ =~ ranges_specifier + byte_range_set = split_header_value($1) + byte_range_set.collect{|range_spec| + case range_spec + when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i + when /^(\d+)-/ then $1.to_i .. -1 + when /^-(\d+)/ then -($1.to_i) .. -1 + else return nil + end + } + end + end + module_function :parse_range_header + + ## + # Parses q values in +value+ as used in Accept headers. + + def parse_qvalues(value) + tmp = [] + if value + parts = value.split(/,[ \t]*/) + parts.each {|part| + if m = %r{^([^ \t,]+?)(?:;[ \t]*q=(\d+(?:\.\d+)?))?$}.match(part) + val = m[1] + q = (m[2] or 1).to_f + tmp.push([val, q]) + end + } + tmp = tmp.sort_by{|val, q| -q} + tmp.collect!{|val, q| val} + end + return tmp + end + module_function :parse_qvalues + + ## + # Removes quotes and escapes from +str+ + + def dequote(str) + ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup + ret.gsub!(/\\(.)/, "\\1") + ret + end + module_function :dequote + + ## + # Quotes and escapes quotes in +str+ + + def quote(str) + +'"' << str.gsub(/[\\\"]/o, "\\\1") << '"' + end + module_function :quote + + ## + # Stores multipart form data. FormData objects are created when + # WEBrick::HTTPUtils.parse_form_data is called. + + class FormData < String + EmptyRawHeader = [].freeze # :nodoc: + EmptyHeader = {}.freeze # :nodoc: + + ## + # The name of the form data part + + attr_accessor :name + + ## + # The filename of the form data part + + attr_accessor :filename + + attr_accessor :next_data # :nodoc: + protected :next_data + + ## + # Creates a new FormData object. + # + # +args+ is an Array of form data entries. One FormData will be created + # for each entry. + # + # This is called by WEBrick::HTTPUtils.parse_form_data for you + + def initialize(*args) + @name = @filename = @next_data = nil + if args.empty? + @raw_header = [] + @header = nil + super("") + else + @raw_header = EmptyRawHeader + @header = EmptyHeader + super(args.shift) + unless args.empty? + @next_data = self.class.new(*args) + end + end + end + + ## + # Retrieves the header at the first entry in +key+ + + def [](*key) + begin + @header[key[0].downcase].join(", ") + rescue StandardError, NameError + super + end + end + + ## + # Adds +str+ to this FormData which may be the body, a header or a + # header entry. + # + # This is called by WEBrick::HTTPUtils.parse_form_data for you + + def <<(str) + if @header + super + elsif str == CRLF + @header = HTTPUtils::parse_header(@raw_header.join) + if cd = self['content-disposition'] + if /[ \t]+name="(.*?)"/ =~ cd then @name = $1 end + if /[ \t]+filename="(.*?)"/ =~ cd then @filename = $1 end + end + else + @raw_header << str + end + self + end + + ## + # Adds +data+ at the end of the chain of entries + # + # This is called by WEBrick::HTTPUtils.parse_form_data for you. + + def append_data(data) + tmp = self + while tmp + unless tmp.next_data + tmp.next_data = data + break + end + tmp = tmp.next_data + end + self + end + + ## + # Yields each entry in this FormData + + def each_data + tmp = self + while tmp + next_data = tmp.next_data + yield(tmp) + tmp = next_data + end + end + + ## + # Returns all the FormData as an Array + + def list + ret = [] + each_data{|data| + ret << data.to_s + } + ret + end + + ## + # A FormData will behave like an Array + + alias :to_ary :list + + ## + # This FormData's body + + def to_s + String.new(self) + end + end + + ## + # Parses the query component of a URI in +str+ + + def parse_query(str) + query = Hash.new + if str + str.split(/[&;]/).each{|x| + next if x.empty? + key, val = x.split(/=/,2) + key = unescape_form(key) + val = unescape_form(val.to_s) + val = FormData.new(val) + val.name = key + if query.has_key?(key) + query[key].append_data(val) + next + end + query[key] = val + } + end + query + end + module_function :parse_query + + ## + # Parses form data in +io+ with the given +boundary+ + + def parse_form_data(io, boundary) + boundary_regexp = /\A--#{Regexp.quote(boundary)}(--)?#{CRLF}\z/ + form_data = Hash.new + return form_data unless io + data = nil + io.each_line{|line| + if boundary_regexp =~ line + if data + data.chop! + key = data.name + if form_data.has_key?(key) + form_data[key].append_data(data) + else + form_data[key] = data + end + end + data = FormData.new + next + else + if data + data << line + end + end + } + return form_data + end + module_function :parse_form_data + + ##### + + reserved = ';/?:@&=+$,' + num = '0123456789' + lowalpha = 'abcdefghijklmnopqrstuvwxyz' + upalpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + mark = '-_.!~*\'()' + unreserved = num + lowalpha + upalpha + mark + control = (0x0..0x1f).collect{|c| c.chr }.join + "\x7f" + space = " " + delims = '<>#%"' + unwise = '{}|\\^[]`' + nonascii = (0x80..0xff).collect{|c| c.chr }.join + + module_function + + # :stopdoc: + + def _make_regex(str) /([#{Regexp.escape(str)}])/n end + def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end + def _escape(str, regex) + str = str.b + str.gsub!(regex) {"%%%02X" % $1.ord} + # %-escaped string should contain US-ASCII only + str.force_encoding(Encoding::US_ASCII) + end + def _unescape(str, regex) + str = str.b + str.gsub!(regex) {$1.hex.chr} + # encoding of %-unescaped string is unknown + str + end + + UNESCAPED = _make_regex(control+space+delims+unwise+nonascii) + UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii) + NONASCII = _make_regex(nonascii) + ESCAPED = /%([0-9a-fA-F]{2})/ + UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,") + + # :startdoc: + + ## + # Escapes HTTP reserved and unwise characters in +str+ + + def escape(str) + _escape(str, UNESCAPED) + end + + ## + # Unescapes HTTP reserved and unwise characters in +str+ + + def unescape(str) + _unescape(str, ESCAPED) + end + + ## + # Escapes form reserved characters in +str+ + + def escape_form(str) + ret = _escape(str, UNESCAPED_FORM) + ret.gsub!(/ /, "+") + ret + end + + ## + # Unescapes form reserved characters in +str+ + + def unescape_form(str) + _unescape(str.gsub(/\+/, " "), ESCAPED) + end + + ## + # Escapes path +str+ + + def escape_path(str) + result = +"" + str.scan(%r{/([^/]*)}).each{|i| + result << "/" << _escape(i[0], UNESCAPED_PCHAR) + } + return result + end + + ## + # Escapes 8 bit characters in +str+ + + def escape8bit(str) + _escape(str, NONASCII) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpversion.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpversion.rb new file mode 100644 index 0000000..6349590 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/httpversion.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true +#-- +# HTTPVersion.rb -- presentation of HTTP version +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: httpversion.rb,v 1.5 2002/09/21 12:23:37 gotoyuzo Exp $ + +module WEBrick + + ## + # Represents an HTTP protocol version + + class HTTPVersion + include Comparable + + ## + # The major protocol version number + + attr_accessor :major + + ## + # The minor protocol version number + + attr_accessor :minor + + ## + # Converts +version+ into an HTTPVersion + + def self.convert(version) + version.is_a?(self) ? version : new(version) + end + + ## + # Creates a new HTTPVersion from +version+. + + def initialize(version) + case version + when HTTPVersion + @major, @minor = version.major, version.minor + when String + if /^(\d+)\.(\d+)$/ =~ version + @major, @minor = $1.to_i, $2.to_i + end + end + if @major.nil? || @minor.nil? + raise ArgumentError, + format("cannot convert %s into %s", version.class, self.class) + end + end + + ## + # Compares this version with +other+ according to the HTTP specification + # rules. + + def <=>(other) + unless other.is_a?(self.class) + other = self.class.new(other) + end + if (ret = @major <=> other.major) == 0 + return @minor <=> other.minor + end + return ret + end + + ## + # The HTTP version as show in the HTTP request and response. For example, + # "1.1" + + def to_s + format("%d.%d", @major, @minor) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/log.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/log.rb new file mode 100644 index 0000000..4de4bee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/log.rb @@ -0,0 +1,156 @@ +# frozen_string_literal: true +#-- +# log.rb -- Log Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: log.rb,v 1.26 2002/10/06 17:06:10 gotoyuzo Exp $ + +module WEBrick + + ## + # A generic logging class + + class BasicLog + + # Fatal log level which indicates a server crash + + FATAL = 1 + + # Error log level which indicates a recoverable error + + ERROR = 2 + + # Warning log level which indicates a possible problem + + WARN = 3 + + # Information log level which indicates possibly useful information + + INFO = 4 + + # Debugging error level for messages used in server development or + # debugging + + DEBUG = 5 + + # log-level, messages above this level will be logged + attr_accessor :level + + ## + # Initializes a new logger for +log_file+ that outputs messages at +level+ + # or higher. +log_file+ can be a filename, an IO-like object that + # responds to #<< or nil which outputs to $stderr. + # + # If no level is given INFO is chosen by default + + def initialize(log_file=nil, level=nil) + @level = level || INFO + case log_file + when String + @log = File.open(log_file, "a+") + @log.sync = true + @opened = true + when NilClass + @log = $stderr + else + @log = log_file # requires "<<". (see BasicLog#log) + end + end + + ## + # Closes the logger (also closes the log device associated to the logger) + def close + @log.close if @opened + @log = nil + end + + ## + # Logs +data+ at +level+ if the given level is above the current log + # level. + + def log(level, data) + if @log && level <= @level + data += "\n" if /\n\Z/ !~ data + @log << data + end + end + + ## + # Synonym for log(INFO, obj.to_s) + def <<(obj) + log(INFO, obj.to_s) + end + + # Shortcut for logging a FATAL message + def fatal(msg) log(FATAL, "FATAL " + format(msg)); end + # Shortcut for logging an ERROR message + def error(msg) log(ERROR, "ERROR " + format(msg)); end + # Shortcut for logging a WARN message + def warn(msg) log(WARN, "WARN " + format(msg)); end + # Shortcut for logging an INFO message + def info(msg) log(INFO, "INFO " + format(msg)); end + # Shortcut for logging a DEBUG message + def debug(msg) log(DEBUG, "DEBUG " + format(msg)); end + + # Will the logger output FATAL messages? + def fatal?; @level >= FATAL; end + # Will the logger output ERROR messages? + def error?; @level >= ERROR; end + # Will the logger output WARN messages? + def warn?; @level >= WARN; end + # Will the logger output INFO messages? + def info?; @level >= INFO; end + # Will the logger output DEBUG messages? + def debug?; @level >= DEBUG; end + + private + + ## + # Formats +arg+ for the logger + # + # * If +arg+ is an Exception, it will format the error message and + # the back trace. + # * If +arg+ responds to #to_str, it will return it. + # * Otherwise it will return +arg+.inspect. + def format(arg) + if arg.is_a?(Exception) + +"#{arg.class}: #{AccessLog.escape(arg.message)}\n\t" << + arg.backtrace.join("\n\t") << "\n" + elsif arg.respond_to?(:to_str) + AccessLog.escape(arg.to_str) + else + arg.inspect + end + end + end + + ## + # A logging class that prepends a timestamp to each message. + + class Log < BasicLog + # Format of the timestamp which is applied to each logged line. The + # default is "[%Y-%m-%d %H:%M:%S]" + attr_accessor :time_format + + ## + # Same as BasicLog#initialize + # + # You can set the timestamp format through #time_format + def initialize(log_file=nil, level=nil) + super(log_file, level) + @time_format = "[%Y-%m-%d %H:%M:%S]" + end + + ## + # Same as BasicLog#log + def log(level, data) + tmp = Time.now.strftime(@time_format) + tmp << " " << data + super(level, tmp) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/server.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/server.rb new file mode 100644 index 0000000..d268394 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/server.rb @@ -0,0 +1,380 @@ +# frozen_string_literal: true +# +# server.rb -- GenericServer Class +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $ + +require 'socket' +require_relative 'config' +require_relative 'log' + +module WEBrick + + ## + # Server error exception + + class ServerError < StandardError; end + + ## + # Base server class + + class SimpleServer + + ## + # A SimpleServer only yields when you start it + + def SimpleServer.start + yield + end + end + + ## + # A generic module for daemonizing a process + + class Daemon + + ## + # Performs the standard operations for daemonizing a process. Runs a + # block, if given. + + def Daemon.start + Process.daemon + File.umask(0) + yield if block_given? + end + end + + ## + # Base TCP server class. You must subclass GenericServer and provide a #run + # method. + + class GenericServer + + ## + # The server status. One of :Stop, :Running or :Shutdown + + attr_reader :status + + ## + # The server configuration + + attr_reader :config + + ## + # The server logger. This is independent from the HTTP access log. + + attr_reader :logger + + ## + # Tokens control the number of outstanding clients. The + # :MaxClients configuration sets this. + + attr_reader :tokens + + ## + # Sockets listening for connections. + + attr_reader :listeners + + ## + # Creates a new generic server from +config+. The default configuration + # comes from +default+. + + def initialize(config={}, default=Config::General) + @config = default.dup.update(config) + @status = :Stop + @config[:Logger] ||= Log::new + @logger = @config[:Logger] + + @tokens = Thread::SizedQueue.new(@config[:MaxClients]) + @config[:MaxClients].times{ @tokens.push(nil) } + + webrickv = WEBrick::VERSION + rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]" + @logger.info("WEBrick #{webrickv}") + @logger.info("ruby #{rubyv}") + + @listeners = [] + @shutdown_pipe = nil + unless @config[:DoNotListen] + raise ArgumentError, "Port must be an integer" unless @config[:Port].to_s == @config[:Port].to_i.to_s + + @config[:Port] = @config[:Port].to_i + if @config[:Listen] + warn(":Listen option is deprecated; use GenericServer#listen", uplevel: 1) + end + listen(@config[:BindAddress], @config[:Port]) + if @config[:Port] == 0 + @config[:Port] = @listeners[0].addr[1] + end + end + end + + ## + # Retrieves +key+ from the configuration + + def [](key) + @config[key] + end + + ## + # Adds listeners from +address+ and +port+ to the server. See + # WEBrick::Utils::create_listeners for details. + + def listen(address, port) + @listeners += Utils::create_listeners(address, port) + end + + ## + # Starts the server and runs the +block+ for each connection. This method + # does not return until the server is stopped from a signal handler or + # another thread using #stop or #shutdown. + # + # If the block raises a subclass of StandardError the exception is logged + # and ignored. If an IOError or Errno::EBADF exception is raised the + # exception is ignored. If an Exception subclass is raised the exception + # is logged and re-raised which stops the server. + # + # To completely shut down a server call #shutdown from ensure: + # + # server = WEBrick::GenericServer.new + # # or WEBrick::HTTPServer.new + # + # begin + # server.start + # ensure + # server.shutdown + # end + + def start(&block) + raise ServerError, "already started." if @status != :Stop + server_type = @config[:ServerType] || SimpleServer + + setup_shutdown_pipe + + server_type.start{ + @logger.info \ + "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}" + @status = :Running + call_callback(:StartCallback) + + shutdown_pipe = @shutdown_pipe + + thgroup = ThreadGroup.new + begin + while @status == :Running + begin + sp = shutdown_pipe[0] + if svrs = IO.select([sp, *@listeners]) + if svrs[0].include? sp + # swallow shutdown pipe + buf = String.new + nil while String === sp.read_nonblock(8, buf, exception: false) + break + end + svrs[0].each{|svr| + @tokens.pop # blocks while no token is there. + if sock = accept_client(svr) + unless config[:DoNotReverseLookup].nil? + sock.do_not_reverse_lookup = !!config[:DoNotReverseLookup] + end + th = start_thread(sock, &block) + th[:WEBrickThread] = true + thgroup.add(th) + else + @tokens.push(nil) + end + } + end + rescue Errno::EBADF, Errno::ENOTSOCK, IOError => ex + # if the listening socket was closed in GenericServer#shutdown, + # IO::select raise it. + rescue StandardError => ex + msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" + @logger.error msg + rescue Exception => ex + @logger.fatal ex + raise + end + end + ensure + cleanup_shutdown_pipe(shutdown_pipe) + cleanup_listener + @status = :Shutdown + @logger.info "going to shutdown ..." + thgroup.list.each{|th| th.join if th[:WEBrickThread] } + call_callback(:StopCallback) + @logger.info "#{self.class}#start done." + @status = :Stop + end + } + end + + ## + # Stops the server from accepting new connections. + + def stop + if @status == :Running + @status = :Shutdown + end + + alarm_shutdown_pipe {|f| f.write_nonblock("\0")} + end + + ## + # Shuts down the server and all listening sockets. New listeners must be + # provided to restart the server. + + def shutdown + stop + + alarm_shutdown_pipe(&:close) + end + + ## + # You must subclass GenericServer and implement \#run which accepts a TCP + # client socket + + def run(sock) + @logger.fatal "run() must be provided by user." + end + + private + + # :stopdoc: + + ## + # Accepts a TCP client socket from the TCP server socket +svr+ and returns + # the client socket. + + def accept_client(svr) + case sock = svr.to_io.accept_nonblock(exception: false) + when :wait_readable + nil + else + if svr.respond_to?(:start_immediately) + sock = OpenSSL::SSL::SSLSocket.new(sock, ssl_context) + sock.sync_close = true + # we cannot do OpenSSL::SSL::SSLSocket#accept here because + # a slow client can prevent us from accepting connections + # from other clients + end + sock + end + rescue Errno::ECONNRESET, Errno::ECONNABORTED, + Errno::EPROTO, Errno::EINVAL + nil + rescue StandardError => ex + msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" + @logger.error msg + nil + end + + ## + # Starts a server thread for the client socket +sock+ that runs the given + # +block+. + # + # Sets the socket to the :WEBrickSocket thread local variable + # in the thread. + # + # If any errors occur in the block they are logged and handled. + + def start_thread(sock, &block) + Thread.start{ + begin + Thread.current[:WEBrickSocket] = sock + begin + addr = sock.peeraddr + @logger.debug "accept: #{addr[3]}:#{addr[1]}" + rescue SocketError + @logger.debug "accept:
    " + raise + end + if sock.respond_to?(:sync_close=) && @config[:SSLStartImmediately] + WEBrick::Utils.timeout(@config[:RequestTimeout]) do + begin + sock.accept # OpenSSL::SSL::SSLSocket#accept + rescue Errno::ECONNRESET, Errno::ECONNABORTED, + Errno::EPROTO, Errno::EINVAL + Thread.exit + end + end + end + call_callback(:AcceptCallback, sock) + block ? block.call(sock) : run(sock) + rescue Errno::ENOTCONN + @logger.debug "Errno::ENOTCONN raised" + rescue ServerError => ex + msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" + @logger.error msg + rescue Exception => ex + @logger.error ex + ensure + @tokens.push(nil) + Thread.current[:WEBrickSocket] = nil + if addr + @logger.debug "close: #{addr[3]}:#{addr[1]}" + else + @logger.debug "close:
    " + end + sock.close + end + } + end + + ## + # Calls the callback +callback_name+ from the configuration with +args+ + + def call_callback(callback_name, *args) + @config[callback_name]&.call(*args) + end + + def setup_shutdown_pipe + return @shutdown_pipe ||= IO.pipe + end + + def cleanup_shutdown_pipe(shutdown_pipe) + @shutdown_pipe = nil + shutdown_pipe&.each(&:close) + end + + def alarm_shutdown_pipe + _, pipe = @shutdown_pipe # another thread may modify @shutdown_pipe. + if pipe + if !pipe.closed? + begin + yield pipe + rescue IOError # closed by another thread. + end + end + end + end + + def cleanup_listener + @listeners.each{|s| + if @logger.debug? + addr = s.addr + @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})") + end + begin + s.shutdown + rescue Errno::ENOTCONN + # when 'Errno::ENOTCONN: Socket is not connected' on some platforms, + # call #close instead of #shutdown. + # (ignore @config[:ShutdownSocketWithoutClose]) + s.close + else + unless @config[:ShutdownSocketWithoutClose] + s.close + end + end + } + @listeners.clear + end + end # end of GenericServer +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/ssl.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/ssl.rb new file mode 100644 index 0000000..6937f93 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/ssl.rb @@ -0,0 +1,219 @@ +# frozen_string_literal: true +# +# ssl.rb -- SSL/TLS enhancement for GenericServer +# +# Copyright (c) 2003 GOTOU Yuuzou All rights reserved. +# +# $Id$ + +require 'webrick' +require 'openssl' + +module WEBrick + module Config + svrsoft = General[:ServerSoftware] + osslv = ::OpenSSL::OPENSSL_VERSION.split[1] + + ## + # Default SSL server configuration. + # + # WEBrick can automatically create a self-signed certificate if + # :SSLCertName is set. For more information on the various + # SSL options see OpenSSL::SSL::SSLContext. + # + # :ServerSoftware :: + # The server software name used in the Server: header. + # :SSLEnable :: false, + # Enable SSL for this server. Defaults to false. + # :SSLCertificate :: + # The SSL certificate for the server. + # :SSLPrivateKey :: + # The SSL private key for the server certificate. + # :SSLClientCA :: nil, + # Array of certificates that will be sent to the client. + # :SSLExtraChainCert :: nil, + # Array of certificates that will be added to the certificate chain + # :SSLCACertificateFile :: nil, + # Path to a CA certificate file + # :SSLCACertificatePath :: nil, + # Path to a directory containing CA certificates + # :SSLCertificateStore :: nil, + # OpenSSL::X509::Store used for certificate validation of the client + # :SSLTmpDhCallback :: nil, + # Callback invoked when DH parameters are required. + # :SSLVerifyClient :: + # Sets whether the client is verified. This defaults to VERIFY_NONE + # which is typical for an HTTPS server. + # :SSLVerifyDepth :: + # Number of CA certificates to walk when verifying a certificate chain + # :SSLVerifyCallback :: + # Custom certificate verification callback + # :SSLServerNameCallback:: + # Custom servername indication callback + # :SSLTimeout :: + # Maximum session lifetime + # :SSLOptions :: + # Various SSL options + # :SSLCiphers :: + # Ciphers to be used + # :SSLStartImmediately :: + # Immediately start SSL upon connection? Defaults to true + # :SSLCertName :: + # SSL certificate name. Must be set to enable automatic certificate + # creation. + # :SSLCertComment :: + # Comment used during automatic certificate creation. + + SSL = { + :ServerSoftware => "#{svrsoft} OpenSSL/#{osslv}", + :SSLEnable => false, + :SSLCertificate => nil, + :SSLPrivateKey => nil, + :SSLClientCA => nil, + :SSLExtraChainCert => nil, + :SSLCACertificateFile => nil, + :SSLCACertificatePath => nil, + :SSLCertificateStore => nil, + :SSLTmpDhCallback => nil, + :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE, + :SSLVerifyDepth => nil, + :SSLVerifyCallback => nil, # custom verification + :SSLTimeout => nil, + :SSLOptions => nil, + :SSLCiphers => nil, + :SSLStartImmediately => true, + # Must specify if you use auto generated certificate. + :SSLCertName => nil, + :SSLCertComment => "Generated by Ruby/OpenSSL" + } + General.update(SSL) + end + + module Utils + ## + # Creates a self-signed certificate with the given number of +bits+, + # the issuer +cn+ and a +comment+ to be stored in the certificate. + + def create_self_signed_cert(bits, cn, comment) + rsa = if $VERBOSE + OpenSSL::PKey::RSA.new(bits){|p, n| + case p + when 0; $stderr.putc "." # BN_generate_prime + when 1; $stderr.putc "+" # BN_generate_prime + when 2; $stderr.putc "*" # searching good prime, + # n = #of try, + # but also data from BN_generate_prime + when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q, + # but also data from BN_generate_prime + else; $stderr.putc "*" # BN_generate_prime + end + } + else + OpenSSL::PKey::RSA.new(bits) + end + cert = OpenSSL::X509::Certificate.new + cert.version = 2 + cert.serial = 1 + name = (cn.kind_of? String) ? OpenSSL::X509::Name.parse(cn) + : OpenSSL::X509::Name.new(cn) + cert.subject = name + cert.issuer = name + cert.not_before = Time.now + cert.not_after = Time.now + (365*24*60*60) + cert.public_key = rsa.public_key + + ef = OpenSSL::X509::ExtensionFactory.new(nil,cert) + ef.issuer_certificate = cert + cert.extensions = [ + ef.create_extension("basicConstraints","CA:FALSE"), + ef.create_extension("keyUsage", "keyEncipherment, digitalSignature, keyAgreement, dataEncipherment"), + ef.create_extension("subjectKeyIdentifier", "hash"), + ef.create_extension("extendedKeyUsage", "serverAuth"), + ef.create_extension("nsComment", comment), + ] + aki = ef.create_extension("authorityKeyIdentifier", + "keyid:always,issuer:always") + cert.add_extension(aki) + cert.sign(rsa, "SHA256") + + return [ cert, rsa ] + end + module_function :create_self_signed_cert + end + + ## + #-- + # Updates WEBrick::GenericServer with SSL functionality + + class GenericServer + + ## + # SSL context for the server when run in SSL mode + + def ssl_context # :nodoc: + @ssl_context ||= begin + if @config[:SSLEnable] + ssl_context = setup_ssl_context(@config) + @logger.info("\n" + @config[:SSLCertificate].to_text) + ssl_context + end + end + end + + undef listen + + ## + # Updates +listen+ to enable SSL when the SSL configuration is active. + + def listen(address, port) # :nodoc: + listeners = Utils::create_listeners(address, port) + if @config[:SSLEnable] + listeners.collect!{|svr| + ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context) + ssvr.start_immediately = @config[:SSLStartImmediately] + ssvr + } + end + @listeners += listeners + setup_shutdown_pipe + end + + ## + # Sets up an SSL context for +config+ + + def setup_ssl_context(config) # :nodoc: + unless config[:SSLCertificate] + cn = config[:SSLCertName] + comment = config[:SSLCertComment] + cert, key = Utils::create_self_signed_cert(2048, cn, comment) + config[:SSLCertificate] = cert + config[:SSLPrivateKey] = key + end + ctx = OpenSSL::SSL::SSLContext.new + ctx.key = config[:SSLPrivateKey] + ctx.cert = config[:SSLCertificate] + ctx.client_ca = config[:SSLClientCA] + ctx.extra_chain_cert = config[:SSLExtraChainCert] + ctx.ca_file = config[:SSLCACertificateFile] + ctx.ca_path = config[:SSLCACertificatePath] + ctx.cert_store = config[:SSLCertificateStore] + ctx.tmp_dh_callback = config[:SSLTmpDhCallback] + ctx.verify_mode = config[:SSLVerifyClient] + ctx.verify_depth = config[:SSLVerifyDepth] + ctx.verify_callback = config[:SSLVerifyCallback] + ctx.servername_cb = config[:SSLServerNameCallback] || proc { |args| ssl_servername_callback(*args) } + ctx.timeout = config[:SSLTimeout] + ctx.options = config[:SSLOptions] + ctx.ciphers = config[:SSLCiphers] + ctx + end + + ## + # ServerNameIndication callback + + def ssl_servername_callback(sslsocket, hostname = nil) + # default + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/utils.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/utils.rb new file mode 100644 index 0000000..e4902d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/utils.rb @@ -0,0 +1,265 @@ +# frozen_string_literal: true +# +# utils.rb -- Miscellaneous utilities +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou +# Copyright (c) 2002 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: utils.rb,v 1.10 2003/02/16 22:22:54 gotoyuzo Exp $ + +require 'socket' +require 'io/nonblock' +require 'etc' + +module WEBrick + module Utils + ## + # Sets IO operations on +io+ to be non-blocking + def set_non_blocking(io) + io.nonblock = true if io.respond_to?(:nonblock=) + end + module_function :set_non_blocking + + ## + # Sets the close on exec flag for +io+ + def set_close_on_exec(io) + io.close_on_exec = true if io.respond_to?(:close_on_exec=) + end + module_function :set_close_on_exec + + ## + # Changes the process's uid and gid to the ones of +user+ + def su(user) + if pw = Etc.getpwnam(user) + Process::initgroups(user, pw.gid) + Process::Sys::setgid(pw.gid) + Process::Sys::setuid(pw.uid) + else + warn("WEBrick::Utils::su doesn't work on this platform", uplevel: 1) + end + end + module_function :su + + ## + # The server hostname + def getservername + Socket::gethostname + end + module_function :getservername + + ## + # Creates TCP server sockets bound to +address+:+port+ and returns them. + # + # It will create IPV4 and IPV6 sockets on all interfaces. + def create_listeners(address, port) + unless port + raise ArgumentError, "must specify port" + end + sockets = Socket.tcp_server_sockets(address, port) + sockets = sockets.map {|s| + s.autoclose = false + ts = TCPServer.for_fd(s.fileno) + s.close + ts + } + return sockets + end + module_function :create_listeners + + ## + # Characters used to generate random strings + RAND_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "0123456789" + + "abcdefghijklmnopqrstuvwxyz" + + ## + # Generates a random string of length +len+ + def random_string(len) + rand_max = RAND_CHARS.bytesize + ret = +"" + len.times{ ret << RAND_CHARS[rand(rand_max)] } + ret + end + module_function :random_string + + ########### + + require "timeout" + require "singleton" + + ## + # Class used to manage timeout handlers across multiple threads. + # + # Timeout handlers should be managed by using the class methods which are + # synchronized. + # + # id = TimeoutHandler.register(10, Timeout::Error) + # begin + # sleep 20 + # puts 'foo' + # ensure + # TimeoutHandler.cancel(id) + # end + # + # will raise Timeout::Error + # + # id = TimeoutHandler.register(10, Timeout::Error) + # begin + # sleep 5 + # puts 'foo' + # ensure + # TimeoutHandler.cancel(id) + # end + # + # will print 'foo' + # + class TimeoutHandler + include Singleton + + ## + # Mutex used to synchronize access across threads + TimeoutMutex = Thread::Mutex.new # :nodoc: + + ## + # Registers a new timeout handler + # + # +time+:: Timeout in seconds + # +exception+:: Exception to raise when timeout elapsed + def TimeoutHandler.register(seconds, exception) + at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + seconds + instance.register(Thread.current, at, exception) + end + + ## + # Cancels the timeout handler +id+ + def TimeoutHandler.cancel(id) + instance.cancel(Thread.current, id) + end + + def self.terminate + instance.terminate + end + + ## + # Creates a new TimeoutHandler. You should use ::register and ::cancel + # instead of creating the timeout handler directly. + def initialize + TimeoutMutex.synchronize{ + @timeout_info = Hash.new + } + @queue = Thread::Queue.new + @watcher = nil + end + + # :nodoc: + private \ + def watch + to_interrupt = [] + while true + now = Process.clock_gettime(Process::CLOCK_MONOTONIC) + wakeup = nil + to_interrupt.clear + TimeoutMutex.synchronize{ + @timeout_info.each {|thread, ary| + next unless ary + ary.each{|info| + time, exception = *info + if time < now + to_interrupt.push [thread, info.object_id, exception] + elsif !wakeup || time < wakeup + wakeup = time + end + } + } + } + to_interrupt.each {|arg| interrupt(*arg)} + if !wakeup + @queue.pop + elsif (wakeup -= now) > 0 + begin + (th = Thread.start {@queue.pop}).join(wakeup) + ensure + th&.kill&.join + end + end + @queue.clear + end + end + + # :nodoc: + private \ + def watcher + (w = @watcher)&.alive? and return w # usual case + TimeoutMutex.synchronize{ + (w = @watcher)&.alive? and next w # pathological check + @watcher = Thread.start(&method(:watch)) + } + end + + ## + # Interrupts the timeout handler +id+ and raises +exception+ + def interrupt(thread, id, exception) + if cancel(thread, id) && thread.alive? + thread.raise(exception, "execution timeout") + end + end + + ## + # Registers a new timeout handler + # + # +time+:: Timeout in seconds + # +exception+:: Exception to raise when timeout elapsed + def register(thread, time, exception) + info = nil + TimeoutMutex.synchronize{ + (@timeout_info[thread] ||= []) << (info = [time, exception]) + } + @queue.push nil + watcher + return info.object_id + end + + ## + # Cancels the timeout handler +id+ + def cancel(thread, id) + TimeoutMutex.synchronize{ + if ary = @timeout_info[thread] + ary.delete_if{|info| info.object_id == id } + if ary.empty? + @timeout_info.delete(thread) + end + return true + end + return false + } + end + + ## + def terminate + TimeoutMutex.synchronize{ + @timeout_info.clear + @watcher&.kill&.join + } + end + end + + ## + # Executes the passed block and raises +exception+ if execution takes more + # than +seconds+. + # + # If +seconds+ is zero or nil, simply executes the block + def timeout(seconds, exception=Timeout::Error) + return yield if seconds.nil? or seconds.zero? + # raise ThreadError, "timeout within critical session" if Thread.critical + id = TimeoutHandler.register(seconds, exception) + begin + yield(seconds) + ensure + TimeoutHandler.cancel(id) + end + end + module_function :timeout + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/version.rb b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/version.rb new file mode 100644 index 0000000..0debb77 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/lib/webrick/version.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +#-- +# version.rb -- version and release date +# +# Author: IPR -- Internet Programming with Ruby -- writers +# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU +# Copyright (c) 2003 Internet Programming with Ruby writers. All rights +# reserved. +# +# $IPR: version.rb,v 1.74 2003/07/22 19:20:43 gotoyuzo Exp $ + +module WEBrick + + ## + # The WEBrick version + + VERSION = "1.9.2" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/accesslog.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/accesslog.rbs new file mode 100644 index 0000000..ffdb91d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/accesslog.rbs @@ -0,0 +1,24 @@ +module WEBrick + module AccessLog + class AccessLogError < StandardError + end + + CLF_TIME_FORMAT: String + + COMMON_LOG_FORMAT: String + + CLF: String + + REFERER_LOG_FORMAT: String + + AGENT_LOG_FORMAT: String + + COMBINED_LOG_FORMAT: String + + def self?.setup_params: (Hash[Symbol, untyped] config, HTTPRequest req, HTTPResponse res) -> Hash[String, untyped] + + def self?.format: (String format_string, Hash[String, untyped] params) -> String + + def self?.escape: (String data) -> String + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cgi.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cgi.rbs new file mode 100644 index 0000000..582adb7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cgi.rbs @@ -0,0 +1,92 @@ +module WEBrick + class CGI + @options: Array[untyped] + + class CGIError < StandardError + end + + attr_reader config: Hash[Symbol, untyped] + + attr_reader logger: BasicLog + + def initialize: (*untyped args) -> void + + def []: (Symbol key) -> untyped + + interface _Env + def []: (String) -> String? + end + + def start: (?_Env env, ?IO stdin, ?IO stdout) -> void + + def self.setup_header: () -> untyped + + def self.status_line: () -> "" + + def service: (HTTPRequest req, HTTPResponse res) -> void + + class Socket + @config: Hash[Symbol, untyped] + + @env: _Env + + @header_part: StringIO + + @body_part: IO + + @out_port: IO + + @server_addr: String + + @server_name: String? + + @server_port: String? + + @remote_addr: String? + + @remote_host: String? + + @remote_port: (String | 0) + + include Enumerable[String] + + private + + def initialize: (Hash[Symbol, untyped] config, _Env env, IO stdin, IO stdout) -> void + + def request_line: () -> String + + def setup_header: () -> void + + def add_header: (String hdrname, String value) -> void + + def input: () -> (IO | StringIO) + + public + + def peeraddr: () -> [nil, (String | 0), String?, String?] + + def addr: () -> [nil, String?, String?, String] + + def gets: (?String eol, ?Integer? size) -> String? + + def read: (?Integer? size) -> String? + + def each: () { (String) -> void } -> void + + def eof?: () -> bool + + def <<: (_ToS data) -> IO + + def write: (_ToS data) -> Integer + + def cert: () -> OpenSSL::X509::Certificate? + + def peer_cert: () -> OpenSSL::X509::Certificate? + + def peer_cert_chain: () -> Array[OpenSSL::X509::Certificate]? + + def cipher: () -> [String?, String?, String?, String?]? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/compat.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/compat.rbs new file mode 100644 index 0000000..8d5b745 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/compat.rbs @@ -0,0 +1,18 @@ +# +# System call error module used by webrick for cross platform compatibility. +# +# EPROTO:: protocol error +# ECONNRESET:: remote host reset the connection request +# ECONNABORTED:: Client sent TCP reset (RST) before server has accepted the +# connection requested by client. +# +module Errno + class EPROTO < SystemCallError + end + + class ECONNRESET < SystemCallError + end + + class ECONNABORTED < SystemCallError + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/config.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/config.rbs new file mode 100644 index 0000000..be0a6a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/config.rbs @@ -0,0 +1,17 @@ +module WEBrick + module Config + LIBDIR: String + + # for GenericServer + General: Hash[Symbol, untyped] + + # for HTTPServer, HTTPRequest, HTTPResponse ... + HTTP: Hash[Symbol, untyped] + + FileHandler: Hash[Symbol, untyped] + + BasicAuth: Hash[Symbol, untyped] + + DigestAuth: Hash[Symbol, untyped] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cookie.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cookie.rbs new file mode 100644 index 0000000..6a7dc10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/cookie.rbs @@ -0,0 +1,37 @@ +module WEBrick + class Cookie + @expires: String? + + attr_reader name: String? + + attr_accessor value: String? + + attr_accessor version: Integer + + # + # The cookie domain + attr_accessor domain: String? + + attr_accessor path: String? + + attr_accessor secure: true? + + attr_accessor comment: String? + + attr_accessor max_age: Integer? + + def initialize: (untyped name, untyped value) -> void + + def expires=: ((Time | _ToS)? t) -> untyped + + def expires: () -> Time? + + def to_s: () -> String + + def self.parse: (String? str) -> Array[instance]? + + def self.parse_set_cookie: (String str) -> instance + + def self.parse_set_cookies: (String str) -> Array[instance] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/htmlutils.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/htmlutils.rbs new file mode 100644 index 0000000..00331b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/htmlutils.rbs @@ -0,0 +1,5 @@ +module WEBrick + module HTMLUtils + def self?.escape: (String? string) -> String + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth.rbs new file mode 100644 index 0000000..90f2977 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth.rbs @@ -0,0 +1,13 @@ +module WEBrick + module HTTPAuth + interface _Callable + def call: (String user, String pass) -> bool + end + + def self?._basic_auth: (HTTPRequest req, HTTPResponse res, String realm, String req_field, String res_field, HTTPStatus::Error err_type, _Callable block) -> void + + def self?.basic_auth: (HTTPRequest req, HTTPResponse res, String realm) { (String user, String pass) -> bool } -> void + + def self?.proxy_basic_auth: (HTTPRequest req, HTTPResponse res, String realm) { (String user, String pass) -> bool } -> void + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/authenticator.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/authenticator.rbs new file mode 100644 index 0000000..fe94762 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/authenticator.rbs @@ -0,0 +1,55 @@ +module WEBrick + module HTTPAuth + module Authenticator + @reload_db: bool? + + @request_field: String + + @response_field: String + + @resp_info_field: String + + @auth_exception: singleton(HTTPStatus::ClientError) + + @auth_scheme: String + + RequestField: String + + ResponseField: String + + ResponseInfoField: String + + AuthException: singleton(HTTPStatus::ClientError) + + AuthScheme: String? + + attr_reader realm: String? + + attr_reader userdb: UserDB + + attr_reader logger: Log + + private + + def check_init: (Hash[Symbol, untyped] config) -> void + + def check_scheme: (HTTPRequest req) -> String? + + def log: (interned meth, String fmt, *untyped args) -> void + + def error: (String fmt, *untyped args) -> void + + def info: (String fmt, *untyped args) -> void + end + + module ProxyAuthenticator + RequestField: String + + ResponseField: String + + ResponseInfoField: String + + AuthException: singleton(HTTPStatus::ClientError) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/basicauth.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/basicauth.rbs new file mode 100644 index 0000000..4eb41df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/basicauth.rbs @@ -0,0 +1,29 @@ +module WEBrick + module HTTPAuth + class BasicAuth + @config: Hash[Symbol, untyped] + + include Authenticator + + AuthScheme: String + + def self.make_passwd: (String? realm, String? user, String? pass) -> String + + attr_reader realm: String? + + attr_reader userdb: UserDB + + attr_reader logger: Log + + def initialize: (Hash[Symbol, untyped] config, ?Hash[Symbol, untyped] default) -> void + + def authenticate: (HTTPRequest req, HTTPResponse res) -> void + + def challenge: (HTTPRequest req, HTTPResponse res) -> bot + end + + class ProxyBasicAuth < BasicAuth + include ProxyAuthenticator + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/digestauth.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/digestauth.rbs new file mode 100644 index 0000000..8d12f91 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/digestauth.rbs @@ -0,0 +1,85 @@ +module WEBrick + module HTTPAuth + class DigestAuth + @config: Hash[Symbol, untyped] + + @domain: Array[String]? + + @use_opaque: bool + + @use_next_nonce: bool + + @check_nc: bool + + @use_auth_info_header: bool + + @nonce_expire_period: Integer + + @nonce_expire_delta: Integer + + @internet_explorer_hack: bool + + @h: singleton(Digest::Base) + + @instance_key: String + + @opaques: Hash[String, OpaqueInfo] + + @last_nonce_expire: Time + + @mutex: Thread::Mutex + + include Authenticator + + AuthScheme: String + + class OpaqueInfo < Struct[untyped] + attr_accessor time(): Time + attr_accessor nonce(): String? + attr_accessor nc(): String + end + + attr_reader algorithm: String? + + attr_reader qop: Array[String] + + def self.make_passwd: (String realm, String user, String pass) -> untyped + + def initialize: (Hash[Symbol, untyped] config, ?Hash[Symbol, untyped] default) -> void + + def authenticate: (HTTPRequest req, HTTPResponse res) -> void + + def challenge: (HTTPRequest req, HTTPResponse res, ?bool stale) -> bot + + private + + MustParams: Array[String] + + MustParamsAuth: Array[String] + + def _authenticate: (HTTPRequest req, HTTPResponse res) -> (:nonce_is_stale | bool) + + def split_param_value: (String string) -> Hash[String, String] + + def generate_next_nonce: (HTTPRequest req) -> String + + def check_nonce: (HTTPRequest req, Hash[String, String] auth_req) -> bool + + def generate_opaque: (HTTPRequest req) -> String + + def check_opaque: (OpaqueInfo opaque_struct, untyped req, Hash[String, String] auth_req) -> bool + + def check_uri: (HTTPRequest req, Hash[String, String] auth_req) -> bool + + def hexdigest: (*_ToS? args) -> String + end + + class ProxyDigestAuth < DigestAuth + include ProxyAuthenticator + + private + + def check_uri: (HTTPRequest req, Hash[String, String] auth_req) -> true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htdigest.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htdigest.rbs new file mode 100644 index 0000000..19037e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htdigest.rbs @@ -0,0 +1,31 @@ +module WEBrick + module HTTPAuth + class Htdigest + @path: String + + @mtime: Time + + @digest: Hash[String, Hash[String, String]] + + @mutex: Thread::Mutex + + @auth_type: String + + include UserDB + + def initialize: (String path) -> void + + def reload: () -> void + + def flush: (?String? output) -> void + + def get_passwd: (String realm, String user, bool reload_db) -> String? + + def set_passwd: (String realm, String user, String pass) -> String + + def delete_passwd: (String realm, String user) -> String? + + def each: () { (String user, String realm, String password_hash) -> void } -> void + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htgroup.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htgroup.rbs new file mode 100644 index 0000000..00ca7a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htgroup.rbs @@ -0,0 +1,21 @@ +module WEBrick + module HTTPAuth + class Htgroup + @path: String + + @mtime: Time + + @group: Hash[String, Array[String]] + + def initialize: (String path) -> void + + def reload: () -> void + + def flush: (?String? output) -> void + + def members: (String group) -> Array[String] + + def add: (String group, Array[String] members) -> void + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htpasswd.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htpasswd.rbs new file mode 100644 index 0000000..6b4cc3e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/htpasswd.rbs @@ -0,0 +1,31 @@ +module WEBrick + module HTTPAuth + class Htpasswd + @path: String + + @mtime: Time + + @passwd: Hash[String, String] + + @auth_type: String + + @password_hash: (:crypt | :bcrypt) + + include UserDB + + def initialize: (String path, ?password_hash: (:crypt | :bcrypt)?) -> void + + def reload: () -> void + + def flush: (?String? output) -> void + + def get_passwd: (String realm, String user, bool reload_db) -> String? + + def set_passwd: (String realm, String user, String pass) -> void + + def delete_passwd: (String realm, String user) -> String + + def each: () { ([String, String]) -> void } -> void + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/userdb.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/userdb.rbs new file mode 100644 index 0000000..a6aefd9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpauth/userdb.rbs @@ -0,0 +1,13 @@ +module WEBrick + module HTTPAuth + module UserDB + attr_accessor auth_type: String + + def make_passwd: (String realm, String user, String pass) -> String + + def set_passwd: (String realm, String user, String pass) -> void + + def get_passwd: (String realm, String user, ?bool reload_db) -> String + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpproxy.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpproxy.rbs new file mode 100644 index 0000000..c2bc26b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpproxy.rbs @@ -0,0 +1,61 @@ +module WEBrick + NullReader: untyped + + def self.read: (*untyped args) -> nil + + alias self.gets self.read + + FakeProxyURI: untyped + + def self.method_missing: (untyped meth, *untyped args) -> (nil | untyped) + + class HTTPProxyServer < HTTPServer + @via: untyped + + def initialize: (?::Hash[untyped, untyped] config, ?untyped default) -> void + + # :stopdoc: + def service: (HTTPRequest req, HTTPResponse res) -> untyped + + def proxy_auth: (HTTPRequest req, HTTPResponse res) -> untyped + + def proxy_uri: (HTTPRequest req, HTTPResponse res) -> untyped + + def proxy_service: (HTTPRequest req, HTTPResponse res) -> untyped + + def do_CONNECT: (HTTPRequest req, HTTPResponse res) -> untyped + + def do_GET: (HTTPRequest req, HTTPResponse res) -> untyped + + def do_HEAD: (HTTPRequest req, HTTPResponse res) -> untyped + + def do_POST: (HTTPRequest req, HTTPResponse res) -> untyped + + def do_OPTIONS: (HTTPRequest req, HTTPResponse res) -> untyped + + private + + # Some header fields should not be transferred. + HopByHop: ::Array["connection" | "keep-alive" | "proxy-authenticate" | "upgrade" | "proxy-authorization" | "te" | "trailers" | "transfer-encoding"] + + ShouldNotTransfer: ::Array["set-cookie" | "proxy-connection"] + + def split_field: (untyped f) -> (untyped | ::Array[untyped]) + + def choose_header: (untyped src, untyped dst) -> untyped + + # Net::HTTP is stupid about the multiple header fields. + # Here is workaround: + def set_cookie: (untyped src, untyped dst) -> (untyped | nil) + + def set_via: (untyped h) -> (untyped | nil) + + def setup_proxy_header: (HTTPRequest req, HTTPResponse res) -> untyped + + def setup_upstream_proxy_authentication: (HTTPRequest req, HTTPResponse res, untyped header) -> untyped + + def create_net_http: (untyped uri, untyped upstream) -> untyped + + def perform_proxy_request: (HTTPRequest req, HTTPResponse res, untyped req_class, ?untyped? body_stream) -> untyped + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httprequest.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httprequest.rbs new file mode 100644 index 0000000..82c229e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httprequest.rbs @@ -0,0 +1,167 @@ +module WEBrick + class HTTPRequest + @config: Hash[Symbol, untyped] + + @buffer_size: Integer + + @logger: Log + + @query: Hash[String, HTTPUtils::FormData]? + + @body: String + + @remaining_size: Integer? + + @socket: TCPSocket? + + @forwarded_proto: String? + + @host: String? + + @port: Integer? + + @body_tmp: Array[String] + + @body_rd: Fiber + + @request_bytes: Integer + + @forwarded_server: String? + + @forwarded_host: String? + + @forwarded_port: Integer? + + @forwarded_for: String? + + BODY_CONTAINABLE_METHODS: Array[String] + + attr_reader request_line: String? + + attr_reader request_method: String? + + attr_reader unparsed_uri: String? + + attr_reader http_version: HTTPVersion? + + attr_reader request_uri: URI::Generic? + + attr_reader path: String? + + attr_accessor script_name: String? + + attr_accessor path_info: String? + + attr_accessor query_string: String? + + attr_reader raw_header: Array[String] + + attr_reader header: Hash[String, Array[String]]? + + attr_reader cookies: Array[Cookie] + + attr_reader accept: Array[String] + + attr_reader accept_charset: Array[String] + + attr_reader accept_encoding: Array[String] + + attr_reader accept_language: Array[String] + + attr_accessor user: String? + + attr_reader addr: ([String, Integer, String, String] | []) + + attr_reader peeraddr: ([String, Integer, String, String] | []) + + attr_reader attributes: Hash[untyped, untyped] + + attr_reader keep_alive: bool + + attr_reader request_time: Time? + + def initialize: (Hash[Symbol, untyped] config) -> void + + def parse: (?TCPSocket? socket) -> void + + def continue: () -> void + + type body_chunk_block = ^(String body_chunk) -> void + + def body: () ?{ (String body_chunk) -> void } -> String + + def body_reader: () -> self + + # for IO.copy_stream. + def readpartial: (Integer size, ?String buf) -> String + + def query: () -> Hash[String, HTTPUtils::FormData] + + def content_length: () -> Integer + + def content_type: () -> String? + + def []: (String header_name) -> String? + + def each: [T] () { (String, String) -> T } -> T? + + def host: () -> String? + + def port: () -> Integer? + + def server_name: () -> String? + + def remote_ip: () -> String? + + def ssl?: () -> bool + + def keep_alive?: () -> bool + + def to_s: () -> String + + def fixup: () -> void + + def meta_vars: () -> Hash[String, String] + + private + + MAX_URI_LENGTH: Integer + + # same as Mongrel, Thin and Puma + MAX_HEADER_LENGTH: Integer + + def read_request_line: (IO socket) -> void + + def read_header: (IO socket) -> void + + def parse_uri: (String str, ?String scheme) -> URI::Generic + + HOST_PATTERN: Regexp + + def parse_host_request_line: (String host) -> [String, String] + + def read_body: (IO socket, body_chunk_block block) -> String + | (nil socket, top block) -> nil + + def read_chunk_size: (IO socket) -> [Integer, String?] + + def read_chunked: (IO socket, body_chunk_block block) -> void + + def _read_data: (IO io, Symbol method, *untyped arg) -> String? + + def read_line: (IO io, ?Integer size) -> String? + + def read_data: (IO io, Integer size) -> String? + + def parse_query: () -> void + + PrivateNetworkRegexp: Regexp + + # It's said that all X-Forwarded-* headers will contain more than one + # (comma-separated) value if the original request already contained one of + # these headers. Since we could use these values as Host header, we choose + # the initial(first) value. (apr_table_mergen() adds new value after the + # existing value with ", " prefix) + def setup_forwarded_info: () -> void + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpresponse.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpresponse.rbs new file mode 100644 index 0000000..2baf093 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpresponse.rbs @@ -0,0 +1,117 @@ +module WEBrick + class HTTPResponse + @buffer_size: Integer + + @logger: Log + + @chunked: bool + + @bodytempfile: File | Tempfile | nil + + class InvalidHeader < StandardError + end + + attr_reader http_version: HTTPVersion + + attr_reader status: Integer + + attr_reader header: Hash[String, String] + + attr_reader cookies: Array[Cookie] + + attr_accessor reason_phrase: String + + interface _CallableBody + def call: (_Writer) -> void + end + + attr_accessor body: String | _ReaderPartial | _CallableBody + + attr_accessor request_method: String? + + attr_accessor request_uri: URI::Generic? + + attr_accessor request_http_version: HTTPVersion? + + attr_accessor filename: String? + + attr_accessor keep_alive: bool + + attr_reader config: Hash[Symbol, untyped] + + attr_reader sent_size: Integer + + attr_accessor upgrade: String? + + def initialize: (Hash[Symbol, untyped] config) -> void + + def status_line: () -> String + + def status=: (Integer status) -> Integer + + def []: (String field) -> String? + + def []=: (String field, _ToS value) -> _ToS + + def content_length: () -> Integer? + + def content_length=: (Integer len) -> Integer + + def content_type: () -> String? + + def content_type=: (String type) -> String + + def each: () { (String, String) -> void } -> void + + def chunked?: () -> bool + + def chunked=: (boolish val) -> boolish + + def keep_alive?: () -> bool + + def upgrade!: (String protocol) -> void + + def send_response: (_Writer socket) -> void + + def setup_header: () -> void + + def make_body_tempfile: () -> void + + def remove_body_tempfile: () -> void + + def send_header: (_Writer socket) -> void + + def send_body: (_Writer socket) -> void + + def set_redirect: (singleton(WEBrick::HTTPStatus::Redirect) status, URI::Generic | String url) -> bot + + def set_error: (singleton(Exception) ex, ?bool backtrace) -> void + + private + + def check_header: (_ToS header_value) -> String + + def error_body: (bool backtrace, singleton(Exception) ex, String? host, Integer? port) -> void + + def send_body_io: (_Writer socket) -> void + + def send_body_string: (_Writer socket) -> void + + def send_body_proc: (_Writer socket) -> void + + class ChunkedWrapper + @socket: _Writer + + @resp: HTTPResponse + + def initialize: (_Writer socket, HTTPResponse resp) -> void + + def write: (_ToS buf) -> Integer + + def <<: (*_ToS buf) -> self + end + + # preserved for compatibility with some 3rd-party handlers + def _write_data: [T] (T socket, _ToS data) -> T + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/https.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/https.rbs new file mode 100644 index 0000000..43dcd1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/https.rbs @@ -0,0 +1,49 @@ +module WEBrick + class HTTPRequest + @client_cert_chain: Array[OpenSSL::X509::Certificate] + + attr_reader cipher: [String, String, Integer, Integer]? + + attr_reader server_cert: OpenSSL::X509::Certificate + + attr_reader client_cert: OpenSSL::X509::Certificate? + + alias orig_parse parse + + def parse: (?(TCPSocket | OpenSSL::SSL::SSLSocket)? socket) -> void + | ... + + alias orig_parse_uri parse_uri + + private + + def parse_uri: (String str, ?::String scheme) -> URI::Generic + | ... + + public + + alias orig_meta_vars meta_vars + + def meta_vars: () -> Hash[String, String] + | ... + end + + class SNIRequest + attr_reader host: String? + + attr_reader addr: [String, Integer, String, String] + + attr_reader port: Integer + + def initialize: (OpenSSL::SSL::SSLSocket sslsocket, ?String? hostname) -> void + end + + class HTTPServer < ::WEBrick::GenericServer + def ssl_servername_callback: (OpenSSL::SSL::SSLSocket sslsocket, ?String? hostname) -> OpenSSL::SSL::SSLContext? + + alias orig_virtual_host virtual_host + + def virtual_host: (instance server) -> void + | ... + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpserver.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpserver.rbs new file mode 100644 index 0000000..6c966e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpserver.rbs @@ -0,0 +1,71 @@ +module WEBrick + class HTTPServerError < ServerError + end + + class HTTPServer < ::WEBrick::GenericServer + @http_version: HTTPVersion + + @mount_tab: MountTable + + @virtual_hosts: Array[untyped] + + def initialize: (?Hash[Symbol, untyped] config, ?Hash[Symbol, untyped] default) -> void + + def run: (TCPSocket sock) -> void + + def service: (HTTPRequest req, HTTPResponse res) -> void + + def do_OPTIONS: (HTTPRequest req, HTTPResponse res) -> void + + def mount: (String dir, singleton(HTTPServlet::AbstractServlet) servlet, *untyped options) -> void + + def mount_proc: (String dir, ?HTTPServlet::ProcHandler::_Callable proc) -> void + | (String dir, ?nil proc) { (HTTPRequest, HTTPResponse) -> void } -> void + + def unmount: (String dir) -> MountTable::value_type + + alias umount unmount + + def search_servlet: (String path) -> [singleton(HTTPServlet::AbstractServlet), Array[untyped], String, String]? + + def virtual_host: (instance server) -> void + + def lookup_server: (HTTPRequest req) -> instance? + + def access_log: (Hash[Symbol, untyped] config, HTTPRequest req, HTTPResponse res) -> void + + # + # Creates the HTTPRequest used when handling the HTTP + # request. Can be overridden by subclasses. + def create_request: (Hash[Symbol, untyped] with_webrick_config) -> HTTPRequest + + # + # Creates the HTTPResponse used when handling the HTTP + # request. Can be overridden by subclasses. + def create_response: (Hash[Symbol, untyped] with_webrick_config) -> HTTPResponse + + class MountTable + type value_type = [singleton(HTTPServlet::AbstractServlet), Array[untyped]] + + @tab: Hash[String, value_type] + + @scanner: Regexp + + def initialize: () -> void + + def []: (String dir) -> value_type + + def []=: (String dir, value_type val) -> value_type + + def delete: (String dir) -> value_type + + def scan: (String path) -> [String, String] + + private + + def compile: () -> void + + def normalize: (String dir) -> String + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet.rbs new file mode 100644 index 0000000..36122e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet.rbs @@ -0,0 +1,4 @@ +module WEBrick + module HTTPServlet + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/abstract.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/abstract.rbs new file mode 100644 index 0000000..b067deb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/abstract.rbs @@ -0,0 +1,36 @@ +module WEBrick + module HTTPServlet + class HTTPServletError < StandardError + end + + class AbstractServlet + @server: HTTPServer + + interface _Config + def []: (Symbol) -> untyped + end + + @config: _Config + + @logger: Log + + @options: untyped # Array[untyped] causes RBS::InstanceVariableTypeError + + def self.get_instance: (HTTPServer server, *untyped options) -> instance + + def initialize: (HTTPServer server, *untyped options) -> void + + def service: (HTTPRequest req, HTTPResponse res) -> void + + def do_GET: (HTTPRequest req, HTTPResponse res) -> bot + + def do_HEAD: (HTTPRequest req, HTTPResponse res) -> bot + + def do_OPTIONS: (HTTPRequest req, HTTPResponse res) -> void + + private + + def redirect_to_directory_uri: (HTTPRequest req, HTTPResponse res) -> void + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgi_runner.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgi_runner.rbs new file mode 100644 index 0000000..3112976 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgi_runner.rbs @@ -0,0 +1,3 @@ +class Object + def sysread: (IO io, Integer size) -> String +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgihandler.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgihandler.rbs new file mode 100644 index 0000000..f56427c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/cgihandler.rbs @@ -0,0 +1,23 @@ +module WEBrick + module HTTPServlet + class CGIHandler < AbstractServlet + @script_filename: String + + @tempdir: String? + + @cgicmd: Array[String] | String + + Ruby: String + + CGIRunner: String + + CGIRunnerArray: [String, String] + + def initialize: (HTTPServer server, String name) -> void + + def do_GET: (HTTPRequest req, HTTPResponse res) -> void + + alias do_POST do_GET + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/erbhandler.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/erbhandler.rbs new file mode 100644 index 0000000..9ffa569 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/erbhandler.rbs @@ -0,0 +1,17 @@ +module WEBrick + module HTTPServlet + class ERBHandler < AbstractServlet + @script_filename: String + + def initialize: (HTTPServer server, String name) -> void + + def do_GET: (HTTPRequest req, HTTPResponse res) -> void + + alias do_POST do_GET + + private + + def evaluate: (ERB erb, HTTPRequest servlet_request, HTTPResponse servlet_response) -> String + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/filehandler.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/filehandler.rbs new file mode 100644 index 0000000..792fd2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/filehandler.rbs @@ -0,0 +1,76 @@ +module WEBrick + module HTTPServlet + class DefaultFileHandler < AbstractServlet + @local_path: String + + def initialize: (HTTPServer server, String local_path) -> void + + def do_GET: (HTTPRequest req, HTTPResponse res) -> void + + def not_modified?: (HTTPRequest req, HTTPResponse res, Time mtime, String etag) -> bool + + # returns a lambda for webrick/httpresponse.rb send_body_proc + def multipart_body: (File body, Array[[Numeric, Numeric]] parts, String boundary, String mtype, Integer filesize) -> HTTPResponse::_CallableBody + + def make_partial_content: (HTTPRequest req, HTTPResponse res, String filename, Integer filesize) -> void + + def prepare_range: (Range[Integer] range, Integer filesize) -> [Numeric, Numeric] + end + + class FileHandler < AbstractServlet + @config: AbstractServlet::_Config + + @logger: Log + + @root: String + + @options: Hash[Symbol, untyped] + + HandlerTable: Hash[String, singleton(AbstractServlet)] + + def self.add_handler: (String suffix, singleton(AbstractServlet) handler) -> singleton(AbstractServlet) + + def self.remove_handler: (String suffix) -> singleton(AbstractServlet) + + def initialize: (HTTPServer server, String root, ?Hash[Symbol, untyped] options, ?Hash[Symbol, untyped] default) -> void + + def set_filesystem_encoding: (String str) -> String + + def service: (HTTPRequest req, HTTPResponse res) -> void + + def do_GET: (HTTPRequest req, HTTPResponse res) -> void + + def do_POST: (HTTPRequest req, HTTPResponse res) -> void + + def do_OPTIONS: (HTTPRequest req, HTTPResponse res) -> void + + private + + def trailing_pathsep?: (String path) -> bool + + def prevent_directory_traversal: (HTTPRequest req, HTTPResponse res) -> void + + def exec_handler: (HTTPRequest req, HTTPResponse res) -> bool + + def get_handler: (HTTPRequest req, HTTPResponse res) -> singleton(AbstractServlet) + + def set_filename: (HTTPRequest req, HTTPResponse res) -> bool + + def check_filename: (HTTPRequest req, HTTPResponse res, String name) -> void + + def shift_path_info: (HTTPRequest req, HTTPResponse res, String path_info, ?String? base) -> void + + def search_index_file: (HTTPRequest req, HTTPResponse res) -> String? + + def search_file: (HTTPRequest req, HTTPResponse res, String basename) -> String? + + def call_callback: (Symbol callback_name, HTTPRequest req, HTTPResponse res) -> void + + def windows_ambiguous_name?: (String name) -> bool + + def nondisclosure_name?: (String name) -> bool + + def set_dir_list: (HTTPRequest req, HTTPResponse res) -> void + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/prochandler.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/prochandler.rbs new file mode 100644 index 0000000..66f6929 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpservlet/prochandler.rbs @@ -0,0 +1,21 @@ +module WEBrick + module HTTPServlet + class ProcHandler < AbstractServlet + interface _Callable + def call: (WEBrick::HTTPRequest, WEBrick::HTTPResponse) -> void + end + + @proc: _Callable + + def get_instance: (HTTPServer server, *untyped options) -> self + + def initialize: (_Callable proc) -> void + + def do_GET: (HTTPRequest request, HTTPResponse response) -> void + + alias do_POST do_GET + + alias do_PUT do_GET + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpstatus.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpstatus.rbs new file mode 100644 index 0000000..0b83ada --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpstatus.rbs @@ -0,0 +1,255 @@ +module WEBrick + # + # This module is used to manager HTTP status codes. + # + # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for more + # information. + module HTTPStatus + # + # Root of the HTTP status class hierarchy + class Status < StandardError + attr_reader self.code: Integer + + attr_reader self.reason_phrase: String + + # Returns the HTTP status code + def code: () -> Integer + + # Returns the HTTP status description + def reason_phrase: () -> String + + alias to_i code + end + + # Root of the HTTP info statuses + class Info < Status + end + + # Root of the HTTP success statuses + class Success < Status + end + + # Root of the HTTP redirect statuses + class Redirect < Status + end + + # Root of the HTTP error statuses + class Error < Status + end + + # Root of the HTTP client error statuses + class ClientError < Error + end + + # Root of the HTTP server error statuses + class ServerError < Error + end + + class EOFError < StandardError + end + + # HTTP status codes and descriptions + StatusMessage: Hash[Integer, String] + + # Maps a status code to the corresponding Status class + CodeToError: Hash[Integer, singleton(Status)] + + # WEBrick::HTTPStatus::constants.grep(/\ARC_/).map{"#{_1}: #{WEBrick::HTTPStatus.const_get(_1)}"} + + RC_CONTINUE: 100 + RC_SWITCHING_PROTOCOLS: 101 + RC_OK: 200 + RC_CREATED: 201 + RC_ACCEPTED: 202 + RC_NON_AUTHORITATIVE_INFORMATION: 203 + RC_NO_CONTENT: 204 + RC_RESET_CONTENT: 205 + RC_PARTIAL_CONTENT: 206 + RC_MULTI_STATUS: 207 + RC_MULTIPLE_CHOICES: 300 + RC_MOVED_PERMANENTLY: 301 + RC_FOUND: 302 + RC_SEE_OTHER: 303 + RC_NOT_MODIFIED: 304 + RC_USE_PROXY: 305 + RC_TEMPORARY_REDIRECT: 307 + RC_BAD_REQUEST: 400 + RC_UNAUTHORIZED: 401 + RC_PAYMENT_REQUIRED: 402 + RC_FORBIDDEN: 403 + RC_NOT_FOUND: 404 + RC_METHOD_NOT_ALLOWED: 405 + RC_NOT_ACCEPTABLE: 406 + RC_PROXY_AUTHENTICATION_REQUIRED: 407 + RC_REQUEST_TIMEOUT: 408 + RC_CONFLICT: 409 + RC_GONE: 410 + RC_PRECONDITION_FAILED: 412 + RC_LENGTH_REQUIRED: 411 + RC_REQUEST_ENTITY_TOO_LARGE: 413 + RC_REQUEST_URI_TOO_LARGE: 414 + RC_UNSUPPORTED_MEDIA_TYPE: 415 + RC_EXPECTATION_FAILED: 417 + RC_UNPROCESSABLE_ENTITY: 422 + RC_LOCKED: 423 + RC_FAILED_DEPENDENCY: 424 + RC_REQUEST_RANGE_NOT_SATISFIABLE: 416 + RC_UPGRADE_REQUIRED: 426 + RC_PRECONDITION_REQUIRED: 428 + RC_TOO_MANY_REQUESTS: 429 + RC_REQUEST_HEADER_FIELDS_TOO_LARGE: 431 + RC_UNAVAILABLE_FOR_LEGAL_REASONS: 451 + RC_INTERNAL_SERVER_ERROR: 500 + RC_NOT_IMPLEMENTED: 501 + RC_BAD_GATEWAY: 502 + RC_SERVICE_UNAVAILABLE: 503 + RC_GATEWAY_TIMEOUT: 504 + RC_HTTP_VERSION_NOT_SUPPORTED: 505 + RC_INSUFFICIENT_STORAGE: 507 + RC_NETWORK_AUTHENTICATION_REQUIRED: 511 + + # WEBrick::HTTPStatus::CodeToError.each_value.map{"class #{_1.name.split(/::/).last} < #{_1.superclass.name.split(/::/).last}\nend"} + + class Continue < Info + end + class SwitchingProtocols < Info + end + class OK < Success + end + class Created < Success + end + class Accepted < Success + end + class NonAuthoritativeInformation < Success + end + class NoContent < Success + end + class ResetContent < Success + end + class PartialContent < Success + end + class MultiStatus < Success + end + class MultipleChoices < Redirect + end + class MovedPermanently < Redirect + end + class Found < Redirect + end + class SeeOther < Redirect + end + class NotModified < Redirect + end + class UseProxy < Redirect + end + class TemporaryRedirect < Redirect + end + class BadRequest < ClientError + end + class Unauthorized < ClientError + end + class PaymentRequired < ClientError + end + class Forbidden < ClientError + end + class NotFound < ClientError + end + class MethodNotAllowed < ClientError + end + class NotAcceptable < ClientError + end + class ProxyAuthenticationRequired < ClientError + end + class RequestTimeout < ClientError + end + class Conflict < ClientError + end + class Gone < ClientError + end + class LengthRequired < ClientError + end + class PreconditionFailed < ClientError + end + class RequestEntityTooLarge < ClientError + end + class RequestURITooLarge < ClientError + end + class UnsupportedMediaType < ClientError + end + class RequestRangeNotSatisfiable < ClientError + end + class ExpectationFailed < ClientError + end + class UnprocessableEntity < ClientError + end + class Locked < ClientError + end + class FailedDependency < ClientError + end + class UpgradeRequired < ClientError + end + class PreconditionRequired < ClientError + end + class TooManyRequests < ClientError + end + class RequestHeaderFieldsTooLarge < ClientError + end + class UnavailableForLegalReasons < ClientError + end + class InternalServerError < ServerError + end + class NotImplemented < ServerError + end + class BadGateway < ServerError + end + class ServiceUnavailable < ServerError + end + class GatewayTimeout < ServerError + end + class HTTPVersionNotSupported < ServerError + end + class InsufficientStorage < ServerError + end + class NetworkAuthenticationRequired < ServerError + end + + # + # Returns the description corresponding to the HTTP status +code+ + # + # WEBrick::HTTPStatus.reason_phrase 404 + # => "Not Found" + def self?.reason_phrase: (Integer code) -> String + + # + # Is +code+ an informational status? + def self?.info?: (Integer code) -> bool + + # + # Is +code+ a successful status? + def self?.success?: (Integer code) -> bool + + # + # Is +code+ a redirection status? + def self?.redirect?: (Integer code) -> bool + + # + # Is +code+ an error status? + def self?.error?: (Integer code) -> bool + + # + # Is +code+ a client error status? + def self?.client_error?: (Integer code) -> bool + + # + # Is +code+ a server error status? + def self?.server_error?: (Integer code) -> bool + + # + # Returns the status class corresponding to +code+ + # + # WEBrick::HTTPStatus[302] + # => WEBrick::HTTPStatus::NotFound + # + def self.[]: (Integer code) -> singleton(Status) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httputils.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httputils.rbs new file mode 100644 index 0000000..a554cdf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httputils.rbs @@ -0,0 +1,116 @@ +module WEBrick + CR: String + + LF: String + + CRLF: String + + module HTTPUtils + def self?.normalize_path: (String path) -> String + + type mime_types = Hash[String, String] + + DefaultMimeTypes: mime_types + + def self?.load_mime_types: (string | _ToPath file) -> mime_types + + def self?.mime_type: (String filename, mime_types mime_tab) -> String + + class SplitHeader < Array[String] + def join: (?String separator) -> String + end + + class CookieHeader < Array[String] + def join: (?String separator) -> String + end + + HEADER_CLASSES: Hash[String, untyped] + + def self?.parse_header: (String raw) -> Hash[String, Array[String]] + + def self?.split_header_value: (String str) -> Array[String] + + def self?.parse_range_header: (String? ranges_specifier) -> Array[Range[Integer]]? + + def self?.parse_qvalues: (String? value) -> Array[String] + + def self?.dequote: (String str) -> String + + def self?.quote: (String str) -> String + + class FormData < String + @raw_header: Array[String] + + @header: Hash[String, Array[String]] + + EmptyRawHeader: Array[String] + + EmptyHeader: Hash[String, Array[String]] + + attr_accessor name: String? + + attr_accessor filename: String? + + attr_accessor next_data: instance? + + def initialize: (*String args) -> void + + def []: (*String key) -> String + # following is as same as String#[] + | (int start, ?int length) -> String? + | (range[int?] range) -> String? + | (Regexp regexp, ?MatchData::capture backref) -> String? + | (String substring) -> String? + + def <<: (String str) -> self + + def append_data: (instance data) -> self + + def each_data: () { (instance) -> void } -> void + + def list: () -> Array[String] + + alias to_ary list + + def to_s: () -> String + end + + def self?.parse_query: (String? str) -> Hash[String, FormData] + + interface _EachLine + def each_line: () { (String) -> void } -> void + end + + def self?.parse_form_data: (_EachLine? io, interned boundary) -> Hash[String, FormData] + + def self?._make_regex: (String str) -> Regexp + + def self?._make_regex!: (String str) -> Regexp + + def self?._escape: (String str, Regexp regex) -> String + + def self?._unescape: (String str, Regexp regex) -> String + + UNESCAPED: Regexp + + UNESCAPED_FORM: Regexp + + NONASCII: Regexp + + ESCAPED: Regexp + + UNESCAPED_PCHAR: Regexp + + def self?.escape: (String str) -> String + + def self?.unescape: (String str) -> String + + def self?.escape_form: (String str) -> String + + def self?.unescape_form: (String str) -> String + + def self?.escape_path: (String str) -> String + + def self?.escape8bit: (String str) -> String + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpversion.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpversion.rbs new file mode 100644 index 0000000..92c8940 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/httpversion.rbs @@ -0,0 +1,17 @@ +module WEBrick + class HTTPVersion + include Comparable + + attr_accessor major: Integer + + attr_accessor minor: Integer + + def self.convert: (HTTPVersion | String version) -> instance + + def initialize: (HTTPVersion | String version) -> void + + def <=>: (HTTPVersion | String other) -> Integer? + + def to_s: () -> String + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/log.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/log.rbs new file mode 100644 index 0000000..e985f4a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/log.rbs @@ -0,0 +1,93 @@ +module WEBrick + class BasicLog + @log: IO? + + @opened: TrueClass? + + FATAL: 1 + + ERROR: 2 + + WARN: 3 + + INFO: 4 + + DEBUG: 5 + + # log-level, messages above this level will be logged + attr_accessor level: Integer + + type log_file = (IO | String)? + + def initialize: (?log_file log_file, ?Integer? level) -> void + + # + # Closes the logger (also closes the log device associated to the logger) + def close: () -> void + + def log: (Integer level, String data) -> IO? + + # + # Synonym for log(INFO, obj.to_s) + def <<: (_ToS obj) -> IO? + + type message = Exception | _ToStr | Object + + # Shortcut for logging a FATAL message + def fatal: (message msg) -> IO? + + # Shortcut for logging an ERROR message + def error: (message msg) -> IO? + + # Shortcut for logging a WARN message + def warn: (message msg) -> IO? + + # Shortcut for logging an INFO message + def info: (message msg) -> IO? + + # Shortcut for logging a DEBUG message + def debug: (message msg) -> IO? + + # Will the logger output FATAL messages? + def fatal?: () -> bool + + # Will the logger output ERROR messages? + def error?: () -> bool + + # Will the logger output WARN messages? + def warn?: () -> bool + + # Will the logger output INFO messages? + def info?: () -> bool + + # Will the logger output DEBUG messages? + def debug?: () -> bool + + private + + # + # Formats +arg+ for the logger + # + # * If +arg+ is an Exception, it will format the error message and + # the back trace. + # * If +arg+ responds to #to_str, it will return it. + # * Otherwise it will return +arg+.inspect. + def format: (message arg) -> String + end + + class Log < BasicLog + # Format of the timestamp which is applied to each logged line. The + # default is "[%Y-%m-%d %H:%M:%S]" + attr_accessor time_format: String + + # + # Same as BasicLog#initialize + # + # You can set the timestamp format through #time_format + def initialize: (?BasicLog::log_file log_file, ?Integer? level) -> void + + # + # Same as BasicLog#log + def log: (Integer level, String data) -> IO? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/manifest.yaml b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/manifest.yaml new file mode 100644 index 0000000..7ce3ffe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/manifest.yaml @@ -0,0 +1,8 @@ +dependencies: + - name: digest + - name: erb + - name: openssl + - name: singleton + - name: socket + - name: tempfile + - name: uri diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/server.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/server.rbs new file mode 100644 index 0000000..74db11f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/server.rbs @@ -0,0 +1,57 @@ +module WEBrick + class ServerError < StandardError + end + + class SimpleServer + def self.start: [T] () { () -> T } -> T + end + + class Daemon + def self.start: () -> void + | [T] () { () -> T } -> T + end + + class GenericServer + @shutdown_pipe: [IO, IO]? + + attr_reader status: :Stop | :Running | :Shutdown + + attr_reader config: Hash[Symbol, untyped] + + attr_reader logger: BasicLog + + attr_reader tokens: Thread::SizedQueue + + attr_reader listeners: Array[TCPServer| OpenSSL::SSL::SSLServer] + + def initialize: (?Hash[Symbol, untyped] config, ?Hash[Symbol, untyped] default) -> void + + def []: (Symbol key) -> untyped + + def listen: (String address, Integer port) -> void + + def start: () ?{ (TCPSocket) -> void } -> void + + def stop: () -> void + + def shutdown: () -> void + + def run: (TCPSocket sock) -> void + + private + + def accept_client: (TCPServer svr) -> TCPSocket? + + def start_thread: (TCPSocket sock) ?{ (TCPSocket) -> void } -> Thread + + def call_callback: (Symbol callback_name, *untyped args) -> untyped + + def setup_shutdown_pipe: () -> [IO, IO] + + def cleanup_shutdown_pipe: ([IO, IO]? shutdown_pipe) -> void + + def alarm_shutdown_pipe: [T] () { (IO) -> T } -> T? + + def cleanup_listener: () -> void + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/ssl.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/ssl.rbs new file mode 100644 index 0000000..83f08f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/ssl.rbs @@ -0,0 +1,19 @@ +module WEBrick + module Config + SSL: Hash[Symbol, untyped] + end + + module Utils + def self?.create_self_signed_cert: (untyped bits, untyped cn, untyped comment) -> ::Array[untyped] + end + + class GenericServer + @ssl_context: OpenSSL::SSL::SSLContext? + + def ssl_context: () -> OpenSSL::SSL::SSLContext? + + def setup_ssl_context: (Hash[Symbol, untyped] config) -> OpenSSL::SSL::SSLContext + + def ssl_servername_callback: (untyped sslsocket, ?untyped? hostname) -> untyped + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/utils.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/utils.rbs new file mode 100644 index 0000000..c7d7a68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/utils.rbs @@ -0,0 +1,122 @@ +module WEBrick + module Utils + # + # Sets IO operations on +io+ to be non-blocking + def self?.set_non_blocking: (IO io) -> void + + # + # Sets the close on exec flag for +io+ + def self?.set_close_on_exec: (IO io) -> void + + # + # Changes the process's uid and gid to the ones of +user+ + def self?.su: (String user) -> void + + # + # The server hostname + def self?.getservername: () -> String + + # + # Creates TCP server sockets bound to +address+:+port+ and returns them. + # + # It will create IPV4 and IPV6 sockets on all interfaces. + def self?.create_listeners: (String host, Integer port) -> Array[TCPServer] + + # + # Characters used to generate random strings + RAND_CHARS: String + + # + # Generates a random string of length +len+ + def self?.random_string: (Integer len) -> String + + # + # Class used to manage timeout handlers across multiple threads. + # + # Timeout handlers should be managed by using the class methods which are + # synchronized. + # + # id = TimeoutHandler.register(10, Timeout::Error) + # begin + # sleep 20 + # puts 'foo' + # ensure + # TimeoutHandler.cancel(id) + # end + # + # will raise Timeout::Error + # + # id = TimeoutHandler.register(10, Timeout::Error) + # begin + # sleep 5 + # puts 'foo' + # ensure + # TimeoutHandler.cancel(id) + # end + # + # will print 'foo' + # + class TimeoutHandler + @queue: Thread::Queue + + @watcher: Thread? + + include Singleton + + # + # Mutex used to synchronize access across threads + TimeoutMutex: Thread::Mutex + + # + # Registers a new timeout handler + # + # +time+:: Timeout in seconds + # +exception+:: Exception to raise when timeout elapsed + def self.register: (Numeric seconds, singleton(Exception) exception) -> Integer + + # + # Cancels the timeout handler +id+ + def self.cancel: (Integer id) -> bool + + def self.terminate: () -> Thread? + + # + # Creates a new TimeoutHandler. You should use ::register and ::cancel + # instead of creating the timeout handler directly. + def initialize: () -> void + + private + + def watch: () -> bot + + def watcher: () -> Thread + + public + + # + # Interrupts the timeout handler +id+ and raises +exception+ + def interrupt: (Thread thread, Integer id, singleton(Exception) exception) -> nil + + # + # Registers a new timeout handler + # + # +time+:: Timeout in seconds + # +exception+:: Exception to raise when timeout elapsed + def register: (Thread thread, Numeric time, singleton(Exception) exception) -> Integer + + # + # Cancels the timeout handler +id+ + def cancel: (Thread thread, Integer id) -> bool + + # + def terminate: () -> Thread? + end + + # + # Executes the passed block and raises +exception+ if execution takes more + # than +seconds+. + # + # If +seconds+ is zero or nil, simply executes the block + def self?.timeout: [T] (Numeric? seconds, ?singleton(Exception) exception) { (?Numeric) -> T } -> T + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/version.rbs b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/version.rbs new file mode 100644 index 0000000..64d0ef0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/sig/version.rbs @@ -0,0 +1,3 @@ +module WEBrick + VERSION: String +end diff --git a/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/webrick.gemspec b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/webrick.gemspec new file mode 100644 index 0000000..1ebc674 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/webrick-1.9.2/webrick.gemspec @@ -0,0 +1,105 @@ +# frozen_string_literal: true +begin + require_relative 'lib/webrick/version' +rescue LoadError + # for Ruby core repository + require_relative 'version' +end + +Gem::Specification.new do |s| + s.name = "webrick" + s.version = WEBrick::VERSION + s.summary = "HTTP server toolkit" + s.description = "WEBrick is an HTTP server toolkit that can be configured as an HTTPS server, a proxy server, and a virtual-host server." + + s.require_path = %w{lib} + s.files = [ + "Gemfile", + "LICENSE.txt", + "README.md", + "Rakefile", + "lib/webrick.rb", + "lib/webrick/accesslog.rb", + "lib/webrick/cgi.rb", + "lib/webrick/compat.rb", + "lib/webrick/config.rb", + "lib/webrick/cookie.rb", + "lib/webrick/htmlutils.rb", + "lib/webrick/httpauth.rb", + "lib/webrick/httpauth/authenticator.rb", + "lib/webrick/httpauth/basicauth.rb", + "lib/webrick/httpauth/digestauth.rb", + "lib/webrick/httpauth/htdigest.rb", + "lib/webrick/httpauth/htgroup.rb", + "lib/webrick/httpauth/htpasswd.rb", + "lib/webrick/httpauth/userdb.rb", + "lib/webrick/httpproxy.rb", + "lib/webrick/httprequest.rb", + "lib/webrick/httpresponse.rb", + "lib/webrick/https.rb", + "lib/webrick/httpserver.rb", + "lib/webrick/httpservlet.rb", + "lib/webrick/httpservlet/abstract.rb", + "lib/webrick/httpservlet/cgi_runner.rb", + "lib/webrick/httpservlet/cgihandler.rb", + "lib/webrick/httpservlet/erbhandler.rb", + "lib/webrick/httpservlet/filehandler.rb", + "lib/webrick/httpservlet/prochandler.rb", + "lib/webrick/httpstatus.rb", + "lib/webrick/httputils.rb", + "lib/webrick/httpversion.rb", + "lib/webrick/log.rb", + "lib/webrick/server.rb", + "lib/webrick/ssl.rb", + "lib/webrick/utils.rb", + "lib/webrick/version.rb", + "sig/accesslog.rbs", + "sig/cgi.rbs", + "sig/compat.rbs", + "sig/config.rbs", + "sig/cookie.rbs", + "sig/htmlutils.rbs", + "sig/httpauth.rbs", + "sig/httpauth/authenticator.rbs", + "sig/httpauth/basicauth.rbs", + "sig/httpauth/digestauth.rbs", + "sig/httpauth/htdigest.rbs", + "sig/httpauth/htgroup.rbs", + "sig/httpauth/htpasswd.rbs", + "sig/httpauth/userdb.rbs", + "sig/httpproxy.rbs", + "sig/httprequest.rbs", + "sig/httpresponse.rbs", + "sig/https.rbs", + "sig/httpserver.rbs", + "sig/httpservlet.rbs", + "sig/httpservlet/abstract.rbs", + "sig/httpservlet/cgi_runner.rbs", + "sig/httpservlet/cgihandler.rbs", + "sig/httpservlet/erbhandler.rbs", + "sig/httpservlet/filehandler.rbs", + "sig/httpservlet/prochandler.rbs", + "sig/httpstatus.rbs", + "sig/httputils.rbs", + "sig/httpversion.rbs", + "sig/log.rbs", + "sig/manifest.yaml", + "sig/server.rbs", + "sig/ssl.rbs", + "sig/utils.rbs", + "sig/version.rbs", + "webrick.gemspec", + ] + s.required_ruby_version = ">= 2.4.0" + + s.authors = ["TAKAHASHI Masayoshi", "GOTOU YUUZOU", "Eric Wong"] + s.email = [nil, nil, 'normal@ruby-lang.org'] + s.homepage = "https://github.com/ruby/webrick" + s.licenses = ["Ruby", "BSD-2-Clause"] + + if s.respond_to?(:metadata=) + s.metadata = { + "bug_tracker_uri" => "https://github.com/ruby/webrick/issues", + } + end +end -- cgit v1.2.3